diff --git a/src/gfx/main.cpp b/src/gfx/main.cpp index 240cd129..00955c50 100644 --- a/src/gfx/main.cpp +++ b/src/gfx/main.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include "extern/getopt.hpp" #include "file.hpp" @@ -601,7 +602,6 @@ int main(int argc, char *argv[]) { struct AtFileStackEntry { int parentInd; // Saved offset into parent argv std::vector argv; // This context's arg pointer vec - std::vector argPool; AtFileStackEntry(int parentInd_, std::vector argv_) : parentInd(parentInd_), argv(argv_) {} @@ -610,18 +610,24 @@ int main(int argc, char *argv[]) { int curArgc = argc; char **curArgv = argv; + std::vector> argPools; for (;;) { char *atFileName = parseArgv(curArgc, curArgv); if (atFileName) { + // We need to allocate a new arg pool for each at-file, so as not to invalidate pointers + // previous at-files may have generated to their own arg pools. + // But for the same reason, the arg pool must also outlive the at-file's stack entry! + auto &argPool = argPools.emplace_back(); + // Copy `argv[0]` for error reporting, and because option parsing skips it AtFileStackEntry &stackEntry = atFileStack.emplace_back(musl_optind, std::vector{atFileName}); // It would be nice to compute the char pointers on the fly, but reallocs don't allow // that; so we must compute the offsets after the pool is fixed - auto offsets = readAtFile(&musl_optarg[1], stackEntry.argPool); + auto offsets = readAtFile(&musl_optarg[1], argPool); stackEntry.argv.reserve(offsets.size() + 2); // Avoid a bunch of reallocs for (size_t ofs : offsets) { - stackEntry.argv.push_back(&stackEntry.argPool.data()[ofs]); + stackEntry.argv.push_back(&argPool.data()[ofs]); } stackEntry.argv.push_back(nullptr); // Don't forget the arg vector terminator! diff --git a/test/gfx/at-file-ref.err b/test/gfx/at-file-ref.err new file mode 100644 index 00000000..b0358a13 --- /dev/null +++ b/test/gfx/at-file-ref.err @@ -0,0 +1,14 @@ +error: Failed to fit tile colors [$7f55, $7fff] in specified palettes +error: Failed to fit tile colors [$7f55] in specified palettes +error: Failed to fit tile colors [$6c8a, $7f55, $7fff] in specified palettes +error: Failed to fit tile colors [$6c8a, $7fff] in specified palettes +error: Failed to fit tile colors [$6c8a, $7f55] in specified palettes +error: Failed to fit tile colors [$6c8a] in specified palettes +error: Failed to fit tile colors [$7fff] in specified palettes +note: The following palettes were specified: + [$3f65, $36b3, $262a, $50b0] + [$5f77, $213d, $41a6, $40ee] + [$5f77, $267c, $213d, $40ee] + [$53c3, $3f65, $36b3] + [$267c, $41a6] +Conversion aborted after 7 errors diff --git a/test/gfx/at-file-ref.flags b/test/gfx/at-file-ref.flags new file mode 100644 index 00000000..fe09f6d3 --- /dev/null +++ b/test/gfx/at-file-ref.flags @@ -0,0 +1,2 @@ +-m +-c gbc:result.pal diff --git a/test/gfx/at-file-ref.png b/test/gfx/at-file-ref.png new file mode 100644 index 00000000..57fdd36f Binary files /dev/null and b/test/gfx/at-file-ref.png differ