blob: a545a2e21d8dac41e35907eb8a32b42196628456 [file] [log] [blame]
Jason Sams135c4b72013-12-11 18:24:45 -08001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdio.h>
18#include <vector>
19#include <list>
20#include <string>
21
22using namespace std;
23
24FILE *gIn;
25FILE *gOut;
26
27class Func {
28public:
29 Func() {
30 mMinVersion = 0;
31 mMaxVersion = 0;
32 }
33
34 string mName;
35 int mMinVersion;
36 int mMaxVersion;
37
38 vector<vector<string> > mReplaceables;
39 vector<string> mArgs;
40 string mRet;
41 vector<string> mComment;
42 vector<string> mInline;
43
44};
45
46vector<Func *> gFuncs;
47
48bool getNextLine(FILE *in, string *s) {
49 s->clear();
50 while (1) {
51 int c = fgetc(in);
52 if (c == EOF) return s->size() != 0;
53 if (c == '\n') break;
54 s->push_back((char)c);
55 }
56 return true;
57}
58
59void trim(string *s, size_t start) {
60 if (start > 0) {
61 s->erase(0, start);
62 }
63
64 while (s->size() && (s->at(0) == ' ')) {
65 s->erase(0, 1);
66 }
67
68 size_t p = s->find_first_of("\n\r");
69 if (p != string::npos) {
70 s->erase(p);
71 }
72
73 while ((s->size() > 0) && (s->at(s->size()-1) == ' ')) {
74 s->erase(s->size() -1);
75 }
76}
77
78Func * scanFunction(FILE *in) {
79 Func *f = new Func();
80 bool modeComment = false;
81 bool modeInline = false;
82 size_t replacables = 0;
83
84 while (1) {
85 string s;
86 bool ret = getNextLine(in, &s);
87 if (!ret) break;
88
89 if (modeComment) {
90 if (!s.size() || (s[0] == ' ')) {
91 trim(&s, 0);
92 f->mComment.push_back(s);
93 continue;
94 } else {
95 modeComment = false;
96 }
97 }
98
99 if (modeInline) {
100 if (!s.size() || (s[0] == ' ')) {
101 trim(&s, 0);
102 f->mInline.push_back(s);
103 continue;
104 } else {
105 modeInline = false;
106 }
107 }
108
109 if (s[0] == '#') {
110 continue;
111 }
112
113 if (s.compare(0, 5, "name:") == 0) {
114 trim(&s, 5);
115 f->mName = s;
116 continue;
117 }
118
119 if (s.compare(0, 4, "arg:") == 0) {
120 trim(&s, 4);
121 f->mArgs.push_back(s);
122 continue;
123 }
124
125 if (s.compare(0, 4, "ret:") == 0) {
126 trim(&s, 4);
127 f->mRet = s;
128 continue;
129 }
130
131 if (s.compare(0, 4, "end:") == 0) {
132 return f;
133 }
134
135 if (s.compare(0, 8, "comment:") == 0) {
136 modeComment = true;
137 continue;
138 }
139
140 if (s.compare(0, 7, "inline:") == 0) {
141 modeInline = true;
142 continue;
143 }
144
145 if (s.compare(0, 8, "version:") == 0) {
146 trim(&s, 8);
147 sscanf(s.c_str(), "%i %i", &f->mMinVersion, &f->mMaxVersion);
148 continue;
149 }
150
151 if (s.compare(0, 8, "start:") == 0) {
152 continue;
153 }
154
155 if (s.compare(0, 2, "w:") == 0) {
156 vector<string> t;
157 if (s.find("1") != string::npos) {
158 t.push_back("");
159 }
160 if (s.find("2") != string::npos) {
161 t.push_back("2");
162 }
163 if (s.find("3") != string::npos) {
164 t.push_back("3");
165 }
166 if (s.find("4") != string::npos) {
167 t.push_back("4");
168 }
169 f->mReplaceables.push_back(t);
170 continue;
171 }
172
173 if (s.compare(0, 2, "t:") == 0) {
174 vector<string> t;
175 if (s.find("f16") != string::npos) {
176 t.push_back("half");
177 }
178 if (s.find("f32") != string::npos) {
179 t.push_back("float");
180 }
181 if (s.find("f64") != string::npos) {
182 t.push_back("double");
183 }
184 if (s.find("i8") != string::npos) {
185 t.push_back("char");
186 }
187 if (s.find("u8") != string::npos) {
188 t.push_back("uchar");
189 }
190 if (s.find("i16") != string::npos) {
191 t.push_back("short");
192 }
193 if (s.find("u16") != string::npos) {
194 t.push_back("ushort");
195 }
196 if (s.find("i32") != string::npos) {
197 t.push_back("int");
198 }
199 if (s.find("u32") != string::npos) {
200 t.push_back("uint");
201 }
202 if (s.find("i64") != string::npos) {
203 t.push_back("long");
204 }
205 if (s.find("u64") != string::npos) {
206 t.push_back("ulong");
207 }
208 f->mReplaceables.push_back(t);
209 continue;
210 }
211
212 if (s.size() == 0) {
213 // eat empty line
214 continue;
215 }
216
217 printf("Error, line:\n");
218 printf(" %s\n", s.c_str());
219 }
220
221 delete f;
222 return NULL;
223}
224
225string stringReplace(string s, string match, string rep) {
226 while(1) {
227 size_t p = s.find(match);
228 if (p == string::npos) break;
229
230 s.erase(p, match.size());
231 s.insert(p, rep);
232 }
233 return s;
234}
235
236string stringExpand(string s, const Func *f, int i1, int i2, int i3, int i4) {
237 if (f->mReplaceables.size() > 0) {
238 s = stringReplace(s, "#1", f->mReplaceables[0][i1]);
239 }
240 if (f->mReplaceables.size() > 1) {
241 s = stringReplace(s, "#2", f->mReplaceables[1][i2]);
242 }
243 if (f->mReplaceables.size() > 2) {
244 s = stringReplace(s, "#3", f->mReplaceables[2][i3]);
245 }
246 if (f->mReplaceables.size() > 3) {
247 s = stringReplace(s, "#4", f->mReplaceables[3][i4]);
248 }
249 return s;
250}
251
252void writeHeaderFunc(FILE *o, const Func *f, int i1, int i2, int i3, int i4) {
253 string s;
254
255 if (f->mMinVersion || f->mMaxVersion) {
256 if (f->mMaxVersion) {
257 fprintf(o, "#if (defined(RS_VERSION) && (RS_VERSION >= %i) && (RS_VERSION < %i))\n",
258 f->mMinVersion, f->mMaxVersion);
259 } else {
260 fprintf(o, "#if (defined(RS_VERSION) && (RS_VERSION >= %i))\n",
261 f->mMinVersion);
262 }
263 }
264
265 fprintf(o, "/*\n");
266 for (size_t ct=0; ct < f->mComment.size(); ct++) {
267 s = stringExpand(f->mComment[ct], f, i1, i2, i3, i4);
268 if (s.size()) {
269 fprintf(o, " * %s\n", s.c_str());
270 } else {
271 fprintf(o, " *\n");
272 }
273 }
274 fprintf(o, " *\n");
275 if (f->mMinVersion || f->mMaxVersion) {
276 if (f->mMaxVersion) {
277 fprintf(o, " * Suppored by API versions %i - %i\n",
278 f->mMinVersion, f->mMaxVersion);
279 } else {
280 fprintf(o, " * Supported by API versions %i and newer.\n",
281 f->mMinVersion);
282 }
283 }
284
285 fprintf(o, " */\n");
286
287 s.clear();
288 s += "extern ";
289 s += f->mRet;
290 s += " __attribute__((const, overloadable))";
291 s += f->mName;
292 s += "(";
293 if (f->mArgs.size()) {
294 s += f->mArgs[0];
295 }
296 for (size_t ct=1; ct < f->mArgs.size(); ct++) {
297 s += ", ";
298 s += f->mArgs[0];
299 }
300 s += ");";
301 s = stringExpand(s, f, i1, i2, i3, i4);
302 fprintf(o, "%s\n", s.c_str());
303
304
305 if (f->mMinVersion || f->mMaxVersion) {
306 fprintf(o, "#endif\n");
307 }
308
309 fprintf(o, "\n", s.c_str());
310}
311
312
313void writeHeaderFuncs(FILE *o, const Func *f) {
314 switch(f->mReplaceables.size()) {
315 case 0:
316 writeHeaderFunc(o, f, -1, -1, -1, -1);
317 break;
318 case 1:
319 for (size_t i1 = 0; i1 < f->mReplaceables[0].size(); i1++) {
320 writeHeaderFunc(o, f, i1, -1, -1, -1);
321 }
322 break;
323 case 2:
324 for (size_t i2 = 0; i2 < f->mReplaceables[1].size(); i2++) {
325 for (size_t i1 = 0; i1 < f->mReplaceables[0].size(); i1++) {
326 writeHeaderFunc(o, f, i1, i2, -1, -1);
327 }
328 }
329 break;
330 case 3:
331 for (size_t i3 = 0; i3 < f->mReplaceables[2].size(); i3++) {
332 for (size_t i2 = 0; i2 < f->mReplaceables[1].size(); i2++) {
333 for (size_t i1 = 0; i1 < f->mReplaceables[0].size(); i1++) {
334 writeHeaderFunc(o, f, i1, i2, i3, -1);
335 }
336 }
337 }
338 break;
339 case 4:
340 for (size_t i4 = 0; i4 < f->mReplaceables[3].size(); i4++) {
341 for (size_t i3 = 0; i3 < f->mReplaceables[2].size(); i3++) {
342 for (size_t i2 = 0; i2 < f->mReplaceables[1].size(); i2++) {
343 for (size_t i1 = 0; i1 < f->mReplaceables[0].size(); i1++) {
344 writeHeaderFunc(o, f, i1, i2, i3, i4);
345 }
346 }
347 }
348 }
349 break;
350 }
351}
352
353
354
355int main(int argc, char* argv[])
356{
357 const char *inpath = "runtime.spec";
358 const char *outpath = "rs_core_math.rsh";
359
360 gIn = fopen(inpath, "rt");
361 if (!gIn) {
362 printf("Error opening input file: %s", inpath);
363 return -1;
364 }
365
366 while (1) {
367 Func *f = scanFunction(gIn);
368 if (f != NULL) {
369 gFuncs.push_back(f);
370 } else {
371 break;
372 }
373 }
374
375 gOut = fopen(outpath, "wt");
376 if (!gOut) {
377 printf("Error opening output file: %s", outpath);
378 return -1;
379 }
380
381 for (size_t ct=0; ct < gFuncs.size(); ct++) {
382 writeHeaderFuncs(gOut, gFuncs[ct]);
383 }
384
385 fclose (gIn);
386 fclose (gOut);
387
388 printf("%i Functions processed.\n", (int)gFuncs.size());
389
390 return 0;
391}
392
393