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 ++++++++++++++++++++++++++++++---------------- tools/preproc/c_file.h | 4 + tools/preproc/char_util.h | 4 +- 3 files changed, 124 insertions(+), 67 deletions(-) (limited to 'tools') 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. diff --git a/tools/preproc/c_file.h b/tools/preproc/c_file.h index b6041cc00..1a2573839 100644 --- a/tools/preproc/c_file.h +++ b/tools/preproc/c_file.h @@ -42,6 +42,10 @@ private: long m_lineNum; std::string m_filename; + bool ConsumeHorizontalWhitespace(); + bool ConsumeNewline(); + void SkipWhitespace(); + void TryConvertString(); void ReportDiagnostic(const char* type, const char* format, std::va_list args); void RaiseError(const char* format, ...); void RaiseWarning(const char* format, ...); diff --git a/tools/preproc/char_util.h b/tools/preproc/char_util.h index ab20dbc53..02a6e1ceb 100644 --- a/tools/preproc/char_util.h +++ b/tools/preproc/char_util.h @@ -56,13 +56,13 @@ inline bool IsAsciiPrintable(unsigned char c) return (c >= ' ' && c <= '~'); } -// Returns whether the character can start the identifier of a "{FOO}" constant in strings. +// Returns whether the character can start a C identifier or the identifier of a "{FOO}" constant in strings. inline bool IsIdentifierStartingChar(unsigned char c) { return IsAsciiAlpha(c) || c == '_'; } -// Returns whether the character can be used in the identifier of a "{FOO}" constant in strings. +// Returns whether the character can be used in a C identifier or the identifier of a "{FOO}" constant in strings. inline bool IsIdentifierChar(unsigned char c) { return IsAsciiAlphanum(c) || c == '_'; -- 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/asm_file.cpp | 37 +---- tools/preproc/c_file.cpp | 161 ++++++++++++++++++- tools/preproc/c_file.h | 4 + tools/scaninc/Makefile | 6 +- tools/scaninc/asm_file.cpp | 191 +++++++++++++++++++++++ tools/scaninc/asm_file.h | 119 ++++++++++++++ tools/scaninc/c_file.cpp | 329 ++++++++++++++++++++++++++++++++++++++ tools/scaninc/c_file.h | 54 +++++++ tools/scaninc/scaninc.cpp | 382 ++++++++++----------------------------------- tools/scaninc/scaninc.h | 59 +++++++ 10 files changed, 1008 insertions(+), 334 deletions(-) create mode 100644 tools/scaninc/asm_file.cpp create mode 100644 tools/scaninc/asm_file.h create mode 100644 tools/scaninc/c_file.cpp create mode 100644 tools/scaninc/c_file.h create mode 100644 tools/scaninc/scaninc.h (limited to 'tools') diff --git a/tools/preproc/asm_file.cpp b/tools/preproc/asm_file.cpp index 7deaccc8a..49c9e3c66 100644 --- a/tools/preproc/asm_file.cpp +++ b/tools/preproc/asm_file.cpp @@ -111,45 +111,22 @@ void AsmFile::RemoveComments() m_buffer[pos++] = ' '; m_buffer[pos++] = ' '; - char commentStringChar = 0; - for (;;) { if (m_buffer[pos] == 0) return; - if (commentStringChar != 0) + if (m_buffer[pos] == '*' && m_buffer[pos + 1] == '/') { - if (m_buffer[pos] == '\\' && m_buffer[pos + 1] == commentStringChar) - { - m_buffer[pos++] = ' '; - m_buffer[pos++] = ' '; - } - else - { - if (m_buffer[pos] == commentStringChar) - commentStringChar = 0; - if (m_buffer[pos] != '\n') - m_buffer[pos] = ' '; - pos++; - } + m_buffer[pos++] = ' '; + m_buffer[pos++] = ' '; + break; } else { - if (m_buffer[pos] == '*' && m_buffer[pos + 1] == '/') - { - m_buffer[pos++] = ' '; - m_buffer[pos++] = ' '; - break; - } - else - { - if (m_buffer[pos] == '"' || m_buffer[pos] == '\'') - commentStringChar = m_buffer[pos]; - if (m_buffer[pos] != '\n') - m_buffer[pos] = ' '; - pos++; - } + if (m_buffer[pos] != '\n') + m_buffer[pos] = ' '; + pos++; } } } 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) { diff --git a/tools/preproc/c_file.h b/tools/preproc/c_file.h index 1a2573839..ddd57fd84 100644 --- a/tools/preproc/c_file.h +++ b/tools/preproc/c_file.h @@ -24,6 +24,7 @@ #include #include #include +#include #include "preproc.h" class CFile @@ -46,6 +47,9 @@ private: bool ConsumeNewline(); void SkipWhitespace(); void TryConvertString(); + std::unique_ptr CFile::ReadWholeFile(const std::string& path, int& size); + bool CheckIdentifier(const std::string& ident); + void TryConvertIncbin(); void ReportDiagnostic(const char* type, const char* format, std::va_list args); void RaiseError(const char* format, ...); void RaiseWarning(const char* format, ...); diff --git a/tools/scaninc/Makefile b/tools/scaninc/Makefile index 0efe283f1..71c4389ef 100644 --- a/tools/scaninc/Makefile +++ b/tools/scaninc/Makefile @@ -2,11 +2,13 @@ CXX = g++ CXXFLAGS = -Wall -std=c++11 -O2 -SRCS = scaninc.cpp +SRCS = scaninc.cpp c_file.cpp asm_file.cpp + +HEADERS := scaninc.h asm_file.h c_file.h .PHONY: clean -scaninc: $(SRCS) +scaninc: $(SRCS) $(HEADERS) $(CXX) $(CXXFLAGS) $(SRCS) -o $@ clean: diff --git a/tools/scaninc/asm_file.cpp b/tools/scaninc/asm_file.cpp new file mode 100644 index 000000000..143c70242 --- /dev/null +++ b/tools/scaninc/asm_file.cpp @@ -0,0 +1,191 @@ +// Copyright(c) 2015-2017 YamaArashi +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include +#include +#include "scaninc.h" +#include "asm_file.h" + +AsmFile::AsmFile(std::string path) +{ + m_path = path; + + FILE *fp = fopen(path.c_str(), "rb"); + + if (fp == NULL) + FATAL_ERROR("Failed to open \"%s\" for reading.\n", path.c_str()); + + fseek(fp, 0, SEEK_END); + + m_size = ftell(fp); + + m_buffer = new char[m_size]; + + rewind(fp); + + if (fread(m_buffer, m_size, 1, fp) != 1) + FATAL_ERROR("Failed to read \"%s\".\n", path.c_str()); + + fclose(fp); + + m_pos = 0; + m_lineNum = 1; +} + +AsmFile::~AsmFile() +{ + delete[] m_buffer; +} + +IncDirectiveType AsmFile::ReadUntilIncDirective(std::string &path) +{ + // At the beginning of each loop iteration, the current file position + // should be at the start of a line or at the end of the file. + for (;;) + { + SkipTabsAndSpaces(); + + IncDirectiveType incDirectiveType = IncDirectiveType::None; + + if (PeekChar() == '.') + { + m_pos++; + + if (MatchIncDirective("incbin", path)) + incDirectiveType = IncDirectiveType::Incbin; + else if (MatchIncDirective("include", path)) + incDirectiveType = IncDirectiveType::Include; + } + + for (;;) + { + int c = GetChar(); + + if (c == -1) + return incDirectiveType; + + if (c == ';') + { + SkipEndOfLineComment(); + break; + } + else if (c == '/' && PeekChar() == '*') + { + m_pos++; + SkipMultiLineComment(); + } + else if (c == '"') + { + SkipString(); + } + else if (c == '\n') + { + break; + } + } + + if (incDirectiveType != IncDirectiveType::None) + return incDirectiveType; + } +} + +std::string AsmFile::ReadPath() +{ + int length = 0; + int startPos = m_pos; + + for (;;) + { + int c = GetChar(); + + if (c == '"') + break; + + if (c == -1) + FATAL_INPUT_ERROR("unexpected EOF in include string\n"); + + if (c == 0) + FATAL_INPUT_ERROR("unexpected NUL character in include string\n"); + + if (c == '\n') + FATAL_INPUT_ERROR("unexpected end of line character in include string\n"); + + // Don't bother allowing any escape sequences. + if (c == '\\') + FATAL_INPUT_ERROR("unexpected escape in include string\n"); + + length++; + + if (length > SCANINC_MAX_PATH) + FATAL_INPUT_ERROR("path is too long"); + } + + return std::string(m_buffer, startPos, length); +} + +void AsmFile::SkipEndOfLineComment() +{ + int c; + + do + { + c = GetChar(); + } while (c != -1 && c != '\n'); +} + +void AsmFile::SkipMultiLineComment() +{ + for (;;) + { + int c = GetChar(); + + if (c == '*') + { + if (PeekChar() == '/') + { + m_pos++; + return; + } + } + else if (c == -1) + { + return; + } + } +} + +void AsmFile::SkipString() +{ + for (;;) + { + int c = GetChar(); + + if (c == '"') + break; + + if (c == -1) + FATAL_INPUT_ERROR("unexpected EOF in string\n"); + + if (c == '\\') + { + c = GetChar(); + } + } +} diff --git a/tools/scaninc/asm_file.h b/tools/scaninc/asm_file.h new file mode 100644 index 000000000..ad99b757e --- /dev/null +++ b/tools/scaninc/asm_file.h @@ -0,0 +1,119 @@ +// Copyright(c) 2015-2017 YamaArashi +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef ASM_FILE_H +#define ASM_FILE_H + +#include +#include "scaninc.h" + +enum class IncDirectiveType +{ + None, + Include, + Incbin +}; + +class AsmFile +{ +public: + AsmFile(std::string path); + ~AsmFile(); + IncDirectiveType ReadUntilIncDirective(std::string& path); + +private: + char *m_buffer; + int m_pos; + int m_size; + int m_lineNum; + std::string m_path; + + int GetChar() + { + if (m_pos >= m_size) + return -1; + + int c = m_buffer[m_pos++]; + + if (c == '\r') + { + if (m_pos < m_size && m_buffer[m_pos++] == '\n') + { + m_lineNum++; + return '\n'; + } + else + { + FATAL_INPUT_ERROR("CR line endings are not supported\n"); + } + } + + if (c == '\n') + m_lineNum++; + + return c; + } + + // No newline translation because it's not needed for any use of this function. + int PeekChar() + { + if (m_pos >= m_size) + return -1; + + return m_buffer[m_pos]; + } + + void SkipTabsAndSpaces() + { + while (m_pos < m_size && (m_buffer[m_pos] == '\t' || m_buffer[m_pos] == ' ')) + m_pos++; + } + + bool MatchIncDirective(std::string directiveName, std::string& path) + { + int length = directiveName.length(); + int i; + + for (i = 0; i < length && m_pos + i < m_size; i++) + if (directiveName[i] != m_buffer[m_pos + i]) + return false; + + if (i < length) + return false; + + m_pos += length; + + SkipTabsAndSpaces(); + + if (GetChar() != '"') + FATAL_INPUT_ERROR("no path after \".%s\" directive\n", directiveName.c_str()); + + path = ReadPath(); + + return true; + } + + std::string ReadPath(); + void SkipEndOfLineComment(); + void SkipMultiLineComment(); + void SkipString(); +}; + +#endif // ASM_FILE_H diff --git a/tools/scaninc/c_file.cpp b/tools/scaninc/c_file.cpp new file mode 100644 index 000000000..4af741f6e --- /dev/null +++ b/tools/scaninc/c_file.cpp @@ -0,0 +1,329 @@ +// Copyright(c) 2017 YamaArashi +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "c_file.h" + +CFile::CFile(std::string path) +{ + m_path = path; + + FILE *fp = fopen(path.c_str(), "rb"); + + if (fp == NULL) + FATAL_ERROR("Failed to open \"%s\" for reading.\n", path.c_str()); + + fseek(fp, 0, SEEK_END); + + m_size = ftell(fp); + + m_buffer = new char[m_size + 1]; + m_buffer[m_size] = 0; + + rewind(fp); + + if (fread(m_buffer, m_size, 1, fp) != 1) + FATAL_ERROR("Failed to read \"%s\".\n", path.c_str()); + + fclose(fp); + + m_pos = 0; + m_lineNum = 1; + + RemoveComments(); +} + +CFile::~CFile() +{ + delete[] m_buffer; +} + +// Removes comments to simplify further processing. +// It stops upon encountering a null character, +// which may or may not be the end of file marker. +// If it's not, the error will be caught later. +void CFile::RemoveComments() +{ + long pos = 0; + char stringChar = 0; + + for (;;) + { + if (m_buffer[pos] == 0) + return; + + if (stringChar != 0) + { + if (m_buffer[pos] == '\\' && m_buffer[pos + 1] == stringChar) + { + pos += 2; + } + else + { + if (m_buffer[pos] == stringChar) + stringChar = 0; + pos++; + } + } + else if (m_buffer[pos] == '/' && m_buffer[pos + 1] == '/') + { + while (m_buffer[pos] != '\n' && m_buffer[pos] != 0) + m_buffer[pos++] = ' '; + } + else if (m_buffer[pos] == '/' && m_buffer[pos + 1] == '*') + { + m_buffer[pos++] = ' '; + m_buffer[pos++] = ' '; + + for (;;) + { + if (m_buffer[pos] == 0) + return; + + if (m_buffer[pos] == '*' && m_buffer[pos + 1] == '/') + { + m_buffer[pos++] = ' '; + m_buffer[pos++] = ' '; + break; + } + else + { + if (m_buffer[pos] != '\n') + m_buffer[pos] = ' '; + pos++; + } + } + } + else + { + if (m_buffer[pos] == '"' || m_buffer[pos] == '\'') + stringChar = m_buffer[pos]; + pos++; + } + } +} + +void CFile::FindIncbins() +{ + char stringChar = 0; + + while (m_pos < m_size) + { + if (stringChar) + { + if (m_buffer[m_pos] == stringChar) + { + m_pos++; + stringChar = 0; + } + else if (m_buffer[m_pos] == '\\' && m_buffer[m_pos + 1] == stringChar) + { + m_pos += 2; + } + else + { + if (m_buffer[m_pos] == '\n') + m_lineNum++; + m_pos++; + } + } + else + { + CheckIncbin(); + + if (m_pos >= m_size) + break; + + char c = m_buffer[m_pos++]; + + if (c == '\n') + m_lineNum++; + else if (c == '"') + stringChar = '"'; + else if (c == '\'') + stringChar = '\''; + else if (c == 0) + FATAL_INPUT_ERROR("unexpected null character"); + } + } +} + +bool CFile::ConsumeHorizontalWhitespace() +{ + if (m_buffer[m_pos] == '\t' || m_buffer[m_pos] == ' ') + { + m_pos++; + return true; + } + + return false; +} + +bool CFile::ConsumeNewline() +{ + if (m_buffer[m_pos] == '\r' && m_buffer[m_pos + 1] == '\n') + { + m_pos += 2; + m_lineNum++; + return true; + } + + if (m_buffer[m_pos] == '\n') + { + m_pos++; + m_lineNum++; + return true; + } + + return false; +} + +void CFile::SkipWhitespace() +{ + while (ConsumeHorizontalWhitespace() || ConsumeNewline()) + ; +} + +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) + FATAL_INPUT_ERROR("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) + FATAL_INPUT_ERROR("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::CheckIncbin() +{ + 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; + + 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] != '"') + FATAL_INPUT_ERROR("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) + FATAL_INPUT_ERROR("unexpected EOF in path string"); + else + FATAL_INPUT_ERROR("unexpected null character in path string"); + } + + if (m_buffer[m_pos] == '\r' || m_buffer[m_pos] == '\n') + FATAL_INPUT_ERROR("unexpected end of line character in path string"); + + if (m_buffer[m_pos] == '\\') + FATAL_INPUT_ERROR("unexpected escape in path string"); + + m_pos++; + } + + std::string path(&m_buffer[startPos], m_pos - startPos); + + m_pos++; + + SkipWhitespace(); + + if (m_buffer[m_pos] != ')') + FATAL_INPUT_ERROR("expected ')'"); + + m_pos++; + + m_incbins.emplace(path); +} diff --git a/tools/scaninc/c_file.h b/tools/scaninc/c_file.h new file mode 100644 index 000000000..fcd327d28 --- /dev/null +++ b/tools/scaninc/c_file.h @@ -0,0 +1,54 @@ +// Copyright(c) 2017 YamaArashi +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef C_FILE_H +#define C_FILE_H + +#include +#include +#include +#include "scaninc.h" + +class CFile +{ +public: + CFile(std::string path); + ~CFile(); + void FindIncbins(); + const std::set& GetIncbins() { return m_incbins; } + +private: + char *m_buffer; + int m_pos; + int m_size; + int m_lineNum; + std::string m_path; + std::set m_incbins; + + void CFile::RemoveComments(); + bool ConsumeHorizontalWhitespace(); + bool ConsumeNewline(); + void SkipWhitespace(); + std::unique_ptr CFile::ReadWholeFile(const std::string& path, int& size); + bool CheckIdentifier(const std::string& ident); + void CheckIncbin(); +}; + +#endif // C_FILE_H diff --git a/tools/scaninc/scaninc.cpp b/tools/scaninc/scaninc.cpp index 3bd6b81a5..2f9ed81e9 100644 --- a/tools/scaninc/scaninc.cpp +++ b/tools/scaninc/scaninc.cpp @@ -1,317 +1,97 @@ -// Copyright (c) 2015 YamaArashi +// Copyright(c) 2015-2017 YamaArashi +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. #include #include #include #include #include - -#ifdef _MSC_VER - -#define FATAL_INPUT_ERROR(format, ...) \ -do { \ - fprintf(stderr, "%s:%d " format, m_path.c_str(), m_lineNum, __VA_ARGS__); \ - exit(1); \ -} while (0) - -#define FATAL_ERROR(format, ...) \ -do { \ - fprintf(stderr, format, __VA_ARGS__); \ - exit(1); \ -} while (0) - -#else - -#define FATAL_INPUT_ERROR(format, ...) \ -do { \ - fprintf(stderr, "%s:%d " format, m_path.c_str(), m_lineNum, ##__VA_ARGS__); \ - exit(1); \ -} while (0) - -#define FATAL_ERROR(format, ...) \ -do { \ - fprintf(stderr, format, ##__VA_ARGS__); \ - exit(1); \ -} while (0) - -#endif // _MSC_VER - -#define SCANINC_MAX_PATH 255 - -enum class IncDirectiveType { - None, - Include, - Incbin -}; - -class AsmFile -{ -public: - AsmFile(std::string path); - ~AsmFile(); - IncDirectiveType ReadUntilIncDirective(std::string &path); - -private: - char *m_buffer; - int m_pos; - int m_size; - int m_lineNum; - std::string m_path; - - int GetChar() - { - if (m_pos >= m_size) - return -1; - - int c = m_buffer[m_pos++]; - - if (c == '\r') { - if (m_pos < m_size && m_buffer[m_pos++] == '\n') { - m_lineNum++; - return '\n'; - } else { - FATAL_INPUT_ERROR("CR line endings are not supported\n"); - } - } - - if (c == '\n') - m_lineNum++; - - return c; - } - - // No newline translation because it's not needed for any use of this function. - int PeekChar() - { - if (m_pos >= m_size) - return -1; - - return m_buffer[m_pos]; - } - - void SkipTabsAndSpaces() - { - while (m_pos < m_size && (m_buffer[m_pos] == '\t' || m_buffer[m_pos] == ' ')) - m_pos++; - } - - bool MatchIncDirective(std::string directiveName, std::string &path) - { - int length = directiveName.length(); - int i; - - for (i = 0; i < length && m_pos + i < m_size; i++) - if (directiveName[i] != m_buffer[m_pos + i]) - return false; - - if (i < length) - return false; - - m_pos += length; - - SkipTabsAndSpaces(); - - if (GetChar() != '"') - FATAL_INPUT_ERROR("no path after \".%s\" directive\n", directiveName.c_str()); - - path = ReadPath(); - - return true; - } - - std::string ReadPath(); - void SkipEndOfLineComment(); - void SkipMultiLineComment(); - void SkipString(); -}; - -AsmFile::AsmFile(std::string path) -{ - m_path = path; - - FILE *fp = fopen(path.c_str(), "rb"); - - if (fp == NULL) - FATAL_ERROR("Failed to open \"%s\" for reading.\n", path.c_str()); - - fseek(fp, 0, SEEK_END); - - m_size = ftell(fp); - - m_buffer = new char[m_size]; - - rewind(fp); - - if (fread(m_buffer, m_size, 1, fp) != 1) - FATAL_ERROR("Failed to read \"%s\".\n", path.c_str()); - - fclose(fp); - - m_pos = 0; - m_lineNum = 1; -} - -AsmFile::~AsmFile() -{ - delete[] m_buffer; -} - -IncDirectiveType AsmFile::ReadUntilIncDirective(std::string &path) -{ - // At the beginning of each loop iteration, the current file position - // should be at the start of a line or at the end of the file. - for (;;) { - SkipTabsAndSpaces(); - - IncDirectiveType incDirectiveType = IncDirectiveType::None; - - if (PeekChar() == '.') { - m_pos++; - - if (MatchIncDirective("incbin", path)) - incDirectiveType = IncDirectiveType::Incbin; - else if (MatchIncDirective("include", path)) - incDirectiveType = IncDirectiveType::Include; - } - - for (;;) { - int c = GetChar(); - - if (c == -1) - return incDirectiveType; - - if (c == ';') { - SkipEndOfLineComment(); - break; - } else if (c == '/' && PeekChar() == '*') { - m_pos++; - SkipMultiLineComment(); - } else if (c == '"') { - SkipString(); - } else if (c == '\n') { - break; - } - } - - if (incDirectiveType != IncDirectiveType::None) - return incDirectiveType; - } -} - -std::string AsmFile::ReadPath() -{ - int length = 0; - int startPos = m_pos; - - for (;;) { - int c = GetChar(); - - if (c == '"') - break; - - if (c == -1) - FATAL_INPUT_ERROR("unexpected EOF in include string\n"); - - if (c == 0) - FATAL_INPUT_ERROR("unexpected NUL character in include string\n"); - - if (c == '\n') - FATAL_INPUT_ERROR("unexpected end of line character in include string\n"); - - // Don't bother allowing any escape sequences. - if (c == '\\') - FATAL_INPUT_ERROR("unexpected escape '\\%c' in include string\n", c); - - length++; - - if (length > SCANINC_MAX_PATH) - FATAL_INPUT_ERROR("path is too long"); - } - - return std::string(m_buffer, startPos, length); -} - -void AsmFile::SkipEndOfLineComment() -{ - int c; - - do { - c = GetChar(); - } while (c != -1 && c != '\n'); -} - -void AsmFile::SkipMultiLineComment() -{ - for (;;) { - int c = GetChar(); - - if (c == '*') { - if (PeekChar() == '/') { - m_pos++; - return; - } - } else if (c == -1) { - return; - } - } -} - -void AsmFile::SkipString() -{ - for (;;) { - int c = GetChar(); - - if (c == '"') - break; - - if (c == -1) - FATAL_INPUT_ERROR("unexpected EOF in string\n"); - - if (c == '\\') { - c = GetChar(); - } - } -} +#include "scaninc.h" +#include "asm_file.h" +#include "c_file.h" bool CanOpenFile(std::string path) { - FILE *fp = fopen(path.c_str(), "rb"); + FILE *fp = fopen(path.c_str(), "rb"); - if (fp == NULL) - return false; + if (fp == NULL) + return false; - fclose(fp); - return true; + fclose(fp); + return true; } int main(int argc, char **argv) { - if (argc < 2) - FATAL_ERROR("Usage: scaninc ASM_FILE_PATH\n"); - - std::stack filesToProcess; - std::set dependencies; - - filesToProcess.push(std::string(argv[1])); - - while (!filesToProcess.empty()) { - AsmFile file(filesToProcess.top()); - - filesToProcess.pop(); - - IncDirectiveType incDirectiveType; - std::string path; - - while ((incDirectiveType = file.ReadUntilIncDirective(path)) != IncDirectiveType::None) { - bool inserted = dependencies.insert(path).second; - if (inserted - && incDirectiveType == IncDirectiveType::Include - && CanOpenFile(path)) - filesToProcess.push(path); - } - } - - for (const std::string &path : dependencies) { - printf("%s\n", path.c_str()); - } + if (argc < 2) + FATAL_ERROR("Usage: scaninc FILE_PATH\n"); + + std::stack filesToProcess; + std::set dependencies; + + std::string initialPath(argv[1]); + + std::size_t pos = initialPath.find_last_of('.'); + + if (pos == std::string::npos) + FATAL_ERROR("no file extension in path \"%s\"\n", initialPath.c_str()); + + std::string extension = initialPath.substr(pos + 1); + + if (extension == "c") + { + CFile file(initialPath); + + file.FindIncbins(); + dependencies = file.GetIncbins(); + } + else if (extension == "s") + { + filesToProcess.push(std::string(argv[1])); + + while (!filesToProcess.empty()) + { + AsmFile file(filesToProcess.top()); + + filesToProcess.pop(); + + IncDirectiveType incDirectiveType; + std::string path; + + while ((incDirectiveType = file.ReadUntilIncDirective(path)) != IncDirectiveType::None) + { + bool inserted = dependencies.insert(path).second; + if (inserted + && incDirectiveType == IncDirectiveType::Include + && CanOpenFile(path)) + filesToProcess.push(path); + } + } + } + else + { + FATAL_ERROR("unknown extension \"%s\"\n", extension.c_str()); + } + + for (const std::string &path : dependencies) + { + printf("%s\n", path.c_str()); + } } diff --git a/tools/scaninc/scaninc.h b/tools/scaninc/scaninc.h new file mode 100644 index 000000000..30cc9611c --- /dev/null +++ b/tools/scaninc/scaninc.h @@ -0,0 +1,59 @@ +// Copyright(c) 2015-2017 YamaArashi +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef SCANINC_H +#define SCANINC_H + +#include +#include + +#ifdef _MSC_VER + +#define FATAL_INPUT_ERROR(format, ...) \ +do { \ + fprintf(stderr, "%s:%d " format, m_path.c_str(), m_lineNum, __VA_ARGS__); \ + exit(1); \ +} while (0) + +#define FATAL_ERROR(format, ...) \ +do { \ + fprintf(stderr, format, __VA_ARGS__); \ + exit(1); \ +} while (0) + +#else + +#define FATAL_INPUT_ERROR(format, ...) \ +do { \ + fprintf(stderr, "%s:%d " format, m_path.c_str(), m_lineNum, ##__VA_ARGS__); \ + exit(1); \ +} while (0) + +#define FATAL_ERROR(format, ...) \ +do { \ + fprintf(stderr, format, ##__VA_ARGS__); \ + exit(1); \ +} while (0) + +#endif // _MSC_VER + +#define SCANINC_MAX_PATH 255 + +#endif // SCANINC_H -- 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/Makefile | 2 +- tools/preproc/c_file.cpp | 4 ++-- tools/preproc/c_file.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/preproc/Makefile b/tools/preproc/Makefile index 2d577c79f..24f60e3f6 100644 --- a/tools/preproc/Makefile +++ b/tools/preproc/Makefile @@ -1,6 +1,6 @@ CXX := g++ -CXXFLAGS := -std=c++11 -O2 -Wall -Wno-switch +CXXFLAGS := -std=c++14 -O2 -Wall -Wno-switch SRCS := asm_file.cpp c_file.cpp charmap.cpp preproc.cpp string_parser.cpp \ utf8.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; diff --git a/tools/preproc/c_file.h b/tools/preproc/c_file.h index ddd57fd84..7369aba85 100644 --- a/tools/preproc/c_file.h +++ b/tools/preproc/c_file.h @@ -47,7 +47,7 @@ private: bool ConsumeNewline(); void SkipWhitespace(); void TryConvertString(); - std::unique_ptr CFile::ReadWholeFile(const std::string& path, int& size); + std::unique_ptr ReadWholeFile(const std::string& path, int& size); bool CheckIdentifier(const std::string& ident); void TryConvertIncbin(); void ReportDiagnostic(const char* type, const char* format, std::va_list args); -- cgit v1.2.3 From 72bc8f23d37c6efd68ad4a0f86ba87b6cd3db4d2 Mon Sep 17 00:00:00 2001 From: Cameron Hall Date: Thu, 26 Jan 2017 01:15:49 -0500 Subject: make scaninc build under GCC (#218) --- tools/scaninc/Makefile | 2 +- tools/scaninc/c_file.cpp | 4 ++-- tools/scaninc/c_file.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/scaninc/Makefile b/tools/scaninc/Makefile index 71c4389ef..c408e4a6e 100644 --- a/tools/scaninc/Makefile +++ b/tools/scaninc/Makefile @@ -1,6 +1,6 @@ CXX = g++ -CXXFLAGS = -Wall -std=c++11 -O2 +CXXFLAGS = -Wall -std=c++14 -O2 SRCS = scaninc.cpp c_file.cpp asm_file.cpp diff --git a/tools/scaninc/c_file.cpp b/tools/scaninc/c_file.cpp index 4af741f6e..970fbe135 100644 --- a/tools/scaninc/c_file.cpp +++ b/tools/scaninc/c_file.cpp @@ -202,9 +202,9 @@ void CFile::SkipWhitespace() 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; diff --git a/tools/scaninc/c_file.h b/tools/scaninc/c_file.h index fcd327d28..2503acac1 100644 --- a/tools/scaninc/c_file.h +++ b/tools/scaninc/c_file.h @@ -42,11 +42,11 @@ private: std::string m_path; std::set m_incbins; - void CFile::RemoveComments(); + void RemoveComments(); bool ConsumeHorizontalWhitespace(); bool ConsumeNewline(); void SkipWhitespace(); - std::unique_ptr CFile::ReadWholeFile(const std::string& path, int& size); + std::unique_ptr ReadWholeFile(const std::string& path, int& size); bool CheckIdentifier(const std::string& ident); void CheckIncbin(); }; -- 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/Makefile | 2 +- tools/preproc/c_file.cpp | 2 +- tools/scaninc/Makefile | 2 +- tools/scaninc/c_file.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/preproc/Makefile b/tools/preproc/Makefile index 24f60e3f6..2d577c79f 100644 --- a/tools/preproc/Makefile +++ b/tools/preproc/Makefile @@ -1,6 +1,6 @@ CXX := g++ -CXXFLAGS := -std=c++14 -O2 -Wall -Wno-switch +CXXFLAGS := -std=c++11 -O2 -Wall -Wno-switch SRCS := asm_file.cpp c_file.cpp charmap.cpp preproc.cpp string_parser.cpp \ utf8.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); diff --git a/tools/scaninc/Makefile b/tools/scaninc/Makefile index c408e4a6e..71c4389ef 100644 --- a/tools/scaninc/Makefile +++ b/tools/scaninc/Makefile @@ -1,6 +1,6 @@ CXX = g++ -CXXFLAGS = -Wall -std=c++14 -O2 +CXXFLAGS = -Wall -std=c++11 -O2 SRCS = scaninc.cpp c_file.cpp asm_file.cpp diff --git a/tools/scaninc/c_file.cpp b/tools/scaninc/c_file.cpp index 970fbe135..bb84fedbe 100644 --- a/tools/scaninc/c_file.cpp +++ b/tools/scaninc/c_file.cpp @@ -222,7 +222,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/asm_file.cpp | 2 +- tools/preproc/c_file.cpp | 16 +++++++------- tools/preproc/preproc.cpp | 14 ++++++------ tools/scaninc/asm_file.cpp | 12 +++++------ tools/scaninc/c_file.cpp | 54 ++++++---------------------------------------- tools/scaninc/c_file.h | 1 - tools/scaninc/scaninc.cpp | 6 +++--- 7 files changed, 31 insertions(+), 74 deletions(-) (limited to 'tools') diff --git a/tools/preproc/asm_file.cpp b/tools/preproc/asm_file.cpp index 49c9e3c66..bb296b78b 100644 --- a/tools/preproc/asm_file.cpp +++ b/tools/preproc/asm_file.cpp @@ -494,7 +494,7 @@ bool AsmFile::IsAtEnd() // Output the current location to set gas's logical file and line numbers. void AsmFile::OutputLocation() { - printf("# %ld \"%s\"\n", m_lineNum, m_filename.c_str()); + std::printf("# %ld \"%s\"\n", m_lineNum, m_filename.c_str()); } // Reports a diagnostic message. 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("}"); diff --git a/tools/preproc/preproc.cpp b/tools/preproc/preproc.cpp index b51861580..8320a2d27 100644 --- a/tools/preproc/preproc.cpp +++ b/tools/preproc/preproc.cpp @@ -31,15 +31,15 @@ void PrintAsmBytes(unsigned char *s, int length) { if (length > 0) { - printf("\t.byte "); + std::printf("\t.byte "); for (int i = 0; i < length; i++) { - printf("0x%02X", s[i]); + std::printf("0x%02X", s[i]); if (i < length - 1) - printf(", "); + std::printf(", "); } - putchar('\n'); + std::putchar('\n'); } } @@ -89,8 +89,8 @@ void PreprocAsmFile(std::string filename) if (globalLabel.length() != 0) { - printf("\t.global %s\n", globalLabel.c_str()); - printf("%s:\n", globalLabel.c_str()); + std::printf("\t.global %s\n", globalLabel.c_str()); + std::printf("%s:\n", globalLabel.c_str()); } else { @@ -134,7 +134,7 @@ int main(int argc, char **argv) { if (argc != 3) { - fprintf(stderr, "Usage: %s SRC_FILE CHARMAP_FILE", argv[0]); + std::fprintf(stderr, "Usage: %s SRC_FILE CHARMAP_FILE", argv[0]); return 1; } diff --git a/tools/scaninc/asm_file.cpp b/tools/scaninc/asm_file.cpp index 143c70242..c3d140bb1 100644 --- a/tools/scaninc/asm_file.cpp +++ b/tools/scaninc/asm_file.cpp @@ -27,23 +27,23 @@ AsmFile::AsmFile(std::string path) { m_path = path; - FILE *fp = fopen(path.c_str(), "rb"); + FILE *fp = std::fopen(path.c_str(), "rb"); if (fp == NULL) FATAL_ERROR("Failed to open \"%s\" for reading.\n", path.c_str()); - fseek(fp, 0, SEEK_END); + std::fseek(fp, 0, SEEK_END); - m_size = ftell(fp); + m_size = std::ftell(fp); m_buffer = new char[m_size]; - rewind(fp); + std::rewind(fp); - if (fread(m_buffer, m_size, 1, fp) != 1) + if (std::fread(m_buffer, m_size, 1, fp) != 1) FATAL_ERROR("Failed to read \"%s\".\n", path.c_str()); - fclose(fp); + std::fclose(fp); m_pos = 0; m_lineNum = 1; diff --git a/tools/scaninc/c_file.cpp b/tools/scaninc/c_file.cpp index bb84fedbe..b82276dd6 100644 --- a/tools/scaninc/c_file.cpp +++ b/tools/scaninc/c_file.cpp @@ -24,24 +24,24 @@ CFile::CFile(std::string path) { m_path = path; - FILE *fp = fopen(path.c_str(), "rb"); + FILE *fp = std::fopen(path.c_str(), "rb"); if (fp == NULL) FATAL_ERROR("Failed to open \"%s\" for reading.\n", path.c_str()); - fseek(fp, 0, SEEK_END); + std::fseek(fp, 0, SEEK_END); - m_size = ftell(fp); + m_size = std::ftell(fp); m_buffer = new char[m_size + 1]; m_buffer[m_size] = 0; - rewind(fp); + std::rewind(fp); - if (fread(m_buffer, m_size, 1, fp) != 1) + if (std::fread(m_buffer, m_size, 1, fp) != 1) FATAL_ERROR("Failed to read \"%s\".\n", path.c_str()); - fclose(fp); + std::fclose(fp); m_pos = 0; m_lineNum = 1; @@ -211,48 +211,6 @@ bool CFile::CheckIdentifier(const std::string& ident) 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) - FATAL_INPUT_ERROR("Failed to open \"%s\" for reading.\n", path.c_str()); - - fseek(fp, 0, SEEK_END); - - size = ftell(fp); - - std::unique_ptr buffer = std::unique_ptr(new unsigned char[size]); - - rewind(fp); - - if (fread(buffer.get(), size, 1, fp) != 1) - FATAL_INPUT_ERROR("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::CheckIncbin() { std::string idents[6] = { "INCBIN_S8", "INCBIN_U8", "INCBIN_S16", "INCBIN_U16", "INCBIN_S32", "INCBIN_U32" }; diff --git a/tools/scaninc/c_file.h b/tools/scaninc/c_file.h index 2503acac1..922cb4639 100644 --- a/tools/scaninc/c_file.h +++ b/tools/scaninc/c_file.h @@ -46,7 +46,6 @@ private: bool ConsumeHorizontalWhitespace(); bool ConsumeNewline(); void SkipWhitespace(); - std::unique_ptr ReadWholeFile(const std::string& path, int& size); bool CheckIdentifier(const std::string& ident); void CheckIncbin(); }; diff --git a/tools/scaninc/scaninc.cpp b/tools/scaninc/scaninc.cpp index 2f9ed81e9..b6f7ba767 100644 --- a/tools/scaninc/scaninc.cpp +++ b/tools/scaninc/scaninc.cpp @@ -29,12 +29,12 @@ bool CanOpenFile(std::string path) { - FILE *fp = fopen(path.c_str(), "rb"); + FILE *fp = std::fopen(path.c_str(), "rb"); if (fp == NULL) return false; - fclose(fp); + std::fclose(fp); return true; } @@ -92,6 +92,6 @@ int main(int argc, char **argv) for (const std::string &path : dependencies) { - printf("%s\n", path.c_str()); + std::printf("%s\n", path.c_str()); } } -- cgit v1.2.3