utils/finderrors.c
changeset 588 ef3d2efa822d
parent 578 6c8f73c845e7
child 901 a9f799b93150
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/utils/finderrors.c	Thu Feb 12 17:29:24 2009 -0500
@@ -0,0 +1,222 @@
+/**
+ * MojoShader; generate shader programs from bytecode of compiled
+ *  Direct3D shaders.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ *  This file written by Ryan C. Gordon.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <errno.h>
+
+#include "mojoshader.h"
+
+#if FINDERRORS_COMPILE_SHADERS
+#include "SDL.h"
+#endif
+
+#ifdef _MSC_VER
+#define WIN32_LEAN_AND_MEAN 1
+#include <windows.h>
+#include <malloc.h>  // for alloca().
+#define snprintf _snprintf
+#else
+#include <dirent.h>
+#endif
+
+#define report printf
+
+static int do_file(const char *profile, const char *dname, const char *fn, int *total)
+{
+    int do_quit = 0;
+
+    #if FINDERRORS_COMPILE_SHADERS
+    SDL_Event e;  // pump event queue to keep OS happy.
+    while (SDL_PollEvent(&e))
+    {
+        if (e.type == SDL_QUIT)
+            do_quit = 1;
+    } // while
+    SDL_GL_SwapBuffers();
+    #endif
+
+    if (do_quit)
+    {
+        report("FAIL: user requested quit!\n");
+        return 0;
+    } // if
+
+    int assembly = 0;
+    if (strstr(fn, ".bytecode") != NULL)
+        assembly = 0;
+    else if (strstr(fn, ".disasm") != NULL)
+        assembly = 1;
+    else
+        return 1;
+
+    (*total)++;
+
+    char *fname = (char *) alloca(strlen(fn) + strlen(dname) + 1);
+    sprintf(fname, "%s/%s", dname, fn);
+    FILE *io = fopen(fname, "rb");
+    if (io == NULL)
+    {
+        report("FAIL: %s fopen() failed.\n", fname);
+        return 1;
+    } // if
+
+    static unsigned char buf[1024 * 256];
+    int rc = fread(buf, 1, sizeof (buf), io);
+    fclose(io);
+    if (rc == -1)
+    {
+        report("FAIL: %s %s\n", fname, strerror(errno));
+        return 1;
+    } // if
+
+    if (assembly)
+    {
+        const MOJOSHADER_parseData *a;
+
+        buf[rc] = '\0';  // make sure the source is null-terminated.
+        a = MOJOSHADER_assemble(fname, (char *) buf, rc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+        if (a->error_count > 0)
+        {
+            report("FAIL: %s (line %d) %s\n",
+                a->errors[0].filename ? a->errors[0].filename : "???",
+                a->errors[0].error_position,
+                a->errors[0].error);
+            return 1;
+        } // if
+
+        else if (a->output_len > sizeof (buf))
+        {
+            report("FAIL: %s buffer overflow in finderrors.c\n", fname);
+            return 1;
+        } // if
+
+        rc = a->output_len;
+        memcpy(buf, a->output, rc);
+        MOJOSHADER_freeParseData(a);
+    } // if
+
+    #if FINDERRORS_COMPILE_SHADERS
+    MOJOSHADER_glShader *shader = MOJOSHADER_glCompileShader(buf, rc, NULL, 0);
+    if (shader == NULL)
+        report("FAIL: %s %s\n", fname, MOJOSHADER_glGetError());
+    else
+    {
+        const MOJOSHADER_parseData *pd = MOJOSHADER_glGetShaderParseData(shader);
+        MOJOSHADER_glShader *v = (pd->shader_type == MOJOSHADER_TYPE_VERTEX) ? shader : NULL;
+        MOJOSHADER_glShader *p = (pd->shader_type == MOJOSHADER_TYPE_PIXEL) ? shader : NULL;
+        MOJOSHADER_glProgram *program = MOJOSHADER_glLinkProgram(v, p);
+        if (program == NULL)
+            report("FAIL: %s %s\n", fname, MOJOSHADER_glGetError());
+        else
+        {
+            report("PASS: %s\n", fname);
+            MOJOSHADER_glDeleteProgram(program);
+        } // else
+        MOJOSHADER_glDeleteShader(shader);
+    }
+    #else
+    const MOJOSHADER_parseData *pd = MOJOSHADER_parse(profile, buf, rc, NULL, 0, NULL, NULL, NULL);
+    if (pd->error != NULL)
+        report("FAIL: %s (position %d) %s\n", fname, pd->error_position, pd->error);
+    else
+        report("PASS: %s\n", fname);
+    MOJOSHADER_freeParseData(pd);
+    #endif
+
+    return 1;
+} // do_file
+
+
+static int do_dir(const char *dname, const char *profile)
+{
+    int total = 0;
+
+#ifdef _MSC_VER
+    WIN32_FIND_DATA dent;
+    HANDLE dirp = INVALID_HANDLE_VALUE;
+    FindFirstFileA(dname, &dent);
+    if (dirp != INVALID_HANDLE_VALUE)
+    {
+        do
+        {
+            if (!do_file(profile, dname, dent.cFileName, &total))
+                break;
+        } while (FindNextFileA(dirp, &dent) != 0);
+        CloseHandle(dirp);
+    } // if
+#else
+    struct dirent *dent = NULL;
+    DIR *dirp = opendir(dname);
+    if (dirp != NULL)
+    {
+        while ((dent = readdir(dirp)) != NULL)
+        {
+            if (!do_file(profile, dname, dent->d_name, &total))
+                break;
+        } // while
+        closedir(dirp);
+    } // if
+#endif
+
+    return total;
+} // do_dir
+
+
+int main(int argc, char **argv)
+{
+    //printf("MojoShader finderrors\n");
+    //printf("Compiled against version %d\n", MOJOSHADER_VERSION);
+    //printf("Linked against version %d\n", MOJOSHADER_version());
+    //printf("\n");
+
+    if (argc <= 2)
+        printf("\n\nUSAGE: %s <profile> [dir1] ... [dirN]\n\n", argv[0]);
+    else
+    {
+        int total = 0;
+        int i;
+        const char *profile = argv[1];
+
+        #if FINDERRORS_COMPILE_SHADERS
+        SDL_Init(SDL_INIT_VIDEO);
+        SDL_GL_LoadLibrary(NULL);
+        SDL_SetVideoMode(640, 480, 0, SDL_OPENGL);
+        printf("Best profile is '%s'\n", MOJOSHADER_glBestProfile(SDL_GL_GetProcAddress));
+        MOJOSHADER_glContext *ctx;
+        ctx = MOJOSHADER_glCreateContext(profile, SDL_GL_GetProcAddress, 0, 0, 0);
+        if (ctx == NULL)
+        {
+            printf("MOJOSHADER_glCreateContext() fail: %s\n", MOJOSHADER_glGetError());
+            SDL_Quit();
+            return 1;
+        } // if
+        MOJOSHADER_glMakeContextCurrent(ctx);
+        #endif
+
+        for (i = 2; i < argc; i++)
+            total += do_dir(argv[i], profile);
+
+        printf("Saw %d files.\n", total);
+
+        #if FINDERRORS_COMPILE_SHADERS
+        MOJOSHADER_glDestroyContext(ctx);
+        SDL_Quit();
+        #endif
+    } // else
+
+    return 0;
+} // main
+
+// end of finderrors.c ...
+