glsl: Introduce sl_pp_context and maintain a reuseable pool of strings.
authorMichal Krol <michal@vmware.com>
Wed, 17 Jun 2009 11:49:06 +0000 (13:49 +0200)
committerMichal Krol <michal@vmware.com>
Mon, 7 Sep 2009 08:11:43 +0000 (10:11 +0200)
12 files changed:
src/glsl/apps/process.c
src/glsl/apps/tokenise.c
src/glsl/apps/version.c
src/glsl/pp/SConscript
src/glsl/pp/sl_pp_context.c [new file with mode: 0644]
src/glsl/pp/sl_pp_context.h [new file with mode: 0644]
src/glsl/pp/sl_pp_process.c
src/glsl/pp/sl_pp_process.h
src/glsl/pp/sl_pp_token.c
src/glsl/pp/sl_pp_token.h
src/glsl/pp/sl_pp_version.c
src/glsl/pp/sl_pp_version.h

index 6e2828aa4118b39166f2e4f23122802aae548130..abcf1a92b83b160f1a89db93f405ff1bef3cad75 100644 (file)
@@ -28,6 +28,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
+#include "../pp/sl_pp_context.h"
 #include "../pp/sl_pp_purify.h"
 #include "../pp/sl_pp_version.h"
 #include "../pp/sl_pp_process.h"
@@ -42,6 +43,7 @@ main(int argc,
    char *inbuf;
    struct sl_pp_purify_options options;
    char *outbuf;
+   struct sl_pp_context context;
    struct sl_pp_token_info *tokens;
    unsigned int version;
    unsigned int tokens_eaten;
@@ -86,19 +88,24 @@ main(int argc,
 
    free(inbuf);
 
-   if (sl_pp_tokenise(outbuf, &tokens)) {
+   sl_pp_context_init(&context);
+
+   if (sl_pp_tokenise(&context, outbuf, &tokens)) {
+      sl_pp_context_destroy(&context);
       free(outbuf);
       return 1;
    }
 
    free(outbuf);
 
-   if (sl_pp_version(tokens, &version, &tokens_eaten)) {
+   if (sl_pp_version(&context, tokens, &version, &tokens_eaten)) {
+      sl_pp_context_destroy(&context);
       free(tokens);
       return -1;
    }
 
-   if (sl_pp_process(&tokens[tokens_eaten], &outtokens)) {
+   if (sl_pp_process(&context, &tokens[tokens_eaten], &outtokens)) {
+      sl_pp_context_destroy(&context);
       free(tokens);
       return -1;
    }
@@ -107,6 +114,7 @@ main(int argc,
 
    out = fopen(argv[2], "wb");
    if (!out) {
+      sl_pp_context_destroy(&context);
       free(outtokens);
       return 1;
    }
@@ -298,13 +306,11 @@ main(int argc,
          break;
 
       case SL_PP_IDENTIFIER:
-         fprintf(out, "%s ", outtokens[i].data.identifier);
-         free(outtokens[i].data.identifier);
+         fprintf(out, "%s ", sl_pp_context_cstr(&context, outtokens[i].data.identifier));
          break;
 
       case SL_PP_NUMBER:
-         fprintf(out, "(%s) ", outtokens[i].data.number);
-         free(outtokens[i].data.number);
+         fprintf(out, "%s ", sl_pp_context_cstr(&context, outtokens[i].data.number));
          break;
 
       case SL_PP_OTHER:
@@ -316,6 +322,7 @@ main(int argc,
       }
    }
 
+   sl_pp_context_destroy(&context);
    free(outtokens);
    fclose(out);
 
index 2631b82998685b6d684949ae265799fcfe56a04b..b5092ba35f6bf7d1240e2dccd16b222f3355afbf 100644 (file)
@@ -28,6 +28,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
+#include "../pp/sl_pp_context.h"
 #include "../pp/sl_pp_purify.h"
 #include "../pp/sl_pp_token.h"
 
@@ -41,6 +42,7 @@ main(int argc,
    char *inbuf;
    struct sl_pp_purify_options options;
    char *outbuf;
+   struct sl_pp_context context;
    struct sl_pp_token_info *tokens;
    FILE *out;
    unsigned int i;
@@ -82,7 +84,10 @@ main(int argc,
 
    free(inbuf);
 
-   if (sl_pp_tokenise(outbuf, &tokens)) {
+   sl_pp_context_init(&context);
+
+   if (sl_pp_tokenise(&context, outbuf, &tokens)) {
+      sl_pp_context_destroy(&context);
       free(outbuf);
       return 1;
    }
@@ -91,6 +96,7 @@ main(int argc,
 
    out = fopen(argv[2], "wb");
    if (!out) {
+      sl_pp_context_destroy(&context);
       free(tokens);
       return 1;
    }
@@ -289,13 +295,11 @@ main(int argc,
          break;
 
       case SL_PP_IDENTIFIER:
-         fprintf(out, "%s ", tokens[i].data.identifier);
-         free(tokens[i].data.identifier);
+         fprintf(out, "%s ", sl_pp_context_cstr(&context, tokens[i].data.identifier));
          break;
 
       case SL_PP_NUMBER:
-         fprintf(out, "(%s) ", tokens[i].data.number);
-         free(tokens[i].data.number);
+         fprintf(out, "(%s) ", sl_pp_context_cstr(&context, tokens[i].data.number));
          break;
 
       case SL_PP_OTHER:
@@ -311,6 +315,7 @@ main(int argc,
       }
    }
 
+   sl_pp_context_destroy(&context);
    free(tokens);
    fclose(out);
 
index b49395ba97fa64ff15c74a5d498890e157c2ab4b..c56ae9dde9a92a92cb7c80db9df542f5e9ca9b3e 100644 (file)
@@ -41,6 +41,7 @@ main(int argc,
    char *inbuf;
    struct sl_pp_purify_options options;
    char *outbuf;
+   struct sl_pp_context context;
    struct sl_pp_token_info *tokens;
    unsigned int version;
    unsigned int tokens_eaten;
@@ -83,18 +84,23 @@ main(int argc,
 
    free(inbuf);
 
-   if (sl_pp_tokenise(outbuf, &tokens)) {
+   sl_pp_context_init(&context);
+
+   if (sl_pp_tokenise(&context, outbuf, &tokens)) {
+      sl_pp_context_destroy(&context);
       free(outbuf);
       return 1;
    }
 
    free(outbuf);
 
-   if (sl_pp_version(tokens, &version, &tokens_eaten)) {
+   if (sl_pp_version(&context, tokens, &version, &tokens_eaten)) {
+      sl_pp_context_destroy(&context);
       free(tokens);
       return -1;
    }
 
+   sl_pp_context_destroy(&context);
    free(tokens);
 
    out = fopen(argv[2], "wb");
index 0be21147946ceafabbd39d5a64cb7b2edb487cff..3d4a1cb967ca2c8a39fd91e02343a363f93fde65 100644 (file)
@@ -8,6 +8,7 @@ env = env.Clone()
 glsl = env.StaticLibrary(
     target = 'glsl',
     source = [
+        'sl_pp_context.c',
         'sl_pp_process.c',
         'sl_pp_purify.c',
         'sl_pp_token.c',
diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c
new file mode 100644 (file)
index 0000000..71712de
--- /dev/null
@@ -0,0 +1,77 @@
+/**************************************************************************
+ * 
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#include <stdlib.h>
+#include "sl_pp_context.h"
+
+
+void
+sl_pp_context_init(struct sl_pp_context *context)
+{
+   memset(context, 0, sizeof(struct sl_pp_context));
+}
+
+void
+sl_pp_context_destroy(struct sl_pp_context *context)
+{
+   free(context->cstr_pool);
+}
+
+int
+sl_pp_context_add_str(struct sl_pp_context *context,
+                      const char *str)
+{
+   unsigned int size;
+   unsigned int offset;
+
+   size = strlen(str) + 1;
+
+   if (context->cstr_pool_len + size > context->cstr_pool_max) {
+      context->cstr_pool_max = (context->cstr_pool_len + size + 0xffff) & ~0xffff;
+      context->cstr_pool = realloc(context->cstr_pool, context->cstr_pool_max);
+   }
+
+   if (!context->cstr_pool) {
+      return -1;
+   }
+
+   offset = context->cstr_pool_len;
+   memcpy(&context->cstr_pool[offset], str, size);
+   context->cstr_pool_len += size;
+
+   return offset;
+}
+
+const char *
+sl_pp_context_cstr(const struct sl_pp_context *context,
+                   int offset)
+{
+   if (offset == -1) {
+      return NULL;
+   }
+   return &context->cstr_pool[offset];
+}
diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h
new file mode 100644 (file)
index 0000000..3a1e215
--- /dev/null
@@ -0,0 +1,52 @@
+/**************************************************************************
+ * 
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#ifndef SL_PP_CONTEXT_H
+#define SL_PP_CONTEXT_H
+
+
+struct sl_pp_context {
+   char *cstr_pool;
+   unsigned int cstr_pool_max;
+   unsigned int cstr_pool_len;
+};
+
+void
+sl_pp_context_init(struct sl_pp_context *context);
+
+void
+sl_pp_context_destroy(struct sl_pp_context *context);
+
+int
+sl_pp_context_add_str(struct sl_pp_context *context,
+                      const char *str);
+
+const char *
+sl_pp_context_cstr(const struct sl_pp_context *context,
+                   int offset);
+
+#endif /* SL_PP_VERSION_H */
index 56b8fab52a0b20c94d4894209e153844d8fbd68f..a97c750de461cc80705bbba32abd4bce96639f04 100644 (file)
@@ -26,7 +26,6 @@
  **************************************************************************/
 
 #include <stdlib.h>
-#include <string.h>
 #include "sl_pp_process.h"
 
 
@@ -38,7 +37,8 @@ enum process_state {
 };
 
 int
-sl_pp_process(const struct sl_pp_token_info *input,
+sl_pp_process(struct sl_pp_context *context,
+              const struct sl_pp_token_info *input,
               struct sl_pp_token_info **output)
 {
    unsigned int i = 0;
@@ -132,18 +132,6 @@ sl_pp_process(const struct sl_pp_token_info *input,
             out_max = new_max;
          }
 
-         if (info.token == SL_PP_IDENTIFIER) {
-            info.data.identifier = strdup(info.data.identifier);
-            if (!info.data.identifier) {
-               return -1;
-            }
-         } else if (info.token == SL_PP_NUMBER) {
-            info.data.number = strdup(info.data.number);
-            if (!info.data.number) {
-               return -1;
-            }
-         }
-
          out[out_len++] = info;
 
          if (info.token == SL_PP_EOF) {
index 6e930ca567add17d6a7a112c8701999a81d05899..b71ee4466a1122ab05c8c6be5d85e3b0390c7e2c 100644 (file)
@@ -32,7 +32,8 @@
 
 
 int
-sl_pp_process(const struct sl_pp_token_info *input,
+sl_pp_process(struct sl_pp_context *context,
+              const struct sl_pp_token_info *input,
               struct sl_pp_token_info **output);
 
 #endif /* SL_PP_PROCESS_H */
index 4001fe54c8b72d1558d8cd0aeaa1782faae447b6..e200b961aaf654eaa1b98c83b2b1cb314c65079d 100644 (file)
@@ -30,7 +30,8 @@
 
 
 static int
-_tokenise_identifier(const char **pinput,
+_tokenise_identifier(struct sl_pp_context *context,
+                     const char **pinput,
                      struct sl_pp_token_info *info)
 {
    const char *input = *pinput;
@@ -38,7 +39,7 @@ _tokenise_identifier(const char **pinput,
    unsigned int i = 0;
 
    info->token = SL_PP_IDENTIFIER;
-   info->data.identifier = NULL;
+   info->data.identifier = -1;
 
    identifier[i++] = *input++;
    while ((*input >= 'a' && *input <= 'z') ||
@@ -52,11 +53,10 @@ _tokenise_identifier(const char **pinput,
    }
    identifier[i++] = '\0';
 
-   info->data.identifier = malloc(i);
-   if (!info->data.identifier) {
+   info->data.identifier = sl_pp_context_add_str(context, identifier);
+   if (info->data.identifier == -1) {
       return -1;
    }
-   memcpy(info->data.identifier, identifier, i);
 
    *pinput = input;
    return 0;
@@ -64,7 +64,8 @@ _tokenise_identifier(const char **pinput,
 
 
 static int
-_tokenise_number(const char **pinput,
+_tokenise_number(struct sl_pp_context *context,
+                 const char **pinput,
                  struct sl_pp_token_info *info)
 {
    const char *input = *pinput;
@@ -72,7 +73,7 @@ _tokenise_number(const char **pinput,
    unsigned int i = 0;
 
    info->token = SL_PP_NUMBER;
-   info->data.number = NULL;
+   info->data.number = -1;
 
    number[i++] = *input++;
    while ((*input >= '0' && *input <= '9') ||
@@ -90,11 +91,10 @@ _tokenise_number(const char **pinput,
    }
    number[i++] = '\0';
 
-   info->data.number = malloc(i);
-   if (!info->data.number) {
+   info->data.number = sl_pp_context_add_str(context, number);
+   if (info->data.number == -1) {
       return -1;
    }
-   memcpy(info->data.number, number, i);
 
    *pinput = input;
    return 0;
@@ -102,7 +102,8 @@ _tokenise_number(const char **pinput,
 
 
 int
-sl_pp_tokenise(const char *input,
+sl_pp_tokenise(struct sl_pp_context *context,
+               const char *input,
                struct sl_pp_token_info **output)
 {
    struct sl_pp_token_info *out = NULL;
@@ -171,7 +172,7 @@ sl_pp_tokenise(const char *input,
 
       case '.':
          if (input[1] >= '0' && input[1] <= '9') {
-            if (_tokenise_number(&input, &info)) {
+            if (_tokenise_number(context, &input, &info)) {
                free(out);
                return -1;
             }
@@ -355,12 +356,12 @@ sl_pp_tokenise(const char *input,
          if ((*input >= 'a' && *input <= 'z') ||
              (*input >= 'A' && *input <= 'Z') ||
              (*input == '_')) {
-            if (_tokenise_identifier(&input, &info)) {
+            if (_tokenise_identifier(context, &input, &info)) {
                free(out);
                return -1;
             }
          } else if (*input >= '0' && *input <= '9') {
-            if (_tokenise_number(&input, &info)) {
+            if (_tokenise_number(context, &input, &info)) {
                free(out);
                return -1;
             }
index 5e7fae7d29c43b306b5abefe8db31249f2a52611..c801804ae6eef88f4247cee10623659043a67382 100644 (file)
@@ -90,8 +90,8 @@ enum sl_pp_token {
 };
 
 union sl_pp_token_data {
-   char *identifier;
-   char *number;
+   int identifier;
+   int number;
    char other;
 };
 
@@ -101,7 +101,8 @@ struct sl_pp_token_info {
 };
 
 int
-sl_pp_tokenise(const char *input,
+sl_pp_tokenise(struct sl_pp_context *context,
+               const char *input,
                struct sl_pp_token_info **output);
 
 #endif /* SL_PP_TOKEN_H */
index e743a098417e7c3402e9ee3997cc45ae20a858fd..89c3cfa1a5bf70e87eb1feeea945882a54786900 100644 (file)
@@ -54,7 +54,8 @@ _parse_integer(const char *input,
 
 
 int
-sl_pp_version(const struct sl_pp_token_info *input,
+sl_pp_version(struct sl_pp_context *context,
+              const struct sl_pp_token_info *input,
               unsigned int *version,
               unsigned int *tokens_eaten)
 {
@@ -99,11 +100,18 @@ sl_pp_version(const struct sl_pp_token_info *input,
             break;
 
          case SL_PP_IDENTIFIER:
-            if (strcmp(input[i].data.identifier, "version")) {
-               return 0;
+            {
+               const char *id = sl_pp_context_cstr(context, input[i].data.identifier);
+
+               if (!id) {
+                  return -1;
+               }
+               if (strcmp(id, "version")) {
+                  return 0;
+               }
+               i++;
+               found_version = 1;
             }
-            i++;
-            found_version = 1;
             break;
 
          default:
@@ -119,12 +127,19 @@ sl_pp_version(const struct sl_pp_token_info *input,
             break;
 
          case SL_PP_NUMBER:
-            if (_parse_integer(input[i].data.number, version)) {
-               /* Expected version number. */
-               return -1;
+            {
+               const char *num = sl_pp_context_cstr(context, input[i].data.number);
+
+               if (!num) {
+                  return -1;
+               }
+               if (_parse_integer(num, version)) {
+                  /* Expected version number. */
+                  return -1;
+               }
+               i++;
+               found_number = 1;
             }
-            i++;
-            found_number = 1;
             break;
 
          default:
index 7deee1a1349cbafba90ffec0f96e9c17a75a3047..cee9f55bc6ca13cef63bf9740f536d030de3ad47 100644 (file)
 #ifndef SL_PP_VERSION_H
 #define SL_PP_VERSION_H
 
+#include "sl_pp_context.h"
 #include "sl_pp_token.h"
 
 
 int
-sl_pp_version(const struct sl_pp_token_info *input,
+sl_pp_version(struct sl_pp_context *context,
+              const struct sl_pp_token_info *input,
               unsigned int *version,
               unsigned int *tokens_eaten);