--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/utils/mojoshader-compiler.c Thu Feb 19 03:19:15 2009 -0500
@@ -0,0 +1,246 @@
+/**
+ * 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 "mojoshader.h"
+
+static const char **include_paths = NULL;
+static unsigned int include_path_count = 0;
+
+
+static int open_include(MOJOSHADER_includeType inctype, const char *fname,
+ const char *parent, const char **outdata,
+ unsigned int *outbytes, MOJOSHADER_malloc m,
+ MOJOSHADER_free f, void *d)
+{
+ int i;
+ for (i = 0; i < include_path_count; i++)
+ {
+ const char *path = include_paths[i];
+ const size_t len = strlen(path) + strlen(fname) + 2;
+ char *buf = (char *) m(len, d);
+ if (buf == NULL)
+ return 0;
+
+ snprintf(buf, len, "%s/%s", path, fname);
+ FILE *io = fopen(buf, "rb");
+ f(buf, d);
+ if (io == NULL)
+ continue;
+
+ if (fseek(io, 0, SEEK_END) != -1)
+ {
+ const long fsize = ftell(io);
+ if ((fsize == -1) || (fseek(io, 0, SEEK_SET) == -1))
+ {
+ fclose(io);
+ return 0;
+ } // if
+
+ char *data = (char *) m(fsize, d);
+ if (data == NULL)
+ {
+ fclose(io);
+ return 0;
+ } // if
+
+ if (fread(data, fsize, 1, io) != 1)
+ {
+ f(data, d);
+ fclose(io);
+ return 0;
+ } // if
+
+ fclose(io);
+ *outdata = data;
+ *outbytes = (unsigned int) fsize;
+ return 1;
+ } // if
+ } // for
+
+ return 0;
+} // open_include
+
+
+static void close_include(const char *data, MOJOSHADER_malloc m,
+ MOJOSHADER_free f, void *d)
+{
+ f((void *) data, d);
+} // close_include
+
+
+static int preprocess(const char *fname, const char *buf, int len,
+ const char *outfile,
+ const MOJOSHADER_preprocessorDefine *defs,
+ unsigned int defcount)
+{
+ FILE *io = outfile ? fopen(outfile, "wb") : stdout;
+ if (io == NULL)
+ {
+ printf(" ... fopen('%s') failed.\n", outfile);
+ return 0;
+ } // if
+
+ const MOJOSHADER_preprocessData *pd;
+ int retval = 0;
+
+ pd = MOJOSHADER_preprocess(fname, buf, len, defs, defcount,
+ open_include, close_include, NULL, NULL, NULL);
+
+ if (pd->error_count > 0)
+ {
+ int i;
+ for (i = 0; i < pd->error_count; i++)
+ {
+ printf("%s:%d: ERROR: %s\n",
+ pd->errors[i].filename ? pd->errors[i].filename : "???",
+ pd->errors[i].error_position,
+ pd->errors[i].error);
+ } // for
+ } // if
+ else
+ {
+ if (pd->output != NULL)
+ {
+ if (fwrite(pd->output, pd->output_len, 1, io) != 1)
+ printf(" ... fwrite('%s') failed.\n", outfile);
+ else if ((outfile != NULL) && (fclose(io) == EOF))
+ printf(" ... fclose('%s') failed.\n", outfile);
+ else
+ retval = 1;
+ } // if
+ } // else
+ MOJOSHADER_freePreprocessData(pd);
+
+ return retval;
+} // preprocess
+
+
+int main(int argc, char **argv)
+{
+ int retval = 1;
+ const char *infile = NULL;
+ const char *outfile = NULL;
+ int i;
+
+ MOJOSHADER_preprocessorDefine *defs = NULL;
+ unsigned int defcount = 0;
+
+ for (i = 1; i < argc; i++)
+ {
+ const char *arg = argv[i];
+
+ if (strcmp(arg, "-o") == 0)
+ {
+ if (outfile != NULL)
+ {
+ printf("multiple output files specified.\n");
+ exit(1);
+ } // if
+
+ arg = argv[++i];
+ if (arg == NULL)
+ {
+ printf("no filename after '-o'\n");
+ exit(1);
+ } // if
+ outfile = arg;
+ } // if
+
+ if (strcmp(arg, "-I") == 0)
+ {
+ arg = argv[++i];
+ if (arg == NULL)
+ {
+ printf("no path after '-I'\n");
+ exit(1);
+ } // if
+ include_paths = (const char **) realloc(include_paths,
+ (include_path_count+1) * sizeof (char *));
+ include_paths[include_path_count] = arg;
+ include_path_count++;
+ } // if
+
+ else if (strncmp(arg, "-D", 2) == 0)
+ {
+ arg += 2;
+ char *ident = strdup(arg);
+ char *ptr = strchr(ident, '=');
+ const char *val = "";
+ if (ptr)
+ {
+ *ptr = '\0';
+ val = ptr+1;
+ } // if
+
+ defs = (MOJOSHADER_preprocessorDefine *) realloc(defs,
+ (defcount+1) * sizeof (MOJOSHADER_preprocessorDefine));
+ defs[defcount].identifier = ident;
+ defs[defcount].definition = val;
+ defcount++;
+ } // else if
+
+ else
+ {
+ if (infile != NULL)
+ {
+ printf("multiple input files specified.\n");
+ exit(1);
+ } // if
+ infile = arg;
+ } // else
+ } // for
+
+ if (infile == NULL)
+ {
+ printf("no input file specified.\n");
+ exit(1);
+ } // if
+
+ FILE *io = fopen(infile, "rb");
+ if (io == NULL)
+ printf(" ... fopen('%s') failed.\n", infile);
+ else
+ {
+ fseek(io, 0, SEEK_END);
+ long fsize = ftell(io);
+ fseek(io, 0, SEEK_SET);
+ if (fsize == -1)
+ fsize = 1000000;
+ char *buf = (char *) malloc(fsize);
+ const int rc = fread(buf, 1, fsize, io);
+ fclose(io);
+ if (rc == EOF)
+ printf(" ... fread('%s') failed.\n", infile);
+ else
+ {
+ if (preprocess(infile, buf, rc, outfile, defs, defcount))
+ retval = 0;
+ else
+ {
+ if (outfile != NULL)
+ remove(outfile);
+ } // else
+ free(buf);
+ } // else
+ } // else
+
+ for (i = 0; i < defcount; i++)
+ free((void *) defs[i].identifier);
+ free(defs);
+
+ free(include_paths);
+
+ return retval;
+} // main
+
+// end of preprocess.c ...
+