#defines are no longer processed when out of scope

This commit is contained in:
Pierre Pronchery 2008-06-04 15:01:54 +00:00
parent e270d2a832
commit c85694ebfb

181
src/cpp.c
View File

@ -17,6 +17,7 @@
* - comments are not handled in directives * - comments are not handled in directives
* - fix includes (system vs regular, inclusion order) * - fix includes (system vs regular, inclusion order)
* - potential memory leak with tokens' data * - potential memory leak with tokens' data
* - add a filter for the "%" operator
* - add a way to tokenize input from a string (and handle "#" and "##") */ * - add a way to tokenize input from a string (and handle "#" and "##") */
@ -609,11 +610,9 @@ static int _cpp_callback_comment(Parser * parser, Token * token, int c,
/* cpp_callback_directive */ /* cpp_callback_directive */
/* directives: these functions should return 0 (or -1 on errors) */ /* directives: these functions should return 0 (or -1 on errors) */
static int _directive_define(Cpp * cpp, Token * token, char const * str);
static int _directive_ifdef(Token * token, char const * str); static int _directive_ifdef(Token * token, char const * str);
static int _directive_ifndef(Token * token, char const * str); static int _directive_ifndef(Token * token, char const * str);
static int _directive_include(Cpp * cpp, Token * token, char const * str); static int _directive_include(Cpp * cpp, Token * token, char const * str);
static int _directive_undef(Cpp * cpp, Token * token, char const * str);
static int _directive_unknown(Token * token, char const * str); static int _directive_unknown(Token * token, char const * str);
static int _cpp_callback_directive(Parser * parser, Token * token, int c, static int _cpp_callback_directive(Parser * parser, Token * token, int c,
@ -649,7 +648,7 @@ static int _cpp_callback_directive(Parser * parser, Token * token, int c,
switch(i) switch(i)
{ {
case CPP_DIRECTIVE_DEFINE: case CPP_DIRECTIVE_DEFINE:
ret = _directive_define(cpp, token, pos); token_set_code(token, CPP_CODE_META_DEFINE);
break; break;
case CPP_DIRECTIVE_ELIF: case CPP_DIRECTIVE_ELIF:
/* FIXME implement */ /* FIXME implement */
@ -686,7 +685,7 @@ static int _cpp_callback_directive(Parser * parser, Token * token, int c,
token_set_code(token, CPP_CODE_META_PRAGMA); token_set_code(token, CPP_CODE_META_PRAGMA);
break; break;
case CPP_DIRECTIVE_UNDEF: case CPP_DIRECTIVE_UNDEF:
ret = _directive_undef(cpp, token, str); token_set_code(token, CPP_CODE_META_UNDEF);
break; break;
case CPP_DIRECTIVE_WARNING: case CPP_DIRECTIVE_WARNING:
token_set_code(token, CPP_CODE_META_WARNING); token_set_code(token, CPP_CODE_META_WARNING);
@ -710,46 +709,6 @@ static int _directive_unknown(Token * token, char const * str)
} }
/* directives */ /* directives */
/* directive_define */
static int _directive_define(Cpp * cpp, Token * token, char const * str)
{
size_t i;
size_t j;
size_t k = 0;
int tmp;
char * var;
char const * val;
token_set_code(token, CPP_CODE_META_DEFINE);
for(i = 1; (tmp = str[i]) != '\0' && !isspace(tmp); i++)
{
/* FIXME actually implement macros */
if(str[i] != '(')
continue;
for(k = i; str[i] != '\0' && str[i] != ')'; i++);
if(str[i] == ')')
i++;
break;
}
for(j = i; (tmp = str[j]) != '\0' && isspace(tmp); j++);
val = (str[j] != '\0') ? &str[j] : NULL;
/* FIXME inject an error token instead */
if((var = strdup(str)) == NULL)
{
token_set_code(token, CPP_CODE_META_ERROR);
token_set_string(token, strerror(errno));
return 0;
}
var[k != 0 ? k : i] = '\0';
if(cpp_define_add(cpp, var, val) != 0)
{
token_set_code(token, CPP_CODE_META_ERROR);
token_set_string(token, error_get());
}
free(var);
return 0;
}
/* directive_ifdef */ /* directive_ifdef */
static int _directive_ifdef(Token * token, char const * str) static int _directive_ifdef(Token * token, char const * str)
{ {
@ -868,14 +827,6 @@ static char * _lookup_error(Token * token, char const * path, int system)
return NULL; return NULL;
} }
/* directive_undef */
static int _directive_undef(Cpp * cpp, Token * token, char const * str)
{
cpp_define_remove(cpp, str);
token_set_code(token, CPP_CODE_META_UNDEF);
return 0;
}
/* cpp_callback_comma */ /* cpp_callback_comma */
static int _cpp_callback_comma(Parser * parser, Token * token, int c, static int _cpp_callback_comma(Parser * parser, Token * token, int c,
@ -1164,15 +1115,15 @@ int cpp_define_remove(Cpp * cpp, char const * name)
{ {
size_t i; size_t i;
cpp = cpp->parent;
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "DEBUG: %s(cpp, \"%s\")\n", __func__, name); fprintf(stderr, "DEBUG: %s(cpp, \"%s\")\n", __func__, name);
#endif #endif
cpp = cpp->parent;
for(i = 0; i < cpp->defines_cnt; i++) for(i = 0; i < cpp->defines_cnt; i++)
if(strcmp(cpp->defines[i].name, name) == 0) if(strcmp(cpp->defines[i].name, name) == 0)
break; break;
if(i == cpp->defines_cnt) if(i == cpp->defines_cnt)
return 1; /* was not found */ return error_set_code(1, "%s is not defined", name);
free(cpp->defines[i].name); free(cpp->defines[i].name);
free(cpp->defines[i].value); free(cpp->defines[i].value);
cpp->defines_cnt--; cpp->defines_cnt--;
@ -1212,32 +1163,48 @@ static int _scan_if(Cpp * cpp);
static int _scan_elif(Cpp * cpp, Token ** token); static int _scan_elif(Cpp * cpp, Token ** token);
static int _scan_else(Cpp * cpp, Token ** token); static int _scan_else(Cpp * cpp, Token ** token);
static int _scan_endif(Cpp * cpp, Token ** token); static int _scan_endif(Cpp * cpp, Token ** token);
static int _scan_define(Cpp * cpp, Token ** token);
static int _scan_undef(Cpp * cpp, Token ** token);
int cpp_scan(Cpp * cpp, Token ** token) int cpp_scan(Cpp * cpp, Token ** token)
{ {
int ret; int ret;
TokenCode code; TokenCode code;
if((ret = _scan_get_next(cpp, token)) != 0) for(; (ret = _scan_get_next(cpp, token)) == 0; token_delete(*token))
return ret; {
if(*token == NULL) if(*token == NULL) /* end of file */
return 0; break;
if((code = token_get_code(*token)) == CPP_CODE_META_IFDEF) switch((code = token_get_code(*token)))
{
case CPP_CODE_META_IFDEF:
return _scan_ifdef(cpp, token); return _scan_ifdef(cpp, token);
if(code == CPP_CODE_META_IFNDEF) case CPP_CODE_META_IFNDEF:
return _scan_ifndef(cpp, token); return _scan_ifndef(cpp, token);
if(code == CPP_CODE_META_IF) case CPP_CODE_META_IF:
return _scan_if(cpp); return _scan_if(cpp);
if(code == CPP_CODE_META_ELIF) case CPP_CODE_META_ELIF:
return _scan_elif(cpp, token); return _scan_elif(cpp, token);
if(code == CPP_CODE_META_ELSE) case CPP_CODE_META_ELSE:
return _scan_else(cpp, token); return _scan_else(cpp, token);
if(code == CPP_CODE_META_ENDIF) case CPP_CODE_META_ENDIF:
return _scan_endif(cpp, token); return _scan_endif(cpp, token);
if(_cpp_scope_get(cpp) == CPP_SCOPE_TAKING) default:
break;
}
if(_cpp_scope_get(cpp) != CPP_SCOPE_TAKING) /* not in scope */
continue;
switch(code)
{
case CPP_CODE_META_DEFINE:
return _scan_define(cpp, token);
case CPP_CODE_META_UNDEF:
return _scan_undef(cpp, token);
default:
return 0; return 0;
token_delete(*token); }
return cpp_scan(cpp, token); /* FIXME do this in a loop */ }
return ret;
} }
static int _scan_get_next(Cpp * cpp, Token ** token) static int _scan_get_next(Cpp * cpp, Token ** token)
@ -1302,11 +1269,11 @@ static int _scan_elif(Cpp * cpp, Token ** token)
" or #ifndef"); " or #ifndef");
return 0; return 0;
} }
/* FIXME check the condition */
scope = _cpp_scope_get(cpp); scope = _cpp_scope_get(cpp);
if(scope == CPP_SCOPE_TAKING) if(scope == CPP_SCOPE_TAKING)
_cpp_scope_set(cpp, CPP_SCOPE_TAKEN); _cpp_scope_set(cpp, CPP_SCOPE_TAKEN);
else if(scope == CPP_SCOPE_NOTYET) else if(scope == CPP_SCOPE_NOTYET)
/* FIXME check the condition */
_cpp_scope_set(cpp, CPP_SCOPE_TAKING); _cpp_scope_set(cpp, CPP_SCOPE_TAKING);
return 0; return 0;
} }
@ -1343,3 +1310,81 @@ static int _scan_endif(Cpp * cpp, Token ** token)
_cpp_scope_pop(cpp); _cpp_scope_pop(cpp);
return 0; return 0;
} }
static int _scan_define(Cpp * cpp, Token ** token)
{
char const * str;
int tmp;
size_t i;
size_t j;
size_t k = 0;
char * var;
char const * val;
str = token_get_string(*token);
/* skip '#' and white-spaces */
for(str++; (tmp = *str) != '\0' && isspace(tmp); str++);
/* skip "define" and white-spaces */
for(str+=6; (tmp = *str) != '\0' && isspace(tmp); str++);
/* fetch variable name */
for(i = 1; (tmp = str[i]) != '\0' && !isspace(tmp); i++)
{
/* FIXME actually implement macros */
if(str[i] != '(')
continue;
for(k = i; str[i] != '\0' && str[i] != ')'; i++);
if(str[i] == ')')
i++;
break;
}
/* skip white-spaces and fetch value */
for(j = i; (tmp = str[j]) != '\0' && isspace(tmp); j++);
val = (str[j] != '\0') ? &str[j] : NULL;
/* FIXME inject an error token instead */
if((var = strdup(str)) == NULL)
{
token_set_code(*token, CPP_CODE_META_ERROR);
token_set_string(*token, strerror(errno));
return 0;
}
var[k != 0 ? k : i] = '\0';
if(cpp_define_add(cpp, var, val) != 0)
{
token_set_code(*token, CPP_CODE_META_ERROR);
token_set_string(*token, error_get());
}
free(var);
return 0;
}
static int _scan_undef(Cpp * cpp, Token ** token)
/* FIXME ignores what's after the spaces after the variable name */
{
char const * str;
int tmp;
size_t i;
char * var;
str = token_get_string(*token);
/* skip '#' and white-spaces */
for(str++; (tmp = *str) != '\0' && isspace(tmp); str++);
/* skip "undef" and white-spaces */
for(str+=5; (tmp = *str) != '\0' && isspace(tmp); str++);
/* fetch variable name */
for(i = 1; (tmp = str[i]) != '\0' && !isspace(tmp); i++);
/* FIXME inject an error token instead */
if((var = strdup(str)) == NULL)
{
token_set_code(*token, CPP_CODE_META_ERROR);
token_set_string(*token, strerror(errno));
return 0;
}
var[i] = '\0';
if(cpp_define_remove(cpp, var) != 0)
{
token_set_code(*token, CPP_CODE_META_ERROR);
token_set_string(*token, error_get());
}
free(var);
return 0;
}