Also partially implemented #elif

This commit is contained in:
Pierre Pronchery 2009-08-01 02:40:03 +00:00
parent 153753d0bd
commit 33269a5353
2 changed files with 47 additions and 28 deletions

View File

@ -575,6 +575,7 @@ static int _cpp_callback_dequeue(Parser * parser, Token * token, int c,
switch(cpp->queue_code) switch(cpp->queue_code)
{ {
case CPP_CODE_META_DEFINE: case CPP_CODE_META_DEFINE:
case CPP_CODE_META_ELIF:
case CPP_CODE_META_IF: case CPP_CODE_META_IF:
case CPP_CODE_META_IFDEF: case CPP_CODE_META_IFDEF:
case CPP_CODE_META_IFNDEF: case CPP_CODE_META_IFNDEF:

View File

@ -14,7 +14,8 @@
* NonCommercial-ShareAlike 3.0 along with cpp; if not, browse to * NonCommercial-ShareAlike 3.0 along with cpp; if not, browse to
* http://creativecommons.org/licenses/by-nc-sa/3.0/ */ * http://creativecommons.org/licenses/by-nc-sa/3.0/ */
/* FIXME: /* FIXME:
* - potential memory leak with tokens' data */ * - potential memory leak with tokens' data
* - apparently not checking that scopes are properly closed upon exit */
@ -221,53 +222,70 @@ static int _scan_ifndef(Cpp * cpp, Token ** token)
return 0; return 0;
} }
static CppScope _if_do(Cpp * cpp, char const * str);
static int _scan_if(Cpp * cpp, Token ** token) static int _scan_if(Cpp * cpp, Token ** token)
{ {
char * str; char * str;
char * p;
char const * q;
DEBUG_SCOPE(); DEBUG_SCOPE();
if((str = token_get_data(*token)) == NULL) str = token_get_data(*token);
/* FIXME it's probably an error case instead */ _cpp_scope_push(cpp, _if_do(cpp, str));
_cpp_scope_push(cpp, CPP_SCOPE_NOTYET); token_set_data(*token, NULL);
else if(strcmp(str, "1") == 0)
_cpp_scope_push(cpp, CPP_SCOPE_TAKING);
else if(strncmp(str, "defined(", 8) == 0 &&
(p = strchr(str, ')')) != NULL)
{
*p = '\0';
_cpp_scope_push(cpp, cpp_define_get(cpp, &str[8]) != NULL
? CPP_SCOPE_TAKING : CPP_SCOPE_NOTYET);
}
else if((q = cpp_define_get(cpp, str)) != NULL && strcmp(q, "1") == 0)
_cpp_scope_push(cpp, CPP_SCOPE_TAKING);
else
/* FIXME really check the condition */
_cpp_scope_push(cpp, CPP_SCOPE_NOTYET);
free(str); free(str);
return 0; return 0;
} }
static CppScope _if_do(Cpp * cpp, char const * str)
{
char * p;
char const * q;
if(str == NULL)
/* FIXME it's probably an error case instead */
return CPP_SCOPE_NOTYET;
if(strcmp(str, "1") == 0)
return CPP_SCOPE_TAKING;
if(strncmp(str, "defined(", 8) == 0 && (p = strchr(str, ')')) != NULL)
{
*p = '\0';
return (cpp_define_get(cpp, &str[8]) != NULL)
? CPP_SCOPE_TAKING : CPP_SCOPE_NOTYET;
}
else if((q = cpp_define_get(cpp, str)) != NULL && strcmp(q, "1") == 0)
return CPP_SCOPE_TAKING;
/* FIXME really check the condition */
return CPP_SCOPE_NOTYET;
}
static int _scan_elif(Cpp * cpp, Token ** token) static int _scan_elif(Cpp * cpp, Token ** token)
{ {
int ret = 0;
CppScope scope; CppScope scope;
char * str;
DEBUG_SCOPE(); DEBUG_SCOPE();
str = token_get_data(*token);
if(_cpp_scope_get_count(cpp) == 0) if(_cpp_scope_get_count(cpp) == 0)
{ {
token_set_code(*token, CPP_CODE_META_ERROR); token_set_code(*token, CPP_CODE_META_ERROR);
token_set_string(*token, "#elif without #if or #ifdef" token_set_string(*token, "#elif without #if or #ifdef"
" or #ifndef"); " or #ifndef");
return 0; ret = 0;
} }
else
{
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, _if_do(cpp, str));
_cpp_scope_set(cpp, CPP_SCOPE_TAKING); }
return 0; if(str != NULL)
{
token_set_data(*token, NULL);
free(str);
}
return ret;
} }
static int _scan_else(Cpp * cpp, Token ** token) static int _scan_else(Cpp * cpp, Token ** token)