static void FreeArgumentList(void) { while (--resp_argc >= 0) { GlbspFree(resp_argv[resp_argc]); } }
// // SetErrorMsg // void SetErrorMsg(const char *str, ...) { va_list args; va_start(args, str); vsnprintf(message_buf, sizeof(message_buf), str, args); va_end(args); GlbspFree(cur_comms->message); cur_comms->message = GlbspStrDup(message_buf); }
glbsp_ret_e GlbspParseArgs(nodebuildinfo_t *info, volatile nodebuildcomms_t *comms, const char ** argv, int argc) { const char *opt_str; int num_files = 0; int got_output = FALSE; cur_comms = comms; SetErrorMsg("(Unknown Problem)"); while (argc > 0) { if (argv[0][0] != '-') { // --- ORDINARY FILENAME --- if (got_output) { SetErrorMsg("Input filenames must precede the -o option"); cur_comms = NULL; return GLBSP_E_BadArgs; } if (CheckExtension(argv[0], "gwa")) { SetErrorMsg("Input file cannot be GWA (contains nothing to build)"); cur_comms = NULL; return GLBSP_E_BadArgs; } if (num_files >= 1) { AddExtraFile(info, GlbspStrDup(argv[0])); } else { GlbspFree(info->input_file); info->input_file = GlbspStrDup(argv[0]); } num_files++; argv++; argc--; continue; } // --- AN OPTION --- opt_str = &argv[0][1]; // handle GNU style options beginning with '--' if (opt_str[0] == '-') opt_str++; if (UtilStrCaseCmp(opt_str, "o") == 0) { if (got_output) { SetErrorMsg("The -o option cannot be used more than once"); cur_comms = NULL; return GLBSP_E_BadArgs; } if (num_files >= 2) { SetErrorMsg("Cannot use -o with multiple input files."); cur_comms = NULL; return GLBSP_E_BadArgs; } if (argc < 2 || argv[1][0] == '-') { SetErrorMsg("Missing filename for the -o option"); cur_comms = NULL; return GLBSP_E_BadArgs; } GlbspFree(info->output_file); info->output_file = GlbspStrDup(argv[1]); got_output = TRUE; argv += 2; argc -= 2; continue; } if (UtilStrCaseCmp(opt_str, "factor") == 0 || UtilStrCaseCmp(opt_str, "c") == 0) { if (argc < 2) { SetErrorMsg("Missing factor value"); cur_comms = NULL; return GLBSP_E_BadArgs; } info->factor = (int) strtol(argv[1], NULL, 10); argv += 2; argc -= 2; continue; } if (tolower(opt_str[0]) == 'v' && isdigit(opt_str[1])) { info->spec_version = (opt_str[1] - '0'); argv++; argc--; continue; } if (UtilStrCaseCmp(opt_str, "maxblock") == 0 || UtilStrCaseCmp(opt_str, "b") == 0) { if (argc < 2) { SetErrorMsg("Missing maxblock value"); cur_comms = NULL; return GLBSP_E_BadArgs; } info->block_limit = (int) strtol(argv[1], NULL, 10); argv += 2; argc -= 2; continue; } HANDLE_BOOLEAN2("q", "quiet", quiet) HANDLE_BOOLEAN2("f", "fast", fast) HANDLE_BOOLEAN2("w", "warn", mini_warnings) HANDLE_BOOLEAN2("p", "pack", pack_sides) HANDLE_BOOLEAN2("n", "normal", force_normal) HANDLE_BOOLEAN2("xr", "noreject", no_reject) HANDLE_BOOLEAN2("xp", "noprog", no_progress) HANDLE_BOOLEAN2("m", "mergevert", merge_vert) HANDLE_BOOLEAN2("u", "prunesec", prune_sect) HANDLE_BOOLEAN2("y", "windowfx", window_fx) HANDLE_BOOLEAN2("s", "skipselfref", skip_self_ref) HANDLE_BOOLEAN2("xu", "noprune", no_prune) HANDLE_BOOLEAN2("xn", "nonormal", no_normal) // to err is human... HANDLE_BOOLEAN("noprogress", no_progress) HANDLE_BOOLEAN("packsides", pack_sides) HANDLE_BOOLEAN("prunesect", prune_sect) // ignore these options for backwards compatibility if (UtilStrCaseCmp(opt_str, "fresh") == 0 || UtilStrCaseCmp(opt_str, "keepdummy") == 0 || UtilStrCaseCmp(opt_str, "keepsec") == 0 || UtilStrCaseCmp(opt_str, "keepsect") == 0) { argv++; argc--; continue; } // backwards compatibility HANDLE_BOOLEAN("forcegwa", gwa_mode) HANDLE_BOOLEAN("forcenormal", force_normal) HANDLE_BOOLEAN("loadall", load_all) // The -hexen option is only kept for backwards compatibility HANDLE_BOOLEAN("hexen", force_hexen) SetErrorMsg("Unknown option: %s", argv[0]); cur_comms = NULL; return GLBSP_E_BadArgs; } cur_comms = NULL; return GLBSP_E_OK; }
glbsp_ret_e GlbspCheckInfo(nodebuildinfo_t *info, volatile nodebuildcomms_t *comms) { cur_comms = comms; SetErrorMsg("(Unknown Problem)"); info->same_filenames = FALSE; info->missing_output = FALSE; if (!info->input_file || info->input_file[0] == 0) { SetErrorMsg("Missing input filename !"); return GLBSP_E_BadArgs; } if (CheckExtension(info->input_file, "gwa")) { SetErrorMsg("Input file cannot be GWA (contains nothing to build)"); return GLBSP_E_BadArgs; } if (!info->output_file || info->output_file[0] == 0) { GlbspFree(info->output_file); info->output_file = GlbspStrDup(ReplaceExtension( info->input_file, "gwa")); info->gwa_mode = TRUE; info->missing_output = TRUE; } else /* has output filename */ { if (CheckExtension(info->output_file, "gwa")) info->gwa_mode = TRUE; } if (UtilStrCaseCmp(info->input_file, info->output_file) == 0) { info->load_all = TRUE; info->same_filenames = TRUE; } if (info->no_prune && info->pack_sides) { info->pack_sides = FALSE; SetErrorMsg("-noprune and -packsides cannot be used together"); return GLBSP_E_BadInfoFixed; } if (info->gwa_mode && info->force_normal) { info->force_normal = FALSE; SetErrorMsg("-forcenormal used, but GWA files don't have normal nodes"); return GLBSP_E_BadInfoFixed; } if (info->no_normal && info->force_normal) { info->force_normal = FALSE; SetErrorMsg("-forcenormal and -nonormal cannot be used together"); return GLBSP_E_BadInfoFixed; } if (info->factor <= 0 || info->factor > 32) { info->factor = DEFAULT_FACTOR; SetErrorMsg("Bad factor value !"); return GLBSP_E_BadInfoFixed; } if (info->spec_version <= 0 || info->spec_version > 5) { info->spec_version = 2; SetErrorMsg("Bad GL-Nodes version number !"); return GLBSP_E_BadInfoFixed; } else if (info->spec_version == 4) { info->spec_version = 5; SetErrorMsg("V4 GL-Nodes is not supported"); return GLBSP_E_BadInfoFixed; } if (info->block_limit < 1000 || info->block_limit > 64000) { info->block_limit = DEFAULT_BLOCK_LIMIT; SetErrorMsg("Bad blocklimit value !"); return GLBSP_E_BadInfoFixed; } return GLBSP_E_OK; }
int main(int argc, char **argv) { int extra_idx = 0; TextStartup(); ShowTitle(); // skip program name itself argv++, argc--; if (argc <= 0) { ShowInfo(); TextShutdown(); exit(1); } if (strcmp(argv[0], "/?") == 0 || strcmp(argv[0], "-h") == 0 || strcmp(argv[0], "-help") == 0 || strcmp(argv[0], "--help") == 0 || strcmp(argv[0], "-HELP") == 0 || strcmp(argv[0], "--HELP") == 0) { ShowOptions(); TextShutdown(); exit(1); } BuildArgumentList(argc, argv); info = default_buildinfo; comms = default_buildcomms; if (GLBSP_E_OK != GlbspParseArgs(&info, &comms, resp_argv, resp_argc)) { TextFatalError("Error: %s\n", comms.message ? comms.message : "(Unknown error when parsing args)"); } if (info.extra_files) { int ext_j; /* catch this mistake: glbsp in.wad out.wad (forget the -o) */ if (info.input_file && info.extra_files[0] && ! info.extra_files[1] && FileExists(info.input_file) && ! FileExists(info.extra_files[0])) { TextFatalError("Error: Cannot find WAD file: %s (" "Maybe you forgot -o)\n", info.extra_files[0]); } /* balk NOW if any of the input files doesn't exist */ if (! FileExists(info.input_file)) TextFatalError("Error: Cannot find WAD file: %s\n", info.input_file); for (ext_j = 0; info.extra_files[ext_j]; ext_j++) { if (FileExists(info.extra_files[ext_j])) continue; TextFatalError("Error: Cannot find WAD file: %s\n", info.extra_files[ext_j]); } } /* process each input file */ for (;;) { if (GLBSP_E_OK != GlbspCheckInfo(&info, &comms)) { TextFatalError("Error: %s\n", comms.message ? comms.message : "(Unknown error when checking args)"); } if (info.no_progress) TextDisableProgress(); if (GLBSP_E_OK != GlbspBuildNodes(&info, &cmdline_funcs, &comms)) { TextFatalError("Error: %s\n", comms.message ? comms.message : "(Unknown error during build)"); } /* when there are extra input files, process them too */ if (! info.extra_files || ! info.extra_files[extra_idx]) break; ShowDivider(); GlbspFree(info.input_file); GlbspFree(info.output_file); info.input_file = GlbspStrDup(info.extra_files[extra_idx]); info.output_file = NULL; extra_idx++; } TextShutdown(); FreeArgumentList(); return 0; }