GenerateHeaderFiles.cpp revision c5184e202ced435258adb2cfe2013570e7190954
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,
75c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                         const vector<string>& comment, bool closeBlock) {
76c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (briefComment.empty() && comment.size() == 0) {
77c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        return;
78c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
79c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *file << "/*\n";
80c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (!briefComment.empty()) {
81c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << " * " << name << ": " << briefComment << "\n";
82c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << " *\n";
83c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
84c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (size_t ct = 0; ct < comment.size(); ct++) {
85c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        string s = stripHtml(comment[ct]);
86c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        s = stringReplace(s, "@", "");
87c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (!s.empty()) {
88c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << " * " << s << "\n";
89c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        } else {
90c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << " *\n";
91c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
92c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
93c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (closeBlock) {
94c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << " */\n";
95c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
96c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
97c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
98c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic void writeConstant(GeneratedFile* file, const Constant& constant) {
99c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const string name = constant.getName();
100c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    writeComment(file, name, constant.getSummary(), constant.getDescription(), true);
101c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
102c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto spec : constant.getSpecifications()) {
103c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        VersionInfo info = spec->getVersionInfo();
104c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeVersionGuardStart(file, info);
105c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << "#define " << name << " " << spec->getValue() << "\n";
106c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeVersionGuardEnd(file, info);
107c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
108c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *file << "\n";
109c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
110c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
111c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic void writeTypeSpecification(GeneratedFile* file, const string& typeName,
112c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                                   const TypeSpecification& spec) {
113c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const VersionInfo info = spec.getVersionInfo();
114c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    writeVersionGuardStart(file, info);
115c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    switch (spec.getKind()) {
116c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        case SIMPLE:
117c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << "typedef " << spec.getSimpleType() << " " << typeName << ";\n";
118c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            break;
119c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        case ENUM: {
120c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << "typedef enum ";
121c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            const string name = spec.getEnumName();
122c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            if (!name.empty()) {
123c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *file << name << " ";
124c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
125c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << "{\n";
126c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
127c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            const vector<string>& values = spec.getValues();
128c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            const vector<string>& valueComments = spec.getValueComments();
129c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            const size_t last = values.size() - 1;
130c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            for (size_t i = 0; i <= last; i++) {
131c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *file << "    " << values[i];
132c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                if (i != last) {
133c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                    *file << ",";
134c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                }
135c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                if (valueComments.size() > i && !valueComments[i].empty()) {
136c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                    *file << " // " << valueComments[i];
137c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                }
138c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *file << "\n";
139c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
140c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << "} " << typeName << ";\n";
141c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            break;
142c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
143c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        case STRUCT: {
144c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << "typedef struct ";
145c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            const string name = spec.getStructName();
146c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            if (!name.empty()) {
147c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *file << name << " ";
148c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
149c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << "{\n";
150c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
151c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            const vector<string>& fields = spec.getFields();
152c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            const vector<string>& fieldComments = spec.getFieldComments();
153c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            for (size_t i = 0; i < fields.size(); i++) {
154c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *file << "    " << fields[i] << ";";
155c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                if (fieldComments.size() > i && !fieldComments[i].empty()) {
156c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                    *file << " // " << fieldComments[i];
157c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                }
158c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *file << "\n";
159c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
160c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << "} ";
161c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            const string attrib = spec.getAttrib();
162c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            if (!attrib.empty()) {
163c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *file << attrib << " ";
164c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
165c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            *file << typeName << ";\n";
166c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            break;
167c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
168c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
169c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    writeVersionGuardEnd(file, info);
170c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *file << "\n";
171c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
172c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
173c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic void writeType(GeneratedFile* file, const Type& type) {
174c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const string name = type.getName();
175c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    writeComment(file, name, type.getSummary(), type.getDescription(), true);
176c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
177c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto spec : type.getSpecifications()) {
178c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeTypeSpecification(file, name, *spec);
179c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
180c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *file << "\n";
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
275c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic void writeFunction(GeneratedFile* file, const Function& function) {
276c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Write the generic documentation.
277c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    writeComment(file, function.getName(), function.getSummary(), function.getDescription(), false);
278c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
279c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Comment the parameters.
280c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (function.someParametersAreDocumented()) {
281c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << " *\n";
282c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << " * Parameters:\n";
283c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        for (auto p : function.getParameters()) {
284c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            if (!p->documentation.empty()) {
285c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                *file << " *   " << p->name << " " << p->documentation << "\n";
286c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            }
287c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
288c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
289c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
290c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Comment the return type.
291c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const string returnDoc = function.getReturnDocumentation();
292c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (!returnDoc.empty()) {
293c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << " *\n";
294c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        *file << " * Returns: " << returnDoc << "\n";
295c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
296c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
297c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    *file << " */\n";
298c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
299c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Write all the variants.
300c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto spec : function.getSpecifications()) {
301c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        for (auto permutation : spec->getPermutations()) {
302c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            writeFunctionPermutation(file, *spec, *permutation);
303c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
304c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
305c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
306c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
307c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletstatic bool writeHeaderFile(const SpecFile& specFile) {
308c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const string headerFileName = specFile.getHeaderFileName();
309c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
310c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // We generate one header file for each spec file.
311c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    GeneratedFile file;
312c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (!file.start(headerFileName)) {
313c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        return false;
314c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
315c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
316c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Write the comments that start the file.
317c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file.writeNotices();
318c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    writeComment(&file, headerFileName, specFile.getBriefDescription(),
319c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet                 specFile.getFullDescription(), true);
320c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
321c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Write the ifndef that prevents the file from being included twice.
322c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    const string guard = makeGuardString(headerFileName);
323c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file << "#ifndef " << guard << "\n";
324c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file << "#define " << guard << "\n\n";
325c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
326c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    // Add lines that need to be put in "as is".
327c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    if (specFile.getVerbatimInclude().size() > 0) {
328c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        for (auto s : specFile.getVerbatimInclude()) {
329c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            file << s << "\n";
330c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
331c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        file << "\n";
332c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
333c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
334c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    /* Write the constants, types, and functions in the same order as
335c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     * encountered in the spec file.
336c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet     */
337c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto iter : specFile.getConstantsList()) {
338c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeConstant(&file, *iter);
339c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
340c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto iter : specFile.getTypesList()) {
341c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeType(&file, *iter);
342c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
343c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto iter : specFile.getFunctionsList()) {
344c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        writeFunction(&file, *iter);
345c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
346c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
347c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file << "#endif // " << guard << "\n";
348c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    file.close();
349c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    return true;
350c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
351c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet
352c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletbool GenerateHeaderFiles() {
353c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    bool success = true;
354c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    for (auto specFile : systemSpecification.getSpecFiles()) {
355c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        if (!writeHeaderFile(*specFile)) {
356c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet            success = false;
357c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet        }
358c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    }
359c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet    return success;
360c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet}
361