Process #include only if it's in scope
This commit is contained in:
parent
441ef54e5d
commit
397c08cebf
194
src/parser.c
194
src/parser.c
|
@ -559,10 +559,6 @@ static int _cpp_callback_inject(Parser * parser, Token * token, int c,
|
|||
|
||||
|
||||
/* cpp_callback_dequeue */
|
||||
static int _dequeue_include(CppParser * cpp, Token * token, char const * str);
|
||||
static char * _include_path(CppParser * cpp, char const * str);
|
||||
static char * _path_lookup(CppParser * cpp, char const * path, int system);
|
||||
|
||||
static int _cpp_callback_dequeue(Parser * parser, Token * token, int c,
|
||||
void * data)
|
||||
{
|
||||
|
@ -581,15 +577,12 @@ static int _cpp_callback_dequeue(Parser * parser, Token * token, int c,
|
|||
case CPP_CODE_META_DEFINE:
|
||||
case CPP_CODE_META_IFDEF:
|
||||
case CPP_CODE_META_IFNDEF:
|
||||
case CPP_CODE_META_INCLUDE:
|
||||
case CPP_CODE_META_UNDEF:
|
||||
token_set_string(token, "");
|
||||
token_set_data(token, cpp->queue_string);
|
||||
cpp->queue_string = NULL;
|
||||
break;
|
||||
case CPP_CODE_META_INCLUDE:
|
||||
token_set_string(token, "");
|
||||
ret = _dequeue_include(cpp, token, cpp->queue_string);
|
||||
break;
|
||||
case CPP_CODE_META_ERROR:
|
||||
case CPP_CODE_META_WARNING:
|
||||
token_set_string(token, (cpp->queue_string != NULL)
|
||||
|
@ -612,98 +605,6 @@ static int _cpp_callback_dequeue(Parser * parser, Token * token, int c,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int _dequeue_include(CppParser * cp, Token * token, char const * str)
|
||||
{
|
||||
char * path;
|
||||
|
||||
if((path = _include_path(cp, str)) == NULL)
|
||||
{
|
||||
token_set_code(token, CPP_CODE_META_ERROR);
|
||||
token_set_string(token, error_get());
|
||||
return 0;
|
||||
}
|
||||
if((cp->subparser = cppparser_new(cp->cpp, cp, path, cp->filters))
|
||||
== NULL)
|
||||
{
|
||||
free(path);
|
||||
return -1;
|
||||
}
|
||||
free(path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char * _include_path(CppParser * cpp, char const * str)
|
||||
{
|
||||
int d;
|
||||
size_t len;
|
||||
char * path = NULL;
|
||||
char * p;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s(%p, \"%s\")\n", __func__, cpp, str);
|
||||
#endif
|
||||
if(str[0] == '"')
|
||||
d = str[0];
|
||||
else if(str[0] == '<')
|
||||
d = '>';
|
||||
else
|
||||
{
|
||||
error_set("%s", "Invalid include directive");
|
||||
return NULL;
|
||||
}
|
||||
len = strlen(str);
|
||||
if(len < 3 || str[len - 1] != d)
|
||||
{
|
||||
error_set("%s", "Invalid include directive");
|
||||
return NULL;
|
||||
}
|
||||
if((path = strdup(&str[1])) == NULL)
|
||||
{
|
||||
error_set("%s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
path[len - 2] = '\0';
|
||||
p = _path_lookup(cpp, path, d == '>');
|
||||
free(path);
|
||||
return p;
|
||||
}
|
||||
|
||||
static char * _path_lookup(CppParser * cp, char const * path, int system)
|
||||
{
|
||||
Cpp * cpp = cp->cpp;
|
||||
char const * filename;
|
||||
char * p;
|
||||
char * q;
|
||||
char * r;
|
||||
struct stat st;
|
||||
|
||||
if(system != 0)
|
||||
return cpp_path_lookup(cp->cpp, path);
|
||||
for(; cp != NULL; cp = cp->parent)
|
||||
{
|
||||
filename = parser_get_filename(cp->parser);
|
||||
if((p = string_new(filename)) == NULL)
|
||||
return NULL;
|
||||
q = dirname(p);
|
||||
if((r = string_new(q)) == NULL || string_append(&r, "/") != 0
|
||||
|| string_append(&r, path) != 0)
|
||||
{
|
||||
string_delete(r);
|
||||
string_delete(p);
|
||||
return NULL;
|
||||
}
|
||||
string_delete(p);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: stat(\"%s\", %p)\n", r, &st);
|
||||
#endif
|
||||
if(stat(r, &st) == 0)
|
||||
return r;
|
||||
error_set("%s: %s", r, strerror(errno));
|
||||
string_delete(r);
|
||||
}
|
||||
return cpp_path_lookup(cpp, path); /* XXX errors change "" into <> */
|
||||
}
|
||||
|
||||
|
||||
/* cpp_callback_header */
|
||||
static int _cpp_callback_header(Parser * parser, Token * token, int c,
|
||||
|
@ -1026,6 +927,99 @@ char const * cppparser_get_filename(CppParser * cpp)
|
|||
|
||||
|
||||
/* useful */
|
||||
/* cppparser_include */
|
||||
static char * _include_path(CppParser * cpp, char const * str);
|
||||
static char * _path_lookup(CppParser * cp, char const * path, int system);
|
||||
|
||||
int cppparser_include(CppParser * cp, char const * include)
|
||||
{
|
||||
char * path;
|
||||
|
||||
if((path = _include_path(cp, include)) == NULL)
|
||||
return -1;
|
||||
if((cp->subparser = cppparser_new(cp->cpp, cp, path, cp->filters))
|
||||
== NULL)
|
||||
{
|
||||
free(path);
|
||||
return -1;
|
||||
}
|
||||
free(path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char * _include_path(CppParser * cpp, char const * str)
|
||||
{
|
||||
int d;
|
||||
size_t len;
|
||||
char * path = NULL;
|
||||
char * p;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s(%p, \"%s\")\n", __func__, cpp, str);
|
||||
#endif
|
||||
if(str[0] == '"')
|
||||
d = str[0];
|
||||
else if(str[0] == '<')
|
||||
d = '>';
|
||||
else
|
||||
{
|
||||
error_set("%s", "Invalid include directive");
|
||||
return NULL;
|
||||
}
|
||||
len = strlen(str);
|
||||
if(len < 3 || str[len - 1] != d)
|
||||
{
|
||||
error_set("%s", "Invalid include directive");
|
||||
return NULL;
|
||||
}
|
||||
if((path = strdup(&str[1])) == NULL)
|
||||
{
|
||||
error_set("%s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
path[len - 2] = '\0';
|
||||
p = _path_lookup(cpp, path, d == '>');
|
||||
free(path);
|
||||
return p;
|
||||
}
|
||||
|
||||
static char * _path_lookup(CppParser * cp, char const * path, int system)
|
||||
{
|
||||
Cpp * cpp = cp->cpp;
|
||||
char const * filename;
|
||||
char * p;
|
||||
char * q;
|
||||
char * r;
|
||||
struct stat st;
|
||||
|
||||
if(system != 0)
|
||||
return cpp_path_lookup(cp->cpp, path);
|
||||
for(; cp != NULL; cp = cp->parent)
|
||||
{
|
||||
filename = parser_get_filename(cp->parser);
|
||||
if((p = string_new(filename)) == NULL)
|
||||
return NULL;
|
||||
q = dirname(p);
|
||||
if((r = string_new(q)) == NULL || string_append(&r, "/") != 0
|
||||
|| string_append(&r, path) != 0)
|
||||
{
|
||||
string_delete(r);
|
||||
string_delete(p);
|
||||
return NULL;
|
||||
}
|
||||
string_delete(p);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: stat(\"%s\", %p)\n", r, &st);
|
||||
#endif
|
||||
if(stat(r, &st) == 0)
|
||||
return r;
|
||||
error_set("%s: %s", r, strerror(errno));
|
||||
string_delete(r);
|
||||
}
|
||||
return cpp_path_lookup(cpp, path); /* XXX errors change "" into <> */
|
||||
}
|
||||
|
||||
|
||||
/* cppparser_inject */
|
||||
/* FIXME should take a buffer as input? */
|
||||
int cppparser_inject(CppParser * cp, char const * string)
|
||||
|
|
|
@ -36,6 +36,7 @@ char const * cppparser_get_filename(CppParser * cppparser);
|
|||
|
||||
|
||||
/* useful */
|
||||
int cppparser_include(CppParser * cppparser, char const * include);
|
||||
int cppparser_inject(CppParser * cppparser, char const * string);
|
||||
int cppparser_scan(CppParser * cppparser, Token ** token);
|
||||
|
||||
|
|
|
@ -116,6 +116,7 @@ static int _scan_elif(Cpp * cpp, Token ** token);
|
|||
static int _scan_else(Cpp * cpp, Token ** token);
|
||||
static int _scan_endif(Cpp * cpp, Token ** token);
|
||||
static int _scan_define(Cpp * cpp, Token ** token);
|
||||
static int _scan_include(Cpp * cpp, Token * token);
|
||||
static int _scan_undef(Cpp * cpp, Token ** token);
|
||||
|
||||
int cpp_scan(Cpp * cpp, Token ** token)
|
||||
|
@ -163,6 +164,8 @@ int cpp_scan(Cpp * cpp, Token ** token)
|
|||
{
|
||||
case CPP_CODE_META_DEFINE:
|
||||
return _scan_define(cpp, token);
|
||||
case CPP_CODE_META_INCLUDE:
|
||||
return _scan_include(cpp, *token);
|
||||
case CPP_CODE_META_UNDEF:
|
||||
return _scan_undef(cpp, token);
|
||||
case CPP_CODE_WORD:
|
||||
|
@ -325,6 +328,15 @@ static int _scan_define(Cpp * cpp, Token ** token)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int _scan_include(Cpp * cpp, Token * token)
|
||||
{
|
||||
if(cppparser_include(cpp->parser, token_get_data(token)) == 0)
|
||||
return 0;
|
||||
token_set_code(token, CPP_CODE_META_ERROR);
|
||||
token_set_string(token, error_get());
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _scan_undef(Cpp * cpp, Token ** token)
|
||||
/* FIXME ignores what's after the spaces after the variable name */
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user