mojoshader_preprocessor.c
changeset 612 72ccfe69eaf1
parent 611 8c2ee1a97ee1
child 614 0f2f298003ae
--- a/mojoshader_preprocessor.c	Fri Feb 13 10:15:36 2009 -0500
+++ b/mojoshader_preprocessor.c	Fri Feb 13 18:54:21 2009 -0500
@@ -23,6 +23,14 @@
     struct DefineHash *next;
 } DefineHash;
 
+// Simple linked list to cache source filenames, so we don't have to copy
+//  the same string over and over for each opcode.
+typedef struct FilenameCache
+{
+    char *filename;
+    struct FilenameCache *next;
+} FilenameCache;
+
 typedef struct Context
 {
     int isfail;
@@ -30,6 +38,7 @@
     char failstr[256];
     IncludeState *include_stack;
     DefineHash *define_hashtable[256];
+    FilenameCache *filename_cache;
     MOJOSHADER_includeOpen open_callback;
     MOJOSHADER_includeClose close_callback;
     MOJOSHADER_malloc malloc;
@@ -325,6 +334,54 @@
 } // find_define
 
 
+// filename cache stuff...
+
+static const char *cache_filename(Context *ctx, const char *fname)
+{
+    if (fname == NULL)
+        return NULL;
+
+    // !!! FIXME: this could be optimized into a hash table, but oh well.
+    FilenameCache *item = ctx->filename_cache;
+    while (item != NULL)
+    {
+        if (strcmp(item->filename, fname) == 0)
+            return item->filename;
+        item = item->next;
+    } // while
+
+    // new cache item.
+    item = (FilenameCache *) Malloc(ctx, sizeof (FilenameCache));
+    if (item == NULL)
+        return NULL;
+
+    item->filename = StrDup(ctx, fname);
+    if (item->filename == NULL)
+    {
+        Free(ctx, item);
+        return NULL;
+    } // if
+
+    item->next = ctx->filename_cache;
+    ctx->filename_cache = item;
+
+    return item->filename;
+} // cache_filename
+
+
+static void free_filename_cache(Context *ctx)
+{
+    FilenameCache *item = ctx->filename_cache;
+    while (item != NULL)
+    {
+        FilenameCache *next = item->next;
+        Free(ctx, item->filename);
+        Free(ctx, item);
+        item = next;
+    } // while
+} // free_filename_cache
+
+
 static int push_source(Context *ctx, const char *fname, const char *source,
                        unsigned int srclen, int included)
 {
@@ -335,7 +392,7 @@
 
     if (fname != NULL)
     {
-        state->filename = StrDup(ctx, fname);
+        state->filename = cache_filename(ctx, fname);
         if (state->filename == NULL)
         {
             Free(ctx, state);
@@ -369,8 +426,9 @@
                             ctx->free, ctx->malloc_data);
     } // if
 
+    // state->filename is a pointer to the filename cache; don't free it here!
+
     ctx->include_stack = state->next;
-    Free(ctx, state->filename);
     Free(ctx, state);
 } // pop_source
 
@@ -435,6 +493,7 @@
         pop_source(ctx);
 
     free_all_defines(ctx);
+    free_filename_cache(ctx);
 
     Free(ctx, ctx);
 } // preprocessor_end