mojoshader.c
branchtrunk
changeset 54 b2b64d39df0f
parent 51 b3978661fd6b
child 55 0ad8810899a0
--- a/mojoshader.c	Thu Mar 27 23:22:33 2008 -0400
+++ b/mojoshader.c	Fri Mar 28 05:40:24 2008 -0400
@@ -185,10 +185,16 @@
 // A simple linked list of strings, so we can build the final output without
 //  realloc()ing for each new line, and easily insert lines into the middle
 //  of the output without much trouble.
+typedef struct OutputListNode
+{
+    char *str;
+    struct OutputListNode *next;
+} OutputListNode;
+
 typedef struct OutputList
 {
-    char *str;
-    struct OutputList *next;
+    OutputListNode head;
+    OutputListNode *tail;
 } OutputList;
 
 
@@ -258,9 +264,11 @@
     MOJOSHADER_free free;
     const uint32 *tokens;
     uint32 tokencount;
-    OutputList output;
-    OutputList *output_tail;
-    int output_len; // total strlen; prevents walking the list just to malloc.
+    OutputList *output;
+    OutputList globals;
+    OutputList subroutines;
+    OutputList mainline;
+    int output_len; // total strlen; prevents walking the lists just to malloc.
     int indent;
     const char *endline;
     int endline_len;
@@ -371,10 +379,12 @@
 static int output_line(Context *ctx, const char *fmt, ...) ISPRINTF(2,3);
 static int output_line(Context *ctx, const char *fmt, ...)
 {
+    OutputListNode *item = NULL;
+
     if (isfail(ctx))
         return FAIL;  // we failed previously, don't go on...
 
-    OutputList *item = (OutputList *) ctx->malloc(sizeof (OutputList));
+    item = (OutputListNode *) ctx->malloc(sizeof (OutputListNode));
     if (item == NULL)
         return out_of_memory(ctx);
 
@@ -410,9 +420,11 @@
     } // else
 
     item->next = NULL;
-    ctx->output_tail->next = item;
-    ctx->output_tail = item;
+
+    ctx->output->tail->next = item;
+    ctx->output->tail = item;
     ctx->output_len += len + ctx->endline_len;
+
     return 0;
 } // output_line
 
@@ -2521,9 +2533,10 @@
     ctx->tokencount = bufsize / sizeof (uint32);
     ctx->endline = endline_str;
     ctx->endline_len = strlen(ctx->endline);
-    ctx->output.str = NULL;
-    ctx->output.next = NULL;
-    ctx->output_tail = &ctx->output;
+    ctx->globals.tail = &ctx->globals.head;
+    ctx->subroutines.tail = &ctx->subroutines.head;
+    ctx->mainline.tail = &ctx->mainline.head;
+    ctx->output = &ctx->globals;
 
     const int profileid = find_profile_id(profile);
     ctx->profileid = profileid;
@@ -2536,21 +2549,27 @@
 } // build_context
 
 
+static void free_output_list(MOJOSHADER_free f, OutputListNode *item)
+{
+    while (item != NULL)
+    {
+        OutputListNode *next = item->next;
+        if (item->str != NULL)
+            f(item->str);
+        f(item);
+        item = next;
+    } // while
+} // free_output_list
+
+
 static void destroy_context(Context *ctx)
 {
     if (ctx != NULL)
     {
         MOJOSHADER_free f = ((ctx->free != NULL) ? ctx->free : internal_free);
-        OutputList *item = ctx->output.next;
-        while (item != NULL)
-        {
-            OutputList *next = item->next;
-            if (item->str != NULL)
-                f(item->str);
-            f(item);
-            item = next;
-        } // while
-
+        free_output_list(f, ctx->globals.head.next);
+        free_output_list(f, ctx->subroutines.head.next);
+        free_output_list(f, ctx->mainline.head.next);
         if ((ctx->failstr != NULL) && (ctx->failstr != out_of_mem_str))
             f((void *) ctx->failstr);
         f(ctx);
@@ -2558,6 +2577,24 @@
 } // destroy_context
 
 
+static void append_list(char **_wptr, const char *endline,
+                        const size_t endline_len, OutputListNode *item)
+{
+    char *wptr = *_wptr;
+    while (item != NULL)
+    {
+        const size_t len = strlen(item->str);
+        memcpy(wptr, item->str, len);
+        wptr += len;
+        memcpy(wptr, endline, endline_len);
+        wptr += endline_len;
+        item = item->next;
+    } // while
+    *wptr = '\0';
+    *_wptr = wptr;
+} // append_list
+
+
 static char *build_output(Context *ctx)
 {
     char *retval = (char *) ctx->malloc(ctx->output_len + 1);
@@ -2565,20 +2602,12 @@
         out_of_memory(ctx);
     else
     {
-        const char *endline = ctx->endline;
-        const size_t endline_len = ctx->endline_len;
+        const char *endl = ctx->endline;
+        const size_t endllen = ctx->endline_len;
         char *wptr = retval;
-        OutputList *item = ctx->output.next;
-        while (item != NULL)
-        {
-            const size_t len = strlen(item->str);
-            memcpy(wptr, item->str, len);
-            wptr += len;
-            memcpy(wptr, endline, endline_len);
-            wptr += endline_len;
-            item = item->next;
-        } // while
-        *wptr = '\0';
+        append_list(&wptr, endl, endllen, ctx->globals.head.next);
+        append_list(&wptr, endl, endllen, ctx->subroutines.head.next);
+        append_list(&wptr, endl, endllen, ctx->mainline.head.next);
     } // else
 
     return retval;