shithub: rgbds

Download patch

ref: b3391f699f85391267e17c6a0182f1cebcecf9b9
parent: e25a4b0abc29eb82842b4d79b4586989c172045e
parent: 5a3c12cc6bc1e102a063081f98e4d342053a3317
author: Antonio Niño Díaz <antonio_nd@outlook.com>
date: Mon Dec 10 18:04:56 EST 2018

Merge pull request #310 from dbrotz/fix-302

Fix #302

--- a/src/asm/lexer.c
+++ b/src/asm/lexer.c
@@ -6,6 +6,7 @@
  * SPDX-License-Identifier: MIT
  */
 
+#include <assert.h>
 #include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
@@ -110,6 +111,21 @@
 	free(buf);
 }
 
+/*
+ * Maintains the following invariants:
+ * 1. nBufferSize < capacity
+ * 2. The buffer is terminated with 0
+ * 3. nBufferSize is the size without the terminator
+ */
+static void yy_buffer_append(YY_BUFFER_STATE buf, uint32_t capacity, char c)
+{
+	assert(buf->pBuffer[buf->nBufferSize] == 0);
+	assert(buf->nBufferSize + 1 < capacity);
+
+	buf->pBuffer[buf->nBufferSize++] = c;
+	buf->pBuffer[buf->nBufferSize] = 0;
+}
+
 YY_BUFFER_STATE yy_scan_bytes(char *mem, uint32_t size)
 {
 	YY_BUFFER_STATE pBuffer = malloc(sizeof(struct yy_buffer_state));
@@ -145,8 +161,11 @@
 	size = ftell(f);
 	fseek(f, 0, SEEK_SET);
 
-	pBuffer->pBufferRealStart = malloc(size + 2 + SAFETYMARGIN);
+	/* Give extra room for 2 newlines and terminator */
+	uint32_t capacity = size + 3;
 
+	pBuffer->pBufferRealStart = malloc(capacity + SAFETYMARGIN);
+
 	if (pBuffer->pBufferRealStart == NULL)
 		fatalerror("%s: Out of memory for buffer!", __func__);
 
@@ -155,9 +174,8 @@
 
 	size = fread(pBuffer->pBuffer, sizeof(uint8_t), size, f);
 
-	pBuffer->pBuffer[size] = '\n';
-	pBuffer->pBuffer[size + 1] = 0;
-	pBuffer->nBufferSize = size + 1;
+	pBuffer->pBuffer[size] = 0;
+	pBuffer->nBufferSize = size;
 
 	/* Convert all line endings to LF and spaces */
 
@@ -216,6 +234,22 @@
 				mem += 1;
 			}
 		}
+	}
+
+	/* Add newline if file doesn't end with one */
+	if (size == 0 || pBuffer->pBuffer[size - 1] != '\n')
+		yy_buffer_append(pBuffer, capacity, '\n');
+
+	/* Add newline if \ will eat the last newline */
+	if (pBuffer->nBufferSize >= 2) {
+		size_t pos = pBuffer->nBufferSize - 2;
+
+		/* Skip spaces */
+		while (pos > 0 && pBuffer->pBuffer[pos] == ' ')
+			pos--;
+
+		if (pBuffer->pBuffer[pos] == '\\')
+			yy_buffer_append(pBuffer, capacity, '\n');
 	}
 
 	pBuffer->oAtLineStart = 1;
--- /dev/null
+++ b/test/asm/line-continuation.asm
@@ -1,0 +1,1 @@
+foo @bar\
\ No newline at end of file
--- /dev/null
+++ b/test/asm/line-continuation.out
@@ -1,0 +1,2 @@
+ERROR: line-continuation.asm(2) -> @(-1):
+    Macro '@' not defined