[gtk+/wip/otte/shader: 9/98] gsksltokenizer: Parse strings



commit 7ebeaf2198d4ead338b251454c9aa9b1b88f24a1
Author: Benjamin Otte <otte redhat com>
Date:   Mon Oct 2 00:24:32 2017 +0200

    gsksltokenizer: Parse strings
    
    And when we encounter any strings in the preprocessor, we promptly emit
    an error and skip them. But we do that after the preprocessor runs, so
    we can access strings inside the preprocessor.

 gsk/gskslpreprocessor.c     |    6 ++++++
 gsk/gsksltokenizer.c        |   42 ++++++++++++++++++++++++++++++++++++++++++
 gsk/gsksltokenizerprivate.h |    1 +
 3 files changed, 49 insertions(+), 0 deletions(-)
---
diff --git a/gsk/gskslpreprocessor.c b/gsk/gskslpreprocessor.c
index 11f39df..eb22aaa 100644
--- a/gsk/gskslpreprocessor.c
+++ b/gsk/gskslpreprocessor.c
@@ -224,6 +224,12 @@ gsk_sl_preprocessor_append_token (GskSlPreprocessor *preproc,
       gsk_sl_token_init_from_identifier (&pp->token, ident);
       g_free (ident);
     }
+  else if (gsk_sl_token_is (&pp->token, GSK_SL_TOKEN_STRING))
+    {
+      gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, &pp->location, "Unexpected string.");
+      gsk_sl_preprocessor_clear_token (pp);
+      return;
+    }
 
   g_array_append_val (preproc->tokens, *pp);
 }
diff --git a/gsk/gsksltokenizer.c b/gsk/gsksltokenizer.c
index e935686..ae3c5e5 100644
--- a/gsk/gsksltokenizer.c
+++ b/gsk/gsksltokenizer.c
@@ -85,6 +85,7 @@ gsk_sl_token_clear (GskSlToken *token)
   switch (token->type)
     {
     case GSK_SL_TOKEN_IDENTIFIER:
+    case GSK_SL_TOKEN_STRING:
       g_free (token->str);
       break;
 
@@ -323,6 +324,7 @@ gsk_sl_token_copy (GskSlToken       *dest,
   switch (src->type)
     {
     case GSK_SL_TOKEN_IDENTIFIER:
+    case GSK_SL_TOKEN_STRING:
       dest->str = g_strdup (src->str);
       break;
 
@@ -910,6 +912,12 @@ gsk_sl_token_print (const GskSlToken *token,
       g_string_append (string, token->str);
       break;
 
+    case GSK_SL_TOKEN_STRING:
+      g_string_append_c (string, '"');
+      g_string_append (string, token->str);
+      g_string_append_c (string, '"');
+      break;
+
     case GSK_SL_TOKEN_FLOATCONSTANT:
       g_ascii_dtostr (buf, G_ASCII_DTOSTR_BUF_SIZE, token->f);
       g_string_append (string, buf);
@@ -1734,6 +1742,36 @@ gsk_sl_token_reader_read_identifier (GskSlTokenReader  *reader,
   token->str = g_string_free (string, FALSE);
 }
 
+static void
+gsk_sl_token_reader_read_string (GskSlTokenReader  *reader,
+                                 GskSlToken        *token,
+                                 GError           **error)
+{
+  GString *string;
+  char c;
+
+  g_assert (gsk_sl_token_reader_get (reader, 0) == '"');
+  gsk_sl_token_reader_consume (reader, 1);
+
+  string = g_string_new ("");
+
+  for (c = gsk_sl_token_reader_get (reader, 0);
+       c != '"' && c != 0;
+       c = gsk_sl_token_reader_get (reader, 0))
+    {
+      g_string_append_c (string, c);
+      gsk_sl_token_reader_consume (reader, 1);
+    }
+
+  if (c == 0)
+    set_parse_error (error, "Unterminated string literal.");
+  else
+    gsk_sl_token_reader_consume (reader, 1);
+
+  gsk_sl_token_init (token, GSK_SL_TOKEN_STRING);
+  token->str = g_string_free (string, FALSE);
+}
+
 gboolean
 gsk_sl_string_is_valid_identifier (const char *ident)
 {
@@ -1840,6 +1878,10 @@ gsk_sl_tokenizer_read_token (GskSlTokenizer *tokenizer,
         }
       break;
 
+    case '"':
+      gsk_sl_token_reader_read_string (&reader, token, &error);
+      break;
+
     case '<':
       switch (gsk_sl_token_reader_get (&reader, 1))
         {
diff --git a/gsk/gsksltokenizerprivate.h b/gsk/gsksltokenizerprivate.h
index e968d31..381a851 100644
--- a/gsk/gsksltokenizerprivate.h
+++ b/gsk/gsksltokenizerprivate.h
@@ -29,6 +29,7 @@ typedef enum {
   GSK_SL_TOKEN_WHITESPACE,
   GSK_SL_TOKEN_COMMENT,
   GSK_SL_TOKEN_SINGLE_LINE_COMMENT,
+  GSK_SL_TOKEN_STRING,
   /* real tokens */
   GSK_SL_TOKEN_CONST,
   GSK_SL_TOKEN_BOOL,


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