aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/pre-process.c
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-06-04 10:59:25 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-06-04 23:24:42 +0200
commit2b2e96ab37568f68085be64ba8c2b9e7d71de088 (patch)
treed355459b50dc8ce58c1014104cdbed56dab53cc3 /pre-process.c
parent1dd127244b7e1908215843d4ebcff465e70f6156 (diff)
downloadsparse-dev-2b2e96ab37568f68085be64ba8c2b9e7d71de088.tar.gz
dyn-macro: use a table to expand __DATE__, __FILE__, ...
GCC consider these macros as being defined, sparse doesn't. Also sparse uses a sequence of comparisons, one for each of __DATE__, __FILE__, ..., which is not ideal. Fix this by defining and using a table to associate to the corresponding symbol a method doing the expansion. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Diffstat (limited to 'pre-process.c')
-rw-r--r--pre-process.c78
1 files changed, 57 insertions, 21 deletions
diff --git a/pre-process.c b/pre-process.c
index 7d335ab0..1e472543 100644
--- a/pre-process.c
+++ b/pre-process.c
@@ -154,39 +154,60 @@ static void replace_with_defined(struct token *token)
token->number = string[defined];
}
+static void expand_line(struct token *token)
+{
+ replace_with_integer(token, token->pos.line);
+}
+
+static void expand_file(struct token *token)
+{
+ replace_with_string(token, stream_name(token->pos.stream));
+}
+
+static time_t t = 0;
+static void expand_date(struct token *token)
+{
+ static char buffer[12]; /* __DATE__: 3 + ' ' + 2 + ' ' + 4 + '\0' */
+
+ if (!t)
+ time(&t);
+ strftime(buffer, 12, "%b %e %Y", localtime(&t));
+ replace_with_string(token, buffer);
+}
+
+static void expand_time(struct token *token)
+{
+ static char buffer[9]; /* __TIME__: 2 + ':' + 2 + ':' + 2 + '\0' */
+
+ if (!t)
+ time(&t);
+ strftime(buffer, 9, "%T", localtime(&t));
+ replace_with_string(token, buffer);
+}
+
+static void expand_counter(struct token *token)
+{
+ replace_with_integer(token, counter_macro++);
+}
+
static int expand_one_symbol(struct token **list)
{
struct token *token = *list;
struct symbol *sym;
- static char buffer[12]; /* __DATE__: 3 + ' ' + 2 + ' ' + 4 + '\0' */
- static time_t t = 0;
if (token->pos.noexpand)
return 1;
sym = lookup_macro(token->ident);
- if (sym) {
+ if (!sym)
+ return 1;
+ if (sym->expander) {
+ sym->expander(token);
+ return 1;
+ } else {
sym->used_in = file_scope;
return expand(list, sym);
}
- if (token->ident == &__LINE___ident) {
- replace_with_integer(token, token->pos.line);
- } else if (token->ident == &__FILE___ident) {
- replace_with_string(token, stream_name(token->pos.stream));
- } else if (token->ident == &__DATE___ident) {
- if (!t)
- time(&t);
- strftime(buffer, 12, "%b %e %Y", localtime(&t));
- replace_with_string(token, buffer);
- } else if (token->ident == &__TIME___ident) {
- if (!t)
- time(&t);
- strftime(buffer, 9, "%T", localtime(&t));
- replace_with_string(token, buffer);
- } else if (token->ident == &__COUNTER___ident) {
- replace_with_integer(token, counter_macro++);
- }
- return 1;
}
static inline struct token *scan_next(struct token **where)
@@ -1891,6 +1912,16 @@ static void init_preprocessor(void)
{ "if", handle_if },
{ "elif", handle_elif },
};
+ static struct {
+ const char *name;
+ void (*expander)(struct token *);
+ } dynamic[] = {
+ { "__LINE__", expand_line },
+ { "__FILE__", expand_file },
+ { "__DATE__", expand_date },
+ { "__TIME__", expand_time },
+ { "__COUNTER__", expand_counter },
+ };
for (i = 0; i < ARRAY_SIZE(normal); i++) {
struct symbol *sym;
@@ -1904,6 +1935,11 @@ static void init_preprocessor(void)
sym->handler = special[i].handler;
sym->normal = 0;
}
+ for (i = 0; i < ARRAY_SIZE(dynamic); i++) {
+ struct symbol *sym;
+ sym = create_symbol(stream, dynamic[i].name, SYM_NODE, NS_MACRO);
+ sym->expander = dynamic[i].expander;
+ }
counter_macro = 0;
}