diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2018-12-09 16:09:28 +0100 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2018-12-09 16:16:50 +0100 |
commit | 72f2e21897547949e328484e9a06e857879f25c3 (patch) | |
tree | 7764669a2046bac834c00a50ff944a5a7ebe12e2 | |
parent | b7f05bc01b1b61359e3f7e41b504e763e5a9880b (diff) | |
parent | 0e2f8a82757196ef5009f0f8ae5c5e1724b82248 (diff) | |
download | sparse-72f2e21897547949e328484e9a06e857879f25c3.tar.gz |
Merge branch 'dump-macros'
* fixes for -dD
* add support for -dM
Luc Van Oostenryck (2):
dump-macro: break the loop at TOKEN_UNTAINT
dump-macro: simplify processing of whitespace
Ramsay Jones (5):
pre-process: suppress trailing space when dumping macros
pre-process: print macros containing # and ## correctly
pre-process: don't put spaces in macro parameter list
pre-process: print variable argument macros correctly
pre-process: add the -dM option to dump macro definitions
-rw-r--r-- | lib.c | 41 | ||||
-rw-r--r-- | lib.h | 1 | ||||
-rw-r--r-- | pre-process.c | 27 | ||||
-rw-r--r-- | validation/preprocessor/dump-macros-only.c | 36 | ||||
-rw-r--r-- | validation/preprocessor/dump-macros.c | 16 |
5 files changed, 105 insertions, 16 deletions
@@ -294,6 +294,7 @@ int Wunknown_attribute = 0; int Wvla = 1; int dump_macro_defs = 0; +int dump_macros_only = 0; int dbg_compound = 0; int dbg_dead = 0; @@ -806,16 +807,34 @@ static char **handle_switch_v(char *arg, char **next) return next; } -static struct flag dumps[] = { - { "D", &dump_macro_defs}, -}; - static char **handle_switch_d(char *arg, char **next) { - char ** ret = handle_onoff_switch(arg, next, dumps, ARRAY_SIZE(dumps)); - if (ret) - return ret; + char *arg_char = arg + 1; + /* + * -d<CHARS>, where <CHARS> is a sequence of characters, not preceded + * by a space. If you specify characters whose behaviour conflicts, + * the result is undefined. + */ + while (*arg_char) { + switch (*arg_char) { + case 'M': /* dump just the macro definitions */ + dump_macros_only = 1; + dump_macro_defs = 0; + break; + case 'D': /* like 'M', but also output pre-processed text */ + dump_macro_defs = 1; + dump_macros_only = 0; + break; + case 'N': /* like 'D', but only output macro names not bodies */ + break; + case 'I': /* like 'D', but also output #include directives */ + break; + case 'U': /* like 'D', but only output expanded macros */ + break; + } + arg_char++; + } return next; } @@ -1331,8 +1350,12 @@ static struct symbol_list *sparse_tokenstream(struct token *token) // Preprocess the stream token = preprocess(token); - if (dump_macro_defs && !builtin) - dump_macro_definitions(); + if (dump_macro_defs || dump_macros_only) { + if (!builtin) + dump_macro_definitions(); + if (dump_macros_only) + return NULL; + } if (preprocess_only) { while (!eof_token(token)) { @@ -182,6 +182,7 @@ extern int Wunknown_attribute; extern int Wvla; extern int dump_macro_defs; +extern int dump_macros_only; extern int dbg_compound; extern int dbg_dead; diff --git a/pre-process.c b/pre-process.c index 1ed7a47c..df208bcf 100644 --- a/pre-process.c +++ b/pre-process.c @@ -2173,6 +2173,12 @@ struct token * preprocess(struct token *token) return token; } +static int is_VA_ARGS_token(struct token *token) +{ + return (token_type(token) == TOKEN_IDENT) && + (token->ident == &__VA_ARGS___ident); +} + static void dump_macro(struct symbol *sym) { int nargs = sym->arglist ? sym->arglist->count.normal : 0; @@ -2188,27 +2194,34 @@ static void dump_macro(struct symbol *sym) for (; !eof_token(token); token = token->next) { if (token_type(token) == TOKEN_ARG_COUNT) continue; - printf("%s%s", sep, show_token(token)); + if (is_VA_ARGS_token(token)) + printf("%s...", sep); + else + printf("%s%s", sep, show_token(token)); args[narg++] = token; - sep = ", "; + sep = ","; } putchar(')'); } - putchar(' '); token = sym->expansion; - while (!eof_token(token)) { + while (token_type(token) != TOKEN_UNTAINT) { struct token *next = token->next; + if (token->pos.whitespace) + putchar(' '); switch (token_type(token)) { - case TOKEN_UNTAINT: + case TOKEN_CONCAT: + printf("##"); break; + case TOKEN_STR_ARGUMENT: + printf("#"); + /* fall-through */ + case TOKEN_QUOTED_ARGUMENT: case TOKEN_MACRO_ARGUMENT: token = args[token->argnum]; /* fall-through */ default: printf("%s", show_token(token)); - if (next->pos.whitespace) - putchar(' '); } token = next; } diff --git a/validation/preprocessor/dump-macros-only.c b/validation/preprocessor/dump-macros-only.c new file mode 100644 index 00000000..cee6f870 --- /dev/null +++ b/validation/preprocessor/dump-macros-only.c @@ -0,0 +1,36 @@ + +#define ABC abc +#undef ABC + +#define DEF def +#undef DEF +#define DEF xyz + +#define NYDEF ydef + +#define STRING(x) #x +#define CONCAT(x,y) x ## y + +#define unlocks(...) annotate(unlock_func(__VA_ARGS__)) +#define apply(x,...) x(__VA_ARGS__) + +int main(int argc, char *argv[]) +{ + return 0; +} +/* + * check-name: dump-macros only -dM + * check-command: sparse -E -dM -DIJK=ijk -UNDEF -UNYDEF $file + * + * check-output-ignore +check-output-pattern(1): #define __CHECKER__ 1 +check-output-contains: #define IJK ijk +check-output-contains: #define DEF xyz +check-output-contains: #define NYDEF ydef +check-output-contains: #define STRING(x) #x +check-output-contains: #define CONCAT(x,y) x ## y +check-output-contains: #define unlocks(...) annotate(unlock_func(__VA_ARGS__)) +check-output-contains: #define apply(x,...) x(__VA_ARGS__) +check-output-excludes: int main(int argc, char \\*argv\\[\\]) +check-output-excludes: ^\\[^#] + */ diff --git a/validation/preprocessor/dump-macros.c b/validation/preprocessor/dump-macros.c index 4dbb9620..dc2d7d19 100644 --- a/validation/preprocessor/dump-macros.c +++ b/validation/preprocessor/dump-macros.c @@ -6,6 +6,17 @@ #define DEF xyz #define NYDEF ydef + +#define STRING(x) #x +#define CONCAT(x,y) x ## y + +#define unlocks(...) annotate(unlock_func(__VA_ARGS__)) +#define apply(x,...) x(__VA_ARGS__) + +int main(int argc, char *argv[]) +{ + return 0; +} /* * check-name: dump-macros * check-command: sparse -E -dD -DIJK=ijk -UNDEF -UNYDEF $file @@ -15,4 +26,9 @@ check-output-pattern(1): #define __CHECKER__ 1 check-output-contains: #define IJK ijk check-output-contains: #define DEF xyz check-output-contains: #define NYDEF ydef +check-output-contains: #define STRING(x) #x +check-output-contains: #define CONCAT(x,y) x ## y +check-output-contains: #define unlocks(...) annotate(unlock_func(__VA_ARGS__)) +check-output-contains: #define apply(x,...) x(__VA_ARGS__) +check-output-contains: int main(int argc, char \\*argv\\[\\]) */ |