[PATCH 2/4] dyn-macro: use a table to expand __DATE__, __FILE__, ...

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx>
---
 ident-list.h                      |  5 --
 pre-process.c                     | 78 ++++++++++++++++++++++---------
 symbol.h                          |  1 +
 validation/preprocessor/dynamic.c |  1 -
 4 files changed, 58 insertions(+), 27 deletions(-)

diff --git a/ident-list.h b/ident-list.h
index 2f1fecb48..5394f5877 100644
--- a/ident-list.h
+++ b/ident-list.h
@@ -61,14 +61,9 @@ IDENT(defined);
 IDENT(once);
 __IDENT(pragma_ident, "__pragma__", 0);
 __IDENT(__VA_ARGS___ident, "__VA_ARGS__", 0);
-__IDENT(__LINE___ident, "__LINE__", 0);
-__IDENT(__FILE___ident, "__FILE__", 0);
-__IDENT(__DATE___ident, "__DATE__", 0);
-__IDENT(__TIME___ident, "__TIME__", 0);
 __IDENT(__func___ident, "__func__", 0);
 __IDENT(__FUNCTION___ident, "__FUNCTION__", 0);
 __IDENT(__PRETTY_FUNCTION___ident, "__PRETTY_FUNCTION__", 0);
-__IDENT(__COUNTER___ident, "__COUNTER__", 0);
 
 /* Sparse commands */
 IDENT_RESERVED(__context__);
diff --git a/pre-process.c b/pre-process.c
index 7d335ab0c..1e4725439 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;
 }
diff --git a/symbol.h b/symbol.h
index 4edb44041..c1ae4d2b0 100644
--- a/symbol.h
+++ b/symbol.h
@@ -155,6 +155,7 @@ struct symbol {
 			struct token *expansion;
 			struct token *arglist;
 			struct scope *used_in;
+			void (*expander)(struct token *);
 		};
 		struct /* NS_PREPROCESSOR */ {
 			int (*handler)(struct stream *, struct token **, struct token *);
diff --git a/validation/preprocessor/dynamic.c b/validation/preprocessor/dynamic.c
index 3622be8d1..a829542f8 100644
--- a/validation/preprocessor/dynamic.c
+++ b/validation/preprocessor/dynamic.c
@@ -17,7 +17,6 @@ counter
 /*
  * check-name: dynamic-macros
  * check-command: sparse -E $file
- * check-known-to-fail
  *
  * check-output-start
 
-- 
2.17.1

--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux