Added error position information to MOJOSHADER_parseData.
authorRyan C. Gordon <icculus@icculus.org>
Wed, 10 Dec 2008 03:48:38 -0500
changeset 475 ea119c8ce5cd
parent 474 c2d4e63efdd1
child 476 def04fdc464a
Added error position information to MOJOSHADER_parseData.
finderrors.c
mojoshader.c
mojoshader.h
testoutput.c
testparse.c
--- a/finderrors.c	Wed Dec 10 03:47:19 2008 -0500
+++ b/finderrors.c	Wed Dec 10 03:48:38 2008 -0500
@@ -96,7 +96,7 @@
     #else
     const MOJOSHADER_parseData *pd = MOJOSHADER_parse(profile, buf, rc, NULL, 0, NULL, NULL, NULL);
     if (pd->error != NULL)
-        report("FAIL: %s %s\n", fname, pd->error);
+        report("FAIL: %s (position %d) %s\n", fname, pd->error_position, pd->error);
     else
         report("PASS: %s\n", fname);
     MOJOSHADER_freeParseData(pd);
--- a/mojoshader.c	Wed Dec 10 03:47:19 2008 -0500
+++ b/mojoshader.c	Wed Dec 10 03:48:38 2008 -0500
@@ -161,8 +161,10 @@
     MOJOSHADER_malloc malloc;
     MOJOSHADER_free free;
     void *malloc_data;
+    const uint32 *orig_tokens;
     const uint32 *tokens;
     uint32 tokencount;
+    int started_parsing;
     const MOJOSHADER_swizzle *swizzles;
     unsigned int swizzles_count;
     OutputList *output;
@@ -234,7 +236,7 @@
 // Convenience functions for allocators...
 
 MOJOSHADER_parseData out_of_mem_data = {
-    "Out of memory", 0, 0, 0, 0, MOJOSHADER_TYPE_UNKNOWN, 0, 0, 0, 0
+    "Out of memory", -1, 0, 0, 0, 0, MOJOSHADER_TYPE_UNKNOWN, 0, 0, 0, 0
 };
 
 const char *out_of_mem_str = "Out of memory";
@@ -6627,6 +6629,7 @@
     ctx->free = f;
     ctx->malloc_data = d;
     ctx->tokens = (const uint32 *) tokenbuf;
+    ctx->orig_tokens = (const uint32 *) tokenbuf;
     ctx->tokencount = bufsize / sizeof (uint32);
     ctx->swizzles = swiz;
     ctx->swizzles_count = swizcount;
@@ -7083,11 +7086,16 @@
             Free(ctx, samplers);
         } // if
 
+        if (ctx->started_parsing)
+            retval->error_position = (ctx->tokens - ctx->orig_tokens) * sizeof (uint32);
+        else
+            retval->error_position = -1;
         retval->error = ctx->failstr;  // we recycle.  :)
         ctx->failstr = NULL;  // don't let this get free()'d too soon.
     } // if
     else
     {
+        retval->error_position = -2;
         retval->profile = ctx->profile->name;
         retval->output = output;
         retval->output_len = ctx->output_len;
@@ -7297,7 +7305,10 @@
 
     // Version token always comes first.
     if (!isfail(ctx))
+    {
+        ctx->started_parsing = 1;
         rc = parse_version_token(ctx, profile);
+    } // if
 
     // parse out the rest of the tokens after the version token...
     while ( (rc > 0) && (!isfail(ctx)) )
--- a/mojoshader.h	Wed Dec 10 03:47:19 2008 -0500
+++ b/mojoshader.h	Wed Dec 10 03:48:38 2008 -0500
@@ -252,6 +252,15 @@
     const char *error;
 
     /*
+     * Position of error, if there is one. Will be -2 if there was no
+     *  error, and -1 if there was an error before processing started. If >= 0,
+     *  MOJOSHADER_parse() sets this to the byte offset (starting at zero) into
+     *  the bytecode you supplied, and MOJOSHADER_assemble() sets this to a
+     *  a line number in the source code you supplied (starting at zero).
+     */
+    int error_position;
+
+    /*
      * The name of the profile used to parse the shader. Will be NULL on error.
      */
     const char *profile;
--- a/testoutput.c	Wed Dec 10 03:47:19 2008 -0500
+++ b/testoutput.c	Wed Dec 10 03:48:38 2008 -0500
@@ -18,7 +18,7 @@
 
     pd = MOJOSHADER_parse(prof, buf, len, NULL, 0, NULL, NULL, NULL);
     if (pd->error != NULL)
-        printf("ERROR: %s\n", pd->error);
+        printf("ERROR: (position %d) %s\n", pd->error_position, pd->error);
     else
     {
         retval = 1;
--- a/testparse.c	Wed Dec 10 03:47:19 2008 -0500
+++ b/testparse.c	Wed Dec 10 03:48:38 2008 -0500
@@ -62,7 +62,7 @@
     pd = MOJOSHADER_parse(prof, buf, len, NULL, 0, Malloc, Free, NULL);
     printf("PROFILE: %s\n", prof);
     if (pd->error != NULL)
-        printf("ERROR: %s\n", pd->error);
+        printf("ERROR: (position %d) %s\n", pd->error_position, pd->error);
     else
     {
         retval = 1;