diff options
Diffstat (limited to 'tools/scaninc')
-rw-r--r-- | tools/scaninc/.gitignore | 2 | ||||
-rw-r--r-- | tools/scaninc/LICENSE | 38 | ||||
-rw-r--r-- | tools/scaninc/asm_file.cpp | 384 | ||||
-rw-r--r-- | tools/scaninc/c_file.cpp | 614 | ||||
-rw-r--r-- | tools/scaninc/scaninc.cpp | 256 | ||||
-rw-r--r-- | tools/scaninc/source_file.cpp | 260 |
6 files changed, 777 insertions, 777 deletions
diff --git a/tools/scaninc/.gitignore b/tools/scaninc/.gitignore index 94bfbf9..a167a08 100644 --- a/tools/scaninc/.gitignore +++ b/tools/scaninc/.gitignore @@ -1 +1 @@ -scaninc +scaninc
diff --git a/tools/scaninc/LICENSE b/tools/scaninc/LICENSE index b66bf81..01c9d12 100644 --- a/tools/scaninc/LICENSE +++ b/tools/scaninc/LICENSE @@ -1,19 +1,19 @@ -Copyright (c) 2015 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. +Copyright (c) 2015 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.
diff --git a/tools/scaninc/asm_file.cpp b/tools/scaninc/asm_file.cpp index 109e604..e94d678 100644 --- a/tools/scaninc/asm_file.cpp +++ b/tools/scaninc/asm_file.cpp @@ -1,192 +1,192 @@ -// 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 <cstdio> -#include <string> -#include "scaninc.h" -#include "asm_file.h" - -AsmFile::AsmFile(std::string path) -{ - m_path = path; - - FILE *fp = std::fopen(path.c_str(), "rb"); - - if (fp == NULL) - FATAL_ERROR("Failed to open \"%s\" for reading.\n", path.c_str()); - - std::fseek(fp, 0, SEEK_END); - - m_size = std::ftell(fp); - - m_buffer = new char[m_size]; - - std::rewind(fp); - - if (std::fread(m_buffer, m_size, 1, fp) != 1) - FATAL_ERROR("Failed to read \"%s\".\n", path.c_str()); - - std::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; - - char c = PeekChar(); - if (c == '.' || c == '#') - { - 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(); - } - } -} +// 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 <cstdio>
+#include <string>
+#include "scaninc.h"
+#include "asm_file.h"
+
+AsmFile::AsmFile(std::string path)
+{
+ m_path = path;
+
+ FILE *fp = std::fopen(path.c_str(), "rb");
+
+ if (fp == NULL)
+ FATAL_ERROR("Failed to open \"%s\" for reading.\n", path.c_str());
+
+ std::fseek(fp, 0, SEEK_END);
+
+ m_size = std::ftell(fp);
+
+ m_buffer = new char[m_size];
+
+ std::rewind(fp);
+
+ if (std::fread(m_buffer, m_size, 1, fp) != 1)
+ FATAL_ERROR("Failed to read \"%s\".\n", path.c_str());
+
+ std::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;
+
+ char c = PeekChar();
+ if (c == '.' || c == '#')
+ {
+ 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/c_file.cpp b/tools/scaninc/c_file.cpp index 595f366..e3cd988 100644 --- a/tools/scaninc/c_file.cpp +++ b/tools/scaninc/c_file.cpp @@ -1,307 +1,307 @@ -// 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 = std::fopen(path.c_str(), "rb"); - - if (fp == NULL) - FATAL_ERROR("Failed to open \"%s\" for reading.\n", path.c_str()); - - std::fseek(fp, 0, SEEK_END); - - m_size = std::ftell(fp); - - m_buffer = new char[m_size + 1]; - m_buffer[m_size] = 0; - - std::rewind(fp); - - if (std::fread(m_buffer, m_size, 1, fp) != 1) - FATAL_ERROR("Failed to read \"%s\".\n", path.c_str()); - - std::fclose(fp); - - m_pos = 0; - m_lineNum = 1; -} - -CFile::~CFile() -{ - delete[] m_buffer; -} - -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 - { - SkipWhitespace(); - CheckInclude(); - 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] == '\n') - { - m_pos++; - m_lineNum++; - return true; - } - - if (m_buffer[m_pos] == '\r' && m_buffer[m_pos + 1] == '\n') - { - m_pos += 2; - m_lineNum++; - return true; - } - - return false; -} - -bool CFile::ConsumeComment() -{ - if (m_buffer[m_pos] == '/' && m_buffer[m_pos + 1] == '*') - { - m_pos += 2; - while (m_buffer[m_pos] != '*' || m_buffer[m_pos + 1] != '/') - { - if (m_buffer[m_pos] == 0) - return false; - if (!ConsumeNewline()) - m_pos++; - } - m_pos += 2; - return true; - } - else if (m_buffer[m_pos] == '/' && m_buffer[m_pos + 1] == '/') - { - m_pos += 2; - while (!ConsumeNewline()) - { - if (m_buffer[m_pos] == 0) - return false; - m_pos++; - } - return true; - } - - return false; -} - -void CFile::SkipWhitespace() -{ - while (ConsumeHorizontalWhitespace() || ConsumeNewline() || ConsumeComment()) - ; -} - -bool CFile::CheckIdentifier(const std::string& ident) -{ - unsigned int i; - - for (i = 0; i < ident.length() && m_pos + i < (unsigned)m_size; i++) - if (ident[i] != m_buffer[m_pos + i]) - return false; - - return (i == ident.length()); -} - -void CFile::CheckInclude() -{ - if (m_buffer[m_pos] != '#') - return; - - std::string ident = "#include"; - - if (!CheckIdentifier(ident)) - { - return; - } - - m_pos += ident.length(); - - ConsumeHorizontalWhitespace(); - - std::string path = ReadPath(); - - if (!path.empty()) { - m_includes.emplace(path); - } -} - -void CFile::CheckIncbin() -{ - // Optimization: assume most lines are not incbins - if (!(m_buffer[m_pos+0] == 'I' - && m_buffer[m_pos+1] == 'N' - && m_buffer[m_pos+2] == 'C' - && m_buffer[m_pos+3] == 'B' - && m_buffer[m_pos+4] == 'I' - && m_buffer[m_pos+5] == 'N' - && m_buffer[m_pos+6] == '_')) - { - return; - } - - 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++; - - while (true) - { - SkipWhitespace(); - - std::string path = ReadPath(); - - SkipWhitespace(); - - m_incbins.emplace(path); - - if (m_buffer[m_pos] != ',') - break; - - m_pos++; - } - - if (m_buffer[m_pos] != ')') - FATAL_INPUT_ERROR("expected ')'"); - - m_pos++; - -} - -std::string CFile::ReadPath() -{ - if (m_buffer[m_pos] != '"') - { - if (m_buffer[m_pos] == '<') - { - return std::string(); - } - FATAL_INPUT_ERROR("expected '\"' or '<'"); - } - - 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++; - } - - m_pos++; - - return std::string(m_buffer + startPos, m_pos - 1 - startPos); -} +// 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 = std::fopen(path.c_str(), "rb");
+
+ if (fp == NULL)
+ FATAL_ERROR("Failed to open \"%s\" for reading.\n", path.c_str());
+
+ std::fseek(fp, 0, SEEK_END);
+
+ m_size = std::ftell(fp);
+
+ m_buffer = new char[m_size + 1];
+ m_buffer[m_size] = 0;
+
+ std::rewind(fp);
+
+ if (std::fread(m_buffer, m_size, 1, fp) != 1)
+ FATAL_ERROR("Failed to read \"%s\".\n", path.c_str());
+
+ std::fclose(fp);
+
+ m_pos = 0;
+ m_lineNum = 1;
+}
+
+CFile::~CFile()
+{
+ delete[] m_buffer;
+}
+
+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
+ {
+ SkipWhitespace();
+ CheckInclude();
+ 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] == '\n')
+ {
+ m_pos++;
+ m_lineNum++;
+ return true;
+ }
+
+ if (m_buffer[m_pos] == '\r' && m_buffer[m_pos + 1] == '\n')
+ {
+ m_pos += 2;
+ m_lineNum++;
+ return true;
+ }
+
+ return false;
+}
+
+bool CFile::ConsumeComment()
+{
+ if (m_buffer[m_pos] == '/' && m_buffer[m_pos + 1] == '*')
+ {
+ m_pos += 2;
+ while (m_buffer[m_pos] != '*' || m_buffer[m_pos + 1] != '/')
+ {
+ if (m_buffer[m_pos] == 0)
+ return false;
+ if (!ConsumeNewline())
+ m_pos++;
+ }
+ m_pos += 2;
+ return true;
+ }
+ else if (m_buffer[m_pos] == '/' && m_buffer[m_pos + 1] == '/')
+ {
+ m_pos += 2;
+ while (!ConsumeNewline())
+ {
+ if (m_buffer[m_pos] == 0)
+ return false;
+ m_pos++;
+ }
+ return true;
+ }
+
+ return false;
+}
+
+void CFile::SkipWhitespace()
+{
+ while (ConsumeHorizontalWhitespace() || ConsumeNewline() || ConsumeComment())
+ ;
+}
+
+bool CFile::CheckIdentifier(const std::string& ident)
+{
+ unsigned int i;
+
+ for (i = 0; i < ident.length() && m_pos + i < (unsigned)m_size; i++)
+ if (ident[i] != m_buffer[m_pos + i])
+ return false;
+
+ return (i == ident.length());
+}
+
+void CFile::CheckInclude()
+{
+ if (m_buffer[m_pos] != '#')
+ return;
+
+ std::string ident = "#include";
+
+ if (!CheckIdentifier(ident))
+ {
+ return;
+ }
+
+ m_pos += ident.length();
+
+ ConsumeHorizontalWhitespace();
+
+ std::string path = ReadPath();
+
+ if (!path.empty()) {
+ m_includes.emplace(path);
+ }
+}
+
+void CFile::CheckIncbin()
+{
+ // Optimization: assume most lines are not incbins
+ if (!(m_buffer[m_pos+0] == 'I'
+ && m_buffer[m_pos+1] == 'N'
+ && m_buffer[m_pos+2] == 'C'
+ && m_buffer[m_pos+3] == 'B'
+ && m_buffer[m_pos+4] == 'I'
+ && m_buffer[m_pos+5] == 'N'
+ && m_buffer[m_pos+6] == '_'))
+ {
+ return;
+ }
+
+ 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++;
+
+ while (true)
+ {
+ SkipWhitespace();
+
+ std::string path = ReadPath();
+
+ SkipWhitespace();
+
+ m_incbins.emplace(path);
+
+ if (m_buffer[m_pos] != ',')
+ break;
+
+ m_pos++;
+ }
+
+ if (m_buffer[m_pos] != ')')
+ FATAL_INPUT_ERROR("expected ')'");
+
+ m_pos++;
+
+}
+
+std::string CFile::ReadPath()
+{
+ if (m_buffer[m_pos] != '"')
+ {
+ if (m_buffer[m_pos] == '<')
+ {
+ return std::string();
+ }
+ FATAL_INPUT_ERROR("expected '\"' or '<'");
+ }
+
+ 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++;
+ }
+
+ m_pos++;
+
+ return std::string(m_buffer + startPos, m_pos - 1 - startPos);
+}
diff --git a/tools/scaninc/scaninc.cpp b/tools/scaninc/scaninc.cpp index a3e40c5..a91b872 100644 --- a/tools/scaninc/scaninc.cpp +++ b/tools/scaninc/scaninc.cpp @@ -1,128 +1,128 @@ -// 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 <cstdio> -#include <cstdlib> -#include <list> -#include <queue> -#include <set> -#include <string> -#include "scaninc.h" -#include "source_file.h" - -bool CanOpenFile(std::string path) -{ - FILE *fp = std::fopen(path.c_str(), "rb"); - - if (fp == NULL) - return false; - - std::fclose(fp); - return true; -} - -const char *const USAGE = "Usage: scaninc [-I INCLUDE_PATH] FILE_PATH\n"; - -int main(int argc, char **argv) -{ - std::queue<std::string> filesToProcess; - std::set<std::string> dependencies; - - std::vector<std::string> includeDirs; - - argc--; - argv++; - - while (argc > 1) - { - std::string arg(argv[0]); - if (arg.substr(0, 2) == "-I") - { - std::string includeDir = arg.substr(2); - if (includeDir.empty()) - { - argc--; - argv++; - includeDir = std::string(argv[0]); - } - if (!includeDir.empty() && includeDir.back() != '/') - { - includeDir += '/'; - } - includeDirs.push_back(includeDir); - } - else - { - FATAL_ERROR(USAGE); - } - argc--; - argv++; - } - - if (argc != 1) { - FATAL_ERROR(USAGE); - } - - std::string initialPath(argv[0]); - - filesToProcess.push(initialPath); - - while (!filesToProcess.empty()) - { - std::string filePath = filesToProcess.front(); - SourceFile file(filePath); - filesToProcess.pop(); - - includeDirs.push_back(file.GetSrcDir()); - for (auto incbin : file.GetIncbins()) - { - dependencies.insert(incbin); - } - for (auto include : file.GetIncludes()) - { - bool exists = false; - std::string path(""); - for (auto includeDir : includeDirs) - { - path = includeDir + include; - if (CanOpenFile(path)) - { - exists = true; - break; - } - } - if (!exists && file.FileType() == SourceFileType::Asm) - { - path = include; - } - bool inserted = dependencies.insert(path).second; - if (inserted && exists) - { - filesToProcess.push(path); - } - } - includeDirs.pop_back(); - } - - for (const std::string &path : dependencies) - { - std::printf("%s\n", path.c_str()); - } -} +// 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 <cstdio>
+#include <cstdlib>
+#include <list>
+#include <queue>
+#include <set>
+#include <string>
+#include "scaninc.h"
+#include "source_file.h"
+
+bool CanOpenFile(std::string path)
+{
+ FILE *fp = std::fopen(path.c_str(), "rb");
+
+ if (fp == NULL)
+ return false;
+
+ std::fclose(fp);
+ return true;
+}
+
+const char *const USAGE = "Usage: scaninc [-I INCLUDE_PATH] FILE_PATH\n";
+
+int main(int argc, char **argv)
+{
+ std::queue<std::string> filesToProcess;
+ std::set<std::string> dependencies;
+
+ std::vector<std::string> includeDirs;
+
+ argc--;
+ argv++;
+
+ while (argc > 1)
+ {
+ std::string arg(argv[0]);
+ if (arg.substr(0, 2) == "-I")
+ {
+ std::string includeDir = arg.substr(2);
+ if (includeDir.empty())
+ {
+ argc--;
+ argv++;
+ includeDir = std::string(argv[0]);
+ }
+ if (!includeDir.empty() && includeDir.back() != '/')
+ {
+ includeDir += '/';
+ }
+ includeDirs.push_back(includeDir);
+ }
+ else
+ {
+ FATAL_ERROR(USAGE);
+ }
+ argc--;
+ argv++;
+ }
+
+ if (argc != 1) {
+ FATAL_ERROR(USAGE);
+ }
+
+ std::string initialPath(argv[0]);
+
+ filesToProcess.push(initialPath);
+
+ while (!filesToProcess.empty())
+ {
+ std::string filePath = filesToProcess.front();
+ SourceFile file(filePath);
+ filesToProcess.pop();
+
+ includeDirs.push_back(file.GetSrcDir());
+ for (auto incbin : file.GetIncbins())
+ {
+ dependencies.insert(incbin);
+ }
+ for (auto include : file.GetIncludes())
+ {
+ bool exists = false;
+ std::string path("");
+ for (auto includeDir : includeDirs)
+ {
+ path = includeDir + include;
+ if (CanOpenFile(path))
+ {
+ exists = true;
+ break;
+ }
+ }
+ if (!exists && file.FileType() == SourceFileType::Asm)
+ {
+ path = include;
+ }
+ bool inserted = dependencies.insert(path).second;
+ if (inserted && exists)
+ {
+ filesToProcess.push(path);
+ }
+ }
+ includeDirs.pop_back();
+ }
+
+ for (const std::string &path : dependencies)
+ {
+ std::printf("%s\n", path.c_str());
+ }
+}
diff --git a/tools/scaninc/source_file.cpp b/tools/scaninc/source_file.cpp index df31282..255c818 100644 --- a/tools/scaninc/source_file.cpp +++ b/tools/scaninc/source_file.cpp @@ -1,130 +1,130 @@ -// Copyright(c) 2019 Phlosioneer -// -// 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 <new> -#include "source_file.h" - - -SourceFileType GetFileType(std::string& path) -{ - std::size_t pos = path.find_last_of('.'); - - if (pos == std::string::npos) - FATAL_ERROR("no file extension in path \"%s\"\n", path.c_str()); - - std::string extension = path.substr(pos + 1); - - if (extension == "c") - return SourceFileType::Cpp; - else if (extension == "s") - return SourceFileType::Asm; - else if (extension == "h") - return SourceFileType::Header; - else if (extension == "inc") - return SourceFileType::Inc; - else - FATAL_ERROR("Unrecognized extension \"%s\"\n", extension.c_str()); - - // Unreachable - return SourceFileType::Cpp; -} - -std::string GetDir(std::string& path) -{ - std::size_t slash = path.rfind('/'); - - if (slash != std::string::npos) - return path.substr(0, slash + 1); - else - return std::string(""); -} - -SourceFile::SourceFile(std::string path) -{ - m_file_type = GetFileType(path); - - m_src_dir = GetDir(path); - - if (m_file_type == SourceFileType::Cpp - || m_file_type == SourceFileType::Header) - { - new (&m_source_file.c_file) CFile(path); - m_source_file.c_file.FindIncbins(); - } - else - { - AsmFile file(path); - std::set<std::string> incbins; - std::set<std::string> includes; - - IncDirectiveType incDirectiveType; - std::string outputPath; - - while ((incDirectiveType = file.ReadUntilIncDirective(outputPath)) != IncDirectiveType::None) - { - if (incDirectiveType == IncDirectiveType::Include) - includes.insert(outputPath); - else - incbins.insert(outputPath); - } - - new (&m_source_file.asm_wrapper) SourceFile::InnerUnion::AsmWrapper{incbins, includes}; - } -} - -SourceFileType SourceFile::FileType() -{ - return m_file_type; -} - -SourceFile::~SourceFile() -{ - if (m_file_type == SourceFileType::Cpp || m_file_type == SourceFileType::Header) - { - m_source_file.c_file.~CFile(); - } - else - { - m_source_file.asm_wrapper.asm_incbins.~set(); - m_source_file.asm_wrapper.asm_includes.~set(); - } -} - -const std::set<std::string>& SourceFile::GetIncbins() -{ - if (m_file_type == SourceFileType::Cpp || m_file_type == SourceFileType::Header) - return m_source_file.c_file.GetIncbins(); - else - return m_source_file.asm_wrapper.asm_incbins; -} - -const std::set<std::string>& SourceFile::GetIncludes() -{ - if (m_file_type == SourceFileType::Cpp || m_file_type == SourceFileType::Header) - return m_source_file.c_file.GetIncludes(); - else - return m_source_file.asm_wrapper.asm_includes; -} - -std::string& SourceFile::GetSrcDir() -{ - return m_src_dir; -} - +// Copyright(c) 2019 Phlosioneer
+//
+// 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 <new>
+#include "source_file.h"
+
+
+SourceFileType GetFileType(std::string& path)
+{
+ std::size_t pos = path.find_last_of('.');
+
+ if (pos == std::string::npos)
+ FATAL_ERROR("no file extension in path \"%s\"\n", path.c_str());
+
+ std::string extension = path.substr(pos + 1);
+
+ if (extension == "c")
+ return SourceFileType::Cpp;
+ else if (extension == "s")
+ return SourceFileType::Asm;
+ else if (extension == "h")
+ return SourceFileType::Header;
+ else if (extension == "inc")
+ return SourceFileType::Inc;
+ else
+ FATAL_ERROR("Unrecognized extension \"%s\"\n", extension.c_str());
+
+ // Unreachable
+ return SourceFileType::Cpp;
+}
+
+std::string GetDir(std::string& path)
+{
+ std::size_t slash = path.rfind('/');
+
+ if (slash != std::string::npos)
+ return path.substr(0, slash + 1);
+ else
+ return std::string("");
+}
+
+SourceFile::SourceFile(std::string path)
+{
+ m_file_type = GetFileType(path);
+
+ m_src_dir = GetDir(path);
+
+ if (m_file_type == SourceFileType::Cpp
+ || m_file_type == SourceFileType::Header)
+ {
+ new (&m_source_file.c_file) CFile(path);
+ m_source_file.c_file.FindIncbins();
+ }
+ else
+ {
+ AsmFile file(path);
+ std::set<std::string> incbins;
+ std::set<std::string> includes;
+
+ IncDirectiveType incDirectiveType;
+ std::string outputPath;
+
+ while ((incDirectiveType = file.ReadUntilIncDirective(outputPath)) != IncDirectiveType::None)
+ {
+ if (incDirectiveType == IncDirectiveType::Include)
+ includes.insert(outputPath);
+ else
+ incbins.insert(outputPath);
+ }
+
+ new (&m_source_file.asm_wrapper) SourceFile::InnerUnion::AsmWrapper{incbins, includes};
+ }
+}
+
+SourceFileType SourceFile::FileType()
+{
+ return m_file_type;
+}
+
+SourceFile::~SourceFile()
+{
+ if (m_file_type == SourceFileType::Cpp || m_file_type == SourceFileType::Header)
+ {
+ m_source_file.c_file.~CFile();
+ }
+ else
+ {
+ m_source_file.asm_wrapper.asm_incbins.~set();
+ m_source_file.asm_wrapper.asm_includes.~set();
+ }
+}
+
+const std::set<std::string>& SourceFile::GetIncbins()
+{
+ if (m_file_type == SourceFileType::Cpp || m_file_type == SourceFileType::Header)
+ return m_source_file.c_file.GetIncbins();
+ else
+ return m_source_file.asm_wrapper.asm_incbins;
+}
+
+const std::set<std::string>& SourceFile::GetIncludes()
+{
+ if (m_file_type == SourceFileType::Cpp || m_file_type == SourceFileType::Header)
+ return m_source_file.c_file.GetIncludes();
+ else
+ return m_source_file.asm_wrapper.asm_includes;
+}
+
+std::string& SourceFile::GetSrcDir()
+{
+ return m_src_dir;
+}
+
|