From 0faa6c9c93804c4ce0e6fc8e5a6d5cfbc85f01da Mon Sep 17 00:00:00 2001 From: yenatch Date: Sat, 22 Jul 2017 18:49:38 -0400 Subject: scaninc: read c includes Now editing .h files triggers a rebuild. Also allow .h and .inc files to be passed as a main argument. src/ and include/ are temporarily hardcoded. --- tools/scaninc/c_file.cpp | 57 ++++++++++++++++++++++++++++++++++++++--------- tools/scaninc/c_file.h | 4 ++++ tools/scaninc/scaninc.cpp | 41 +++++++++++++++++++++++++++++----- 3 files changed, 85 insertions(+), 17 deletions(-) (limited to 'tools') diff --git a/tools/scaninc/c_file.cpp b/tools/scaninc/c_file.cpp index b82276dd6..2dd400967 100644 --- a/tools/scaninc/c_file.cpp +++ b/tools/scaninc/c_file.cpp @@ -145,6 +145,7 @@ void CFile::FindIncbins() } else { + CheckInclude(); CheckIncbin(); if (m_pos >= m_size) @@ -211,6 +212,29 @@ bool CFile::CheckIdentifier(const std::string& ident) 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() { std::string idents[6] = { "INCBIN_S8", "INCBIN_U8", "INCBIN_S16", "INCBIN_U16", "INCBIN_S32", "INCBIN_U32" }; @@ -246,8 +270,28 @@ void CFile::CheckIncbin() SkipWhitespace(); + std::string path = ReadPath(); + + SkipWhitespace(); + + if (m_buffer[m_pos] != ')') + FATAL_INPUT_ERROR("expected ')'"); + + m_pos++; + + m_incbins.emplace(path); +} + +std::string CFile::ReadPath() +{ if (m_buffer[m_pos] != '"') - FATAL_INPUT_ERROR("expected double quote"); + { + if (m_buffer[m_pos] == '<') + { + return std::string(); + } + FATAL_INPUT_ERROR("expected '\"' or '<'"); + } m_pos++; @@ -272,16 +316,7 @@ void CFile::CheckIncbin() 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); + return std::string(m_buffer, startPos, m_pos - 1 - startPos); } diff --git a/tools/scaninc/c_file.h b/tools/scaninc/c_file.h index 922cb4639..38b10f04e 100644 --- a/tools/scaninc/c_file.h +++ b/tools/scaninc/c_file.h @@ -33,6 +33,7 @@ public: ~CFile(); void FindIncbins(); const std::set& GetIncbins() { return m_incbins; } + const std::set& GetIncludes() { return m_includes; } private: char *m_buffer; @@ -41,13 +42,16 @@ private: int m_lineNum; std::string m_path; std::set m_incbins; + std::set m_includes; void RemoveComments(); bool ConsumeHorizontalWhitespace(); bool ConsumeNewline(); void SkipWhitespace(); bool CheckIdentifier(const std::string& ident); + void CheckInclude(); void CheckIncbin(); + std::string ReadPath(); }; #endif // C_FILE_H diff --git a/tools/scaninc/scaninc.cpp b/tools/scaninc/scaninc.cpp index b6f7ba767..10cb06eee 100644 --- a/tools/scaninc/scaninc.cpp +++ b/tools/scaninc/scaninc.cpp @@ -55,16 +55,45 @@ int main(int argc, char **argv) std::string extension = initialPath.substr(pos + 1); - if (extension == "c") + std::string srcDir("src/"); + std::string includeDir("include/"); + + if (extension == "c" || extension == "h") { - CFile file(initialPath); + filesToProcess.push(initialPath); + + while (!filesToProcess.empty()) + { + CFile file(filesToProcess.top()); + filesToProcess.pop(); - file.FindIncbins(); - dependencies = file.GetIncbins(); + file.FindIncbins(); + for (auto incbin : file.GetIncbins()) + { + dependencies.insert(incbin); + } + for (auto include : file.GetIncludes()) + { + std::string path(srcDir + include); + if (!CanOpenFile(path)) + { + path = includeDir + include; + } + + if (CanOpenFile(path)) + { + bool inserted = dependencies.insert(path).second; + if (inserted) + { + filesToProcess.push(path); + } + } + } + } } - else if (extension == "s") + else if (extension == "s" || extension == "inc") { - filesToProcess.push(std::string(argv[1])); + filesToProcess.push(initialPath); while (!filesToProcess.empty()) { -- cgit v1.2.3 From 7451ea31c62604cc3a96fa9c4123aea3cc5b5cb6 Mon Sep 17 00:00:00 2001 From: yenatch Date: Sun, 23 Jul 2017 21:44:37 -0400 Subject: scaninc: add -I and stop hardcoding include paths --- tools/scaninc/scaninc.cpp | 49 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/scaninc/scaninc.cpp b/tools/scaninc/scaninc.cpp index 10cb06eee..2d91db646 100644 --- a/tools/scaninc/scaninc.cpp +++ b/tools/scaninc/scaninc.cpp @@ -38,15 +38,48 @@ bool CanOpenFile(std::string path) return true; } +const char *const USAGE = "Usage: scaninc [-I INCLUDE_PATH] FILE_PATH\n"; + int main(int argc, char **argv) { - if (argc < 2) - FATAL_ERROR("Usage: scaninc FILE_PATH\n"); - std::stack filesToProcess; std::set dependencies; - std::string initialPath(argv[1]); + std::string includeDir(""); + + argc--; + argv++; + + while (argc > 1) + { + std::string arg(argv[0]); + if (arg.substr(0, 2) == "-I") + { + includeDir = arg.substr(2); + if (includeDir.empty()) + { + argc--; + argv++; + includeDir = std::string(argv[0]); + } + if (includeDir.back() != '/') + { + includeDir += '/'; + } + } + else + { + FATAL_ERROR(USAGE); + } + argc--; + argv++; + } + + if (argc != 1) { + FATAL_ERROR(USAGE); + } + + std::string initialPath(argv[0]); std::size_t pos = initialPath.find_last_of('.'); @@ -55,8 +88,12 @@ int main(int argc, char **argv) std::string extension = initialPath.substr(pos + 1); - std::string srcDir("src/"); - std::string includeDir("include/"); + std::string srcDir(""); + std::size_t slash = initialPath.rfind('/'); + if (slash != std::string::npos) + { + srcDir = initialPath.substr(0, slash + 1); + } if (extension == "c" || extension == "h") { -- cgit v1.2.3 From 89c9c19446843c978485f67eeaa3d55ac26a15ec Mon Sep 17 00:00:00 2001 From: yenatch Date: Sun, 23 Jul 2017 22:29:57 -0400 Subject: scaninc: faster incbin detection --- tools/scaninc/c_file.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'tools') diff --git a/tools/scaninc/c_file.cpp b/tools/scaninc/c_file.cpp index 2dd400967..2d3f8749a 100644 --- a/tools/scaninc/c_file.cpp +++ b/tools/scaninc/c_file.cpp @@ -237,6 +237,18 @@ void CFile::CheckInclude() 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; -- cgit v1.2.3 From e73ec108adb15cda40c17ebe891d25460c3c42b3 Mon Sep 17 00:00:00 2001 From: yenatch Date: Sun, 23 Jul 2017 22:34:49 -0400 Subject: scaninc: skipping comments seems to be faster than removing them --- tools/scaninc/c_file.cpp | 97 +++++++++++++++--------------------------------- tools/scaninc/c_file.h | 2 +- 2 files changed, 30 insertions(+), 69 deletions(-) (limited to 'tools') diff --git a/tools/scaninc/c_file.cpp b/tools/scaninc/c_file.cpp index 2d3f8749a..e4e20e609 100644 --- a/tools/scaninc/c_file.cpp +++ b/tools/scaninc/c_file.cpp @@ -45,8 +45,6 @@ CFile::CFile(std::string path) m_pos = 0; m_lineNum = 1; - - RemoveComments(); } CFile::~CFile() @@ -54,71 +52,6 @@ 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; @@ -195,9 +128,37 @@ bool CFile::ConsumeNewline() 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 (!ConsumeNewline()) + { + m_pos++; + } + } + m_pos += 2; + return true; + } + else if (m_buffer[m_pos] == '/' && m_buffer[m_pos + 1] == '/') + { + m_pos += 2; + while (!ConsumeNewline()) + { + m_pos++; + } + return true; + } + + return false; +} + void CFile::SkipWhitespace() { - while (ConsumeHorizontalWhitespace() || ConsumeNewline()) + while (ConsumeHorizontalWhitespace() || ConsumeNewline() || ConsumeComment()) ; } diff --git a/tools/scaninc/c_file.h b/tools/scaninc/c_file.h index 38b10f04e..618901b85 100644 --- a/tools/scaninc/c_file.h +++ b/tools/scaninc/c_file.h @@ -44,9 +44,9 @@ private: std::set m_incbins; std::set m_includes; - void RemoveComments(); bool ConsumeHorizontalWhitespace(); bool ConsumeNewline(); + bool ConsumeComment(); void SkipWhitespace(); bool CheckIdentifier(const std::string& ident); void CheckInclude(); -- cgit v1.2.3 From d2a1118862eac8473d056cfd8a8af28be2b947fd Mon Sep 17 00:00:00 2001 From: yenatch Date: Sun, 23 Jul 2017 22:37:53 -0400 Subject: scaninc: optimize for unix newlines this probably has no effect whatsoever --- tools/scaninc/c_file.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/scaninc/c_file.cpp b/tools/scaninc/c_file.cpp index e4e20e609..035af4e1b 100644 --- a/tools/scaninc/c_file.cpp +++ b/tools/scaninc/c_file.cpp @@ -111,16 +111,16 @@ bool CFile::ConsumeHorizontalWhitespace() bool CFile::ConsumeNewline() { - if (m_buffer[m_pos] == '\r' && m_buffer[m_pos + 1] == '\n') + if (m_buffer[m_pos] == '\n') { - m_pos += 2; + m_pos++; m_lineNum++; return true; } - if (m_buffer[m_pos] == '\n') + if (m_buffer[m_pos] == '\r' && m_buffer[m_pos + 1] == '\n') { - m_pos++; + m_pos += 2; m_lineNum++; return true; } -- cgit v1.2.3 From e98e074138c9a8083a812760d71144f7174b34d8 Mon Sep 17 00:00:00 2001 From: yenatch Date: Sun, 23 Jul 2017 23:11:26 -0400 Subject: scaninc: allow multiple include paths also use a queue instead of a stack for filesToProcess --- tools/scaninc/scaninc.cpp | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) (limited to 'tools') diff --git a/tools/scaninc/scaninc.cpp b/tools/scaninc/scaninc.cpp index 2d91db646..3dc221479 100644 --- a/tools/scaninc/scaninc.cpp +++ b/tools/scaninc/scaninc.cpp @@ -20,7 +20,8 @@ #include #include -#include +#include +#include #include #include #include "scaninc.h" @@ -42,10 +43,10 @@ const char *const USAGE = "Usage: scaninc [-I INCLUDE_PATH] FILE_PATH\n"; int main(int argc, char **argv) { - std::stack filesToProcess; + std::queue filesToProcess; std::set dependencies; - std::string includeDir(""); + std::list includeDirs; argc--; argv++; @@ -55,22 +56,23 @@ int main(int argc, char **argv) std::string arg(argv[0]); if (arg.substr(0, 2) == "-I") { - includeDir = arg.substr(2); + std::string includeDir = arg.substr(2); if (includeDir.empty()) - { + { argc--; argv++; - includeDir = std::string(argv[0]); + includeDir = std::string(argv[0]); } if (includeDir.back() != '/') { includeDir += '/'; } - } + includeDirs.push_back(includeDir); + } else { FATAL_ERROR(USAGE); - } + } argc--; argv++; } @@ -94,6 +96,7 @@ int main(int argc, char **argv) { srcDir = initialPath.substr(0, slash + 1); } + includeDirs.push_back(srcDir); if (extension == "c" || extension == "h") { @@ -101,7 +104,7 @@ int main(int argc, char **argv) while (!filesToProcess.empty()) { - CFile file(filesToProcess.top()); + CFile file(filesToProcess.front()); filesToProcess.pop(); file.FindIncbins(); @@ -111,18 +114,17 @@ int main(int argc, char **argv) } for (auto include : file.GetIncludes()) { - std::string path(srcDir + include); - if (!CanOpenFile(path)) - { - path = includeDir + include; - } - - if (CanOpenFile(path)) + for (auto includeDir : includeDirs) { - bool inserted = dependencies.insert(path).second; - if (inserted) + std::string path(includeDir + include); + if (CanOpenFile(path)) { - filesToProcess.push(path); + bool inserted = dependencies.insert(path).second; + if (inserted) + { + filesToProcess.push(path); + } + break; } } } @@ -134,7 +136,7 @@ int main(int argc, char **argv) while (!filesToProcess.empty()) { - AsmFile file(filesToProcess.top()); + AsmFile file(filesToProcess.front()); filesToProcess.pop(); -- cgit v1.2.3 From c0ebc30a60b1fa919b424a34bd355a565b317ab8 Mon Sep 17 00:00:00 2001 From: yenatch Date: Mon, 24 Jul 2017 00:17:38 -0400 Subject: scaninc: skip whitespace/comments in the read loop fixes e73ec108adb15cda40c17ebe891d25460c3c42b3 --- tools/scaninc/c_file.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/scaninc/c_file.cpp b/tools/scaninc/c_file.cpp index 035af4e1b..bba196857 100644 --- a/tools/scaninc/c_file.cpp +++ b/tools/scaninc/c_file.cpp @@ -78,6 +78,7 @@ void CFile::FindIncbins() } else { + SkipWhitespace(); CheckInclude(); CheckIncbin(); -- cgit v1.2.3 From b21c159b08c57a948edb268ac9b9b5baf6b4332d Mon Sep 17 00:00:00 2001 From: yenatch Date: Sat, 29 Jul 2017 14:57:06 -0400 Subject: scaninc: fix buffer overflow --- tools/scaninc/c_file.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/scaninc/c_file.cpp b/tools/scaninc/c_file.cpp index bba196857..c55ca9a8c 100644 --- a/tools/scaninc/c_file.cpp +++ b/tools/scaninc/c_file.cpp @@ -292,5 +292,5 @@ std::string CFile::ReadPath() m_pos++; - return std::string(m_buffer, startPos, m_pos - 1 - startPos); + return std::string(m_buffer + startPos, m_pos - 1 - startPos); } -- cgit v1.2.3