From 535ed69d33072543b543829b86409758cc7f6318 Mon Sep 17 00:00:00 2001 From: YamaArashi Date: Sun, 22 Jan 2017 21:55:01 -0800 Subject: change preproc syntax for C strings --- tools/preproc/c_file.cpp | 183 ++++++++++++++++++++++++++++++----------------- 1 file changed, 118 insertions(+), 65 deletions(-) (limited to 'tools/preproc/c_file.cpp') diff --git a/tools/preproc/c_file.cpp b/tools/preproc/c_file.cpp index aed53d44b..4e6035214 100644 --- a/tools/preproc/c_file.cpp +++ b/tools/preproc/c_file.cpp @@ -72,8 +72,6 @@ CFile::~CFile() void CFile::Preproc() { - bool inConcatMode = false; - bool noTerminator = false; char stringChar = 0; while (m_pos < m_size) @@ -94,85 +92,140 @@ void CFile::Preproc() } else { + if (m_buffer[m_pos] == '\n') + m_lineNum++; std::putchar(m_buffer[m_pos]); m_pos++; } } else { - if (inConcatMode ? m_buffer[m_pos] == '"' - : (m_buffer[m_pos] == '_' || m_buffer[m_pos] == '@') && m_buffer[m_pos + 1] == '"') - { - if (!inConcatMode) - { - noTerminator = (m_buffer[m_pos] == '@'); - m_pos++; // skip past underscore or at-sign - } - - unsigned char s[kMaxStringLength]; - int length; - StringParser stringParser(m_buffer, m_size); - - try - { - m_pos += stringParser.ParseString(m_pos, s, length); - } - catch (std::runtime_error e) - { - RaiseError(e.what()); - } - - if (!inConcatMode) - { - std::printf("{ "); - } - - inConcatMode = true; - - for (int i = 0; i < length; i++) - printf("0x%02X, ", s[i]); - } - else - { - char c = m_buffer[m_pos++]; + TryConvertString(); - if (c == '\r') - { - if (m_buffer[m_pos] == '\n') - { - m_pos++; - } + char c = m_buffer[m_pos++]; - c = '\n'; - } + std::putchar(c); - if ((c != ' ' && c != '\t' && c != '\n') && inConcatMode) - { - if (noTerminator) - std::printf(" }"); - else - std::printf("0xFF }"); + if (c == '\n') + m_lineNum++; + else if (c == '"') + stringChar = '"'; + else if (m_buffer[m_pos] == '\'') + stringChar = '\''; + } + } +} - inConcatMode = false; - } +bool CFile::ConsumeHorizontalWhitespace() +{ + if (m_buffer[m_pos] == '\t' || m_buffer[m_pos] == ' ') + { + m_pos++; + return true; + } - std::putchar(c); + return false; +} - if (c == '\n') - m_lineNum++; - else if (c == '"') - stringChar = '"'; - else if (m_buffer[m_pos] == '\'') - stringChar = '\''; - } - } +bool CFile::ConsumeNewline() +{ + if (m_buffer[m_pos] == '\r' && m_buffer[m_pos + 1] == '\n') + { + m_pos += 2; + m_lineNum++; + return true; } - if (inConcatMode) + if (m_buffer[m_pos] == '\n') { - printf("0xFF }"); - RaiseWarning("string at end of file"); + m_pos++; + m_lineNum++; + return true; } + + return false; +} + +void CFile::SkipWhitespace() +{ + while (ConsumeHorizontalWhitespace() || ConsumeNewline()) + ; +} + +void CFile::TryConvertString() +{ + long oldPos = m_pos; + long oldLineNum = m_lineNum; + bool noTerminator = false; + + if (m_buffer[m_pos] != '_' || (m_pos > 0 && IsIdentifierChar(m_buffer[m_pos - 1]))) + return; + + m_pos++; + + if (m_buffer[m_pos] == '_') + { + noTerminator = true; + m_pos++; + } + + SkipWhitespace(); + + if (m_buffer[m_pos] != '(') + { + m_pos = oldPos; + m_lineNum = oldLineNum; + return; + } + + m_pos++; + + SkipWhitespace(); + + std::printf("{ "); + + while (1) + { + SkipWhitespace(); + + if (m_buffer[m_pos] == '"') + { + unsigned char s[kMaxStringLength]; + int length; + StringParser stringParser(m_buffer, m_size); + + try + { + m_pos += stringParser.ParseString(m_pos, s, length); + } + catch (std::runtime_error e) + { + RaiseError(e.what()); + } + + for (int i = 0; i < length; i++) + printf("0x%02X, ", s[i]); + } + else if (m_buffer[m_pos] == ')') + { + m_pos++; + break; + } + else + { + if (m_pos >= m_size) + RaiseError("unexpected EOF"); + if (IsAsciiPrintable(m_buffer[m_pos])) + RaiseError("unexpected character '%c'", m_buffer[m_pos]); + else + RaiseError("unexpected character '\\x%02X'", m_buffer[m_pos]); + } + } + + if (noTerminator) + std::printf(" }"); + else + std::printf("0xFF }"); } // Reports a diagnostic message. -- cgit v1.2.3 From c8542506580c0fa247bbb44c169a2cb1244577e4 Mon Sep 17 00:00:00 2001 From: YamaArashi Date: Mon, 23 Jan 2017 16:34:20 -0800 Subject: preproc incbins --- tools/preproc/c_file.cpp | 161 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 160 insertions(+), 1 deletion(-) (limited to 'tools/preproc/c_file.cpp') diff --git a/tools/preproc/c_file.cpp b/tools/preproc/c_file.cpp index 4e6035214..cd11c8f6d 100644 --- a/tools/preproc/c_file.cpp +++ b/tools/preproc/c_file.cpp @@ -20,6 +20,8 @@ #include #include +#include +#include #include "preproc.h" #include "c_file.h" #include "char_util.h" @@ -101,6 +103,10 @@ void CFile::Preproc() else { TryConvertString(); + TryConvertIncbin(); + + if (m_pos >= m_size) + break; char c = m_buffer[m_pos++]; @@ -110,7 +116,7 @@ void CFile::Preproc() m_lineNum++; else if (c == '"') stringChar = '"'; - else if (m_buffer[m_pos] == '\'') + else if (c == '\'') stringChar = '\''; } } @@ -228,6 +234,159 @@ void CFile::TryConvertString() std::printf("0xFF }"); } +bool CFile::CheckIdentifier(const std::string& ident) +{ + int i; + + for (i = 0; (unsigned)i < ident.length() && m_pos + i < m_size; i++) + if (ident[i] != m_buffer[m_pos + i]) + return false; + + return (i == ident.length()); +} + +std::unique_ptr CFile::ReadWholeFile(const std::string& path, int& size) +{ + FILE* fp = fopen(path.c_str(), "rb"); + + if (fp == nullptr) + RaiseError("Failed to open \"%s\" for reading.\n", path.c_str()); + + fseek(fp, 0, SEEK_END); + + size = ftell(fp); + + std::unique_ptr buffer = std::make_unique(size); + + rewind(fp); + + if (fread(buffer.get(), size, 1, fp) != 1) + RaiseError("Failed to read \"%s\".\n", path.c_str()); + + fclose(fp); + + return buffer; +} + +int ExtractData(const std::unique_ptr& buffer, int offset, int size) +{ + switch (size) + { + case 1: + return buffer[offset]; + case 2: + return (buffer[offset + 1] << 8) + | buffer[offset]; + case 4: + return (buffer[offset + 3] << 24) + | (buffer[offset + 2] << 16) + | (buffer[offset + 1] << 8) + | buffer[offset]; + default: + FATAL_ERROR("Invalid size passed to ExtractData.\n"); + } +} + +void CFile::TryConvertIncbin() +{ + std::string idents[6] = { "INCBIN_S8", "INCBIN_U8", "INCBIN_S16", "INCBIN_U16", "INCBIN_S32", "INCBIN_U32" }; + int incbinType = -1; + + for (int i = 0; i < 6; i++) + { + if (CheckIdentifier(idents[i])) + { + incbinType = i; + break; + } + } + + if (incbinType == -1) + return; + + int size = 1 << (incbinType / 2); + bool isSigned = ((incbinType % 2) == 0); + + long oldPos = m_pos; + long oldLineNum = m_lineNum; + + m_pos += idents[incbinType].length(); + + SkipWhitespace(); + + if (m_buffer[m_pos] != '(') + { + m_pos = oldPos; + m_lineNum = oldLineNum; + return; + } + + m_pos++; + + SkipWhitespace(); + + if (m_buffer[m_pos] != '"') + RaiseError("expected double quote"); + + m_pos++; + + int startPos = m_pos; + + while (m_buffer[m_pos] != '"') + { + if (m_buffer[m_pos] == 0) + { + if (m_pos >= m_size) + RaiseError("unexpected EOF in path string"); + else + RaiseError("unexpected null character in path string"); + } + + if (m_buffer[m_pos] == '\r' || m_buffer[m_pos] == '\n') + RaiseError("unexpected end of line character in path string"); + + if (m_buffer[m_pos] == '\\') + RaiseError("unexpected escape in path string"); + + m_pos++; + } + + std::string path(&m_buffer[startPos], m_pos - startPos); + + m_pos++; + + SkipWhitespace(); + + if (m_buffer[m_pos] != ')') + RaiseError("expected ')'"); + + m_pos++; + + std::printf("{"); + + int fileSize; + std::unique_ptr buffer = ReadWholeFile(path, fileSize); + + if ((fileSize % size) != 0) + RaiseError("Size %d doesn't evenly divide file size %d.\n", size, fileSize); + + int count = fileSize / size; + int offset = 0; + + for (int i = 0; i < count; i++) + { + int data = ExtractData(buffer, offset, size); + offset += size; + + if (isSigned) + printf("%d,", data); + else + printf("%uu,", data); + } + + std::printf("}"); +} + // Reports a diagnostic message. void CFile::ReportDiagnostic(const char* type, const char* format, std::va_list args) { -- cgit v1.2.3 From 3f2ea6a1f076575d0c61ca0b71917704e38f6dd7 Mon Sep 17 00:00:00 2001 From: Cameron Hall Date: Tue, 24 Jan 2017 19:50:28 -0600 Subject: make preproc build under GCC (#215) --- tools/preproc/c_file.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/preproc/c_file.cpp') diff --git a/tools/preproc/c_file.cpp b/tools/preproc/c_file.cpp index cd11c8f6d..3b4024efe 100644 --- a/tools/preproc/c_file.cpp +++ b/tools/preproc/c_file.cpp @@ -236,9 +236,9 @@ void CFile::TryConvertString() bool CFile::CheckIdentifier(const std::string& ident) { - int i; + unsigned int i; - for (i = 0; (unsigned)i < ident.length() && m_pos + i < m_size; i++) + for (i = 0; i < ident.length() && m_pos + i < (unsigned)m_size; i++) if (ident[i] != m_buffer[m_pos + i]) return false; -- cgit v1.2.3 From 18e21f8b090a49934a80d56b1796e0c1d469a22c Mon Sep 17 00:00:00 2001 From: YamaArashi Date: Fri, 3 Feb 2017 20:34:51 -0800 Subject: remove C++14 feature from tools --- tools/preproc/c_file.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/preproc/c_file.cpp') diff --git a/tools/preproc/c_file.cpp b/tools/preproc/c_file.cpp index 3b4024efe..a2f178623 100644 --- a/tools/preproc/c_file.cpp +++ b/tools/preproc/c_file.cpp @@ -256,7 +256,7 @@ std::unique_ptr CFile::ReadWholeFile(const std::string& path, i size = ftell(fp); - std::unique_ptr buffer = std::make_unique(size); + std::unique_ptr buffer = std::unique_ptr(new unsigned char[size]); rewind(fp); -- cgit v1.2.3 From 7c96b16179792a044ded6ade1b74cdb1c0b870a5 Mon Sep 17 00:00:00 2001 From: camthesaxman Date: Fri, 3 Feb 2017 23:16:28 -0600 Subject: use std:: prefix and remove some unused functions --- tools/preproc/c_file.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'tools/preproc/c_file.cpp') diff --git a/tools/preproc/c_file.cpp b/tools/preproc/c_file.cpp index a2f178623..5bfdee086 100644 --- a/tools/preproc/c_file.cpp +++ b/tools/preproc/c_file.cpp @@ -247,23 +247,23 @@ bool CFile::CheckIdentifier(const std::string& ident) std::unique_ptr CFile::ReadWholeFile(const std::string& path, int& size) { - FILE* fp = fopen(path.c_str(), "rb"); + FILE* fp = std::fopen(path.c_str(), "rb"); if (fp == nullptr) RaiseError("Failed to open \"%s\" for reading.\n", path.c_str()); - fseek(fp, 0, SEEK_END); + std::fseek(fp, 0, SEEK_END); - size = ftell(fp); + size = std::ftell(fp); std::unique_ptr buffer = std::unique_ptr(new unsigned char[size]); - rewind(fp); + std::rewind(fp); - if (fread(buffer.get(), size, 1, fp) != 1) + if (std::fread(buffer.get(), size, 1, fp) != 1) RaiseError("Failed to read \"%s\".\n", path.c_str()); - fclose(fp); + std::fclose(fp); return buffer; } @@ -379,9 +379,9 @@ void CFile::TryConvertIncbin() offset += size; if (isSigned) - printf("%d,", data); + std::printf("%d,", data); else - printf("%uu,", data); + std::printf("%uu,", data); } std::printf("}"); -- cgit v1.2.3