1c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/* 2c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Copyright (C) 2013 The Android Open Source Project 3c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * 4c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Licensed under the Apache License, Version 2.0 (the "License"); 5c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * you may not use this file except in compliance with the License. 6c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * You may obtain a copy of the License at 7c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * 8c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * http://www.apache.org/licenses/LICENSE-2.0 9c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * 10c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Unless required by applicable law or agreed to in writing, software 11c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * distributed under the License is distributed on an "AS IS" BASIS, 12c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * See the License for the specific language governing permissions and 14c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * limitations under the License. 15c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet */ 16c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 17c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include <stdio.h> 18c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include <cctype> 19c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include <cstdlib> 20c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include <fstream> 21c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include <functional> 22c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include <iostream> 23c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include <memory> 24c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include <sstream> 25c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include <strings.h> 26c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 27c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include "Generator.h" 28c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include "Scanner.h" 29c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include "Specification.h" 30c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include "Utilities.h" 31c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 32c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletusing namespace std; 33c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 34c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet// API level when RenderScript was added. 3512398d81f32e5e0479d02b8608a83c75cd991bb3Yang Niconst unsigned int MIN_API_LEVEL = 9; 36c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 37c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletconst NumericalType TYPES[] = { 383b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar {"f16", "FLOAT_16", "half", "short", FLOATING_POINT, 11, 5}, 39c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet {"f32", "FLOAT_32", "float", "float", FLOATING_POINT, 24, 8}, 40c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet {"f64", "FLOAT_64", "double", "double", FLOATING_POINT, 53, 11}, 41c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet {"i8", "SIGNED_8", "char", "byte", SIGNED_INTEGER, 7, 0}, 42c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet {"u8", "UNSIGNED_8", "uchar", "byte", UNSIGNED_INTEGER, 8, 0}, 43c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet {"i16", "SIGNED_16", "short", "short", SIGNED_INTEGER, 15, 0}, 44c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet {"u16", "UNSIGNED_16", "ushort", "short", UNSIGNED_INTEGER, 16, 0}, 45c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet {"i32", "SIGNED_32", "int", "int", SIGNED_INTEGER, 31, 0}, 46c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet {"u32", "UNSIGNED_32", "uint", "int", UNSIGNED_INTEGER, 32, 0}, 47c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet {"i64", "SIGNED_64", "long", "long", SIGNED_INTEGER, 63, 0}, 48c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet {"u64", "UNSIGNED_64", "ulong", "long", UNSIGNED_INTEGER, 64, 0}, 49c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}; 50c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 51c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletconst int NUM_TYPES = sizeof(TYPES) / sizeof(TYPES[0]); 52c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 5312398d81f32e5e0479d02b8608a83c75cd991bb3Yang Nistatic const char kTagUnreleased[] = "UNRELEASED"; 5412398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni 5543d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar// Patterns that get substituted with C type or RS Data type names in function 5643d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar// names, arguments, return types, and inlines. 5743d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainarstatic const string kCTypePatterns[] = {"#1", "#2", "#3", "#4"}; 5843d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainarstatic const string kRSTypePatterns[] = {"#RST_1", "#RST_2", "#RST_3", "#RST_4"}; 5943d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar 60c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet// The singleton of the collected information of all the spec files. 61c5184e202ced435258adb2cfe2013570e7190954Jean-Luc BrouilletSystemSpecification systemSpecification; 62c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 63c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet// Returns the index in TYPES for the provided cType 64c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic int findCType(const string& cType) { 65c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (int i = 0; i < NUM_TYPES; i++) { 66c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (cType == TYPES[i].cType) { 67c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return i; 68c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 69c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 70c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return -1; 71c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 72c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 73c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/* Converts a string like "u8, u16" to a vector of "ushort", "uint". 74c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * For non-numerical types, we don't need to convert the abbreviation. 75c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet */ 76c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic vector<string> convertToTypeVector(const string& input) { 77c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // First convert the string to an array of strings. 78c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet vector<string> entries; 79c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet stringstream stream(input); 80c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet string entry; 81c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet while (getline(stream, entry, ',')) { 82c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet trimSpaces(&entry); 83c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet entries.push_back(entry); 84c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 85c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 86c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet /* Second, we look for present numerical types. We do it this way 87c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * so the order of numerical types is always the same, no matter 88c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * how specified in the spec file. 89c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet */ 90c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet vector<string> result; 91c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (auto t : TYPES) { 92c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (auto i = entries.begin(); i != entries.end(); ++i) { 93c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (*i == t.specType) { 94c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet result.push_back(t.cType); 95c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet entries.erase(i); 96c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet break; 97c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 98c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 99c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 100c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 101c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // Add the remaining; they are not numerical types. 102c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (auto s : entries) { 103c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet result.push_back(s); 104c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 105c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 106c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return result; 107c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 108c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 10943d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar// Returns true if each entry in typeVector is an RS numerical type 11043d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainarstatic bool isRSTValid(const vector<string> &typeVector) { 11143d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar for (auto type: typeVector) { 11243d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar if (findCType(type) == -1) 11343d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar return false; 11443d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar } 11543d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar return true; 11643d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar} 11743d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar 1189309a0665a4866f708db9ae67e43b5ea6a27cf27Dean De Leovoid getVectorSizeAndBaseType(const string& type, string& vectorSize, string& baseType) { 1199309a0665a4866f708db9ae67e43b5ea6a27cf27Dean De Leo vectorSize = "1"; 1209309a0665a4866f708db9ae67e43b5ea6a27cf27Dean De Leo baseType = type; 121c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 12266fea24fb5f3a02b744a9c71ae0fc22c03c4fc6eJean-Luc Brouillet /* If it's a vector type, we need to split the base type from the size. 12366fea24fb5f3a02b744a9c71ae0fc22c03c4fc6eJean-Luc Brouillet * We know that's it's a vector type if the last character is a digit and 12466fea24fb5f3a02b744a9c71ae0fc22c03c4fc6eJean-Luc Brouillet * the rest is an actual base type. We used to only verify the first part, 12566fea24fb5f3a02b744a9c71ae0fc22c03c4fc6eJean-Luc Brouillet * which created a problem with rs_matrix2x2. 12666fea24fb5f3a02b744a9c71ae0fc22c03c4fc6eJean-Luc Brouillet */ 1279309a0665a4866f708db9ae67e43b5ea6a27cf27Dean De Leo const int last = type.size() - 1; 1289309a0665a4866f708db9ae67e43b5ea6a27cf27Dean De Leo const char lastChar = type[last]; 129c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (lastChar >= '0' && lastChar <= '9') { 1309309a0665a4866f708db9ae67e43b5ea6a27cf27Dean De Leo const string trimmed = type.substr(0, last); 13166fea24fb5f3a02b744a9c71ae0fc22c03c4fc6eJean-Luc Brouillet int i = findCType(trimmed); 13266fea24fb5f3a02b744a9c71ae0fc22c03c4fc6eJean-Luc Brouillet if (i >= 0) { 1339309a0665a4866f708db9ae67e43b5ea6a27cf27Dean De Leo baseType = trimmed; 1349309a0665a4866f708db9ae67e43b5ea6a27cf27Dean De Leo vectorSize = lastChar; 13566fea24fb5f3a02b744a9c71ae0fc22c03c4fc6eJean-Luc Brouillet } 136c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 1379309a0665a4866f708db9ae67e43b5ea6a27cf27Dean De Leo} 1389309a0665a4866f708db9ae67e43b5ea6a27cf27Dean De Leo 1399309a0665a4866f708db9ae67e43b5ea6a27cf27Dean De Leovoid ParameterDefinition::parseParameterDefinition(const string& type, const string& name, 1409309a0665a4866f708db9ae67e43b5ea6a27cf27Dean De Leo const string& testOption, int lineNumber, 1419309a0665a4866f708db9ae67e43b5ea6a27cf27Dean De Leo bool isReturn, Scanner* scanner) { 1429309a0665a4866f708db9ae67e43b5ea6a27cf27Dean De Leo rsType = type; 1439309a0665a4866f708db9ae67e43b5ea6a27cf27Dean De Leo specName = name; 1449309a0665a4866f708db9ae67e43b5ea6a27cf27Dean De Leo 1459309a0665a4866f708db9ae67e43b5ea6a27cf27Dean De Leo // Determine if this is an output. 1469309a0665a4866f708db9ae67e43b5ea6a27cf27Dean De Leo isOutParameter = isReturn || charRemoved('*', &rsType); 1479309a0665a4866f708db9ae67e43b5ea6a27cf27Dean De Leo 1489309a0665a4866f708db9ae67e43b5ea6a27cf27Dean De Leo getVectorSizeAndBaseType(rsType, mVectorSize, rsBaseType); 14966fea24fb5f3a02b744a9c71ae0fc22c03c4fc6eJean-Luc Brouillet typeIndex = findCType(rsBaseType); 15066fea24fb5f3a02b744a9c71ae0fc22c03c4fc6eJean-Luc Brouillet 151c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (mVectorSize == "3") { 152c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet vectorWidth = "4"; 153c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 154c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet vectorWidth = mVectorSize; 155c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 156c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 157c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet /* Create variable names to be used in the java and .rs files. Because x and 158c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * y are reserved in .rs files, we prefix variable names with "in" or "out". 159c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet */ 160c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (isOutParameter) { 161c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet variableName = "out"; 162c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (!specName.empty()) { 163c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet variableName += capitalize(specName); 164c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else if (!isReturn) { 165c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner->error(lineNumber) << "Should have a name.\n"; 166c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 167f8ccbb19e0d3140114f9512bfd685f37089800d1Pirama Arumuga Nainar doubleVariableName = variableName + "Double"; 168c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 169c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet variableName = "in"; 170c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (specName.empty()) { 171c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner->error(lineNumber) << "Should have a name.\n"; 172c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 173c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet variableName += capitalize(specName); 1743b2be14b4f4e1932f4e67c12d691ca85e937d936Pirama Arumuga Nainar doubleVariableName = variableName + "Double"; 175c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 176c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet rsAllocName = "gAlloc" + capitalize(variableName); 177c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet javaAllocName = variableName; 178c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet javaArrayName = "array" + capitalize(javaAllocName); 179c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 180c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // Process the option. 181c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet undefinedIfOutIsNan = false; 182c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet compatibleTypeIndex = -1; 183c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (!testOption.empty()) { 184c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (testOption.compare(0, 6, "range(") == 0) { 185c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet size_t pComma = testOption.find(','); 186c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet size_t pParen = testOption.find(')'); 187c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (pComma == string::npos || pParen == string::npos) { 188c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner->error(lineNumber) << "Incorrect range " << testOption << "\n"; 189c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 190c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet minValue = testOption.substr(6, pComma - 6); 191c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet maxValue = testOption.substr(pComma + 1, pParen - pComma - 1); 192c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 193c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else if (testOption.compare(0, 6, "above(") == 0) { 194c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet size_t pParen = testOption.find(')'); 195c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (pParen == string::npos) { 196c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner->error(lineNumber) << "Incorrect testOption " << testOption << "\n"; 197c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 198c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet smallerParameter = testOption.substr(6, pParen - 6); 199c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 200c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else if (testOption.compare(0, 11, "compatible(") == 0) { 201c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet size_t pParen = testOption.find(')'); 202c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (pParen == string::npos) { 203c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner->error(lineNumber) << "Incorrect testOption " << testOption << "\n"; 204c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 205c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet compatibleTypeIndex = findCType(testOption.substr(11, pParen - 11)); 206c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 207c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else if (testOption.compare(0, 11, "conditional") == 0) { 208c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet undefinedIfOutIsNan = true; 209c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 210c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner->error(lineNumber) << "Unrecognized testOption " << testOption << "\n"; 211c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 212c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 213c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 214c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet isFloatType = false; 215c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (typeIndex >= 0) { 216c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet javaBaseType = TYPES[typeIndex].javaType; 217c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet specType = TYPES[typeIndex].specType; 218c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet isFloatType = TYPES[typeIndex].exponentBits > 0; 219c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 220c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (!minValue.empty()) { 221c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (typeIndex < 0 || TYPES[typeIndex].kind != FLOATING_POINT) { 222c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner->error(lineNumber) << "range(,) is only supported for floating point\n"; 223c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 224c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 225c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 226c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 22712398d81f32e5e0479d02b8608a83c75cd991bb3Yang Nibool VersionInfo::scan(Scanner* scanner, unsigned int maxApiLevel) { 228c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner->findOptionalTag("version:")) { 229c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const string s = scanner->getValue(); 23012398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni if (s.compare(0, sizeof(kTagUnreleased), kTagUnreleased) == 0) { 23112398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni // The API is still under development and does not have 23212398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni // an official version number. 23312398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni minVersion = maxVersion = kUnreleasedVersion; 23412398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni } else { 23512398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni sscanf(s.c_str(), "%u %u", &minVersion, &maxVersion); 23612398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni if (minVersion && minVersion < MIN_API_LEVEL) { 23712398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni scanner->error() << "Minimum version must >= 9\n"; 23812398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni } 23912398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni if (minVersion == MIN_API_LEVEL) { 24012398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni minVersion = 0; 24112398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni } 24212398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni if (maxVersion && maxVersion < MIN_API_LEVEL) { 24312398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni scanner->error() << "Maximum version must >= 9\n"; 24412398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni } 245c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 246c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 247c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner->findOptionalTag("size:")) { 248c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet sscanf(scanner->getValue().c_str(), "%i", &intSize); 249c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 25012398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni 2512217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet if (maxVersion > maxApiLevel) { 2522217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet maxVersion = maxApiLevel; 2532217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet } 25412398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni 2552217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet return minVersion == 0 || minVersion <= maxApiLevel; 256c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 257c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 25867923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc BrouilletDefinition::Definition(const std::string& name) 25936e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet : mName(name), mDeprecatedApiLevel(0), mHidden(false), mFinalVersion(-1) { 26067923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet} 26167923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet 26267923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouilletvoid Definition::updateFinalVersion(const VersionInfo& info) { 26367923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet /* We set it if: 26467923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet * - We have never set mFinalVersion before, or 26567923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet * - The max version is 0, which means we have not expired this API, or 26667923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet * - We have a max that's later than what we currently have. 26767923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet */ 26867923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet if (mFinalVersion < 0 || info.maxVersion == 0 || 26967923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet (mFinalVersion > 0 && info.maxVersion > mFinalVersion)) { 27067923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet mFinalVersion = info.maxVersion; 27167923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet } 272c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 273c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 2747c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouilletvoid Definition::scanDocumentationTags(Scanner* scanner, bool firstOccurence, 2757c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet const SpecFile* specFile) { 276c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner->findOptionalTag("hidden:")) { 277c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner->checkNoValue(); 278c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mHidden = true; 279c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 2804a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet if (scanner->findOptionalTag("deprecated:")) { 28136e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet string value = scanner->getValue(); 28236e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet size_t pComma = value.find(", "); 28336e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet if (pComma != string::npos) { 28436e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet mDeprecatedMessage = value.substr(pComma + 2); 28536e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet value.erase(pComma); 28636e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet } 28736e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet sscanf(value.c_str(), "%i", &mDeprecatedApiLevel); 28836e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet if (mDeprecatedApiLevel <= 0) { 28936e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet scanner->error() << "deprecated entries should have a level > 0\n"; 29036e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet } 2914a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet } 292c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (firstOccurence) { 293c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner->findTag("summary:")) { 294c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mSummary = scanner->getValue(); 295c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 296c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner->findTag("description:")) { 297c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner->checkNoValue(); 298c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet while (scanner->findOptionalTag("")) { 299c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mDescription.push_back(scanner->getValue()); 300c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 301c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 3027c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet mUrl = specFile->getDetailedDocumentationUrl() + "#android_rs:" + mName; 303c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else if (scanner->findOptionalTag("summary:")) { 304c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner->error() << "Only the first specification should have a summary.\n"; 305c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 306c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 307c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 308c5184e202ced435258adb2cfe2013570e7190954Jean-Luc BrouilletConstant::~Constant() { 309c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (auto i : mSpecifications) { 310c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet delete i; 311c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 312c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 313c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 314c5184e202ced435258adb2cfe2013570e7190954Jean-Luc BrouilletType::~Type() { 315c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (auto i : mSpecifications) { 316c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet delete i; 317c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 318c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 319c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 3207c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc BrouilletFunction::Function(const string& name) : Definition(name) { 321c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mCapitalizedName = capitalize(mName); 322c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 323c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 324c5184e202ced435258adb2cfe2013570e7190954Jean-Luc BrouilletFunction::~Function() { 325c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (auto i : mSpecifications) { 326c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet delete i; 327c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 328c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 329c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 330c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletbool Function::someParametersAreDocumented() const { 331c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (auto p : mParameters) { 332c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (!p->documentation.empty()) { 333c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return true; 334c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 335c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 336c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return false; 337c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 338c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 339c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid Function::addParameter(ParameterEntry* entry, Scanner* scanner) { 340c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (auto i : mParameters) { 341c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (i->name == entry->name) { 342c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // It's a duplicate. 343c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (!entry->documentation.empty()) { 344c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner->error(entry->lineNumber) 345c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet << "Only the first occurence of an arg should have the " 346c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet "documentation.\n"; 347c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 348c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return; 349c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 350c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 351c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mParameters.push_back(entry); 352c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 353c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 354c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid Function::addReturn(ParameterEntry* entry, Scanner* scanner) { 355c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (entry->documentation.empty()) { 356c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return; 357c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 358c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (!mReturnDocumentation.empty()) { 359c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner->error() << "ret: should be documented only for the first variant\n"; 360c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 361c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mReturnDocumentation = entry->documentation; 362c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 363c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 3642217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouilletvoid ConstantSpecification::scanConstantSpecification(Scanner* scanner, SpecFile* specFile, 36512398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni unsigned int maxApiLevel) { 366c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet string name = scanner->getValue(); 3672217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet VersionInfo info; 3682217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet if (!info.scan(scanner, maxApiLevel)) { 3692217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet cout << "Skipping some " << name << " definitions.\n"; 3702217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet scanner->skipUntilTag("end:"); 3712217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet return; 3722217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet } 373c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 374c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet bool created = false; 3757c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet Constant* constant = systemSpecification.findOrCreateConstant(name, &created); 3767c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet ConstantSpecification* spec = new ConstantSpecification(constant); 377c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet constant->addSpecification(spec); 37867923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet constant->updateFinalVersion(info); 3797c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet specFile->addConstantSpecification(spec, created); 3802217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet spec->mVersionInfo = info; 381c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 382c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner->findTag("value:")) { 383c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->mValue = scanner->getValue(); 384c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 385cb25a819dbb5bda7e5554ec5ff09d29586d84493David Gross if (scanner->findTag("type:")) { 386cb25a819dbb5bda7e5554ec5ff09d29586d84493David Gross spec->mType = scanner->getValue(); 387cb25a819dbb5bda7e5554ec5ff09d29586d84493David Gross } 3887c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet constant->scanDocumentationTags(scanner, created, specFile); 389c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 390c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner->findTag("end:"); 391c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 392c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 3932217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouilletvoid TypeSpecification::scanTypeSpecification(Scanner* scanner, SpecFile* specFile, 39412398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni unsigned int maxApiLevel) { 395c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet string name = scanner->getValue(); 3962217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet VersionInfo info; 3972217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet if (!info.scan(scanner, maxApiLevel)) { 3982217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet cout << "Skipping some " << name << " definitions.\n"; 3992217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet scanner->skipUntilTag("end:"); 4002217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet return; 4012217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet } 402c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 403c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet bool created = false; 4047c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet Type* type = systemSpecification.findOrCreateType(name, &created); 4057c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet TypeSpecification* spec = new TypeSpecification(type); 406c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet type->addSpecification(spec); 40767923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet type->updateFinalVersion(info); 4087c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet specFile->addTypeSpecification(spec, created); 4092217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet spec->mVersionInfo = info; 410c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 411c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner->findOptionalTag("simple:")) { 412c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->mKind = SIMPLE; 413c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->mSimpleType = scanner->getValue(); 414c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 415ca51c78b9e3097ee31dd24cdc5982f550ee563d1Stephen Hines if (scanner->findOptionalTag("rs_object:")) { 416ca51c78b9e3097ee31dd24cdc5982f550ee563d1Stephen Hines spec->mKind = RS_OBJECT; 417ca51c78b9e3097ee31dd24cdc5982f550ee563d1Stephen Hines } 418c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner->findOptionalTag("struct:")) { 419c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->mKind = STRUCT; 420c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->mStructName = scanner->getValue(); 421c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet while (scanner->findOptionalTag("field:")) { 422c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet string s = scanner->getValue(); 423c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet string comment; 424c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner->parseDocumentation(&s, &comment); 425c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->mFields.push_back(s); 426c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->mFieldComments.push_back(comment); 427c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 428c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 429c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner->findOptionalTag("enum:")) { 430c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->mKind = ENUM; 431c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->mEnumName = scanner->getValue(); 432c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet while (scanner->findOptionalTag("value:")) { 433c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet string s = scanner->getValue(); 434c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet string comment; 435c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner->parseDocumentation(&s, &comment); 436c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->mValues.push_back(s); 437c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->mValueComments.push_back(comment); 438c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 439c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 44036e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet if (scanner->findOptionalTag("attrib:")) { 44136e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet spec->mAttribute = scanner->getValue(); 44236e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet } 4437c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet type->scanDocumentationTags(scanner, created, specFile); 444c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 445c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner->findTag("end:"); 446c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 447c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 448c5184e202ced435258adb2cfe2013570e7190954Jean-Luc BrouilletFunctionSpecification::~FunctionSpecification() { 449c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (auto i : mParameters) { 450c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet delete i; 451c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 452c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet delete mReturn; 453c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (auto i : mPermutations) { 454c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet delete i; 455c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 456c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 457c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 45843d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainarstring FunctionSpecification::expandRSTypeInString(const string &s, 45943d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar const string &pattern, 46043d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar const string &cTypeStr) const { 46143d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar // Find index of numerical type corresponding to cTypeStr. The case where 46243d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar // pattern is found in s but cTypeStr is not a numerical type is checked in 46343d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar // checkRSTPatternValidity. 46443d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar int typeIdx = findCType(cTypeStr); 46543d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar if (typeIdx == -1) { 46643d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar return s; 46743d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar } 46843d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar // If index exists, perform replacement. 46943d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar return stringReplace(s, pattern, TYPES[typeIdx].rsDataType); 47043d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar} 47143d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar 472c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstring FunctionSpecification::expandString(string s, 473c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet int replacementIndexes[MAX_REPLACEABLES]) const { 47443d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar 47543d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar 47643d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar for (unsigned idx = 0; idx < mReplaceables.size(); idx ++) { 47743d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar string toString = mReplaceables[idx][replacementIndexes[idx]]; 47843d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar 47943d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar // replace #RST_i patterns with RS datatype corresponding to toString 48043d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar s = expandRSTypeInString(s, kRSTypePatterns[idx], toString); 48143d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar 48243d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar // replace #i patterns with C type from mReplaceables 48343d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar s = stringReplace(s, kCTypePatterns[idx], toString); 484c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 48543d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar 486c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return s; 487c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 488c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 489c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid FunctionSpecification::expandStringVector(const vector<string>& in, 490c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet int replacementIndexes[MAX_REPLACEABLES], 491c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet vector<string>* out) const { 492c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet out->clear(); 493c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (vector<string>::const_iterator iter = in.begin(); iter != in.end(); iter++) { 494c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet out->push_back(expandString(*iter, replacementIndexes)); 495c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 496c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 497c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 498c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid FunctionSpecification::createPermutations(Function* function, Scanner* scanner) { 499c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet int start[MAX_REPLACEABLES]; 500c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet int end[MAX_REPLACEABLES]; 501c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (int i = 0; i < MAX_REPLACEABLES; i++) { 502c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (i < (int)mReplaceables.size()) { 503c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet start[i] = 0; 504c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet end[i] = mReplaceables[i].size(); 505c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 506c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet start[i] = -1; 507c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet end[i] = 0; 508c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 509c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 510c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet int replacementIndexes[MAX_REPLACEABLES]; 511c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // TODO: These loops assume that MAX_REPLACEABLES is 4. 512c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (replacementIndexes[3] = start[3]; replacementIndexes[3] < end[3]; 513c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet replacementIndexes[3]++) { 514c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (replacementIndexes[2] = start[2]; replacementIndexes[2] < end[2]; 515c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet replacementIndexes[2]++) { 516c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (replacementIndexes[1] = start[1]; replacementIndexes[1] < end[1]; 517c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet replacementIndexes[1]++) { 518c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (replacementIndexes[0] = start[0]; replacementIndexes[0] < end[0]; 519c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet replacementIndexes[0]++) { 520c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet auto p = new FunctionPermutation(function, this, replacementIndexes, scanner); 521c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mPermutations.push_back(p); 522c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 523c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 524c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 525c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 526c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 527c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 528c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstring FunctionSpecification::getName(int replacementIndexes[MAX_REPLACEABLES]) const { 529c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return expandString(mUnexpandedName, replacementIndexes); 530c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 531c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 532c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid FunctionSpecification::getReturn(int replacementIndexes[MAX_REPLACEABLES], 533c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet std::string* retType, int* lineNumber) const { 534c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *retType = expandString(mReturn->type, replacementIndexes); 535c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *lineNumber = mReturn->lineNumber; 536c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 537c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 538c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid FunctionSpecification::getParam(size_t index, int replacementIndexes[MAX_REPLACEABLES], 539c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet std::string* type, std::string* name, std::string* testOption, 540c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet int* lineNumber) const { 541c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet ParameterEntry* p = mParameters[index]; 542c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *type = expandString(p->type, replacementIndexes); 543c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *name = p->name; 544c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *testOption = expandString(p->testOption, replacementIndexes); 545c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *lineNumber = p->lineNumber; 546c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 547c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 548c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid FunctionSpecification::getInlines(int replacementIndexes[MAX_REPLACEABLES], 549c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet std::vector<std::string>* inlines) const { 550c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet expandStringVector(mInline, replacementIndexes, inlines); 551c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 552c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 553c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid FunctionSpecification::parseTest(Scanner* scanner) { 554c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const string value = scanner->getValue(); 555c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (value == "scalar" || value == "vector" || value == "noverify" || value == "custom" || 556c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet value == "none") { 557c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mTest = value; 558c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else if (value.compare(0, 7, "limited") == 0) { 559c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mTest = "limited"; 560c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (value.compare(7, 1, "(") == 0) { 561c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet size_t pParen = value.find(')'); 562c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (pParen == string::npos) { 563c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner->error() << "Incorrect test: \"" << value << "\"\n"; 564c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 565c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mPrecisionLimit = value.substr(8, pParen - 8); 566c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 567c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 568c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 569c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner->error() << "Unrecognized test option: \"" << value << "\"\n"; 570c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 571c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 572c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 57312398d81f32e5e0479d02b8608a83c75cd991bb3Yang Nibool FunctionSpecification::hasTests(unsigned int versionOfTestFiles) const { 574c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (mVersionInfo.maxVersion != 0 && mVersionInfo.maxVersion < versionOfTestFiles) { 575c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return false; 576c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 577c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (mTest == "none") { 578c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return false; 579c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 580c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return true; 581c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 582c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 58343d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainarvoid FunctionSpecification::checkRSTPatternValidity(const string &inlineStr, bool allow, 58443d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar Scanner *scanner) { 58543d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar for (int i = 0; i < MAX_REPLACEABLES; i ++) { 58643d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar bool patternFound = inlineStr.find(kRSTypePatterns[i]) != string::npos; 58743d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar 58843d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar if (patternFound) { 58943d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar if (!allow) { 59043d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar scanner->error() << "RST_i pattern not allowed here\n"; 59143d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar } 59243d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar else if (mIsRSTAllowed[i] == false) { 59343d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar scanner->error() << "Found pattern \"" << kRSTypePatterns[i] 59443d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar << "\" in spec. But some entry in the corresponding" 59543d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar << " parameter list cannot be translated to an RS type\n"; 59643d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar } 59743d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar } 59843d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar } 59943d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar} 60043d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar 6012217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouilletvoid FunctionSpecification::scanFunctionSpecification(Scanner* scanner, SpecFile* specFile, 60212398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni unsigned int maxApiLevel) { 603c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // Some functions like convert have # part of the name. Truncate at that point. 6042217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet const string& unexpandedName = scanner->getValue(); 6052217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet string name = unexpandedName; 606c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet size_t p = name.find('#'); 607c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (p != string::npos) { 608c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (p > 0 && name[p - 1] == '_') { 609c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet p--; 610c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 611c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet name.erase(p); 612c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 6132217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet VersionInfo info; 6142217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet if (!info.scan(scanner, maxApiLevel)) { 6152217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet cout << "Skipping some " << name << " definitions.\n"; 6162217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet scanner->skipUntilTag("end:"); 6172217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet return; 6182217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet } 619c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 620c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet bool created = false; 6217c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet Function* function = systemSpecification.findOrCreateFunction(name, &created); 6227c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet FunctionSpecification* spec = new FunctionSpecification(function); 623c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet function->addSpecification(spec); 62467923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet function->updateFinalVersion(info); 6257c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet specFile->addFunctionSpecification(spec, created); 626c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 6272217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet spec->mUnexpandedName = unexpandedName; 628c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->mTest = "scalar"; // default 6292217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet spec->mVersionInfo = info; 630c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 63112398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni if (scanner->findOptionalTag("internal:")) { 63212398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni spec->mInternal = (scanner->getValue() == "true"); 63312398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni } 63412398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni if (scanner->findOptionalTag("intrinsic:")) { 63512398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni spec->mIntrinsic = (scanner->getValue() == "true"); 63612398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni } 637c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner->findOptionalTag("attrib:")) { 638c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->mAttribute = scanner->getValue(); 639c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 640c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner->findOptionalTag("w:")) { 641c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet vector<string> t; 642c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner->getValue().find("1") != string::npos) { 643c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet t.push_back(""); 644c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 645c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner->getValue().find("2") != string::npos) { 646c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet t.push_back("2"); 647c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 648c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner->getValue().find("3") != string::npos) { 649c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet t.push_back("3"); 650c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 651c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner->getValue().find("4") != string::npos) { 652c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet t.push_back("4"); 653c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 654c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->mReplaceables.push_back(t); 65543d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar // RST_i pattern not applicable for width. 65643d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar spec->mIsRSTAllowed.push_back(false); 657c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 658c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 659c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet while (scanner->findOptionalTag("t:")) { 660c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->mReplaceables.push_back(convertToTypeVector(scanner->getValue())); 66143d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar spec->mIsRSTAllowed.push_back(isRSTValid(spec->mReplaceables.back())); 662c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 663c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 66443d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar // Disallow RST_* pattern in function name 66543d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar // FIXME the line number for this error would be wrong 66643d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar spec->checkRSTPatternValidity(unexpandedName, false, scanner); 66743d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar 668c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner->findTag("ret:")) { 669c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet ParameterEntry* p = scanner->parseArgString(true); 670c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet function->addReturn(p, scanner); 671c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->mReturn = p; 67243d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar 67343d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar // Disallow RST_* pattern in return type 67443d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar spec->checkRSTPatternValidity(p->type, false, scanner); 675c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 676c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet while (scanner->findOptionalTag("arg:")) { 677c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet ParameterEntry* p = scanner->parseArgString(false); 678c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet function->addParameter(p, scanner); 679c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->mParameters.push_back(p); 68043d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar 68143d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar // Disallow RST_* pattern in parameter type or testOption 68243d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar spec->checkRSTPatternValidity(p->type, false, scanner); 68343d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar spec->checkRSTPatternValidity(p->testOption, false, scanner); 684c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 685c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 6867c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet function->scanDocumentationTags(scanner, created, specFile); 687c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 688c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner->findOptionalTag("inline:")) { 689c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner->checkNoValue(); 690c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet while (scanner->findOptionalTag("")) { 691c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->mInline.push_back(scanner->getValue()); 69243d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar 69343d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar // Allow RST_* pattern in inline definitions 69443d758c56868560fdd3cdcfeea599819ed037031Pirama Arumuga Nainar spec->checkRSTPatternValidity(spec->mInline.back(), true, scanner); 695c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 696c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 697c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner->findOptionalTag("test:")) { 698c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->parseTest(scanner); 699c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 700c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 701c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner->findTag("end:"); 702c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 703c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->createPermutations(function, scanner); 704c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 705c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 706c5184e202ced435258adb2cfe2013570e7190954Jean-Luc BrouilletFunctionPermutation::FunctionPermutation(Function* func, FunctionSpecification* spec, 707c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet int replacementIndexes[MAX_REPLACEABLES], Scanner* scanner) 7084a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet : mReturn(nullptr), mInputCount(0), mOutputCount(0) { 709c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // We expand the strings now to make capitalization easier. The previous code preserved 710c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // the #n 711c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // markers just before emitting, which made capitalization difficult. 712c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mName = spec->getName(replacementIndexes); 713c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mNameTrunk = func->getName(); 714c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mTest = spec->getTest(); 715c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mPrecisionLimit = spec->getPrecisionLimit(); 716c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->getInlines(replacementIndexes, &mInline); 717c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 718c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mHasFloatAnswers = false; 719c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (size_t i = 0; i < spec->getNumberOfParams(); i++) { 720c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet string type, name, testOption; 721c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet int lineNumber = 0; 722c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->getParam(i, replacementIndexes, &type, &name, &testOption, &lineNumber); 723c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet ParameterDefinition* def = new ParameterDefinition(); 724c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet def->parseParameterDefinition(type, name, testOption, lineNumber, false, scanner); 725c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (def->isOutParameter) { 726c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mOutputCount++; 727c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 728c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mInputCount++; 729c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 730c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 731c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (def->typeIndex < 0 && mTest != "none") { 732c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner->error(lineNumber) 733c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet << "Could not find " << def->rsBaseType 734c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet << " while generating automated tests. Use test: none if not needed.\n"; 735c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 736c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (def->isOutParameter && def->isFloatType) { 737c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mHasFloatAnswers = true; 738c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 739c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mParams.push_back(def); 740c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 741c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 742c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet string retType; 743c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet int lineNumber = 0; 744c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet spec->getReturn(replacementIndexes, &retType, &lineNumber); 745c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (!retType.empty()) { 746c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mReturn = new ParameterDefinition(); 747c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mReturn->parseParameterDefinition(retType, "", "", lineNumber, true, scanner); 748c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (mReturn->isFloatType) { 749c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mHasFloatAnswers = true; 750c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 751c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mOutputCount++; 752c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 753c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 754c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 755c5184e202ced435258adb2cfe2013570e7190954Jean-Luc BrouilletFunctionPermutation::~FunctionPermutation() { 756c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (auto i : mParams) { 757c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet delete i; 758c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 759c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet delete mReturn; 760c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 761c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 762c5184e202ced435258adb2cfe2013570e7190954Jean-Luc BrouilletSpecFile::SpecFile(const string& specFileName) : mSpecFileName(specFileName) { 763c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet string core = mSpecFileName; 764c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // Remove .spec 765c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet size_t l = core.length(); 766c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const char SPEC[] = ".spec"; 767c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const int SPEC_SIZE = sizeof(SPEC) - 1; 768c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const int start = l - SPEC_SIZE; 769c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (start >= 0 && core.compare(start, SPEC_SIZE, SPEC) == 0) { 770c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet core.erase(start); 771c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 772c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 773c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // The header file name should have the same base but with a ".rsh" extension. 774c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mHeaderFileName = core + ".rsh"; 775d9935eeb051068c6049a533f375f0dffa0e6bd16Jean-Luc Brouillet mDetailedDocumentationUrl = core + ".html"; 776c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 777c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 7787c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouilletvoid SpecFile::addConstantSpecification(ConstantSpecification* spec, bool hasDocumentation) { 7797c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet mConstantSpecificationsList.push_back(spec); 7807c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet if (hasDocumentation) { 7817c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet Constant* constant = spec->getConstant(); 7827c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet mDocumentedConstants.insert(pair<string, Constant*>(constant->getName(), constant)); 783c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 7847c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet} 7857c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet 7867c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouilletvoid SpecFile::addTypeSpecification(TypeSpecification* spec, bool hasDocumentation) { 7877c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet mTypeSpecificationsList.push_back(spec); 7887c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet if (hasDocumentation) { 7897c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet Type* type = spec->getType(); 7907c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet mDocumentedTypes.insert(pair<string, Type*>(type->getName(), type)); 791c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 7927c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet} 7937c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet 7947c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouilletvoid SpecFile::addFunctionSpecification(FunctionSpecification* spec, bool hasDocumentation) { 7957c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet mFunctionSpecificationsList.push_back(spec); 7967c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet if (hasDocumentation) { 7977c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet Function* function = spec->getFunction(); 7987c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet mDocumentedFunctions.insert(pair<string, Function*>(function->getName(), function)); 799c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 800c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 801c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 802c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet// Read the specification, adding the definitions to the global functions map. 80312398d81f32e5e0479d02b8608a83c75cd991bb3Yang Nibool SpecFile::readSpecFile(unsigned int maxApiLevel) { 804c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet FILE* specFile = fopen(mSpecFileName.c_str(), "rt"); 805c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (!specFile) { 806c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet cerr << "Error opening input file: " << mSpecFileName << "\n"; 807c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return false; 808c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 809c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 810c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet Scanner scanner(mSpecFileName, specFile); 811c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 812c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // Scan the header that should start the file. 813c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner.skipBlankEntries(); 814c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner.findTag("header:")) { 815c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner.findTag("summary:")) { 816c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mBriefDescription = scanner.getValue(); 817c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 818c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner.findTag("description:")) { 819c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner.checkNoValue(); 820c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet while (scanner.findOptionalTag("")) { 821c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mFullDescription.push_back(scanner.getValue()); 822c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 823c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 824c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner.findOptionalTag("include:")) { 825c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner.checkNoValue(); 826c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet while (scanner.findOptionalTag("")) { 827c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mVerbatimInclude.push_back(scanner.getValue()); 828c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 829c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 830c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner.findTag("end:"); 831c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 832c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 833c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet while (1) { 834c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner.skipBlankEntries(); 835c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (scanner.atEnd()) { 836c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet break; 837c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 838c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const string tag = scanner.getNextTag(); 839c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (tag == "function:") { 8402217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet FunctionSpecification::scanFunctionSpecification(&scanner, this, maxApiLevel); 841c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else if (tag == "type:") { 8422217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet TypeSpecification::scanTypeSpecification(&scanner, this, maxApiLevel); 843c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else if (tag == "constant:") { 8442217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet ConstantSpecification::scanConstantSpecification(&scanner, this, maxApiLevel); 845c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 846c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet scanner.error() << "Expected function:, type:, or constant:. Found: " << tag << "\n"; 847c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return false; 848c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 849c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 850c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 851c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet fclose(specFile); 852c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return scanner.getErrorCount() == 0; 853c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 854c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 8557c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc BrouilletSystemSpecification::~SystemSpecification() { 8567c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet for (auto i : mConstants) { 8577c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet delete i.second; 8587c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet } 8597c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet for (auto i : mTypes) { 8607c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet delete i.second; 8617c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet } 8627c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet for (auto i : mFunctions) { 8637c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet delete i.second; 8647c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet } 8657c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet for (auto i : mSpecFiles) { 8667c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet delete i; 8677c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet } 8687c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet} 8697c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet 870c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet// Returns the named entry in the map. Creates it if it's not there. 871c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillettemplate <class T> 8727c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc BrouilletT* findOrCreate(const string& name, map<string, T*>* map, bool* created) { 873c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet auto iter = map->find(name); 874c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (iter != map->end()) { 875c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *created = false; 876c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return iter->second; 877c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 878c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *created = true; 8797c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet T* f = new T(name); 880c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet map->insert(pair<string, T*>(name, f)); 881c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return f; 882c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 883c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 8847c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc BrouilletConstant* SystemSpecification::findOrCreateConstant(const string& name, bool* created) { 8857c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet return findOrCreate<Constant>(name, &mConstants, created); 886c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 887c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 8887c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc BrouilletType* SystemSpecification::findOrCreateType(const string& name, bool* created) { 8897c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet return findOrCreate<Type>(name, &mTypes, created); 890c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 891c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 8927c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc BrouilletFunction* SystemSpecification::findOrCreateFunction(const string& name, bool* created) { 8937c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet return findOrCreate<Function>(name, &mFunctions, created); 894c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 895c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 89612398d81f32e5e0479d02b8608a83c75cd991bb3Yang Nibool SystemSpecification::readSpecFile(const string& fileName, unsigned int maxApiLevel) { 897c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet SpecFile* spec = new SpecFile(fileName); 8982217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet if (!spec->readSpecFile(maxApiLevel)) { 899c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet cerr << fileName << ": Failed to parse.\n"; 900c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return false; 901c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 902c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mSpecFiles.push_back(spec); 9037c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet return true; 904c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 905c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 90636090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet 90712398d81f32e5e0479d02b8608a83c75cd991bb3Yang Nistatic void updateMaxApiLevel(const VersionInfo& info, unsigned int* maxApiLevel) { 90812398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni if (info.minVersion == VersionInfo::kUnreleasedVersion) { 90912398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni // Ignore development API level in consideration of max API level. 91012398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni return; 91112398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni } 91236090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet *maxApiLevel = max(*maxApiLevel, max(info.minVersion, info.maxVersion)); 91336090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet} 91436090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet 91512398d81f32e5e0479d02b8608a83c75cd991bb3Yang Niunsigned int SystemSpecification::getMaximumApiLevel() { 91612398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni unsigned int maxApiLevel = 0; 91736090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet for (auto i : mConstants) { 91836090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet for (auto j: i.second->getSpecifications()) { 91936090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet updateMaxApiLevel(j->getVersionInfo(), &maxApiLevel); 92036090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet } 92136090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet } 92236090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet for (auto i : mTypes) { 92336090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet for (auto j: i.second->getSpecifications()) { 92436090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet updateMaxApiLevel(j->getVersionInfo(), &maxApiLevel); 92536090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet } 92636090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet } 92736090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet for (auto i : mFunctions) { 92836090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet for (auto j: i.second->getSpecifications()) { 92936090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet updateMaxApiLevel(j->getVersionInfo(), &maxApiLevel); 93036090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet } 93136090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet } 93236090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet return maxApiLevel; 93336090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet} 93436090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet 93512398d81f32e5e0479d02b8608a83c75cd991bb3Yang Nibool SystemSpecification::generateFiles(bool forVerification, unsigned int maxApiLevel) const { 9362a85b6b9d6f9cb8f1b20d573c1c5ceafe901b011Jean-Luc Brouillet bool success = generateHeaderFiles("include") && 9372217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet generateDocumentation("docs", forVerification) && 93836090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet generateTestFiles("test", maxApiLevel) && 93936090673baf50cf3c70bdc89f9a4a872c05cf0f6Jean-Luc Brouillet generateStubsWhiteList("slangtest", maxApiLevel); 940c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (success) { 941c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet cout << "Successfully processed " << mTypes.size() << " types, " << mConstants.size() 942c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet << " constants, and " << mFunctions.size() << " functions.\n"; 943c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 944c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return success; 945c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 946c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 947c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstring SystemSpecification::getHtmlAnchor(const string& name) const { 948c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet Definition* d = nullptr; 949c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet auto c = mConstants.find(name); 950c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (c != mConstants.end()) { 951c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet d = c->second; 952c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 953c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet auto t = mTypes.find(name); 954c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (t != mTypes.end()) { 955c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet d = t->second; 956c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 957c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet auto f = mFunctions.find(name); 958c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (f != mFunctions.end()) { 959c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet d = f->second; 960c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 961c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return string(); 962c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 963c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 964c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 965c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet ostringstream stream; 966c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet stream << "<a href='" << d->getUrl() << "'>" << name << "</a>"; 967c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return stream.str(); 968c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 969