From 8b8c593bf6fc3dea6af8546c33493a28366389d9 Mon Sep 17 00:00:00 2001 From: FosterProgramming Date: Wed, 5 Nov 2025 10:04:30 +0100 Subject: [PATCH] Fix preproc not correctly reading skipped lines symbols inside enum (#2197) --- tools/preproc/asm_file.cpp | 50 +++++++++++++++++++++++++++++++++++++- tools/preproc/asm_file.h | 1 + 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/tools/preproc/asm_file.cpp b/tools/preproc/asm_file.cpp index 69b412b24e..fcc996d66d 100644 --- a/tools/preproc/asm_file.cpp +++ b/tools/preproc/asm_file.cpp @@ -584,7 +584,11 @@ bool AsmFile::ParseEnum() RaiseError("%s:%ld: empty enum is invalid", headerFilename.c_str(), currentHeaderLine); } - if (m_buffer[m_pos] != ',') + if (m_buffer[m_pos] == '#') + { + currentHeaderLine = ParseLineSkipInEnum(); + } + else if (m_buffer[m_pos] != ',') { currentHeaderLine += SkipWhitespaceAndEol(); if (m_buffer[m_pos++] == '}' && m_buffer[m_pos++] == ';') @@ -688,6 +692,50 @@ int AsmFile::SkipWhitespaceAndEol() return newlines; } +int AsmFile::ParseLineSkipInEnum(void) +{ + m_pos++; + while (m_buffer[m_pos] == ' ' || m_buffer[m_pos] == '\t') + m_pos++; + + if (!IsAsciiDigit(m_buffer[m_pos])) + RaiseError("malformatted line indicator found inside `enum`, expected line number"); + + unsigned n = 0; + int digit = 0; + while ((digit = ConvertDigit(m_buffer[m_pos++], 10)) != -1) + n = 10 * n + digit; + + while (m_buffer[m_pos] == ' ' || m_buffer[m_pos] == '\t') + m_pos++; + + if (m_buffer[m_pos++] != '"') + RaiseError("malformatted line indicator found before `enum`, expected filename"); + + while (m_buffer[m_pos] != '"') + { + unsigned char c = m_buffer[m_pos++]; + + if (c == 0) + { + if (m_pos >= m_size) + RaiseError("unexpected EOF in line indicator"); + else + RaiseError("unexpected null character in line indicator"); + } + + if (!IsAsciiPrintable(c)) + RaiseError("unexpected character '\\x%02X' in line indicator", c); + + if (c == '\\') + { + c = m_buffer[m_pos]; + RaiseError("unexpected escape '\\%c' in line indicator", c); + } + } + return n - 1; +} + // returns the last line indicator and its corresponding file name without modifying the token index int AsmFile::FindLastLineNumber(std::string& filename) { diff --git a/tools/preproc/asm_file.h b/tools/preproc/asm_file.h index 33e6ce5c49..9cab32a97f 100644 --- a/tools/preproc/asm_file.h +++ b/tools/preproc/asm_file.h @@ -73,6 +73,7 @@ private: void VerifyStringLength(int length); int SkipWhitespaceAndEol(); int FindLastLineNumber(std::string& filename); + int ParseLineSkipInEnum(void); std::string ReadIdentifier(); long ReadInteger(std::string filename, long line); };