Cleaned up MOJOSHADER_preprocessor().
authorRyan C. Gordon <icculus@icculus.org>
Wed, 17 Nov 2010 15:58:40 -0500
changeset 955 9315c168a97a
parent 954 13919266d1ec
child 956 7888858a6777
Cleaned up MOJOSHADER_preprocessor(). Not only does this clean up the pile of error cases, but it makes sure preprocessor_end() isn't called until all the things using MallocBridge() are destroyed first.
mojoshader_preprocessor.c
--- a/mojoshader_preprocessor.c	Tue Nov 16 13:51:59 2010 -0500
+++ b/mojoshader_preprocessor.c	Wed Nov 17 15:58:40 2010 -0500
@@ -2190,6 +2190,19 @@
                              MOJOSHADER_includeClose include_close,
                              MOJOSHADER_malloc m, MOJOSHADER_free f, void *d)
 {
+    MOJOSHADER_preprocessData *retval = NULL;
+    Preprocessor *pp = NULL;
+    ErrorList *errors = NULL;
+    Buffer *buffer = NULL;
+    Token token = TOKEN_UNKNOWN;
+    const char *tokstr = NULL;
+    int nl = 1;
+    int indent = 0;
+    unsigned int len = 0;
+    char *output = NULL;
+    int errcount = 0;
+    size_t total_bytes = 0;
+
     // !!! FIXME: what's wrong with ENDLINE_STR?
     #ifdef _WINDOWS
     static const char endline[] = { '\r', '\n' };
@@ -2202,34 +2215,20 @@
     if (!include_open) include_open = MOJOSHADER_internal_include_open;
     if (!include_close) include_close = MOJOSHADER_internal_include_close;
 
-    Preprocessor *pp = preprocessor_start(filename, source, sourcelen,
-                                          include_open, include_close,
-                                          defines, define_count, 0, m, f, d);
-
+    pp = preprocessor_start(filename, source, sourcelen,
+                            include_open, include_close,
+                            defines, define_count, 0, m, f, d);
     if (pp == NULL)
-        return &out_of_mem_data_preprocessor;
-
-    ErrorList *errors = errorlist_create(MallocBridge, FreeBridge, pp);
-    if (errors == NULL)
-    {
-        preprocessor_end(pp);
-        return &out_of_mem_data_preprocessor;
-    } // if
+        goto preprocess_out_of_mem;
 
-    Buffer *buffer = buffer_create(4096, MallocBridge, FreeBridge, pp);
-    if (!buffer)
-    {
-        errorlist_destroy(errors);
-        preprocessor_end(pp);
-        return &out_of_mem_data_preprocessor;
-    } // if
+    errors = errorlist_create(MallocBridge, FreeBridge, pp);
+    if (errors == NULL)
+        goto preprocess_out_of_mem;
 
-    Token token = TOKEN_UNKNOWN;
-    const char *tokstr = NULL;
+    buffer = buffer_create(4096, MallocBridge, FreeBridge, pp);
+    if (buffer == NULL)
+        goto preprocess_out_of_mem;
 
-    int nl = 1;
-    int indent = 0;
-    unsigned int len = 0;
     while ((tokstr = preprocessor_nexttoken(pp, &len, &token)) != NULL)
     {
         int isnewline = 0;
@@ -2237,12 +2236,7 @@
         assert(token != TOKEN_EOI);
 
         if (preprocessor_outofmemory(pp))
-        {
-            preprocessor_end(pp);
-            buffer_destroy(buffer);
-            errorlist_destroy(errors);
-            return &out_of_mem_data_preprocessor;
-        } // if
+            goto preprocess_out_of_mem;
 
         // Microsoft's preprocessor is weird.
         // It ignores newlines, and then inserts its own around certain
@@ -2294,49 +2288,47 @@
     
     assert(token == TOKEN_EOI);
 
-    preprocessor_end(pp);
+    total_bytes = buffer_size(buffer);
+    output = buffer_flatten(buffer);
+    buffer_destroy(buffer);
+    buffer = NULL;  // don't free this pointer again.
 
-    const size_t total_bytes = buffer_size(buffer);
-    char *output = buffer_flatten(buffer);
-    buffer_destroy(buffer);
     if (output == NULL)
-    {
-        errorlist_destroy(errors);
-        return &out_of_mem_data_preprocessor;
-    } // if
+        goto preprocess_out_of_mem;
 
-    MOJOSHADER_preprocessData *retval = (MOJOSHADER_preprocessData *)
-                                    m(sizeof (MOJOSHADER_preprocessData), d);
+    retval = (MOJOSHADER_preprocessData *) m(sizeof (*retval), d);
     if (retval == NULL)
-    {
-        errorlist_destroy(errors);
-        f(output, d);
-        return &out_of_mem_data_preprocessor;
-    } // if
+        goto preprocess_out_of_mem;
 
     memset(retval, '\0', sizeof (*retval));
-    const int errcount = errorlist_count(errors);
+    errcount = errorlist_count(errors);
     if (errcount > 0)
     {
         retval->error_count = errcount;
         retval->errors = errorlist_flatten(errors);
         if (retval->errors == NULL)
-        {
-            errorlist_destroy(errors);
-            f(retval, d);
-            f(output, d);
-            return &out_of_mem_data_preprocessor;
-        } // if
+            goto preprocess_out_of_mem;
     } // if
 
-    errorlist_destroy(errors);
-
     retval->output = output;
     retval->output_len = total_bytes;
     retval->malloc = m;
     retval->free = f;
     retval->malloc_data = d;
+
+    errorlist_destroy(errors);
+    preprocessor_end(pp);
     return retval;
+
+preprocess_out_of_mem:
+    if (retval != NULL)
+        f(retval->errors, d);
+    f(retval, d);
+    f(output, d);
+    buffer_destroy(buffer);
+    errorlist_destroy(errors);
+    preprocessor_end(pp);
+    return &out_of_mem_data_preprocessor;
 } // MOJOSHADER_preprocess