ivlpp: foundation for 'magic' macros, eg `__LINE__

This commit is contained in:
Joe Auricchio 2010-11-27 02:11:12 -05:00 committed by Stephen Williams
parent 25c1795fb7
commit 8cf66adbc0
1 changed files with 49 additions and 0 deletions

View File

@ -45,6 +45,7 @@ static void macro_start_args();
static void macro_add_to_arg();
static void macro_finish_arg();
static void do_expand(int use_args);
static const char* do_magic(const char*name);
static const char* macro_name();
static void include_filename();
@ -650,6 +651,10 @@ struct define_t
char* value;
int keyword; /* keywords don't get rescanned for fresh values. */
int argc;
int magic; /* 1 for 'magic' macros like __FILE__ and __LINE__. magic
* macros cannot be undefined. magic macros are expanded
* by do_magic. N.B. DON'T set a magic macro with
* argc > 1 or with keyword true. */
struct define_t* left;
struct define_t* right;
@ -779,6 +784,7 @@ void define_macro(const char* name, const char* value, int keyword, int argc)
def->value = strdup(value);
def->keyword = keyword;
def->argc = argc;
def->magic = 0;
def->left = 0;
def->right = 0;
def->up = 0;
@ -854,6 +860,17 @@ static size_t define_cnt = 0;
static int define_continue_flag = 0;
/*
* The do_magic function puts the expansions of magic macros into
* this buffer and returns its address. It reallocs as needed to
* fit its whole expansion. Because of this, do_magic is
* -NOT REENTRANT-. It is called from do_expand, which strdups
* or otherwise copies the result before doing any recursion, so
* I don't anticipate any problems.
*/
static char* magic_text = 0;
static size_t magic_cnt = 0;
/*
* Define a special character code used to mark the insertion point
* for arguments in the macro text. This should be a character that
@ -1095,6 +1112,7 @@ static void def_undefine()
cur = def_lookup(def_buf);
if (cur == 0) return;
if (cur->magic) return;
if (cur->up == 0)
{
@ -1379,6 +1397,12 @@ static void do_expand(int use_args)
{
isp->str = &exp_buf[head];
}
else if(cur_macro->magic)
{
// cast const char * to char * to suppress warning, since we won't
// be modifying isp->str in place.
isp->str = (char*)do_magic(cur_macro->name);
}
else
{
isp->str = cur_macro->value;
@ -1432,6 +1456,31 @@ static void do_expand(int use_args)
}
}
/*
* Expand the magic macro named name. Return a buffer containing the expansion.
*/
static const char* do_magic(const char*name)
{
size_t desired_cnt = 0;
if(!magic_text)
{
magic_text = malloc(24); // unimportant initial size
}
if(!strcmp(name, "__LINE__"))
{
// to be implemented
}
// if we get here, then either there was no magic macro with the requested
// name, or for some reason (an error?) we want to return an empty string
assert(magic_cnt > 0);
magic_text[0] = '\0';
return magic_text;
}
/*
* Include file handling works by keeping an include stack of the
* files that are opened and being processed. The first item on the