void parse_command_line(int argc, char *argv[], int spec) { const char *arg, *aispec; char tmpspec[100], tmpargbuf[CLIBUFSIZE], blurb[BLURBSIZE]; int i, n, numused, total_arg_space, tmpargbuflen = 0; /* This macro just checks that a required next argument is actually there. */ #define REQUIRE_ONE_ARG \ if (i + 1 >= argc) { \ fprintf(stderr, "Error: `%s' requires an argument, exiting now\n", argv[i]); \ had_error = TRUE; \ continue; \ } \ numused = 2; /* Each of these causes argument parsing to skip over the option if it's not the right time to look at it. */ #define GENERAL_OPTION if (spec != general_options) continue; #define VARIANT_OPTION if (spec != variant_options) continue; #define PLAYER_OPTION if (spec != player_options) continue; /* (should peel off any path stuff) */ program_name = argv[0]; if (spec == general_options) init_options(); total_arg_space = 0; for (i = 0; i < argc; ++i) { if (!empty_string(argv[i])) { strncpy(tmpargbuf, argv[i], CLIBUFSIZE); tmpargbuf[CLIBUFSIZE - 1] = 0; tmpargbuflen = strlen(tmpargbuf); total_arg_space += tmpargbuflen + 2; (argv[i])[tmpargbuflen] = 0; } } if (args_used == NULL) args_used = (char *)xmalloc (total_arg_space); for (i = 1; i < argc; ++i) { if (argv[i] == NULL || (argv[i])[0] == '\0') { /* Empty or already munched, nothing to do. */ } else if ((argv[i])[0] == '-') { arg = argv[i]; Dprintf("%s\n", arg); numused = 1; if (strcmp(arg, "-c") == 0) { REQUIRE_ONE_ARG; GENERAL_OPTION; checkpoint_interval = atoi(argv[i+1]); } else if (strcmp(arg, "-design") == 0) { GENERAL_OPTION; #ifdef DESIGNERS allbedesigners = TRUE; #else fprintf(stderr, "No designing available, ignoring option `%s'\n", arg); #endif /* DESIGNERS */ } else if (strncmp(arg, "-D", 2) == 0) { GENERAL_OPTION; #ifdef DEBUGGING Debug = TRUE; if (strchr(arg+2, '-')) Debug = FALSE; if (strchr(arg+2, 'M')) DebugM = TRUE; if (strchr(arg+2, 'G')) DebugG = TRUE; #else fprintf(stderr, "No debugging available, ignoring option `%s'\n", arg); #endif /* DEBUGGING */ } else if (strncmp(arg, "-e", 2) == 0) { REQUIRE_ONE_ARG; PLAYER_OPTION; n = atoi(argv[i+1]); /* A comma indicates that the name of a particular desired AI type follows. */ if (strlen(arg) > 2) { aispec = arg + 2; if (*aispec != ',') { sprintf(tmpspec, "%s%s", default_ai_type, aispec); aispec = tmpspec; } } else { aispec = default_ai_type; } while (n-- > 0) add_a_raw_player_spec(aispec); } else if (strcmp(arg, "-f") == 0) { REQUIRE_ONE_ARG; GENERAL_OPTION; add_a_module(NULL, argv[i+1]); } else if (strcmp(arg, "-g") == 0) { REQUIRE_ONE_ARG; GENERAL_OPTION; add_a_module(copy_string(argv[i+1]), NULL); } else if (strcmp(arg, "-h") == 0) { REQUIRE_ONE_ARG; PLAYER_OPTION; n = atoi(argv[i+1]); option_num_to_wait_for += n; while (n-- > 0) add_a_raw_player_spec("?@"); } else if (strcmp(arg, "-help") == 0) { GENERAL_OPTION; help_wanted = TRUE; /* Will display help info later. */ } else if (strcmp(arg, "-host") == 0) { REQUIRE_ONE_ARG; GENERAL_OPTION; option_game_to_host = copy_string(argv[i+1]); } else if (strcmp(arg, "-join") == 0) { REQUIRE_ONE_ARG; GENERAL_OPTION; option_game_to_join = copy_string(argv[i+1]); } else if (strcmp(arg, "-L") == 0) { REQUIRE_ONE_ARG; GENERAL_OPTION; if (strcmp(argv[i+1], "-") == 0) add_library_path(NULL); else add_library_path(argv[i+1]); } else if (strcmp(arg, "-M") == 0) { REQUIRE_ONE_ARG; VARIANT_OPTION; parse_world_option(argv[i+1]); } else if (strcmp(arg, "-noai") == 0) { PLAYER_OPTION; initially_no_ai = TRUE; } else if (strcmp(arg, "-r") == 0) { PLAYER_OPTION; option_add_default_player = FALSE; } else if (strcmp(arg, "-R") == 0) { REQUIRE_ONE_ARG; GENERAL_OPTION; #ifdef DEBUGGING init_xrandom(atoi(argv[i+1])); #else fprintf(stderr, "No debugging available, ignoring option `%s'\n", arg); #endif /* DEBUGGING */ } else if (strcmp(arg, "-seq") == 0) { VARIANT_OPTION; push_key_int_binding(&variant_settings, K_SEQUENTIAL, 1); } else if (strcmp(arg, "-sim") == 0) { VARIANT_OPTION; push_key_int_binding(&variant_settings, K_SEQUENTIAL, 0); } else if (strncmp(arg, "-t", 2) == 0) { REQUIRE_ONE_ARG; VARIANT_OPTION; parse_realtime_option(arg, argv[i+1]); } else if (strncmp(arg, "-v", 2) == 0) { VARIANT_OPTION; parse_variant(arg + 2); } else if (strcmp(arg, "-V") == 0) { VARIANT_OPTION; push_key_int_binding(&variant_settings, K_SEE_ALL, 1); } else if (strcmp(arg, "-V0") == 0) { VARIANT_OPTION; push_key_int_binding(&variant_settings, K_SEE_ALL, 0); } else if (strcmp(arg, "-Vfalse") == 0) { VARIANT_OPTION; push_key_int_binding(&variant_settings, K_SEE_ALL, 0); } else if (strcmp(arg, "-w") == 0) { GENERAL_OPTION; warnings_suppressed = TRUE; } else if (strcmp(arg, "-x") == 0) { GENERAL_OPTION; option_popup_new_game_dialog = TRUE; } else if (strcmp(arg, "--help") == 0) { GENERAL_OPTION; help_wanted = TRUE; /* Will display help info later. */ } else if (strcmp(arg, "--version") == 0) { GENERAL_OPTION; version_wanted = TRUE; } else { numused = 0; /* Anything unrecognized during the last parse is an error. */ if (spec >= leftover_options) { fprintf(stderr, "Unrecognized option `%s'\n", arg); had_error = TRUE; } } if (numused >= 1) { strcat(args_used, " "); strcat(args_used, argv[i]); argv[i] = NULL; } if (numused >= 2) { strcat(args_used, " "); strcat(args_used, argv[i+1]); argv[i+1] = NULL; } if (numused >= 1) i += (numused - 1); } else { if (spec == player_options) { if (*(argv[i]) == '+' || *(argv[i]) == '@') { raw_default_player_spec = argv[i]; } else { add_a_raw_player_spec(argv[i]); } strcat(args_used, " "); strcat(args_used, argv[i]); argv[i] = NULL; } } } if (version_wanted) { version_info(); } if (had_error || help_wanted || variant_help_wanted) { /* If we want to get help about a particular game, have to load it first. */ if (help_wanted || variant_help_wanted) load_all_modules(); if (had_error || help_wanted) general_usage_info(); if (had_error || help_wanted) player_usage_info(); if (help_wanted && mainmodule != NULL) { printf("\nGame info:\n\n"); if (!empty_string(mainmodule->title)) printf("%s (%s)\n", mainmodule->title, mainmodule->name); else printf("%s\n", mainmodule->name); printf(" \n"); if (mainmodule->blurb != lispnil) { append_blurb_strings(blurb, mainmodule->blurb); printf("%s", blurb); } else { printf("(no description)"); } } /* Display variant info here so it comes after basic info about the game module. */ if (had_error || help_wanted || variant_help_wanted) game_usage_info(); } if (had_error || help_wanted || variant_help_wanted || version_wanted) { exit(had_error); } }
int main(int argc, const char *argv[]) { const char *p; char *t; int i; int ret; char buf[128]; for(i = 1; i < argc; i++) { p = argv[i]; if (*p != '-') add_source(p); else { switch(p[1]) { case 'V': verbose = 1; break; /* What are we doing */ case 'c': mode = MODE_OBJ; break; case 'E': mode = MODE_CPP; break; case 'S': mode = MODE_ASM; break; case 'v': printf("fcc: front end to sdcc\n"); add_argument("sdcc"); add_argument("-v"); do_command(); exit(0); case 'D': add_macro(p); break; case 'l': add_library(p+2); break; case 'L': if (p[2] == 0) add_library_path(argv[++i]); else add_library_path(p+2); break; case 'I': if (p[2] == 0) add_include_path(argv[++i]); else add_include_path(p+2); break; case 'o': if (p[2] == 0) set_target(argv[++i]); else set_target(p + 2); break; case 'O': set_optimize(p + 2); break; case 'm': if (p[2] == 0) set_cpu(argv[++i]); else set_cpu(p + 2); break; case 'M': if (p[2] == 0) set_map(argv[++i]); else set_map(p + 2); break; case 't': if (p[2] == 0) set_platform(argv[++i]); else set_platform(p + 2); break; case 'g': debug = 1; break; default: if (strcmp(p, "-Werror") == 0) werror = 1; else if (strcmp(p, "-funsigned-char") == 0) unschar = 1; else if (strcmp(p, "--pedantic") == 0) pedantic = 1; else if (strcmp(p, "--nostdio") == 0) nostdio = 1; else { fprintf(stderr, "fcc: Unknown option '%s'.\n", p); exit(1); } } } } add_include_path(FCC_DIR "/include/"); add_library_path(FCC_DIR "/lib/"); snprintf(buf, sizeof(buf), "c%s", platform); add_library(buf); if (mode == MODE_OBJ) { while (srchead) { build_command(); ret = do_command(); if (ret) break; if (mode == MODE_OBJ && target) { char *orel = filebasename(rebuildname("", srchead->p, "rel")); if (rename(orel, target) == -1) { fprintf(stderr, "Unable to rename %s to %s.\n", orel, target); perror(srchead->p); exit(1); } } srchead = srchead->next; argp = 0; } } else { build_command(); ret = do_command(); } if (mode != MODE_LINK || ret) exit(ret); argp = 0; add_argument("makebin"); add_argument("-p"); add_argument("-s"); add_argument("65535"); add_argument(target); add_argument(t = rebuildname("", target, "bin")); ret = do_command(); if (ret) exit(ret); argp = 0; add_argument(FCC_DIR "/bin/binman"); snprintf(buf, sizeof(buf), "%x", progbase); add_argument(buf); add_argument(t); add_argument(rebuildname("", target, "map")); add_argument(target); ret = do_command(); exit(ret); }
int main(int argc, char *argv[]) { char **p = argv; signal(SIGCHLD, SIG_DFL); while (*++p) { /* filename or option ? */ if (**p != '-') { add_file(*p); continue; } switch ((*p)[1]) { /* Don't link */ case 'c': uniopt(*p); last_phase = 3; break; /* Don't assemble */ case 'S': uniopt(*p); last_phase = 2; break; /* Only pre-process */ case 'E': uniopt(*p); last_phase = 1; only_one_input = 1; break; case 'l': p = add_library(p); break; case 'I': p = add_includes(p); break; case 'L': p = add_library_path(p); break; case 'D': p = add_macro(p); break; case 'i': /* split_id();*/ uniopt(*p); break; case 'o': if (target != NULL) { fprintf(stderr, "-o can only be used once.\n"); fatal(); } if ((*p)[2]) target = *p + 2; else target = *++p; break; case 'X': uniopt(*p); keep_temp = 1; break; default: usage(); } } if (target == NULL) target = "a.out"; if (only_one_input && c_files > 1) one_input(); processing_loop(); unused_files(); return 0; }
int main(int argc, char **argv) { #define FIND_LONG_OPTION(ARRAY) \ { \ for(i = 0; i < sizeof (ARRAY) / sizeof(struct option); i++) { \ struct option *o = (ARRAY) + i; \ if(o->arg < 2) { \ if(strcmp(arg, o->opt) == 0) { \ const char *a = o->arg ? *++v : argv[0]; \ if(o->arg && !a) { \ fprintf(stderr, "%s: option '%s' need an argument\n", argv[0], *v); \ return 1; \ } \ if(o->act) o->act(a); \ goto first_loop; \ } \ } else { \ size_t len = strlen(o->opt); \ if(strncmp(arg, o->opt, len) == 0) { \ if(arg[len] && arg[len] != '=') continue; \ if(!arg[len] || !arg[len + 1]) { \ fprintf(stderr, "%s: option '%s' need an argument\n", argv[0], *v); \ return 1; \ } \ const char *a = arg + len + 1; \ if(o->act) o->act(a); \ goto first_loop; \ } \ } \ } \ } #define UNRECOGNIZED_OPTION(O) \ do { \ fprintf(stderr, "%s: error: unrecognized option '%s'\n", \ argv[0], (O)); \ return 1; \ } while(0) int verbose = 0; int no_link = 0; int preprocess_only = -1; int no_warning = -1; int end_of_options = 0; const char *output_file = NULL; char **v = argv; init_argv(); const char *vs_path = getenv("VS_PATH"); if(!vs_path) vs_path = getenv("VSINSTALLDIR"); if(!getenv("INCLUDE")) { if(vs_path) { size_t len = strlen(vs_path); if(vs_path[len - 1] == '/' || vs_path[len - 1] == '\\') len--; char buffer[len + 12 + len + 24 + 1]; memcpy(buffer, vs_path, len); memcpy(buffer + len, "/VC/include;", 12); memcpy(buffer + len + 12, vs_path, len); strcpy(buffer + len + 12 + len, "/VC/PlatformSDK/include;"); setenv("INCLUDE", buffer, 0); } else { no_warning = find_argv(argv, "-w"); if(!no_warning) fprintf(stderr, "%s: warning: no system include path set\n", argv[0]); } } if(!getenv("LIB")) { if(vs_path) { size_t len = strlen(vs_path); if(vs_path[len - 1] == '/' || vs_path[len - 1] == '\\') len--; char buffer[len + 8 + len + 20 + 1]; memcpy(buffer, vs_path, len); memcpy(buffer + len, "/VC/lib;", 8); memcpy(buffer + len + 12, vs_path, len); strcpy(buffer + len + 12 + len, "/VC/PlatformSDK/lib;"); setenv("LIB", buffer, 0); } else { if(no_warning == -1) no_warning = find_argv(argv, "-w"); if(!no_warning) fprintf(stderr, "%s: warning: no system library path set\n", argv[0]); } } first_loop: while(*++v) { if(!end_of_options && **v == '-') { int i; if((*v)[1] == '-') { const char *arg = *v + 2; if(!*arg) { end_of_options = 1; continue; } FIND_LONG_OPTION(double_dash_long_options); if(strcmp(arg, "verbose") == 0) { verbose = 1; } else UNRECOGNIZED_OPTION(*v); } else { const char *arg = *v + 1; FIND_LONG_OPTION(singal_dash_long_options); switch(*arg) { case 0: goto not_an_option; case 'c': if(arg[1]) UNRECOGNIZED_OPTION(*v); add_to_argv("-c"); no_link = 1; break; case 'D': if(arg[1]) add_to_argv(*v); else { const char *d = *++v; if(!d) { fprintf(stderr, "%s: error: macro name missing after '-D'\n", argv[0]); return 1; } define(d); } break; case 'E': if(arg[1]) UNRECOGNIZED_OPTION(*v); add_to_argv("-E"); preprocess_only = 1; break; case 'f': if(arg[1]) set_feature(arg + 1); else { const char *feature = *++v; if(!feature) { fprintf(stderr, "%s: error: option '-f' need an argument\n", argv[0]); return -1; } set_feature(feature); } break; case 'g': // -g[coff][<level>] (level: 0~3) if(arg[1]) { const char *level = arg + 1; if(strncmp(level, "coff", 4) == 0) level += 4; if(*level && *level != '-') { int i = 0; do { if(!isdigit(level[i])) { fprintf(stderr, "%s: error: unrecognized debug output level \"%s\"\n", argv[0], level); return 1; } } while(level[++i]); /* if(i > 1 || *level > '3') { fprintf(stderr, "%s: error: debug output level %s is too high\n", argv[0], level); return 1; } if(*level == '0') break; */ int l = atoi(level); if(!l) break; if(l > 3) { fprintf(stderr, "%s: error: debug output level %s is too high\n", argv[0], level); return 1; } } } add_to_argv("-Zi"); break; case 'I': if(no_warning == -1) no_warning = find_argv(argv, "-w"); //if(arg[1]) add_to_argv(*v); if(arg[1]) add_include_path(arg + 1, no_warning); else { const char *path = *++v; if(!path) { fprintf(stderr, "%s: error: option '-I' need an argument\n", argv[0]); return 1; } add_include_path(path, no_warning); } break; case 'L': if(no_warning == -1) no_warning = find_argv(argv, "-w"); if(arg[1]) add_library_path(arg + 1, no_warning); else { const char *path = *++v; if(!path) { fprintf(stderr, "%s: error: option '-L' need an argument\n", argv[0]); return 1; } add_library_path(path, no_warning); } break; case 'l': if(arg[1]) add_library(arg + 1); else { const char *path = *++v; if(!path) { fprintf(stderr, "%s: error: option '-l' need an argument\n", argv[0]); return 1; } add_library(path); } break; case 'M': if(arg[1]) UNRECOGNIZED_OPTION(*v); add_to_argv("-showIncludes"); break; case 'm': if(arg[1]) set_machine(arg + 1); else { const char *machine = *++v; if(!machine) { fprintf(stderr, "%s: argument to `-m' is missing\n", argv[0]); return 1; } set_machine(machine); } break; case 'O': if(arg[1]) { const char *o = arg + 1; if(strcmp(o, "0") == 0) add_to_argv("-Od"); else if(strcmp(o, "1") == 0) add_to_argv("-O2"); else if(strcmp(o, "3") == 0) add_to_argv("-Ox"); else if(strcmp(o, "s") == 0) add_to_argv("-O1"); else if(strcmp(o, "fast") == 0) add_to_argv("-O2"); else add_to_argv(*v); } else add_to_argv("-O2"); break; case 'o': if(arg[1]) output_file = arg + 1; else { output_file = *++v; if(!output_file) { fprintf(stderr, "%s: error: option '-o' need an argument\n", argv[0]); return 1; } } break; case 'P': if(preprocess_only == -1) preprocess_only = find_argv(argv, "-E"); if(preprocess_only) add_to_argv("-EP"); break; case 's': if(arg[1]) UNRECOGNIZED_OPTION(*v); break; case 'U': if(arg[1]) add_to_argv(*v); else { const char *u = *++v; if(!u) { fprintf(stderr, "%s: error: macro name missing after '-U'\n", argv[0]); return 1; } undefine(u); } break; case 'v': if(arg[1]) UNRECOGNIZED_OPTION(*v); verbose = 1; break; case 'W': if(!arg[1]) { if(no_warning == -1) no_warning = find_argv(argv, "-w"); if(!no_warning) { fprintf(stderr, "%s: warning: option '-W' is deprecated; use '-Wextra' instead\n", argv[0]); } add_to_argv("-Wall"); break; } if(strncmp(arg, "Wa,", 3) == 0 || strncmp(arg, "Wp,", 3) == 0 || strncmp(arg, "Wl,", 3) == 0) { (*v)[3] = 0; // XXX fprintf(stderr, "%s: warning: option '%s' is not supported\n", argv[0], *v); break; } if(set_warning(arg + 1)) break; add_to_argv(*v); break; case 'w': if(arg[1]) UNRECOGNIZED_OPTION(*v); add_to_argv("-w"); no_warning = 1; break; case 'x': if(arg[1]) set_language(arg + 1); else { const char *lang = *++v; if(!lang) { fprintf(stderr, "%s: error: missing argument to ‘-x’", argv[0]); return 4; } set_language(lang); } break; default: fprintf(stderr, "%s: error: unrecognized option '%s'\n", argv[0], *v); return 1; } } } else { not_an_option: #if defined __INTERIX && !defined _NO_CONV_PATH if(**v == '/') { char buffer[PATH_MAX + 1]; if(unixpath2win(*v, 0, buffer, sizeof buffer) == 0) { add_input_file(buffer); } else { if(no_warning == -1) no_warning = find_argv(argv, "-w"); if(!no_warning) { fprintf(stderr, "%s: warning: cannot convert '%s' to Windows path name, %s\n", argv[0], *v, strerror(errno)); } add_input_file(*v); } } else #endif add_input_file(*v); } } setvbuf(stdout, NULL, _IOLBF, 0); if(preprocess_only == -1) preprocess_only = 0; if(no_warning == -1) no_warning = 0; if(last_language && last_language_unused && !no_warning) { fprintf(stderr, "%s: warning: '-x %s' after last input file has no effect\n", argv[0], last_language); } if(!first_input_file) { if(verbose) { if(!no_link) add_to_argv("-c"); start_cl(); return 0; } fprintf(stderr, "%s: no input files\n", argv[0]); return 1; } if(multiple_input_files && (preprocess_only || no_link)) { if(output_file) { fprintf(stderr, "%s: error: cannot specify -o with -c or -E with multiple files\n", argv[0]); return 4; } else if(no_link) { fprintf(stderr, "%s: error: '-c' with multiple files is currently not supported\n", argv[0]); return -1; } } if(!output_file && !preprocess_only) { if(no_link) { size_t len = strlen(first_input_file); int n = get_last_dot(first_input_file, len); if(n >= 0) len = n; char *p = malloc(len + 3); if(!p) { perror(argv[0]); return 1; } memcpy(p, first_input_file, len); strcpy(p + len, ".o"); output_file = p; } else output_file = DEFAULT_OUTPUT_FILENAME; } if(!verbose) add_to_argv("-nologo"); if(preprocess_only) { if(output_file) target.name = output_file; target.type = PREPROCESSED_SOURCE; } else set_output_file(output_file, no_link, no_warning); //if(no_static_link) add_to_argv("-MD"); add_to_argv(no_static_link ? "-MD" : "-MT"); add_libraries_to_argv(); if(verbose) print_argv(); return start_cl(); }