1c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/* 2c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Copyright (C) 2015 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 <iostream> 18c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include <sstream> 19c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 20c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include "Generator.h" 21c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include "Specification.h" 22c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include "Utilities.h" 23c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 24c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletusing namespace std; 25c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 26c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet// Convert a file name into a string that can be used to guard the include file with #ifdef... 27c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic string makeGuardString(const string& filename) { 28c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet string s; 29c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet s.resize(15 + filename.size()); 30c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet s = "RENDERSCRIPT_"; 31c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (char c : filename) { 32c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (c == '.') { 33c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet s += '_'; 34c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 35c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet s += toupper(c); 36c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 37c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 38c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return s; 39c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 40c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 4167923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet/* Write #ifdef's that ensure that the specified version is present. If we're at the final version, 4267923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet * add a check on a flag that can be set for internal builds. This enables us to keep supporting 4367923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet * old APIs in the runtime code. 4467923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet */ 4512398d81f32e5e0479d02b8608a83c75cd991bb3Yang Nistatic void writeVersionGuardStart(GeneratedFile* file, VersionInfo info, unsigned int finalVersion) { 46c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (info.intSize == 32) { 47c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << "#ifndef __LP64__\n"; 48c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else if (info.intSize == 64) { 49c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << "#ifdef __LP64__\n"; 50c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 51c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 5267923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet ostringstream checkMaxVersion; 5367923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet if (info.maxVersion > 0) { 5467923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet checkMaxVersion << "("; 5567923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet if (info.maxVersion == finalVersion) { 5667923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet checkMaxVersion << "defined(RS_DECLARE_EXPIRED_APIS) || "; 5767923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet } 5867923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet checkMaxVersion << "RS_VERSION <= " << info.maxVersion << ")"; 5967923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet } 6067923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet 61c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (info.minVersion <= 1) { 62c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // No minimum 63c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (info.maxVersion > 0) { 6467923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet *file << "#if !defined(RS_VERSION) || " << checkMaxVersion.str() << "\n"; 65c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 66c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 6767923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet *file << "#if (defined(RS_VERSION) && (RS_VERSION >= " << info.minVersion << ")"; 6867923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet if (info.maxVersion > 0) { 6967923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet *file << " && " << checkMaxVersion.str(); 70c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 7167923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet *file << ")\n"; 72c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 73c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 74c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 75c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic void writeVersionGuardEnd(GeneratedFile* file, VersionInfo info) { 76c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (info.minVersion > 1 || info.maxVersion != 0) { 77c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << "#endif\n"; 78c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 79c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (info.intSize != 0) { 80c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << "#endif\n"; 81c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 82c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 83c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 84c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic void writeComment(GeneratedFile* file, const string& name, const string& briefComment, 854a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet const vector<string>& comment, bool addDeprecatedWarning, 864a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet bool closeBlock) { 87c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (briefComment.empty() && comment.size() == 0) { 88c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return; 89c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 90c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << "/*\n"; 91c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (!briefComment.empty()) { 92c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << " * " << name << ": " << briefComment << "\n"; 93c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << " *\n"; 94c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 954a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet if (addDeprecatedWarning) { 964a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet *file << " * DEPRECATED. Do not use.\n"; 974a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet *file << " *\n"; 984a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet } 99c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (size_t ct = 0; ct < comment.size(); ct++) { 100c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet string s = stripHtml(comment[ct]); 101c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet s = stringReplace(s, "@", ""); 102c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (!s.empty()) { 103c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << " * " << s << "\n"; 104c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 105c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << " *\n"; 106c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 107c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 108c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (closeBlock) { 109c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << " */\n"; 110c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 111c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 112c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 1137c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouilletstatic void writeConstantComment(GeneratedFile* file, const Constant& constant) { 114c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const string name = constant.getName(); 1154a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet writeComment(file, name, constant.getSummary(), constant.getDescription(), 1164a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet constant.deprecated(), true); 1177c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet} 118c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 1197c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouilletstatic void writeConstantSpecification(GeneratedFile* file, const ConstantSpecification& spec) { 12067923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet const Constant* constant = spec.getConstant(); 1217c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet VersionInfo info = spec.getVersionInfo(); 12267923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet writeVersionGuardStart(file, info, constant->getFinalVersion()); 123cb25a819dbb5bda7e5554ec5ff09d29586d84493David Gross *file << "static const " << spec.getType() << " " << constant->getName() 124cb25a819dbb5bda7e5554ec5ff09d29586d84493David Gross << " = " << spec.getValue() << ";\n\n"; 1257c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet writeVersionGuardEnd(file, info); 126c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 127c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 1287c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouilletstatic void writeTypeSpecification(GeneratedFile* file, const TypeSpecification& spec) { 12967923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet const Type* type = spec.getType(); 13067923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet const string& typeName = type->getName(); 131c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const VersionInfo info = spec.getVersionInfo(); 13267923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet writeVersionGuardStart(file, info, type->getFinalVersion()); 13336e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet 13436e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet const string attribute = 13536e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet makeAttributeTag(spec.getAttribute(), "", type->getDeprecatedApiLevel(), 13636e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet type->getDeprecatedMessage()); 13736e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet *file << "typedef "; 138c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet switch (spec.getKind()) { 139c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet case SIMPLE: 14036e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet *file << spec.getSimpleType() << attribute; 141c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet break; 142ca51c78b9e3097ee31dd24cdc5982f550ee563d1Stephen Hines case RS_OBJECT: 143ca51c78b9e3097ee31dd24cdc5982f550ee563d1Stephen Hines *file << "struct " << typeName << " _RS_OBJECT_DECL" << attribute; 144ca51c78b9e3097ee31dd24cdc5982f550ee563d1Stephen Hines break; 145c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet case ENUM: { 14636e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet *file << "enum" << attribute << " "; 147c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const string name = spec.getEnumName(); 148c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (!name.empty()) { 149c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << name << " "; 150c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 151c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << "{\n"; 152c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 153c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const vector<string>& values = spec.getValues(); 154c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const vector<string>& valueComments = spec.getValueComments(); 155c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const size_t last = values.size() - 1; 156c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (size_t i = 0; i <= last; i++) { 157c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << " " << values[i]; 158c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (i != last) { 159c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << ","; 160c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 161c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (valueComments.size() > i && !valueComments[i].empty()) { 162c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << " // " << valueComments[i]; 163c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 164c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << "\n"; 165c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 16636e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet *file << "}"; 167c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet break; 168c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 169c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet case STRUCT: { 17036e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet *file << "struct" << attribute << " "; 171c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const string name = spec.getStructName(); 172c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (!name.empty()) { 173c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << name << " "; 174c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 175c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << "{\n"; 176c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 177c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const vector<string>& fields = spec.getFields(); 178c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const vector<string>& fieldComments = spec.getFieldComments(); 179c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (size_t i = 0; i < fields.size(); i++) { 180c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << " " << fields[i] << ";"; 181c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (fieldComments.size() > i && !fieldComments[i].empty()) { 182c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << " // " << fieldComments[i]; 183c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 184c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << "\n"; 185c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 18636e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet *file << "}"; 187c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet break; 188c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 189c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 19036e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet *file << " " << typeName << ";\n"; 19136e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet 192c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet writeVersionGuardEnd(file, info); 193c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << "\n"; 194c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 195c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 1967c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouilletstatic void writeTypeComment(GeneratedFile* file, const Type& type) { 197c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const string name = type.getName(); 1984a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet writeComment(file, name, type.getSummary(), type.getDescription(), type.deprecated(), true); 199c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 200c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 201c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic void writeFunctionPermutation(GeneratedFile* file, const FunctionSpecification& spec, 202c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const FunctionPermutation& permutation) { 20367923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet Function* function = spec.getFunction(); 20467923a9e829d89522bb5338a6d635d807a7ee59bJean-Luc Brouillet writeVersionGuardStart(file, spec.getVersionInfo(), function->getFinalVersion()); 205c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 206c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // Write linkage info. 207c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const auto inlineCodeLines = permutation.getInline(); 208c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (inlineCodeLines.size() > 0) { 209c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << "static inline "; 210c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 211c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << "extern "; 212c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 213c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 214c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // Write the return type. 215c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet auto ret = permutation.getReturn(); 216c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (ret) { 217c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << ret->rsType; 218c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 219c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << "void"; 220c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 221c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 22212398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni *file << makeAttributeTag(spec.getAttribute(), spec.isOverloadable() ? "overloadable" : "", 22336e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet function->getDeprecatedApiLevel(), function->getDeprecatedMessage()); 22436e2be56cd398bf4a318114bbc9fa3f4573c158fJean-Luc Brouillet *file << "\n"; 225c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 226c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // Write the function name. 227c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << " " << permutation.getName() << "("; 228c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const int offset = 4 + permutation.getName().size() + 1; // Size of above 229c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 230c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // Write the arguments. We wrap on mulitple lines if a line gets too long. 231c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet int charsOnLine = offset; 232c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet bool hasGenerated = false; 233c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (auto p : permutation.getParams()) { 234c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (hasGenerated) { 235c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << ","; 236c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet charsOnLine++; 237c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 238c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet ostringstream ps; 239c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet ps << p->rsType; 240c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (p->isOutParameter) { 241c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet ps << "*"; 242c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 243fab6947a18e00964f79e6c802dc70bbaed981730Yang Ni if (!p->specName.empty() && p->rsType != "...") { 244c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet ps << " " << p->specName; 245c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 246c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const string s = ps.str(); 247c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (charsOnLine + s.size() >= 100) { 248c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << "\n" << string(offset, ' '); 249c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet charsOnLine = offset; 250c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else if (hasGenerated) { 251c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << " "; 252c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet charsOnLine++; 253c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 254c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << s; 255c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet charsOnLine += s.size(); 256c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet hasGenerated = true; 257c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 258c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // In C, if no parameters, we need to output void, e.g. fn(void). 259c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (!hasGenerated) { 260c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << "void"; 261c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 262c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << ")"; 263c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 264c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // Write the inline code, if any. 265c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (inlineCodeLines.size() > 0) { 266c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << " {\n"; 267c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (size_t ct = 0; ct < inlineCodeLines.size(); ct++) { 268c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (inlineCodeLines[ct].empty()) { 269c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << "\n"; 270c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 271c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << " " << inlineCodeLines[ct] << "\n"; 272c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 273c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 274c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << "}\n"; 275c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 276c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << ";\n"; 277c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 278c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 279c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet writeVersionGuardEnd(file, spec.getVersionInfo()); 280c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << "\n"; 281c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 282c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 2837c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouilletstatic void writeFunctionComment(GeneratedFile* file, const Function& function) { 284c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // Write the generic documentation. 2854a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet writeComment(file, function.getName(), function.getSummary(), function.getDescription(), 2864a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet function.deprecated(), false); 287c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 288c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // Comment the parameters. 289c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (function.someParametersAreDocumented()) { 290c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << " *\n"; 291c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << " * Parameters:\n"; 292c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (auto p : function.getParameters()) { 293c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (!p->documentation.empty()) { 2944a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet *file << " * " << p->name << ": " << p->documentation << "\n"; 295c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 296c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 297c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 298c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 299c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // Comment the return type. 300c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const string returnDoc = function.getReturnDocumentation(); 301c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (!returnDoc.empty()) { 302c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << " *\n"; 303c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << " * Returns: " << returnDoc << "\n"; 304c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 305c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 306c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *file << " */\n"; 3077c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet} 308c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 3097c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouilletstatic void writeFunctionSpecification(GeneratedFile* file, const FunctionSpecification& spec) { 310c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // Write all the variants. 3117c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet for (auto permutation : spec.getPermutations()) { 3127c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet writeFunctionPermutation(file, spec, *permutation); 313c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 314c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 315c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 31662e099314bb1831035083a50616024ffa6253bdeJean-Luc Brouilletstatic bool writeHeaderFile(const string& directory, const SpecFile& specFile) { 317c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const string headerFileName = specFile.getHeaderFileName(); 318c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 319c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // We generate one header file for each spec file. 320c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet GeneratedFile file; 32162e099314bb1831035083a50616024ffa6253bdeJean-Luc Brouillet if (!file.start(directory, headerFileName)) { 322c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return false; 323c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 324c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 325c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // Write the comments that start the file. 326c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet file.writeNotices(); 327c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet writeComment(&file, headerFileName, specFile.getBriefDescription(), 3284a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet specFile.getFullDescription(), false, true); 3294a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet file << "\n"; 330c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 331c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // Write the ifndef that prevents the file from being included twice. 332c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet const string guard = makeGuardString(headerFileName); 333c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet file << "#ifndef " << guard << "\n"; 334c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet file << "#define " << guard << "\n\n"; 335c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 336c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // Add lines that need to be put in "as is". 337c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (specFile.getVerbatimInclude().size() > 0) { 338c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (auto s : specFile.getVerbatimInclude()) { 339c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet file << s << "\n"; 340c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 341c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet file << "\n"; 342c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 343c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 344c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet /* Write the constants, types, and functions in the same order as 345c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * encountered in the spec file. 346c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet */ 3477c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet set<Constant*> documentedConstants; 3487c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet for (auto spec : specFile.getConstantSpecifications()) { 3497c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet Constant* constant = spec->getConstant(); 3507c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet if (documentedConstants.find(constant) == documentedConstants.end()) { 3517c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet documentedConstants.insert(constant); 3527c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet writeConstantComment(&file, *constant); 3537c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet } 3547c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet writeConstantSpecification(&file, *spec); 355c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 3567c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet set<Type*> documentedTypes; 3577c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet for (auto spec : specFile.getTypeSpecifications()) { 3587c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet Type* type = spec->getType(); 3597c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet if (documentedTypes.find(type) == documentedTypes.end()) { 3607c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet documentedTypes.insert(type); 3617c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet writeTypeComment(&file, *type); 3627c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet } 3637c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet writeTypeSpecification(&file, *spec); 364c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 3657c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet 3667c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet set<Function*> documentedFunctions; 3677c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet for (auto spec : specFile.getFunctionSpecifications()) { 36812398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni // Do not include internal APIs in the header files. 36912398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni if (spec->isInternal()) { 37012398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni continue; 37112398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni } 3727c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet Function* function = spec->getFunction(); 3737c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet if (documentedFunctions.find(function) == documentedFunctions.end()) { 3747c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet documentedFunctions.insert(function); 3757c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet writeFunctionComment(&file, *function); 3767c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet } 3777c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet writeFunctionSpecification(&file, *spec); 378c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 379c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 380c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet file << "#endif // " << guard << "\n"; 381c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet file.close(); 382c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return true; 383c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 384c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 38566fea24fb5f3a02b744a9c71ae0fc22c03c4fc6eJean-Luc Brouilletbool generateHeaderFiles(const string& directory) { 386c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet bool success = true; 387c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (auto specFile : systemSpecification.getSpecFiles()) { 38862e099314bb1831035083a50616024ffa6253bdeJean-Luc Brouillet if (!writeHeaderFile(directory, *specFile)) { 389c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet success = false; 390c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 391c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 392c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return success; 393c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 394