diff --git a/include/cpp.h b/include/cpp.h index bf50c3e..6db6887 100644 --- a/include/cpp.h +++ b/include/cpp.h @@ -28,6 +28,7 @@ typedef struct _Cpp Cpp; typedef enum _CppFilter { + CPP_FILTER_NONE = 0, CPP_FILTER_TRIGRAPH = 1, CPP_FILTER_WHITESPACE = 2 } CppFilter; @@ -99,6 +100,7 @@ typedef enum _CppCode CPP_CODE_OPERATOR_XOR, CPP_CODE_SQUOTE, CPP_CODE_WHITESPACE, + CPP_CODE_NEWLINE, CPP_CODE_WORD, /* FIXME numbers and keywords? */ CPP_CODE_UNKNOWN } CppCode; diff --git a/src/cpp.c b/src/cpp.c index 4d03df9..8998577 100644 --- a/src/cpp.c +++ b/src/cpp.c @@ -193,6 +193,10 @@ static int _cpp_callback_directive(Parser * parser, Token * token, int c, void * data); static int _cpp_callback_whitespace(Parser * parser, Token * token, int c, void * data); +static int _cpp_callback_newline(Parser * parser, Token * token, int c, + void * data); +static int _cpp_callback_otherspace(Parser * parser, Token * token, int c, + void * data); static int _cpp_callback_comment(Parser * parser, Token * token, int c, void * data); static int _cpp_callback_comma(Parser * parser, Token * token, int c, @@ -212,7 +216,7 @@ static int _cpp_callback_unknown(Parser * parser, Token * token, int c, /* cpp_isword */ static int _cpp_isword(int c) { - return isalnum(c) || c == '_'; + return isalnum(c) || c == '_' || c == '$'; } @@ -433,7 +437,7 @@ static int _cpp_callback_whitespace(Parser * parser, Token * token, int c, #endif do { - if(cpp->filters & CPP_FILTER_WHITESPACE && c != '\n') + if(c != '\n') continue; if((p = realloc(str, len + 1)) == NULL) { @@ -458,6 +462,61 @@ static int _cpp_callback_whitespace(Parser * parser, Token * token, int c, } +/* cpp_callback_newline */ +static int _cpp_callback_newline(Parser * parser, Token * token, int c, + void * data) +{ + if(c != '\n') + return 1; +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s()\n", __func__); +#endif + parser_scan_filter(parser); + token_set_code(token, CPP_CODE_NEWLINE); + token_set_string(token, "\n"); + return 0; +} + + +/* cpp_callback_otherspace */ +static int _cpp_callback_otherspace(Parser * parser, Token * token, int c, + void * data) +{ + Cpp * cpp = data; + char * str = NULL; + size_t len = 0; + char * p; + + if(!isspace(c) || c == '\n') + return 1; +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s()\n", __func__); +#endif + do + { + if((p = realloc(str, len + 1)) == NULL) + { + free(str); + return -1; + } + str = p; + str[len++] = c; + } + while(isspace((c = parser_scan_filter(parser))) && c != '\n'); + token_set_code(token, CPP_CODE_WHITESPACE); + if(str != NULL) + { + str[len] = '\0'; + token_set_string(token, str); + free(str); + cpp->directive_newline = 1; + } + else + token_set_string(token, " "); + return 0; +} + + /* cpp_callback_comment */ static int _cpp_callback_comment(Parser * parser, Token * token, int c, void * data) @@ -930,7 +989,13 @@ Cpp * cpp_new(char const * filename, int filters) parser_add_filter(cpp->parser, _cpp_filter_newlines, cpp); if(cpp->filters & CPP_FILTER_TRIGRAPH) parser_add_filter(cpp->parser, _cpp_filter_trigraphs, cpp); - parser_add_callback(cpp->parser, _cpp_callback_whitespace, cpp); + if(cpp->filters & CPP_FILTER_WHITESPACE) + parser_add_callback(cpp->parser, _cpp_callback_whitespace, cpp); + else + { + parser_add_callback(cpp->parser, _cpp_callback_newline, cpp); + parser_add_callback(cpp->parser, _cpp_callback_otherspace, cpp); + } parser_add_callback(cpp->parser, _cpp_callback_comment, NULL); parser_add_callback(cpp->parser, _cpp_callback_directive, cpp); parser_add_callback(cpp->parser, _cpp_callback_comma, NULL); diff --git a/src/main.c b/src/main.c index 7168f3c..5ff884c 100644 --- a/src/main.c +++ b/src/main.c @@ -75,6 +75,7 @@ static int _cpp(Prefs * prefs, int filec, char * filev[]) static int _cpp_do(Prefs * prefs, FILE * fp, char const * filename) { int ret; + int filter = CPP_FILTER_WHITESPACE; Cpp * cpp; size_t i; size_t j; @@ -82,8 +83,9 @@ static int _cpp_do(Prefs * prefs, FILE * fp, char const * filename) Token * token; int code; - if((cpp = cpp_new(filename, prefs->flags & PREFS_t - ? CPP_FILTER_TRIGRAPH : 0)) == NULL) + if(prefs->flags & PREFS_t) + filter |= CPP_FILTER_TRIGRAPH; + if((cpp = cpp_new(filename, filter)) == NULL) return _cpp_error(); for(i = 0; i < prefs->paths_cnt; i++) if(cpp_path_add(cpp, prefs->paths[i]) != 0)