Clean up the command-line parsing; make -w/-W match others

Clean up the command-line parsing and make -w/-W match the behaviour
of all the other options with regards to arguments.
This commit is contained in:
H. Peter Anvin 2007-11-15 17:12:29 -08:00
parent 7812644665
commit 423e381dd7

257
nasm.c
View File

@ -336,9 +336,9 @@ int main(int argc, char **argv)
* Get a parameter for a command line option. * Get a parameter for a command line option.
* First arg must be in the form of e.g. -f... * First arg must be in the form of e.g. -f...
*/ */
static char *get_param(char *p, char *q, int *advance) static char *get_param(char *p, char *q, bool *advance)
{ {
*advance = 0; *advance = false;
if (p[2]) { /* the parameter's in the option */ if (p[2]) { /* the parameter's in the option */
p += 2; p += 2;
while (isspace(*p)) while (isspace(*p))
@ -346,7 +346,7 @@ static char *get_param(char *p, char *q, int *advance)
return p; return p;
} }
if (q && q[0]) { if (q && q[0]) {
*advance = 1; *advance = true;
return q; return q;
} }
report_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE, report_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
@ -367,126 +367,145 @@ struct textargs textopts[] = {
{NULL, 0} {NULL, 0}
}; };
int stopoptions = 0; static bool stopoptions = false;
static int process_arg(char *p, char *q) static bool process_arg(char *p, char *q)
{ {
char *param; char *param;
int i, advance = 0; int i;
bool advance = false;
bool suppress; bool suppress;
if (!p || !p[0]) if (!p || !p[0])
return 0; return false;
if (p[0] == '-' && !stopoptions) { if (p[0] == '-' && !stopoptions) {
if (strchr("oOfpPdDiIlFXuUZwW", p[1])) {
/* These parameters take values */
if (!(param = get_param(p, q, &advance)))
return advance;
}
switch (p[1]) { switch (p[1]) {
case 's': case 's':
error_file = stdout; error_file = stdout;
break; break;
case 'o': /* these parameters take values */
case 'O':
case 'f':
case 'p':
case 'P':
case 'd':
case 'D':
case 'i':
case 'I':
case 'l':
case 'F':
case 'X':
case 'u':
case 'U':
case 'Z':
if (!(param = get_param(p, q, &advance)))
break;
if (p[1] == 'o') { /* output file */
strcpy(outname, param);
} else if (p[1] == 'f') { /* output format */
ofmt = ofmt_find(param);
if (!ofmt) {
report_error(ERR_FATAL | ERR_NOFILE | ERR_USAGE,
"unrecognised output format `%s' - "
"use -hf for a list", param);
} else
ofmt->current_dfmt = ofmt->debug_formats[0];
} else if (p[1] == 'O') { /* Optimization level */
int opt;
if (!*param) { case 'o': /* output file */
/* Naked -O == -Ox */ strcpy(outname, param);
optimizing = INT_MAX >> 1; /* Almost unlimited */ break;
} else {
while (*param) {
switch (*param) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
opt = strtoul(param, &param, 10);
/* -O0 -> optimizing == -1, 0.98 behaviour */ case 'f': /* output format */
/* -O1 -> optimizing == 0, 0.98.09 behaviour */ ofmt = ofmt_find(param);
if (opt < 2) if (!ofmt) {
optimizing = opt - 1; report_error(ERR_FATAL | ERR_NOFILE | ERR_USAGE,
else if (opt <= 5) "unrecognised output format `%s' - "
/* The optimizer seems to have problems with "use -hf for a list", param);
< 5 passes? Hidden bug? */ } else {
optimizing = 5; /* 5 passes */ ofmt->current_dfmt = ofmt->debug_formats[0];
else }
optimizing = opt; /* More than 5 passes */ break;
break;
case 'v': case 'O': /* Optimization level */
case '+': {
param++; int opt;
opt_verbose_info = true;
break;
case 'x': if (!*param) {
param++; /* Naked -O == -Ox */
optimizing = INT_MAX >> 1; /* Almost unlimited */ optimizing = INT_MAX >> 1; /* Almost unlimited */
break; } else {
while (*param) {
switch (*param) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
opt = strtoul(param, &param, 10);
default: /* -O0 -> optimizing == -1, 0.98 behaviour */
report_error(ERR_FATAL, /* -O1 -> optimizing == 0, 0.98.09 behaviour */
"unknown optimization option -O%c\n", if (opt < 2)
*param); optimizing = opt - 1;
break; else if (opt <= 5)
} /* The optimizer seems to have problems with
< 5 passes? Hidden bug? */
optimizing = 5; /* 5 passes */
else
optimizing = opt; /* More than 5 passes */
break;
case 'v':
case '+':
param++;
opt_verbose_info = true;
break;
case 'x':
param++;
optimizing = INT_MAX >> 1; /* Almost unlimited */
break;
default:
report_error(ERR_FATAL,
"unknown optimization option -O%c\n",
*param);
break;
} }
} }
} else if (p[1] == 'P' || p[1] == 'p') { /* pre-include */ }
pp_pre_include(param); break;
} else if (p[1] == 'D' || p[1] == 'd') { /* pre-define */ }
pp_pre_define(param);
} else if (p[1] == 'U' || p[1] == 'u') { /* un-define */ case 'p': /* pre-include */
pp_pre_undefine(param); case 'P':
} else if (p[1] == 'I' || p[1] == 'i') { /* include search path */ pp_pre_include(param);
pp_include_path(param); break;
} else if (p[1] == 'l') { /* listing file */
strcpy(listname, param); case 'd': /* pre-define */
} else if (p[1] == 'Z') { /* error messages file */ case 'D':
strcpy(errname, param); pp_pre_define(param);
} else if (p[1] == 'F') { /* specify debug format */ break;
ofmt->current_dfmt = dfmt_find(ofmt, param);
if (!ofmt->current_dfmt) { case 'u': /* un-define */
report_error(ERR_FATAL | ERR_NOFILE | ERR_USAGE, case 'U':
"unrecognized debug format `%s' for" pp_pre_undefine(param);
" output format `%s'", break;
param, ofmt->shortname);
} case 'i': /* include search path */
} else if (p[1] == 'X') { /* specify error reporting format */ case 'I':
if (nasm_stricmp("vc", param) == 0) pp_include_path(param);
report_error = report_error_vc; break;
else if (nasm_stricmp("gnu", param) == 0)
report_error = report_error_gnu; case 'l': /* listing file */
else strcpy(listname, param);
report_error(ERR_FATAL | ERR_NOFILE | ERR_USAGE, break;
"unrecognized error reporting format `%s'",
param); case 'Z': /* error messages file */
} strcpy(errname, param);
break;
case 'F': /* specify debug format */
ofmt->current_dfmt = dfmt_find(ofmt, param);
if (!ofmt->current_dfmt) {
report_error(ERR_FATAL | ERR_NOFILE | ERR_USAGE,
"unrecognized debug format `%s' for"
" output format `%s'",
param, ofmt->shortname);
}
break;
case 'X': /* specify error reporting format */
if (nasm_stricmp("vc", param) == 0)
report_error = report_error_vc;
else if (nasm_stricmp("gnu", param) == 0)
report_error = report_error_gnu;
else
report_error(ERR_FATAL | ERR_NOFILE | ERR_USAGE,
"unrecognized error reporting format `%s'",
param);
break; break;
case 'g': case 'g':
using_debug_info = true; using_debug_info = true;
break; break;
case 'h': case 'h':
printf printf
("usage: nasm [-@ response file] [-o outfile] [-f format] " ("usage: nasm [-@ response file] [-o outfile] [-f format] "
@ -530,15 +549,18 @@ static int process_arg(char *p, char *q)
} }
exit(0); /* never need usage message here */ exit(0); /* never need usage message here */
break; break;
case 'y': case 'y':
printf("\nvalid debug formats for '%s' output format are" printf("\nvalid debug formats for '%s' output format are"
" ('*' denotes default):\n", ofmt->shortname); " ('*' denotes default):\n", ofmt->shortname);
dfmt_list(ofmt, stdout); dfmt_list(ofmt, stdout);
exit(0); exit(0);
break; break;
case 't': case 't':
tasm_compatible_mode = true; tasm_compatible_mode = true;
break; break;
case 'v': case 'v':
{ {
const char *nasm_version_string = const char *nasm_version_string =
@ -551,44 +573,51 @@ static int process_arg(char *p, char *q)
exit(0); /* never need usage message here */ exit(0); /* never need usage message here */
} }
break; break;
case 'e': /* preprocess only */ case 'e': /* preprocess only */
case 'E': case 'E':
operating_mode = op_preprocess; operating_mode = op_preprocess;
break; break;
case 'a': /* assemble only - don't preprocess */ case 'a': /* assemble only - don't preprocess */
preproc = &no_pp; preproc = &no_pp;
break; break;
case 'W': case 'W':
if (p[2] == 'n' && p[3] == 'o' && p[4] == '-') { if (param[0] == 'n' && param[1] == 'o' && param[2] == '-') {
suppress = true; suppress = true;
p += 5; param += 3;
} else { } else {
suppress = false; suppress = false;
p += 2;
} }
goto set_warning; goto set_warning;
case 'w': case 'w':
if (p[2] != '+' && p[2] != '-') { if (param[0] != '+' && param[0] != '-') {
report_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE, report_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
"invalid option to `-w'"); "invalid option to `-w'");
break; break;
} }
suppress = (p[2] == '-'); suppress = (param[0] == '-');
p += 3; param++;
goto set_warning; goto set_warning;
set_warning: set_warning:
for (i = 0; i <= ERR_WARN_MAX; i++) for (i = 0; i <= ERR_WARN_MAX; i++)
if (!nasm_stricmp(p, suppressed_names[i])) if (!nasm_stricmp(param, suppressed_names[i]))
break; break;
if (i <= ERR_WARN_MAX) if (i <= ERR_WARN_MAX)
suppressed[i] = suppress; suppressed[i] = suppress;
else if (!nasm_stricmp(p, "all")) else if (!nasm_stricmp(param, "all"))
for (i = 1; i <= ERR_WARN_MAX; i++) for (i = 1; i <= ERR_WARN_MAX; i++)
suppressed[i] = suppress; suppressed[i] = suppress;
else if (!nasm_stricmp(param, "none"))
for (i = 1; i <= ERR_WARN_MAX; i++)
suppressed[i] = !suppress;
else else
report_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE, report_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
"invalid warning `%s'", p); "invalid warning `%s'", param);
break; break;
case 'M': case 'M':
operating_mode = p[2] == 'G' ? op_depend_missing_ok : op_depend; operating_mode = p[2] == 'G' ? op_depend_missing_ok : op_depend;
break; break;
@ -774,7 +803,7 @@ static void parse_cmdline(int argc, char **argv)
* Now process the actual command line. * Now process the actual command line.
*/ */
while (--argc) { while (--argc) {
int i; bool advance;
argv++; argv++;
if (argv[0][0] == '@') { if (argv[0][0] == '@') {
/* We have a response file, so process this as a set of /* We have a response file, so process this as a set of
@ -800,7 +829,7 @@ static void parse_cmdline(int argc, char **argv)
argv++; argv++;
} }
if (!stopoptions && argv[0][0] == '-' && argv[0][1] == '@') { if (!stopoptions && argv[0][0] == '-' && argv[0][1] == '@') {
p = get_param(argv[0], argc > 1 ? argv[1] : NULL, &i); p = get_param(argv[0], argc > 1 ? argv[1] : NULL, &advance);
if (p) { if (p) {
rfile = fopen(p, "r"); rfile = fopen(p, "r");
if (rfile) { if (rfile) {
@ -811,8 +840,8 @@ static void parse_cmdline(int argc, char **argv)
"unable to open response file `%s'", p); "unable to open response file `%s'", p);
} }
} else } else
i = process_arg(argv[0], argc > 1 ? argv[1] : NULL); advance = process_arg(argv[0], argc > 1 ? argv[1] : NULL);
argv += i, argc -= i; argv += advance, argc -= advance;
} }
if (!*inname) if (!*inname)