From 8fbb692fd921ac328b9ace8978eeb7622c173549 Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Sun, 2 Mar 2008 01:33:45 +0000 Subject: [PATCH] Working on substitution directives --- include/cpp.h | 3 +++ src/cpp.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++---- src/main.c | 46 +++++++++++++++++++++++++++++++++--------- 3 files changed, 92 insertions(+), 13 deletions(-) diff --git a/include/cpp.h b/include/cpp.h index b61cde3..892e281 100644 --- a/include/cpp.h +++ b/include/cpp.h @@ -100,6 +100,9 @@ void cpp_delete(Cpp * cpp); char const * cpp_get_filename(Cpp * cpp); /* useful */ +int cpp_define_add(Cpp * cpp, char const * name, char const * value); +int cpp_define_remove(Cpp * cpp, char const * name); + int cpp_path_add(Cpp * cpp, char const * path); int cpp_scan(Cpp * cpp, Token ** token); diff --git a/src/cpp.c b/src/cpp.c index 6fa0f13..e7777f6 100644 --- a/src/cpp.c +++ b/src/cpp.c @@ -14,7 +14,10 @@ * NonCommercial-ShareAlike 3.0 along with cpp; if not, browse to * http://creativecommons.org/licenses/by-nc-sa/3.0/ */ /* FIXME - * - comments are not handled in directives */ + * - comments are not handled in directives + * - fix includes (system vs regular, inclusion order) + * - implement define and undef + * - implement ifdef and ifndef */ @@ -55,6 +58,9 @@ struct _Cpp Cpp * subparser; char ** paths; size_t paths_cnt; + /* substitutions */ + char ** defines; /* FIXME also store the value */ + size_t defines_cnt; }; /* FIXME use CPP_CODE_META_* in a structure with strings and pointers to @@ -398,6 +404,7 @@ static int _cpp_callback_comment(Parser * parser, Token * token, int c, /* these functions should return 0 (or -1 on errors) */ static int _directive_error(Cpp * cpp, Token * token, char const * str); static int _directive_include(Cpp * cpp, Token * token, char const * str); +static int _directive_undef(Cpp * cpp, Token * token, char const * str); static int _directive_warning(Cpp * cpp, Token * token, char const * str); static int _cpp_callback_directive(Parser * parser, Token * token, int c, @@ -470,8 +477,7 @@ static int _cpp_callback_directive(Parser * parser, Token * token, int c, token_set_code(token, CPP_CODE_META_PRAGMA); break; case CPP_DIRECTIVE_UNDEF: - /* FIXME implement */ - token_set_code(token, CPP_CODE_META_UNDEF); + _directive_undef(cpp, token, str); break; case CPP_DIRECTIVE_WARNING: _directive_warning(cpp, token, str); @@ -504,7 +510,6 @@ static char * _include_path(Cpp * cpp, Token * token, char const * str); static int _directive_include(Cpp * cpp, Token * token, char const * str) { char * path; - Cpp ** p; size_t i; if((path = _include_path(cpp, token, str)) == NULL) @@ -599,6 +604,13 @@ static char * _lookup_error(Token * token, char const * path, int system) return NULL; } +static int _directive_undef(Cpp * cpp, Token * token, char const * str) +{ + cpp_define_remove(cpp, str); /* FIXME may not be just a word */ + token_set_code(token, CPP_CODE_META_UNDEF); + return 0; +} + static int _directive_warning(Cpp * cpp, Token * token, char const * str) { int ret; @@ -767,6 +779,8 @@ Cpp * cpp_new(char const * filename, int filters) cpp->subparser = NULL; cpp->paths = NULL; cpp->paths_cnt = 0; + cpp->defines = NULL; + cpp->defines_cnt = 0; if((p = strdup(filename)) != NULL) { cpp_path_add(cpp, dirname(p)); /* FIXME inclusion order */ @@ -814,6 +828,40 @@ char const * cpp_get_filename(Cpp * cpp) /* useful */ +/* cpp_define_add */ +int cpp_define_add(Cpp * cpp, char const * name, char const * value) +{ + char ** p; + + if((p = realloc(cpp->defines, sizeof(*p) * (cpp->defines_cnt + 1))) + == NULL) + return error_set_code(1, "%s", strerror(errno)); + cpp->defines = p; + if((p[cpp->defines_cnt] = strdup(name)) == NULL) + return error_set_code(1, "%s", strerror(errno)); + cpp->defines_cnt++; + return 0; +} + + +/* cpp_define_remove */ +int cpp_define_remove(Cpp * cpp, char const * name) +{ + size_t i; + + for(i = 0; i < cpp->defines_cnt; i++) + if(strcmp(cpp->defines[i], name) == 0) + break; + if(i == cpp->defines_cnt) + return 1; + free(cpp->defines[i]); + cpp->defines_cnt--; + for(; i < cpp->defines_cnt; i++) + cpp->defines[i] = cpp->defines[i + 1]; + return 0; +} + + /* cpp_path_add */ int cpp_path_add(Cpp * cpp, char const * path) { diff --git a/src/main.c b/src/main.c index 6c39cee..e2de6d0 100644 --- a/src/main.c +++ b/src/main.c @@ -31,9 +31,11 @@ typedef struct _Prefs { int flags; + char const * outfile; const char ** paths; size_t paths_cnt; - char const * output; + const char ** defines; + size_t defines_cnt; } Prefs; #define PREFS_t 0x1 @@ -53,15 +55,15 @@ static int _cpp(Prefs * prefs, int filec, char * filev[]) FILE * fp; int i; - if(prefs->output == NULL) + if(prefs->outfile == NULL) fp = stdout; - else if((fp = fopen(prefs->output, "w")) == NULL) - return error_set_print("cpp", 1, "%s: %s", prefs->output, + else if((fp = fopen(prefs->outfile, "w")) == NULL) + return error_set_print("cpp", 1, "%s: %s", prefs->outfile, strerror(errno)); for(i = 0; i < filec; i++) ret |= _cpp_do(prefs, fp, filev[i]); if(fclose(fp) != 0) - return error_set_print("cpp", 1, "%s: %s", prefs->output, + return error_set_print("cpp", 1, "%s: %s", prefs->outfile, strerror(errno)); return ret; } @@ -71,6 +73,7 @@ static int _cpp_do(Prefs * prefs, FILE * fp, char const * filename) int ret; Cpp * cpp; size_t i; + size_t j; Token * token; int code; @@ -80,7 +83,10 @@ static int _cpp_do(Prefs * prefs, FILE * fp, char const * filename) for(i = 0; i < prefs->paths_cnt; i++) if(cpp_path_add(cpp, prefs->paths[i]) != 0) break; - if(i != prefs->paths_cnt) + for(j = 0; j < prefs->defines_cnt; j++) + if(cpp_define_add(cpp, prefs->defines[j], NULL) != 0) + break; + if(i != prefs->paths_cnt || j != prefs->defines_cnt) { cpp_delete(cpp); return 1; @@ -127,7 +133,8 @@ static int _cpp_error(void) /* FIXME -E prints metadata? */ static int _usage(void) { - fputs("Usage: " PACKAGE " [-I directory][-o outfile][-t] input...\n" + fputs("Usage: " PACKAGE " [-D name[=value]]...[-I directory][-o outfile][-t] input...\n" +" -D Add a substitution\n" " -I Add a directory to the search path\n" " -o Write output to a file\n" " -t Convert trigraphs\n", stderr); @@ -136,6 +143,7 @@ static int _usage(void) /* main */ +static int _main_add_define(Prefs * name, char * define); static int _main_add_path(Prefs * prefs, char const * path); int main(int argc, char * argv[]) @@ -145,15 +153,19 @@ int main(int argc, char * argv[]) int o; memset(&prefs, 0, sizeof(prefs)); - while((o = getopt(argc, argv, "I:o:t")) != -1) + while((o = getopt(argc, argv, "D:I:o:t")) != -1) switch(o) { + case 'D': + if(_main_add_define(&prefs, optarg) != 0) + return 2; + break; case 'I': if(_main_add_path(&prefs, optarg) != 0) return 2; break; case 'o': - prefs.output = optarg; + prefs.outfile = optarg; break; case 't': prefs.flags |= PREFS_t; @@ -168,6 +180,22 @@ int main(int argc, char * argv[]) return ret; } +static int _main_add_define(Prefs * prefs, char * define) +{ + const char ** p; + char * value; + + if(strlen(define) == 0) + return 1; + value = strtok(define, "="); + if((p = realloc(prefs->defines, sizeof(*p) * (prefs->defines_cnt + 1))) + == NULL) + return error_set_print(PACKAGE, 1, "%s", strerror(errno)); + prefs->defines = p; + prefs->defines[prefs->defines_cnt++] = define; + return 0; +} + static int _main_add_path(Prefs * prefs, char const * path) { const char ** p;