Add %warning, saner unquoting of %error

- Add %warning directive
- Only unquote an %error or %warning string if it is the only thing on
  the directive line.
- Don't expand macros inside a quoted string, even for %error.
This commit is contained in:
H. Peter Anvin 2008-06-10 18:27:38 -07:00
parent 3c74485523
commit 7df0417e58
5 changed files with 37 additions and 15 deletions

View File

@ -2874,19 +2874,19 @@ any tokens at all, whitespace excepted.
The usual \i\c{%elifempty}, \i\c\{%ifnempty}, and \i\c{%elifnempty}
variants are also provided.
\S{pperror} \i\c{%error}: Reporting \i{User-Defined Errors}
\S{pperror} \i\c{%error} and \i\c{%warning}: Reporting \i{User-Defined Errors}
The preprocessor directive \c{%error} will cause NASM to report an
error if it occurs in assembled code. So if other users are going to
try to assemble your source files, you can ensure that they define
the right macros by means of code like this:
try to assemble your source files, you can ensure that they define the
right macros by means of code like this:
\c %ifdef SOME_MACRO
\c %ifdef F1
\c ; do some setup
\c %elifdef SOME_OTHER_MACRO
\c %elifdef F2
\c ; do some different setup
\c %else
\c %error Neither SOME_MACRO nor SOME_OTHER_MACRO was defined.
\c %error Neither F1 nor F2 was defined.
\c %endif
Then any user who fails to understand the way your code is supposed
@ -2894,6 +2894,16 @@ to be assembled will be quickly warned of their mistake, rather than
having to wait until the program crashes on being run and then not
knowing what went wrong.
Similarly, \c{%warning} issues a warning:
\c %ifdef F1
\c ; do some setup
\c %elifdef F2
\c ; do some different setup
\c %else
\c %warning Neither F1 nor F2 was defined, assuming F1.
\c %define F1
\c %endif
\H{rep} \i{Preprocessor Loops}\I{repeating code}: \i\c{%rep}

4
nasm.c
View File

@ -1909,7 +1909,7 @@ static bool is_suppressed_warning(int severity)
static void report_error_common(int severity, const char *fmt,
va_list args)
{
switch (severity & ERR_MASK) {
switch (severity & (ERR_MASK|ERR_NO_SEVERITY)) {
case ERR_WARNING:
fputs("warning: ", error_file);
break;
@ -1925,6 +1925,8 @@ static void report_error_common(int severity, const char *fmt,
case ERR_DEBUG:
fputs("debug: ", error_file);
break;
default:
break;
}
vfprintf(error_file, fmt, args);

View File

@ -54,6 +54,7 @@ extern efunc nasm_malloc_error;
#define ERR_NOFILE 0x00000010 /* don't give source file name/line */
#define ERR_USAGE 0x00000020 /* print a usage message */
#define ERR_PASS1 0x00000040 /* only print this error on pass one */
#define ERR_NO_SEVERITY 0x00000080 /* suppress printing severity */
/*
* These codes define specific types of suppressible warning.

View File

@ -47,4 +47,5 @@
%strlen
%substr
%undef
%warning
%xdefine

View File

@ -2192,22 +2192,30 @@ static int do_directive(Token * tline)
break;
case PP_ERROR:
case PP_WARNING:
{
int severity = PP_ERROR ? ERR_NONFATAL|ERR_NO_SEVERITY :
ERR_WARNING|ERR_NO_SEVERITY;
tline->next = expand_smacro(tline->next);
tline = tline->next;
skip_white_(tline);
if (tok_type_(tline, TOK_STRING)) {
t = tline ? tline->next : NULL;
skip_white_(t);
if (tok_type_(tline, TOK_STRING) && !t) {
/* The line contains only a quoted string */
p = tline->text;
nasm_unquote(p, NULL);
expand_macros_in_string(&p); /* WHY? */
error(ERR_NONFATAL, "%s", p);
nasm_free(p);
} else {
error(severity, "%s: %s", pp_directives[i], p);
} else {
/* Not a quoted string, or more than a quoted string */
p = detoken(tline, false);
error(ERR_WARNING, "%s", p); /* WARNING!??!! */
nasm_free(p);
}
error(severity, "%s: %s", pp_directives[i], p);
nasm_free(p);
}
free_tlist(origline);
break;
}
CASE_PP_IF:
if (istk->conds && !emitting(istk->conds->state))