OSDN Git Service

89728ffc67a331457e8c0fc4d5a4e1c3edb1a8a9
[android-x86/external-mesa.git] / src / compiler / glsl / glcpp / glcpp.c
1 /*
2  * Copyright © 2010 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <getopt.h>
28
29 #include "glcpp.h"
30 #include "main/shaderobj.h"
31 #include "util/strtod.h"
32
33 extern int glcpp_parser_debug;
34
35 void
36 _mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
37                        struct gl_shader *sh)
38 {
39    (void) ctx;
40    *ptr = sh;
41 }
42
43 /* Read from fp until EOF and return a string of everything read.
44  */
45 static char *
46 load_text_fp (void *ctx, FILE *fp)
47 {
48 #define CHUNK 4096
49         char *text = NULL;
50         size_t text_size = 0;
51         size_t total_read = 0;
52         size_t bytes;
53
54         while (1) {
55                 if (total_read + CHUNK + 1 > text_size) {
56                         text_size = text_size ? text_size * 2 : CHUNK + 1;
57                         text = reralloc_size (ctx, text, text_size);
58                         if (text == NULL) {
59                                 fprintf (stderr, "Out of memory\n");
60                                 return NULL;
61                         }
62                 }
63                 bytes = fread (text + total_read, 1, CHUNK, fp);
64                 total_read += bytes;
65
66                 if (bytes < CHUNK) {
67                         break;
68                 }
69         }
70
71         text[total_read] = '\0';
72
73         return text;
74 }
75
76 static char *
77 load_text_file(void *ctx, const char *filename)
78 {
79         char *text;
80         FILE *fp;
81
82         if (filename == NULL || strcmp (filename, "-") == 0)
83                 return load_text_fp (ctx, stdin);
84
85         fp = fopen (filename, "r");
86         if (fp == NULL) {
87                 fprintf (stderr, "Failed to open file %s: %s\n",
88                          filename, strerror (errno));
89                 return NULL;
90         }
91
92         text = load_text_fp (ctx, fp);
93
94         fclose(fp);
95
96         return text;
97 }
98
99 /* Initialize only those things that glcpp cares about.
100  */
101 static void
102 init_fake_gl_context (struct gl_context *gl_ctx)
103 {
104         gl_ctx->API = API_OPENGL_COMPAT;
105         gl_ctx->Const.DisableGLSLLineContinuations = false;
106 }
107
108 static void
109 usage (void)
110 {
111         fprintf (stderr,
112                  "Usage: glcpp [OPTIONS] [--] [<filename>]\n"
113                  "\n"
114                  "Pre-process the given filename (stdin if no filename given).\n"
115                  "The following options are supported:\n"
116                  "    --disable-line-continuations      Do not interpret lines ending with a\n"
117                  "                                      backslash ('\\') as a line continuation.\n");
118 }
119
120 enum {
121         DISABLE_LINE_CONTINUATIONS_OPT = CHAR_MAX + 1
122 };
123
124 static const struct option
125 long_options[] = {
126         {"disable-line-continuations", no_argument, 0, DISABLE_LINE_CONTINUATIONS_OPT },
127         {"debug",                      no_argument, 0, 'd'},
128         {0,                            0,           0, 0 }
129 };
130
131 int
132 main (int argc, char *argv[])
133 {
134         char *filename = NULL;
135         void *ctx = ralloc(NULL, void*);
136         char *info_log = ralloc_strdup(ctx, "");
137         const char *shader;
138         int ret;
139         struct gl_context gl_ctx;
140         int c;
141
142         init_fake_gl_context (&gl_ctx);
143
144         while ((c = getopt_long(argc, argv, "d", long_options, NULL)) != -1) {
145                 switch (c) {
146                 case DISABLE_LINE_CONTINUATIONS_OPT:
147                         gl_ctx.Const.DisableGLSLLineContinuations = true;
148                         break;
149                 case 'd':
150                         glcpp_parser_debug = 1;
151                         break;
152                 default:
153                         usage ();
154                         exit (1);
155                 }
156         }
157
158         if (optind + 1 < argc) {
159                 printf ("Unexpected argument: %s\n", argv[optind+1]);
160                 usage ();
161                 exit (1);
162         }
163         if (optind < argc) {
164                 filename = argv[optind];
165         }
166
167         shader = load_text_file (ctx, filename);
168         if (shader == NULL)
169            return 1;
170
171         _mesa_locale_init();
172
173         ret = glcpp_preprocess(ctx, &shader, &info_log, NULL, NULL, &gl_ctx);
174
175         printf("%s", shader);
176         fprintf(stderr, "%s", info_log);
177
178         ralloc_free(ctx);
179
180         return ret;
181 }