1 /* 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 <climits> 23 #include <fstream> 24 #include <list> 25 #include <map> 26 #include <string> 27 #include <vector> 28 29 class Constant; 30 class ConstantSpecification; 31 class Function; 32 class FunctionPermutation; 33 class FunctionSpecification; 34 class SpecFile; 35 class Specification; 36 class Scanner; 37 class SystemSpecification; 38 class Type; 39 class TypeSpecification; 40 41 enum NumberKind { SIGNED_INTEGER, UNSIGNED_INTEGER, FLOATING_POINT }; 42 43 // Table of type equivalences. 44 struct NumericalType { 45 const char* specType; // Name found in the .spec file 46 const char* rsDataType; // RS data type 47 const char* cType; // Type in a C file 48 const char* javaType; // Type in a Java file 49 NumberKind kind; 50 /* For integers, number of bits of the number, excluding the sign bit. 51 * For floats, number of implied bits of the mantissa. 52 */ 53 int significantBits; 54 // For floats, number of bits of the exponent. 0 for integer types. 55 int exponentBits; 56 }; 57 58 /* Corresponds to one parameter line in a .spec file. These will be parsed when 59 * we instantiate the FunctionPermutation(s) that correspond to one FunctionSpecification. 60 */ 61 struct ParameterEntry { 62 std::string type; 63 std::string name; 64 /* Optional information on how to generate test values for this parameter. Can be: 65 * - range(low, high): Generates values between these two limits only. 66 * - above(other_parameter): The values must be greater than those of the named parameter. 67 * Used for clamp. 68 * - compatible(type): The values must also be fully representable in the specified type. 69 * - conditional: Don't verify this value the function return NaN. 70 */ 71 std::string testOption; 72 std::string documentation; 73 int lineNumber; 74 }; 75 76 /* Information about a parameter to a function. The values of all the fields should only be set by 77 * parseParameterDefinition. 78 */ 79 struct ParameterDefinition { 80 std::string rsType; // The Renderscript type, e.g. "uint3" 81 std::string rsBaseType; // As above but without the number, e.g. "uint" 82 std::string javaBaseType; // The type we need to declare in Java, e.g. "unsigned int" 83 std::string specType; // The type found in the spec, e.g. "f16" 84 bool isFloatType; // True if it's a floating point value 85 /* The number of entries in the vector. It should be either "1", "2", "3", or "4". It's also 86 * "1" for scalars. 87 */ 88 std::string mVectorSize; 89 /* The space the vector takes in an array. It's the same as the vector size, except for size 90 * "3", where the width is "4". 91 */ 92 std::string vectorWidth; 93 94 std::string specName; // e.g. x, as found in the spec file 95 std::string variableName; // e.g. inX, used both in .rs and .java 96 std::string rsAllocName; // e.g. gAllocInX 97 std::string javaAllocName; // e.g. inX 98 std::string javaArrayName; // e.g. arrayInX 99 std::string doubleVariableName; // e.g. inXDouble, used in .java for storing Float16 parameters 100 // in double. 101 102 // If non empty, the mininum and maximum values to be used when generating the test data. 103 std::string minValue; 104 std::string maxValue; 105 /* If non empty, contains the name of another parameter that should be smaller or equal to this 106 * parameter, i.e. value(smallerParameter) <= value(this). This is used when testing clamp. 107 */ 108 std::string smallerParameter; 109 110 bool isOutParameter; // True if this parameter returns data from the script. 111 bool undefinedIfOutIsNan; // If true, we don't validate if 'out' is NaN. 112 113 int typeIndex; // Index in the TYPES array. Negative if not found in the array. 114 int compatibleTypeIndex; // Index in TYPES for which the test data must also fit. 115 116 /* Fill this object from the type, name, and testOption. 117 * isReturn is true if we're processing the "return:" 118 */ 119 void parseParameterDefinition(const std::string& type, const std::string& name, 120 const std::string& testOption, int lineNumber, bool isReturn, 121 Scanner* scanner); 122 isFloat16ParameterParameterDefinition123 bool isFloat16Parameter() const { return specType.compare("f16") == 0; } 124 }; 125 126 struct VersionInfo { 127 /* The range of versions a specification applies to. Zero if there's no restriction, 128 * so an API that became available at 12 and is still valid would have min:12 max:0. 129 * If non zero, both versions should be at least 9, the API level that introduced 130 * RenderScript. 131 */ 132 unsigned int minVersion; 133 unsigned int maxVersion; 134 // Either 0, 32 or 64. If 0, this definition is valid for both 32 and 64 bits. 135 int intSize; 136 VersionInfoVersionInfo137 VersionInfo() : minVersion(0), maxVersion(0), intSize(0) {} 138 /* Scan the version info from the spec file. maxApiLevel specifies the maximum level 139 * we are interested in. This may alter maxVersion. This method returns false if the 140 * minVersion is greater than the maxApiLevel. 141 */ 142 bool scan(Scanner* scanner, unsigned int maxApiLevel); 143 /* Return true if the target can be found whitin the range. */ includesVersionVersionInfo144 bool includesVersion(int target) const { 145 return (minVersion == 0 || target >= minVersion) && 146 (maxVersion == 0 || target <= maxVersion); 147 } 148 149 static constexpr unsigned int kUnreleasedVersion = UINT_MAX; 150 }; 151 152 // We have three type of definitions 153 class Definition { 154 protected: 155 std::string mName; 156 /* If greater than 0, this definition is deprecated. It's the API level at which 157 * we added the deprecation warning. 158 */ 159 int mDeprecatedApiLevel; 160 std::string mDeprecatedMessage; // Optional specific warning if the API is deprecated 161 bool mHidden; // True if it should not be documented 162 std::string mSummary; // A one-line description 163 std::vector<std::string> mDescription; // The comments to be included in the header 164 std::string mUrl; // The URL of the detailed documentation 165 int mFinalVersion; // API level at which this API was removed, 0 if API is still valid 166 167 public: 168 Definition(const std::string& name); 169 getName()170 std::string getName() const { return mName; } deprecated()171 bool deprecated() const { return mDeprecatedApiLevel > 0; } getDeprecatedApiLevel()172 int getDeprecatedApiLevel() const { return mDeprecatedApiLevel; } getDeprecatedMessage()173 std::string getDeprecatedMessage() const { return mDeprecatedMessage; } hidden()174 bool hidden() const { return mHidden; } getSummary()175 std::string getSummary() const { return mSummary; } getDescription()176 const std::vector<std::string>& getDescription() const { return mDescription; } getUrl()177 std::string getUrl() const { return mUrl; } getFinalVersion()178 int getFinalVersion() const { return mFinalVersion; } 179 180 void scanDocumentationTags(Scanner* scanner, bool firstOccurence, const SpecFile* specFile); 181 // Keep track of the final version of this API, if any. 182 void updateFinalVersion(const VersionInfo& info); 183 }; 184 185 /* Represents a constant, like M_PI. This is a grouping of the version specific specifications. 186 * We'll only have one instance of Constant for each name. 187 */ 188 class Constant : public Definition { 189 private: 190 std::vector<ConstantSpecification*> mSpecifications; // Owned 191 192 public: Constant(const std::string & name)193 Constant(const std::string& name) : Definition(name) {} 194 ~Constant(); 195 getSpecifications()196 const std::vector<ConstantSpecification*> getSpecifications() const { return mSpecifications; } 197 // This method should only be called by the scanning code. addSpecification(ConstantSpecification * spec)198 void addSpecification(ConstantSpecification* spec) { mSpecifications.push_back(spec); } 199 }; 200 201 /* Represents a type, like "float4". This is a grouping of the version specific specifications. 202 * We'll only have one instance of Type for each name. 203 */ 204 class Type : public Definition { 205 private: 206 std::vector<TypeSpecification*> mSpecifications; // Owned 207 208 public: Type(const std::string & name)209 Type(const std::string& name) : Definition(name) {} 210 ~Type(); 211 getSpecifications()212 const std::vector<TypeSpecification*> getSpecifications() const { return mSpecifications; } 213 // This method should only be called by the scanning code. addSpecification(TypeSpecification * spec)214 void addSpecification(TypeSpecification* spec) { mSpecifications.push_back(spec); } 215 }; 216 217 /* Represents a function, like "clamp". Even though the spec file contains many entries for clamp, 218 * we'll only have one clamp instance. 219 */ 220 class Function : public Definition { 221 private: 222 // mName in the base class contains the lower case name, e.g. native_log 223 std::string mCapitalizedName; // The capitalized name, e.g. NativeLog 224 225 // The unique parameters between all the specifications. NOT OWNED. 226 std::vector<ParameterEntry*> mParameters; 227 std::string mReturnDocumentation; 228 229 std::vector<FunctionSpecification*> mSpecifications; // Owned 230 231 public: 232 Function(const std::string& name); 233 ~Function(); 234 getCapitalizedName()235 std::string getCapitalizedName() const { return mCapitalizedName; } getParameters()236 const std::vector<ParameterEntry*>& getParameters() const { return mParameters; } getReturnDocumentation()237 std::string getReturnDocumentation() const { return mReturnDocumentation; } getSpecifications()238 const std::vector<FunctionSpecification*> getSpecifications() const { return mSpecifications; } 239 240 bool someParametersAreDocumented() const; 241 242 // The following methods should only be called by the scanning code. 243 void addParameter(ParameterEntry* entry, Scanner* scanner); 244 void addReturn(ParameterEntry* entry, Scanner* scanner); addSpecification(FunctionSpecification * spec)245 void addSpecification(FunctionSpecification* spec) { mSpecifications.push_back(spec); } 246 }; 247 248 /* Base class for TypeSpecification, ConstantSpecification, and FunctionSpecification. 249 * A specification can be specific to a range of RenderScript version or 32bits vs 64 bits. 250 * This base class contains code to parse and store this version information. 251 */ 252 class Specification { 253 protected: 254 VersionInfo mVersionInfo; 255 void scanVersionInfo(Scanner* scanner); 256 257 public: getVersionInfo()258 VersionInfo getVersionInfo() const { return mVersionInfo; } 259 }; 260 261 /* Defines one of the many variations of a constant. There's a one to one correspondance between 262 * ConstantSpecification objects and entries in the spec file. 263 */ 264 class ConstantSpecification : public Specification { 265 private: 266 Constant* mConstant; // Not owned 267 268 std::string mValue; // E.g. "3.1415" 269 public: ConstantSpecification(Constant * constant)270 ConstantSpecification(Constant* constant) : mConstant(constant) {} 271 getConstant()272 Constant* getConstant() const { return mConstant; } getValue()273 std::string getValue() const { return mValue; } 274 275 // Parse a constant specification and add it to specFile. 276 static void scanConstantSpecification(Scanner* scanner, SpecFile* specFile, unsigned int maxApiLevel); 277 }; 278 279 enum TypeKind { 280 SIMPLE, 281 RS_OBJECT, 282 STRUCT, 283 ENUM, 284 }; 285 286 /* Defines one of the many variations of a type. There's a one to one correspondance between 287 * TypeSpecification objects and entries in the spec file. 288 */ 289 class TypeSpecification : public Specification { 290 private: 291 Type* mType; // Not owned 292 293 TypeKind mKind; // The kind of type specification 294 295 // If mKind is SIMPLE: 296 std::string mSimpleType; // The definition of the type 297 298 // If mKind is STRUCT: 299 std::string mStructName; // The name found after the struct keyword 300 std::vector<std::string> mFields; // One entry per struct field 301 std::vector<std::string> mFieldComments; // One entry per struct field 302 std::string mAttribute; // Some structures may have attributes 303 304 // If mKind is ENUM: 305 std::string mEnumName; // The name found after the enum keyword 306 std::vector<std::string> mValues; // One entry per enum value 307 std::vector<std::string> mValueComments; // One entry per enum value 308 public: TypeSpecification(Type * type)309 TypeSpecification(Type* type) : mType(type) {} 310 getType()311 Type* getType() const { return mType; } getKind()312 TypeKind getKind() const { return mKind; } getSimpleType()313 std::string getSimpleType() const { return mSimpleType; } getStructName()314 std::string getStructName() const { return mStructName; } getFields()315 const std::vector<std::string>& getFields() const { return mFields; } getFieldComments()316 const std::vector<std::string>& getFieldComments() const { return mFieldComments; } getAttribute()317 std::string getAttribute() const { return mAttribute; } getEnumName()318 std::string getEnumName() const { return mEnumName; } getValues()319 const std::vector<std::string>& getValues() const { return mValues; } getValueComments()320 const std::vector<std::string>& getValueComments() const { return mValueComments; } 321 322 // Parse a type specification and add it to specFile. 323 static void scanTypeSpecification(Scanner* scanner, SpecFile* specFile, unsigned int maxApiLevel); 324 }; 325 326 // Maximum number of placeholders (like #1, #2) in function specifications. 327 const int MAX_REPLACEABLES = 4; 328 329 /* Defines one of the many variations of the function. There's a one to one correspondance between 330 * FunctionSpecification objects and entries in the spec file. Some of the strings that are parts 331 * of a FunctionSpecification can include placeholders, which are "#1", "#2", "#3", and "#4". We'll 332 * replace these by values before generating the files. 333 */ 334 class FunctionSpecification : public Specification { 335 private: 336 Function* mFunction; // Not owned 337 338 /* How to test. One of: 339 * "scalar": Generate test code that checks entries of each vector indepently. E.g. for 340 * sin(float3), the test code will call the CoreMathVerfier.computeSin 3 times. 341 * "limited": Like "scalar" but we don't generate extreme values. This is not currently 342 * enabled as we were generating to many errors. 343 * "custom": Like "scalar" but instead of calling CoreMathVerifier.computeXXX() to compute 344 * the expected value, we call instead CoreMathVerifier.verifyXXX(). This method 345 * returns a string that contains the error message, null if there's no error. 346 * "vector": Generate test code that calls the CoreMathVerifier only once for each vector. 347 * This is useful for APIs like dot() or length(). 348 * "noverify": Generate test code that calls the API but don't verify the returned value. 349 * This can discover unresolved references. 350 * "": Don't test. This is the default. 351 */ 352 std::string mTest; 353 bool mInternal; // Internal. Not visible to users. (Default: false) 354 bool mIntrinsic; // Compiler intrinsic that is lowered to an internal API. 355 // (Default: false) 356 std::string mAttribute; // Function attributes. 357 std::string mPrecisionLimit; // Maximum precision required when checking output of this 358 // function. 359 360 // The vectors of values with which we'll replace #1, #2, ... 361 std::vector<std::vector<std::string> > mReplaceables; 362 363 // i-th entry is true if each entry in mReplaceables[i] has an equivalent 364 // RS numerical type (i.e. present in TYPES global) 365 std::vector<bool> mIsRSTAllowed; 366 367 /* The collection of permutations for this specification, i.e. this class instantianted 368 * for specific values of #1, #2, etc. Owned. 369 */ 370 std::vector<FunctionPermutation*> mPermutations; 371 372 // The following fields may contain placeholders that will be replaced using the mReplaceables. 373 374 /* As of this writing, convert_... is the only function with #1 in its name. 375 * The related Function object contains the name of the function without #n, e.g. convert. 376 * This is the name with the #, e.g. convert_#1_#2 377 */ 378 std::string mUnexpandedName; 379 ParameterEntry* mReturn; // The return type. The name should be empty. Owned. 380 std::vector<ParameterEntry*> mParameters; // The parameters. Owned. 381 std::vector<std::string> mInline; // The inline code to be included in the header 382 383 /* Substitute the placeholders in the strings (e.g. #1, #2, ...) by the 384 * corresponding entries in mReplaceables. Substitute placeholders for RS 385 * types (#RST_1, #RST_2, ...) by the RS Data type strings (UNSIGNED_8, 386 * FLOAT_32 etc.) of the corresponding types in mReplaceables. 387 * indexOfReplaceable1 selects with value to use for #1, same for 2, 3, and 388 * 4. 389 */ 390 std::string expandString(std::string s, int indexOfReplaceable[MAX_REPLACEABLES]) const; 391 void expandStringVector(const std::vector<std::string>& in, 392 int replacementIndexes[MAX_REPLACEABLES], 393 std::vector<std::string>* out) const; 394 395 // Helper function used by expandString to perform #RST_* substitution 396 std::string expandRSTypeInString(const std::string &s, 397 const std::string &pattern, 398 const std::string &cTypeStr) const; 399 400 // Fill the mPermutations field. 401 void createPermutations(Function* function, Scanner* scanner); 402 403 public: FunctionSpecification(Function * function)404 FunctionSpecification(Function* function) : mFunction(function), mInternal(false), 405 mIntrinsic(false), mReturn(nullptr) {} 406 ~FunctionSpecification(); 407 getFunction()408 Function* getFunction() const { return mFunction; } isInternal()409 bool isInternal() const { return mInternal; } isIntrinsic()410 bool isIntrinsic() const { return mIntrinsic; } getAttribute()411 std::string getAttribute() const { return mAttribute; } getTest()412 std::string getTest() const { return mTest; } getPrecisionLimit()413 std::string getPrecisionLimit() const { return mPrecisionLimit; } 414 getPermutations()415 const std::vector<FunctionPermutation*>& getPermutations() const { return mPermutations; } 416 417 std::string getName(int replacementIndexes[MAX_REPLACEABLES]) const; 418 void getReturn(int replacementIndexes[MAX_REPLACEABLES], std::string* retType, 419 int* lineNumber) const; getNumberOfParams()420 size_t getNumberOfParams() const { return mParameters.size(); } 421 void getParam(size_t index, int replacementIndexes[MAX_REPLACEABLES], std::string* type, 422 std::string* name, std::string* testOption, int* lineNumber) const; 423 void getInlines(int replacementIndexes[MAX_REPLACEABLES], 424 std::vector<std::string>* inlines) const; 425 426 // Parse the "test:" line. 427 void parseTest(Scanner* scanner); 428 429 // Return true if we need to generate tests for this function. 430 bool hasTests(unsigned int versionOfTestFiles) const; 431 hasInline()432 bool hasInline() const { return mInline.size() > 0; } 433 434 /* Return true if this function can be overloaded. This is added by default to all 435 * specifications, so except for the very few exceptions that start the attributes 436 * with an '=' to avoid this, we'll return true. 437 */ isOverloadable()438 bool isOverloadable() const { 439 return mAttribute.empty() || mAttribute[0] != '='; 440 } 441 442 /* Check if RST_i is present in 's' and report an error if 'allow' is false 443 * or the i-th replacement list is not a valid candidate for RST_i 444 * replacement 445 */ 446 void checkRSTPatternValidity(const std::string &s, bool allow, Scanner *scanner); 447 448 // Parse a function specification and add it to specFile. 449 static void scanFunctionSpecification(Scanner* scanner, SpecFile* specFile, unsigned int maxApiLevel); 450 }; 451 452 /* A concrete version of a function specification, where all placeholders have been replaced by 453 * actual values. 454 */ 455 class FunctionPermutation { 456 private: 457 // These are the expanded version of those found on FunctionSpecification 458 std::string mName; 459 std::string mNameTrunk; // The name without any expansion, e.g. convert 460 std::string mTest; // How to test. One of "scalar", "vector", "noverify", "limited", and 461 // "none". 462 std::string mPrecisionLimit; // Maximum precision required when checking output of this 463 // function. 464 465 // The parameters of the function. This does not include the return type. Owned. 466 std::vector<ParameterDefinition*> mParams; 467 // The return type. nullptr if a void function. Owned. 468 ParameterDefinition* mReturn; 469 470 // The number of input and output parameters. mOutputCount counts the return type. 471 int mInputCount; 472 int mOutputCount; 473 474 // Whether one of the output parameters is a float. 475 bool mHasFloatAnswers; 476 477 // The inline code that implements this function. Will be empty if not an inline. 478 std::vector<std::string> mInline; 479 480 public: 481 FunctionPermutation(Function* function, FunctionSpecification* specification, 482 int replacementIndexes[MAX_REPLACEABLES], Scanner* scanner); 483 ~FunctionPermutation(); 484 getName()485 std::string getName() const { return mName; } getNameTrunk()486 std::string getNameTrunk() const { return mNameTrunk; } getTest()487 std::string getTest() const { return mTest; } getPrecisionLimit()488 std::string getPrecisionLimit() const { return mPrecisionLimit; } 489 getInline()490 const std::vector<std::string>& getInline() const { return mInline; } getReturn()491 const ParameterDefinition* getReturn() const { return mReturn; } getInputCount()492 int getInputCount() const { return mInputCount; } getOutputCount()493 int getOutputCount() const { return mOutputCount; } hasFloatAnswers()494 bool hasFloatAnswers() const { return mHasFloatAnswers; } 495 getParams()496 const std::vector<ParameterDefinition*> getParams() const { return mParams; } 497 }; 498 499 // An entire spec file and the methods to process it. 500 class SpecFile { 501 private: 502 std::string mSpecFileName; 503 std::string mHeaderFileName; 504 std::string mDetailedDocumentationUrl; 505 std::string mBriefDescription; 506 std::vector<std::string> mFullDescription; 507 // Text to insert as-is in the generated header. 508 std::vector<std::string> mVerbatimInclude; 509 510 /* The constants, types, and functions specifications declared in this 511 * file, in the order they are found in the file. This matters for 512 * header generation, as some types and inline functions depend 513 * on each other. Pointers not owned. 514 */ 515 std::list<ConstantSpecification*> mConstantSpecificationsList; 516 std::list<TypeSpecification*> mTypeSpecificationsList; 517 std::list<FunctionSpecification*> mFunctionSpecificationsList; 518 519 /* The constants, types, and functions that are documented in this file. 520 * In very rare cases, specifications for an API are split across multiple 521 * files, e.g. currently for ClearObject(). The documentation for 522 * that function must be found in the first spec file encountered, so the 523 * order of the files on the command line matters. 524 */ 525 std::map<std::string, Constant*> mDocumentedConstants; 526 std::map<std::string, Type*> mDocumentedTypes; 527 std::map<std::string, Function*> mDocumentedFunctions; 528 529 public: 530 explicit SpecFile(const std::string& specFileName); 531 getSpecFileName()532 std::string getSpecFileName() const { return mSpecFileName; } getHeaderFileName()533 std::string getHeaderFileName() const { return mHeaderFileName; } getDetailedDocumentationUrl()534 std::string getDetailedDocumentationUrl() const { return mDetailedDocumentationUrl; } getBriefDescription()535 const std::string getBriefDescription() const { return mBriefDescription; } getFullDescription()536 const std::vector<std::string>& getFullDescription() const { return mFullDescription; } getVerbatimInclude()537 const std::vector<std::string>& getVerbatimInclude() const { return mVerbatimInclude; } 538 getConstantSpecifications()539 const std::list<ConstantSpecification*>& getConstantSpecifications() const { 540 return mConstantSpecificationsList; 541 } getTypeSpecifications()542 const std::list<TypeSpecification*>& getTypeSpecifications() const { 543 return mTypeSpecificationsList; 544 } getFunctionSpecifications()545 const std::list<FunctionSpecification*>& getFunctionSpecifications() const { 546 return mFunctionSpecificationsList; 547 } getDocumentedConstants()548 const std::map<std::string, Constant*>& getDocumentedConstants() const { 549 return mDocumentedConstants; 550 } getDocumentedTypes()551 const std::map<std::string, Type*>& getDocumentedTypes() const { return mDocumentedTypes; } getDocumentedFunctions()552 const std::map<std::string, Function*>& getDocumentedFunctions() const { 553 return mDocumentedFunctions; 554 } 555 hasSpecifications()556 bool hasSpecifications() const { 557 return !mDocumentedConstants.empty() || !mDocumentedTypes.empty() || 558 !mDocumentedFunctions.empty(); 559 } 560 561 bool readSpecFile(unsigned int maxApiLevel); 562 563 /* These are called by the parser to keep track of the specifications defined in this file. 564 * hasDocumentation is true if this specification containes the documentation. 565 */ 566 void addConstantSpecification(ConstantSpecification* spec, bool hasDocumentation); 567 void addTypeSpecification(TypeSpecification* spec, bool hasDocumentation); 568 void addFunctionSpecification(FunctionSpecification* spec, bool hasDocumentation); 569 }; 570 571 // The collection of all the spec files. 572 class SystemSpecification { 573 private: 574 std::vector<SpecFile*> mSpecFiles; 575 576 /* Entries in the table of contents. We accumulate them in a map to sort them. 577 * Pointers are owned. 578 */ 579 std::map<std::string, Constant*> mConstants; 580 std::map<std::string, Type*> mTypes; 581 std::map<std::string, Function*> mFunctions; 582 583 public: 584 ~SystemSpecification(); 585 586 /* These are called the parser to create unique instances per name. Set *created to true 587 * if the named specification did not already exist. 588 */ 589 Constant* findOrCreateConstant(const std::string& name, bool* created); 590 Type* findOrCreateType(const std::string& name, bool* created); 591 Function* findOrCreateFunction(const std::string& name, bool* created); 592 593 /* Parse the spec file and create the object hierarchy, adding a pointer to mSpecFiles. 594 * We won't include information passed the specified level. 595 */ 596 bool readSpecFile(const std::string& fileName, unsigned int maxApiLevel); 597 // Generate all the files. 598 bool generateFiles(bool forVerification, unsigned int maxApiLevel) const; 599 getSpecFiles()600 const std::vector<SpecFile*>& getSpecFiles() const { return mSpecFiles; } getConstants()601 const std::map<std::string, Constant*>& getConstants() const { return mConstants; } getTypes()602 const std::map<std::string, Type*>& getTypes() const { return mTypes; } getFunctions()603 const std::map<std::string, Function*>& getFunctions() const { return mFunctions; } 604 605 // Returns "<a href='...'> for the named specification, or empty if not found. 606 std::string getHtmlAnchor(const std::string& name) const; 607 608 // Returns the maximum API level specified in any spec file. 609 unsigned int getMaximumApiLevel(); 610 }; 611 612 // Singleton that represents the collection of all the specs we're processing. 613 extern SystemSpecification systemSpecification; 614 615 // Table of equivalences of numerical types. 616 extern const NumericalType TYPES[]; 617 extern const int NUM_TYPES; 618 619 /* Given a renderscript type (string) calculate the vector size and base type. If the type 620 * is not a vector the vector size is 1 and baseType is just the type itself. 621 */ 622 void getVectorSizeAndBaseType(const std::string& type, std::string& vectorSize, 623 std::string& baseType); 624 625 #endif // ANDROID_RS_API_GENERATOR_SPECIFICATION_H 626