mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-01-30 16:41:05 +08:00
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:
parent
7812644665
commit
423e381dd7
257
nasm.c
257
nasm.c
@ -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, ¶m, 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, ¶m, 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)
|
||||||
|
Loading…
Reference in New Issue
Block a user