blob: 647c657284706cd5ed776c09d767019d069c4a28 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "header_generator.h"
using std::map;
using std::string;
using std::vector;
static const string add_attribute(map<string, string> attributes,
const string& attribute) {
auto ft = attributes.find(attribute);
return (ft == attributes.end()) ? string() : ft->second;
}
static vector<int> collect_nonnull(const Syscall& sc) {
vector<int> nonnull;
int out_idx = static_cast<int>(sc.arg_spec.size());
sc.for_each_return([&](const TypeSpec& type) {
++out_idx;
if (!has_attribute("optional", type.attributes))
nonnull.push_back(out_idx);
});
return nonnull;
}
bool HeaderGenerator::syscall(std::ofstream& os, const Syscall& sc) {
constexpr uint32_t indent_spaces = 4u;
for (const auto& name_prefix : name_prefixes_) {
if (name_prefix.second(sc))
continue;
auto syscall_name = name_prefix.first + sc.name;
os << function_prefix_;
write_syscall_signature_line(
os, sc, name_prefix.first,
"\n" + string(indent_spaces, ' '),
"\n" + string(indent_spaces, ' '),
allow_pointer_wrapping_ && !sc.is_vdso(),
no_args_type_);
if (!allow_pointer_wrapping_) {
const vector<int> nonnull = collect_nonnull(sc);
if (!nonnull.empty()) {
os << " __NONNULL((";
for (int idx : nonnull) {
os << idx << ", ";
}
os.seekp(-2, std::ios_base::end);
os << "))";
}
}
os << " ";
// Writes attributes after arguments.
for (const auto& attr : sc.attributes) {
auto a = add_attribute(attributes_, attr);
if (!a.empty())
os << a << " ";
}
if (sc.ret_spec.size() > 0)
write_argument_annotation(os, sc.ret_spec[0]);
os.seekp(-1, std::ios_base::end);
os << ";\n\n";
}
return os.good();
}