Add %ifmacro and friends, and fix two minor bugs:
a) The argument to %elif* is handled different than the one to %if* b) Incorrect error messages for the %ifdef variants
This commit is contained in:
parent
290b514fac
commit
6574726f21
1 changed files with 116 additions and 27 deletions
143
preproc.c
143
preproc.c
|
@ -1,3 +1,4 @@
|
||||||
|
/* -*- mode: c; c-file-style: "bsd" -*- */
|
||||||
/* preproc.c macro preprocessor for the Netwide Assembler
|
/* preproc.c macro preprocessor for the Netwide Assembler
|
||||||
*
|
*
|
||||||
* The Netwide Assembler is copyright (C) 1996 Simon Tatham and
|
* The Netwide Assembler is copyright (C) 1996 Simon Tatham and
|
||||||
|
@ -276,12 +277,12 @@ static int inverse_ccs[] = {
|
||||||
static char *directives[] = {
|
static char *directives[] = {
|
||||||
"%arg",
|
"%arg",
|
||||||
"%assign", "%clear", "%define", "%elif", "%elifctx", "%elifdef",
|
"%assign", "%clear", "%define", "%elif", "%elifctx", "%elifdef",
|
||||||
"%elifid", "%elifidn", "%elifidni", "%elifnctx", "%elifndef",
|
"%elifid", "%elifidn", "%elifidni", "%elifmacro", "%elifnctx", "%elifndef",
|
||||||
"%elifnid", "%elifnidn", "%elifnidni", "%elifnnum", "%elifnstr",
|
"%elifnid", "%elifnidn", "%elifnidni", "%elifnmacro", "%elifnnum", "%elifnstr",
|
||||||
"%elifnum", "%elifstr", "%else", "%endif", "%endm", "%endmacro",
|
"%elifnum", "%elifstr", "%else", "%endif", "%endm", "%endmacro",
|
||||||
"%endrep", "%error", "%exitrep", "%iassign", "%idefine", "%if",
|
"%endrep", "%error", "%exitrep", "%iassign", "%idefine", "%if",
|
||||||
"%ifctx", "%ifdef", "%ifid", "%ifidn", "%ifidni", "%ifnctx",
|
"%ifctx", "%ifdef", "%ifid", "%ifidn", "%ifidni", "%ifmacro", "%ifnctx",
|
||||||
"%ifndef", "%ifnid", "%ifnidn", "%ifnidni", "%ifnnum",
|
"%ifndef", "%ifnid", "%ifnidn", "%ifnidni", "%ifnmacro", "%ifnnum",
|
||||||
"%ifnstr", "%ifnum", "%ifstr", "%imacro", "%include",
|
"%ifnstr", "%ifnum", "%ifstr", "%imacro", "%include",
|
||||||
"%ixdefine", "%line",
|
"%ixdefine", "%line",
|
||||||
"%local",
|
"%local",
|
||||||
|
@ -293,12 +294,12 @@ enum
|
||||||
{
|
{
|
||||||
PP_ARG,
|
PP_ARG,
|
||||||
PP_ASSIGN, PP_CLEAR, PP_DEFINE, PP_ELIF, PP_ELIFCTX, PP_ELIFDEF,
|
PP_ASSIGN, PP_CLEAR, PP_DEFINE, PP_ELIF, PP_ELIFCTX, PP_ELIFDEF,
|
||||||
PP_ELIFID, PP_ELIFIDN, PP_ELIFIDNI, PP_ELIFNCTX, PP_ELIFNDEF,
|
PP_ELIFID, PP_ELIFIDN, PP_ELIFIDNI, PP_ELIFMACRO, PP_ELIFNCTX, PP_ELIFNDEF,
|
||||||
PP_ELIFNID, PP_ELIFNIDN, PP_ELIFNIDNI, PP_ELIFNNUM, PP_ELIFNSTR,
|
PP_ELIFNID, PP_ELIFNIDN, PP_ELIFNIDNI, PP_ELIFNMACRO, PP_ELIFNNUM, PP_ELIFNSTR,
|
||||||
PP_ELIFNUM, PP_ELIFSTR, PP_ELSE, PP_ENDIF, PP_ENDM, PP_ENDMACRO,
|
PP_ELIFNUM, PP_ELIFSTR, PP_ELSE, PP_ENDIF, PP_ENDM, PP_ENDMACRO,
|
||||||
PP_ENDREP, PP_ERROR, PP_EXITREP, PP_IASSIGN, PP_IDEFINE, PP_IF,
|
PP_ENDREP, PP_ERROR, PP_EXITREP, PP_IASSIGN, PP_IDEFINE, PP_IF,
|
||||||
PP_IFCTX, PP_IFDEF, PP_IFID, PP_IFIDN, PP_IFIDNI, PP_IFNCTX,
|
PP_IFCTX, PP_IFDEF, PP_IFID, PP_IFIDN, PP_IFIDNI, PP_IFMACRO, PP_IFNCTX,
|
||||||
PP_IFNDEF, PP_IFNID, PP_IFNIDN, PP_IFNIDNI, PP_IFNNUM,
|
PP_IFNDEF, PP_IFNID, PP_IFNIDN, PP_IFNIDNI, PP_IFNMACRO, PP_IFNNUM,
|
||||||
PP_IFNSTR, PP_IFNUM, PP_IFSTR, PP_IMACRO, PP_INCLUDE,
|
PP_IFNSTR, PP_IFNUM, PP_IFSTR, PP_IMACRO, PP_INCLUDE,
|
||||||
PP_IXDEFINE, PP_LINE,
|
PP_IXDEFINE, PP_LINE,
|
||||||
PP_LOCAL,
|
PP_LOCAL,
|
||||||
|
@ -307,6 +308,12 @@ enum
|
||||||
PP_STRLEN, PP_SUBSTR, PP_UNDEF, PP_XDEFINE
|
PP_STRLEN, PP_SUBSTR, PP_UNDEF, PP_XDEFINE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* If this is a an IF, ELIF, ELSE or ENDIF keyword */
|
||||||
|
static int is_condition(int arg)
|
||||||
|
{
|
||||||
|
return ((arg >= PP_ELIF) && (arg <= PP_ENDIF)) ||
|
||||||
|
((arg >= PP_IF) && (arg <= PP_IFSTR));
|
||||||
|
}
|
||||||
|
|
||||||
/* For TASM compatibility we need to be able to recognise TASM compatible
|
/* For TASM compatibility we need to be able to recognise TASM compatible
|
||||||
* conditional compilation directives. Using the NASM pre-processor does
|
* conditional compilation directives. Using the NASM pre-processor does
|
||||||
|
@ -1471,8 +1478,8 @@ if_condition(Token * tline, int i)
|
||||||
tline->text[1] != '$')))
|
tline->text[1] != '$')))
|
||||||
{
|
{
|
||||||
error(ERR_NONFATAL,
|
error(ERR_NONFATAL,
|
||||||
"`%%if%sdef' expects macro identifiers",
|
"`%s' expects macro identifiers",
|
||||||
(i == PP_ELIFNDEF ? "n" : ""));
|
directives[i]);
|
||||||
free_tlist(origline);
|
free_tlist(origline);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1549,6 +1556,98 @@ if_condition(Token * tline, int i)
|
||||||
free_tlist(tline);
|
free_tlist(tline);
|
||||||
return j;
|
return j;
|
||||||
|
|
||||||
|
case PP_IFMACRO:
|
||||||
|
case PP_ELIFMACRO:
|
||||||
|
case PP_IFNMACRO:
|
||||||
|
case PP_ELIFNMACRO:
|
||||||
|
{
|
||||||
|
int found = 0;
|
||||||
|
MMacro searching, *mmac;
|
||||||
|
|
||||||
|
tline = tline->next;
|
||||||
|
skip_white_(tline);
|
||||||
|
tline = expand_id(tline);
|
||||||
|
if (!tok_type_(tline, TOK_ID))
|
||||||
|
{
|
||||||
|
error(ERR_NONFATAL,
|
||||||
|
"`%s' expects a macro name",
|
||||||
|
directives[i]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
searching.name = nasm_strdup(tline->text);
|
||||||
|
searching.casesense = (i == PP_MACRO);
|
||||||
|
searching.plus = FALSE;
|
||||||
|
searching.nolist = FALSE;
|
||||||
|
searching.in_progress = FALSE;
|
||||||
|
searching.rep_nest = NULL;
|
||||||
|
searching.nparam_min = 0;
|
||||||
|
searching.nparam_max = INT_MAX;
|
||||||
|
tline = expand_smacro(tline->next);
|
||||||
|
skip_white_(tline);
|
||||||
|
if (!tline)
|
||||||
|
{
|
||||||
|
} else if (!tok_type_(tline, TOK_NUMBER))
|
||||||
|
{
|
||||||
|
error(ERR_NONFATAL,
|
||||||
|
"`%s' expects a parameter count or nothing",
|
||||||
|
directives[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
searching.nparam_min = searching.nparam_max =
|
||||||
|
readnum(tline->text, &j);
|
||||||
|
if (j)
|
||||||
|
error(ERR_NONFATAL,
|
||||||
|
"unable to parse parameter count `%s'",
|
||||||
|
tline->text);
|
||||||
|
}
|
||||||
|
if (tline && tok_is_(tline->next, "-"))
|
||||||
|
{
|
||||||
|
tline = tline->next->next;
|
||||||
|
if (tok_is_(tline, "*"))
|
||||||
|
searching.nparam_max = INT_MAX;
|
||||||
|
else if (!tok_type_(tline, TOK_NUMBER))
|
||||||
|
error(ERR_NONFATAL,
|
||||||
|
"`%s' expects a parameter count after `-'",
|
||||||
|
directives[i]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
searching.nparam_max = readnum(tline->text, &j);
|
||||||
|
if (j)
|
||||||
|
error(ERR_NONFATAL,
|
||||||
|
"unable to parse parameter count `%s'",
|
||||||
|
tline->text);
|
||||||
|
if (searching.nparam_min > searching.nparam_max)
|
||||||
|
error(ERR_NONFATAL,
|
||||||
|
"minimum parameter count exceeds maximum");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tline && tok_is_(tline->next, "+"))
|
||||||
|
{
|
||||||
|
tline = tline->next;
|
||||||
|
searching.plus = TRUE;
|
||||||
|
}
|
||||||
|
mmac = mmacros[hash(searching.name)];
|
||||||
|
while (mmac)
|
||||||
|
{
|
||||||
|
if (!strcmp(mmac->name, searching.name) &&
|
||||||
|
(mmac->nparam_min <= searching.nparam_max
|
||||||
|
|| searching.plus)
|
||||||
|
&& (searching.nparam_min <= mmac->nparam_max
|
||||||
|
|| mmac->plus))
|
||||||
|
{
|
||||||
|
found = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mmac = mmac->next;
|
||||||
|
}
|
||||||
|
nasm_free(searching.name);
|
||||||
|
free_tlist(origline);
|
||||||
|
if (i == PP_IFNMACRO || i == PP_ELIFNMACRO)
|
||||||
|
found = !found;
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
case PP_IFID:
|
case PP_IFID:
|
||||||
case PP_ELIFID:
|
case PP_ELIFID:
|
||||||
case PP_IFNID:
|
case PP_IFNID:
|
||||||
|
@ -1704,22 +1803,8 @@ do_directive(Token * tline)
|
||||||
* directives.
|
* directives.
|
||||||
*/
|
*/
|
||||||
if (((istk->conds && !emitting(istk->conds->state)) ||
|
if (((istk->conds && !emitting(istk->conds->state)) ||
|
||||||
(istk->mstk && !istk->mstk->in_progress)) &&
|
(istk->mstk && !istk->mstk->in_progress)) &&
|
||||||
i != PP_IF && i != PP_ELIF &&
|
!is_condition(i))
|
||||||
i != PP_IFCTX && i != PP_ELIFCTX &&
|
|
||||||
i != PP_IFDEF && i != PP_ELIFDEF &&
|
|
||||||
i != PP_IFID && i != PP_ELIFID &&
|
|
||||||
i != PP_IFIDN && i != PP_ELIFIDN &&
|
|
||||||
i != PP_IFIDNI && i != PP_ELIFIDNI &&
|
|
||||||
i != PP_IFNCTX && i != PP_ELIFNCTX &&
|
|
||||||
i != PP_IFNDEF && i != PP_ELIFNDEF &&
|
|
||||||
i != PP_IFNID && i != PP_ELIFNID &&
|
|
||||||
i != PP_IFNIDN && i != PP_ELIFNIDN &&
|
|
||||||
i != PP_IFNIDNI && i != PP_ELIFNIDNI &&
|
|
||||||
i != PP_IFNNUM && i != PP_ELIFNNUM &&
|
|
||||||
i != PP_IFNSTR && i != PP_ELIFNSTR &&
|
|
||||||
i != PP_IFNUM && i != PP_ELIFNUM &&
|
|
||||||
i != PP_IFSTR && i != PP_ELIFSTR && i != PP_ELSE && i != PP_ENDIF)
|
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2135,11 +2220,13 @@ do_directive(Token * tline)
|
||||||
case PP_IFID:
|
case PP_IFID:
|
||||||
case PP_IFIDN:
|
case PP_IFIDN:
|
||||||
case PP_IFIDNI:
|
case PP_IFIDNI:
|
||||||
|
case PP_IFMACRO:
|
||||||
case PP_IFNCTX:
|
case PP_IFNCTX:
|
||||||
case PP_IFNDEF:
|
case PP_IFNDEF:
|
||||||
case PP_IFNID:
|
case PP_IFNID:
|
||||||
case PP_IFNIDN:
|
case PP_IFNIDN:
|
||||||
case PP_IFNIDNI:
|
case PP_IFNIDNI:
|
||||||
|
case PP_IFNMACRO:
|
||||||
case PP_IFNNUM:
|
case PP_IFNNUM:
|
||||||
case PP_IFNSTR:
|
case PP_IFNSTR:
|
||||||
case PP_IFNUM:
|
case PP_IFNUM:
|
||||||
|
@ -2165,11 +2252,13 @@ do_directive(Token * tline)
|
||||||
case PP_ELIFID:
|
case PP_ELIFID:
|
||||||
case PP_ELIFIDN:
|
case PP_ELIFIDN:
|
||||||
case PP_ELIFIDNI:
|
case PP_ELIFIDNI:
|
||||||
|
case PP_ELIFMACRO:
|
||||||
case PP_ELIFNCTX:
|
case PP_ELIFNCTX:
|
||||||
case PP_ELIFNDEF:
|
case PP_ELIFNDEF:
|
||||||
case PP_ELIFNID:
|
case PP_ELIFNID:
|
||||||
case PP_ELIFNIDN:
|
case PP_ELIFNIDN:
|
||||||
case PP_ELIFNIDNI:
|
case PP_ELIFNIDNI:
|
||||||
|
case PP_ELIFNMACRO:
|
||||||
case PP_ELIFNNUM:
|
case PP_ELIFNNUM:
|
||||||
case PP_ELIFNSTR:
|
case PP_ELIFNSTR:
|
||||||
case PP_ELIFNUM:
|
case PP_ELIFNUM:
|
||||||
|
@ -2181,7 +2270,7 @@ do_directive(Token * tline)
|
||||||
istk->conds->state = COND_NEVER;
|
istk->conds->state = COND_NEVER;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
j = if_condition(expand_mmac_params(tline->next), i);
|
j = if_condition(tline->next, i);
|
||||||
tline->next = NULL; /* it got freed */
|
tline->next = NULL; /* it got freed */
|
||||||
free_tlist(origline);
|
free_tlist(origline);
|
||||||
istk->conds->state =
|
istk->conds->state =
|
||||||
|
|
Loading…
Reference in a new issue