summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-12-09 16:09:28 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-12-09 16:16:50 +0100
commit72f2e21897547949e328484e9a06e857879f25c3 (patch)
tree7764669a2046bac834c00a50ff944a5a7ebe12e2
parentb7f05bc01b1b61359e3f7e41b504e763e5a9880b (diff)
parent0e2f8a82757196ef5009f0f8ae5c5e1724b82248 (diff)
downloadsparse-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.c41
-rw-r--r--lib.h1
-rw-r--r--pre-process.c27
-rw-r--r--validation/preprocessor/dump-macros-only.c36
-rw-r--r--validation/preprocessor/dump-macros.c16
5 files changed, 105 insertions, 16 deletions
diff --git a/lib.c b/lib.c
index ada12ca7..b981bf64 100644
--- a/lib.c
+++ b/lib.c
@@ -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)) {
diff --git a/lib.h b/lib.h
index ef80826c..74315076 100644
--- a/lib.h
+++ b/lib.h
@@ -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\\[\\])
*/