cmake: move defaults into the per-platform section
[piglit.git] / tests / shaders / parser_utils.c
blobc3e6130d1ea3b437e00577b9972a0a017855d422
1 /*
2 * Copyright © 2016 Intel Corporation
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:
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.
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.
23 #include <string.h>
24 #include <ctype.h>
25 #include "parser_utils.h"
27 bool
28 parse_whitespace(const char *s, const char **rest)
30 const char *end = s;
31 for (; *end && *end != '\n' && isspace(*end); end++);
33 if (rest)
34 *rest = end;
36 return end != s;
39 bool
40 parse_str(const char *s, const char *lit, const char **rest)
42 const char *t;
43 parse_whitespace(s, &t);
44 const bool ret = strncmp(t, lit, strlen(lit)) == 0;
46 if (rest)
47 *rest = (ret ? t + strlen(lit) : s);
49 return ret;
52 unsigned
53 parse_ints(const char *s, int *i, unsigned n, const char **rest)
55 const char *end = s;
56 unsigned j;
58 for (j = 0; j < n; j++) {
59 int v = strtoll(s = end, (char **)&end, 0);
60 if (s == end)
61 break;
62 i[j] = v;
65 if (rest)
66 *rest = end;
68 return j;
71 unsigned
72 parse_uints(const char *s, unsigned *u, unsigned n, const char **rest)
74 const char *end = s;
75 unsigned j;
77 for (j = 0; j < n; j++) {
78 unsigned v = strtoul(s = end, (char **)&end, 0);
79 if (s == end)
80 break;
81 u[j] = v;
84 if (rest)
85 *rest = end;
87 return j;
90 unsigned
91 parse_int64s(const char *s, int64_t *i, unsigned n, const char **rest)
93 const char *end = s;
94 unsigned j;
96 for (j = 0; j < n; j++) {
97 int64_t v;
99 s = end;
100 while (isspace(s[0]))
101 s++;
103 /* If the user specified a raw hex value, just parse the raw
104 * bit pattern. Hex values that represent negative numbers
105 * would be clamped to INT64_MAX by strtoll (and errno would
106 * be set to ERANGE).
108 errno = 0;
109 if (strncmp("0x", s, 2) == 0)
110 v = (int64_t) strtoull(s, (char **)&end, 0);
111 else
112 v = strtoll(s, (char **)&end, 0);
114 assert(errno == 0);
116 if (s == end)
117 break;
118 i[j] = v;
121 if (rest)
122 *rest = end;
124 return j;
127 unsigned
128 parse_uint64s(const char *s, uint64_t *u, unsigned n, const char **rest)
130 const char *end = s;
131 unsigned j;
133 for (j = 0; j < n; j++) {
134 uint64_t v = strtoull(s = end, (char **)&end, 0);
135 if (s == end)
136 break;
137 u[j] = v;
140 if (rest)
141 *rest = end;
143 return j;
146 unsigned
147 parse_floats(const char *s, float *f, unsigned n, const char **rest)
149 const char *end = s;
150 unsigned j;
152 for (j = 0; j < n; j++) {
153 float v = strtof_hex(s = end, (char **)&end);
154 if (s == end)
155 break;
156 f[j] = v;
159 if (rest)
160 *rest = end;
162 return j;
165 unsigned
166 parse_doubles(const char *s, double *d, unsigned n, const char **rest)
168 const char *end = s;
169 unsigned j;
171 for (j = 0; j < n; j++) {
172 double v = strtod_hex(s = end, (char **)&end);
173 if (s == end)
174 break;
175 d[j] = v;
178 if (rest)
179 *rest = end;
181 return j;
184 bool
185 parse_word(const char *s, const char **t, const char **rest)
187 parse_whitespace(s, t);
189 const char *end = *t;
190 for (; *end && !isspace(*end); end++);
192 if (rest)
193 *rest = (*t != end ? end : s);
195 return *t != end;
198 bool
199 parse_word_copy(const char *s, char *t, unsigned n, const char **rest)
201 const char *start, *end;
202 const bool ret = parse_word(s, &start, &end) && end - start < n;
204 if (ret) {
205 memcpy(t, start, end - start);
206 t[end - start] = 0;
208 if (rest)
209 *rest = (ret ? end : s);
211 return ret;
214 bool
215 parse_enum_gl(const char *s, GLenum *e, const char **rest)
217 char name[512];
218 const bool ret = parse_word_copy(s, name, sizeof(name), rest);
219 *e = (ret ? piglit_get_gl_enum_from_name(name) : GL_NONE);
220 return ret;
223 bool
224 parse_enum_tab(const struct string_to_enum *tab,
225 const char *s, unsigned *e, const char **rest)
227 const char *end = s;
228 bool ret = parse_word(s, &s, &end);
229 unsigned i = 0;
231 if (ret) {
232 for (i = 0; tab[i].name; i++) {
233 if (!strncmp(tab[i].name, s, end - s) &&
234 !tab[i].name[end - s])
235 break;
238 *e = tab[i].value;
239 ret = tab[i].name;
242 if (rest)
243 *rest = (ret ? end : s);
245 return ret;
248 bool
249 parse_tex_target(const char *s, unsigned *t, const char **rest)
251 static const struct string_to_enum tab[] = {
252 { "1D", GL_TEXTURE_1D },
253 { "2D", GL_TEXTURE_2D },
254 { "3D", GL_TEXTURE_3D },
255 { "Rect", GL_TEXTURE_RECTANGLE },
256 { "Cube", GL_TEXTURE_CUBE_MAP },
257 { "1DArray", GL_TEXTURE_1D_ARRAY },
258 { "2DArray", GL_TEXTURE_2D_ARRAY },
259 { "CubeArray", GL_TEXTURE_CUBE_MAP_ARRAY },
260 { NULL, 0 }
262 return parse_enum_tab(tab, s, t, rest);
265 bool
266 parse_comparison_op(const char *s, enum comparison *t, const char **rest)
268 if (parse_str(s, "==", rest)) {
269 *t = equal;
270 return true;
271 } else if (parse_str(s, "!=", rest)) {
272 *t = greater;
273 return true;
274 } else if (parse_str(s, "<=", rest)) {
275 *t = less_equal;
276 return true;
277 } else if (parse_str(s, "<", rest)) {
278 *t = less;
279 return true;
280 } else if (parse_str(s, ">=", rest)) {
281 *t = greater_equal;
282 return true;
283 } else if (parse_str(s, ">", rest)) {
284 *t = greater;
285 return true;
286 } else {
287 return false;