Better handling of directives
This commit is contained in:
parent
5ec29c6031
commit
b149b38cf9
|
@ -39,6 +39,7 @@ typedef enum _CppCode
|
||||||
CPP_CODE_NULL = TC_NULL,
|
CPP_CODE_NULL = TC_NULL,
|
||||||
CPP_CODE_COMMA,
|
CPP_CODE_COMMA,
|
||||||
CPP_CODE_DQUOTE,
|
CPP_CODE_DQUOTE,
|
||||||
|
CPP_CODE_META_DATA,
|
||||||
CPP_CODE_META_DEFINE,
|
CPP_CODE_META_DEFINE,
|
||||||
CPP_CODE_META_ELIF,
|
CPP_CODE_META_ELIF,
|
||||||
CPP_CODE_META_ELSE,
|
CPP_CODE_META_ELSE,
|
||||||
|
@ -48,7 +49,6 @@ typedef enum _CppCode
|
||||||
CPP_CODE_META_IFDEF,
|
CPP_CODE_META_IFDEF,
|
||||||
CPP_CODE_META_IFNDEF,
|
CPP_CODE_META_IFNDEF,
|
||||||
CPP_CODE_META_INCLUDE,
|
CPP_CODE_META_INCLUDE,
|
||||||
CPP_CODE_META_LINE,
|
|
||||||
CPP_CODE_META_PRAGMA,
|
CPP_CODE_META_PRAGMA,
|
||||||
CPP_CODE_META_UNDEF,
|
CPP_CODE_META_UNDEF,
|
||||||
CPP_CODE_META_WARNING,
|
CPP_CODE_META_WARNING,
|
||||||
|
@ -108,7 +108,7 @@ typedef enum _CppCode
|
||||||
} CppCode;
|
} CppCode;
|
||||||
# define CPP_CODE_LAST CPP_CODE_UNKNOWN
|
# define CPP_CODE_LAST CPP_CODE_UNKNOWN
|
||||||
# define CPP_CODE_COUNT (CPP_CODE_LAST + 1)
|
# define CPP_CODE_COUNT (CPP_CODE_LAST + 1)
|
||||||
# define CPP_CODE_META_FIRST CPP_CODE_META_DEFINE
|
# define CPP_CODE_META_FIRST CPP_CODE_META_DATA
|
||||||
# define CPP_CODE_META_LAST CPP_CODE_META_WARNING
|
# define CPP_CODE_META_LAST CPP_CODE_META_WARNING
|
||||||
|
|
||||||
|
|
||||||
|
|
140
src/parser.c
140
src/parser.c
|
@ -138,8 +138,8 @@ static const size_t _cpp_operators_cnt = sizeof(_cpp_operators)
|
||||||
/* directives */
|
/* directives */
|
||||||
static const char * _cpp_directives[] =
|
static const char * _cpp_directives[] =
|
||||||
{
|
{
|
||||||
"define", "elif", "else", "endif", "error", "if", "ifdef", "ifndef",
|
"data", "define", "elif", "else", "endif", "error", "if", "ifdef",
|
||||||
"include", "line", "pragma", "undef", "warning", NULL
|
"ifndef", "include", "pragma", "undef", "warning", NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -147,6 +147,8 @@ static const char * _cpp_directives[] =
|
||||||
/* useful */
|
/* useful */
|
||||||
static int _cpp_isword(int c);
|
static int _cpp_isword(int c);
|
||||||
static char * _cpp_parse_word(Parser * parser, int c);
|
static char * _cpp_parse_word(Parser * parser, int c);
|
||||||
|
static int _cpp_token_set(CppParser * cp, Token * token, TokenCode code,
|
||||||
|
char const * string);
|
||||||
|
|
||||||
/* filters */
|
/* filters */
|
||||||
static int _cpp_filter_newlines(int * c, void * data);
|
static int _cpp_filter_newlines(int * c, void * data);
|
||||||
|
@ -214,6 +216,33 @@ static char * _cpp_parse_word(Parser * parser, int c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* cpp_token_set */
|
||||||
|
static int _cpp_token_set(CppParser * cp, Token * token, TokenCode code,
|
||||||
|
char const * string)
|
||||||
|
{
|
||||||
|
if(token_set_string(token, string) != 0)
|
||||||
|
return -1;
|
||||||
|
if(cp->queue_code == CPP_CODE_NULL)
|
||||||
|
{
|
||||||
|
token_set_code(token, code);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* we are parsing a directive */
|
||||||
|
token_set_code(token, CPP_CODE_META_DATA);
|
||||||
|
if(code == CPP_CODE_COMMENT)
|
||||||
|
/* comments really are whitespaces */
|
||||||
|
string = " ";
|
||||||
|
if(cp->queue_string == NULL)
|
||||||
|
{
|
||||||
|
if((cp->queue_string = string_new(string)) == NULL)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if(string_append(&cp->queue_string, string) != 0)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* filters */
|
/* filters */
|
||||||
/* cpp_filter_newlines */
|
/* cpp_filter_newlines */
|
||||||
static int _cpp_filter_newlines(int * c, void * data)
|
static int _cpp_filter_newlines(int * c, void * data)
|
||||||
|
@ -442,7 +471,7 @@ static int _cpp_callback_otherspace(Parser * parser, Token * token, int c,
|
||||||
static int _cpp_callback_comment(Parser * parser, Token * token, int c,
|
static int _cpp_callback_comment(Parser * parser, Token * token, int c,
|
||||||
void * data)
|
void * data)
|
||||||
{
|
{
|
||||||
CppParser * cpp = data;
|
CppParser * cp = data;
|
||||||
char * str = NULL;
|
char * str = NULL;
|
||||||
size_t len = 2;
|
size_t len = 2;
|
||||||
char * p;
|
char * p;
|
||||||
|
@ -451,17 +480,10 @@ static int _cpp_callback_comment(Parser * parser, Token * token, int c,
|
||||||
return 1;
|
return 1;
|
||||||
DEBUG_CALLBACK();
|
DEBUG_CALLBACK();
|
||||||
if((c = parser_scan_filter(parser)) != '*')
|
if((c = parser_scan_filter(parser)) != '*')
|
||||||
{
|
return _cpp_token_set(cp, token, CPP_CODE_OPERATOR_DIVIDE, "/");
|
||||||
if(cpp->queue_code == CPP_CODE_NULL)
|
|
||||||
token_set_code(token, CPP_CODE_OPERATOR_DIVIDE);
|
|
||||||
else
|
|
||||||
token_set_code(token, CPP_CODE_META_LINE); /* XXX */
|
|
||||||
token_set_string(token, "/");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
for(c = parser_scan_filter(parser); c != EOF;)
|
for(c = parser_scan_filter(parser); c != EOF;)
|
||||||
{
|
{
|
||||||
if(!(cpp->filters & CPP_FILTER_COMMENT))
|
if(!(cp->filters & CPP_FILTER_COMMENT))
|
||||||
{
|
{
|
||||||
if((p = realloc(str, len + 3)) == NULL)
|
if((p = realloc(str, len + 3)) == NULL)
|
||||||
return -error_set_code(1, "%s", strerror(
|
return -error_set_code(1, "%s", strerror(
|
||||||
|
@ -479,22 +501,15 @@ static int _cpp_callback_comment(Parser * parser, Token * token, int c,
|
||||||
}
|
}
|
||||||
if(c == EOF)
|
if(c == EOF)
|
||||||
return -error_set_code(1, "%s", "End of file within a comment");
|
return -error_set_code(1, "%s", "End of file within a comment");
|
||||||
if(str != NULL)
|
|
||||||
{
|
|
||||||
str[0] = '/';
|
|
||||||
str[1] = '*';
|
|
||||||
str[len++] = '/';
|
|
||||||
str[len] = '\0';
|
|
||||||
token_set_code(token, CPP_CODE_COMMENT);
|
|
||||||
token_set_string(token, str);
|
|
||||||
free(str);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
token_set_code(token, CPP_CODE_WHITESPACE);
|
|
||||||
token_set_string(token, " ");
|
|
||||||
}
|
|
||||||
parser_scan_filter(parser);
|
parser_scan_filter(parser);
|
||||||
|
if(str == NULL)
|
||||||
|
return _cpp_token_set(cp, token, CPP_CODE_WHITESPACE, " ");
|
||||||
|
str[0] = '/';
|
||||||
|
str[1] = '*';
|
||||||
|
str[len++] = '/';
|
||||||
|
str[len] = '\0';
|
||||||
|
_cpp_token_set(cp, token, CPP_CODE_COMMENT, str); /* XXX may fail */
|
||||||
|
free(str);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -682,7 +697,7 @@ static int _cpp_callback_header(Parser * parser, Token * token, int c,
|
||||||
parser_scan_filter(parser);
|
parser_scan_filter(parser);
|
||||||
}
|
}
|
||||||
str[len] = '\0';
|
str[len] = '\0';
|
||||||
token_set_code(token, CPP_CODE_META_LINE);
|
token_set_code(token, CPP_CODE_META_DATA);
|
||||||
token_set_string(token, str);
|
token_set_string(token, str);
|
||||||
if(cp->queue_string == NULL)
|
if(cp->queue_string == NULL)
|
||||||
cp->queue_string = str;
|
cp->queue_string = str;
|
||||||
|
@ -711,7 +726,7 @@ static int _cpp_callback_control(Parser * parser, Token * token, int c,
|
||||||
}
|
}
|
||||||
DEBUG_CALLBACK();
|
DEBUG_CALLBACK();
|
||||||
parser_scan_filter(parser);
|
parser_scan_filter(parser);
|
||||||
token_set_code(token, CPP_CODE_META_LINE); /* XXX */
|
token_set_code(token, CPP_CODE_META_DATA);
|
||||||
token_set_string(token, "#");
|
token_set_string(token, "#");
|
||||||
cpp->directive_newline = 0;
|
cpp->directive_newline = 0;
|
||||||
cpp->directive_control = 1;
|
cpp->directive_control = 1;
|
||||||
|
@ -724,20 +739,13 @@ static int _cpp_callback_control(Parser * parser, Token * token, int c,
|
||||||
static int _cpp_callback_comma(Parser * parser, Token * token, int c,
|
static int _cpp_callback_comma(Parser * parser, Token * token, int c,
|
||||||
void * data)
|
void * data)
|
||||||
{
|
{
|
||||||
CppParser * cpp = data;
|
CppParser * cp = data;
|
||||||
|
|
||||||
if(c != ',')
|
if(c != ',')
|
||||||
return 1;
|
return 1;
|
||||||
DEBUG_CALLBACK();
|
DEBUG_CALLBACK();
|
||||||
token_set_code(token, CPP_CODE_COMMA);
|
|
||||||
token_set_string(token, ",");
|
|
||||||
if(cpp->queue_code != CPP_CODE_NULL)
|
|
||||||
{
|
|
||||||
token_set_code(token, CPP_CODE_META_LINE); /* XXX */
|
|
||||||
string_append(&cpp->queue_string, ",");
|
|
||||||
}
|
|
||||||
parser_scan_filter(parser);
|
parser_scan_filter(parser);
|
||||||
return 0;
|
return _cpp_token_set(cp, token, CPP_CODE_COMMA, ",");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -746,7 +754,7 @@ static int _cpp_callback_operator(Parser * parser, Token * token, int c,
|
||||||
void * data)
|
void * data)
|
||||||
/* FIXME probably fails for ".." and similar cases */
|
/* FIXME probably fails for ".." and similar cases */
|
||||||
{
|
{
|
||||||
CppParser * cpp = data;
|
CppParser * cp = data;
|
||||||
size_t i;
|
size_t i;
|
||||||
const size_t j = sizeof(_cpp_operators) / sizeof(*_cpp_operators);
|
const size_t j = sizeof(_cpp_operators) / sizeof(*_cpp_operators);
|
||||||
size_t pos;
|
size_t pos;
|
||||||
|
@ -771,19 +779,8 @@ static int _cpp_callback_operator(Parser * parser, Token * token, int c,
|
||||||
}
|
}
|
||||||
if(i == j) /* should not happen */
|
if(i == j) /* should not happen */
|
||||||
return -1;
|
return -1;
|
||||||
token_set_code(token, _cpp_operators[i].code);
|
return _cpp_token_set(cp, token, _cpp_operators[i].code,
|
||||||
token_set_string(token, _cpp_operators[i].string);
|
_cpp_operators[i].string);
|
||||||
if(cpp->queue_code != CPP_CODE_NULL)
|
|
||||||
{
|
|
||||||
token_set_code(token, CPP_CODE_META_LINE); /* XXX */
|
|
||||||
if(cpp->queue_string == NULL)
|
|
||||||
cpp->queue_string = string_new(
|
|
||||||
_cpp_operators[i].string);
|
|
||||||
else
|
|
||||||
string_append(&cpp->queue_string,
|
|
||||||
_cpp_operators[i].string);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -791,7 +788,7 @@ static int _cpp_callback_operator(Parser * parser, Token * token, int c,
|
||||||
static int _cpp_callback_quote(Parser * parser, Token * token, int c,
|
static int _cpp_callback_quote(Parser * parser, Token * token, int c,
|
||||||
void * data)
|
void * data)
|
||||||
{
|
{
|
||||||
CppParser * cpp = data;
|
CppParser * cp = data;
|
||||||
int escape = 0;
|
int escape = 0;
|
||||||
char * str = NULL;
|
char * str = NULL;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
@ -829,15 +826,8 @@ static int _cpp_callback_quote(Parser * parser, Token * token, int c,
|
||||||
parser_scan_filter(parser);
|
parser_scan_filter(parser);
|
||||||
} /* XXX else we should probably issue a warning */
|
} /* XXX else we should probably issue a warning */
|
||||||
str[len] = '\0';
|
str[len] = '\0';
|
||||||
token_set_string(token, str);
|
/* XXX keep code earlier, may fail */
|
||||||
if(cpp->queue_code != CPP_CODE_NULL)
|
_cpp_token_set(cp, token, token_get_code(token), str);
|
||||||
{
|
|
||||||
token_set_code(token, CPP_CODE_META_LINE); /* XXX */
|
|
||||||
if(cpp->queue_string == NULL)
|
|
||||||
cpp->queue_string = string_new(str);
|
|
||||||
else
|
|
||||||
string_append(&cpp->queue_string, str);
|
|
||||||
}
|
|
||||||
free(str);
|
free(str);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -871,7 +861,7 @@ static int _cpp_callback_directive(Parser * parser, Token * token, int c,
|
||||||
cpp->queue_string = string_new_append("Invalid directive: #",
|
cpp->queue_string = string_new_append("Invalid directive: #",
|
||||||
str, ":", NULL); /* XXX check for errors */
|
str, ":", NULL); /* XXX check for errors */
|
||||||
}
|
}
|
||||||
token_set_code(token, CPP_CODE_META_LINE); /* XXX */
|
token_set_code(token, CPP_CODE_META_DATA);
|
||||||
token_set_string(token, str);
|
token_set_string(token, str);
|
||||||
free(str);
|
free(str);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -882,7 +872,7 @@ static int _cpp_callback_directive(Parser * parser, Token * token, int c,
|
||||||
static int _cpp_callback_word(Parser * parser, Token * token, int c,
|
static int _cpp_callback_word(Parser * parser, Token * token, int c,
|
||||||
void * data)
|
void * data)
|
||||||
{
|
{
|
||||||
CppParser * cpp = data;
|
CppParser * cp = data;
|
||||||
char * str;
|
char * str;
|
||||||
|
|
||||||
if(!_cpp_isword(c))
|
if(!_cpp_isword(c))
|
||||||
|
@ -890,16 +880,7 @@ static int _cpp_callback_word(Parser * parser, Token * token, int c,
|
||||||
DEBUG_CALLBACK();
|
DEBUG_CALLBACK();
|
||||||
if((str = _cpp_parse_word(parser, c)) == NULL)
|
if((str = _cpp_parse_word(parser, c)) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
token_set_code(token, CPP_CODE_WORD);
|
_cpp_token_set(cp, token, CPP_CODE_WORD, str); /* XXX may fail */
|
||||||
token_set_string(token, str);
|
|
||||||
if(cpp->queue_code != CPP_CODE_NULL)
|
|
||||||
{
|
|
||||||
token_set_code(token, CPP_CODE_META_LINE); /* XXX */
|
|
||||||
if(cpp->queue_string == NULL)
|
|
||||||
cpp->queue_string = string_new(str);
|
|
||||||
else
|
|
||||||
string_append(&cpp->queue_string, str);
|
|
||||||
}
|
|
||||||
free(str);
|
free(str);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -909,7 +890,7 @@ static int _cpp_callback_word(Parser * parser, Token * token, int c,
|
||||||
static int _cpp_callback_unknown(Parser * parser, Token * token, int c,
|
static int _cpp_callback_unknown(Parser * parser, Token * token, int c,
|
||||||
void * data)
|
void * data)
|
||||||
{
|
{
|
||||||
CppParser * cpp = data;
|
CppParser * cp = data;
|
||||||
char buf[2] = "\0";
|
char buf[2] = "\0";
|
||||||
|
|
||||||
if(c == EOF)
|
if(c == EOF)
|
||||||
|
@ -917,14 +898,7 @@ static int _cpp_callback_unknown(Parser * parser, Token * token, int c,
|
||||||
DEBUG_CALLBACK();
|
DEBUG_CALLBACK();
|
||||||
buf[0] = c;
|
buf[0] = c;
|
||||||
parser_scan(parser);
|
parser_scan(parser);
|
||||||
token_set_code(token, CPP_CODE_UNKNOWN);
|
return _cpp_token_set(cp, token, CPP_CODE_UNKNOWN, buf);
|
||||||
token_set_string(token, buf);
|
|
||||||
if(cpp->queue_code != CPP_CODE_NULL)
|
|
||||||
{
|
|
||||||
token_set_code(token, CPP_CODE_META_LINE); /* XXX */
|
|
||||||
string_append(&cpp->queue_string, buf);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user