diff --git a/contrib/zsh_compl/_rgbasm b/contrib/zsh_compl/_rgbasm index 2998be21..a2301817 100644 --- a/contrib/zsh_compl/_rgbasm +++ b/contrib/zsh_compl/_rgbasm @@ -48,9 +48,10 @@ local args=( '*'{-D,--define}'+[Define a string symbol]:name + value (default 1):' '(-g --gfx-chars)'{-g,--gfx-chars}'+[Change chars for gfx constants]:chars spec:' '(-I --include)'{-I,--include}'+[Add an include directory]:include path:_files -/' - '(-M --dependfile)'{-M,--dependfile}"+[Write deps in make format]:output file:_files -g '*.{d,mk}'" - -MG'[Assume missing files should be generated]' - -MP'[Add phony targets to all deps]' + '(-M --dependfile)'{-M,--dependfile}"+[Write dependencies in Makefile format]:output file:_files -g '*.{d,mk}'" + -MC'[Continue after missing dependencies]' + -MG'[Assume missing dependencies should be generated]' + -MP'[Add phony targets to all dependencies]' '*'-MT"+[Add a target to the rules]:target:_files -g '*.{d,mk,o}'" '*'-MQ"+[Add a target to the rules]:target:_files -g '*.{d,mk,o}'" '(-o --output)'{-o,--output}'+[Output file]:output file:_files' diff --git a/include/asm/main.hpp b/include/asm/main.hpp index 890da1f8..4a93cc3f 100644 --- a/include/asm/main.hpp +++ b/include/asm/main.hpp @@ -10,6 +10,7 @@ extern bool verbose; extern FILE *dependFile; extern std::string targetFileName; +extern bool continueAfterMissingIncludes; extern bool generatedMissingIncludes; extern bool failedOnMissingInclude; extern bool generatePhonyDeps; diff --git a/man/rgbasm.1 b/man/rgbasm.1 index 41cf54d0..a6363456 100644 --- a/man/rgbasm.1 +++ b/man/rgbasm.1 @@ -14,6 +14,7 @@ .Op Fl g Ar chars .Op Fl I Ar path .Op Fl M Ar depend_file +.Op Fl MC .Op Fl MG .Op Fl MP .Op Fl MT Ar target_file @@ -114,6 +115,17 @@ Write .Xr make 1 dependencies to .Ar depend_file . +.It Fl MC +To be used in conjunction with +.Fl MG . +This makes +.Nm +continue processing after a non-existent dependency file, instead of exiting. +Note that this is +.Em not +recommended if any non-existent dependencies would have influenced subsequent processing, e.g. by causing an +.Ic IF +condition to take a different branch. .It Fl MG To be used in conjunction with .Fl M . @@ -126,8 +138,10 @@ or .Ic INCBIN is attempted on a non-existent file, it is added as a dependency, then .Nm -exits normally instead of erroring out. -This feature is used in automatic updating of makefiles. +exits normally or continues processing (depending on whether +.Fl MC +was enabled) instead of erroring out. +This feature is used in automatic updating of Makefiles. .It Fl MP When enabled, this causes a phony target to be added for each dependency other than the main file. This prevents @@ -269,7 +283,7 @@ Enables literally every warning. .El .Pp The following warnings are actual warning flags; with each description, the corresponding warning flag is included. -Note that each of these flag also has a negation (for example, +Note that each of these flags also has a negation (for example, .Fl Wcharmap-redef enables the warning that .Fl Wno-charmap-redef diff --git a/src/asm/fstack.cpp b/src/asm/fstack.cpp index 302a3081..8ea7fbae 100644 --- a/src/asm/fstack.cpp +++ b/src/asm/fstack.cpp @@ -312,7 +312,7 @@ void fstk_RunInclude(std::string const &path, bool preInclude) { if (!fullPath) { if (generatedMissingIncludes && !preInclude) { // LCOV_EXCL_START - if (verbose) { + if (verbose && !continueAfterMissingIncludes) { printf("Aborting (-MG) on INCLUDE file '%s' (%s)\n", path.c_str(), strerror(errno)); } // LCOV_EXCL_STOP diff --git a/src/asm/main.cpp b/src/asm/main.cpp index b9b5db4b..0c493e04 100644 --- a/src/asm/main.cpp +++ b/src/asm/main.cpp @@ -24,10 +24,11 @@ #include "asm/symbol.hpp" #include "asm/warning.hpp" -FILE *dependFile = nullptr; // -M -bool generatedMissingIncludes = false; // -MG -bool generatePhonyDeps = false; // -MP -std::string targetFileName; // -MQ, -MT +FILE *dependFile = nullptr; // -M +bool continueAfterMissingIncludes = false; // -MC +bool generatedMissingIncludes = false; // -MG +bool generatePhonyDeps = false; // -MP +std::string targetFileName; // -MQ, -MT bool failedOnMissingInclude = false; bool verbose = false; // -v @@ -70,6 +71,7 @@ static option const longopts[] = { {"help", no_argument, nullptr, 'h'}, {"include", required_argument, nullptr, 'I'}, {"dependfile", required_argument, nullptr, 'M'}, + {"MC", no_argument, &depType, 'C'}, {"MG", no_argument, &depType, 'G'}, {"MP", no_argument, &depType, 'P'}, {"MQ", required_argument, &depType, 'Q'}, @@ -91,7 +93,7 @@ static option const longopts[] = { static void printUsage() { fputs( "Usage: rgbasm [-EhVvw] [-b chars] [-D name[=value]] [-g chars] [-I path]\n" - " [-M depend_file] [-MG] [-MP] [-MT target_file] [-MQ target_file]\n" + " [-M depend_file] [-MC] [-MG] [-MP] [-MT target_file] [-MQ target_file]\n" " [-o out_file] [-P include_file] [-p pad_value] [-Q precision]\n" " [-r depth] [-s features:state_file] [-W warning] [-X max_errors]\n" " \n" @@ -372,6 +374,10 @@ int main(int argc, char *argv[]) { // Long-only options case 0: switch (depType) { + case 'C': + continueAfterMissingIncludes = true; + break; + case 'G': generatedMissingIncludes = true; break; diff --git a/src/asm/parser.y b/src/asm/parser.y index db38e360..ec8a91dd 100644 --- a/src/asm/parser.y +++ b/src/asm/parser.y @@ -1137,7 +1137,7 @@ export_def: include: label POP_INCLUDE string endofline { fstk_RunInclude($3, false); - if (failedOnMissingInclude) { + if (failedOnMissingInclude && !continueAfterMissingIncludes) { YYACCEPT; } } @@ -1146,19 +1146,19 @@ include: incbin: POP_INCBIN string { sect_BinaryFile($2, 0); - if (failedOnMissingInclude) { + if (failedOnMissingInclude && !continueAfterMissingIncludes) { YYACCEPT; } } | POP_INCBIN string COMMA iconst { sect_BinaryFile($2, $4); - if (failedOnMissingInclude) { + if (failedOnMissingInclude && !continueAfterMissingIncludes) { YYACCEPT; } } | POP_INCBIN string COMMA iconst COMMA iconst { sect_BinaryFileSlice($2, $4, $6); - if (failedOnMissingInclude) { + if (failedOnMissingInclude && !continueAfterMissingIncludes) { YYACCEPT; } } diff --git a/src/asm/section.cpp b/src/asm/section.cpp index 4a9b9b5f..e85c71e1 100644 --- a/src/asm/section.cpp +++ b/src/asm/section.cpp @@ -911,7 +911,7 @@ void sect_BinaryFile(std::string const &name, int32_t startPos) { if (!file) { if (generatedMissingIncludes) { // LCOV_EXCL_START - if (verbose) { + if (verbose && !continueAfterMissingIncludes) { printf("Aborting (-MG) on INCBIN file '%s' (%s)\n", name.c_str(), strerror(errno)); } // LCOV_EXCL_STOP @@ -976,7 +976,7 @@ void sect_BinaryFileSlice(std::string const &name, int32_t startPos, int32_t len if (!file) { if (generatedMissingIncludes) { // LCOV_EXCL_START - if (verbose) { + if (verbose && !continueAfterMissingIncludes) { printf("Aborting (-MG) on INCBIN file '%s' (%s)\n", name.c_str(), strerror(errno)); } // LCOV_EXCL_STOP diff --git a/test/asm/continues-after-missing-include/a.asm b/test/asm/continues-after-missing-include/a.asm new file mode 100644 index 00000000..63caab8a --- /dev/null +++ b/test/asm/continues-after-missing-include/a.asm @@ -0,0 +1,13 @@ +PUSHC +PUSHO +PUSHS +SECTION "test", WRAM0 +UNION +INCLUDE "nonexistent1.inc" +WARN "still going!" +INCLUDE "nonexistent2.inc" +WARN "and going!" +ENDU +POPS +POPO +POPC diff --git a/test/asm/continues-after-missing-include/a.err b/test/asm/continues-after-missing-include/a.err new file mode 100644 index 00000000..99fb01c8 --- /dev/null +++ b/test/asm/continues-after-missing-include/a.err @@ -0,0 +1,4 @@ +warning: continues-after-missing-include/a.asm(7): [-Wuser] + still going! +warning: continues-after-missing-include/a.asm(9): [-Wuser] + and going! diff --git a/test/asm/continues-after-missing-include/a.out b/test/asm/continues-after-missing-include/a.out new file mode 100644 index 00000000..d245b61b --- /dev/null +++ b/test/asm/continues-after-missing-include/a.out @@ -0,0 +1,3 @@ +a.o: continues-after-missing-include/a.asm +a.o: nonexistent1.inc +a.o: nonexistent2.inc diff --git a/test/asm/test.sh b/test/asm/test.sh index 89e67773..e0a01d24 100755 --- a/test/asm/test.sh +++ b/test/asm/test.sh @@ -103,7 +103,7 @@ for i in *.asm notexist.asm; do desired_errput="$gb" # Escape regex metacharacters subst="$(printf '%s\n' "$i" | sed 's:[][\/.^$*]:\\&:g')" - # Replace the file name with a dash to match changed output + # Replace the file name with "" to match changed output sed "s/$subst//g" "$desired_outname" >"$desired_output" sed "s/$subst//g" "$desired_errname" >"$desired_errput" fi @@ -135,6 +135,33 @@ done # These tests do their own thing +i="continues-after-missing-include" +RGBASMFLAGS="-Weverything -M - -MG -MC" +# Piping the .asm file to rgbasm would not make sense for dependency generation, +# so just test the normal variant +(( tests++ )) +echo "${bold}${green}${i%.asm}...${rescolors}${resbold}" +"$RGBASM" $RGBASMFLAGS -o "$o" "$i"/a.asm >"$output" 2>"$errput" +fixed_output="$input" +if which cygpath &>/dev/null; then + # MinGW needs the Windows path substituted but with forward slash separators; + # Cygwin has `cygpath` but just needs the original path substituted. + subst1="$(printf '%s\n' "$o" | sed 's:[][\/.^$*]:\\&:g')" + subst2="$(printf '%s\n' "$(cygpath -w "$o")" | sed -e 's:\\:/:g' -e 's:[][\/.^$*]:\\&:g')" + sed -e "s/$subst1/a.o/g" -e "s/$subst2/a.o/g" "$output" >"$fixed_output" +else + subst="$(printf '%s\n' "$o" | sed 's:[][\/.^$*]:\\&:g')" + sed "s/$subst/a.o/g" "$output" >"$fixed_output" +fi +tryDiff "$i"/a.out "$fixed_output" out +our_rc=$? +tryDiff "$i"/a.err "$errput" err +(( our_rc = our_rc || $? )) +(( rc = rc || our_rc )) +if [[ $our_rc -ne 0 ]]; then + (( failed++ )) +fi + i="state-file" if which cygpath &>/dev/null; then # MinGW translates path names before passing them as command-line arguments,