utils/finderrors.c
changeset 588 ef3d2efa822d
parent 578 6c8f73c845e7
child 901 a9f799b93150
equal deleted inserted replaced
587:202354e004fc 588:ef3d2efa822d
       
     1 /**
       
     2  * MojoShader; generate shader programs from bytecode of compiled
       
     3  *  Direct3D shaders.
       
     4  *
       
     5  * Please see the file LICENSE.txt in the source's root directory.
       
     6  *
       
     7  *  This file written by Ryan C. Gordon.
       
     8  */
       
     9 
       
    10 #include <stdio.h>
       
    11 #include <stdlib.h>
       
    12 #include <string.h>
       
    13 #include <stdarg.h>
       
    14 #include <sys/types.h>
       
    15 #include <errno.h>
       
    16 
       
    17 #include "mojoshader.h"
       
    18 
       
    19 #if FINDERRORS_COMPILE_SHADERS
       
    20 #include "SDL.h"
       
    21 #endif
       
    22 
       
    23 #ifdef _MSC_VER
       
    24 #define WIN32_LEAN_AND_MEAN 1
       
    25 #include <windows.h>
       
    26 #include <malloc.h>  // for alloca().
       
    27 #define snprintf _snprintf
       
    28 #else
       
    29 #include <dirent.h>
       
    30 #endif
       
    31 
       
    32 #define report printf
       
    33 
       
    34 static int do_file(const char *profile, const char *dname, const char *fn, int *total)
       
    35 {
       
    36     int do_quit = 0;
       
    37 
       
    38     #if FINDERRORS_COMPILE_SHADERS
       
    39     SDL_Event e;  // pump event queue to keep OS happy.
       
    40     while (SDL_PollEvent(&e))
       
    41     {
       
    42         if (e.type == SDL_QUIT)
       
    43             do_quit = 1;
       
    44     } // while
       
    45     SDL_GL_SwapBuffers();
       
    46     #endif
       
    47 
       
    48     if (do_quit)
       
    49     {
       
    50         report("FAIL: user requested quit!\n");
       
    51         return 0;
       
    52     } // if
       
    53 
       
    54     int assembly = 0;
       
    55     if (strstr(fn, ".bytecode") != NULL)
       
    56         assembly = 0;
       
    57     else if (strstr(fn, ".disasm") != NULL)
       
    58         assembly = 1;
       
    59     else
       
    60         return 1;
       
    61 
       
    62     (*total)++;
       
    63 
       
    64     char *fname = (char *) alloca(strlen(fn) + strlen(dname) + 1);
       
    65     sprintf(fname, "%s/%s", dname, fn);
       
    66     FILE *io = fopen(fname, "rb");
       
    67     if (io == NULL)
       
    68     {
       
    69         report("FAIL: %s fopen() failed.\n", fname);
       
    70         return 1;
       
    71     } // if
       
    72 
       
    73     static unsigned char buf[1024 * 256];
       
    74     int rc = fread(buf, 1, sizeof (buf), io);
       
    75     fclose(io);
       
    76     if (rc == -1)
       
    77     {
       
    78         report("FAIL: %s %s\n", fname, strerror(errno));
       
    79         return 1;
       
    80     } // if
       
    81 
       
    82     if (assembly)
       
    83     {
       
    84         const MOJOSHADER_parseData *a;
       
    85 
       
    86         buf[rc] = '\0';  // make sure the source is null-terminated.
       
    87         a = MOJOSHADER_assemble(fname, (char *) buf, rc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
       
    88 
       
    89         if (a->error_count > 0)
       
    90         {
       
    91             report("FAIL: %s (line %d) %s\n",
       
    92                 a->errors[0].filename ? a->errors[0].filename : "???",
       
    93                 a->errors[0].error_position,
       
    94                 a->errors[0].error);
       
    95             return 1;
       
    96         } // if
       
    97 
       
    98         else if (a->output_len > sizeof (buf))
       
    99         {
       
   100             report("FAIL: %s buffer overflow in finderrors.c\n", fname);
       
   101             return 1;
       
   102         } // if
       
   103 
       
   104         rc = a->output_len;
       
   105         memcpy(buf, a->output, rc);
       
   106         MOJOSHADER_freeParseData(a);
       
   107     } // if
       
   108 
       
   109     #if FINDERRORS_COMPILE_SHADERS
       
   110     MOJOSHADER_glShader *shader = MOJOSHADER_glCompileShader(buf, rc, NULL, 0);
       
   111     if (shader == NULL)
       
   112         report("FAIL: %s %s\n", fname, MOJOSHADER_glGetError());
       
   113     else
       
   114     {
       
   115         const MOJOSHADER_parseData *pd = MOJOSHADER_glGetShaderParseData(shader);
       
   116         MOJOSHADER_glShader *v = (pd->shader_type == MOJOSHADER_TYPE_VERTEX) ? shader : NULL;
       
   117         MOJOSHADER_glShader *p = (pd->shader_type == MOJOSHADER_TYPE_PIXEL) ? shader : NULL;
       
   118         MOJOSHADER_glProgram *program = MOJOSHADER_glLinkProgram(v, p);
       
   119         if (program == NULL)
       
   120             report("FAIL: %s %s\n", fname, MOJOSHADER_glGetError());
       
   121         else
       
   122         {
       
   123             report("PASS: %s\n", fname);
       
   124             MOJOSHADER_glDeleteProgram(program);
       
   125         } // else
       
   126         MOJOSHADER_glDeleteShader(shader);
       
   127     }
       
   128     #else
       
   129     const MOJOSHADER_parseData *pd = MOJOSHADER_parse(profile, buf, rc, NULL, 0, NULL, NULL, NULL);
       
   130     if (pd->error != NULL)
       
   131         report("FAIL: %s (position %d) %s\n", fname, pd->error_position, pd->error);
       
   132     else
       
   133         report("PASS: %s\n", fname);
       
   134     MOJOSHADER_freeParseData(pd);
       
   135     #endif
       
   136 
       
   137     return 1;
       
   138 } // do_file
       
   139 
       
   140 
       
   141 static int do_dir(const char *dname, const char *profile)
       
   142 {
       
   143     int total = 0;
       
   144 
       
   145 #ifdef _MSC_VER
       
   146     WIN32_FIND_DATA dent;
       
   147     HANDLE dirp = INVALID_HANDLE_VALUE;
       
   148     FindFirstFileA(dname, &dent);
       
   149     if (dirp != INVALID_HANDLE_VALUE)
       
   150     {
       
   151         do
       
   152         {
       
   153             if (!do_file(profile, dname, dent.cFileName, &total))
       
   154                 break;
       
   155         } while (FindNextFileA(dirp, &dent) != 0);
       
   156         CloseHandle(dirp);
       
   157     } // if
       
   158 #else
       
   159     struct dirent *dent = NULL;
       
   160     DIR *dirp = opendir(dname);
       
   161     if (dirp != NULL)
       
   162     {
       
   163         while ((dent = readdir(dirp)) != NULL)
       
   164         {
       
   165             if (!do_file(profile, dname, dent->d_name, &total))
       
   166                 break;
       
   167         } // while
       
   168         closedir(dirp);
       
   169     } // if
       
   170 #endif
       
   171 
       
   172     return total;
       
   173 } // do_dir
       
   174 
       
   175 
       
   176 int main(int argc, char **argv)
       
   177 {
       
   178     //printf("MojoShader finderrors\n");
       
   179     //printf("Compiled against version %d\n", MOJOSHADER_VERSION);
       
   180     //printf("Linked against version %d\n", MOJOSHADER_version());
       
   181     //printf("\n");
       
   182 
       
   183     if (argc <= 2)
       
   184         printf("\n\nUSAGE: %s <profile> [dir1] ... [dirN]\n\n", argv[0]);
       
   185     else
       
   186     {
       
   187         int total = 0;
       
   188         int i;
       
   189         const char *profile = argv[1];
       
   190 
       
   191         #if FINDERRORS_COMPILE_SHADERS
       
   192         SDL_Init(SDL_INIT_VIDEO);
       
   193         SDL_GL_LoadLibrary(NULL);
       
   194         SDL_SetVideoMode(640, 480, 0, SDL_OPENGL);
       
   195         printf("Best profile is '%s'\n", MOJOSHADER_glBestProfile(SDL_GL_GetProcAddress));
       
   196         MOJOSHADER_glContext *ctx;
       
   197         ctx = MOJOSHADER_glCreateContext(profile, SDL_GL_GetProcAddress, 0, 0, 0);
       
   198         if (ctx == NULL)
       
   199         {
       
   200             printf("MOJOSHADER_glCreateContext() fail: %s\n", MOJOSHADER_glGetError());
       
   201             SDL_Quit();
       
   202             return 1;
       
   203         } // if
       
   204         MOJOSHADER_glMakeContextCurrent(ctx);
       
   205         #endif
       
   206 
       
   207         for (i = 2; i < argc; i++)
       
   208             total += do_dir(argv[i], profile);
       
   209 
       
   210         printf("Saw %d files.\n", total);
       
   211 
       
   212         #if FINDERRORS_COMPILE_SHADERS
       
   213         MOJOSHADER_glDestroyContext(ctx);
       
   214         SDL_Quit();
       
   215         #endif
       
   216     } // else
       
   217 
       
   218     return 0;
       
   219 } // main
       
   220 
       
   221 // end of finderrors.c ...
       
   222