GenerateHeaderFiles.cpp revision 4a73004df5231d188c41267fee17c566ae7c3631
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
41c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet// Write #ifdef's that ensure that the specified version is present
42c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic void writeVersionGuardStart(GeneratedFile* file, VersionInfo info) {
43c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (info.intSize == 32) {
44c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << "#ifndef __LP64__\n";
45c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else if (info.intSize == 64) {
46c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << "#ifdef __LP64__\n";
47c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
48c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
49c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (info.minVersion <= 1) {
50c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        // No minimum
51c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (info.maxVersion > 0) {
52c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << "#if !defined(RS_VERSION) || (RS_VERSION <= " << info.maxVersion << ")\n";
53c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
54c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else {
55c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (info.maxVersion == 0) {
56c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            // No maximum
57c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << "#if (defined(RS_VERSION) && (RS_VERSION >= " << info.minVersion << "))\n";
58c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        } else {
59c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << "#if (defined(RS_VERSION) && (RS_VERSION >= " << info.minVersion
60c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                  << ") && (RS_VERSION <= " << info.maxVersion << "))\n";
61c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
62c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
63c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
64c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
65c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic void writeVersionGuardEnd(GeneratedFile* file, VersionInfo info) {
66c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (info.minVersion > 1 || info.maxVersion != 0) {
67c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << "#endif\n";
68c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
69c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (info.intSize != 0) {
70c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << "#endif\n";
71c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
72c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
73c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
74c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic void writeComment(GeneratedFile* file, const string& name, const string& briefComment,
754a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet                         const vector<string>& comment, bool addDeprecatedWarning,
764a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet                         bool closeBlock) {
77c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (briefComment.empty() && comment.size() == 0) {
78c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        return;
79c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
80c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *file << "/*\n";
81c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (!briefComment.empty()) {
82c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << " * " << name << ": " << briefComment << "\n";
83c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << " *\n";
84c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
854a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet    if (addDeprecatedWarning) {
864a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet        *file << " * DEPRECATED.  Do not use.\n";
874a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet        *file << " *\n";
884a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet    }
89c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (size_t ct = 0; ct < comment.size(); ct++) {
90c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        string s = stripHtml(comment[ct]);
91c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        s = stringReplace(s, "@", "");
92c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (!s.empty()) {
93c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << " * " << s << "\n";
94c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        } else {
95c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << " *\n";
96c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
97c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
98c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (closeBlock) {
99c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << " */\n";
100c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
101c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
102c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1037c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouilletstatic void writeConstantComment(GeneratedFile* file, const Constant& constant) {
104c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const string name = constant.getName();
1054a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet    writeComment(file, name, constant.getSummary(), constant.getDescription(),
1064a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet                 constant.deprecated(), true);
1077c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet}
108c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1097c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouilletstatic void writeConstantSpecification(GeneratedFile* file, const ConstantSpecification& spec) {
1107c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet    VersionInfo info = spec.getVersionInfo();
1117c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet    writeVersionGuardStart(file, info);
1127c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet    *file << "#define " << spec.getConstant()->getName() << " " << spec.getValue() << "\n\n";
1137c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet    writeVersionGuardEnd(file, info);
114c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
115c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1167c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouilletstatic void writeTypeSpecification(GeneratedFile* file, const TypeSpecification& spec) {
1177c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet    const string& typeName = spec.getType()->getName();
118c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const VersionInfo info = spec.getVersionInfo();
119c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    writeVersionGuardStart(file, info);
120c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    switch (spec.getKind()) {
121c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        case SIMPLE:
122c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << "typedef " << spec.getSimpleType() << " " << typeName << ";\n";
123c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            break;
124c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        case ENUM: {
125c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << "typedef enum ";
126c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            const string name = spec.getEnumName();
127c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            if (!name.empty()) {
128c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *file << name << " ";
129c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
130c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << "{\n";
131c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
132c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            const vector<string>& values = spec.getValues();
133c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            const vector<string>& valueComments = spec.getValueComments();
134c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            const size_t last = values.size() - 1;
135c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            for (size_t i = 0; i <= last; i++) {
136c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *file << "    " << values[i];
137c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                if (i != last) {
138c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                    *file << ",";
139c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                }
140c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                if (valueComments.size() > i && !valueComments[i].empty()) {
141c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                    *file << " // " << valueComments[i];
142c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                }
143c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *file << "\n";
144c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
145c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << "} " << typeName << ";\n";
146c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            break;
147c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
148c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        case STRUCT: {
149c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << "typedef struct ";
150c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            const string name = spec.getStructName();
151c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            if (!name.empty()) {
152c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *file << name << " ";
153c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
154c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << "{\n";
155c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
156c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            const vector<string>& fields = spec.getFields();
157c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            const vector<string>& fieldComments = spec.getFieldComments();
158c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            for (size_t i = 0; i < fields.size(); i++) {
159c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *file << "    " << fields[i] << ";";
160c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                if (fieldComments.size() > i && !fieldComments[i].empty()) {
161c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                    *file << " // " << fieldComments[i];
162c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                }
163c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *file << "\n";
164c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
165c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << "} ";
166c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            const string attrib = spec.getAttrib();
167c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            if (!attrib.empty()) {
168c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *file << attrib << " ";
169c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
170c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << typeName << ";\n";
171c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            break;
172c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
173c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
174c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    writeVersionGuardEnd(file, info);
175c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *file << "\n";
176c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
177c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
1787c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouilletstatic void writeTypeComment(GeneratedFile* file, const Type& type) {
179c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const string name = type.getName();
1804a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet    writeComment(file, name, type.getSummary(), type.getDescription(), type.deprecated(), true);
181c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
182c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
183c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic void writeFunctionPermutation(GeneratedFile* file, const FunctionSpecification& spec,
184c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                     const FunctionPermutation& permutation) {
185c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    writeVersionGuardStart(file, spec.getVersionInfo());
186c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
187c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Write linkage info.
188c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const auto inlineCodeLines = permutation.getInline();
189c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (inlineCodeLines.size() > 0) {
190c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << "static inline ";
191c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else {
192c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << "extern ";
193c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
194c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
195c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Write the return type.
196c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    auto ret = permutation.getReturn();
197c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (ret) {
198c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << ret->rsType;
199c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else {
200c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << "void";
201c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
202c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
203c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Write the attribute.
204c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *file << " __attribute__((";
205c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const string attrib = spec.getAttribute();
206c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (attrib.empty()) {
207c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << "overloadable";
208c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else if (attrib[0] == '=') {
209c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        /* If starts with an equal, we don't automatically add overloadable.
210c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet         * This is because of the error we made defining rsUnpackColor8888().
211c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet         */
212c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << attrib.substr(1);
213c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else {
214c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << attrib << ", overloadable";
215c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
216c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *file << "))\n";
217c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
218c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Write the function name.
219c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *file << "    " << permutation.getName() << "(";
220c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const int offset = 4 + permutation.getName().size() + 1;  // Size of above
221c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
222c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Write the arguments.  We wrap on mulitple lines if a line gets too long.
223c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    int charsOnLine = offset;
224c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    bool hasGenerated = false;
225c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto p : permutation.getParams()) {
226c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (hasGenerated) {
227c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << ",";
228c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            charsOnLine++;
229c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
230c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        ostringstream ps;
231c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        ps << p->rsType;
232c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (p->isOutParameter) {
233c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            ps << "*";
234c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
235c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (!p->specName.empty()) {
236c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            ps << " " << p->specName;
237c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
238c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        const string s = ps.str();
239c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (charsOnLine + s.size() >= 100) {
240c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << "\n" << string(offset, ' ');
241c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            charsOnLine = offset;
242c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        } else if (hasGenerated) {
243c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << " ";
244c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            charsOnLine++;
245c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
246c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << s;
247c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        charsOnLine += s.size();
248c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        hasGenerated = true;
249c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
250c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // In C, if no parameters, we need to output void, e.g. fn(void).
251c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (!hasGenerated) {
252c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << "void";
253c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
254c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *file << ")";
255c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
256c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Write the inline code, if any.
257c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (inlineCodeLines.size() > 0) {
258c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << " {\n";
259c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        for (size_t ct = 0; ct < inlineCodeLines.size(); ct++) {
260c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            if (inlineCodeLines[ct].empty()) {
261c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *file << "\n";
262c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            } else {
263c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *file << "    " << inlineCodeLines[ct] << "\n";
264c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
265c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
266c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << "}\n";
267c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    } else {
268c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << ";\n";
269c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
270c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
271c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    writeVersionGuardEnd(file, spec.getVersionInfo());
272c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *file << "\n";
273c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
274c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
2757c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouilletstatic void writeFunctionComment(GeneratedFile* file, const Function& function) {
276c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Write the generic documentation.
2774a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet    writeComment(file, function.getName(), function.getSummary(), function.getDescription(),
2784a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet                 function.deprecated(), false);
279c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
280c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Comment the parameters.
281c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (function.someParametersAreDocumented()) {
282c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << " *\n";
283c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << " * Parameters:\n";
284c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        for (auto p : function.getParameters()) {
285c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            if (!p->documentation.empty()) {
2864a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet                *file << " *   " << p->name << ": " << p->documentation << "\n";
287c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
288c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
289c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
290c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
291c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Comment the return type.
292c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const string returnDoc = function.getReturnDocumentation();
293c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (!returnDoc.empty()) {
294c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << " *\n";
295c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << " * Returns: " << returnDoc << "\n";
296c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
297c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
298c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *file << " */\n";
2997c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet}
300c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
3017c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouilletstatic void writeFunctionSpecification(GeneratedFile* file, const FunctionSpecification& spec) {
302c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Write all the variants.
3037c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet    for (auto permutation : spec.getPermutations()) {
3047c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet        writeFunctionPermutation(file, spec, *permutation);
305c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
306c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
307c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
30862e099314bb1831035083a50616024ffa6253bdeJean-Luc Brouilletstatic bool writeHeaderFile(const string& directory, const SpecFile& specFile) {
309c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const string headerFileName = specFile.getHeaderFileName();
310c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
311c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // We generate one header file for each spec file.
312c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    GeneratedFile file;
31362e099314bb1831035083a50616024ffa6253bdeJean-Luc Brouillet    if (!file.start(directory, headerFileName)) {
314c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        return false;
315c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
316c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
317c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Write the comments that start the file.
318c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file.writeNotices();
319c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    writeComment(&file, headerFileName, specFile.getBriefDescription(),
3204a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet                 specFile.getFullDescription(), false, true);
3214a73004df5231d188c41267fee17c566ae7c3631Jean-Luc Brouillet    file << "\n";
322c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
323c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Write the ifndef that prevents the file from being included twice.
324c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const string guard = makeGuardString(headerFileName);
325c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file << "#ifndef " << guard << "\n";
326c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file << "#define " << guard << "\n\n";
327c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
328c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Add lines that need to be put in "as is".
329c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (specFile.getVerbatimInclude().size() > 0) {
330c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        for (auto s : specFile.getVerbatimInclude()) {
331c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            file << s << "\n";
332c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
333c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        file << "\n";
334c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
335c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
336c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    /* Write the constants, types, and functions in the same order as
337c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     * encountered in the spec file.
338c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     */
3397c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet    set<Constant*> documentedConstants;
3407c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet    for (auto spec : specFile.getConstantSpecifications()) {
3417c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet        Constant* constant = spec->getConstant();
3427c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet        if (documentedConstants.find(constant) == documentedConstants.end()) {
3437c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet            documentedConstants.insert(constant);
3447c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet            writeConstantComment(&file, *constant);
3457c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet        }
3467c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet        writeConstantSpecification(&file, *spec);
347c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
3487c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet    set<Type*> documentedTypes;
3497c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet    for (auto spec : specFile.getTypeSpecifications()) {
3507c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet        Type* type = spec->getType();
3517c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet        if (documentedTypes.find(type) == documentedTypes.end()) {
3527c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet            documentedTypes.insert(type);
3537c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet            writeTypeComment(&file, *type);
3547c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet        }
3557c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet        writeTypeSpecification(&file, *spec);
356c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
3577c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet
3587c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet    set<Function*> documentedFunctions;
3597c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet    for (auto spec : specFile.getFunctionSpecifications()) {
3607c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet        Function* function = spec->getFunction();
3617c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet        if (documentedFunctions.find(function) == documentedFunctions.end()) {
3627c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet            documentedFunctions.insert(function);
3637c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet            writeFunctionComment(&file, *function);
3647c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet        }
3657c07854a959eb70ff9623202b2ca064407a1cc68Jean-Luc Brouillet        writeFunctionSpecification(&file, *spec);
366c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
367c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
368c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file << "#endif // " << guard << "\n";
369c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file.close();
370c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    return true;
371c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
372c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
37362e099314bb1831035083a50616024ffa6253bdeJean-Luc Brouilletbool GenerateHeaderFiles(const string& directory) {
374c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    bool success = true;
375c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto specFile : systemSpecification.getSpecFiles()) {
37662e099314bb1831035083a50616024ffa6253bdeJean-Luc Brouillet        if (!writeHeaderFile(directory, *specFile)) {
377c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            success = false;
378c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
379c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
380c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    return success;
381c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
382