ref: 43cf20b155f9888b838ef226f348983923992380
parent: e27a6d53a0219deda031496767e73999bb988b74
author: Rangi <remy.oukaour+rangi42@gmail.com>
date: Mon Apr 26 07:55:50 EDT 2021
Support Mac OS classic CR line endings in linkerscripts This also refactors `readChar(file)` to `nextChar()` to be more like the rgbasm lexer.
--- a/src/link/script.c
+++ b/src/link/script.c
@@ -43,8 +43,7 @@
if (!fileStackSize) /* Init file stack */
fileStackSize = 4;
fileStackSize *= 2;
- fileStack = realloc(fileStack,
- sizeof(*fileStack) * fileStackSize);
+ fileStack = realloc(fileStack, sizeof(*fileStack) * fileStackSize);
if (!fileStack)
err(1, "%s(%" PRIu32 "): Internal INCLUDE error",
linkerScriptName, lineNo);
@@ -173,11 +172,11 @@
[COMMAND_ALIGN] = "ALIGN"
};
-static int readChar(FILE *file)
+static int nextChar(void)
{
- int curchar = getc(file);
+ int curchar = getc(linkerScript);
- if (curchar == EOF && ferror(file))
+ if (curchar == EOF && ferror(linkerScript))
err(1, "%s(%" PRIu32 "): Unexpected error in %s",
linkerScriptName, lineNo, __func__);
return curchar;
@@ -194,14 +193,14 @@
/* Skip initial whitespace... */
do
- curchar = readChar(linkerScript);
+ curchar = nextChar();
while (isWhiteSpace(curchar));
/* If this is a comment, skip to the end of the line */
if (curchar == ';') {
- do
- curchar = readChar(linkerScript);
- while (!isNewline(curchar) && curchar != EOF);
+ do {
+ curchar = nextChar();
+ } while (!isNewline(curchar) && curchar != EOF);
}
if (curchar == EOF) {
@@ -210,9 +209,14 @@
/* If we have a newline char, this is a newline token */
token.type = TOKEN_NEWLINE;
- /* FIXME: This works with CRLF newlines, but not CR-only */
- if (curchar == '\r')
- readChar(linkerScript); /* Read and discard LF */
+ if (curchar == '\r') {
+ /* Handle CRLF */
+ curchar = nextChar();
+ if (curchar != '\n') {
+ ungetc(curchar, linkerScript);
+ curchar = '\r';
+ }
+ }
} else if (curchar == '"') {
/* If we have a string start, this is a string */
token.type = TOKEN_STRING;
@@ -222,7 +226,7 @@
size_t capacity = 16; /* Half of the default capacity */
do {
- curchar = readChar(linkerScript);
+ curchar = nextChar();
if (curchar == EOF || isNewline(curchar)) {
errx(1, "%s(%" PRIu32 "): Unterminated string",
linkerScriptName, lineNo);
@@ -231,7 +235,7 @@
curchar = '\0';
} else if (curchar == '\\') {
/* Backslashes are escape sequences */
- curchar = readChar(linkerScript);
+ curchar = nextChar();
if (curchar == EOF || isNewline(curchar))
errx(1, "%s(%" PRIu32 "): Unterminated string",
linkerScriptName, lineNo);
@@ -248,8 +252,7 @@
if (size >= capacity || token.attr.string == NULL) {
capacity *= 2;
- token.attr.string = realloc(token.attr.string,
- capacity);
+ token.attr.string = realloc(token.attr.string, capacity);
if (!token.attr.string)
err(1, "%s: Failed to allocate memory for string",
__func__);
@@ -276,10 +279,9 @@
if (!curchar)
break;
- curchar = readChar(linkerScript);
+ curchar = nextChar();
/* Whitespace, a newline or a comment end the token */
- if (isWhiteSpace(curchar) || isNewline(curchar)
- || curchar == ';') {
+ if (isWhiteSpace(curchar) || isNewline(curchar) || curchar == ';') {
ungetc(curchar, linkerScript);
curchar = '\0';
}
@@ -298,8 +300,7 @@
if (token.type == TOKEN_INVALID) {
/* Try to match a bank specifier */
- for (enum SectionType type = 0; type < SECTTYPE_INVALID;
- type++) {
+ for (enum SectionType type = 0; type < SECTTYPE_INVALID; type++) {
if (!strcmp(typeNames[type], str)) {
token.type = TOKEN_BANK;
token.attr.secttype = type;
@@ -329,8 +330,7 @@
return &token;
}
-static void processCommand(enum LinkerScriptCommand command, uint16_t arg,
- uint16_t *pc)
+static void processCommand(enum LinkerScriptCommand command, uint16_t arg, uint16_t *pc)
{
switch (command) {
case COMMAND_INVALID:
@@ -475,8 +475,7 @@
errx(1, "%s(%" PRIu32 "): Command specified without an argument",
linkerScriptName, lineNo);
- processCommand(attr.command, arg,
- &curaddr[type][bankID]);
+ processCommand(attr.command, arg, &curaddr[type][bankID]);
} else { /* TOKEN_BANK */
type = attr.secttype;
/*
--- a/test/link/linkerscript-escapes-test.link
+++ b/test/link/linkerscript-escapes-test.link
@@ -1,3 +1,1 @@
-ROM0
- "A\"B\tC\rD\nE"
- "in\{valid"
+; This uses CR line endings ROM0 "A\"B\tC\rD\nE" "in\{valid"
\ No newline at end of file
--- a/test/link/linkerscript-escapes-test.out
+++ b/test/link/linkerscript-escapes-test.out
@@ -1,1 +1,1 @@
-error: ./linkerscript-escapes-test.link(3): Illegal character escape
+error: ./linkerscript-escapes-test.link(4): Illegal character escape