1 // Copyright 2018 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 #include "generator.h"
6 
header(std::ofstream & os)7 bool JsonGenerator::header(std::ofstream& os) {
8     os << "{\n";
9     os << "  \"syscalls\": [\n";
10     return os.good();
11 }
12 
footer(std::ofstream & os)13 bool JsonGenerator::footer(std::ofstream& os) {
14     os << "\n";
15     os << "  ]\n";
16     os << "}\n";
17     return os.good();
18 }
19 
syscall(std::ofstream & os,const Syscall & sc)20 bool JsonGenerator::syscall(std::ofstream& os, const Syscall& sc) {
21     if (first_syscall_) {
22         first_syscall_ = false;
23     } else {
24         os << ",\n";
25     }
26     os << "    {\n";
27     os << "      \"name\": \"" << sc.name << "\",\n";
28 
29     // Attributes.
30     os << "      \"attributes\": [\n";
31     for (std::vector<std::string>::size_type index = 0;
32          index != sc.attributes.size(); ++index) {
33         os << "        \"" << sc.attributes[index] << "\"";
34         if (index < sc.attributes.size() - 1) {
35             os << ",";
36         }
37         os << "\n";
38     }
39     os << "      ],\n";
40 
41     // Top description.
42     os << "      \"top_description\": [\n";
43     os << "        ";
44     for (size_t i = 0; i < sc.top_description.size(); ++i) {
45         os << "\"" << sc.top_description[i] << "\"";
46         if (i < sc.top_description.size() - 1) {
47             os << ", ";
48         }
49     }
50     os << "\n      ],\n";
51 
52     // Requirements.
53     os << "      \"requirements\": [\n";
54     for (size_t i = 0; i < sc.requirements.size(); ++i) {
55         os << "        ";
56         for (size_t j = 0; j < sc.requirements[i].size(); ++j) {
57             os << "\"" << sc.requirements[i][j] << "\"";
58             if (j < sc.requirements[i].size() - 1) {
59                 os << ", ";
60             }
61         }
62         if (i < sc.requirements.size() - 1) {
63             os << ",";
64         }
65         os << "\n";
66     }
67     os << "      ],\n";
68 
69     // Arguments.
70     os << "      \"arguments\": [\n";
71     bool first_arg = true;
72     bool has_args = false;
73     sc.for_each_kernel_arg([&](const TypeSpec& arg) {
74         has_args = true;
75         if (first_arg) {
76             first_arg = false;
77         } else {
78             os << ",\n";
79         }
80         os << "        {\n";
81         os << "          \"name\": \"" << arg.name << "\",\n";
82         os << "          \"type\": \"" << arg.type << "\",\n";
83 
84         // Array spec.
85         os << "          \"is_array\": " << (arg.arr_spec ? "true" : "false") << ",\n";
86         if (arg.arr_spec) {
87             if (arg.arr_spec->count) {
88                 os << "          \"array_count\": " << arg.arr_spec->count << ",\n";
89             } else {
90                 os << "          \"array_multipliers\": [\n";
91                 for (std::vector<std::string>::size_type index = 0;
92                      index != arg.arr_spec->multipliers.size(); ++index) {
93                     os << "            \"" << arg.arr_spec->multipliers[index] << "\"";
94                     if (index < arg.arr_spec->multipliers.size() - 1) {
95                         os << ",";
96                     }
97                     os << "\n";
98                 }
99                 os << "          ],\n";
100             }
101         }
102 
103         // Attributes.
104         os << "          \"attributes\": [\n";
105         for (std::vector<std::string>::size_type index = 0;
106              index != arg.attributes.size(); ++index) {
107             os << "            \"" << arg.attributes[index] << "\"";
108             if (index < arg.attributes.size() - 1) {
109                 os << ",";
110             }
111             os << "\n";
112         }
113         os << "          ]\n";
114         os << "        }";
115     });
116     if (has_args) {
117         os << "\n";
118     }
119     os << "      ],\n";
120 
121     os << "      \"return_type\": \"" << sc.return_type() << "\"\n";
122 
123     os << "    }";
124     return os.good();
125 }
126