Prevent macro expand in strings, and add a stringify syntax

Verilog does not allow macro expansion in strings, and that's that.
But sometimes people want strings of a macro expansion, so add a
stringify syntax that does the trick.
This commit is contained in:
Stephen Williams 2008-05-08 18:43:07 -07:00
parent fd3ca037aa
commit 73dcace781
1 changed files with 33 additions and 22 deletions

View File

@ -42,7 +42,7 @@ static void do_define();
static int def_is_done();
static int is_defined(const char*name);
static int macro_needs_args();
static int macro_needs_args(const char*name);
static void macro_start_args();
static void macro_add_to_arg();
static void macro_finish_arg();
@ -72,6 +72,8 @@ struct include_stack_t
*/
int ebs;
int stringify_flag;
unsigned lineno;
YY_BUFFER_STATE yybs;
@ -86,6 +88,8 @@ static void emit_pathline(struct include_stack_t* isp);
*/
static struct include_stack_t* file_queue = 0;
static int do_expand_stringify_flag = 0;
/*
* The istack is the inclusion stack.
*/
@ -245,7 +249,7 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
}
<PCOMENT>`[a-zA-Z][a-zA-Z0-9_$]* {
if (macro_needs_args()) yy_push_state(MA_START); else do_expand(0);
if (macro_needs_args(yytext+1)) yy_push_state(MA_START); else do_expand(0);
}
/* Strings do not contain preprocessor directives, but can expand
@ -262,21 +266,6 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
<CSTRING>\" { BEGIN(string_enter); ECHO; }
<CSTRING>. { ECHO; }
<CSTRING>`{keywords} {
emit_pathline(istack);
error_count += 1;
fprintf
(
stderr,
"error: macro names cannot be directive keywords ('%s'); replaced with nothing.\n",
yytext
);
}
<CSTRING>`[a-zA-Z][a-zA-Z0-9_$]* {
if (macro_needs_args()) yy_push_state(MA_START); else do_expand(0);
}
/* This set of patterns matches the include directive and the name
* that follows it. when the directive ends, the do_include function
* performs the include operation.
@ -295,7 +284,7 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
}
<PPINCLUDE>`[a-zA-Z][a-zA-Z0-9_]* {
if (macro_needs_args()) yy_push_state(MA_START); else do_expand(0);
if (macro_needs_args(yytext+1)) yy_push_state(MA_START); else do_expand(0);
}
<PPINCLUDE>\"[^\"]*\" { include_filename(); }
@ -551,12 +540,23 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
/* This pattern notices macros and arranges for them to be replaced. */
`[a-zA-Z_][a-zA-Z0-9_$]* {
if (macro_needs_args())
if (macro_needs_args(yytext+1))
yy_push_state(MA_START);
else
do_expand(0);
}
/* Stringified version of macro expansion. */
``[a-zA-Z_][a-zA-Z0-9_$]* {
assert(do_expand_stringify_flag == 0);
do_expand_stringify_flag = 1;
fputc('"', yyout);
if (macro_needs_args(yytext+2))
yy_push_state(MA_START);
else
do_expand(0);
}
<MA_START>\( { BEGIN(MA_ADD); macro_start_args(); }
<MA_START>{W} {}
@ -1171,16 +1171,16 @@ static void def_undefine()
*/
static struct define_t* cur_macro = 0;
static int macro_needs_args()
static int macro_needs_args(const char*text)
{
cur_macro = def_lookup(yytext+1);
cur_macro = def_lookup(text);
if (cur_macro)
return (cur_macro->argc > 1);
else
{
emit_pathline(istack);
fprintf(stderr, "warning: macro %s undefined (and assumed null) at this point.\n", yytext);
fprintf(stderr, "warning: macro %s undefined (and assumed null) at this point.\n", text);
return 0;
}
}
@ -1348,6 +1348,8 @@ static void do_expand(int use_args)
isp = (struct include_stack_t*) calloc(1, sizeof(struct include_stack_t));
isp->stringify_flag = do_expand_stringify_flag;
do_expand_stringify_flag = 0;
if (use_args)
{
isp->str = &exp_buf[head];
@ -1364,6 +1366,11 @@ static void do_expand(int use_args)
istack = isp;
yy_switch_to_buffer(yy_create_buffer(istack->file, YY_BUF_SIZE));
} else {
if (do_expand_stringify_flag) {
do_expand_stringify_flag = 0;
fputc('"', yyout);
}
}
}
@ -1537,6 +1544,10 @@ static int load_next_input()
exp_buf_free += isp->ebs;
}
if (isp->stringify_flag) {
fputc('"', yyout);
}
free(isp);
/* If I am out of include stack, the main input is