blob: 978331060ae9da6759f2c98401a7fce68feb7918 [file] [log] [blame]
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -07001/*
2 * Copyright (C) 2015 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#ifndef ANDROID_RS_API_GENERATOR_SPECIFICATION_H
18#define ANDROID_RS_API_GENERATOR_SPECIFICATION_H
19
20// See Generator.cpp for documentation of the .spec file format.
21
22#include <fstream>
23#include <list>
24#include <map>
25#include <string>
26#include <vector>
27
28class Constant;
29class ConstantSpecification;
30class Function;
31class FunctionPermutation;
32class FunctionSpecification;
33class SpecFile;
34class Specification;
35class Scanner;
36class SystemSpecification;
37class Type;
38class TypeSpecification;
39
40enum NumberKind { SIGNED_INTEGER, UNSIGNED_INTEGER, FLOATING_POINT };
41
42// Table of type equivalences.
43struct NumericalType {
44 const char* specType; // Name found in the .spec file
45 const char* rsDataType; // RS data type
46 const char* cType; // Type in a C file
47 const char* javaType; // Type in a Java file
48 NumberKind kind;
49 /* For integers, number of bits of the number, excluding the sign bit.
50 * For floats, number of implied bits of the mantissa.
51 */
52 int significantBits;
53 // For floats, number of bits of the exponent. 0 for integer types.
54 int exponentBits;
55};
56
57/* Corresponds to one parameter line in a .spec file. These will be parsed when
58 * we instantiate the FunctionPermutation(s) that correspond to one FunctionSpecification.
59 */
60struct ParameterEntry {
61 std::string type;
62 std::string name;
63 /* Optional information on how to generate test values for this parameter. Can be:
64 * - range(low, high): Generates values between these two limits only.
65 * - above(other_parameter): The values must be greater than those of the named parameter.
66 * Used for clamp.
67 * - compatible(type): The values must also be fully representable in the specified type.
68 * - conditional: Don't verify this value the function return NaN.
69 */
70 std::string testOption;
71 std::string documentation;
72 int lineNumber;
73};
74
75/* Information about a parameter to a function. The values of all the fields should only be set by
76 * parseParameterDefinition.
77 */
78struct ParameterDefinition {
79 std::string rsType; // The Renderscript type, e.g. "uint3"
80 std::string rsBaseType; // As above but without the number, e.g. "uint"
81 std::string javaBaseType; // The type we need to declare in Java, e.g. "unsigned int"
82 std::string specType; // The type found in the spec, e.g. "f16"
83 bool isFloatType; // True if it's a floating point value
84 /* The number of entries in the vector. It should be either "1", "2", "3", or "4". It's also
85 * "1" for scalars.
86 */
87 std::string mVectorSize;
88 /* The space the vector takes in an array. It's the same as the vector size, except for size
89 * "3", where the width is "4".
90 */
91 std::string vectorWidth;
92
93 std::string specName; // e.g. x, as found in the spec file
94 std::string variableName; // e.g. inX, used both in .rs and .java
95 std::string rsAllocName; // e.g. gAllocInX
96 std::string javaAllocName; // e.g. inX
97 std::string javaArrayName; // e.g. arrayInX
98
99 // If non empty, the mininum and maximum values to be used when generating the test data.
100 std::string minValue;
101 std::string maxValue;
102 /* If non empty, contains the name of another parameter that should be smaller or equal to this
103 * parameter, i.e. value(smallerParameter) <= value(this). This is used when testing clamp.
104 */
105 std::string smallerParameter;
106
107 bool isOutParameter; // True if this parameter returns data from the script.
108 bool undefinedIfOutIsNan; // If true, we don't validate if 'out' is NaN.
109
110 int typeIndex; // Index in the TYPES array. Negative if not found in the array.
111 int compatibleTypeIndex; // Index in TYPES for which the test data must also fit.
112
113 /* Fill this object from the type, name, and testOption.
114 * isReturn is true if we're processing the "return:"
115 */
116 void parseParameterDefinition(const std::string& type, const std::string& name,
117 const std::string& testOption, int lineNumber, bool isReturn,
118 Scanner* scanner);
119};
120
121struct VersionInfo {
122 /* The range of versions a specification applies to. Zero if there's no restriction,
123 * so an API that became available at 12 and is still valid would have min:12 max:0.
124 * If non zero, both versions should be at least 9, the API level that introduced
125 * RenderScript.
126 */
127 int minVersion;
128 int maxVersion;
129 // Either 0, 32 or 64. If 0, this definition is valid for both 32 and 64 bits.
130 int intSize;
131
132 VersionInfo() : minVersion(0), maxVersion(0), intSize(0) {}
Jean-Luc Brouillet2217eb72015-04-24 14:41:48 -0700133 /* Scan the version info from the spec file. maxApiLevel specifies the maximum level
134 * we are interested in. This may alter maxVersion. This method returns false if the
135 * minVersion is greater than the maxApiLevel.
136 */
137 bool scan(Scanner* scanner, int maxApiLevel);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700138};
139
140// We have three type of definitions
141class Definition {
142protected:
143 std::string mName;
Jean-Luc Brouillet4a730042015-04-02 16:15:25 -0700144 bool mDeprecated; // True if this API should not be used
145 std::string mDeprecatedMessage; // Optional specific warning if the API is deprecated
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700146 bool mHidden; // True if it should not be documented
147 std::string mSummary; // A one-line description
148 std::vector<std::string> mDescription; // The comments to be included in the header
149 std::string mUrl; // The URL of the detailed documentation
Jean-Luc Brouillet67923a92015-05-12 15:38:27 -0700150 int mFinalVersion; // API level at which this API was removed, 0 if API is still valid
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700151
152public:
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700153 Definition(const std::string& name);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700154
155 std::string getName() const { return mName; }
Jean-Luc Brouillet4a730042015-04-02 16:15:25 -0700156 bool deprecated() const { return mDeprecated; }
157 std::string getDeprecatedMessage() const { return mDeprecatedMessage; }
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700158 bool hidden() const { return mHidden; }
159 std::string getSummary() const { return mSummary; }
160 const std::vector<std::string>& getDescription() const { return mDescription; }
161 std::string getUrl() const { return mUrl; }
Jean-Luc Brouillet67923a92015-05-12 15:38:27 -0700162 int getFinalVersion() const { return mFinalVersion; }
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700163
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700164 void scanDocumentationTags(Scanner* scanner, bool firstOccurence, const SpecFile* specFile);
Jean-Luc Brouillet67923a92015-05-12 15:38:27 -0700165 // Keep track of the final version of this API, if any.
166 void updateFinalVersion(const VersionInfo& info);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700167};
168
169/* Represents a constant, like M_PI. This is a grouping of the version specific specifications.
170 * We'll only have one instance of Constant for each name.
171 */
172class Constant : public Definition {
173private:
174 std::vector<ConstantSpecification*> mSpecifications; // Owned
175
176public:
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700177 Constant(const std::string& name) : Definition(name) {}
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700178 ~Constant();
179
180 const std::vector<ConstantSpecification*> getSpecifications() const { return mSpecifications; }
181 // This method should only be called by the scanning code.
182 void addSpecification(ConstantSpecification* spec) { mSpecifications.push_back(spec); }
183};
184
185/* Represents a type, like "float4". This is a grouping of the version specific specifications.
186 * We'll only have one instance of Type for each name.
187 */
188class Type : public Definition {
189private:
190 std::vector<TypeSpecification*> mSpecifications; // Owned
191
192public:
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700193 Type(const std::string& name) : Definition(name) {}
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700194 ~Type();
195
196 const std::vector<TypeSpecification*> getSpecifications() const { return mSpecifications; }
197 // This method should only be called by the scanning code.
198 void addSpecification(TypeSpecification* spec) { mSpecifications.push_back(spec); }
199};
200
201/* Represents a function, like "clamp". Even though the spec file contains many entries for clamp,
202 * we'll only have one clamp instance.
203 */
204class Function : public Definition {
205private:
206 // mName in the base class contains the lower case name, e.g. native_log
207 std::string mCapitalizedName; // The capitalized name, e.g. NativeLog
208
209 // The unique parameters between all the specifications. NOT OWNED.
210 std::vector<ParameterEntry*> mParameters;
211 std::string mReturnDocumentation;
212
213 std::vector<FunctionSpecification*> mSpecifications; // Owned
214
215public:
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700216 Function(const std::string& name);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700217 ~Function();
218
219 std::string getCapitalizedName() const { return mCapitalizedName; }
220 const std::vector<ParameterEntry*>& getParameters() const { return mParameters; }
221 std::string getReturnDocumentation() const { return mReturnDocumentation; }
222 const std::vector<FunctionSpecification*> getSpecifications() const { return mSpecifications; }
223
224 bool someParametersAreDocumented() const;
225
226 // The following methods should only be called by the scanning code.
227 void addParameter(ParameterEntry* entry, Scanner* scanner);
228 void addReturn(ParameterEntry* entry, Scanner* scanner);
229 void addSpecification(FunctionSpecification* spec) { mSpecifications.push_back(spec); }
230};
231
232/* Base class for TypeSpecification, ConstantSpecification, and FunctionSpecification.
233 * A specification can be specific to a range of RenderScript version or 32bits vs 64 bits.
234 * This base class contains code to parse and store this version information.
235 */
236class Specification {
237protected:
238 VersionInfo mVersionInfo;
239 void scanVersionInfo(Scanner* scanner);
240
241public:
242 VersionInfo getVersionInfo() const { return mVersionInfo; }
243};
244
245/* Defines one of the many variations of a constant. There's a one to one correspondance between
246 * ConstantSpecification objects and entries in the spec file.
247 */
248class ConstantSpecification : public Specification {
249private:
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700250 Constant* mConstant; // Not owned
251
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700252 std::string mValue; // E.g. "3.1415"
253public:
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700254 ConstantSpecification(Constant* constant) : mConstant(constant) {}
255
256 Constant* getConstant() const { return mConstant; }
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700257 std::string getValue() const { return mValue; }
258
259 // Parse a constant specification and add it to specFile.
Jean-Luc Brouillet2217eb72015-04-24 14:41:48 -0700260 static void scanConstantSpecification(Scanner* scanner, SpecFile* specFile, int maxApiLevel);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700261};
262
263enum TypeKind {
264 SIMPLE,
265 STRUCT,
266 ENUM,
267};
268
269/* Defines one of the many variations of a type. There's a one to one correspondance between
270 * TypeSpecification objects and entries in the spec file.
271 */
272class TypeSpecification : public Specification {
273private:
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700274 Type* mType; // Not owned
275
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700276 TypeKind mKind; // The kind of type specification
277
278 // If mKind is SIMPLE:
279 std::string mSimpleType; // The definition of the type
280
281 // If mKind is STRUCT:
282 std::string mStructName; // The name found after the struct keyword
283 std::vector<std::string> mFields; // One entry per struct field
284 std::vector<std::string> mFieldComments; // One entry per struct field
285 std::string mAttrib; // Some structures may have attributes
286
287 // If mKind is ENUM:
288 std::string mEnumName; // The name found after the enum keyword
289 std::vector<std::string> mValues; // One entry per enum value
290 std::vector<std::string> mValueComments; // One entry per enum value
291public:
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700292 TypeSpecification(Type* type) : mType(type) {}
293
294 Type* getType() const { return mType; }
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700295 TypeKind getKind() const { return mKind; }
296 std::string getSimpleType() const { return mSimpleType; }
297 std::string getStructName() const { return mStructName; }
298 const std::vector<std::string>& getFields() const { return mFields; }
299 const std::vector<std::string>& getFieldComments() const { return mFieldComments; }
300 std::string getAttrib() const { return mAttrib; }
301 std::string getEnumName() const { return mEnumName; }
302 const std::vector<std::string>& getValues() const { return mValues; }
303 const std::vector<std::string>& getValueComments() const { return mValueComments; }
304
305 // Parse a type specification and add it to specFile.
Jean-Luc Brouillet2217eb72015-04-24 14:41:48 -0700306 static void scanTypeSpecification(Scanner* scanner, SpecFile* specFile, int maxApiLevel);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700307};
308
309// Maximum number of placeholders (like #1, #2) in function specifications.
310const int MAX_REPLACEABLES = 4;
311
312/* Defines one of the many variations of the function. There's a one to one correspondance between
313 * FunctionSpecification objects and entries in the spec file. Some of the strings that are parts
314 * of a FunctionSpecification can include placeholders, which are "#1", "#2", "#3", and "#4". We'll
315 * replace these by values before generating the files.
316 */
317class FunctionSpecification : public Specification {
318private:
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700319 Function* mFunction; // Not owned
320
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700321 /* How to test. One of:
322 * "scalar": Generate test code that checks entries of each vector indepently. E.g. for
323 * sin(float3), the test code will call the CoreMathVerfier.computeSin 3 times.
324 * "limited": Like "scalar" but we don't generate extreme values. This is not currently
325 * enabled as we were generating to many errors.
326 * "custom": Like "scalar" but instead of calling CoreMathVerifier.computeXXX() to compute
327 * the expected value, we call instead CoreMathVerifier.verifyXXX(). This method
328 * returns a string that contains the error message, null if there's no error.
329 * "vector": Generate test code that calls the CoreMathVerifier only once for each vector.
330 * This is useful for APIs like dot() or length().
331 * "noverify": Generate test code that calls the API but don't verify the returned value.
332 * This can discover unresolved references.
Jean-Luc Brouillet66fea242015-04-09 16:47:59 -0700333 * "": Don't test. This is the default.
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700334 */
335 std::string mTest;
336 std::string mAttribute; // Function attributes.
337 std::string mPrecisionLimit; // Maximum precision required when checking output of this
338 // function.
339
340 // The vectors of values with which we'll replace #1, #2, ...
341 std::vector<std::vector<std::string> > mReplaceables;
342
343 /* The collection of permutations for this specification, i.e. this class instantianted
344 * for specific values of #1, #2, etc. Owned.
345 */
346 std::vector<FunctionPermutation*> mPermutations;
347
348 // The following fields may contain placeholders that will be replaced using the mReplaceables.
349
350 /* As of this writing, convert_... is the only function with #1 in its name.
351 * The related Function object contains the name of the function without #n, e.g. convert.
352 * This is the name with the #, e.g. convert_#1_#2
353 */
354 std::string mUnexpandedName;
Jean-Luc Brouillet2217eb72015-04-24 14:41:48 -0700355 ParameterEntry* mReturn; // The return type. The name should be empty. Owned.
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700356 std::vector<ParameterEntry*> mParameters; // The parameters. Owned.
357 std::vector<std::string> mInline; // The inline code to be included in the header
358
359 /* Substitute the placeholders in the strings (e.g. #1, #2, ...) by the corresponding
360 * entries in mReplaceables. indexOfReplaceable1 selects with value to use for #1,
361 * same for 2, 3, and 4.
362 */
363 std::string expandString(std::string s, int indexOfReplaceable[MAX_REPLACEABLES]) const;
364 void expandStringVector(const std::vector<std::string>& in,
365 int replacementIndexes[MAX_REPLACEABLES],
366 std::vector<std::string>* out) const;
367
368 // Fill the mPermutations field.
369 void createPermutations(Function* function, Scanner* scanner);
370
371public:
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700372 FunctionSpecification(Function* function) : mFunction(function), mReturn(nullptr) {}
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700373 ~FunctionSpecification();
374
Jean-Luc Brouillet67923a92015-05-12 15:38:27 -0700375 Function* getFunction() const { return mFunction; }
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700376 std::string getAttribute() const { return mAttribute; }
377 std::string getTest() const { return mTest; }
378 std::string getPrecisionLimit() const { return mPrecisionLimit; }
379
380 const std::vector<FunctionPermutation*>& getPermutations() const { return mPermutations; }
381
382 std::string getName(int replacementIndexes[MAX_REPLACEABLES]) const;
383 void getReturn(int replacementIndexes[MAX_REPLACEABLES], std::string* retType,
384 int* lineNumber) const;
385 size_t getNumberOfParams() const { return mParameters.size(); }
386 void getParam(size_t index, int replacementIndexes[MAX_REPLACEABLES], std::string* type,
387 std::string* name, std::string* testOption, int* lineNumber) const;
388 void getInlines(int replacementIndexes[MAX_REPLACEABLES],
389 std::vector<std::string>* inlines) const;
390
391 // Parse the "test:" line.
392 void parseTest(Scanner* scanner);
393
394 // Return true if we need to generate tests for this function.
395 bool hasTests(int versionOfTestFiles) const;
396
397 // Parse a function specification and add it to specFile.
Jean-Luc Brouillet2217eb72015-04-24 14:41:48 -0700398 static void scanFunctionSpecification(Scanner* scanner, SpecFile* specFile, int maxApiLevel);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700399};
400
401/* A concrete version of a function specification, where all placeholders have been replaced by
402 * actual values.
403 */
404class FunctionPermutation {
405private:
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700406 // These are the expanded version of those found on FunctionSpecification
407 std::string mName;
408 std::string mNameTrunk; // The name without any expansion, e.g. convert
409 std::string mTest; // How to test. One of "scalar", "vector", "noverify", "limited", and
410 // "none".
411 std::string mPrecisionLimit; // Maximum precision required when checking output of this
412 // function.
413
414 // The parameters of the function. This does not include the return type. Owned.
415 std::vector<ParameterDefinition*> mParams;
416 // The return type. nullptr if a void function. Owned.
417 ParameterDefinition* mReturn;
418
419 // The number of input and output parameters. mOutputCount counts the return type.
420 int mInputCount;
421 int mOutputCount;
422
423 // Whether one of the output parameters is a float.
424 bool mHasFloatAnswers;
425
426 // The inline code that implements this function. Will be empty if not an inline.
427 std::vector<std::string> mInline;
428
429public:
430 FunctionPermutation(Function* function, FunctionSpecification* specification,
431 int replacementIndexes[MAX_REPLACEABLES], Scanner* scanner);
432 ~FunctionPermutation();
433
434 std::string getName() const { return mName; }
435 std::string getNameTrunk() const { return mNameTrunk; }
436 std::string getTest() const { return mTest; }
437 std::string getPrecisionLimit() const { return mPrecisionLimit; }
438
Jean-Luc Brouillet66fea242015-04-09 16:47:59 -0700439 const std::vector<std::string>& getInline() const { return mInline; }
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700440 const ParameterDefinition* getReturn() const { return mReturn; }
441 int getInputCount() const { return mInputCount; }
442 int getOutputCount() const { return mOutputCount; }
443 bool hasFloatAnswers() const { return mHasFloatAnswers; }
444
445 const std::vector<ParameterDefinition*> getParams() const { return mParams; }
446};
447
448// An entire spec file and the methods to process it.
449class SpecFile {
450private:
451 std::string mSpecFileName;
452 std::string mHeaderFileName;
453 std::string mDetailedDocumentationUrl;
454 std::string mBriefDescription;
455 std::vector<std::string> mFullDescription;
456 // Text to insert as-is in the generated header.
457 std::vector<std::string> mVerbatimInclude;
458
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700459 /* The constants, types, and functions specifications declared in this
460 * file, in the order they are found in the file. This matters for
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700461 * header generation, as some types and inline functions depend
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700462 * on each other. Pointers not owned.
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700463 */
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700464 std::list<ConstantSpecification*> mConstantSpecificationsList;
465 std::list<TypeSpecification*> mTypeSpecificationsList;
466 std::list<FunctionSpecification*> mFunctionSpecificationsList;
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700467
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700468 /* The constants, types, and functions that are documented in this file.
469 * In very rare cases, specifications for an API are split across multiple
470 * files, e.g. currently for ClearObject(). The documentation for
471 * that function must be found in the first spec file encountered, so the
472 * order of the files on the command line matters.
473 */
474 std::map<std::string, Constant*> mDocumentedConstants;
475 std::map<std::string, Type*> mDocumentedTypes;
476 std::map<std::string, Function*> mDocumentedFunctions;
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700477
478public:
479 explicit SpecFile(const std::string& specFileName);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700480
481 std::string getSpecFileName() const { return mSpecFileName; }
482 std::string getHeaderFileName() const { return mHeaderFileName; }
483 std::string getDetailedDocumentationUrl() const { return mDetailedDocumentationUrl; }
484 const std::string getBriefDescription() const { return mBriefDescription; }
485 const std::vector<std::string>& getFullDescription() const { return mFullDescription; }
486 const std::vector<std::string>& getVerbatimInclude() const { return mVerbatimInclude; }
487
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700488 const std::list<ConstantSpecification*>& getConstantSpecifications() const {
489 return mConstantSpecificationsList;
490 }
491 const std::list<TypeSpecification*>& getTypeSpecifications() const {
492 return mTypeSpecificationsList;
493 }
494 const std::list<FunctionSpecification*>& getFunctionSpecifications() const {
495 return mFunctionSpecificationsList;
496 }
497 const std::map<std::string, Constant*>& getDocumentedConstants() const {
498 return mDocumentedConstants;
499 }
500 const std::map<std::string, Type*>& getDocumentedTypes() const { return mDocumentedTypes; }
501 const std::map<std::string, Function*>& getDocumentedFunctions() const {
502 return mDocumentedFunctions;
503 }
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700504
Jean-Luc Brouillet2217eb72015-04-24 14:41:48 -0700505 bool hasSpecifications() const {
506 return !mDocumentedConstants.empty() || !mDocumentedTypes.empty() ||
507 !mDocumentedFunctions.empty();
508 }
509
510 bool readSpecFile(int maxApiLevel);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700511
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700512 /* These are called by the parser to keep track of the specifications defined in this file.
513 * hasDocumentation is true if this specification containes the documentation.
514 */
515 void addConstantSpecification(ConstantSpecification* spec, bool hasDocumentation);
516 void addTypeSpecification(TypeSpecification* spec, bool hasDocumentation);
517 void addFunctionSpecification(FunctionSpecification* spec, bool hasDocumentation);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700518};
519
520// The collection of all the spec files.
521class SystemSpecification {
522private:
523 std::vector<SpecFile*> mSpecFiles;
524
525 /* Entries in the table of contents. We accumulate them in a map to sort them.
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700526 * Pointers are owned.
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700527 */
528 std::map<std::string, Constant*> mConstants;
529 std::map<std::string, Type*> mTypes;
530 std::map<std::string, Function*> mFunctions;
531
532public:
533 ~SystemSpecification();
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700534
535 /* These are called the parser to create unique instances per name. Set *created to true
536 * if the named specification did not already exist.
537 */
538 Constant* findOrCreateConstant(const std::string& name, bool* created);
539 Type* findOrCreateType(const std::string& name, bool* created);
540 Function* findOrCreateFunction(const std::string& name, bool* created);
541
Jean-Luc Brouillet2217eb72015-04-24 14:41:48 -0700542 /* Parse the spec file and create the object hierarchy, adding a pointer to mSpecFiles.
543 * We won't include information passed the specified level.
544 */
545 bool readSpecFile(const std::string& fileName, int maxApiLevel);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700546 // Generate all the files.
Jean-Luc Brouillet2217eb72015-04-24 14:41:48 -0700547 bool generateFiles(bool forVerification, int maxApiLevel) const;
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700548
549 const std::vector<SpecFile*>& getSpecFiles() const { return mSpecFiles; }
550 const std::map<std::string, Constant*>& getConstants() const { return mConstants; }
551 const std::map<std::string, Type*>& getTypes() const { return mTypes; }
552 const std::map<std::string, Function*>& getFunctions() const { return mFunctions; }
553
554 // Returns "<a href='...'> for the named specification, or empty if not found.
555 std::string getHtmlAnchor(const std::string& name) const;
556};
557
558// Singleton that represents the collection of all the specs we're processing.
559extern SystemSpecification systemSpecification;
560
561// Table of equivalences of numerical types.
562extern const NumericalType TYPES[];
563extern const int NUM_TYPES;
564
565#endif // ANDROID_RS_API_GENERATOR_SPECIFICATION_H