i965: Stop making a pointless region for DRI2 to just throw it away.
[mesa.git] / src / glsl / glcpp / glcpp.c
index a245cb54060809ebb6ff0adbc6dbf74b2620243d..07b1500b6b8cf1696c21b2e020ee3237bc76bdfc 100644 (file)
  * DEALINGS IN THE SOFTWARE.
  */
 
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+
 #include "glcpp.h"
+#include "main/mtypes.h"
+#include "main/shaderobj.h"
 
-extern int yydebug;
+extern int glcpp_parser_debug;
 
+void
+_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
+                       struct gl_shader *sh)
+{
+   (void) ctx;
+   *ptr = sh;
+}
+
+/* Read from fp until EOF and return a string of everything read.
+ */
 static char *
-load_text_file(void *ctx, const char *file_name)
+load_text_fp (void *ctx, FILE *fp)
 {
+#define CHUNK 4096
        char *text = NULL;
-       struct stat st;
-       ssize_t total_read = 0;
-       int fd = file_name == NULL ? STDIN_FILENO : open(file_name, O_RDONLY);
+       size_t text_size = 0;
+       size_t total_read = 0;
+       size_t bytes;
 
-       if (fd < 0) {
-               return NULL;
-       }
+       while (1) {
+               if (total_read + CHUNK + 1 > text_size) {
+                       text_size = text_size ? text_size * 2 : CHUNK + 1;
+                       text = reralloc_size (ctx, text, text_size);
+                       if (text == NULL) {
+                               fprintf (stderr, "Out of memory\n");
+                               return NULL;
+                       }
+               }
+               bytes = fread (text + total_read, 1, CHUNK, fp);
+               total_read += bytes;
 
-       if (fstat(fd, & st) == 0) {
-               text = (char *) talloc_size(ctx, st.st_size + 1);
-               if (text != NULL) {
-                       do {
-                               ssize_t bytes = read(fd, text + total_read,
-                                                    st.st_size - total_read);
-                               if (bytes < 0) {
-                                       text = NULL;
-                                       break;
-                               }
-
-                               if (bytes == 0) {
-                                       break;
-                               }
-
-                               total_read += bytes;
-                       } while (total_read < st.st_size);
-
-                       text[total_read] = '\0';
+               if (bytes < CHUNK) {
+                       break;
                }
        }
 
-       close(fd);
+       text[total_read] = '\0';
+
+       return text;
+}
+
+static char *
+load_text_file(void *ctx, const char *filename)
+{
+       char *text;
+       FILE *fp;
+
+       if (filename == NULL || strcmp (filename, "-") == 0)
+               return load_text_fp (ctx, stdin);
+
+       fp = fopen (filename, "r");
+       if (fp == NULL) {
+               fprintf (stderr, "Failed to open file %s: %s\n",
+                        filename, strerror (errno));
+               return NULL;
+       }
+
+       text = load_text_fp (ctx, fp);
+
+       fclose(fp);
 
        return text;
 }
 
+/* Initialize only those things that glcpp cares about.
+ */
+static void
+init_fake_gl_context (struct gl_context *gl_ctx)
+{
+       gl_ctx->API = API_OPENGL_COMPAT;
+       gl_ctx->Const.DisableGLSLLineContinuations = false;
+}
+
+static void
+usage (void)
+{
+       fprintf (stderr,
+                "Usage: glcpp [OPTIONS] [--] [<filename>]\n"
+                "\n"
+                "Pre-process the given filename (stdin if no filename given).\n"
+                "The following options are supported:\n"
+                "    --disable-line-continuations      Do not interpret lines ending with a\n"
+                "                                      backslash ('\\') as a line continuation.\n");
+}
+
+enum {
+       DISABLE_LINE_CONTINUATIONS_OPT = CHAR_MAX + 1
+};
+
+const static struct option
+long_options[] = {
+       {"disable-line-continuations", no_argument, 0, DISABLE_LINE_CONTINUATIONS_OPT },
+       {0,                            0,           0, 0 }
+};
+
 int
-main (void)
+main (int argc, char *argv[])
 {
-       void *ctx = talloc(NULL, void*);
-       const char *shader = load_text_file(ctx, NULL);
-       char *info_log = talloc_strdup(ctx, "");
-       int ret = preprocess(ctx, &shader, &info_log, NULL);
+       char *filename = NULL;
+       void *ctx = ralloc(NULL, void*);
+       char *info_log = ralloc_strdup(ctx, "");
+       const char *shader;
+       int ret;
+       struct gl_context gl_ctx;
+       int c;
+
+       init_fake_gl_context (&gl_ctx);
+
+       while ((c = getopt_long(argc, argv, "", long_options, NULL)) != -1) {
+               switch (c) {
+               case DISABLE_LINE_CONTINUATIONS_OPT:
+                       gl_ctx.Const.DisableGLSLLineContinuations = true;
+                       break;
+               default:
+                       usage ();
+                       exit (1);
+               }
+       }
+
+       if (optind + 1 < argc) {
+               printf ("Unexpected argument: %s\n", argv[optind+1]);
+               usage ();
+               exit (1);
+       }
+       if (optind < argc) {
+               filename = argv[optind];
+       }
+
+       shader = load_text_file (ctx, filename);
+       if (shader == NULL)
+          return 1;
+
+       ret = glcpp_preprocess(ctx, &shader, &info_log, NULL, &gl_ctx);
 
        printf("%s", shader);
        fprintf(stderr, "%s", info_log);
 
-       talloc_free(ctx);
+       ralloc_free(ctx);
 
        return ret;
 }