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 */
|
/* 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,
|
static int _cpp_callback_dequeue(Parser * parser, Token * token, int c,
|
||||||
void * data)
|
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_DEFINE:
|
||||||
case CPP_CODE_META_IFDEF:
|
case CPP_CODE_META_IFDEF:
|
||||||
case CPP_CODE_META_IFNDEF:
|
case CPP_CODE_META_IFNDEF:
|
||||||
|
case CPP_CODE_META_INCLUDE:
|
||||||
case CPP_CODE_META_UNDEF:
|
case CPP_CODE_META_UNDEF:
|
||||||
token_set_string(token, "");
|
token_set_string(token, "");
|
||||||
token_set_data(token, cpp->queue_string);
|
token_set_data(token, cpp->queue_string);
|
||||||
cpp->queue_string = NULL;
|
cpp->queue_string = NULL;
|
||||||
break;
|
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_ERROR:
|
||||||
case CPP_CODE_META_WARNING:
|
case CPP_CODE_META_WARNING:
|
||||||
token_set_string(token, (cpp->queue_string != NULL)
|
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;
|
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 */
|
/* cpp_callback_header */
|
||||||
static int _cpp_callback_header(Parser * parser, Token * token, int c,
|
static int _cpp_callback_header(Parser * parser, Token * token, int c,
|
||||||
|
@ -1026,6 +927,99 @@ char const * cppparser_get_filename(CppParser * cpp)
|
||||||
|
|
||||||
|
|
||||||
/* useful */
|
/* 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 */
|
/* cppparser_inject */
|
||||||
/* FIXME should take a buffer as input? */
|
/* FIXME should take a buffer as input? */
|
||||||
int cppparser_inject(CppParser * cp, char const * string)
|
int cppparser_inject(CppParser * cp, char const * string)
|
||||||
|
|
|
@ -36,6 +36,7 @@ char const * cppparser_get_filename(CppParser * cppparser);
|
||||||
|
|
||||||
|
|
||||||
/* useful */
|
/* useful */
|
||||||
|
int cppparser_include(CppParser * cppparser, char const * include);
|
||||||
int cppparser_inject(CppParser * cppparser, char const * string);
|
int cppparser_inject(CppParser * cppparser, char const * string);
|
||||||
int cppparser_scan(CppParser * cppparser, Token ** token);
|
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_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_define(Cpp * cpp, Token ** token);
|
||||||
|
static int _scan_include(Cpp * cpp, Token * token);
|
||||||
static int _scan_undef(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)
|
||||||
|
@ -163,6 +164,8 @@ int cpp_scan(Cpp * cpp, Token ** token)
|
||||||
{
|
{
|
||||||
case CPP_CODE_META_DEFINE:
|
case CPP_CODE_META_DEFINE:
|
||||||
return _scan_define(cpp, token);
|
return _scan_define(cpp, token);
|
||||||
|
case CPP_CODE_META_INCLUDE:
|
||||||
|
return _scan_include(cpp, *token);
|
||||||
case CPP_CODE_META_UNDEF:
|
case CPP_CODE_META_UNDEF:
|
||||||
return _scan_undef(cpp, token);
|
return _scan_undef(cpp, token);
|
||||||
case CPP_CODE_WORD:
|
case CPP_CODE_WORD:
|
||||||
|
@ -325,6 +328,15 @@ static int _scan_define(Cpp * cpp, Token ** token)
|
||||||
return 0;
|
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)
|
static int _scan_undef(Cpp * cpp, Token ** token)
|
||||||
/* FIXME ignores what's after the spaces after the variable name */
|
/* FIXME ignores what's after the spaces after the variable name */
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user