xref: /aosp_15_r20/frameworks/rs/script_api/Generator.cpp (revision e1eccf28f96817838ad6867f7f39d2351ec11f56)
1*e1eccf28SAndroid Build Coastguard Worker /*
2*e1eccf28SAndroid Build Coastguard Worker  * Copyright (C) 2013 The Android Open Source Project
3*e1eccf28SAndroid Build Coastguard Worker  *
4*e1eccf28SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*e1eccf28SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*e1eccf28SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*e1eccf28SAndroid Build Coastguard Worker  *
8*e1eccf28SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*e1eccf28SAndroid Build Coastguard Worker  *
10*e1eccf28SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*e1eccf28SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*e1eccf28SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e1eccf28SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*e1eccf28SAndroid Build Coastguard Worker  * limitations under the License.
15*e1eccf28SAndroid Build Coastguard Worker  */
16*e1eccf28SAndroid Build Coastguard Worker 
17*e1eccf28SAndroid Build Coastguard Worker /* This program processes Renderscript function definitions described in spec files.
18*e1eccf28SAndroid Build Coastguard Worker  * For each spec file provided on the command line, it generates a corresponding
19*e1eccf28SAndroid Build Coastguard Worker  * Renderscript header (*.rsh) which is meant for inclusion in client scripts.
20*e1eccf28SAndroid Build Coastguard Worker  *
21*e1eccf28SAndroid Build Coastguard Worker  * This program also generates Junit test files to automatically test each of the
22*e1eccf28SAndroid Build Coastguard Worker  * functions using randomly generated data.  We create two files for each function:
23*e1eccf28SAndroid Build Coastguard Worker  * - a Renderscript file named Test{Function}.rs,
24*e1eccf28SAndroid Build Coastguard Worker  * - a Junit file named Test{function}.java, which calls the above RS file.
25*e1eccf28SAndroid Build Coastguard Worker  *
26*e1eccf28SAndroid Build Coastguard Worker  * Finally, this program generates HTML documentation files.
27*e1eccf28SAndroid Build Coastguard Worker  *
28*e1eccf28SAndroid Build Coastguard Worker  * This program takes an optional -v parameter, the API level to target.  The generated
29*e1eccf28SAndroid Build Coastguard Worker  * files will not contain APIs passed that API level.  Note that this does not affect
30*e1eccf28SAndroid Build Coastguard Worker  * generic comments found in headers.
31*e1eccf28SAndroid Build Coastguard Worker  *
32*e1eccf28SAndroid Build Coastguard Worker  * This program contains five main classes:
33*e1eccf28SAndroid Build Coastguard Worker  * - SpecFile: Represents on spec file.
34*e1eccf28SAndroid Build Coastguard Worker  * - Function: Each instance represents a function, like clamp.  Even though the
35*e1eccf28SAndroid Build Coastguard Worker  *      spec file contains many entries for clamp, we'll only have one clamp instance.
36*e1eccf28SAndroid Build Coastguard Worker  * - FunctionSpecification: Defines one of the many variations of the function.  There's
37*e1eccf28SAndroid Build Coastguard Worker  *      a one to one correspondance between FunctionSpecification objects and entries in the
38*e1eccf28SAndroid Build Coastguard Worker  *      spec file.  Strings that are parts of a FunctionSpecification can include placeholders,
39*e1eccf28SAndroid Build Coastguard Worker  *      which are "#1", "#2", "#3", and "#4".  We'll replace these by values before
40*e1eccf28SAndroid Build Coastguard Worker  *      generating the files.
41*e1eccf28SAndroid Build Coastguard Worker  * - Permutation: A concrete version of a specification, where all placeholders have
42*e1eccf28SAndroid Build Coastguard Worker  *      been replaced by actual values.
43*e1eccf28SAndroid Build Coastguard Worker  * - ParameterDefinition: A definition of a parameter of a concrete function.
44*e1eccf28SAndroid Build Coastguard Worker  *
45*e1eccf28SAndroid Build Coastguard Worker  * The format of the .spec files is described below.  Line that starts with # are comments.
46*e1eccf28SAndroid Build Coastguard Worker  * Replace the {} sections with your own contents.  [] indicates optional parts.
47*e1eccf28SAndroid Build Coastguard Worker  *
48*e1eccf28SAndroid Build Coastguard Worker  * It should start with a header as follows:
49*e1eccf28SAndroid Build Coastguard Worker  *
50*e1eccf28SAndroid Build Coastguard Worker  * header:
51*e1eccf28SAndroid Build Coastguard Worker  * summary:  {A one line string describing this section.}
52*e1eccf28SAndroid Build Coastguard Worker  * description:
53*e1eccf28SAndroid Build Coastguard Worker  *     {Multiline description.  Can include HTML.  References to constants, types,
54*e1eccf28SAndroid Build Coastguard Worker  *      and functions can be created by prefixing with a '@'.}
55*e1eccf28SAndroid Build Coastguard Worker  * [include:
56*e1eccf28SAndroid Build Coastguard Worker  *     { Multiline code lines to be included as-is in the generated header file.}]
57*e1eccf28SAndroid Build Coastguard Worker  * end:
58*e1eccf28SAndroid Build Coastguard Worker  *
59*e1eccf28SAndroid Build Coastguard Worker  * Constants are defined as follows:
60*e1eccf28SAndroid Build Coastguard Worker  *
61*e1eccf28SAndroid Build Coastguard Worker  * constant:  {The name of the constant.}
62*e1eccf28SAndroid Build Coastguard Worker  * [version: ({Starting API level} [ {Last API level that supports this.}] | UNRELEASED)
63*e1eccf28SAndroid Build Coastguard Worker  * [size: {32 or 64.  Used if this is available only for 32 or 64 bit code.}]
64*e1eccf28SAndroid Build Coastguard Worker  * value: {The value of the constant.}
65*e1eccf28SAndroid Build Coastguard Worker  * type: {The type of the constant.}
66*e1eccf28SAndroid Build Coastguard Worker  * [hidden:]   ...If present, don't document the constant.  Omit the following two fields.
67*e1eccf28SAndroid Build Coastguard Worker  * [deprecated: [{Deprecation message.}]   ... This is deprecated.  Compiler will issue a wrning.
68*e1eccf28SAndroid Build Coastguard Worker  * summary: {A one line string describing this section.}
69*e1eccf28SAndroid Build Coastguard Worker  * description:
70*e1eccf28SAndroid Build Coastguard Worker  *     {Multiline description.  Can include HTML.  References to constants, types,
71*e1eccf28SAndroid Build Coastguard Worker  *      and functions can be created by prefixing with a '@'.}
72*e1eccf28SAndroid Build Coastguard Worker  * end:
73*e1eccf28SAndroid Build Coastguard Worker  *
74*e1eccf28SAndroid Build Coastguard Worker  * Types can either be simple types, structs, or enums.  They have the format:
75*e1eccf28SAndroid Build Coastguard Worker  *
76*e1eccf28SAndroid Build Coastguard Worker  * type:  {The typedef name of the type.}
77*e1eccf28SAndroid Build Coastguard Worker  * [version: ({Starting API level} [ {Last API level that supports this.}] | UNRELEASED)
78*e1eccf28SAndroid Build Coastguard Worker  * [size: {32 or 64.  Used if this is available only for 32 or 64 bit code.}]
79*e1eccf28SAndroid Build Coastguard Worker  * simple: {The C declaration that this type is the typedef equivalent.}
80*e1eccf28SAndroid Build Coastguard Worker  * [hidden:]   ...If present, don't document the type.  Omit the following two fields.
81*e1eccf28SAndroid Build Coastguard Worker  * [deprecated: [{Deprecation message.}]   ... This is deprecated.  Compiler will issue a wrning.
82*e1eccf28SAndroid Build Coastguard Worker  * summary: {A one line string describing this section.}
83*e1eccf28SAndroid Build Coastguard Worker  * description:
84*e1eccf28SAndroid Build Coastguard Worker  *     {Multiline description.  Can include HTML.  References to constants, types,
85*e1eccf28SAndroid Build Coastguard Worker  *      and functions can be created by prefixing with a '@'.}
86*e1eccf28SAndroid Build Coastguard Worker  * end:
87*e1eccf28SAndroid Build Coastguard Worker  *
88*e1eccf28SAndroid Build Coastguard Worker  * type:  {The typedef name of the type.}
89*e1eccf28SAndroid Build Coastguard Worker  * [version: ({Starting API level} [ {Last API level that supports this.}] | UNRELEASED)
90*e1eccf28SAndroid Build Coastguard Worker  * [size: {32 or 64.  Used if this is available only for 32 or 64 bit code.}]
91*e1eccf28SAndroid Build Coastguard Worker  * struct: [{The name that will appear right after the struct keyword}]
92*e1eccf28SAndroid Build Coastguard Worker  * field: {Type and name of the field}[, "{One line documentation of the field}"]
93*e1eccf28SAndroid Build Coastguard Worker  * field:   ... Same for all the other fields of the struct.
94*e1eccf28SAndroid Build Coastguard Worker  * [attrib: {Attributes of the struct.}]
95*e1eccf28SAndroid Build Coastguard Worker  * [hidden:]   ...If present, don't document the type.  Omit the following two fields.
96*e1eccf28SAndroid Build Coastguard Worker  * summary: {A one line string describing this section.}
97*e1eccf28SAndroid Build Coastguard Worker  * description:
98*e1eccf28SAndroid Build Coastguard Worker  *     {Multiline description.  Can include HTML.  References to constants, types,
99*e1eccf28SAndroid Build Coastguard Worker  *      and functions can be created by prefixing with a '@'.}
100*e1eccf28SAndroid Build Coastguard Worker  * end:
101*e1eccf28SAndroid Build Coastguard Worker  *
102*e1eccf28SAndroid Build Coastguard Worker  * type:  {The typedef name of the type.}
103*e1eccf28SAndroid Build Coastguard Worker  * [version: ({Starting API level} [ {Last API level that supports this.}] | UNRELEASED)
104*e1eccf28SAndroid Build Coastguard Worker  * [size: {32 or 64.  Used if this is available only for 32 or 64 bit code.}]
105*e1eccf28SAndroid Build Coastguard Worker  * enum: [{The name that will appear right after the enum keyword}]
106*e1eccf28SAndroid Build Coastguard Worker  * value: {Type and name of the field}[, "{One line documentation of the field}"]
107*e1eccf28SAndroid Build Coastguard Worker  * value:   ... Same for all the other values of the enum.
108*e1eccf28SAndroid Build Coastguard Worker  * [hidden:]   ...If present, don't document the type.  Omit the following two fields.
109*e1eccf28SAndroid Build Coastguard Worker  * summary: {A one line string describing this section.}
110*e1eccf28SAndroid Build Coastguard Worker  * description:
111*e1eccf28SAndroid Build Coastguard Worker  *     {Multiline description.  Can include HTML.  References to constants, types,
112*e1eccf28SAndroid Build Coastguard Worker  *      and functions can be created by prefixing with a '@'.}
113*e1eccf28SAndroid Build Coastguard Worker  * end:
114*e1eccf28SAndroid Build Coastguard Worker 
115*e1eccf28SAndroid Build Coastguard Worker  * Functions have the following format:
116*e1eccf28SAndroid Build Coastguard Worker  *
117*e1eccf28SAndroid Build Coastguard Worker  * function:  {The name of the function.}
118*e1eccf28SAndroid Build Coastguard Worker  * [version: ({Starting API level} [ {Last API level that supports this.}] | UNRELEASED)
119*e1eccf28SAndroid Build Coastguard Worker  * [size: {32 or 64.  Used if this is available only for 32 or 64 bit code.}]
120*e1eccf28SAndroid Build Coastguard Worker  * [attrib: {Attributes of the function.}]
121*e1eccf28SAndroid Build Coastguard Worker  * [w: {A comma separated list of width supported.  Only 1, 2, 3, 4 are supported.
122*e1eccf28SAndroid Build Coastguard Worker  * [t: {A comma separated list of the types supported.}]]
123*e1eccf28SAndroid Build Coastguard Worker  * ... Up to four w: or t: can be defined.  The order matter.  These will be replace
124*e1eccf28SAndroid Build Coastguard Worker  * ... the #1, #2, #3, #4 that can be found in the rest of the specification.
125*e1eccf28SAndroid Build Coastguard Worker  * ret: [{The return type} [, "{One line documentation of the return}"]]
126*e1eccf28SAndroid Build Coastguard Worker  * [arg:(({Type}[ {Name})]|{Elipsis})[, {ParameterEntry.testOption}][, "{One line documentation of the field}"]]
127*e1eccf28SAndroid Build Coastguard Worker  * [arg:   ... Same for all the other arguments of the function.]
128*e1eccf28SAndroid Build Coastguard Worker  * [hidden:]   ... If present, don't include in the HTML documentation.
129*e1eccf28SAndroid Build Coastguard Worker  * [deprecated: [{Deprecation message.}]   ... This is deprecated.  Compiler will issue a wrning.
130*e1eccf28SAndroid Build Coastguard Worker  * summary: {A one line string describing this section.}
131*e1eccf28SAndroid Build Coastguard Worker  * description:
132*e1eccf28SAndroid Build Coastguard Worker  *     {Multiline description.  Can include HTML.  References to constants, types,
133*e1eccf28SAndroid Build Coastguard Worker  *      and functions can be created by prefixing with a '@'.}
134*e1eccf28SAndroid Build Coastguard Worker  * [inline:
135*e1eccf28SAndroid Build Coastguard Worker  *     {Multiline code that implements this function inline.}]
136*e1eccf28SAndroid Build Coastguard Worker  * [test: {How to test this function.  See FunctionSpecification::mTest.}]
137*e1eccf28SAndroid Build Coastguard Worker  * end:
138*e1eccf28SAndroid Build Coastguard Worker  */
139*e1eccf28SAndroid Build Coastguard Worker 
140*e1eccf28SAndroid Build Coastguard Worker #include <stdio.h>
141*e1eccf28SAndroid Build Coastguard Worker #include <cctype>
142*e1eccf28SAndroid Build Coastguard Worker #include <cstdlib>
143*e1eccf28SAndroid Build Coastguard Worker #include <fstream>
144*e1eccf28SAndroid Build Coastguard Worker #include <functional>
145*e1eccf28SAndroid Build Coastguard Worker #include <iostream>
146*e1eccf28SAndroid Build Coastguard Worker #include <memory>
147*e1eccf28SAndroid Build Coastguard Worker #include <sstream>
148*e1eccf28SAndroid Build Coastguard Worker #include <strings.h>
149*e1eccf28SAndroid Build Coastguard Worker 
150*e1eccf28SAndroid Build Coastguard Worker #include "Generator.h"
151*e1eccf28SAndroid Build Coastguard Worker #include "Scanner.h"
152*e1eccf28SAndroid Build Coastguard Worker #include "Specification.h"
153*e1eccf28SAndroid Build Coastguard Worker #include "Utilities.h"
154*e1eccf28SAndroid Build Coastguard Worker 
155*e1eccf28SAndroid Build Coastguard Worker using namespace std;
156*e1eccf28SAndroid Build Coastguard Worker 
parseCommandLine(int argc,char * argv[],unsigned int * maxApiLevel,vector<string> * specFileNames)157*e1eccf28SAndroid Build Coastguard Worker static bool parseCommandLine(int argc, char* argv[], unsigned int* maxApiLevel,
158*e1eccf28SAndroid Build Coastguard Worker                              vector<string>* specFileNames) {
159*e1eccf28SAndroid Build Coastguard Worker     for (int i = 1; i < argc; i++) {
160*e1eccf28SAndroid Build Coastguard Worker         if (argv[i][0] == '-') {
161*e1eccf28SAndroid Build Coastguard Worker             if (argv[i][1] == 'v') {
162*e1eccf28SAndroid Build Coastguard Worker                 i++;
163*e1eccf28SAndroid Build Coastguard Worker                 if (i < argc) {
164*e1eccf28SAndroid Build Coastguard Worker                     char* end;
165*e1eccf28SAndroid Build Coastguard Worker                     *maxApiLevel = strtol(argv[i], &end, 10);
166*e1eccf28SAndroid Build Coastguard Worker                     if (*end != '\0') {
167*e1eccf28SAndroid Build Coastguard Worker                         cerr << "Error. Can't parse the version number" << argv[i] << "\n";
168*e1eccf28SAndroid Build Coastguard Worker                         return false;
169*e1eccf28SAndroid Build Coastguard Worker                     }
170*e1eccf28SAndroid Build Coastguard Worker                 } else {
171*e1eccf28SAndroid Build Coastguard Worker                     cerr << "Missing version number after -v\n";
172*e1eccf28SAndroid Build Coastguard Worker                     return false;
173*e1eccf28SAndroid Build Coastguard Worker                 }
174*e1eccf28SAndroid Build Coastguard Worker             } else {
175*e1eccf28SAndroid Build Coastguard Worker                 cerr << "Unrecognized flag %s\n" << argv[i] << "\n";
176*e1eccf28SAndroid Build Coastguard Worker                 return false;
177*e1eccf28SAndroid Build Coastguard Worker             }
178*e1eccf28SAndroid Build Coastguard Worker         } else {
179*e1eccf28SAndroid Build Coastguard Worker             specFileNames->push_back(argv[i]);
180*e1eccf28SAndroid Build Coastguard Worker         }
181*e1eccf28SAndroid Build Coastguard Worker     }
182*e1eccf28SAndroid Build Coastguard Worker     if (specFileNames->size() == 0) {
183*e1eccf28SAndroid Build Coastguard Worker         cerr << "No spec file specified\n";
184*e1eccf28SAndroid Build Coastguard Worker         return false;
185*e1eccf28SAndroid Build Coastguard Worker     }
186*e1eccf28SAndroid Build Coastguard Worker     return true;
187*e1eccf28SAndroid Build Coastguard Worker }
188*e1eccf28SAndroid Build Coastguard Worker 
main(int argc,char * argv[])189*e1eccf28SAndroid Build Coastguard Worker int main(int argc, char* argv[]) {
190*e1eccf28SAndroid Build Coastguard Worker     // If there's no restriction, generated test files for the very highest version.
191*e1eccf28SAndroid Build Coastguard Worker     unsigned int maxApiLevel = VersionInfo::kUnreleasedVersion;
192*e1eccf28SAndroid Build Coastguard Worker     vector<string> specFileNames;
193*e1eccf28SAndroid Build Coastguard Worker     if (!parseCommandLine(argc, argv, &maxApiLevel, &specFileNames)) {
194*e1eccf28SAndroid Build Coastguard Worker         cout << "Usage: gen_runtime spec_file [spec_file...] [-v "
195*e1eccf28SAndroid Build Coastguard Worker                 "version_of_test_files]\n";
196*e1eccf28SAndroid Build Coastguard Worker         return -1;
197*e1eccf28SAndroid Build Coastguard Worker     }
198*e1eccf28SAndroid Build Coastguard Worker     bool success = true;
199*e1eccf28SAndroid Build Coastguard Worker     for (auto i : specFileNames) {
200*e1eccf28SAndroid Build Coastguard Worker         if (!systemSpecification.readSpecFile(i, maxApiLevel)) {
201*e1eccf28SAndroid Build Coastguard Worker             success = false;
202*e1eccf28SAndroid Build Coastguard Worker         }
203*e1eccf28SAndroid Build Coastguard Worker     }
204*e1eccf28SAndroid Build Coastguard Worker     if (success) {
205*e1eccf28SAndroid Build Coastguard Worker         success = systemSpecification.generateFiles(maxApiLevel);
206*e1eccf28SAndroid Build Coastguard Worker     }
207*e1eccf28SAndroid Build Coastguard Worker     return success ? 0 : -2;
208*e1eccf28SAndroid Build Coastguard Worker }
209