diff --git a/Makefile b/Makefile index c9a7c2e05..e5b35a830 100644 --- a/Makefile +++ b/Makefile @@ -168,7 +168,7 @@ $(ASM_BUILDDIR)/%.o: $(ASM_SUBDIR)/%.s $$(asm_dep) ifeq ($(NODEP),1) $(DATA_ASM_BUILDDIR)/%.o: data_dep := else -$(DATA_ASM_BUILDDIR)/%.o: data_dep = $(shell $(SCANINC) $(DATA_ASM_SUBDIR)/$*.s) +$(DATA_ASM_BUILDDIR)/%.o: data_dep = $(shell $(SCANINC) -I include $(DATA_ASM_SUBDIR)/$*.s) endif $(DATA_ASM_BUILDDIR)/%.o: $(DATA_ASM_SUBDIR)/%.s $$(data_dep) diff --git a/src/field_message_box.c b/src/field_message_box.c index ac5e7a4bb..ca1c05e22 100755 --- a/src/field_message_box.c +++ b/src/field_message_box.c @@ -1,6 +1,6 @@ +#include #include "global.h" #include "menu.h" -#include "string.h" #include "string_util.h" #include "task.h" #include "text.h" diff --git a/src/item_menu.c b/src/item_menu.c index 5b9946e62..5d5dfe854 100755 --- a/src/item_menu.c +++ b/src/item_menu.c @@ -1,3 +1,4 @@ +#include #include "global.h" #include "item_menu.h" #include "battle.h" @@ -40,7 +41,6 @@ #include "shop.h" #include "sound.h" #include "sprite.h" -#include "string.h" #include "strings.h" #include "string_util.h" #include "task.h" diff --git a/src/main_menu.c b/src/main_menu.c index e6e29d942..1879495f5 100644 --- a/src/main_menu.c +++ b/src/main_menu.c @@ -1,3 +1,4 @@ +#include #include "global.h" #include "trainer_pokemon_sprites.h" #include "bg.h" @@ -30,7 +31,6 @@ #include "scanline_effect.h" #include "sound.h" #include "sprite.h" -#include "string.h" #include "strings.h" #include "string_util.h" #include "task.h" diff --git a/tools/scaninc/Makefile b/tools/scaninc/Makefile index 367a3350b..53c9d0060 100644 --- a/tools/scaninc/Makefile +++ b/tools/scaninc/Makefile @@ -2,9 +2,9 @@ CXX = g++ CXXFLAGS = -Wall -Werror -std=c++11 -O2 -SRCS = scaninc.cpp c_file.cpp asm_file.cpp +SRCS = scaninc.cpp c_file.cpp asm_file.cpp source_file.cpp -HEADERS := scaninc.h asm_file.h c_file.h +HEADERS := scaninc.h asm_file.h c_file.h source_file.h .PHONY: clean diff --git a/tools/scaninc/asm_file.cpp b/tools/scaninc/asm_file.cpp index 6322749e2..109e604a2 100644 --- a/tools/scaninc/asm_file.cpp +++ b/tools/scaninc/asm_file.cpp @@ -64,7 +64,8 @@ IncDirectiveType AsmFile::ReadUntilIncDirective(std::string &path) IncDirectiveType incDirectiveType = IncDirectiveType::None; - if (PeekChar() == '.') + char c = PeekChar(); + if (c == '.' || c == '#') { m_pos++; diff --git a/tools/scaninc/scaninc.cpp b/tools/scaninc/scaninc.cpp index 3dc221479..0d55d11f6 100644 --- a/tools/scaninc/scaninc.cpp +++ b/tools/scaninc/scaninc.cpp @@ -25,8 +25,7 @@ #include #include #include "scaninc.h" -#include "asm_file.h" -#include "c_file.h" +#include "source_file.h" bool CanOpenFile(std::string path) { @@ -46,7 +45,7 @@ int main(int argc, char **argv) std::queue filesToProcess; std::set dependencies; - std::list includeDirs; + std::vector includeDirs; argc--; argv++; @@ -83,79 +82,50 @@ int main(int argc, char **argv) std::string initialPath(argv[0]); - std::size_t pos = initialPath.find_last_of('.'); + filesToProcess.push(initialPath); - if (pos == std::string::npos) - FATAL_ERROR("no file extension in path \"%s\"\n", initialPath.c_str()); - - std::string extension = initialPath.substr(pos + 1); - - std::string srcDir(""); - std::size_t slash = initialPath.rfind('/'); - if (slash != std::string::npos) + while (!filesToProcess.empty()) { - srcDir = initialPath.substr(0, slash + 1); - } - includeDirs.push_back(srcDir); + std::string filePath = filesToProcess.front(); + SourceFile file(filePath); + filesToProcess.pop(); - if (extension == "c" || extension == "h") - { - filesToProcess.push(initialPath); - - while (!filesToProcess.empty()) + includeDirs.push_back(file.GetSrcDir()); + for (auto incbin : file.GetIncbins()) { - CFile file(filesToProcess.front()); - filesToProcess.pop(); - - file.FindIncbins(); - for (auto incbin : file.GetIncbins()) + dependencies.insert(incbin); + } + for (auto include : file.GetIncludes()) + { + bool found = false; + for (auto includeDir : includeDirs) { - dependencies.insert(incbin); - } - for (auto include : file.GetIncludes()) - { - for (auto includeDir : includeDirs) + std::string path(includeDir + include); + if (CanOpenFile(path)) { - std::string path(includeDir + include); - if (CanOpenFile(path)) + bool inserted = dependencies.insert(path).second; + if (inserted) { - bool inserted = dependencies.insert(path).second; - if (inserted) - { - filesToProcess.push(path); - } - break; + filesToProcess.push(path); } + found = true; + break; } } - } - } - else if (extension == "s" || extension == "inc") - { - filesToProcess.push(initialPath); - - while (!filesToProcess.empty()) - { - AsmFile file(filesToProcess.front()); - - filesToProcess.pop(); - - IncDirectiveType incDirectiveType; - std::string path; - - while ((incDirectiveType = file.ReadUntilIncDirective(path)) != IncDirectiveType::None) + if (!found) { - bool inserted = dependencies.insert(path).second; - if (inserted - && incDirectiveType == IncDirectiveType::Include - && CanOpenFile(path)) - filesToProcess.push(path); + if (GetFileType(include) == SourceFileType::Header) + // We don't have any generated .h files... yet. + // Better to give a warning; debugging the makefile when a + // header is missing is very difficult. + fprintf(stderr, "scaninc: warning: C header file \"%s\" not found. (included from \"%s\")\n", + include.c_str(), filePath.c_str()); + + // It's probably a generated file. + dependencies.insert(include); } } - } - else - { - FATAL_ERROR("unknown extension \"%s\"\n", extension.c_str()); + includeDirs.pop_back(); } for (const std::string &path : dependencies) diff --git a/tools/scaninc/scaninc.h b/tools/scaninc/scaninc.h index 30cc9611c..d6736e01b 100644 --- a/tools/scaninc/scaninc.h +++ b/tools/scaninc/scaninc.h @@ -1,4 +1,4 @@ -// Copyright(c) 2015-2017 YamaArashi +// 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 diff --git a/tools/scaninc/source_file.cpp b/tools/scaninc/source_file.cpp new file mode 100644 index 000000000..f23ff6db6 --- /dev/null +++ b/tools/scaninc/source_file.cpp @@ -0,0 +1,125 @@ +// 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 +#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 incbins; + std::set 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}; + } +} + +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& 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& 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; +} + diff --git a/tools/scaninc/source_file.h b/tools/scaninc/source_file.h new file mode 100644 index 000000000..15ea50a03 --- /dev/null +++ b/tools/scaninc/source_file.h @@ -0,0 +1,71 @@ +// 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 SOURCE_FILE_H +#define SOURCE_FILE_H + +#include +#include "scaninc.h" +#include "asm_file.h" +#include "c_file.h" + +enum class SourceFileType +{ + Cpp, + Header, + Asm, + Inc +}; + +SourceFileType GetFileType(std::string& path); + +class SourceFile +{ +public: + + SourceFile(std::string path); + ~SourceFile(); + SourceFile(SourceFile const&) = delete; + SourceFile(SourceFile&&) = delete; + SourceFile& operator =(SourceFile const&) = delete; + SourceFile& operator =(SourceFile&&) = delete; + bool HasIncbins(); + const std::set& GetIncbins(); + const std::set& GetIncludes(); + std::string& GetSrcDir(); + +private: + union InnerUnion { + CFile c_file; + struct AsmWrapper { + std::set asm_incbins; + std::set asm_includes; + } asm_wrapper; + + // Construction and destruction handled by SourceFile. + InnerUnion() {}; + ~InnerUnion() {}; + } m_source_file; + SourceFileType m_file_type; + std::string m_src_dir; +}; + +#endif // SOURCE_FILE_H +