/
finderrors.c
219 lines (186 loc) · 5.57 KB
1
2
3
4
5
6
7
8
9
/**
* 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.
*/
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <sys/types.h>
#include <errno.h>
#include "mojoshader.h"
19
20
21
22
#if FINDERRORS_COMPILE_SHADERS
#include "SDL.h"
#endif
23
#ifdef _MSC_VER
24
25
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
26
#include <malloc.h> // for alloca().
27
#define snprintf _snprintf
28
29
#else
#include <dirent.h>
30
31
#endif
32
#define report printf
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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
54
55
int assembly = 0;
if (strstr(fn, ".bytecode") != NULL)
56
assembly = 0;
57
58
59
else if (strstr(fn, ".disasm") != NULL)
assembly = 1;
else
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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];
74
int rc = fread(buf, 1, sizeof (buf), io);
75
76
77
78
79
80
81
fclose(io);
if (rc == -1)
{
report("FAIL: %s %s\n", fname, strerror(errno));
return 1;
} // if
82
83
84
85
if (assembly)
{
const MOJOSHADER_parseData *a;
86
buf[rc] = '\0'; // make sure the source is null-terminated.
87
88
a = MOJOSHADER_assemble((char *) buf, rc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
89
if (a->error_count > 0)
90
{
91
report("FAIL: %s (line %d) %s\n", fname, a->errors[0].error_position, a->errors[0].error);
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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
106
#if FINDERRORS_COMPILE_SHADERS
107
MOJOSHADER_glShader *shader = MOJOSHADER_glCompileShader(buf, rc, NULL, 0);
108
109
110
if (shader == NULL)
report("FAIL: %s %s\n", fname, MOJOSHADER_glGetError());
else
111
112
113
114
115
116
117
118
119
120
121
122
123
124
{
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);
}
125
#else
126
const MOJOSHADER_parseData *pd = MOJOSHADER_parse(profile, buf, rc, NULL, 0, NULL, NULL, NULL);
127
if (pd->error != NULL)
128
report("FAIL: %s (position %d) %s\n", fname, pd->error_position, pd->error);
129
130
131
132
133
134
135
136
137
else
report("PASS: %s\n", fname);
MOJOSHADER_freeParseData(pd);
#endif
return 1;
} // do_file
138
static int do_dir(const char *dname, const char *profile)
139
140
{
int total = 0;
141
142
143
144
#ifdef _MSC_VER
WIN32_FIND_DATA dent;
HANDLE dirp = INVALID_HANDLE_VALUE;
145
FindFirstFileA(dname, &dent);
146
147
148
149
150
151
if (dirp != INVALID_HANDLE_VALUE)
{
do
{
if (!do_file(profile, dname, dent.cFileName, &total))
break;
152
} while (FindNextFileA(dirp, &dent) != 0);
153
154
155
156
CloseHandle(dirp);
} // if
#else
struct dirent *dent = NULL;
157
158
159
160
161
DIR *dirp = opendir(dname);
if (dirp != NULL)
{
while ((dent = readdir(dirp)) != NULL)
{
162
if (!do_file(profile, dname, dent->d_name, &total))
163
break;
164
165
166
} // while
closedir(dirp);
} // if
167
#endif
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
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;
185
int i;
186
const char *profile = argv[1];
187
188
189
#if FINDERRORS_COMPILE_SHADERS
SDL_Init(SDL_INIT_VIDEO);
190
SDL_GL_LoadLibrary(NULL);
191
SDL_SetVideoMode(640, 480, 0, SDL_OPENGL);
192
printf("Best profile is '%s'\n", MOJOSHADER_glBestProfile(SDL_GL_GetProcAddress));
193
MOJOSHADER_glContext *ctx;
194
ctx = MOJOSHADER_glCreateContext(profile, SDL_GL_GetProcAddress, 0, 0, 0);
195
if (ctx == NULL)
196
{
197
printf("MOJOSHADER_glCreateContext() fail: %s\n", MOJOSHADER_glGetError());
198
199
200
SDL_Quit();
return 1;
} // if
201
MOJOSHADER_glMakeContextCurrent(ctx);
202
203
#endif
204
for (i = 2; i < argc; i++)
205
total += do_dir(argv[i], profile);
206
207
printf("Saw %d files.\n", total);
208
209
#if FINDERRORS_COMPILE_SHADERS
210
MOJOSHADER_glDestroyContext(ctx);
211
212
SDL_Quit();
#endif
213
214
215
216
217
218
} // else
return 0;
} // main
// end of finderrors.c ...