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