Mesa (master): glcpp: Add support for "redefined macro" error.

Carl Worth cworth at kemper.freedesktop.org
Wed Aug 18 06:42:14 UTC 2010


Module: Mesa
Branch: master
Commit: 3882cf21696d2576bd3d855dbc97c9354f72a15f
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=3882cf21696d2576bd3d855dbc97c9354f72a15f

Author: Carl Worth <cworth at cworth.org>
Date:   Tue Aug 17 23:20:58 2010 -0700

glcpp: Add support for "redefined macro" error.

Carefully avoiding printing any error when the new definition matches
the existing definition.

This fixes the recently-added 088-redefine-macro-legitimate.c and
089-redefine-macro-error.c tests as well as glsparsertest/preprocess1
in piglit.

---

 src/glsl/glcpp/glcpp-parse.y |  125 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 123 insertions(+), 2 deletions(-)

diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y
index c91da15..3275496 100644
--- a/src/glsl/glcpp/glcpp-parse.y
+++ b/src/glsl/glcpp/glcpp-parse.y
@@ -63,6 +63,9 @@ _string_list_contains (string_list_t *list, const char *member, int *index);
 static int
 _string_list_length (string_list_t *list);
 
+static int
+_string_list_equal (string_list_t *a, string_list_t *b);
+
 static argument_list_t *
 _argument_list_create (void *ctx);
 
@@ -95,6 +98,9 @@ _token_list_append (token_list_t *list, token_t *token);
 static void
 _token_list_append_list (token_list_t *list, token_list_t *tail);
 
+static int
+_token_list_equal_ignoring_space (token_list_t *a, token_list_t *b);
+
 static active_list_t *
 _active_list_push (active_list_t *list,
 		   const char *identifier,
@@ -604,6 +610,31 @@ _string_list_length (string_list_t *list)
 	return length;
 }
 
+int
+_string_list_equal (string_list_t *a, string_list_t *b)
+{
+	string_node_t *node_a, *node_b;
+
+	if (a == NULL && b == NULL)
+		return 1;
+
+	if (a == NULL || b == NULL)
+		return 0;
+
+	for (node_a = a->head, node_b = b->head;
+	     node_a && node_b;
+	     node_a = node_a->next, node_b = node_b->next)
+	{
+		if (strcmp (node_a->str, node_b->str))
+			return 0;
+	}
+
+	/* Catch the case of lists being different lengths, (which
+	 * would cause the loop above to terminate after the shorter
+	 * list). */
+	return node_a == node_b;
+}
+
 argument_list_t *
 _argument_list_create (void *ctx)
 {
@@ -781,6 +812,61 @@ _token_list_trim_trailing_space (token_list_t *list)
 	}
 }
 
+int
+_token_list_equal_ignoring_space (token_list_t *a, token_list_t *b)
+{
+	token_node_t *node_a, *node_b;
+
+	node_a = a->head;
+	node_b = b->head;
+
+	while (1)
+	{
+		if (node_a == NULL && node_b == NULL)
+			break;
+
+		if (node_a == NULL || node_b == NULL)
+			return 0;
+
+		if (node_a->token->type == SPACE) {
+			node_a = node_a->next;
+			continue;
+		}
+
+		if (node_b->token->type == SPACE) {
+			node_b = node_b->next;
+			continue;
+		}
+
+		if (node_a->token->type != node_b->token->type)
+			return 0;
+
+		switch (node_a->token->type) {
+		case INTEGER:
+			if (node_a->token->value.ival != 
+			    node_b->token->value.ival)
+			{
+				return 0;
+			}
+			break;
+		case IDENTIFIER:
+		case INTEGER_STRING:
+		case OTHER:
+			if (strcmp (node_a->token->value.str,
+				    node_b->token->value.str))
+			{
+				return 0;
+			}
+			break;
+		}
+
+		node_a = node_a->next;
+		node_b = node_b->next;
+	}
+
+	return 1;
+}
+
 static void
 _token_print (char **out, token_t *token)
 {
@@ -1522,13 +1608,28 @@ _check_for_reserved_macro_name (glcpp_parser_t *parser, YYLTYPE *loc,
 	}
 }
 
+static int
+_macro_equal (macro_t *a, macro_t *b)
+{
+	if (a->is_function != b->is_function)
+		return 0;
+
+	if (a->is_function) {
+		if (! _string_list_equal (a->parameters, b->parameters))
+			return 0;
+	}
+
+	return _token_list_equal_ignoring_space (a->replacements,
+						 b->replacements);
+}
+
 void
 _define_object_macro (glcpp_parser_t *parser,
 		      YYLTYPE *loc,
 		      const char *identifier,
 		      token_list_t *replacements)
 {
-	macro_t *macro;
+	macro_t *macro, *previous;
 
 	if (loc != NULL)
 		_check_for_reserved_macro_name(parser, loc, identifier);
@@ -1540,6 +1641,16 @@ _define_object_macro (glcpp_parser_t *parser,
 	macro->identifier = talloc_strdup (macro, identifier);
 	macro->replacements = talloc_steal (macro, replacements);
 
+	previous = hash_table_find (parser->defines, identifier);
+	if (previous) {
+		if (_macro_equal (macro, previous)) {
+			talloc_free (macro);
+			return;
+		}
+		glcpp_error (loc, parser, "Redefinition of macro %s\n",
+			     identifier);
+	}
+
 	hash_table_insert (parser->defines, macro, identifier);
 }
 
@@ -1550,7 +1661,7 @@ _define_function_macro (glcpp_parser_t *parser,
 			string_list_t *parameters,
 			token_list_t *replacements)
 {
-	macro_t *macro;
+	macro_t *macro, *previous;
 
 	_check_for_reserved_macro_name(parser, loc, identifier);
 
@@ -1561,6 +1672,16 @@ _define_function_macro (glcpp_parser_t *parser,
 	macro->identifier = talloc_strdup (macro, identifier);
 	macro->replacements = talloc_steal (macro, replacements);
 
+	previous = hash_table_find (parser->defines, identifier);
+	if (previous) {
+		if (_macro_equal (macro, previous)) {
+			talloc_free (macro);
+			return;
+		}
+		glcpp_error (loc, parser, "Redefinition of macro %s\n",
+			     identifier);
+	}
+
 	hash_table_insert (parser->defines, macro, identifier);
 }
 




More information about the mesa-commit mailing list