1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #import "header_generator.h"
6
7 using std::map;
8 using std::string;
9 using std::vector;
10
add_attribute(map<string,string> attributes,const string & attribute)11 static const string add_attribute(map<string, string> attributes,
12 const string& attribute) {
13 auto ft = attributes.find(attribute);
14 return (ft == attributes.end()) ? string() : ft->second;
15 }
16
collect_nonnull(const Syscall & sc)17 static vector<int> collect_nonnull(const Syscall& sc) {
18 vector<int> nonnull;
19 int out_idx = static_cast<int>(sc.arg_spec.size());
20 sc.for_each_return([&](const TypeSpec& type) {
21 ++out_idx;
22 if (!has_attribute("optional", type.attributes))
23 nonnull.push_back(out_idx);
24 });
25 return nonnull;
26 }
27
syscall(std::ofstream & os,const Syscall & sc)28 bool HeaderGenerator::syscall(std::ofstream& os, const Syscall& sc) {
29 constexpr uint32_t indent_spaces = 4u;
30
31 for (const auto& name_prefix : name_prefixes_) {
32 if (name_prefix.second(sc))
33 continue;
34
35 auto syscall_name = name_prefix.first + sc.name;
36
37 os << function_prefix_;
38
39 write_syscall_signature_line(
40 os, sc, name_prefix.first,
41 "\n" + string(indent_spaces, ' '),
42 "\n" + string(indent_spaces, ' '),
43 allow_pointer_wrapping_ && !sc.is_vdso(),
44 no_args_type_);
45
46 if (!allow_pointer_wrapping_) {
47 const vector<int> nonnull = collect_nonnull(sc);
48 if (!nonnull.empty()) {
49 os << " __NONNULL((";
50 for (int idx : nonnull) {
51 os << idx << ", ";
52 }
53 os.seekp(-2, std::ios_base::end);
54 os << "))";
55 }
56 }
57
58 os << " ";
59
60 // Writes attributes after arguments.
61 for (const auto& attr : sc.attributes) {
62 auto a = add_attribute(attributes_, attr);
63 if (!a.empty())
64 os << a << " ";
65 }
66
67 if (sc.ret_spec.size() > 0)
68 write_argument_annotation(os, sc.ret_spec[0]);
69
70 os.seekp(-1, std::ios_base::end);
71
72 os << ";\n\n";
73 }
74
75 return os.good();
76 }
77