From 2a39532c9dc817e339fa390e776e2c3f8bbebf23 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Sun, 10 Jul 2022 14:19:22 +0700 Subject: [PATCH 01/26] verify command line options --- CMakeLists.txt | 2 +- man/CMakeLists.txt | 10 ++++++++ man/docgen | 49 ++++++++++++++++++++++++++++++++++- src/CMakeLists.txt | 11 ++++++-- src/d_main.c | 4 +++ src/i_main.c | 6 ++++- src/m_argv.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++ src/m_argv.h | 4 +++ 8 files changed, 145 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d0e7351b0..45b922a27 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -217,7 +217,7 @@ include(CPack) add_subdirectory(data) add_subdirectory(opl) add_subdirectory(textscreen) +add_subdirectory(man) add_subdirectory(src) add_subdirectory(toolsrc) add_subdirectory(setup) -add_subdirectory(man) diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt index 2478b1d68..a287acbfe 100644 --- a/man/CMakeLists.txt +++ b/man/CMakeLists.txt @@ -1,3 +1,13 @@ + +if(Python3_EXECUTABLE) + add_custom_target(GenParams + COMMAND "${Python3_EXECUTABLE}" docgen -a + "${PROJECT_SOURCE_DIR}/src" > "${PROJECT_SOURCE_DIR}/src/params.h" + DEPENDS "${PROJECT_SOURCE_DIR}/src" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + ) +endif() + configure_file(WoofInstall.cmake.in WoofInstall.cmake ESCAPE_QUOTES @ONLY) install(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/WoofInstall.cmake") diff --git a/man/docgen b/man/docgen index b90046b36..a40a9a2c5 100644 --- a/man/docgen +++ b/man/docgen @@ -142,6 +142,28 @@ class Category: return result + def carray_output(self): + result = "" + + self.params.sort() + + for p in self.params: + if p.should_show() and not p.args: + result += "\"" + p.carray_output(0) + "\",\n" + + return result + + def carray_output_args(self): + result = "" + + self.params.sort() + + for p in self.params: + if p.should_show() and p.args: + result += "\"" + p.carray_output(0) + "\",\n" + + return result + def manpage_output(self): result = ".SH " + self.description.upper() + "\n" @@ -336,6 +358,12 @@ class Parameter: return result + def carray_output(self, w): + + result = self.name + + return result + # Read list of wiki pages def read_wikipages(): @@ -531,6 +559,22 @@ def completion_output(targets, substs, template_file): print_template(template_file, substs, content) +def carray_output(targets, substs, template): + + content = "\nstatic const char *params[] = {\n" + + for t in targets: + content += t.carray_output() + + content += "};\n\nstatic const char *params_with_args[] = {\n" + + for t in targets: + content += t.carray_output_args() + + content += "};\n" + + print(content) + def usage(): print("Usage: %s [-V] [-c tag] -s project_name [ -z shortname ] ( -M | -m | -w | -p ) ..." \ % sys.argv[0]) @@ -544,13 +588,14 @@ def usage(): print(" -w : Wikitext output") print(" -p : Plaintext output") print(" -b : Bash-Completion output") + print(" -a : C array output") print(" -V : Don't show Vanilla Doom options") print(" -g : Only document options for specified game.") sys.exit(0) # Parse command line -opts, args = getopt.getopt(sys.argv[1:], "s:z:M:m:wp:b:c:g:V") +opts, args = getopt.getopt(sys.argv[1:], "s:z:M:m:wp:b:ap:c:g:V") output_function = None template = None @@ -577,6 +622,8 @@ for opt in opts: elif opt[0] == "-b": output_function = completion_output template = opt[1] + elif opt[0] == "-a": + output_function = carray_output elif opt[0] == "-V": show_vanilla_options = False elif opt[0] == "-c": diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 80f0f8e1e..5162f2f32 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -117,7 +117,9 @@ set(WOOF_SOURCES z_zone.c z_zone.h ../miniz/miniz.c ../miniz/miniz.h) -list(APPEND WOOF_LIBRARIES textscreen) +if (Python3_EXECUTABLE) + list(APPEND WOOF_SOURCES params.h) +endif() if(WIN32) list(APPEND @@ -156,13 +158,18 @@ add_executable(woof WIN32 ${WOOF_SOURCES}) target_woof_settings(woof) target_include_directories(woof PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../") +if(Python3_EXECUTABLE) + add_dependencies(woof GenParams) + target_compile_definitions(woof PRIVATE HAVE_GEN_PARAMS) +endif() + if (FluidSynth_FOUND) list(APPEND WOOF_LIBRARIES FluidSynth::FluidSynth) target_compile_definitions(woof PRIVATE HAVE_FLUIDSYNTH) endif() target_link_libraries(woof PRIVATE ${WOOF_LIBRARIES} - SDL2::SDL2 SDL2::mixer SDL2::net opl) + SDL2::SDL2 SDL2::mixer SDL2::net opl textscreen) if(MSVC) # MSVC tries to supply a default manifest and complains when it finds ours diff --git a/src/d_main.c b/src/d_main.c index a09da4aed..10846983d 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1783,6 +1783,10 @@ void D_DoomMain(void) I_AtExitPrio(I_ErrorMsg, true, "I_ErrorMsg", exit_priority_verylast); +#if defined(HAVE_GEN_PARAMS) + M_CheckCommandLine(); +#endif + dsdh_InitTables(); #if defined(_WIN32) diff --git a/src/i_main.c b/src/i_main.c index fe6e810a5..b3387dd2e 100644 --- a/src/i_main.c +++ b/src/i_main.c @@ -108,7 +108,11 @@ int main(int argc, char **argv) myargc = argc; myargv = argv; - // print the program version and exit + //! + // + // Print the program version and exit. + // + if (M_ParmExists("-version") || M_ParmExists("--version")) { puts(PROJECT_STRING); diff --git a/src/m_argv.c b/src/m_argv.c index 97ad7638f..0e5acb69d 100644 --- a/src/m_argv.c +++ b/src/m_argv.c @@ -69,6 +69,70 @@ boolean M_ParmExists(const char *check) return M_CheckParm(check) != 0; } +#if defined(HAVE_GEN_PARAMS) +#include "params.h" +#include "i_system.h" + +static void CheckParams(int num) +{ + int i; + + for (i = 0; i < arrlen(params); ++i) + { + if (!strcasecmp(myargv[num], params[i])) + return; + } + + I_Error("No such option %s\n", myargv[num]); +} + +static boolean CheckParamsWithArgs(int num) +{ + int i; + + for (i = 0; i < arrlen(params_with_args); ++i) + { + if (!strcasecmp(myargv[num], params_with_args[i])) + { + if (num + 1 < myargc && myargv[num + 1][0] != '-') + return true; + else + I_Error("No parameter for %s", myargv[num]); + } + } + + return false; +} + +void M_CheckCommandLine(void) +{ + int i; + + for (i = 1; i < myargc; i++) + { + if (CheckParamsWithArgs(i)) + { + // -file and -warp may have multiple arguments + if (!strcasecmp(myargv[i], "-file") || + !strcasecmp(myargv[i], "-warp")) + { + do + i++; + while (i < myargc && myargv[i][0] != '-'); + } + else + { + i++; + } + + continue; + } + + CheckParams(i); + } +} +#endif + //---------------------------------------------------------------------------- // // $Log: m_argv.c,v $ diff --git a/src/m_argv.h b/src/m_argv.h index 66ee9d429..ee42b5957 100644 --- a/src/m_argv.h +++ b/src/m_argv.h @@ -49,6 +49,10 @@ int M_CheckParmWithArgs(const char *check, int num_args); // line arguments, false if not. boolean M_ParmExists(const char *check); +#if defined(HAVE_GEN_PARAMS) +boolean M_CheckCommandLine(void); +#endif + #endif //---------------------------------------------------------------------------- From 11498c9aa3ad945aa18a656c45a79ae19983acb4 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Sun, 10 Jul 2022 14:46:49 +0700 Subject: [PATCH 02/26] fix cmake --- src/CMakeLists.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5162f2f32..1e63be134 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -117,10 +117,6 @@ set(WOOF_SOURCES z_zone.c z_zone.h ../miniz/miniz.c ../miniz/miniz.h) -if (Python3_EXECUTABLE) - list(APPEND WOOF_SOURCES params.h) -endif() - if(WIN32) list(APPEND WOOF_SOURCES From beefac05482f0691b50b064d9f7fa0e5e6e3df0a Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Sun, 10 Jul 2022 14:54:55 +0700 Subject: [PATCH 03/26] add -deh -bex to multiple options check --- src/m_argv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/m_argv.c b/src/m_argv.c index 0e5acb69d..591ae29f0 100644 --- a/src/m_argv.c +++ b/src/m_argv.c @@ -112,9 +112,9 @@ void M_CheckCommandLine(void) { if (CheckParamsWithArgs(i)) { - // -file and -warp may have multiple arguments - if (!strcasecmp(myargv[i], "-file") || - !strcasecmp(myargv[i], "-warp")) + // options that can take multiple arguments + if (!strcasecmp(myargv[i], "-file") || !strcasecmp(myargv[i], "-warp") || + !strcasecmp(myargv[i], "-deh") || !strcasecmp(myargv[i], "-bex") ||) { do i++; From 2e24294f7340ba3cb1acc2cd7afe49b1b38c2e94 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Sun, 10 Jul 2022 15:00:10 +0700 Subject: [PATCH 04/26] fix typo --- src/m_argv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_argv.c b/src/m_argv.c index 591ae29f0..40fa1b643 100644 --- a/src/m_argv.c +++ b/src/m_argv.c @@ -114,7 +114,7 @@ void M_CheckCommandLine(void) { // options that can take multiple arguments if (!strcasecmp(myargv[i], "-file") || !strcasecmp(myargv[i], "-warp") || - !strcasecmp(myargv[i], "-deh") || !strcasecmp(myargv[i], "-bex") ||) + !strcasecmp(myargv[i], "-deh") || !strcasecmp(myargv[i], "-bex")) { do i++; From e2c901ea0772bc1d267f1bc4a29b5ce66c40d054 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Mon, 11 Jul 2022 00:36:40 +0700 Subject: [PATCH 05/26] fix parameter count check --- src/m_argv.c | 89 ++++++++++++++++++++++++++++++++-------------------- src/m_argv.h | 2 ++ 2 files changed, 57 insertions(+), 34 deletions(-) diff --git a/src/m_argv.c b/src/m_argv.c index 40fa1b643..8e7465be8 100644 --- a/src/m_argv.c +++ b/src/m_argv.c @@ -26,6 +26,7 @@ //----------------------------------------------------------------------------- #include "doomtype.h" +#include #include int myargc; @@ -69,66 +70,86 @@ boolean M_ParmExists(const char *check) return M_CheckParm(check) != 0; } +boolean M_ParmStrToInt(const char *str, int *result) +{ + return sscanf(str, " %d", result) == 1; +} + #if defined(HAVE_GEN_PARAMS) #include "params.h" #include "i_system.h" -static void CheckParams(int num) +static int CheckArgs(int p, int num_args) { int i; - for (i = 0; i < arrlen(params); ++i) - { - if (!strcasecmp(myargv[num], params[i])) - return; - } - - I_Error("No such option %s\n", myargv[num]); -} + ++p; -static boolean CheckParamsWithArgs(int num) -{ - int i; - - for (i = 0; i < arrlen(params_with_args); ++i) + for (i = p; i < p + num_args && i < myargc; ++i) { - if (!strcasecmp(myargv[num], params_with_args[i])) - { - if (num + 1 < myargc && myargv[num + 1][0] != '-') - return true; - else - I_Error("No parameter for %s", myargv[num]); - } + if (myargv[i][0] == '-') + break; } - return false; + if (i > p) + return i; + + return 0; } void M_CheckCommandLine(void) { - int i; + int p = 1; - for (i = 1; i < myargc; i++) + while (p < myargc) { - if (CheckParamsWithArgs(i)) + int i; + int args = -1; + + for (i = 0; i < arrlen(params_with_args); ++i) { - // options that can take multiple arguments - if (!strcasecmp(myargv[i], "-file") || !strcasecmp(myargv[i], "-warp") || - !strcasecmp(myargv[i], "-deh") || !strcasecmp(myargv[i], "-bex")) + if (!strcasecmp(myargv[p], "-file") || + !strcasecmp(myargv[p], "-deh") || + !strcasecmp(myargv[p], "-bex")) { - do - i++; - while (i < myargc && myargv[i][0] != '-'); + args = myargc; + break; } - else + else if (!strcasecmp(myargv[p], "-warp") || + !strcasecmp(myargv[p], "-recordfrom")) + { + args = 2; + break; + } + else if (!strcasecmp(myargv[p], params_with_args[i])) { - i++; + args = 1; + break; } + } + + if (args > 0) + { + int check = CheckArgs(p, args); + + if (!check) + I_Error("No parameter for %s", myargv[p]); + else + p = check; continue; } - CheckParams(i); + for (i = 0; i < arrlen(params); ++i) + { + if (!strcasecmp(myargv[p], params[i])) + break; + } + + if (i == arrlen(params)) + I_Error("No such option %s", myargv[p]); + + ++p; } } #endif diff --git a/src/m_argv.h b/src/m_argv.h index ee42b5957..f95ea9c27 100644 --- a/src/m_argv.h +++ b/src/m_argv.h @@ -53,6 +53,8 @@ boolean M_ParmExists(const char *check); boolean M_CheckCommandLine(void); #endif +boolean M_ParmStrToInt(const char *str, int *result); + #endif //---------------------------------------------------------------------------- From 67f1f145e995008c0974b4790dc9ff35eb867152 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Mon, 11 Jul 2022 00:40:46 +0700 Subject: [PATCH 06/26] add validation for some arguments --- src/d_main.c | 36 ++++++++++++++++++++++++++---------- src/g_game.c | 3 +++ 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 10846983d..e209224c3 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -2137,10 +2137,19 @@ void D_DoomMain(void) // if ((p = M_CheckParm ("-skill")) && p < myargc-1) - { - startskill = myargv[p+1][0]-'1'; - autostart = true; - } + { + if (M_ParmStrToInt(myargv[p+1], (int *)&startskill) && + startskill > sk_none && startskill <= sk_nightmare) + { + autostart = true; + } + else + { + I_Error("Wrong -skill parameter '%s', valid values are 1-5 " + "(1: easiest, 5: hardest). " + "A skill of 0 disables all monsters.", myargv[p+1]); + } + } //! // @category game @@ -2152,9 +2161,16 @@ void D_DoomMain(void) if ((p = M_CheckParm ("-episode")) && p < myargc-1) { - startepisode = myargv[p+1][0]-'0'; - startmap = 1; - autostart = true; + if (M_ParmStrToInt(myargv[p+1], &startepisode) && + startepisode >= 1 && startepisode <= 4) + { + startmap = 1; + autostart = true; + } + else + { + I_Error("Wrong -episode parameter '%s', should be 1-4", myargv[p+1]); + } } //! @@ -2167,9 +2183,9 @@ void D_DoomMain(void) if ((p = M_CheckParm ("-timer")) && p < myargc-1 && deathmatch) { - int time = atoi(myargv[p+1]); - timelimit = time; - printf("Levels will end after %d minute%s.\n", time, time>1 ? "s" : ""); + if (!M_ParmStrToInt(myargv[p+1], &timelimit)) + I_Error("Wrong -timer parameter '%s', valid value n minutes", myargv[p+1]); + printf("Levels will end after %d minute%s.\n", timelimit, timelimit>1 ? "s" : ""); } //! diff --git a/src/g_game.c b/src/g_game.c index cc83d80fa..9207ac9ae 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2773,6 +2773,9 @@ void G_ReloadDefaults(void) int l = G_GetNamedComplevel(myargv[i+1]); if (l > -1) demo_version = l; + else + I_Error("Wrong -complevel parameter '%s', " + "valid values are 'vanilla', 'boom', 'mbf', 'mbf21'", myargv[i+1]); } } From be53c42ae8437051b854d32156eeadf70211af0d Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Mon, 11 Jul 2022 02:31:09 +0700 Subject: [PATCH 07/26] fix skill 0 --- src/d_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index e209224c3..5d11b575c 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -2138,8 +2138,9 @@ void D_DoomMain(void) if ((p = M_CheckParm ("-skill")) && p < myargc-1) { - if (M_ParmStrToInt(myargv[p+1], (int *)&startskill) && - startskill > sk_none && startskill <= sk_nightmare) + boolean check = M_ParmStrToInt(myargv[p+1], (int *)&startskill); + startskill--; + if (check && startskill >= sk_none && startskill <= sk_nightmare) { autostart = true; } From 25381d535a080bfaf676c75dfc7a53f7e4e4e406 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Tue, 12 Jul 2022 12:51:40 +0700 Subject: [PATCH 08/26] validate all parameters with argumets --- src/.gitignore | 1 + src/d_loop.c | 4 ++-- src/d_main.c | 35 +++++++++++++++++++---------------- src/g_game.c | 4 ++-- src/i_system.c | 8 +++++++- src/m_argv.c | 45 +++++++++++++++++++++++++++++++++++++++++---- src/m_argv.h | 3 ++- src/m_menu.c | 12 ++++++++---- src/net_gui.c | 2 +- src/net_sdl.c | 2 +- src/p_map.c | 3 ++- src/p_spec.c | 2 +- 12 files changed, 87 insertions(+), 34 deletions(-) create mode 100644 src/.gitignore diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 000000000..8e69d0489 --- /dev/null +++ b/src/.gitignore @@ -0,0 +1 @@ +params.h diff --git a/src/d_loop.c b/src/d_loop.c index e4f76a344..34b3023f4 100644 --- a/src/d_loop.c +++ b/src/d_loop.c @@ -356,7 +356,7 @@ void D_StartNetGame(net_gamesettings_t *settings, i = M_CheckParmWithArgs("-extratics", 1); if (i > 0) - settings->extratics = atoi(myargv[i+1]); + settings->extratics = M_ParmArgToInt(i); else settings->extratics = 1; @@ -371,7 +371,7 @@ void D_StartNetGame(net_gamesettings_t *settings, i = M_CheckParmWithArgs("-dup", 1); if (i > 0) - settings->ticdup = atoi(myargv[i+1]); + settings->ticdup = M_ParmArgToInt(i); else settings->ticdup = 1; diff --git a/src/d_main.c b/src/d_main.c index 5d11b575c..a4520f487 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -592,8 +592,8 @@ static boolean D_AddZipFile(const char *file) memset(&zip_archive, 0, sizeof(zip_archive)); if (!mz_zip_reader_init_file(&zip_archive, file, MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) { - printf("D_AddZipFile: Failed to open %s\n", file); - return true; + I_Error("D_AddZipFile: Failed to open %s\n", file); + return false; } str = M_StringJoin("_", PROJECT_SHORTNAME, "_", M_BaseName(file), NULL); @@ -2023,7 +2023,7 @@ void D_DoomMain(void) extern int sidemove[2]; if (p 400) @@ -2138,9 +2138,9 @@ void D_DoomMain(void) if ((p = M_CheckParm ("-skill")) && p < myargc-1) { - boolean check = M_ParmStrToInt(myargv[p+1], (int *)&startskill); + startskill = M_ParmArgToInt(p); startskill--; - if (check && startskill >= sk_none && startskill <= sk_nightmare) + if (startskill >= sk_none && startskill <= sk_nightmare) { autostart = true; } @@ -2157,20 +2157,20 @@ void D_DoomMain(void) // @arg // @vanilla // - // Start playing on episode n (1-4) + // Start playing on episode n (0-99) // if ((p = M_CheckParm ("-episode")) && p < myargc-1) { - if (M_ParmStrToInt(myargv[p+1], &startepisode) && - startepisode >= 1 && startepisode <= 4) + startepisode = M_ParmArgToInt(p); + if (startepisode >= 0 && startepisode <= 99) { startmap = 1; autostart = true; } else { - I_Error("Wrong -episode parameter '%s', should be 1-4", myargv[p+1]); + I_Error("Wrong -episode parameter '%s', valid values are 0-99", myargv[p+1]); } } @@ -2184,8 +2184,7 @@ void D_DoomMain(void) if ((p = M_CheckParm ("-timer")) && p < myargc-1 && deathmatch) { - if (!M_ParmStrToInt(myargv[p+1], &timelimit)) - I_Error("Wrong -timer parameter '%s', valid value n minutes", myargv[p+1]); + timelimit = M_ParmArgToInt(p); printf("Levels will end after %d minute%s.\n", timelimit, timelimit>1 ? "s" : ""); } @@ -2216,21 +2215,21 @@ void D_DoomMain(void) { if (gamemode == commercial) { - startmap = atoi(myargv[p+1]); + startmap = M_ParmArgToInt(p); autostart = true; } else // 1/25/98 killough: fix -warp xxx from crashing Doom 1 / UD // [crispy] only if second argument is not another option if (p < myargc-2 && myargv[p+2][0] != '-') { - startepisode = atoi(myargv[++p]); - startmap = atoi(myargv[p+1]); + startepisode = M_ParmArgToInt(p); + startmap = M_ParmArg2ToInt(p); autostart = true; } // [crispy] allow second digit without space in between for Doom 1 else { - int em = atoi(myargv[++p]); + int em = M_ParmArgToInt(p); startepisode = em / 10; startmap = em % 10; autostart = true; @@ -2400,7 +2399,7 @@ void D_DoomMain(void) p = M_CheckParmWithArgs("-loadgame", 1); if (p) { - startloadgame = atoi(myargv[p+1]); + startloadgame = M_ParmArgToInt(p); } else { @@ -2487,6 +2486,10 @@ void D_DoomMain(void) { demoskip_tics = (int) (sec * TICRATE); } + else + { + I_Error("Wrong -skipsec parameter '%s', should be min:sec", myargv[p+1]); + } demoskip_tics = abs(demoskip_tics); } diff --git a/src/g_game.c b/src/g_game.c index 9207ac9ae..b699884b8 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2544,7 +2544,7 @@ static int G_GetHelpers(void) // j = M_CheckParm ("-dogs"); - return j ? j+1 < myargc ? atoi(myargv[j+1]) : 1 : default_dogs; + return j ? j+1 < myargc ? M_ParmArgToInt(j) : 1 : default_dogs; } // [FG] support named complevels on the command line, e.g. "-complevel boom", @@ -3086,7 +3086,7 @@ void G_RecordDemo(char *name) i = M_CheckParm ("-maxdemo"); if (i && i #include +#include "i_system.h" int myargc; char **myargv; @@ -70,14 +71,32 @@ boolean M_ParmExists(const char *check) return M_CheckParm(check) != 0; } -boolean M_ParmStrToInt(const char *str, int *result) +static int ArgToInt(int p, int arg) +{ + int result; + + if (p + arg >= myargc) + I_Error("No parameter for %s", myargv[p]); + + if (sscanf(myargv[p + arg], " %d", &result) != 1) + I_Error("Wrong %s parameter '%s', should be a number", myargv[p], myargv[p + arg]); + + return result; +} + +int M_ParmArgToInt(int p) +{ + return ArgToInt(p, 1); +} + +int M_ParmArg2ToInt(int p) { - return sscanf(str, " %d", result) == 1; + return ArgToInt(p, 2); } + #if defined(HAVE_GEN_PARAMS) #include "params.h" -#include "i_system.h" static int CheckArgs(int p, int num_args) { @@ -133,9 +152,27 @@ void M_CheckCommandLine(void) int check = CheckArgs(p, args); if (!check) - I_Error("No parameter for %s", myargv[p]); + { + // -turbo has default value + if (!strcasecmp(myargv[p], "-turbo")) + { + ++p; + } + // -statdump allow "-" parameter + else if (!strcasecmp(myargv[p], "-statdump") && + p + 1 < myargc && !strcmp(myargv[p + 1], "-")) + { + p += 2; + } + else + { + I_Error("No parameter for %s", myargv[p]); + } + } else + { p = check; + } continue; } diff --git a/src/m_argv.h b/src/m_argv.h index f95ea9c27..724bf20f3 100644 --- a/src/m_argv.h +++ b/src/m_argv.h @@ -53,7 +53,8 @@ boolean M_ParmExists(const char *check); boolean M_CheckCommandLine(void); #endif -boolean M_ParmStrToInt(const char *str, int *result); +int M_ParmArgToInt(int p); +int M_ParmArg2ToInt(int p); #endif diff --git a/src/m_menu.c b/src/m_menu.c index ed2642b74..1db665ba8 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3843,7 +3843,9 @@ static void M_ResetTimeScale(void) I_SetTimeScale(100); else { - int p, time_scale; + int p; + + int time_scale = realtic_clock_rate; //! // @arg @@ -3855,9 +3857,11 @@ static void M_ResetTimeScale(void) p = M_CheckParmWithArgs("-speed", 1); if (p) - time_scale = BETWEEN(10, 1000, atoi(myargv[p+1])); - else - time_scale = realtic_clock_rate; + { + time_scale = M_ParmArgToInt(p); + if (time_scale < 10 || time_scale > 1000) + I_Error("Wrong -speed parameter '%d', valid values are 10-1000", time_scale); + } I_SetTimeScale(time_scale); } diff --git a/src/net_gui.c b/src/net_gui.c index 632453d8e..4fd3b3a2d 100644 --- a/src/net_gui.c +++ b/src/net_gui.c @@ -251,7 +251,7 @@ static void ParseCommandLineArgs(void) i = M_CheckParmWithArgs("-nodes", 1); if (i > 0) { - expected_nodes = atoi(myargv[i + 1]); + expected_nodes = M_ParmArgToInt(i); } } diff --git a/src/net_sdl.c b/src/net_sdl.c index ba0689df0..4f31a75fd 100644 --- a/src/net_sdl.c +++ b/src/net_sdl.c @@ -170,7 +170,7 @@ static boolean NET_SDL_InitClient(void) p = M_CheckParmWithArgs("-port", 1); if (p > 0) - port = atoi(myargv[p+1]); + port = M_ParmArgToInt(p); SDLNet_Init(); diff --git a/src/p_map.c b/src/p_map.c index 214c6b7b4..4bfa17114 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2309,7 +2309,8 @@ static void SpechitOverrun(line_t *ld) if (p > 0) { - M_StrToInt(myargv[p+1], (int *) &baseaddr); + if (!M_StrToInt(myargv[p+1], (int *) &baseaddr)) + I_Error("Wrong -spechit parameter '%s'", myargv[p+1]); } else { diff --git a/src/p_spec.c b/src/p_spec.c index 26ab6b1a8..3d19a49fc 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2392,7 +2392,7 @@ void P_SpawnSpecials (void) if (i && deathmatch) { int frags; - frags = atoi(myargv[i+1]); + frags = M_ParmArgToInt(i); if (frags <= 0) frags = 10; // default 10 if no count provided levelFragLimit = true; levelFragLimitCount = frags; From 077782b2bbd939d5311b527670a3f165cae723a6 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Tue, 12 Jul 2022 13:28:48 +0700 Subject: [PATCH 09/26] cosmetic fixes --- src/d_main.c | 7 ++++--- src/g_game.c | 5 +++-- src/i_system.c | 4 ++-- src/m_argv.c | 8 ++++---- src/m_menu.c | 3 ++- src/p_map.c | 2 +- 6 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index a4520f487..7f92d99fb 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -2146,7 +2146,7 @@ void D_DoomMain(void) } else { - I_Error("Wrong -skill parameter '%s', valid values are 1-5 " + I_Error("Invalid parameter '%s' for -skill, valid values are 1-5 " "(1: easiest, 5: hardest). " "A skill of 0 disables all monsters.", myargv[p+1]); } @@ -2170,7 +2170,8 @@ void D_DoomMain(void) } else { - I_Error("Wrong -episode parameter '%s', valid values are 0-99", myargv[p+1]); + I_Error("Invalid parameter '%s' for -episode, valid values are 0-99.", + myargv[p+1]); } } @@ -2488,7 +2489,7 @@ void D_DoomMain(void) } else { - I_Error("Wrong -skipsec parameter '%s', should be min:sec", myargv[p+1]); + I_Error("Invalid parameter '%s' for -skipsec, should be min:sec", myargv[p+1]); } demoskip_tics = abs(demoskip_tics); diff --git a/src/g_game.c b/src/g_game.c index b699884b8..eeed3930d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2774,8 +2774,9 @@ void G_ReloadDefaults(void) if (l > -1) demo_version = l; else - I_Error("Wrong -complevel parameter '%s', " - "valid values are 'vanilla', 'boom', 'mbf', 'mbf21'", myargv[i+1]); + I_Error("Invalid parameter '%s' for -complevel, " + "valid values are vanilla, boom, mbf, mbf21.", + myargv[i+1]); } } diff --git a/src/i_system.c b/src/i_system.c index d3ae8979b..ed96c0276 100644 --- a/src/i_system.c +++ b/src/i_system.c @@ -306,8 +306,8 @@ boolean I_GetMemoryValue(unsigned int offset, void *value, int size) if (!M_StrToInt(myargv[p], &val)) { - I_Error("Wrong -setmem parameter '%s', " - "valid values are: dos622, dos71, dosbox " + I_Error("Invalid parameter '%s' for -setmem, " + "valid values are dos622, dos71, dosbox " "or memory offset.", myargv[p]); } diff --git a/src/m_argv.c b/src/m_argv.c index 6c5477f45..b4602631a 100644 --- a/src/m_argv.c +++ b/src/m_argv.c @@ -76,10 +76,10 @@ static int ArgToInt(int p, int arg) int result; if (p + arg >= myargc) - I_Error("No parameter for %s", myargv[p]); + I_Error("No parameter for '%s'.", myargv[p]); if (sscanf(myargv[p + arg], " %d", &result) != 1) - I_Error("Wrong %s parameter '%s', should be a number", myargv[p], myargv[p + arg]); + I_Error("Invalid parameter '%s' for %s, must be a number.", myargv[p + arg], myargv[p]); return result; } @@ -166,7 +166,7 @@ void M_CheckCommandLine(void) } else { - I_Error("No parameter for %s", myargv[p]); + I_Error("No parameter for '%s'.", myargv[p]); } } else @@ -184,7 +184,7 @@ void M_CheckCommandLine(void) } if (i == arrlen(params)) - I_Error("No such option %s", myargv[p]); + I_Error("No such option '%s'.", myargv[p]); ++p; } diff --git a/src/m_menu.c b/src/m_menu.c index 1db665ba8..36e47d24f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3860,7 +3860,8 @@ static void M_ResetTimeScale(void) { time_scale = M_ParmArgToInt(p); if (time_scale < 10 || time_scale > 1000) - I_Error("Wrong -speed parameter '%d', valid values are 10-1000", time_scale); + I_Error("Invalid parameter '%s' for -speed, valid values are 10-1000.", + time_scale); } I_SetTimeScale(time_scale); diff --git a/src/p_map.c b/src/p_map.c index 4bfa17114..3b6936010 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2310,7 +2310,7 @@ static void SpechitOverrun(line_t *ld) if (p > 0) { if (!M_StrToInt(myargv[p+1], (int *) &baseaddr)) - I_Error("Wrong -spechit parameter '%s'", myargv[p+1]); + I_Error("Invalid parameter '%s' for -spechit.", myargv[p+1]); } else { From ed892141a80218fbd907c91fe43391c2aeaefa8f Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Tue, 12 Jul 2022 13:35:43 +0700 Subject: [PATCH 10/26] don't check undocumented options if -devparm is set --- src/d_main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/d_main.c b/src/d_main.c index 7f92d99fb..e81924550 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1784,7 +1784,11 @@ void D_DoomMain(void) I_AtExitPrio(I_ErrorMsg, true, "I_ErrorMsg", exit_priority_verylast); #if defined(HAVE_GEN_PARAMS) - M_CheckCommandLine(); + // Don't check undocumented options if -devparm is set + if (!M_ParmExists("-devparm")) + { + M_CheckCommandLine(); + } #endif dsdh_InitTables(); From 1b13549f3bf0d7049ecb0d260782d7eb529134d1 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Tue, 12 Jul 2022 13:41:22 +0700 Subject: [PATCH 11/26] fix format error --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 36e47d24f..e3f8255aa 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3860,7 +3860,7 @@ static void M_ResetTimeScale(void) { time_scale = M_ParmArgToInt(p); if (time_scale < 10 || time_scale > 1000) - I_Error("Invalid parameter '%s' for -speed, valid values are 10-1000.", + I_Error("Invalid parameter '%d' for -speed, valid values are 10-1000.", time_scale); } From 38e0fb76af8d89c3272204fb2b1cb2e53a06ff83 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Tue, 12 Jul 2022 13:41:45 +0700 Subject: [PATCH 12/26] fix whitespace --- src/d_main.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index e81924550..14906b29f 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -2168,15 +2168,15 @@ void D_DoomMain(void) { startepisode = M_ParmArgToInt(p); if (startepisode >= 0 && startepisode <= 99) - { - startmap = 1; - autostart = true; - } - else - { - I_Error("Invalid parameter '%s' for -episode, valid values are 0-99.", - myargv[p+1]); - } + { + startmap = 1; + autostart = true; + } + else + { + I_Error("Invalid parameter '%s' for -episode, valid values are 0-99.", + myargv[p+1]); + } } //! From 37896b8b067b2eceb0ec52e98a35ac2fc18d5485 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Tue, 12 Jul 2022 15:42:02 +0700 Subject: [PATCH 13/26] docgen cleanup --- man/docgen | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/man/docgen b/man/docgen index a40a9a2c5..516bceee8 100644 --- a/man/docgen +++ b/man/docgen @@ -38,14 +38,6 @@ import getopt TEXT_WRAP_WIDTH = 78 INCLUDE_STATEMENT_RE = re.compile("@include\s+(\S+)") -# Use appropriate stdout function for Python 2 or 3 - -def stdout(buf): - if sys.version_info.major < 3: - sys.stdout.write(buf) - else: - sys.stdout.buffer.write(buf) - # Find the maximum width of a list of parameters (for plain text output) def parameter_list_width(params): @@ -142,24 +134,13 @@ class Category: return result - def carray_output(self): - result = "" - - self.params.sort() - - for p in self.params: - if p.should_show() and not p.args: - result += "\"" + p.carray_output(0) + "\",\n" - - return result - - def carray_output_args(self): + def carray_output(self, check_args): result = "" self.params.sort() for p in self.params: - if p.should_show() and p.args: + if p.should_show() and p.args if check_args else not p.args: result += "\"" + p.carray_output(0) + "\",\n" return result @@ -511,7 +492,6 @@ def print_template(template_file, substs, content): for k,v in substs.items(): line = line.replace(k,v) print(line.rstrip()) - # stdout(line.rstrip().encode('UTF-8') + b'\n') finally: f.close() @@ -531,7 +511,6 @@ def wiki_output(targets, _, template): for t in targets: print(st.wiki_output()) - # stdout(t.wiki_output().encode('UTF-8') + b'\n') def markdown_output(targets, substs, template_file): content = "" @@ -564,12 +543,12 @@ def carray_output(targets, substs, template): content = "\nstatic const char *params[] = {\n" for t in targets: - content += t.carray_output() + content += t.carray_output(0) content += "};\n\nstatic const char *params_with_args[] = {\n" for t in targets: - content += t.carray_output_args() + content += t.carray_output(1) content += "};\n" From d637a8afca52e6d5ed4d970507040d8cb64a0aac Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Tue, 12 Jul 2022 15:43:02 +0700 Subject: [PATCH 14/26] rename GenParams->paramsgen --- man/CMakeLists.txt | 2 +- src/CMakeLists.txt | 4 ++-- src/d_main.c | 2 +- src/m_argv.c | 2 +- src/m_argv.h | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt index a287acbfe..f451cfe2c 100644 --- a/man/CMakeLists.txt +++ b/man/CMakeLists.txt @@ -1,6 +1,6 @@ if(Python3_EXECUTABLE) - add_custom_target(GenParams + add_custom_target(paramsgen COMMAND "${Python3_EXECUTABLE}" docgen -a "${PROJECT_SOURCE_DIR}/src" > "${PROJECT_SOURCE_DIR}/src/params.h" DEPENDS "${PROJECT_SOURCE_DIR}/src" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1e63be134..30048b399 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -155,8 +155,8 @@ target_woof_settings(woof) target_include_directories(woof PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../") if(Python3_EXECUTABLE) - add_dependencies(woof GenParams) - target_compile_definitions(woof PRIVATE HAVE_GEN_PARAMS) + add_dependencies(woof paramsgen) + target_compile_definitions(woof PRIVATE HAVE_PARAMS_GEN) endif() if (FluidSynth_FOUND) diff --git a/src/d_main.c b/src/d_main.c index 14906b29f..5689b0f2c 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1783,7 +1783,7 @@ void D_DoomMain(void) I_AtExitPrio(I_ErrorMsg, true, "I_ErrorMsg", exit_priority_verylast); -#if defined(HAVE_GEN_PARAMS) +#if defined(HAVE_PARAMS_GEN) // Don't check undocumented options if -devparm is set if (!M_ParmExists("-devparm")) { diff --git a/src/m_argv.c b/src/m_argv.c index b4602631a..f068c2535 100644 --- a/src/m_argv.c +++ b/src/m_argv.c @@ -95,7 +95,7 @@ int M_ParmArg2ToInt(int p) } -#if defined(HAVE_GEN_PARAMS) +#if defined(HAVE_PARAMS_GEN) #include "params.h" static int CheckArgs(int p, int num_args) diff --git a/src/m_argv.h b/src/m_argv.h index 724bf20f3..d4e647bbf 100644 --- a/src/m_argv.h +++ b/src/m_argv.h @@ -49,7 +49,7 @@ int M_CheckParmWithArgs(const char *check, int num_args); // line arguments, false if not. boolean M_ParmExists(const char *check); -#if defined(HAVE_GEN_PARAMS) +#if defined(HAVE_PARAMS_GEN) boolean M_CheckCommandLine(void); #endif From 6348fea370dec2625351634344b0ad5da2aed8f2 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Tue, 12 Jul 2022 20:35:04 +0700 Subject: [PATCH 15/26] fix -turbo check --- src/d_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_main.c b/src/d_main.c index 5689b0f2c..8ad49841d 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -2026,7 +2026,7 @@ void D_DoomMain(void) extern int forwardmove[2]; extern int sidemove[2]; - if (p Date: Tue, 12 Jul 2022 22:13:56 +0700 Subject: [PATCH 16/26] more docgen cleanup --- man/docgen | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/man/docgen b/man/docgen index 516bceee8..668166883 100644 --- a/man/docgen +++ b/man/docgen @@ -141,7 +141,7 @@ class Category: for p in self.params: if p.should_show() and p.args if check_args else not p.args: - result += "\"" + p.carray_output(0) + "\",\n" + result += "\"" + p.carray_output() + "\",\n" return result @@ -339,7 +339,7 @@ class Parameter: return result - def carray_output(self, w): + def carray_output(self): result = self.name From f3705c33e5ec35ab83c4feed2678520bc753ce0d Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Wed, 13 Jul 2022 01:31:40 +0700 Subject: [PATCH 17/26] generate help string --- man/docgen | 22 ++++++++++++++++------ src/d_iwad.c | 1 + src/d_loop.c | 3 +++ src/d_main.c | 25 ++++++++++++++++++++++--- src/d_net.c | 1 + src/g_game.c | 14 +++++++++++--- src/m_argv.c | 5 +++++ src/m_argv.h | 1 + src/net_server.c | 1 + 9 files changed, 61 insertions(+), 12 deletions(-) diff --git a/man/docgen b/man/docgen index 668166883..53870ef7a 100644 --- a/man/docgen +++ b/man/docgen @@ -93,7 +93,7 @@ class Category: # Plain text output - def plaintext_output(self): + def plaintext_output(self, check_help): result = "=== %s ===\n\n" % self.description self.params.sort() @@ -101,7 +101,7 @@ class Category: w = parameter_list_width(self.params) for p in self.params: - if p.should_show(): + if p.should_show() and p.help if check_help else True: result += p.plaintext_output(w) result = result.rstrip() + "\n" @@ -202,6 +202,7 @@ class Parameter: self.args = None self.platform = None self.category = None + self.help = False self.vanilla_option = False self.games = None @@ -226,6 +227,8 @@ class Parameter: self.platform = data elif option_type == "category": self.category = data + elif option_type == "help": + self.help = True elif option_type == "vanilla": self.vanilla_option = True elif option_type == "game": @@ -525,7 +528,7 @@ def plaintext_output(targets, substs, template_file): content = "" for t in targets: - content += t.plaintext_output() + "\n" + content += t.plaintext_output(False) + "\n" print_template(template_file, substs, content) @@ -543,14 +546,21 @@ def carray_output(targets, substs, template): content = "\nstatic const char *params[] = {\n" for t in targets: - content += t.carray_output(0) + content += t.carray_output(False) content += "};\n\nstatic const char *params_with_args[] = {\n" for t in targets: - content += t.carray_output(1) + content += t.carray_output(True) + + content += "};\n\n#define HELP_STRING \"" + + for t in targets: + # no video and obscure category + if t != categories[2][1] and t != categories[7][1]: + content += (t.plaintext_output(True) + "\n").replace("\n", "\\n\\\n") - content += "};\n" + content += "\"" print(content) diff --git a/src/d_iwad.c b/src/d_iwad.c index d9a20ba26..ceb30a5d8 100644 --- a/src/d_iwad.c +++ b/src/d_iwad.c @@ -656,6 +656,7 @@ char *D_FindIWADFile(GameMode_t *mode, GameMission_t *mission) // Specify an IWAD file to use. // // @arg + // @help // int iwadparm = M_CheckParmWithArgs("-iwad", 1); diff --git a/src/d_loop.c b/src/d_loop.c index 34b3023f4..34a9e33d0 100644 --- a/src/d_loop.c +++ b/src/d_loop.c @@ -433,6 +433,7 @@ boolean D_InitNetGame(net_connect_data_t *connect_data) //! // @category net + // @help // // Start a multiplayer server, listening for connections. // @@ -453,6 +454,7 @@ boolean D_InitNetGame(net_connect_data_t *connect_data) { //! // @category net + // @help // // Automatically search the local LAN for a multiplayer // server and join it. @@ -473,6 +475,7 @@ boolean D_InitNetGame(net_connect_data_t *connect_data) //! // @arg
// @category net + // @help // // Connect to a multiplayer server running on the given // address. diff --git a/src/d_main.c b/src/d_main.c index 8ad49841d..ddf7e499c 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1088,9 +1088,10 @@ static void InitGameVersion(void) //! // @arg // @category compat + // @help // - // Emulate a specific version of Doom. Valid values are "1.9", - // "ultimate", "final", "chex". + // Emulate a specific version of Doom. Valid values are 1.9, + // ultimate, final, chex. // p = M_CheckParm("-gameversion"); @@ -1407,6 +1408,7 @@ static void D_ProcessDehCommandLine(void) //! // @arg // @category mod + // @help // // Load the given dehacked/bex patch(es). // @@ -1789,6 +1791,17 @@ void D_DoomMain(void) { M_CheckCommandLine(); } + + //! + // + // Print command line help. + // + + if (M_ParmExists("-help")) + { + M_PrintHelpString(); + I_SafeExit(0); + } #endif dsdh_InitTables(); @@ -1871,6 +1884,7 @@ void D_DoomMain(void) //! // @category game + // @help // // Enables automatic pistol starts on each level. // @@ -2057,6 +2071,7 @@ void D_DoomMain(void) //! // @arg // @vanilla + // @help // // Load the specified PWAD files. // @@ -2084,6 +2099,7 @@ void D_DoomMain(void) // @arg // @category demo // @vanilla + // @help // // Play back the demo named demo.lmp. // @@ -2135,6 +2151,7 @@ void D_DoomMain(void) // @category game // @arg // @vanilla + // @help // // Set the game skill, 1-5 (1: easiest, 5: hardest). A skill of // 0 disables all monsters. @@ -2210,6 +2227,7 @@ void D_DoomMain(void) // @category game // @arg [ | ] // @vanilla + // @help // // Start a game immediately, warping to ExMy (Doom 1) or MAPxy // (Doom 2) @@ -2475,7 +2493,7 @@ void D_DoomMain(void) // @category demo // // Skip min:sec time during viewing of the demo. - // "-warp -skipsec " will skip min:sec time on level x. + // '-warp -skipsec ' will skip min:sec time on level x. // p = M_CheckParmWithArgs("-skipsec", 1); @@ -2523,6 +2541,7 @@ void D_DoomMain(void) // @arg // @category demo // @vanilla + // @help // // Record a demo named demo.lmp. // diff --git a/src/d_net.c b/src/d_net.c index 292de36c8..2503b596b 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -224,6 +224,7 @@ static void InitConnectData(net_connect_data_t *connect_data) //! // @category demo + // @help // // Play with low turning resolution to emulate demo recording. // diff --git a/src/g_game.c b/src/g_game.c index eeed3930d..a66dba7f3 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1144,7 +1144,13 @@ static void G_DoCompleted(void) { int i; - // [crispy] Write level statistics upon exit + //! + // @category demo + // @help + // + // Write level statistics upon exit to levelstat.txt + // + if (M_CheckParm("-levelstat")) { G_WriteLevelStat(); @@ -2761,9 +2767,10 @@ void G_ReloadDefaults(void) //! // @arg // @category compat + // @help // // Emulate a specific version of Doom/Boom/MBF. Valid values are - // "vanilla", "boom", "mbf", "mbf21". + // vanilla, boom, mbf, mbf21. // int i = M_CheckParmWithArgs("-complevel", 1); @@ -2786,7 +2793,8 @@ void G_ReloadDefaults(void) strictmode = default_strictmode; //! - // @category compat + // @category demo + // @help // // Sets compatibility and cosmetic settings according to DSDA rules. // diff --git a/src/m_argv.c b/src/m_argv.c index f068c2535..0fd63f5da 100644 --- a/src/m_argv.c +++ b/src/m_argv.c @@ -189,6 +189,11 @@ void M_CheckCommandLine(void) ++p; } } + +void M_PrintHelpString(void) +{ + printf(HELP_STRING); +} #endif //---------------------------------------------------------------------------- diff --git a/src/m_argv.h b/src/m_argv.h index d4e647bbf..3e336e9a3 100644 --- a/src/m_argv.h +++ b/src/m_argv.h @@ -51,6 +51,7 @@ boolean M_ParmExists(const char *check); #if defined(HAVE_PARAMS_GEN) boolean M_CheckCommandLine(void); +void M_PrintHelpString(void); #endif int M_ParmArgToInt(int p); diff --git a/src/net_server.c b/src/net_server.c index cf984851c..afd0f6c65 100644 --- a/src/net_server.c +++ b/src/net_server.c @@ -1911,6 +1911,7 @@ void NET_SV_RegisterWithMaster(void) { //! // @category net + // @help // // When running a server, don't register with the global master server. // Implies -server. From 86affe6d87a737c500050653444f3d67b463f2db Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Wed, 13 Jul 2022 02:18:08 +0700 Subject: [PATCH 18/26] use dictionary --- man/docgen | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/man/docgen b/man/docgen index 53870ef7a..71c7eeee0 100644 --- a/man/docgen +++ b/man/docgen @@ -555,9 +555,11 @@ def carray_output(targets, substs, template): content += "};\n\n#define HELP_STRING \"" + category = dict(categories) + for t in targets: # no video and obscure category - if t != categories[2][1] and t != categories[7][1]: + if t != category.get("video") and t != category.get("obscure"): content += (t.plaintext_output(True) + "\n").replace("\n", "\\n\\\n") content += "\"" From 91523423e07c09bde6c08b012528750f665c3ba0 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Wed, 13 Jul 2022 03:35:54 +0700 Subject: [PATCH 19/26] condense help text --- man/docgen | 44 ++++++++++++++++++++++++++++++++++++++++---- src/d_main.c | 9 ++++----- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/man/docgen b/man/docgen index 71c7eeee0..75e808dc8 100644 --- a/man/docgen +++ b/man/docgen @@ -34,6 +34,7 @@ import os import re import glob import getopt +import textwrap TEXT_WRAP_WIDTH = 78 INCLUDE_STATEMENT_RE = re.compile("@include\s+(\S+)") @@ -93,7 +94,7 @@ class Category: # Plain text output - def plaintext_output(self, check_help): + def plaintext_output(self): result = "=== %s ===\n\n" % self.description self.params.sort() @@ -101,13 +102,33 @@ class Category: w = parameter_list_width(self.params) for p in self.params: - if p.should_show() and p.help if check_help else True: + if p.should_show(): result += p.plaintext_output(w) result = result.rstrip() + "\n" return result + def help_output(self): + result = self.description + ": \n" + + self.params.sort() + + params_help = [] + + for p in self.params: + if p.should_show() and p.help: + params_help.append(p) + + w = parameter_list_width(params_help) + + for p in params_help: + result += p.help_output(w) + + result = result.rstrip() + "\n" + + return result + def markdown_output(self): result = "## %s\n\n| Parameter | Description |\n| - | - |\n" % self.description @@ -281,6 +302,21 @@ class Parameter: return result + def help_output(self, indent): + result = self.name + + if self.args: + result += " " + self.args + + result += " " * (indent - len(result)) + + result += textwrap.fill(self.text, width = (90 - indent), + subsequent_indent = (" " * indent)) + + result += "\n" + + return result + def markdown_output(self): if self.args: name = "%s %s" % (self.name, self.args) @@ -528,7 +564,7 @@ def plaintext_output(targets, substs, template_file): content = "" for t in targets: - content += t.plaintext_output(False) + "\n" + content += t.plaintext_output() + "\n" print_template(template_file, substs, content) @@ -560,7 +596,7 @@ def carray_output(targets, substs, template): for t in targets: # no video and obscure category if t != category.get("video") and t != category.get("obscure"): - content += (t.plaintext_output(True) + "\n").replace("\n", "\\n\\\n") + content += (t.help_output() + "\n").replace("\n", "\\n\\\n") content += "\"" diff --git a/src/d_main.c b/src/d_main.c index ddf7e499c..c65ddd80d 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1090,7 +1090,7 @@ static void InitGameVersion(void) // @category compat // @help // - // Emulate a specific version of Doom. Valid values are 1.9, + // Emulate a specific version of Doom. Valid values are 1.9, // ultimate, final, chex. // @@ -2153,8 +2153,8 @@ void D_DoomMain(void) // @vanilla // @help // - // Set the game skill, 1-5 (1: easiest, 5: hardest). A skill of - // 0 disables all monsters. + // Set the game skill, 1-5 (1: easiest, 5: hardest). A skill of 0 disables all + // monsters. // if ((p = M_CheckParm ("-skill")) && p < myargc-1) @@ -2229,8 +2229,7 @@ void D_DoomMain(void) // @vanilla // @help // - // Start a game immediately, warping to ExMy (Doom 1) or MAPxy - // (Doom 2) + // Start a game immediately, warping to ExMy (Doom 1) or MAPxy (Doom 2). // if (((p = M_CheckParm ("-warp")) || // killough 5/2/98 From c163642850ffd5215e0a24ff7a2d485a30492489 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Wed, 13 Jul 2022 09:45:09 +0700 Subject: [PATCH 20/26] escape `"` --- man/docgen | 5 ++++- src/d_main.c | 4 ++-- src/g_game.c | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/man/docgen b/man/docgen index 75e808dc8..687ad0cb4 100644 --- a/man/docgen +++ b/man/docgen @@ -596,7 +596,10 @@ def carray_output(targets, substs, template): for t in targets: # no video and obscure category if t != category.get("video") and t != category.get("obscure"): - content += (t.help_output() + "\n").replace("\n", "\\n\\\n") + s = t.help_output() + "\n"; + s = s.replace("\"", "\\\"") + s = s.replace("\n", "\\n\\\n") + content += s content += "\"" diff --git a/src/d_main.c b/src/d_main.c index c65ddd80d..36d35d07c 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1090,8 +1090,8 @@ static void InitGameVersion(void) // @category compat // @help // - // Emulate a specific version of Doom. Valid values are 1.9, - // ultimate, final, chex. + // Emulate a specific version of Doom. Valid values are "1.9", + // "ultimate", "final", "chex". // p = M_CheckParm("-gameversion"); diff --git a/src/g_game.c b/src/g_game.c index a66dba7f3..61c4bc3fe 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2770,7 +2770,7 @@ void G_ReloadDefaults(void) // @help // // Emulate a specific version of Doom/Boom/MBF. Valid values are - // vanilla, boom, mbf, mbf21. + // "vanilla", "boom", "mbf", "mbf21". // int i = M_CheckParmWithArgs("-complevel", 1); From 666b1af117f220de14711b5493670f333c54d817 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Wed, 13 Jul 2022 09:49:06 +0700 Subject: [PATCH 21/26] remove -gameversion from help string --- src/d_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 36d35d07c..7b026da98 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1088,10 +1088,9 @@ static void InitGameVersion(void) //! // @arg // @category compat - // @help // // Emulate a specific version of Doom. Valid values are "1.9", - // "ultimate", "final", "chex". + // "ultimate", "final", "chex". Implies -complevel vanilla. // p = M_CheckParm("-gameversion"); From 59273d98d189f7dcb1102e58ba770152f43f6aa3 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Wed, 13 Jul 2022 20:45:33 +0700 Subject: [PATCH 22/26] set wrap width to 80, few tweaks --- man/docgen | 5 +++-- src/d_main.c | 2 +- src/g_game.c | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/man/docgen b/man/docgen index 687ad0cb4..a026c33e5 100644 --- a/man/docgen +++ b/man/docgen @@ -310,9 +310,10 @@ class Parameter: result += " " * (indent - len(result)) - result += textwrap.fill(self.text, width = (90 - indent), - subsequent_indent = (" " * indent)) + print("text: " + self.text) + result += textwrap.fill(self.text, width = 80 - indent, + subsequent_indent = " " * indent) result += "\n" return result diff --git a/src/d_main.c b/src/d_main.c index 7b026da98..869bcd717 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -2224,7 +2224,7 @@ void D_DoomMain(void) //! // @category game - // @arg [ | ] + // @arg | // @vanilla // @help // diff --git a/src/g_game.c b/src/g_game.c index 61c4bc3fe..d8d8064af 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2765,7 +2765,7 @@ void G_ReloadDefaults(void) { //! - // @arg + // @arg // @category compat // @help // From 1b8846f2c9c54fe949b02a1f217b28d2887bde7a Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Wed, 13 Jul 2022 20:54:27 +0700 Subject: [PATCH 23/26] remove debug line --- man/docgen | 2 -- 1 file changed, 2 deletions(-) diff --git a/man/docgen b/man/docgen index a026c33e5..3756a0e7b 100644 --- a/man/docgen +++ b/man/docgen @@ -310,8 +310,6 @@ class Parameter: result += " " * (indent - len(result)) - print("text: " + self.text) - result += textwrap.fill(self.text, width = 80 - indent, subsequent_indent = " " * indent) result += "\n" From 96a1cbe35401671da50eb6a0f852248f684671b7 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Thu, 14 Jul 2022 09:05:38 +0700 Subject: [PATCH 24/26] -setmem error message correction --- man/docgen | 4 ++-- src/i_system.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/man/docgen b/man/docgen index 3756a0e7b..a8f6b3ca6 100644 --- a/man/docgen +++ b/man/docgen @@ -590,11 +590,11 @@ def carray_output(targets, substs, template): content += "};\n\n#define HELP_STRING \"" - category = dict(categories) + c = dict(categories) for t in targets: # no video and obscure category - if t != category.get("video") and t != category.get("obscure"): + if t != c["video"] and t != c["obscure"]: s = t.help_output() + "\n"; s = s.replace("\"", "\\\"") s = s.replace("\n", "\\n\\\n") diff --git a/src/i_system.c b/src/i_system.c index ed96c0276..f1d5d7ad1 100644 --- a/src/i_system.c +++ b/src/i_system.c @@ -308,7 +308,7 @@ boolean I_GetMemoryValue(unsigned int offset, void *value, int size) { I_Error("Invalid parameter '%s' for -setmem, " "valid values are dos622, dos71, dosbox " - "or memory offset.", myargv[p]); + "or memory dump (up to 10 bytes).", myargv[p]); } mem_dump_custom[i++] = (unsigned char) val; From cdd7dc1cd783225cb9e0c3471f6ef1837f5e7694 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Thu, 14 Jul 2022 13:44:02 +0700 Subject: [PATCH 25/26] fix -episode check and -skill description --- src/d_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 869bcd717..218c5a366 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -2153,7 +2153,7 @@ void D_DoomMain(void) // @help // // Set the game skill, 1-5 (1: easiest, 5: hardest). A skill of 0 disables all - // monsters. + // monsters only in -complevel vanilla. // if ((p = M_CheckParm ("-skill")) && p < myargc-1) @@ -2177,20 +2177,20 @@ void D_DoomMain(void) // @arg // @vanilla // - // Start playing on episode n (0-99) + // Start playing on episode n (1-99) // if ((p = M_CheckParm ("-episode")) && p < myargc-1) { startepisode = M_ParmArgToInt(p); - if (startepisode >= 0 && startepisode <= 99) + if (startepisode >= 1 && startepisode <= 99) { startmap = 1; autostart = true; } else { - I_Error("Invalid parameter '%s' for -episode, valid values are 0-99.", + I_Error("Invalid parameter '%s' for -episode, valid values are 1-99.", myargv[p+1]); } } From 34c5e2f4ed8c352c733e2ffe9d0c8f20445235bd Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Thu, 14 Jul 2022 13:45:58 +0700 Subject: [PATCH 26/26] little cleanup --- CMakeLists.txt | 2 +- src/d_main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 45b922a27..d0e7351b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -217,7 +217,7 @@ include(CPack) add_subdirectory(data) add_subdirectory(opl) add_subdirectory(textscreen) -add_subdirectory(man) add_subdirectory(src) add_subdirectory(toolsrc) add_subdirectory(setup) +add_subdirectory(man) diff --git a/src/d_main.c b/src/d_main.c index 218c5a366..159d4d517 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -2491,7 +2491,7 @@ void D_DoomMain(void) // @category demo // // Skip min:sec time during viewing of the demo. - // '-warp -skipsec ' will skip min:sec time on level x. + // "-warp -skipsec " will skip min:sec time on level x. // p = M_CheckParmWithArgs("-skipsec", 1);