Branch data Line data Source code
1 : : #include <string.h>
2 : :
3 : : #include "codegen_c.h"
4 : :
5 : : #define llu(x) (long long unsigned int)(x)
6 : : #define lld(x) (long long int)(x)
7 : :
8 : 10 : int fb_gen_common_c_builder_header(fb_output_t *out)
9 : : {
10 : 10 : const char *nsc = out->nsc;
11 : 10 : const char *nscup = out->nscup;
12 : :
13 : 10 : fprintf(out->fp, "#ifndef %s_COMMON_BUILDER_H\n", nscup);
14 : 10 : fprintf(out->fp, "#define %s_COMMON_BUILDER_H\n", nscup);
15 : 10 : fprintf(out->fp, "\n/* " FLATCC_GENERATED_BY " */\n\n");
16 : 10 : fprintf(out->fp, "/* Common FlatBuffers build functionality for C. */\n\n");
17 : : gen_pragma_push(out);
18 : :
19 : 10 : fprintf(out->fp, "#ifndef FLATBUILDER_H\n");
20 : 10 : fprintf(out->fp, "#include \"flatcc/flatcc_builder.h\"\n");
21 : 10 : fprintf(out->fp, "#endif\n");
22 [ + - ]: 10 : if (strcmp(nsc, "flatcc_builder_")) {
23 : 10 : fprintf(out->fp, "typedef flatcc_builder_t %sbuilder_t;\n", nsc);
24 : 10 : fprintf(out->fp, "typedef flatcc_builder_ref_t %sref_t;\n", nsc);
25 : 10 : fprintf(out->fp, "typedef flatcc_builder_ref_t %svec_ref_t;\n", nsc);
26 : 10 : fprintf(out->fp, "/* integer return code (ref and ptr always fail on 0) */\n"
27 : : "#define %sfailed(x) ((x) < 0)\n", nsc);
28 : : }
29 : 10 : fprintf(out->fp, "typedef %sref_t %sroot_t;\n", nsc, nsc);
30 : 10 : fprintf(out->fp, "#define %sroot(ref) ((%sroot_t)(ref))\n", nsc, nsc);
31 [ - + ]: 10 : if (strcmp(nsc, "flatbuffers_")) {
32 : 0 : fprintf(out->fp, "#define %sis_native_pe flatbuffers_is_native_pe\n", nsc);
33 : 0 : fprintf(out->fp, "typedef flatbuffers_fid_t %sfid_t;\n", nsc);
34 : : }
35 : 10 : fprintf(out->fp, "\n");
36 : 10 : fprintf(out->fp,
37 : : "#define __%sbuild_buffer(NS)\\\n"
38 : : "typedef NS ## ref_t NS ## buffer_ref_t;\\\n"
39 : : "static inline int NS ## buffer_start(NS ## builder_t *B, NS ##fid_t fid)\\\n"
40 : : "{ return flatcc_builder_start_buffer(B, fid, 0, 0); }\\\n"
41 : : "static inline int NS ## buffer_start_with_size(NS ## builder_t *B, NS ##fid_t fid)\\\n"
42 : : "{ return flatcc_builder_start_buffer(B, fid, 0, flatcc_builder_with_size); }\\\n"
43 : : "static inline int NS ## buffer_start_aligned(NS ## builder_t *B, NS ##fid_t fid, uint16_t block_align)\\\n"
44 : : "{ return flatcc_builder_start_buffer(B, fid, block_align, 0); }\\\n"
45 : : "static inline int NS ## buffer_start_aligned_with_size(NS ## builder_t *B, NS ##fid_t fid, uint16_t block_align)\\\n"
46 : : "{ return flatcc_builder_start_buffer(B, fid, block_align, flatcc_builder_with_size); }\\\n"
47 : : "static inline NS ## buffer_ref_t NS ## buffer_end(NS ## builder_t *B, NS ## ref_t root)\\\n"
48 : : "{ return flatcc_builder_end_buffer(B, root); }\n"
49 : : "\n",
50 : : nsc);
51 : :
52 : 10 : fprintf(out->fp,
53 : : "#define __%sbuild_table_root(NS, N, FID, TFID)\\\n"
54 : : "static inline int N ## _start_as_root(NS ## builder_t *B)\\\n"
55 : : "{ return NS ## buffer_start(B, FID) ? -1 : N ## _start(B); }\\\n"
56 : : "static inline int N ## _start_as_root_with_size(NS ## builder_t *B)\\\n"
57 : : "{ return NS ## buffer_start_with_size(B, FID) ? -1 : N ## _start(B); }\\\n"
58 : : "static inline int N ## _start_as_typed_root(NS ## builder_t *B)\\\n"
59 : : "{ return NS ## buffer_start(B, TFID) ? -1 : N ## _start(B); }\\\n"
60 : : "static inline int N ## _start_as_typed_root_with_size(NS ## builder_t *B)\\\n"
61 : : "{ return NS ## buffer_start_with_size(B, TFID) ? -1 : N ## _start(B); }\\\n"
62 : : "static inline NS ## buffer_ref_t N ## _end_as_root(NS ## builder_t *B)\\\n"
63 : : "{ return NS ## buffer_end(B, N ## _end(B)); }\\\n"
64 : : "static inline NS ## buffer_ref_t N ## _end_as_typed_root(NS ## builder_t *B)\\\n"
65 : : "{ return NS ## buffer_end(B, N ## _end(B)); }\\\n"
66 : : /*
67 : : * Unlike structs, we do no use flatcc_builder_create_buffer
68 : : * because we would have to manage alignment, and we save very
69 : : * little because tables require stack allocations in any case.
70 : : */
71 : : "static inline NS ## buffer_ref_t N ## _create_as_root(NS ## builder_t *B __ ## N ## _formal_args)\\\n"
72 : : "{ if (NS ## buffer_start(B, FID)) return 0; return NS ## buffer_end(B, N ## _create(B __ ## N ## _call_args)); }\\\n"
73 : : "static inline NS ## buffer_ref_t N ## _create_as_root_with_size(NS ## builder_t *B __ ## N ## _formal_args)\\\n"
74 : : "{ if (NS ## buffer_start_with_size(B, FID)) return 0; return NS ## buffer_end(B, N ## _create(B __ ## N ## _call_args)); }\\\n"
75 : : "static inline NS ## buffer_ref_t N ## _create_as_typed_root(NS ## builder_t *B __ ## N ## _formal_args)\\\n"
76 : : "{ if (NS ## buffer_start(B, TFID)) return 0; return NS ## buffer_end(B, N ## _create(B __ ## N ## _call_args)); }\\\n"
77 : : "static inline NS ## buffer_ref_t N ## _create_as_typed_root_with_size(NS ## builder_t *B __ ## N ## _formal_args)\\\n"
78 : : "{ if (NS ## buffer_start_with_size(B, TFID)) return 0; return NS ## buffer_end(B, N ## _create(B __ ## N ## _call_args)); }\n"
79 : : "\n",
80 : : nsc);
81 : :
82 : 10 : fprintf(out->fp,
83 : : "#define __%sbuild_table_prolog(NS, N, FID, TFID)\\\n"
84 : : "__%sbuild_table_vector_ops(NS, N ## _vec, N)\\\n"
85 : : "__%sbuild_table_root(NS, N, FID, TFID)\n"
86 : : "\n",
87 : : nsc, nsc, nsc);
88 : :
89 : :
90 : 10 : fprintf(out->fp,
91 : : "#define __%sbuild_struct_root(NS, N, A, FID, TFID)\\\n"
92 : : "static inline N ## _t *N ## _start_as_root(NS ## builder_t *B)\\\n"
93 : : "{ return NS ## buffer_start(B, FID) ? 0 : N ## _start(B); }\\\n"
94 : : "static inline N ## _t *N ## _start_as_root_with_size(NS ## builder_t *B)\\\n"
95 : : "{ return NS ## buffer_start_with_size(B, FID) ? 0 : N ## _start(B); }\\\n"
96 : : "static inline N ## _t *N ## _start_as_typed_root(NS ## builder_t *B)\\\n"
97 : : "{ return NS ## buffer_start(B, TFID) ? 0 : N ## _start(B); }\\\n"
98 : : "static inline N ## _t *N ## _start_as_typed_root_with_size(NS ## builder_t *B)\\\n"
99 : : "{ return NS ## buffer_start_with_size(B, TFID) ? 0 : N ## _start(B); }\\\n"
100 : : "static inline NS ## buffer_ref_t N ## _end_as_root(NS ## builder_t *B)\\\n"
101 : : "{ return NS ## buffer_end(B, N ## _end(B)); }\\\n"
102 : : "static inline NS ## buffer_ref_t N ## _end_as_typed_root(NS ## builder_t *B)\\\n"
103 : : "{ return NS ## buffer_end(B, N ## _end(B)); }\\\n"
104 : : "static inline NS ## buffer_ref_t N ## _end_pe_as_root(NS ## builder_t *B)\\\n"
105 : : "{ return NS ## buffer_end(B, N ## _end_pe(B)); }\\\n"
106 : : "static inline NS ## buffer_ref_t N ## _end_pe_as_typed_root(NS ## builder_t *B)\\\n"
107 : : "{ return NS ## buffer_end(B, N ## _end_pe(B)); }\\\n"
108 : : "static inline NS ## buffer_ref_t N ## _create_as_root(NS ## builder_t *B __ ## N ## _formal_args)\\\n"
109 : : "{ return flatcc_builder_create_buffer(B, FID, 0,\\\n"
110 : : " N ## _create(B __ ## N ## _call_args), A, 0); }\\\n"
111 : : "static inline NS ## buffer_ref_t N ## _create_as_root_with_size(NS ## builder_t *B __ ## N ## _formal_args)\\\n"
112 : : "{ return flatcc_builder_create_buffer(B, FID, 0,\\\n"
113 : : " N ## _create(B __ ## N ## _call_args), A, flatcc_builder_with_size); }\\\n"
114 : : "static inline NS ## buffer_ref_t N ## _create_as_typed_root(NS ## builder_t *B __ ## N ## _formal_args)\\\n"
115 : : "{ return flatcc_builder_create_buffer(B, TFID, 0,\\\n"
116 : : " N ## _create(B __ ## N ## _call_args), A, 0); }\\\n"
117 : : "static inline NS ## buffer_ref_t N ## _create_as_typed_root_with_size(NS ## builder_t *B __ ## N ## _formal_args)\\\n"
118 : : "{ return flatcc_builder_create_buffer(B, TFID, 0,\\\n"
119 : : " N ## _create(B __ ## N ## _call_args), A, flatcc_builder_with_size); }\n"
120 : : "\n",
121 : : nsc);
122 : :
123 : 10 : fprintf(out->fp,
124 : : "#define __%sbuild_nested_table_root(NS, N, TN, FID, TFID)\\\n"
125 : : "static inline int N ## _start_as_root(NS ## builder_t *B)\\\n"
126 : : "{ return NS ## buffer_start(B, FID) ? -1 : TN ## _start(B); }\\\n"
127 : : "static inline int N ## _start_as_typed_root(NS ## builder_t *B)\\\n"
128 : : "{ return NS ## buffer_start(B, TFID) ? -1 : TN ## _start(B); }\\\n"
129 : : "static inline int N ## _end_as_root(NS ## builder_t *B)\\\n"
130 : : "{ return N ## _add(B, NS ## buffer_end(B, TN ## _end(B))); }\\\n"
131 : : "static inline int N ## _end_as_typed_root(NS ## builder_t *B)\\\n"
132 : : "{ return N ## _add(B, NS ## buffer_end(B, TN ## _end(B))); }\\\n"
133 : : "static inline int N ## _nest(NS ## builder_t *B, void *data, size_t size, uint16_t align)\\\n"
134 : : "{ if (NS ## buffer_start(B, FID)) return -1;\\\n"
135 : : " return N ## _add(B, NS ## buffer_end(B, flatcc_builder_create_vector(B, data, size, 1,\\\n"
136 : : " align ? align : 8, FLATBUFFERS_COUNT_MAX(1)))); }\\\n"
137 : : "static inline int N ## _typed_nest(NS ## builder_t *B, void *data, size_t size, uint16_t align)\\\n"
138 : : "{ if (NS ## buffer_start(B, TFID)) return -1;\\\n"
139 : : " return N ## _add(B, NS ## buffer_end(B, flatcc_builder_create_vector(B, data, size, 1,\\\n"
140 : : " align ? align : 8, FLATBUFFERS_COUNT_MAX(1)))); }\n"
141 : : "\n",
142 : : nsc);
143 : :
144 : 10 : fprintf(out->fp,
145 : : "#define __%sbuild_nested_struct_root(NS, N, TN, A, FID, TFID)\\\n"
146 : : "static inline TN ## _t *N ## _start_as_root(NS ## builder_t *B)\\\n"
147 : : "{ return NS ## buffer_start(B, FID) ? 0 : TN ## _start(B); }\\\n"
148 : : "static inline TN ## _t *N ## _start_as_typed_root(NS ## builder_t *B)\\\n"
149 : : "{ return NS ## buffer_start(B, FID) ? 0 : TN ## _start(B); }\\\n"
150 : : "static inline int N ## _end_as_root(NS ## builder_t *B)\\\n"
151 : : "{ return N ## _add(B, NS ## buffer_end(B, TN ## _end(B))); }\\\n"
152 : : "static inline int N ## _end_as_typed_root(NS ## builder_t *B)\\\n"
153 : : "{ return N ## _add(B, NS ## buffer_end(B, TN ## _end(B))); }\\\n"
154 : : "static inline int N ## _end_pe_as_root(NS ## builder_t *B)\\\n"
155 : : "{ return N ## _add(B, NS ## buffer_end(B, TN ## _end_pe(B))); }\\\n"
156 : : "static inline int N ## _create_as_root(NS ## builder_t *B __ ## TN ## _formal_args)\\\n"
157 : : "{ return N ## _add(B, flatcc_builder_create_buffer(B, FID, 0,\\\n"
158 : : " TN ## _create(B __ ## TN ## _call_args), A, flatcc_builder_is_nested)); }\\\n"
159 : : "static inline int N ## _create_as_typed_root(NS ## builder_t *B __ ## TN ## _formal_args)\\\n"
160 : : "{ return N ## _add(B, flatcc_builder_create_buffer(B, TFID, 0,\\\n"
161 : : " TN ## _create(B __ ## TN ## _call_args), A, flatcc_builder_is_nested)); }\\\n"
162 : : "static inline int N ## _nest(NS ## builder_t *B, void *data, size_t size, uint16_t align)\\\n"
163 : : "{ if (NS ## buffer_start(B, FID)) return -1;\\\n"
164 : : " return N ## _add(B, NS ## buffer_end(B, flatcc_builder_create_vector(B, data, size, 1,\\\n"
165 : : " align < A ? A : align, FLATBUFFERS_COUNT_MAX(1)))); }\\\n"
166 : : "static inline int N ## _typed_nest(NS ## builder_t *B, void *data, size_t size, uint16_t align)\\\n"
167 : : "{ if (NS ## buffer_start(B, TFID)) return -1;\\\n"
168 : : " return N ## _add(B, NS ## buffer_end(B, flatcc_builder_create_vector(B, data, size, 1,\\\n"
169 : : " align < A ? A : align, FLATBUFFERS_COUNT_MAX(1)))); }\n"
170 : : "\n",
171 : : nsc);
172 : :
173 : 10 : fprintf(out->fp,
174 : : "#define __%sbuild_vector_ops(NS, V, N, TN, T)\\\n"
175 : : "static inline T *V ## _extend(NS ## builder_t *B, size_t len)\\\n"
176 : : "{ return flatcc_builder_extend_vector(B, len); }\\\n"
177 : : "static inline T *V ## _append(NS ## builder_t *B, const T *data, size_t len)\\\n"
178 : : "{ return flatcc_builder_append_vector(B, data, len); }\\\n"
179 : : "static inline int V ## _truncate(NS ## builder_t *B, size_t len)\\\n"
180 : : "{ return flatcc_builder_truncate_vector(B, len); }\\\n"
181 : : "static inline T *V ## _edit(NS ## builder_t *B)\\\n"
182 : : "{ return flatcc_builder_vector_edit(B); }\\\n"
183 : : "static inline size_t V ## _reserved_len(NS ## builder_t *B)\\\n"
184 : : "{ return flatcc_builder_vector_count(B); }\\\n"
185 : : "static inline T *V ## _push(NS ## builder_t *B, const T *p)\\\n"
186 : : "{ T *_p; return (_p = flatcc_builder_extend_vector(B, 1)) ? (memcpy(_p, p, TN ## __size()), _p) : 0; }\\\n"
187 : : "static inline T *V ## _push_copy(NS ## builder_t *B, const T *p)\\\n"
188 : : "{ T *_p; return (_p = flatcc_builder_extend_vector(B, 1)) ? TN ## _copy(_p, p) : 0; }\\\n"
189 : : "static inline T *V ## _push_create(NS ## builder_t *B __ ## TN ## _formal_args)\\\n"
190 : : "{ T *_p; return (_p = flatcc_builder_extend_vector(B, 1)) ? TN ## _assign(_p __ ## TN ## _call_args) : 0; }\n"
191 : : "\n",
192 : : nsc);
193 : :
194 : 10 : fprintf(out->fp,
195 : : /* NS: common namespace, N: typename, T: element type, S: elem size, A: alignment */
196 : : "#define __%sbuild_vector(NS, N, T, S, A)\\\n"
197 : : "typedef NS ## ref_t N ## _vec_ref_t;\\\n"
198 : : "static inline int N ## _vec_start(NS ## builder_t *B)\\\n"
199 : : "{ return flatcc_builder_start_vector(B, S, A, FLATBUFFERS_COUNT_MAX(S)); }\\\n"
200 : : "static inline N ## _vec_ref_t N ## _vec_end_pe(NS ## builder_t *B)\\\n"
201 : : "{ return flatcc_builder_end_vector(B); }\\\n"
202 : : "static inline N ## _vec_ref_t N ## _vec_end(NS ## builder_t *B)\\\n"
203 : : "{ if (!NS ## is_native_pe()) { size_t i, n; T *p = flatcc_builder_vector_edit(B);\\\n"
204 : : " for (i = 0, n = flatcc_builder_vector_count(B); i < n; ++i)\\\n"
205 : : " { N ## _to_pe(N ## __ptr_add(p, i)); }} return flatcc_builder_end_vector(B); }\\\n"
206 : : "static inline N ## _vec_ref_t N ## _vec_create_pe(NS ## builder_t *B, const T *data, size_t len)\\\n"
207 : : "{ return flatcc_builder_create_vector(B, data, len, S, A, FLATBUFFERS_COUNT_MAX(S)); }\\\n"
208 : : "static inline N ## _vec_ref_t N ## _vec_create(NS ## builder_t *B, const T *data, size_t len)\\\n"
209 : : "{ if (!NS ## is_native_pe()) { size_t i; T *p; int ret = flatcc_builder_start_vector(B, S, A, FLATBUFFERS_COUNT_MAX(S)); if (ret) { return ret; }\\\n"
210 : : " p = flatcc_builder_extend_vector(B, len); if (!p) return 0;\\\n"
211 : : " for (i = 0; i < len; ++i) { N ## _copy_to_pe(N ## __ptr_add(p, i), N ## __const_ptr_add(data, i)); }\\\n"
212 : : " return flatcc_builder_end_vector(B); } else return flatcc_builder_create_vector(B, data, len, S, A, FLATBUFFERS_COUNT_MAX(S)); }\\\n"
213 : : "static inline N ## _vec_ref_t N ## _vec_clone(NS ## builder_t *B, N ##_vec_t vec)\\\n"
214 : : "{ return flatcc_builder_create_vector(B, vec, N ## _vec_len(vec), S, A, FLATBUFFERS_COUNT_MAX(S)); }\\\n"
215 : : "static inline N ## _vec_ref_t N ## _vec_slice(NS ## builder_t *B, N ##_vec_t vec, size_t index, size_t len)\\\n"
216 : : "{ size_t n = N ## _vec_len(vec); if (index >= n) index = n; n -= index; if (len > n) len = n;\\\n"
217 : : " return flatcc_builder_create_vector(B, N ## __const_ptr_add(vec, index), len, S, A, FLATBUFFERS_COUNT_MAX(S)); }\\\n"
218 : : "__%sbuild_vector_ops(NS, N ## _vec, N, N, T)\n"
219 : : "\n",
220 : : nsc, nsc);
221 : :
222 : : /* In addtion to offset_vector_ops... */
223 : 10 : fprintf(out->fp,
224 : : "#define __%sbuild_string_vector_ops(NS, N)\\\n"
225 : : "static inline int N ## _push_start(NS ## builder_t *B)\\\n"
226 : : "{ return NS ## string_start(B); }\\\n"
227 : : "static inline NS ## string_ref_t *N ## _push_end(NS ## builder_t *B)\\\n"
228 : : "{ return NS ## string_vec_push(B, NS ## string_end(B)); }\\\n"
229 : : "static inline NS ## string_ref_t *N ## _push_create(NS ## builder_t *B, const char *s, size_t len)\\\n"
230 : : "{ return NS ## string_vec_push(B, NS ## string_create(B, s, len)); }\\\n"
231 : : "static inline NS ## string_ref_t *N ## _push_create_str(NS ## builder_t *B, const char *s)\\\n"
232 : : "{ return NS ## string_vec_push(B, NS ## string_create_str(B, s)); }\\\n"
233 : : "static inline NS ## string_ref_t *N ## _push_create_strn(NS ## builder_t *B, const char *s, size_t max_len)\\\n"
234 : : "{ return NS ## string_vec_push(B, NS ## string_create_strn(B, s, max_len)); }\\\n"
235 : : "static inline NS ## string_ref_t *N ## _push_clone(NS ## builder_t *B, NS ## string_t string)\\\n"
236 : : "{ return NS ## string_vec_push(B, NS ## string_clone(B, string)); }\\\n"
237 : : "static inline NS ## string_ref_t *N ## _push_slice(NS ## builder_t *B, NS ## string_t string, size_t index, size_t len)\\\n"
238 : : "{ return NS ## string_vec_push(B, NS ## string_slice(B, string, index, len)); }\n"
239 : : "\n",
240 : : nsc);
241 : :
242 : : /* In addtion to offset_vector_ops... */
243 : 10 : fprintf(out->fp,
244 : : "#define __%sbuild_table_vector_ops(NS, N, TN)\\\n"
245 : : "static inline int N ## _push_start(NS ## builder_t *B)\\\n"
246 : : "{ return TN ## _start(B); }\\\n"
247 : : "static inline TN ## _ref_t *N ## _push_end(NS ## builder_t *B)\\\n"
248 : : "{ return N ## _push(B, TN ## _end(B)); }\\\n"
249 : : "static inline TN ## _ref_t *N ## _push_create(NS ## builder_t *B __ ## TN ##_formal_args)\\\n"
250 : : "{ return N ## _push(B, TN ## _create(B __ ## TN ## _call_args)); }\n"
251 : : "\n",
252 : : nsc);
253 : :
254 : 10 : fprintf(out->fp,
255 : : "#define __%sbuild_offset_vector_ops(NS, V, N, TN)\\\n"
256 : : "static inline TN ## _ref_t *V ## _extend(NS ## builder_t *B, size_t len)\\\n"
257 : : "{ return flatcc_builder_extend_offset_vector(B, len); }\\\n"
258 : : "static inline TN ## _ref_t *V ## _append(NS ## builder_t *B, const TN ## _ref_t *data, size_t len)\\\n"
259 : : "{ return flatcc_builder_append_offset_vector(B, data, len); }\\\n"
260 : : "static inline int V ## _truncate(NS ## builder_t *B, size_t len)\\\n"
261 : : "{ return flatcc_builder_truncate_offset_vector(B, len); }\\\n"
262 : : "static inline TN ## _ref_t *V ## _edit(NS ## builder_t *B)\\\n"
263 : : "{ return flatcc_builder_offset_vector_edit(B); }\\\n"
264 : : "static inline size_t V ## _reserved_len(NS ## builder_t *B)\\\n"
265 : : "{ return flatcc_builder_offset_vector_count(B); }\\\n"
266 : : "static inline TN ## _ref_t *V ## _push(NS ## builder_t *B, const TN ## _ref_t ref)\\\n"
267 : : "{ return ref ? flatcc_builder_offset_vector_push(B, ref) : 0; }\n"
268 : : "\n",
269 : : nsc);
270 : :
271 : 10 : fprintf(out->fp,
272 : : "#define __%sbuild_offset_vector(NS, N)\\\n"
273 : : "typedef NS ## ref_t N ## _vec_ref_t;\\\n"
274 : : "static inline int N ## _vec_start(NS ## builder_t *B)\\\n"
275 : : "{ return flatcc_builder_start_offset_vector(B); }\\\n"
276 : : "static inline N ## _vec_ref_t N ## _vec_end(NS ## builder_t *B)\\\n"
277 : : "{ return flatcc_builder_end_offset_vector(B); }\\\n"
278 : : "static inline N ## _vec_ref_t N ## _vec_create(NS ## builder_t *B, const N ## _ref_t *data, size_t len)\\\n"
279 : : "{ return flatcc_builder_create_offset_vector(B, data, len); }\\\n"
280 : : "__%sbuild_offset_vector_ops(NS, N ## _vec, N, N)\n"
281 : : "\n",
282 : : nsc, nsc);
283 : :
284 : 10 : fprintf(out->fp,
285 : : "#define __%sbuild_string_ops(NS, N)\\\n"
286 : : "static inline char *N ## _append(NS ## builder_t *B, const char *s, size_t len)\\\n"
287 : : "{ return flatcc_builder_append_string(B, s, len); }\\\n"
288 : : "static inline char *N ## _append_str(NS ## builder_t *B, const char *s)\\\n"
289 : : "{ return flatcc_builder_append_string_str(B, s); }\\\n"
290 : : "static inline char *N ## _append_strn(NS ## builder_t *B, const char *s, size_t len)\\\n"
291 : : "{ return flatcc_builder_append_string_strn(B, s, len); }\\\n"
292 : : "static inline size_t N ## _reserved_len(NS ## builder_t *B)\\\n"
293 : : "{ return flatcc_builder_string_len(B); }\\\n"
294 : : "static inline char *N ## _extend(NS ## builder_t *B, size_t len)\\\n"
295 : : "{ return flatcc_builder_extend_string(B, len); }\\\n"
296 : : "static inline char *N ## _edit(NS ## builder_t *B)\\\n"
297 : : "{ return flatcc_builder_string_edit(B); }\\\n"
298 : : "static inline int N ## _truncate(NS ## builder_t *B, size_t len)\\\n"
299 : : "{ return flatcc_builder_truncate_string(B, len); }\n"
300 : : "\n",
301 : : nsc);
302 : :
303 : 10 : fprintf(out->fp,
304 : : "#define __%sbuild_string(NS)\\\n"
305 : : "typedef NS ## ref_t NS ## string_ref_t;\\\n"
306 : : "static inline int NS ## string_start(NS ## builder_t *B)\\\n"
307 : : "{ return flatcc_builder_start_string(B); }\\\n"
308 : : "static inline NS ## string_ref_t NS ## string_end(NS ## builder_t *B)\\\n"
309 : : "{ return flatcc_builder_end_string(B); }\\\n"
310 : : "static inline NS ## ref_t NS ## string_create(NS ## builder_t *B, const char *s, size_t len)\\\n"
311 : : "{ return flatcc_builder_create_string(B, s, len); }\\\n"
312 : : "static inline NS ## ref_t NS ## string_create_str(NS ## builder_t *B, const char *s)\\\n"
313 : : "{ return flatcc_builder_create_string_str(B, s); }\\\n"
314 : : "static inline NS ## ref_t NS ## string_create_strn(NS ## builder_t *B, const char *s, size_t len)\\\n"
315 : : "{ return flatcc_builder_create_string_strn(B, s, len); }\\\n"
316 : : "static inline NS ## string_ref_t NS ## string_clone(NS ## builder_t *B, NS ## string_t string)\\\n"
317 : : "{ return flatcc_builder_create_string(B, string, NS ## string_len(string)); }\\\n"
318 : : "static inline NS ## string_ref_t NS ## string_slice(NS ## builder_t *B, NS ## string_t string, size_t index, size_t len)\\\n"
319 : : "{ size_t n = NS ## string_len(string); if (index >= n) index = n; n -= index; if (len > n) len = n;\\\n"
320 : : " return flatcc_builder_create_string(B, string + index, len); }\\\n"
321 : : "__%sbuild_string_ops(NS, NS ## string)\\\n"
322 : : "__%sbuild_offset_vector(NS, NS ## string)\n"
323 : : "\n",
324 : : nsc, nsc, nsc);
325 : 10 : fprintf(out->fp,
326 : : "#define __%scopy_from_pe(P, P2, N) (*(P) = N ## _cast_from_pe(*P2), (P))\n"
327 : : "#define __%sfrom_pe(P, N) (*(P) = N ## _cast_from_pe(*P), (P))\n"
328 : : "#define __%scopy_to_pe(P, P2, N) (*(P) = N ## _cast_to_pe(*P2), (P))\n"
329 : : "#define __%sto_pe(P, N) (*(P) = N ## _cast_to_pe(*P), (P))\n",
330 : : nsc, nsc, nsc, nsc);
331 : 10 : fprintf(out->fp,
332 : : "#define __%sdefine_scalar_primitives(NS, N, T)\\\n"
333 : : "static inline T *N ## _from_pe(T *p) { return __ ## NS ## from_pe(p, N); }\\\n"
334 : : "static inline T *N ## _to_pe(T *p) { return __ ## NS ## to_pe(p, N); }\\\n"
335 : : "static inline T *N ## _copy(T *p, const T *p2) { *p = *p2; return p; }\\\n"
336 : : "static inline T *N ## _copy_from_pe(T *p, const T *p2)\\\n"
337 : : "{ return __ ## NS ## copy_from_pe(p, p2, N); }\\\n"
338 : : "static inline T *N ## _copy_to_pe(T *p, const T *p2) \\\n"
339 : : "{ return __ ## NS ## copy_to_pe(p, p2, N); }\\\n"
340 : : "static inline T *N ## _assign(T *p, const T v0) { *p = v0; return p; }\\\n"
341 : : "static inline T *N ## _assign_from_pe(T *p, T v0)\\\n"
342 : : "{ *p = N ## _cast_from_pe(v0); return p; }\\\n"
343 : : "static inline T *N ## _assign_to_pe(T *p, T v0)\\\n"
344 : : "{ *p = N ## _cast_to_pe(v0); return p; }\n"
345 : : "#define __%sbuild_scalar(NS, N, T)\\\n"
346 : : "__ ## NS ## define_scalar_primitives(NS, N, T)\\\n"
347 : : "__ ## NS ## build_vector(NS, N, T, sizeof(T), sizeof(T))\n",
348 : : nsc, nsc);
349 : :
350 : 10 : fprintf(out->fp,
351 : : "/* Depends on generated copy_to/from_pe functions, and the type. */\n"
352 : : "#define __%sdefine_struct_primitives(NS, N)\\\n"
353 : : "static inline N ## _t *N ##_to_pe(N ## _t *p)\\\n"
354 : : "{ if (!NS ## is_native_pe()) { N ## _copy_to_pe(p, p); }; return p; }\\\n"
355 : : "static inline N ## _t *N ##_from_pe(N ## _t *p)\\\n"
356 : : "{ if (!NS ## is_native_pe()) { N ## _copy_from_pe(p, p); }; return p; }\\\n"
357 : : "static inline N ## _t *N ## _clear(N ## _t *p) { return memset(p, 0, N ## __size()); }\n"
358 : : "\n"
359 : : "/* Depends on generated copy/assign_to/from_pe functions, and the type. */\n"
360 : : "#define __%sbuild_struct(NS, N, S, A, FID, TFID)\\\n"
361 : : "__ ## NS ## define_struct_primitives(NS, N)\\\n"
362 : : "typedef NS ## ref_t N ## _ref_t;\\\n"
363 : : "static inline N ## _t *N ## _start(NS ## builder_t *B)\\\n"
364 : : "{ return flatcc_builder_start_struct(B, S, A); }\\\n"
365 : : "static inline N ## _ref_t N ## _end(NS ## builder_t *B)\\\n"
366 : : "{ if (!NS ## is_native_pe()) { N ## _to_pe(flatcc_builder_struct_edit(B)); }\\\n"
367 : : " return flatcc_builder_end_struct(B); }\\\n"
368 : : "static inline N ## _ref_t N ## _end_pe(NS ## builder_t *B)\\\n"
369 : : "{ return flatcc_builder_end_struct(B); }\\\n"
370 : : "static inline N ## _ref_t N ## _create(NS ## builder_t *B __ ## N ## _formal_args)\\\n"
371 : : "{ N ## _t *_p = N ## _start(B); if (!_p) return 0; N ##_assign_to_pe(_p __ ## N ## _call_args);\\\n"
372 : : " return N ## _end_pe(B); }\\\n"
373 : : "__%sbuild_vector(NS, N, N ## _t, S, A)\\\n"
374 : : "__%sbuild_struct_root(NS, N, A, FID, TFID)\n"
375 : : "\n",
376 : : nsc, nsc, nsc, nsc);
377 : :
378 : 10 : fprintf(out->fp,
379 : : "#define __%sbuild_table(NS, N, K)\\\n"
380 : : "typedef NS ## ref_t N ## _ref_t;\\\n"
381 : : "static inline int N ## _start(NS ## builder_t *B)\\\n"
382 : : "{ return flatcc_builder_start_table(B, K); }\\\n"
383 : : "static inline N ## _ref_t N ## _end(NS ## builder_t *B)\\\n"
384 : : "{ assert(flatcc_builder_check_required(B, __ ## N ## _required,\\\n"
385 : : " sizeof(__ ## N ## _required) / sizeof(__ ## N ## _required[0]) - 1));\\\n"
386 : : " return flatcc_builder_end_table(B); }\\\n"
387 : : "__%sbuild_offset_vector(NS, N)\n"
388 : : "\n",
389 : : nsc, nsc);
390 : :
391 : 10 : fprintf(out->fp,
392 : : "#define __%sbuild_table_field(ID, NS, N, TN)\\\n"
393 : : "static inline int N ## _add(NS ## builder_t *B, TN ## _ref_t ref)\\\n"
394 : : "{ TN ## _ref_t *_p; return (ref && (_p = flatcc_builder_table_add_offset(B, ID))) ?\\\n"
395 : : " ((*_p = ref), 0) : -1; }\\\n"
396 : : "static inline int N ## _start(NS ## builder_t *B)\\\n"
397 : : "{ return TN ## _start(B); }\\\n"
398 : : "static inline int N ## _end(NS ## builder_t *B)\\\n"
399 : : "{ return N ## _add(B, TN ## _end(B)); }\\\n"
400 : : "static inline TN ## _ref_t N ## _create(NS ## builder_t *B __ ## TN ##_formal_args)\\\n"
401 : : "{ return N ## _add(B, TN ## _create(B __ ## TN ## _call_args)); }\n"
402 : : "\n",
403 : : nsc);
404 : :
405 : 10 : fprintf(out->fp,
406 : : "#define __%sbuild_union_field(ID, NS, N, TN)\\\n"
407 : : "static inline int N ## _add(NS ## builder_t *B, TN ## _union_ref_t uref)\\\n"
408 : : "{ NS ## ref_t *_p; TN ## _union_type_t *_pt; if (uref.type == TN ## _NONE) return 0; if (uref._member == 0) return -1;\\\n"
409 : : " if (!(_pt = flatcc_builder_table_add(B, ID - 1, sizeof(*_pt), sizeof(_pt))) ||\\\n"
410 : : " !(_p = flatcc_builder_table_add_offset(B, ID))) return -1; *_pt = uref.type; *_p = uref._member; return 0; }\\\n"
411 : : "static inline int N ## _add_type(NS ## builder_t *B, TN ## _union_type_t type)\\\n"
412 : : "{ TN ## _union_type_t *_pt; if (type == TN ## _NONE) return 0; return (_pt = flatcc_builder_table_add(B, ID - 1,\\\n"
413 : : " sizeof(*_pt), sizeof(*_pt))) ? ((*_pt = type), 0) : -1; }\\\n"
414 : : "static inline int N ## _add_member(NS ## builder_t *B, TN ## _union_ref_t uref)\\\n"
415 : : "{ NS ## ref_t *p; if (uref.type == TN ## _NONE) return 0; return (p = flatcc_builder_table_add_offset(B, ID)) ?\\\n"
416 : : " ((*p = uref._member), 0) : -1; }\n"
417 : : "\n",
418 : : nsc);
419 : :
420 : 10 : fprintf(out->fp,
421 : : "/* M is the union member name and T is its type, i.e. the qualified name. */\n"
422 : : "#define __%sbuild_union_member_field(NS, N, NU, M, T)\\\n"
423 : : "static inline int N ## _ ## M ## _add(NS ## builder_t *B, T ## _ref_t ref)\\\n"
424 : : "{ return N ## _add(B, NU ## _as_ ## M (ref)); }\\\n"
425 : : "static inline int N ## _ ## M ## _start(NS ## builder_t *B)\\\n"
426 : : "{ return T ## _start(B); }\\\n"
427 : : "static inline int N ## _ ## M ## _end(NS ## builder_t *B)\\\n"
428 : : "{ return N ## _ ## M ## _add(B, T ## _end(B)); }\n"
429 : : "\n",
430 : : nsc);
431 : :
432 : 10 : fprintf(out->fp,
433 : : "/* NS: common namespace, ID: table field id (not offset), TN: name of type T,\n"
434 : : " * S: sizeof of scalar type, A: alignment of type T, default value V of type T. */\n"
435 : : "#define __%sbuild_scalar_field(ID, NS, N, TN, T, S, A, V)\\\n"
436 : : "static inline int N ## _add(NS ## builder_t *B, const T v)\\\n"
437 : : "{ T *_p; if (v == V) return 0; if (!(_p = flatcc_builder_table_add(B, ID, S, A))) return -1;\\\n"
438 : : " TN ## _assign_to_pe(_p, v); return 0; }\\\n"
439 : : "static inline int N ## _force_add(NS ## builder_t *B, const T v)\\\n"
440 : : "{ T *_p; if (!(_p = flatcc_builder_table_add(B, ID, S, A))) return -1;\\\n"
441 : : " TN ## _assign_to_pe(_p, v); return 0; }\\\n"
442 : : "\n",
443 : : nsc);
444 : :
445 : 10 : fprintf(out->fp,
446 : : "#define __%sbuild_struct_field(ID, NS, N, TN, S, A)\\\n"
447 : : "static inline TN ## _t *N ## _start(NS ## builder_t *B)\\\n"
448 : : "{ return flatcc_builder_table_add(B, ID, S, A); }\\\n"
449 : : "static inline int N ## _end(NS ## builder_t *B)\\\n"
450 : : "{ if (!NS ## is_native_pe()) { TN ## _to_pe(flatcc_builder_table_edit(B, S)); } return 0; }\\\n"
451 : : "static inline int N ## _end_pe(NS ## builder_t *B) { return 0; }\\\n"
452 : : "static inline int N ## _create(NS ## builder_t *B __ ## TN ## _formal_args)\\\n"
453 : : "{ TN ## _t *_p = N ## _start(B); if (!_p) return 0; TN ##_assign_to_pe(_p __ ## TN ## _call_args);\\\n"
454 : : " return 0; }\\\n"
455 : : "static inline int N ## _add(NS ## builder_t *B, const TN ## _t *p)\\\n"
456 : : "{ TN ## _t *_p = N ## _start(B); if (!_p) return -1; TN ##_copy_to_pe(_p, p); return 0; }\\\n"
457 : : "static inline int N ## _clone(NS ## builder_t *B, TN ## _struct_t p)\\\n"
458 : : "{ return 0 == flatcc_builder_table_add_copy(B, ID, p, S, A) ? -1 : 0; }\n"
459 : : "\n",
460 : : nsc);
461 : :
462 : : /* This goes for scalar, struct, and enum vectors. */
463 : 10 : fprintf(out->fp,
464 : : "#define __%sbuild_vector_field(ID, NS, N, TN, T)\\\n"
465 : : "static inline int N ## _add(NS ## builder_t *B, TN ## _vec_ref_t ref)\\\n"
466 : : "{ TN ## _vec_ref_t *_p; return (ref && (_p = flatcc_builder_table_add_offset(B, ID))) ? ((*_p = ref), 0) : -1; }\\\n"
467 : : "static inline int N ## _start(NS ## builder_t *B)\\\n"
468 : : "{ return TN ## _vec_start(B); }\\\n"
469 : : "static inline int N ## _end_pe(NS ## builder_t *B)\\\n"
470 : : "{ return N ## _add(B, TN ## _vec_end_pe(B)); }\\\n"
471 : : "static inline int N ## _end(NS ## builder_t *B)\\\n"
472 : : "{ return N ## _add(B, TN ## _vec_end(B)); }\\\n"
473 : : "static inline int N ## _create_pe(NS ## builder_t *B, T *data, size_t len)\\\n"
474 : : "{ return N ## _add(B, TN ## _vec_create_pe(B, data, len)); }\\\n"
475 : : "static inline int N ## _create(NS ## builder_t *B, T *data, size_t len)\\\n"
476 : : "{ return N ## _add(B, TN ## _vec_create(B, data, len)); }\\\n"
477 : : "static inline int N ## _clone(NS ## builder_t *B, TN ## _vec_t vec)\\\n"
478 : : "{ return N ## _add(B, TN ## _vec_clone(B, vec)); }\\\n"
479 : : "static inline int N ## _slice(NS ## builder_t *B, TN ## _vec_t vec, size_t index, size_t len)\\\n"
480 : : "{ return N ## _add(B, TN ## _vec_slice(B, vec, index, len)); }\\\n"
481 : : "__%sbuild_vector_ops(NS, N, N, TN, T)\n"
482 : : "\n",
483 : : nsc, nsc);
484 : :
485 : 10 : fprintf(out->fp,
486 : : "#define __%sbuild_offset_vector_field(ID, NS, N, TN)\\\n"
487 : : "static inline int N ## _add(NS ## builder_t *B, TN ## _vec_ref_t ref)\\\n"
488 : : "{ TN ## _vec_ref_t *_p; return (ref && (_p = flatcc_builder_table_add_offset(B, ID))) ? ((*_p = ref), 0) : -1; }\\\n"
489 : : "static inline int N ## _start(NS ## builder_t *B)\\\n"
490 : : "{ return flatcc_builder_start_offset_vector(B); }\\\n"
491 : : "static inline int N ## _end(NS ## builder_t *B)\\\n"
492 : : "{ return N ## _add(B, flatcc_builder_end_offset_vector(B)); }\\\n"
493 : : "static inline int N ## _create(NS ## builder_t *B, const TN ## _ref_t *data, size_t len)\\\n"
494 : : "{ return N ## _add(B, flatcc_builder_create_offset_vector(B, data, len)); }\\\n"
495 : : "__%sbuild_offset_vector_ops(NS, N, N, TN)\n"
496 : : "\n",
497 : : nsc, nsc);
498 : :
499 : 10 : fprintf(out->fp,
500 : : "#define __%sbuild_string_field(ID, NS, N)\\\n"
501 : : "static inline int N ## _add(NS ## builder_t *B, NS ## string_ref_t ref)\\\n"
502 : : "{ NS ## string_ref_t *_p; return (ref && (_p = flatcc_builder_table_add_offset(B, ID))) ? ((*_p = ref), 0) : -1; }\\\n"
503 : : "static inline int N ## _start(NS ## builder_t *B)\\\n"
504 : : "{ return flatcc_builder_start_string(B); }\\\n"
505 : : "static inline int N ## _end(NS ## builder_t *B)\\\n"
506 : : "{ return N ## _add(B, flatcc_builder_end_string(B)); }\\\n"
507 : : "static inline int N ## _create(NS ## builder_t *B, const char *s, size_t len)\\\n"
508 : : "{ return N ## _add(B, flatcc_builder_create_string(B, s, len)); }\\\n"
509 : : "static inline int N ## _create_str(NS ## builder_t *B, const char *s)\\\n"
510 : : "{ return N ## _add(B, flatcc_builder_create_string_str(B, s)); }\\\n"
511 : : "static inline int N ## _create_strn(NS ## builder_t *B, const char *s, size_t max_len)\\\n"
512 : : "{ return N ## _add(B, flatcc_builder_create_string_strn(B, s, max_len)); }\\\n"
513 : : "static inline int N ## _clone(NS ## builder_t *B, NS ## string_t string)\\\n"
514 : : "{ return N ## _add(B, NS ## string_clone(B, string)); }\\\n"
515 : : "static inline int N ## _slice(NS ## builder_t *B, NS ## string_t string, size_t index, size_t len)\\\n"
516 : : "{ return N ## _add(B, NS ## string_slice(B, string, index, len)); }\\\n"
517 : : "__%sbuild_string_ops(NS, N)\n"
518 : : "\n",
519 : : nsc, nsc);
520 : :
521 : 10 : fprintf(out->fp,
522 : : "#define __%sbuild_table_vector_field(ID, NS, N, TN)\\\n"
523 : : "__%sbuild_offset_vector_field(ID, NS, N, TN)\\\n"
524 : : "__%sbuild_table_vector_ops(NS, N, TN)\n"
525 : : "\n",
526 : : nsc, nsc, nsc);
527 : :
528 : 10 : fprintf(out->fp,
529 : : "#define __%sbuild_string_vector_field(ID, NS, N)\\\n"
530 : : "__%sbuild_offset_vector_field(ID, NS, N, NS ## string)\\\n"
531 : : "__%sbuild_string_vector_ops(NS, N)\n"
532 : : "\n",
533 : : nsc, nsc, nsc);
534 : :
535 : 10 : fprintf(out->fp, "#define __%suint8_formal_args , uint8_t v0\n", nsc);
536 : 10 : fprintf(out->fp, "#define __%suint8_call_args , v0\n", nsc);
537 : 10 : fprintf(out->fp, "#define __%sint8_formal_args , int8_t v0\n", nsc);
538 : 10 : fprintf(out->fp, "#define __%sint8_call_args , v0\n", nsc);
539 : 10 : fprintf(out->fp, "#define __%sbool_formal_args , %sbool_t v0\n", nsc, nsc);
540 : 10 : fprintf(out->fp, "#define __%sbool_call_args , v0\n", nsc);
541 : 10 : fprintf(out->fp, "#define __%suint16_formal_args , uint16_t v0\n", nsc);
542 : 10 : fprintf(out->fp, "#define __%suint16_call_args , v0\n", nsc);
543 : 10 : fprintf(out->fp, "#define __%suint32_formal_args , uint32_t v0\n", nsc);
544 : 10 : fprintf(out->fp, "#define __%suint32_call_args , v0\n", nsc);
545 : 10 : fprintf(out->fp, "#define __%suint64_formal_args , uint64_t v0\n", nsc);
546 : 10 : fprintf(out->fp, "#define __%suint64_call_args , v0\n", nsc);
547 : 10 : fprintf(out->fp, "#define __%sint16_formal_args , int16_t v0\n", nsc);
548 : 10 : fprintf(out->fp, "#define __%sint16_call_args , v0\n", nsc);
549 : 10 : fprintf(out->fp, "#define __%sint32_formal_args , int32_t v0\n", nsc);
550 : 10 : fprintf(out->fp, "#define __%sint32_call_args , v0\n", nsc);
551 : 10 : fprintf(out->fp, "#define __%sint64_formal_args , int64_t v0\n", nsc);
552 : 10 : fprintf(out->fp, "#define __%sint64_call_args , v0\n", nsc);
553 : 10 : fprintf(out->fp, "#define __%sfloat_formal_args , float v0\n", nsc);
554 : 10 : fprintf(out->fp, "#define __%sfloat_call_args , v0\n", nsc);
555 : 10 : fprintf(out->fp, "#define __%sdouble_formal_args , double v0\n", nsc);
556 : 10 : fprintf(out->fp, "#define __%sdouble_call_args , v0\n", nsc);
557 : 10 : fprintf(out->fp, "\n");
558 : 10 : fprintf(out->fp, "__%sbuild_scalar(%s, %suint8, uint8_t)\n", nsc, nsc, nsc);
559 : 10 : fprintf(out->fp, "__%sbuild_scalar(%s, %sint8, int8_t)\n", nsc, nsc, nsc);
560 : 10 : fprintf(out->fp, "__%sbuild_scalar(%s, %sbool, %sbool_t)\n", nsc, nsc, nsc, nsc);
561 : 10 : fprintf(out->fp, "__%sbuild_scalar(%s, %suint16, uint16_t)\n", nsc, nsc, nsc);
562 : 10 : fprintf(out->fp, "__%sbuild_scalar(%s, %suint32, uint32_t)\n", nsc, nsc, nsc);
563 : 10 : fprintf(out->fp, "__%sbuild_scalar(%s, %suint64, uint64_t)\n", nsc, nsc, nsc);
564 : 10 : fprintf(out->fp, "__%sbuild_scalar(%s, %sint16, int16_t)\n", nsc, nsc, nsc);
565 : 10 : fprintf(out->fp, "__%sbuild_scalar(%s, %sint32, int32_t)\n", nsc, nsc, nsc);
566 : 10 : fprintf(out->fp, "__%sbuild_scalar(%s, %sint64, int64_t)\n", nsc, nsc, nsc);
567 : 10 : fprintf(out->fp, "__%sbuild_scalar(%s, %sfloat, float)\n", nsc, nsc, nsc);
568 : 10 : fprintf(out->fp, "__%sbuild_scalar(%s, %sdouble, double)\n", nsc, nsc, nsc);
569 : 10 : fprintf(out->fp, "\n");
570 : 10 : fprintf(out->fp, "__%sbuild_string(%s)\n", nsc, nsc);
571 : 10 : fprintf(out->fp, "\n");
572 : :
573 : 10 : fprintf(out->fp, "__%sbuild_buffer(%s)\n", nsc, nsc);
574 : : gen_pragma_pop(out);
575 : 10 : fprintf(out->fp, "#endif /* %s_COMMON_BUILDER_H */\n", nscup);
576 : 10 : return 0;
577 : : }
578 : :
579 : 24 : static int gen_builder_pretext(fb_output_t *out)
580 : : {
581 : 24 : const char *nsc = out->nsc;
582 : 24 : const char *nscup = out->nscup;
583 : :
584 : 24 : fprintf(out->fp,
585 : : "#ifndef %s_BUILDER_H\n"
586 : : "#define %s_BUILDER_H\n",
587 : 24 : out->S->basenameup, out->S->basenameup);
588 : :
589 : 24 : fprintf(out->fp, "\n/* " FLATCC_GENERATED_BY " */\n\n");
590 : 24 : fprintf(out->fp, "#ifndef %s_READER_H\n", out->S->basenameup);
591 : 24 : fprintf(out->fp, "#include \"%s_reader.h\"\n", out->S->basename);
592 : 24 : fprintf(out->fp, "#endif\n");
593 : 24 : fprintf(out->fp, "#ifndef %s_COMMON_BUILDER_H\n", nscup);
594 : 24 : fprintf(out->fp, "#include \"%scommon_builder.h\"\n", nsc);
595 : 24 : fprintf(out->fp, "#endif\n");
596 : :
597 : 24 : fb_gen_c_includes(out, "_builder.h", "_BUILDER_H");
598 : :
599 : : gen_pragma_push(out);
600 : :
601 : : /*
602 : : * Even if defined in the reader header, we must redefine it here
603 : : * because another file might sneak in and update.
604 : : */
605 [ + + ]: 24 : if (out->S->file_identifier.type == vt_string) {
606 : 8 : fprintf(out->fp,
607 : : "#undef %sidentifier\n"
608 : : "#define %sidentifier \"%.*s\"\n",
609 : : nsc,
610 : : nsc, out->S->file_identifier.s.len, out->S->file_identifier.s.s);
611 : : } else {
612 : 16 : fprintf(out->fp,
613 : : "#ifndef %sidentifier\n"
614 : : "#define %sidentifier 0\n"
615 : : "#endif\n",
616 : : nsc, nsc);
617 : : }
618 [ + + ]: 24 : if (out->S->file_extension.type == vt_string) {
619 : 8 : fprintf(out->fp,
620 : : "#undef %sextension\n"
621 : : "#define %sextension \".%.*s\"\n",
622 : : nsc,
623 : : nsc, out->S->file_extension.s.len, out->S->file_extension.s.s);
624 : : } else {
625 : 16 : fprintf(out->fp,
626 : : /* Configured extensions include dot, schema does not. */
627 : : "#ifndef %sextension\n"
628 : : "#define %sextension \"%s\"\n"
629 : : "#endif\n",
630 : 16 : nsc, nsc, out->opts->default_bin_ext);
631 : : }
632 : 24 : fprintf(out->fp, "\n");
633 : 24 : return 0;
634 : : }
635 : :
636 : 310 : static int get_total_struct_field_count(fb_compound_type_t *ct)
637 : : {
638 : : fb_member_t *member;
639 : : fb_symbol_t *sym;
640 : : int count = 0;
641 [ + + ]: 427 : for (sym = ct->members; sym; sym = sym->link) {
642 : : member = (fb_member_t *)sym;
643 [ + + ]: 272 : if (member->metadata_flags & fb_f_deprecated) {
644 : 2 : continue;
645 : : }
646 [ + + ]: 270 : switch (member->type.type) {
647 : : case vt_compound_type_ref:
648 [ + + ]: 55 : if (member->type.ct->symbol.kind == fb_is_struct) {
649 : 35 : count += get_total_struct_field_count(member->type.ct);
650 : 35 : continue;
651 : : }
652 : : /* enum fall through. */
653 : : default:
654 : 235 : ++count;
655 : : }
656 : : }
657 : 155 : return count;
658 : : }
659 : :
660 : 2248 : static inline void gen_comma(fb_output_t *out, int index, int count, int is_macro)
661 : : {
662 [ + + ]: 1124 : char *cont = is_macro ? "\\\n" : "\n";
663 : :
664 [ + - ]: 1124 : if (count == 0) {
665 : : return;
666 : : }
667 [ + + ]: 1124 : if (index == 0) {
668 [ + + ]: 243 : if (count > 4) {
669 : 96 : fprintf(out->fp, ",%s ", cont);
670 : : } else {
671 : 147 : fprintf(out->fp, ", ");
672 : : }
673 : : } else {
674 [ + + ][ + + ]: 881 : if (index % 4 || count - index <= 2) {
675 : 768 : fprintf(out->fp, ", ");
676 : : } else {
677 : 113 : fprintf(out->fp, ",%s ", cont);
678 : : }
679 : : }
680 : : }
681 : :
682 : 220 : static int gen_builder_struct_args(fb_output_t *out, fb_compound_type_t *ct, int index, int len, int is_macro)
683 : : {
684 : 220 : const char *nsc = out->nsc;
685 : : fb_member_t *member;
686 : : fb_symbol_t *sym;
687 : : const char *tname, *tname_ns;
688 : : fb_scoped_name_t snref;
689 : :
690 : 220 : fb_clear(snref);
691 : :
692 [ + + ]: 596 : for (sym = ct->members; sym; sym = sym->link) {
693 : : member = (fb_member_t *)sym;
694 [ + + ]: 376 : if (member->metadata_flags & fb_f_deprecated) {
695 : 4 : continue;
696 : : }
697 [ + + - ]: 372 : switch (member->type.type) {
698 : : case vt_compound_type_ref:
699 [ + + ]: 92 : if (member->type.ct->symbol.kind == fb_is_struct) {
700 : 52 : index = gen_builder_struct_args(out, member->type.ct, index, len, is_macro);
701 : 52 : continue;
702 : : }
703 : 40 : gen_comma(out, index, len, is_macro);
704 : 40 : fb_compound_name(member->type.ct, &snref);
705 : 40 : fprintf(out->fp, "%s_enum_t v%i", snref.text, index++);
706 : : break;
707 : : case vt_scalar_type:
708 : 280 : gen_comma(out, index, len, is_macro);
709 : 280 : tname_ns = scalar_type_ns(member->type.st, nsc);
710 : 280 : tname = scalar_type_name(member->type.st);
711 : 280 : fprintf(out->fp, "%s%s v%i", tname_ns, tname, index++);
712 : : break;
713 : : default:
714 : 0 : gen_panic(out, "internal error: unexpected struct member type");
715 : : continue;
716 : : }
717 : : }
718 : 220 : return index;
719 : : }
720 : :
721 : 72 : static int gen_builder_struct_call_list(fb_output_t *out, fb_compound_type_t *ct, int index, int arg_count, int is_macro)
722 : : {
723 : : int i;
724 : 72 : int len = get_total_struct_field_count(ct);
725 : :
726 [ + + ]: 203 : for (i = 0; i < len; ++i) {
727 : 131 : gen_comma(out, i, arg_count, is_macro);
728 : 131 : fprintf(out->fp, "v%i", index++);
729 : : }
730 : 72 : return index;
731 : : }
732 : :
733 : : enum { no_conversion, convert_from_pe, convert_to_pe };
734 : :
735 : : /* Note: returned index is not correct when using from_ptr since it doesn't track arguments, but it shouldn't matter. */
736 : 252 : static int gen_builder_struct_field_assign(fb_output_t *out, fb_compound_type_t *ct, int index, int arg_count, int conversion, int from_ptr)
737 : : {
738 : 252 : const char *nsc = out->nsc;
739 : : fb_member_t *member;
740 : : fb_symbol_t *sym;
741 : : int n;
742 : : const char *s;
743 : : int deprecated_index = 0;
744 : : const char *kind, *tprefix;
745 : : fb_scoped_name_t snref;
746 : :
747 : 252 : fb_clear(snref);
748 [ + + + ]: 252 : switch (conversion) {
749 : : case convert_to_pe: kind = "_to_pe"; break;
750 : : case convert_from_pe: kind = "_from_pe"; break;
751 : : default: kind = ""; break;
752 : : }
753 [ + + ]: 696 : for (sym = ct->members; sym; sym = sym->link) {
754 : : member = (fb_member_t *)sym;
755 : : symbol_name(sym, &n, &s);
756 : :
757 [ + + ]: 444 : if (index > 0) {
758 [ + + ]: 318 : if (index % 4 == 0) {
759 : 48 : fprintf(out->fp, ";\n ");
760 : : } else {
761 : 270 : fprintf(out->fp, "; ");
762 : : }
763 : : }
764 [ + + - ]: 444 : switch (member->type.type) {
765 : : case vt_compound_type_ref:
766 : 126 : fb_compound_name(member->type.ct, &snref);
767 [ + + ]: 126 : if (member->type.ct->symbol.kind == fb_is_struct) {
768 [ + + ]: 66 : if (member->metadata_flags & fb_f_deprecated) {
769 : 6 : fprintf(out->fp, "memset(p->__deprecated%i, 0, sizeof(*p->__deprecated%i))",
770 : : deprecated_index, deprecated_index);
771 : 6 : deprecated_index++;
772 : 6 : index += get_total_struct_field_count(member->type.ct);
773 : 6 : continue;
774 : : }
775 [ + + ]: 60 : if (from_ptr) {
776 : 30 : fprintf(out->fp, "%s_copy%s(&p->%.*s, &p2->%.*s)", snref.text, kind, n, s, n, s);
777 : : /* `index` does not count children, but it doesn't matter here. */
778 : 30 : ++index;
779 : : } else {
780 : 30 : fprintf(out->fp, "%s_assign%s(&p->%.*s", snref.text, kind, n, s);
781 : 30 : index = gen_builder_struct_call_list(out, member->type.ct, index, arg_count, 0);
782 : 30 : fprintf(out->fp, ")");
783 : : }
784 : 60 : continue;
785 : : }
786 [ - + ]: 60 : if (member->metadata_flags & fb_f_deprecated) {
787 : 0 : fprintf(out->fp, "p->__deprecated%i = 0", deprecated_index++);
788 : 0 : ++index;
789 : 0 : continue;
790 : : }
791 [ + + ]: 60 : switch (member->size == 1 ? no_conversion : conversion) {
[ + + + ]
792 : : case convert_from_pe:
793 [ + + ]: 2 : if (from_ptr) {
794 : 1 : fprintf(out->fp, "%s_copy_from_pe(&p->%.*s, &p2->%.*s)",
795 : : snref.text, n, s, n, s);
796 : : } else {
797 : 1 : fprintf(out->fp, "%s_assign_from_pe(&p->%.*s, v%i)",
798 : : snref.text, n, s, index);
799 : : }
800 : : break;
801 : : case convert_to_pe:
802 [ + + ]: 2 : if (from_ptr) {
803 : 1 : fprintf(out->fp, "%s_copy_to_pe(&p->%.*s, &p2->%.*s)",
804 : : snref.text, n, s, n, s);
805 : : } else {
806 : 1 : fprintf(out->fp, "%s_assign_to_pe(&p->%.*s, v%i)",
807 : : snref.text, n, s, index);
808 : : }
809 : : break;
810 : : default:
811 [ + + ]: 56 : if (from_ptr) {
812 : 28 : fprintf(out->fp, "p->%.*s = p2->%.*s", n, s, n, s);
813 : : } else {
814 : 28 : fprintf(out->fp, "p->%.*s = v%i", n, s, index);
815 : : }
816 : : break;
817 : : }
818 : 60 : ++index;
819 : 60 : continue;
820 : : case vt_scalar_type:
821 : 318 : tprefix = scalar_type_prefix(member->type.st);
822 [ - + ]: 318 : if (member->metadata_flags & fb_f_deprecated) {
823 : 0 : fprintf(out->fp, "p->__deprecated%i = 0", deprecated_index++);
824 : 0 : ++index;
825 : 0 : continue;
826 : : }
827 [ + + ]: 318 : switch (member->size == 1 ? no_conversion : conversion) {
[ + + + ]
828 : : case convert_from_pe:
829 [ + + ]: 82 : if (from_ptr) {
830 : 41 : fprintf(out->fp, "%s%s_copy_from_pe(&p->%.*s, &p2->%.*s)",
831 : : nsc, tprefix, n, s, n, s);
832 : : } else {
833 : 41 : fprintf(out->fp, "%s%s_assign_from_pe(&p->%.*s, v%i)",
834 : : nsc, tprefix, n, s, index);
835 : : }
836 : : break;
837 : : case convert_to_pe:
838 [ + + ]: 82 : if (from_ptr) {
839 : 41 : fprintf(out->fp, "%s%s_copy_to_pe(&p->%.*s, &p2->%.*s)",
840 : : nsc, tprefix, n, s, n, s);
841 : : } else {
842 : 41 : fprintf(out->fp, "%s%s_assign_to_pe(&p->%.*s, v%i)",
843 : : nsc, tprefix, n, s, index);
844 : : }
845 : : break;
846 : : default:
847 [ + + ]: 154 : if (from_ptr) {
848 : 77 : fprintf(out->fp, "p->%.*s = p2->%.*s", n, s, n, s);
849 : : } else {
850 : 77 : fprintf(out->fp, "p->%.*s = v%i", n, s, index);
851 : : }
852 : : break;
853 : : }
854 : 318 : ++index;
855 : : break;
856 : : default:
857 : 0 : gen_panic(out, "internal error: type error");
858 : : continue;
859 : : }
860 : : }
861 [ + + ]: 252 : if (arg_count > 0) {
862 : 126 : fprintf(out->fp, ";\n ");
863 : : }
864 : 252 : return index;
865 : : }
866 : :
867 : 42 : static void gen_builder_struct(fb_output_t *out, fb_compound_type_t *ct)
868 : : {
869 : 42 : const char *nsc = out->nsc;
870 : : int arg_count;
871 : : fb_scoped_name_t snt;
872 : :
873 : 42 : fb_clear(snt);
874 : : assert(ct->symbol.kind == fb_is_struct);
875 : :
876 : : fb_compound_name(ct, &snt);
877 : :
878 : 42 : arg_count = get_total_struct_field_count(ct);
879 : 42 : fprintf(out->fp, "#define __%s_formal_args ", snt.text);
880 : 42 : gen_builder_struct_args(out, ct, 0, arg_count, 1);
881 : 42 : fprintf(out->fp, "\n#define __%s_call_args ", snt.text);
882 : 42 : gen_builder_struct_call_list(out, ct, 0, arg_count, 1);
883 : 42 : fprintf(out->fp, "\n");
884 : 42 : fprintf(out->fp,
885 : : "static inline %s_t *%s_assign(%s_t *p",
886 : : snt.text, snt.text, snt.text);
887 : 42 : gen_builder_struct_args(out, ct, 0, arg_count, 0);
888 : 42 : fprintf(out->fp, ")\n{ ");
889 : 42 : gen_builder_struct_field_assign(out, ct, 0, arg_count, no_conversion, 0);
890 : 42 : fprintf(out->fp, "return p; }\n");
891 : 42 : fprintf(out->fp,
892 : : "static inline %s_t *%s_copy(%s_t *p, const %s_t *p2)\n",
893 : : snt.text, snt.text, snt.text, snt.text);
894 : 42 : fprintf(out->fp, "{ ");
895 : 42 : gen_builder_struct_field_assign(out, ct, 0, arg_count, no_conversion, 1);
896 : 42 : fprintf(out->fp, "return p; }\n");
897 : 42 : fprintf(out->fp,
898 : : "static inline %s_t *%s_assign_to_pe(%s_t *p",
899 : : snt.text, snt.text, snt.text);
900 : 42 : gen_builder_struct_args(out, ct, 0, arg_count, 0);
901 : 42 : fprintf(out->fp, ")\n{ ");
902 : 42 : gen_builder_struct_field_assign(out, ct, 0, arg_count, convert_to_pe, 0);
903 : 42 : fprintf(out->fp, "return p; }\n");
904 : 42 : fprintf(out->fp,
905 : : "static inline %s_t *%s_copy_to_pe(%s_t *p, const %s_t *p2)\n",
906 : : snt.text, snt.text, snt.text, snt.text);
907 : 42 : fprintf(out->fp, "{ ");
908 : 42 : gen_builder_struct_field_assign(out, ct, 0, arg_count, convert_to_pe, 1);
909 : 42 : fprintf(out->fp, "return p; }\n");
910 : 42 : fprintf(out->fp,
911 : : "static inline %s_t *%s_assign_from_pe(%s_t *p",
912 : : snt.text, snt.text, snt.text);
913 : 42 : gen_builder_struct_args(out, ct, 0, arg_count, 0);
914 : 42 : fprintf(out->fp, ")\n{ ");
915 : 42 : gen_builder_struct_field_assign(out, ct, 0, arg_count, convert_from_pe, 0);
916 : 42 : fprintf(out->fp, "return p; }\n");
917 : 42 : fprintf(out->fp,
918 : : "static inline %s_t *%s_copy_from_pe(%s_t *p, const %s_t *p2)\n",
919 : : snt.text, snt.text, snt.text, snt.text);
920 : 42 : fprintf(out->fp, "{ ");
921 : 42 : gen_builder_struct_field_assign(out, ct, 0, arg_count, convert_from_pe, 1);
922 : 42 : fprintf(out->fp, "return p; }\n");
923 : 42 : fprintf(out->fp, "__%sbuild_struct(%s, %s, %llu, %u, %s_identifier, %s_type_identifier)\n",
924 : 84 : nsc, nsc, snt.text, llu(ct->size), ct->align, snt.text, snt.text);
925 : 42 : }
926 : :
927 : : static int get_create_table_arg_count(fb_compound_type_t *ct)
928 : : {
929 : : fb_member_t *member;
930 : : fb_symbol_t *sym;
931 : : int count = 0;
932 : :
933 [ + + ][ + + ]: 816 : for (sym = ct->members; sym; sym = sym->link) {
934 : : member = (fb_member_t *)sym;
935 [ + + ][ + + ]: 690 : if (member->metadata_flags & fb_f_deprecated) {
936 : 18 : continue;
937 : : }
938 : 672 : ++count;
939 : : }
940 : : return count;
941 : : }
942 : :
943 : 126 : static int gen_builder_table_call_list(fb_output_t *out, fb_compound_type_t *ct, int arg_count, int is_macro)
944 : : {
945 : : fb_member_t *member;
946 : : fb_symbol_t *sym;
947 : : int index = 0;
948 : :
949 [ + + ]: 408 : for (sym = ct->members; sym; sym = sym->link) {
950 : : member = (fb_member_t *)sym;
951 [ + + ]: 345 : if (member->metadata_flags & fb_f_deprecated) {
952 : 9 : continue;
953 : : }
954 : 336 : gen_comma(out, index, arg_count, is_macro);
955 : 336 : fprintf(out->fp, "v%llu", llu(member->id));
956 : 336 : ++index;
957 : : }
958 : 63 : return index;
959 : : }
960 : :
961 : :
962 : 63 : static int gen_required_table_fields(fb_output_t *out, fb_compound_type_t *ct)
963 : : {
964 : 63 : const char *nsc = out->nsc;
965 : : fb_member_t *member;
966 : : fb_symbol_t *sym;
967 : : int index;
968 : : int arg_count;
969 : : fb_scoped_name_t snt;
970 : :
971 : 63 : fb_clear(snt);
972 : : arg_count = get_create_table_arg_count(ct);
973 : : index = 0;
974 : : fb_compound_name(ct, &snt);
975 : 63 : fprintf(out->fp, "static const %svoffset_t __%s_required[] = {", nsc, snt.text);
976 [ + + ]: 408 : for (sym = ct->members; sym; sym = sym->link) {
977 : : member = (fb_member_t *)sym;
978 [ + + ]: 345 : if (member->metadata_flags & fb_f_deprecated) {
979 : 9 : continue;
980 : : }
981 [ + + ]: 336 : if (member->metadata_flags & fb_f_required) {
982 [ + + ]: 10 : if (index > 0) {
983 : 1 : gen_comma(out, index, arg_count, 0);
984 : : } else {
985 : 9 : fprintf(out->fp, " ");
986 : : }
987 : 10 : fprintf(out->fp, "%u", (unsigned)member->id);
988 : 10 : index++;
989 : : }
990 : : }
991 : : /* Add extra element to avoid null arrays. */
992 [ + + ]: 63 : if (index > 0) {
993 : 9 : fprintf(out->fp, ", 0 };\n");
994 : : } else {
995 : 54 : fprintf(out->fp, "0 };\n");
996 : : }
997 : 63 : return index;
998 : : }
999 : :
1000 : 63 : static int gen_builder_table_args(fb_output_t *out, fb_compound_type_t *ct, int arg_count, int is_macro)
1001 : : {
1002 : 63 : const char *nsc = out->nsc;
1003 : : fb_symbol_t *sym;
1004 : : fb_member_t *member;
1005 : : const char *tname, *tname_ns;
1006 : : int index;
1007 : : fb_scoped_name_t snref;
1008 : :
1009 : 63 : fb_clear(snref);
1010 : : /* Just to help the comma. */
1011 : : index = 0;
1012 : : /* We use the id to name arguments so sorted assignment can find the arguments trivially. */
1013 [ + + ]: 408 : for (sym = ct->members; sym; sym = sym->link) {
1014 : : member = (fb_member_t *)sym;
1015 [ + + ]: 345 : if (member->metadata_flags & fb_f_deprecated) {
1016 : 9 : continue;
1017 : : }
1018 : 336 : gen_comma(out, index++, arg_count, is_macro);
1019 [ + + + + : 336 : switch (member->type.type) {
+ + - ]
1020 : : case vt_compound_type_ref:
1021 : 109 : fb_compound_name(member->type.ct, &snref);
1022 [ + + + + : 109 : switch (member->type.ct->symbol.kind) {
- ]
1023 : : case fb_is_struct:
1024 : 27 : fprintf(out->fp, "%s_t *v%llu", snref.text, llu(member->id));
1025 : : break;
1026 : : case fb_is_enum:
1027 : 48 : fprintf(out->fp, "%s_enum_t v%llu", snref.text, llu(member->id));
1028 : : break;
1029 : : case fb_is_table:
1030 : 23 : fprintf(out->fp, "%s_ref_t v%llu", snref.text, llu(member->id));
1031 : : break;
1032 : : case fb_is_union:
1033 : : /* Unions jump an index because it is two fields. */
1034 : 11 : fprintf(out->fp, "%s_union_ref_t v%llu", snref.text, llu(member->id));
1035 : : break;
1036 : : default:
1037 : 0 : gen_panic(out, "internal error: unexpected table field type");
1038 : : continue;
1039 : : }
1040 : : break;
1041 : : case vt_vector_compound_type_ref:
1042 : 18 : fb_compound_name(member->type.ct, &snref);
1043 [ + - ][ + - ]: 18 : switch (member->type.ct->symbol.kind) {
1044 : : case fb_is_struct:
1045 : : case fb_is_enum:
1046 : : case fb_is_table:
1047 : 18 : fprintf(out->fp, "%s_vec_ref_t v%llu", snref.text, llu(member->id));
1048 : : break;
1049 : : /* There are no union vectors. */
1050 : : default:
1051 : 0 : gen_panic(out, "internal error: unexpected table table type");
1052 : : continue;
1053 : : }
1054 : : break;
1055 : : case vt_scalar_type:
1056 : 147 : tname_ns = scalar_type_ns(member->type.st, nsc);
1057 : 147 : tname = scalar_type_name(member->type.st);
1058 : 147 : fprintf(out->fp, "%s%s v%llu", tname_ns, tname, llu(member->id));
1059 : : break;
1060 : : case vt_vector_type:
1061 : 25 : tname = scalar_type_prefix(member->type.st);
1062 : 25 : fprintf(out->fp, "%s%s_vec_ref_t v%llu", nsc, tname, llu(member->id));
1063 : : break;
1064 : : case vt_string_type:
1065 : 27 : fprintf(out->fp, "%sstring_ref_t v%llu", nsc, llu(member->id));
1066 : : break;
1067 : : case vt_vector_string_type:
1068 : 10 : fprintf(out->fp, "%sstring_vec_ref_t v%llu", nsc, llu(member->id));
1069 : : break;
1070 : : default:
1071 : 0 : gen_panic(out, "internal error: unexpected struct member type");
1072 : : continue;
1073 : : }
1074 : : }
1075 : 63 : return index;
1076 : : }
1077 : :
1078 : 63 : static int gen_builder_create_table_decl(fb_output_t *out, fb_compound_type_t *ct)
1079 : : {
1080 : 63 : const char *nsc = out->nsc;
1081 : : int arg_count;
1082 : : fb_scoped_name_t snt;
1083 : :
1084 : 63 : fb_clear(snt);
1085 : : fb_compound_name(ct, &snt);
1086 : :
1087 : : arg_count = get_create_table_arg_count(ct);
1088 : 63 : fprintf(out->fp, "#define __%s_formal_args ", snt.text);
1089 : 63 : gen_builder_table_args(out, ct, arg_count, 1);
1090 : 63 : fprintf(out->fp, "\n#define __%s_call_args ", snt.text);
1091 : 63 : gen_builder_table_call_list(out, ct, arg_count, 1);
1092 : 63 : fprintf(out->fp, "\n");
1093 : :
1094 : 63 : fprintf(out->fp,
1095 : : "static inline %s_ref_t %s_create(%sbuilder_t *B __%s_formal_args);\n",
1096 : : snt.text, snt.text, nsc, snt.text);
1097 : 63 : return 0;
1098 : : }
1099 : :
1100 : 63 : static int gen_builder_create_table(fb_output_t *out, fb_compound_type_t *ct)
1101 : : {
1102 : 63 : const char *nsc = out->nsc;
1103 : : fb_member_t *member;
1104 : : int n;
1105 : : const char *s;
1106 : 63 : int patch_union = !(ct->metadata_flags & fb_f_original_order);
1107 : : int has_union = 0;
1108 : : fb_scoped_name_t snt;
1109 : :
1110 : 63 : fb_clear(snt);
1111 : : fb_compound_name(ct, &snt);
1112 : :
1113 : 63 : fprintf(out->fp,
1114 : : "static inline %s_ref_t %s_create(%sbuilder_t *B __%s_formal_args)\n",
1115 : : snt.text, snt.text, nsc, snt.text);
1116 : :
1117 : 63 : fprintf(out->fp, "{\n if (%s_start(B)", snt.text);
1118 [ + + ]: 408 : for (member = ct->ordered_members; member; member = member->order) {
1119 [ + + ]: 345 : if (member->metadata_flags & fb_f_deprecated) {
1120 : 9 : continue;
1121 : : }
1122 : : symbol_name(&member->symbol, &n, &s);
1123 [ + + ][ + + ]: 336 : if (member->type.type == vt_compound_type_ref && member->type.ct->symbol.kind == fb_is_union) {
1124 : : has_union = 1;
1125 [ + + ]: 11 : if (patch_union) {
1126 : 10 : fprintf(out->fp, "\n || %s_%.*s_add_member(B, v%llu)", snt.text, n, s, llu(member->id));
1127 : 10 : continue;
1128 : : }
1129 : : }
1130 : 326 : fprintf(out->fp, "\n || %s_%.*s_add(B, v%llu)", snt.text, n, s, llu(member->id));
1131 : : }
1132 [ + + ]: 63 : if (patch_union && has_union) {
1133 [ + + ]: 207 : for (member = ct->ordered_members; member; member = member->order) {
1134 [ + + ]: 197 : if (member->metadata_flags & fb_f_deprecated) {
1135 : 8 : continue;
1136 : : }
1137 [ + + ][ + + ]: 189 : if (member->type.type == vt_compound_type_ref && member->type.ct->symbol.kind == fb_is_union) {
1138 : : symbol_name(&member->symbol, &n, &s);
1139 : 10 : fprintf(out->fp, "\n || %s_%.*s_add_type(B, v%llu.type)", snt.text, n, s, llu(member->id));
1140 : : }
1141 : : }
1142 : : }
1143 : 63 : fprintf(out->fp, ") {\n return 0;\n }\n return %s_end(B);\n}\n", snt.text);
1144 : 63 : return 0;
1145 : : }
1146 : :
1147 : 24 : static int gen_builder_structs(fb_output_t *out)
1148 : : {
1149 : : fb_compound_type_t *ct;
1150 : :
1151 : : /* Generate structs in topologically sorted order. */
1152 [ + + ]: 66 : for (ct = out->S->ordered_structs; ct; ct = ct->order) {
1153 : 42 : gen_builder_struct(out, ct);
1154 : 42 : fprintf(out->fp, "\n");
1155 : : }
1156 : 24 : return 0;
1157 : : }
1158 : :
1159 : 63 : static int gen_builder_table(fb_output_t *out, fb_compound_type_t *ct)
1160 : : {
1161 : 63 : const char *nsc = out->nsc;
1162 : : fb_scoped_name_t snt;
1163 : :
1164 : 63 : fb_clear(snt);
1165 : : fb_compound_name(ct, &snt);
1166 : :
1167 : 63 : fprintf(out->fp, "__%sbuild_table(%s, %s, %llu)\n",
1168 : 63 : nsc, nsc, snt.text, llu(ct->count));
1169 : 63 : return 0;
1170 : : }
1171 : :
1172 : 63 : static int gen_builder_table_prolog(fb_output_t *out, fb_compound_type_t *ct)
1173 : : {
1174 : 63 : const char *nsc = out->nsc;
1175 : : fb_scoped_name_t snt;
1176 : :
1177 : 63 : fb_clear(snt);
1178 : : fb_compound_name(ct, &snt);
1179 : :
1180 : 63 : fprintf(out->fp, "__%sbuild_table_prolog(%s, %s, %s_identifier, %s_type_identifier)\n",
1181 : : nsc, nsc, snt.text, snt.text, snt.text);
1182 : 63 : return 0;
1183 : : }
1184 : :
1185 : 11 : static int gen_union_member_fields(fb_output_t *out, const char *st, int n, const char *s, fb_compound_type_t *ct)
1186 : : {
1187 : 11 : const char *nsc = out->nsc;
1188 : : fb_symbol_t *sym;
1189 : : fb_member_t *member;
1190 : : const char *su;
1191 : : int nu;
1192 : : fb_scoped_name_t snref;
1193 : : fb_scoped_name_t snu;
1194 : :
1195 : 11 : fb_clear(snref);
1196 : 11 : fb_clear(snu);
1197 : : fb_compound_name(ct, &snref);
1198 [ + + ]: 46 : for (sym = ct->members; sym; sym = sym->link) {
1199 : : member = (fb_member_t *)sym;
1200 [ + + ]: 35 : switch (member->type.type) {
1201 : : case vt_compound_type_ref:
1202 : 24 : fb_compound_name(member->type.ct, &snu);
1203 : : symbol_name(sym, &nu, &su);
1204 : 24 : fprintf(out->fp,
1205 : : "__%sbuild_union_member_field(%s, %s_%.*s, %s, %.*s, %s)\n",
1206 : : nsc, nsc, st, n, s, snref.text, nu, su, snu.text);
1207 : 24 : break;
1208 : : default:
1209 : : break;
1210 : : }
1211 : : }
1212 : 11 : return 0;
1213 : : }
1214 : :
1215 : 63 : static int gen_builder_table_fields(fb_output_t *out, fb_compound_type_t *ct)
1216 : : {
1217 : 63 : const char *nsc = out->nsc;
1218 : : fb_member_t *member;
1219 : : fb_symbol_t *sym;
1220 : : const char *s, *tprefix, *tname, *tname_ns;
1221 : : int n;
1222 : : fb_scoped_name_t snt;
1223 : : fb_scoped_name_t snref;
1224 : :
1225 : 63 : fb_clear(snt);
1226 : 63 : fb_clear(snref);
1227 : : fb_compound_name(ct, &snt);
1228 : :
1229 [ + + ]: 408 : for (sym = ct->members; sym; sym = sym->link) {
1230 : : member = (fb_member_t *)sym;
1231 : : symbol_name(&member->symbol, &n, &s);
1232 [ + + ]: 345 : if (member->metadata_flags & fb_f_deprecated) {
1233 : 9 : fprintf(out->fp, "/* Skipping build of deprecated field: '%s_%.*s' */\n\n", snt.text, n, s);
1234 : 9 : continue;
1235 : : }
1236 [ + + + + : 336 : switch (member->type.type) {
+ + - ]
1237 : : case vt_scalar_type:
1238 : 147 : tname_ns = scalar_type_ns(member->type.st, nsc);
1239 : 147 : tname = scalar_type_name(member->type.st);
1240 : 147 : tprefix = scalar_type_prefix(member->type.st);
1241 [ + + + + : 147 : switch (member->value.type) {
- ]
1242 : : case vt_uint:
1243 : 65 : fprintf(out->fp,
1244 : : "__%sbuild_scalar_field(%llu, %s, %s_%.*s, %s%s, %s%s, %llu, %u, %llu)\n",
1245 : 65 : nsc, llu(member->id), nsc, snt.text, n, s, nsc, tprefix, tname_ns, tname,
1246 : 130 : llu(member->size), member->align, llu(member->value.u));
1247 : 65 : break;
1248 : : case vt_int:
1249 : 75 : fprintf(out->fp,
1250 : : "__%sbuild_scalar_field(%llu, %s, %s_%.*s, %s%s, %s%s, %llu, %u, %lld)\n",
1251 : 75 : nsc, llu(member->id), nsc, snt.text, n, s, nsc, tprefix, tname_ns, tname,
1252 : 150 : llu(member->size), member->align, lld(member->value.i));
1253 : 75 : break;
1254 : : case vt_bool:
1255 : 2 : fprintf(out->fp,
1256 : : "__%sbuild_scalar_field(%llu, %s, %s_%.*s, %s%s, %s%s, %llu, %u, %u)\n",
1257 : 2 : nsc, llu(member->id), nsc, snt.text, n, s, nsc, tprefix, tname_ns, tname,
1258 : 6 : llu(member->size), member->align, (unsigned)member->value.b);
1259 : 2 : break;
1260 : : case vt_float:
1261 : 5 : fprintf(out->fp,
1262 : : "__%sbuild_scalar_field(%llu, %s, %s_%.*s, %s%s, %s%s, %llu, %u, %.17g)\n",
1263 : 5 : nsc, llu(member->id), nsc, snt.text, n, s, nsc, tprefix, tname_ns, tname,
1264 : 10 : llu(member->size), member->align, member->value.f);
1265 : 5 : break;
1266 : : default:
1267 : 0 : gen_panic(out, "internal error: unexpected scalar table default value");
1268 : : continue;
1269 : : }
1270 : : break;
1271 : : case vt_vector_type:
1272 : 25 : tname_ns = scalar_type_ns(member->type.st, nsc);
1273 : 25 : tname = scalar_type_name(member->type.st);
1274 : 25 : tprefix = scalar_type_prefix(member->type.st);
1275 : 25 : fprintf(out->fp,
1276 : : "__%sbuild_vector_field(%llu, %s, %s_%.*s, %s%s, %s%s)\n",
1277 : 25 : nsc, llu(member->id), nsc, snt.text, n, s, nsc, tprefix, tname_ns, tname);
1278 : : /* [ubyte] vectors can nest buffers. */
1279 [ + + ]: 25 : if (member->nest) {
1280 [ + + - ]: 9 : switch (member->nest->symbol.kind) {
1281 : : case fb_is_table:
1282 : : fb_compound_name((fb_compound_type_t *)(&member->nest->symbol), &snref);
1283 : 8 : fprintf(out->fp, "__%sbuild_nested_table_root(%s, %s_%.*s, %s, %s_identifier, %s_type_identifier)\n",
1284 : : nsc, nsc, snt.text, n, s, snref.text, snref.text, snref.text);
1285 : 8 : break;
1286 : : case fb_is_struct:
1287 : : fb_compound_name((fb_compound_type_t *)(&member->nest->symbol), &snref);
1288 : 1 : fprintf(out->fp, "__%sbuild_nested_struct_root(%s, %s_%.*s, %s, %u, %s_identifier, %s_type_identifier)\n",
1289 : : nsc, nsc, snt.text, n, s, snref.text,
1290 : 1 : (unsigned)((fb_compound_type_t *)(member->nest))->align, snref.text, snref.text);
1291 : 1 : break;
1292 : : default:
1293 : 0 : gen_panic(out, "internal error: unexpected nested type");
1294 : : continue;
1295 : : }
1296 : : }
1297 : : break;
1298 : : case vt_string_type:
1299 : 27 : fprintf(out->fp,
1300 : : "__%sbuild_string_field(%llu, %s, %s_%.*s)\n",
1301 : 27 : nsc, llu(member->id), nsc, snt.text, n, s);
1302 : 27 : break;
1303 : : case vt_vector_string_type:
1304 : 10 : fprintf(out->fp,
1305 : : "__%sbuild_string_vector_field(%llu, %s, %s_%.*s)\n",
1306 : 10 : nsc, llu(member->id), nsc, snt.text, n, s);
1307 : 10 : break;
1308 : : case vt_compound_type_ref:
1309 : 109 : fb_compound_name(member->type.ct, &snref);
1310 [ + + + + : 109 : switch (member->type.ct->symbol.kind) {
- ]
1311 : : case fb_is_struct:
1312 : 27 : fprintf(out->fp,
1313 : : "__%sbuild_struct_field(%llu, %s, %s_%.*s, %s, %llu, %u)\n",
1314 : 54 : nsc, llu(member->id), nsc, snt.text, n, s, snref.text, llu(member->size), member->align);
1315 : 27 : break;
1316 : : case fb_is_table:
1317 : 23 : fprintf(out->fp,
1318 : : "__%sbuild_table_field(%llu, %s, %s_%.*s, %s)\n",
1319 : 23 : nsc, llu(member->id), nsc, snt.text, n, s, snref.text);
1320 : 23 : break;
1321 : : case fb_is_enum:
1322 [ + + - - ]: 48 : switch (member->value.type) {
1323 : : case vt_uint:
1324 : 2 : fprintf(out->fp,
1325 : : "__%sbuild_scalar_field(%llu, %s, %s_%.*s, %s, %s_enum_t, %llu, %u, %llu)\n",
1326 : 2 : nsc, llu(member->id), nsc, snt.text, n, s, snref.text, snref.text,
1327 : 4 : llu(member->size), member->align, llu(member->value.u));
1328 : 2 : break;
1329 : : case vt_int:
1330 : 46 : fprintf(out->fp,
1331 : : "__%sbuild_scalar_field(%llu, %s, %s_%.*s, %s, %s_enum_t, %llu, %u, %lli)\n",
1332 : 46 : nsc, llu(member->id), nsc, snt.text, n, s, snref.text, snref.text,
1333 : 92 : llu(member->size), member->align, lld(member->value.i));
1334 : 46 : break;
1335 : : case vt_bool:
1336 : 0 : fprintf(out->fp,
1337 : : "__%sbuild_scalar_field(%llu, %s, %s_%.*s, %s, %s_enum_t, %llu, %u, %u)\n",
1338 : 0 : nsc, llu(member->id), nsc, snt.text, n, s, snref.text, snref.text,
1339 : 0 : llu(member->size), member->align, (unsigned)member->value.b);
1340 : 0 : break;
1341 : : default:
1342 : 0 : gen_panic(out, "internal error: unexpected enum type referenced by table");
1343 : : continue;
1344 : : }
1345 : : break;
1346 : : case fb_is_union:
1347 : 11 : fprintf(out->fp,
1348 : : "__%sbuild_union_field(%llu, %s, %s_%.*s, %s)\n",
1349 : 11 : nsc, llu(member->id), nsc, snt.text, n, s, snref.text);
1350 : 11 : gen_union_member_fields(out, snt.text, n, s, member->type.ct);
1351 : 11 : break;
1352 : : default:
1353 : 0 : gen_panic(out, "internal error: unexpected compound type in table during code generation");
1354 : : break;
1355 : : }
1356 : : break;
1357 : : case vt_vector_compound_type_ref:
1358 : 18 : fb_compound_name(member->type.ct, &snref);
1359 [ + + + - : 18 : switch (member->type.ct->symbol.kind) {
- ]
1360 : : case fb_is_struct:
1361 [ - + ]: 8 : if (member->type.ct->symbol.flags & fb_indexed) {
1362 : 0 : fprintf(out->fp, "/* vector has keyed elements */\n");
1363 : : }
1364 : 8 : fprintf(out->fp,
1365 : : "__%sbuild_vector_field(%llu, %s, %s_%.*s, %s, %s_t)\n",
1366 : 8 : nsc, llu(member->id), nsc, snt.text, n, s, snref.text, snref.text);
1367 : 8 : break;
1368 : : case fb_is_table:
1369 [ + + ]: 9 : if (member->type.ct->symbol.flags & fb_indexed) {
1370 : 8 : fprintf(out->fp, "/* vector has keyed elements */\n");
1371 : : }
1372 : 9 : fprintf(out->fp,
1373 : : "__%sbuild_table_vector_field(%llu, %s, %s_%.*s, %s)\n",
1374 : 9 : nsc, llu(member->id), nsc, snt.text, n, s, snref.text);
1375 : 9 : break;
1376 : : case fb_is_enum:
1377 : 1 : fprintf(out->fp,
1378 : : "__%sbuild_vector_field(%llu, %s, %s_%.*s, %s, %s_enum_t)\n",
1379 : 1 : nsc, llu(member->id), nsc, snt.text, n, s, snref.text, snref.text);
1380 : 1 : break;
1381 : : case fb_is_union:
1382 : 0 : gen_panic(out, "internal error: unexpected vector of union present in table");
1383 : : break;
1384 : : default:
1385 : 0 : gen_panic(out, "internal error: unexpected vector compound type in table during code generation");
1386 : : break;
1387 : : }
1388 : : break;
1389 : : default:
1390 : 0 : gen_panic(out, "internal error: unexpected table member type during code generation");
1391 : : break;
1392 : : }
1393 : : }
1394 : 63 : fprintf(out->fp, "\n");
1395 : 63 : return 0;
1396 : : }
1397 : :
1398 : 24 : static int gen_builder_enums(fb_output_t *out)
1399 : : {
1400 : 24 : const char *nsc = out->nsc;
1401 : : fb_symbol_t *sym;
1402 : : int was_here = 0;
1403 : : fb_scoped_name_t snt;
1404 : :
1405 : 24 : fb_clear(snt);
1406 : :
1407 [ + + ]: 166 : for (sym = out->S->symbols; sym; sym = sym->link) {
1408 [ + + ]: 142 : switch (sym->kind) {
1409 : : case fb_is_enum:
1410 : : fb_compound_name((fb_compound_type_t *)sym, &snt);
1411 : 27 : fprintf(out->fp,
1412 : : "#define __%s_formal_args , %s_enum_t v0\n"
1413 : : "#define __%s_call_args , v0\n",
1414 : : snt.text, snt.text,
1415 : : snt.text);
1416 : 27 : fprintf(out->fp, "__%sbuild_scalar(%s, %s, %s_enum_t)\n",
1417 : : nsc, nsc, snt.text, snt.text);
1418 : : was_here = 1;
1419 : 27 : break;
1420 : : default:
1421 : 115 : continue;
1422 : : }
1423 : : }
1424 [ + + ]: 24 : if (was_here) {
1425 : 16 : fprintf(out->fp, "\n");
1426 : : }
1427 : 24 : return 0;
1428 : : }
1429 : :
1430 : : /*
1431 : : * Scope resolution is a bit fuzzy in unions -
1432 : : *
1433 : : * Googles flatc compiler allows dot notation in unions but not enums.
1434 : : * C++ generates unqualified enum members (i.e. MyGame.Example.Monster
1435 : : * becomes Monster) in the generated enum but still refers to the
1436 : : * specific table type in the given namespace. This makes it possible
1437 : : * to have name conflicts, and flatc raises these like other enum
1438 : : * conficts.
1439 : : *
1440 : : * We use the same approach and this is why we both look up compound
1441 : : * name and symbol name for the same member but the code generator
1442 : : * is not concerned with how the scope is parsed or how errors are
1443 : : * flagged - it just expects members to be unique.
1444 : : */
1445 : 9 : static int gen_union(fb_output_t *out, fb_compound_type_t *ct)
1446 : : {
1447 : 9 : const char *nsc = out->nsc;
1448 : : fb_member_t *member;
1449 : : fb_symbol_t *sym;
1450 : : const char *s;
1451 : : int n;
1452 : : fb_scoped_name_t snt;
1453 : : fb_scoped_name_t snref;
1454 : :
1455 : 9 : fb_clear(snt);
1456 : 9 : fb_clear(snref);
1457 : : fb_compound_name(ct, &snt);
1458 : :
1459 : 9 : fprintf(out->fp,
1460 : : "struct %s_union_ref {\n"
1461 : : " %s_union_type_t type;\n"
1462 : : " union {\n"
1463 : : " %sref_t _member;\n",
1464 : : snt.text, snt.text, nsc);
1465 [ + + ]: 36 : for (sym = ct->members; sym; sym = sym->link) {
1466 : : member = (fb_member_t *)sym;
1467 [ + + - ]: 27 : switch (member->type.type) {
1468 : : case vt_compound_type_ref:
1469 : 18 : fb_compound_name((fb_compound_type_t *)member->type.ct, &snref);
1470 : : symbol_name(sym, &n, &s);
1471 : 18 : fprintf(out->fp,
1472 : : " %s_ref_t %.*s;\n",
1473 : : snref.text, n, s);
1474 : 18 : break;
1475 : : case vt_missing:
1476 : 9 : fprintf(out->fp, " %sref_t NONE;\n", nsc);
1477 : 9 : break;
1478 : : default:
1479 : 0 : gen_panic(out, "internal error: unexpected union member type");
1480 : : break;
1481 : : }
1482 : : }
1483 : 9 : fprintf(out->fp,
1484 : : " };\n"
1485 : : "};\n\n");
1486 [ + + ]: 36 : for (sym = ct->members; sym; sym = sym->link) {
1487 : : member = (fb_member_t *)sym;
1488 [ + + - ]: 27 : switch (member->type.type) {
1489 : : case vt_compound_type_ref:
1490 : 18 : fb_compound_name((fb_compound_type_t *)member->type.ct, &snref);
1491 : : symbol_name(sym, &n, &s);
1492 : 18 : fprintf(out->fp,
1493 : : "static inline %s_union_ref_t %s_as_%.*s(%s_ref_t ref)\n"
1494 : : "{ %s_union_ref_t uref; uref.type = %s_%.*s; uref.%.*s = ref; return uref; }\n",
1495 : : snt.text, snt.text, n, s, snref.text,
1496 : : snt.text, snt.text, n, s, n, s);
1497 : 18 : break;
1498 : : case vt_missing:
1499 : 9 : fprintf(out->fp,
1500 : : "static inline %s_union_ref_t %s_as_NONE()\n"
1501 : : "{ %s_union_ref_t uref; uref.type = %s_NONE; uref._member = 0; return uref; }\n",
1502 : : snt.text, snt.text, snt.text, snt.text);
1503 : 9 : break;
1504 : : default:
1505 : 0 : gen_panic(out, "internal error: unexpected union member type");
1506 : : break;
1507 : : }
1508 : : }
1509 : 9 : return 0;
1510 : : }
1511 : :
1512 : 48 : static int gen_union_typedefs(fb_output_t *out)
1513 : : {
1514 : : fb_symbol_t *sym;
1515 : : int was_here = 0;
1516 : : fb_scoped_name_t snt;
1517 : :
1518 : 24 : fb_clear(snt);
1519 : :
1520 [ + + ]: 166 : for (sym = out->S->symbols; sym; sym = sym->link) {
1521 [ + + ]: 142 : switch (sym->kind) {
1522 : : case fb_is_union:
1523 : : fb_compound_name((fb_compound_type_t *)sym, &snt);
1524 : 9 : fprintf(out->fp,
1525 : : "typedef struct %s_union_ref %s_union_ref_t;\n",
1526 : : snt.text, snt.text);
1527 : : was_here = 1;
1528 : : break;
1529 : : default:
1530 : 133 : continue;
1531 : : }
1532 : : }
1533 [ + + ]: 24 : if (was_here) {
1534 : 9 : fprintf(out->fp, "\n");
1535 : : }
1536 : 24 : return 0;
1537 : : }
1538 : :
1539 : 24 : static int gen_unions(fb_output_t *out)
1540 : : {
1541 : : fb_symbol_t *sym;
1542 : : int was_here = 0;
1543 : :
1544 [ + + ]: 166 : for (sym = out->S->symbols; sym; sym = sym->link) {
1545 [ + + ]: 142 : switch (sym->kind) {
1546 : : case fb_is_union:
1547 : 9 : gen_union(out, (fb_compound_type_t *)sym);
1548 : : was_here = 1;
1549 : 9 : break;
1550 : : default:
1551 : 133 : continue;
1552 : : }
1553 : : }
1554 [ + + ]: 24 : if (was_here) {
1555 : 9 : fprintf(out->fp, "\n");
1556 : : }
1557 : 24 : return 0;
1558 : : }
1559 : :
1560 : 24 : static int gen_builder_tables(fb_output_t *out)
1561 : : {
1562 : : fb_symbol_t *sym;
1563 : : int was_here = 0;
1564 : :
1565 : : /* Needed by table create args. */
1566 : 24 : gen_union_typedefs(out);
1567 : : /*
1568 : : * Because tables are recursive, we need the type and `start/end/add`
1569 : : * operations before the fields. We also need create for push_create
1570 : : * but it needs all dependent types, so create is fw declared
1571 : : * in a subsequent step. The actual create impl. then follows
1572 : : * after the table fields.
1573 : : */
1574 [ + + ]: 166 : for (sym = out->S->symbols; sym; sym = sym->link) {
1575 [ + + ]: 142 : switch (sym->kind) {
1576 : : case fb_is_table:
1577 : : was_here = 1;
1578 : 63 : gen_required_table_fields(out, (fb_compound_type_t *)sym);
1579 : 63 : gen_builder_table(out, (fb_compound_type_t *)sym);
1580 : 63 : break;
1581 : : default:
1582 : 79 : continue;
1583 : : }
1584 : : }
1585 [ + + ]: 166 : for (sym = out->S->symbols; sym; sym = sym->link) {
1586 [ + + ]: 142 : switch (sym->kind) {
1587 : : case fb_is_table:
1588 : 63 : gen_builder_create_table_decl(out, (fb_compound_type_t *)sym);
1589 : 63 : break;
1590 : : default:
1591 : 79 : continue;
1592 : : }
1593 : : }
1594 [ + + ]: 24 : if (was_here) {
1595 : 10 : fprintf(out->fp, "\n");
1596 : : }
1597 : : /* Unions require the table ref_t types to be present. */
1598 : 24 : gen_unions(out);
1599 [ + + ]: 24 : if (!was_here) {
1600 : : return 0;
1601 : : }
1602 [ + + ]: 138 : for (sym = out->S->symbols; sym; sym = sym->link) {
1603 [ + + ]: 128 : switch (sym->kind) {
1604 : : case fb_is_table:
1605 : 63 : gen_builder_table_fields(out, (fb_compound_type_t *)sym);
1606 : 63 : gen_builder_create_table(out, (fb_compound_type_t *)sym);
1607 : 63 : gen_builder_table_prolog(out, (fb_compound_type_t *)sym);
1608 : 63 : fprintf(out->fp, "\n");
1609 : 63 : break;
1610 : : default:
1611 : 65 : continue;
1612 : : }
1613 : : }
1614 : : return 0;
1615 : : }
1616 : :
1617 : 24 : static int gen_builder_footer(fb_output_t *out)
1618 : : {
1619 : : gen_pragma_pop(out);
1620 : 24 : fprintf(out->fp,
1621 : : "#endif /* %s_BUILDER_H */\n",
1622 : 24 : out->S->basenameup);
1623 : 24 : return 0;
1624 : : }
1625 : :
1626 : 24 : int fb_gen_c_builder(fb_output_t *out)
1627 : : {
1628 : 24 : gen_builder_pretext(out);
1629 : 24 : gen_builder_enums(out);
1630 : 24 : gen_builder_structs(out);
1631 : 24 : gen_builder_tables(out);
1632 : 24 : gen_builder_footer(out);
1633 : 24 : return 0;
1634 : : }
|