glcpp: Add support for pasting of INTEGER tokens.
authorCarl Worth <cworth@cworth.org>
Thu, 29 Nov 2012 01:34:36 +0000 (17:34 -0800)
committerCarl Worth <cworth@cworth.org>
Thu, 29 Nov 2012 21:03:02 +0000 (13:03 -0800)
By generalizing the current code designed to paste string tokens of various
types.

Reviewed-by: Matt Turner <mattst88@gmail.com>
src/glsl/glcpp/glcpp-parse.y

index 8f17d0d8ab3196c471238dae79ad026c001e9520..e7daf7fea5c3638e00bf9aabbe593520012c089e 100644 (file)
@@ -1054,29 +1054,62 @@ _token_paste (glcpp_parser_t *parser, token_t *token, token_t *other)
                return combined;
        }
 
-       /* Two string-valued tokens can usually just be mashed
-        * together.
+       /* Two string-valued (or integer) tokens can usually just be
+        * mashed together. (We also handle a string followed by an
+        * integer here as well.)
         *
         * There are some exceptions here. Notably, if the first token
-        * is a string representing an integer, then the second token
-        * must also be a an integer and must begin with a digit.
+        * is an integer (or a string representing an integer), then
+        * the second token must also be an integer or must be a
+        * string representing an integer that begins with a digit.
         */
-       if ((token->type == IDENTIFIER || token->type == OTHER || token->type == INTEGER_STRING) &&
-           (other->type == IDENTIFIER || other->type == OTHER || other->type == INTEGER_STRING))
+       if ((token->type == IDENTIFIER || token->type == OTHER || token->type == INTEGER_STRING || token->type == INTEGER) &&
+           (other->type == IDENTIFIER || other->type == OTHER || other->type == INTEGER_STRING || other->type == INTEGER))
        {
                char *str;
+               int combined_type;
 
-               if (token->type == INTEGER_STRING) {
-                       if (other->type != INTEGER_STRING)
-                               goto FAIL;
-                       if (other->value.str[0] < '0' ||
-                           other->value.str[0] > '9')
+               /* Check that pasting onto an integer doesn't create a
+                * non-integer, (that is, only digits can be
+                * pasted. */
+               if (token->type == INTEGER_STRING || token->type == INTEGER)
+               {
+                       switch (other->type) {
+                       case INTEGER_STRING:
+                               if (other->value.str[0] < '0' ||
+                                   other->value.str[0] > '9')
+                                       goto FAIL;
+                               break;
+                       case INTEGER:
+                               if (other->value.ival < 0)
+                                       goto FAIL;
+                               break;
+                       default:
                                goto FAIL;
+                       }
                }
 
-               str = ralloc_asprintf (token, "%s%s", token->value.str,
-                                      other->value.str);
-               combined = _token_create_str (token, token->type, str);
+               if (token->type == INTEGER)
+                       str = ralloc_asprintf (token, "%" PRIiMAX,
+                                              token->value.ival);
+               else
+                       str = ralloc_strdup (token, token->value.str);
+                                              
+
+               if (other->type == INTEGER)
+                       ralloc_asprintf_append (&str, "%" PRIiMAX,
+                                               other->value.ival);
+               else
+                       ralloc_strcat (&str, other->value.str);
+
+               /* New token is same type as original token, unless we
+                * started with an integer, in which case we will be
+                * creating an integer-string. */
+               combined_type = token->type;
+               if (combined_type == INTEGER)
+                       combined_type = INTEGER_STRING;
+
+               combined = _token_create_str (token, combined_type, str);
                combined->location = token->location;
                return combined;
        }