1
2#include "spec.h"
3#include <stdio.h>
4#include <string.h>
5
6void printFileHeader(FILE *f) {
7    fprintf(f, "/*\n");
8    fprintf(f, " * Copyright (C) 2011 The Android Open Source Project\n");
9    fprintf(f, " *\n");
10    fprintf(f, " * Licensed under the Apache License, Version 2.0 (the \"License\");\n");
11    fprintf(f, " * you may not use this file except in compliance with the License.\n");
12    fprintf(f, " * You may obtain a copy of the License at\n");
13    fprintf(f, " *\n");
14    fprintf(f, " *      http://www.apache.org/licenses/LICENSE-2.0\n");
15    fprintf(f, " *\n");
16    fprintf(f, " * Unless required by applicable law or agreed to in writing, software\n");
17    fprintf(f, " * distributed under the License is distributed on an \"AS IS\" BASIS,\n");
18    fprintf(f, " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n");
19    fprintf(f, " * See the License for the specific language governing permissions and\n");
20    fprintf(f, " * limitations under the License.\n");
21    fprintf(f, " */\n\n");
22}
23
24void printVarType(FILE *f, const VarType *vt) {
25    int ct;
26    if (vt->isConst) {
27        fprintf(f, "const ");
28    }
29
30    switch (vt->type) {
31    case 0:
32        fprintf(f, "void");
33        break;
34    case 1:
35        fprintf(f, "int%i_t", vt->bits);
36        break;
37    case 2:
38        fprintf(f, "uint%i_t", vt->bits);
39        break;
40    case 3:
41        if (vt->bits == 32)
42            fprintf(f, "float");
43        else
44            fprintf(f, "double");
45        break;
46    case 4:
47        fprintf(f, "%s", vt->typeName);
48        break;
49    }
50
51    if (vt->ptrLevel) {
52        fprintf(f, " ");
53        for (ct=0; ct < vt->ptrLevel; ct++) {
54            fprintf(f, "*");
55        }
56    }
57}
58
59void printVarTypeAndName(FILE *f, const VarType *vt) {
60    printVarType(f, vt);
61
62    if (vt->name[0]) {
63        fprintf(f, " %s", vt->name);
64    }
65}
66
67void printArgList(FILE *f, const ApiEntry * api, int assumePrevious) {
68    int ct;
69    for (ct=0; ct < api->paramCount; ct++) {
70        if (ct || assumePrevious) {
71            fprintf(f, ", ");
72        }
73        printVarTypeAndName(f, &api->params[ct]);
74    }
75}
76
77void printStructures(FILE *f) {
78    int ct;
79    int ct2;
80
81    for (ct=0; ct < apiCount; ct++) {
82        fprintf(f, "typedef struct RS_CMD_%s_rec RS_CMD_%s;\n", apis[ct].name, apis[ct].name);
83    }
84    fprintf(f, "\n");
85
86    for (ct=0; ct < apiCount; ct++) {
87        const ApiEntry * api = &apis[ct];
88        fprintf(f, "#define RS_CMD_ID_%s %i\n", api->name, ct+1);
89        fprintf(f, "struct RS_CMD_%s_rec {\n", api->name);
90        //fprintf(f, "    RsCommandHeader _hdr;\n");
91
92        for (ct2=0; ct2 < api->paramCount; ct2++) {
93            fprintf(f, "    ");
94            printVarTypeAndName(f, &api->params[ct2]);
95            fprintf(f, ";\n");
96        }
97        fprintf(f, "};\n\n");
98    }
99}
100
101void printFuncDecl(FILE *f, const ApiEntry *api, const char *prefix, int addContext, int isFnPtr) {
102    printVarTypeAndName(f, &api->ret);
103    if (isFnPtr) {
104        char t[1024];
105        strcpy(t, api->name);
106        if (strlen(prefix) == 0) {
107            if (t[0] > 'A' && t[0] < 'Z') {
108                t[0] -= 'A' - 'a';
109            }
110        }
111        fprintf(f, " (* %s%s) (", prefix, api->name);
112    } else {
113        fprintf(f, " %s%s (", prefix, api->name);
114    }
115    if (!api->nocontext) {
116        if (addContext) {
117            fprintf(f, "Context *");
118        } else {
119            fprintf(f, "RsContext rsc");
120        }
121    }
122    printArgList(f, api, !api->nocontext);
123    fprintf(f, ")");
124}
125
126void printFuncDecls(FILE *f, const char *prefix, int addContext) {
127    int ct;
128    for (ct=0; ct < apiCount; ct++) {
129        printFuncDecl(f, &apis[ct], prefix, addContext, 0);
130        fprintf(f, ";\n");
131    }
132    fprintf(f, "\n\n");
133}
134
135void printFuncPointers(FILE *f, int addContext) {
136    fprintf(f, "\n");
137    fprintf(f, "typedef struct RsApiEntrypoints {\n");
138    int ct;
139    for (ct=0; ct < apiCount; ct++) {
140        fprintf(f, "    ");
141        printFuncDecl(f, &apis[ct], "", addContext, 1);
142        fprintf(f, ";\n");
143    }
144    fprintf(f, "} RsApiEntrypoints_t;\n\n");
145}
146
147void printPlaybackFuncs(FILE *f, const char *prefix) {
148    int ct;
149    for (ct=0; ct < apiCount; ct++) {
150        if (apis[ct].direct) {
151            continue;
152        }
153
154        fprintf(f, "void %s%s (Context *, const void *);\n", prefix, apis[ct].name);
155    }
156}
157
158static int hasInlineDataPointers(const ApiEntry * api) {
159    int ret = 0;
160    int ct;
161    if (api->sync || api->ret.typeName[0]) {
162        return 0;
163    }
164    for (ct=0; ct < api->paramCount; ct++) {
165        const VarType *vt = &api->params[ct];
166
167        if (!vt->isConst && vt->ptrLevel) {
168            // Non-const pointers cannot be inlined.
169            return 0;
170        }
171        if (vt->ptrLevel > 1) {
172            // not handled yet.
173            return 0;
174        }
175
176        if (vt->isConst && vt->ptrLevel) {
177            // Non-const pointers cannot be inlined.
178            ret = 1;
179        }
180    }
181    return ret;
182}
183
184void printApiCpp(FILE *f) {
185    int ct;
186    int ct2;
187
188    fprintf(f, "#include \"rsDevice.h\"\n");
189    fprintf(f, "#include \"rsContext.h\"\n");
190    fprintf(f, "#include \"rsThreadIO.h\"\n");
191    fprintf(f, "#include \"rsgApiStructs.h\"\n");
192    fprintf(f, "#include \"rsgApiFuncDecl.h\"\n");
193    fprintf(f, "#include \"rsFifo.h\"\n");
194    fprintf(f, "\n");
195    fprintf(f, "using namespace android;\n");
196    fprintf(f, "using namespace android::renderscript;\n");
197    fprintf(f, "\n");
198
199    printFuncPointers(f, 0);
200
201    // Generate RS funcs for local fifo
202    for (ct=0; ct < apiCount; ct++) {
203        int needFlush = 0;
204        const ApiEntry * api = &apis[ct];
205
206        fprintf(f, "static ");
207        printFuncDecl(f, api, "LF_", 0, 0);
208        fprintf(f, "\n{\n");
209        if (api->direct) {
210            fprintf(f, "    ");
211            if (api->ret.typeName[0]) {
212                fprintf(f, "return ");
213            }
214            fprintf(f, "rsi_%s(", api->name);
215            if (!api->nocontext) {
216                fprintf(f, "(Context *)rsc");
217            }
218            for (ct2=0; ct2 < api->paramCount; ct2++) {
219                const VarType *vt = &api->params[ct2];
220                if (ct2 > 0 || !api->nocontext) {
221                    fprintf(f, ", ");
222                }
223                fprintf(f, "%s", vt->name);
224            }
225            fprintf(f, ");\n");
226        } else {
227            fprintf(f, "    ThreadIO *io = &((Context *)rsc)->mIO;\n");
228            fprintf(f, "    const uint32_t size = sizeof(RS_CMD_%s);\n", api->name);
229            if (hasInlineDataPointers(api)) {
230                fprintf(f, "    uint32_t dataSize = 0;\n");
231                for (ct2=0; ct2 < api->paramCount; ct2++) {
232                    const VarType *vt = &api->params[ct2];
233                    if (vt->isConst && vt->ptrLevel) {
234                        fprintf(f, "    dataSize += %s_length;\n", vt->name);
235                    }
236                }
237            }
238
239            //fprintf(f, "    ALOGE(\"add command %s\\n\");\n", api->name);
240            if (hasInlineDataPointers(api)) {
241                fprintf(f, "    RS_CMD_%s *cmd = NULL;\n", api->name);
242                fprintf(f, "    if (dataSize < io->getMaxInlineSize()) {;\n");
243                fprintf(f, "        cmd = static_cast<RS_CMD_%s *>(io->coreHeader(RS_CMD_ID_%s, dataSize + size));\n", api->name, api->name);
244                fprintf(f, "    } else {\n");
245                fprintf(f, "        cmd = static_cast<RS_CMD_%s *>(io->coreHeader(RS_CMD_ID_%s, size));\n", api->name, api->name);
246                fprintf(f, "    }\n");
247                fprintf(f, "    uint8_t *payload = (uint8_t *)&cmd[1];\n");
248            } else {
249                fprintf(f, "    RS_CMD_%s *cmd = static_cast<RS_CMD_%s *>(io->coreHeader(RS_CMD_ID_%s, size));\n", api->name, api->name, api->name);
250            }
251
252            for (ct2=0; ct2 < api->paramCount; ct2++) {
253                const VarType *vt = &api->params[ct2];
254                needFlush += vt->ptrLevel;
255                if (vt->ptrLevel && hasInlineDataPointers(api)) {
256                    fprintf(f, "    if (dataSize < io->getMaxInlineSize()) {\n");
257                    fprintf(f, "        memcpy(payload, %s, %s_length);\n", vt->name, vt->name);
258                    fprintf(f, "        cmd->%s = (", vt->name);
259                    printVarType(f, vt);
260                    fprintf(f, ")(payload - ((uint8_t *)&cmd[1]));\n");
261                    fprintf(f, "        payload += %s_length;\n", vt->name);
262                    fprintf(f, "    } else {\n");
263                    fprintf(f, "        cmd->%s = %s;\n", vt->name, vt->name);
264                    fprintf(f, "    }\n");
265
266                } else {
267                    fprintf(f, "    cmd->%s = %s;\n", vt->name, vt->name);
268                }
269            }
270            if (api->ret.typeName[0] || api->sync) {
271                needFlush = 1;
272            }
273
274            fprintf(f, "    io->coreCommit();\n");
275            if (hasInlineDataPointers(api)) {
276                fprintf(f, "    if (dataSize >= io->getMaxInlineSize()) {\n");
277                fprintf(f, "        io->coreGetReturn(NULL, 0);\n");
278                fprintf(f, "    }\n");
279            } else if (api->ret.typeName[0]) {
280                fprintf(f, "\n    ");
281                printVarType(f, &api->ret);
282                fprintf(f, " ret;\n");
283                fprintf(f, "    io->coreGetReturn(&ret, sizeof(ret));\n");
284                fprintf(f, "    return ret;\n");
285            } else if (needFlush) {
286                fprintf(f, "    io->coreGetReturn(NULL, 0);\n");
287            }
288        }
289        fprintf(f, "};\n\n");
290
291
292        // Generate a remote sender function
293        const char * str = "core";
294        if (api->direct) {
295            str = "async";
296        }
297
298        fprintf(f, "static ");
299        printFuncDecl(f, api, "RF_", 0, 0);
300        fprintf(f, "\n{\n");
301        fprintf(f, "    ThreadIO *io = &((Context *)rsc)->mIO;\n");
302        fprintf(f, "    const uint32_t cmdID = RS_CMD_ID_%s;\n", api->name);
303        fprintf(f, "    io->%sWrite(&cmdID, sizeof(cmdID));\n\n", str);
304
305        for (ct2=0; ct2 < api->paramCount; ct2++) {
306            const VarType *vt = &api->params[ct2];
307            if (vt->ptrLevel == 0) {
308                fprintf(f, "    io->%sWrite(& %s, sizeof(%s));\n", str, vt->name, vt->name);
309            }
310        }
311        fprintf(f, "\n");
312
313        for (ct2=0; ct2 < api->paramCount; ct2++) {
314            const VarType *vt = &api->params[ct2];
315            if ((vt->ptrLevel == 1) && (vt->isConst)) {
316                fprintf(f, "    io->%sWrite(%s, %s_length);\n", str, vt->name, vt->name);
317            }
318        }
319        fprintf(f, "\n");
320
321        for (ct2=0; ct2 < api->paramCount; ct2++) {
322            const VarType *vt = &api->params[ct2];
323            if ((vt->ptrLevel == 2) && (vt->isConst)) {
324                fprintf(f, "    for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name);
325                fprintf(f, "        io->%sWrite(%s[ct], %s_length[ct]);\n", str, vt->name, vt->name);
326                fprintf(f, "    }\n");
327            }
328        }
329        fprintf(f, "\n");
330
331        for (ct2=0; ct2 < api->paramCount; ct2++) {
332            const VarType *vt = &api->params[ct2];
333            if ((vt->ptrLevel == 1) && (!vt->isConst)) {
334                fprintf(f, "    io->%sGetReturn(%s, %s_length);\n", str, vt->name, vt->name);
335            }
336        }
337        fprintf(f, "\n");
338
339        for (ct2=0; ct2 < api->paramCount; ct2++) {
340            const VarType *vt = &api->params[ct2];
341            if ((vt->ptrLevel == 2) && (!vt->isConst)) {
342                fprintf(f, "    for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name);
343                fprintf(f, "        io->%sGetReturn(%s[ct], %s_length[ct]);\n", str, vt->name, vt->name);
344                fprintf(f, "    }\n");
345            }
346        }
347        fprintf(f, "\n");
348
349        if (api->ret.typeName[0]) {
350            fprintf(f, "    ");
351            printVarType(f, &api->ret);
352            fprintf(f, " retValue;\n");
353            fprintf(f, "    io->%sGetReturn(&retValue, sizeof(retValue));\n", str);
354            fprintf(f, "    return retValue;\n");
355        } else /*if (api->sync)*/ {
356            fprintf(f, "    io->%sGetReturn(NULL, 0);\n", str);
357        }
358        fprintf(f, "}\n\n");
359    }
360
361    fprintf(f, "\n");
362    fprintf(f, "static RsApiEntrypoints_t s_LocalTable = {\n");
363    for (ct=0; ct < apiCount; ct++) {
364        fprintf(f, "    LF_%s,\n", apis[ct].name);
365    }
366    fprintf(f, "};\n");
367
368    fprintf(f, "\n");
369    fprintf(f, "static RsApiEntrypoints_t s_RemoteTable = {\n");
370    for (ct=0; ct < apiCount; ct++) {
371        fprintf(f, "    RF_%s,\n", apis[ct].name);
372    }
373    fprintf(f, "};\n");
374
375    fprintf(f, "static RsApiEntrypoints_t *s_CurrentTable = &s_LocalTable;\n\n");
376    for (ct=0; ct < apiCount; ct++) {
377        int needFlush = 0;
378        const ApiEntry * api = &apis[ct];
379
380        printFuncDecl(f, api, "rs", 0, 0);
381        fprintf(f, "\n{\n");
382        fprintf(f, "    ");
383        if (api->ret.typeName[0]) {
384            fprintf(f, "return ");
385        }
386        fprintf(f, "s_CurrentTable->%s(", api->name);
387
388        if (!api->nocontext) {
389            fprintf(f, "(Context *)rsc");
390        }
391
392        for (ct2=0; ct2 < api->paramCount; ct2++) {
393            const VarType *vt = &api->params[ct2];
394            if (ct2 > 0 || !api->nocontext) {
395                fprintf(f, ", ");
396            }
397            fprintf(f, "%s", vt->name);
398        }
399        fprintf(f, ");\n");
400        fprintf(f, "}\n\n");
401    }
402
403}
404
405void printPlaybackCpp(FILE *f) {
406    int ct;
407    int ct2;
408
409    fprintf(f, "#include \"rsDevice.h\"\n");
410    fprintf(f, "#include \"rsContext.h\"\n");
411    fprintf(f, "#include \"rsThreadIO.h\"\n");
412    fprintf(f, "#include \"rsgApiStructs.h\"\n");
413    fprintf(f, "#include \"rsgApiFuncDecl.h\"\n");
414    fprintf(f, "\n");
415    fprintf(f, "namespace android {\n");
416    fprintf(f, "namespace renderscript {\n");
417    fprintf(f, "\n");
418
419    for (ct=0; ct < apiCount; ct++) {
420        const ApiEntry * api = &apis[ct];
421        int needFlush = 0;
422
423        if (api->direct) {
424            continue;
425        }
426
427        fprintf(f, "void rsp_%s(Context *con, const void *vp, size_t cmdSizeBytes) {\n", api->name);
428        fprintf(f, "    const RS_CMD_%s *cmd = static_cast<const RS_CMD_%s *>(vp);\n", api->name, api->name);
429
430        if (hasInlineDataPointers(api)) {
431            fprintf(f, "    const uint8_t *baseData = 0;\n");
432            fprintf(f, "    if (cmdSizeBytes != sizeof(RS_CMD_%s)) {\n", api->name);
433            fprintf(f, "        baseData = &((const uint8_t *)vp)[sizeof(*cmd)];\n");
434            fprintf(f, "    }\n");
435        }
436
437        fprintf(f, "    ");
438        if (api->ret.typeName[0]) {
439            fprintf(f, "\n    ");
440            printVarType(f, &api->ret);
441            fprintf(f, " ret = ");
442        }
443        fprintf(f, "rsi_%s(con", api->name);
444        for (ct2=0; ct2 < api->paramCount; ct2++) {
445            const VarType *vt = &api->params[ct2];
446            needFlush += vt->ptrLevel;
447
448            if (hasInlineDataPointers(api) && vt->ptrLevel) {
449                fprintf(f, ",\n           (const %s *)&baseData[(intptr_t)cmd->%s]", vt->typeName, vt->name);
450            } else {
451                fprintf(f, ",\n           cmd->%s", vt->name);
452            }
453        }
454        fprintf(f, ");\n");
455
456        if (hasInlineDataPointers(api)) {
457            fprintf(f, "    size_t totalSize = 0;\n");
458            for (ct2=0; ct2 < api->paramCount; ct2++) {
459                if (api->params[ct2].ptrLevel) {
460                    fprintf(f, "    totalSize += cmd->%s_length;\n", api->params[ct2].name);
461                }
462            }
463
464            fprintf(f, "    if ((totalSize != 0) && (cmdSizeBytes == sizeof(RS_CMD_%s))) {\n", api->name);
465            fprintf(f, "        con->mIO.coreSetReturn(NULL, 0);\n");
466            fprintf(f, "    }\n");
467        } else if (api->ret.typeName[0]) {
468            fprintf(f, "    con->mIO.coreSetReturn(&ret, sizeof(ret));\n");
469        } else if (api->sync || needFlush) {
470            fprintf(f, "    con->mIO.coreSetReturn(NULL, 0);\n");
471        }
472
473        fprintf(f, "};\n\n");
474    }
475
476    for (ct=0; ct < apiCount; ct++) {
477        const ApiEntry * api = &apis[ct];
478        int needFlush = 0;
479
480        fprintf(f, "void rspr_%s(Context *con, ThreadIO *io) {\n", api->name);
481        fprintf(f, "    RS_CMD_%s cmd;\n", api->name);
482
483        for (ct2=0; ct2 < api->paramCount; ct2++) {
484            const VarType *vt = &api->params[ct2];
485            if (vt->ptrLevel == 0) {
486                fprintf(f, "    io->coreRead(&cmd.%s, sizeof(cmd.%s));\n", vt->name, vt->name);
487            }
488        }
489        fprintf(f, "\n");
490
491        for (ct2=0; ct2 < api->paramCount; ct2++) {
492            const VarType *vt = &api->params[ct2];
493            if (vt->ptrLevel == 1) {
494                fprintf(f, "    cmd.%s = (", vt->name);
495                printVarType(f, vt);
496                fprintf(f, ")malloc(cmd.%s_length);\n", vt->name);
497
498                if (vt->isConst) {
499                    fprintf(f, "    if (cmd.%s_length) io->coreRead((void *)cmd.%s, cmd.%s_length);\n", vt->name, vt->name, vt->name);
500                }
501            }
502        }
503        fprintf(f, "\n");
504
505        for (ct2=0; ct2 < api->paramCount; ct2++) {
506            const VarType *vt = &api->params[ct2];
507            if (vt->ptrLevel == 2) {
508                fprintf(f, "    for (size_t ct = 0; ct < (cmd.%s_length_length / sizeof(cmd.%s_length)); ct++) {\n", vt->name, vt->name);
509                fprintf(f, "        cmd.%s = (", vt->name);
510                printVarType(f, vt);
511                fprintf(f, ")malloc(cmd.%s_length[ct]);\n", vt->name);
512                fprintf(f, "        io->coreRead(& cmd.%s, cmd.%s_length[ct]);\n", vt->name, vt->name);
513                fprintf(f, "    }\n");
514            }
515        }
516        fprintf(f, "\n");
517
518        if (api->ret.typeName[0]) {
519            fprintf(f, "    ");
520            printVarType(f, &api->ret);
521            fprintf(f, " ret =\n");
522        }
523
524        fprintf(f, "    rsi_%s(", api->name);
525        if (!api->nocontext) {
526            fprintf(f, "con");
527        }
528        for (ct2=0; ct2 < api->paramCount; ct2++) {
529            const VarType *vt = &api->params[ct2];
530            if (ct2 > 0 || !api->nocontext) {
531                fprintf(f, ",\n");
532            }
533            fprintf(f, "           cmd.%s", vt->name);
534        }
535        fprintf(f, ");\n");
536
537        for (ct2=0; ct2 < api->paramCount; ct2++) {
538            const VarType *vt = &api->params[ct2];
539            if ((vt->ptrLevel == 1) && (!vt->isConst)) {
540                fprintf(f, "    io->coreSetReturn((void *)cmd.%s, cmd.%s_length);\n", vt->name, vt->name);
541            }
542        }
543
544        for (ct2=0; ct2 < api->paramCount; ct2++) {
545            const VarType *vt = &api->params[ct2];
546            if ((vt->ptrLevel == 2) && (!vt->isConst)) {
547                fprintf(f, "    for (size_t ct = 0; ct < (cmd.%s_length_length / sizeof(cmd.%s_length)); ct++) {\n", vt->name, vt->name);
548                fprintf(f, "        io->coreSetReturn((void *)cmd.%s[ct], cmd.%s_length[ct]);\n", vt->name, vt->name);
549                fprintf(f, "    }\n");
550            }
551        }
552        fprintf(f, "\n");
553
554        if (api->ret.typeName[0]) {
555            fprintf(f, "    io->coreSetReturn(&ret, sizeof(ret));\n");
556        } else /*if (needFlush)*/ {
557            fprintf(f, "    io->coreSetReturn(NULL, 0);\n");
558        }
559
560        for (ct2=0; ct2 < api->paramCount; ct2++) {
561            const VarType *vt = &api->params[ct2];
562            if (vt->ptrLevel == 1) {
563                fprintf(f, "    free((void *)cmd.%s);\n", vt->name);
564            }
565        }
566        for (ct2=0; ct2 < api->paramCount; ct2++) {
567            const VarType *vt = &api->params[ct2];
568            if (vt->ptrLevel == 2) {
569                fprintf(f, "    for (size_t ct = 0; ct < (cmd.%s_length_length / sizeof(cmd.%s_length)); ct++) {\n", vt->name, vt->name);
570                fprintf(f, "        free((void *)cmd.%s);\n", vt->name);
571                fprintf(f, "    }\n");
572            }
573        }
574
575        fprintf(f, "};\n\n");
576    }
577
578    fprintf(f, "RsPlaybackLocalFunc gPlaybackFuncs[%i] = {\n", apiCount + 1);
579    fprintf(f, "    NULL,\n");
580    for (ct=0; ct < apiCount; ct++) {
581        if (apis[ct].direct) {
582            fprintf(f, "    NULL,\n");
583        } else {
584            fprintf(f, "    %s%s,\n", "rsp_", apis[ct].name);
585        }
586    }
587    fprintf(f, "};\n");
588
589    fprintf(f, "RsPlaybackRemoteFunc gPlaybackRemoteFuncs[%i] = {\n", apiCount + 1);
590    fprintf(f, "    NULL,\n");
591    for (ct=0; ct < apiCount; ct++) {
592        fprintf(f, "    %s%s,\n", "rspr_", apis[ct].name);
593    }
594    fprintf(f, "};\n");
595
596    fprintf(f, "};\n");
597    fprintf(f, "};\n");
598}
599
600void yylex();
601
602int main(int argc, char **argv) {
603    if (argc != 3) {
604        fprintf(stderr, "usage: %s commandFile outFile\n", argv[0]);
605        return 1;
606    }
607    const char* rsgFile = argv[1];
608    const char* outFile = argv[2];
609    FILE* input = fopen(rsgFile, "r");
610
611    char choice = fgetc(input);
612    fclose(input);
613
614    if (choice < '0' || choice > '3') {
615        fprintf(stderr, "Uknown command: \'%c\'\n", choice);
616        return -2;
617    }
618
619    yylex();
620    // printf("# of lines = %d\n", num_lines);
621
622    FILE *f = fopen(outFile, "w");
623
624    printFileHeader(f);
625    switch (choice) {
626        case '0': // rsgApiStructs.h
627        {
628            fprintf(f, "\n");
629            fprintf(f, "#include \"rsContext.h\"\n");
630            fprintf(f, "#include \"rsFifo.h\"\n");
631            fprintf(f, "\n");
632            fprintf(f, "namespace android {\n");
633            fprintf(f, "namespace renderscript {\n");
634            printStructures(f);
635            printFuncDecls(f, "rsi_", 1);
636            printPlaybackFuncs(f, "rsp_");
637            fprintf(f, "\n\ntypedef struct RsPlaybackRemoteHeaderRec {\n");
638            fprintf(f, "    uint32_t command;\n");
639            fprintf(f, "    uint32_t size;\n");
640            fprintf(f, "} RsPlaybackRemoteHeader;\n\n");
641            fprintf(f, "typedef void (*RsPlaybackLocalFunc)(Context *, const void *, size_t sizeBytes);\n");
642            fprintf(f, "typedef void (*RsPlaybackRemoteFunc)(Context *, ThreadIO *);\n");
643            fprintf(f, "extern RsPlaybackLocalFunc gPlaybackFuncs[%i];\n", apiCount + 1);
644            fprintf(f, "extern RsPlaybackRemoteFunc gPlaybackRemoteFuncs[%i];\n", apiCount + 1);
645
646            fprintf(f, "}\n");
647            fprintf(f, "}\n");
648        }
649        break;
650
651        case '1': // rsgApiFuncDecl.h
652        {
653            printFuncDecls(f, "rs", 0);
654        }
655        break;
656
657        case '2': // rsgApi.cpp
658        {
659            printApiCpp(f);
660        }
661        break;
662
663        case '3': // rsgApiReplay.cpp
664        {
665            printFileHeader(f);
666            printPlaybackCpp(f);
667        }
668        break;
669
670        case '4': // rsgApiStream.cpp
671        {
672            printFileHeader(f);
673            printPlaybackCpp(f);
674        }
675
676        case '5': // rsgApiStreamReplay.cpp
677        {
678            printFileHeader(f);
679            printPlaybackCpp(f);
680        }
681        break;
682    }
683    fclose(f);
684    return 0;
685}
686