shithub: rgbds

Download patch

ref: 8435a29c4e0db7295d750c87e624374c8bea907f
parent: b7fe78cad8a951aa08c3133478da175eb377e2fd
author: Rangi <[email protected]>
date: Wed Nov 24 12:18:35 EST 2021

Turn the `readChars` macro into a `readInternal` function

This macro was only used twice, and the second usage did
some unnecessary work.

--- a/src/asm/lexer.c
+++ b/src/asm/lexer.c
@@ -808,6 +808,19 @@
 	return str;
 }
 
+static size_t readInternal(size_t bufIndex, size_t nbChars)
+{
+	// This buffer overflow made me lose WEEKS of my life. Never again.
+	assert(bufIndex + nbChars <= LEXER_BUF_SIZE);
+	ssize_t nbReadChars = read(lexerState->fd, &lexerState->buf[bufIndex], nbChars);
+
+	if (nbReadChars == -1)
+		fatalerror("Error while reading \"%s\": %s\n", lexerState->path, strerror(errno));
+
+	// `nbReadChars` cannot be negative, so it's fine to cast to `size_t`
+	return (size_t)nbReadChars;
+}
+
 /* We only need one character of lookahead, for macro arguments */
 static int peekInternal(uint8_t distance)
 {
@@ -839,42 +852,31 @@
 
 		/* Compute the index we'll start writing to */
 		size_t writeIndex = (lexerState->index + lexerState->nbChars) % LEXER_BUF_SIZE;
-		ssize_t nbCharsRead = 0, totalCharsRead = 0;
 
-#define readChars(size) do { \
-	/* This buffer overflow made me lose WEEKS of my life. Never again. */ \
-	assert(writeIndex + (size) <= LEXER_BUF_SIZE); \
-	nbCharsRead = read(lexerState->fd, &lexerState->buf[writeIndex], (size)); \
-	if (nbCharsRead == -1) \
-		fatalerror("Error while reading \"%s\": %s\n", lexerState->path, strerror(errno)); \
-	totalCharsRead += nbCharsRead; \
-	writeIndex += nbCharsRead; \
-	if (writeIndex == LEXER_BUF_SIZE) \
-		writeIndex = 0; \
-	target -= nbCharsRead; \
-} while (0)
-
 		/* If the range to fill passes over the buffer wrapping point, we need two reads */
 		if (writeIndex + target > LEXER_BUF_SIZE) {
 			size_t nbExpectedChars = LEXER_BUF_SIZE - writeIndex;
+			size_t nbReadChars = readInternal(writeIndex, nbExpectedChars);
 
-			readChars(nbExpectedChars);
+			lexerState->nbChars += nbReadChars;
+
+			writeIndex += nbReadChars;
+			if (writeIndex == LEXER_BUF_SIZE)
+				writeIndex = 0;
+
 			// If the read was incomplete, don't perform a second read
-			// `nbCharsRead` cannot be negative, so it's fine to cast to `size_t`
-			if ((size_t)nbCharsRead < nbExpectedChars)
+			target -= nbReadChars;
+			if (nbReadChars < nbExpectedChars)
 				target = 0;
 		}
 		if (target != 0)
-			readChars(target);
+			lexerState->nbChars += readInternal(writeIndex, target);
 
-#undef readChars
-
-		lexerState->nbChars += totalCharsRead;
-
 		/* If there aren't enough chars even after refilling, give up */
 		if (lexerState->nbChars <= distance)
 			return EOF;
 	}
+
 	return (unsigned char)lexerState->buf[(lexerState->index + distance) % LEXER_BUF_SIZE];
 }