nsgenbind
Loading...
Searching...
No Matches
duk-libdom-generated.c
Go to the documentation of this file.
1/* duktape and libdom binding generation implementation
2 *
3 * This file is part of nsgenbind.
4 * Licensed under the MIT License,
5 * http://www.opensource.org/licenses/mit-license.php
6 * Copyright 2015 Vincent Sanders <vince@netsurf-browser.org>
7 */
8
15#include <stdio.h>
16#include <stdlib.h>
17#include <stdbool.h>
18#include <string.h>
19#include <unistd.h>
20#include <getopt.h>
21#include <errno.h>
22#include <ctype.h>
23
24#include "options.h"
25#include "utils.h"
26#include "nsgenbind-ast.h"
27#include "webidl-ast.h"
28#include "ir.h"
29#include "output.h"
30#include "duk-libdom.h"
31
32static int
33output_generated_attribute_user_getter(struct opctx *outc,
34 struct ir_entry *interfacee,
35 struct ir_attribute_entry *atributee)
36{
37 UNUSED(interfacee);
38
39 if ((atributee->typev[0].name != NULL) &&
40 strlen(atributee->typev[0].name) >= 12 &&
41 strcmp(atributee->typev[0].name + strlen(atributee->typev[0].name) - 12,
42 "EventHandler") == 0) {
43
44 /* this can generate for onxxx event handlers */
45 if ((atributee->name[0] != 'o') ||
46 (atributee->name[1] != 'n')) {
47 return -1; /* not onxxx */
48 }
49
50 if (interfacee->u.interface.primary_global) {
51 outputf(outc,
52 "\tdom_event_target *et = NULL;\n");
53 } else {
54 outputf(outc,
55 "\tdom_event_target *et = (dom_event_target *)(((node_private_t *)priv)->node);\n");
56 }
57 outputf(outc,
58 "\tdom_string *name;\n"
59 "\tdom_exception exc;\n\n"
60 "\texc = dom_string_create((const uint8_t *)\"%s\", %ld, &name);\n"
61 "\tif (exc != DOM_NO_ERR) return 0;\n\n"
62 "\tduk_push_this(ctx);\n"
63 "\t/* ... node */\n"
64 "\tif (dukky_get_current_value_of_event_handler(ctx, name, et) == false) {\n"
65 "\t\tdom_string_unref(name);\n"
66 "\t\treturn 0;\n"
67 "\t}\n"
68 "\tdom_string_unref(name);\n"
69 "\t/* ... handler node */\n"
70 "\tduk_pop(ctx);\n"
71 "\t/* ... handler */\n"
72 "\treturn 1;\n",
73 atributee->name + 2,
74 strlen(atributee->name + 2));
75 return 0;
76 }
77 return -1;
78}
79
80/* exported function documented in duk-libdom.h */
81int
83 struct ir_entry *interfacee,
84 struct ir_attribute_entry *atributee)
85{
86 int res = 0;
87
88 /* generation can only cope with a single type on the attribute */
89 if (atributee->typec != 1) {
90 return -1;
91 }
92
93 switch (atributee->typev[0].base) {
95 outputf(outc,
96 "\tdom_exception exc;\n"
97 "\tdom_string *str;\n"
98 "\n");
99 outputf(outc,
100 "\texc = dom_%s_get_%s((struct dom_%s *)((node_private_t*)priv)->node, &str);\n",
101 interfacee->class_name,
102 atributee->property_name,
103 interfacee->class_name);
104 outputf(outc,
105 "\tif (exc != DOM_NO_ERR) {\n"
106 "\t\treturn 0;\n"
107 "\t}\n"
108 "\n"
109 "\tif (str != NULL) {\n"
110 "\t\tduk_push_lstring(ctx,\n"
111 "\t\t\tdom_string_data(str),\n"
112 "\t\t\tdom_string_length(str));\n"
113 "\t\tdom_string_unref(str);\n"
114 "\t} else {\n");
115 if (atributee->typev[0].nullable) {
116 outputf(outc,
117 "\t\tduk_push_null(ctx);\n");
118 } else {
119 outputf(outc,
120 "\t\tduk_push_lstring(ctx, NULL, 0);\n");
121 }
122 outputf(outc,
123 "\t}\n"
124 "\n"
125 "\treturn 1;\n");
126 break;
127
128 case WEBIDL_TYPE_LONG:
129 if (atributee->typev[0].modifier == WEBIDL_TYPE_MODIFIER_UNSIGNED) {
130 outputf(outc,
131 "\tdom_ulong l;\n");
132 } else {
133 outputf(outc,
134 "\tdom_long l;\n");
135 }
136 outputf(outc,
137 "\tdom_exception exc;\n"
138 "\n");
139 outputf(outc,
140 "\texc = dom_%s_get_%s((struct dom_%s *)((node_private_t*)priv)->node, &l);\n",
141 interfacee->class_name,
142 atributee->property_name,
143 interfacee->class_name);
144 outputf(outc,
145 "\tif (exc != DOM_NO_ERR) {\n"
146 "\t\treturn 0;\n"
147 "\t}\n"
148 "\n"
149 "\tduk_push_number(ctx, (duk_double_t)l);\n"
150 "\n"
151 "\treturn 1;\n");
152 break;
153
155 if (atributee->typev[0].modifier == WEBIDL_TYPE_MODIFIER_UNSIGNED) {
156 outputf(outc,
157 "\tdom_ushort s;\n");
158 } else {
159 outputf(outc,
160 "\tdom_short s;\n");
161 }
162 outputf(outc,
163 "\tdom_exception exc;\n"
164 "\n");
165 outputf(outc,
166 "\texc = dom_%s_get_%s((struct dom_%s *)((node_private_t*)priv)->node, &s);\n",
167 interfacee->class_name,
168 atributee->property_name,
169 interfacee->class_name);
170 outputf(outc,
171 "\tif (exc != DOM_NO_ERR) {\n"
172 "\t\treturn 0;\n"
173 "\t}\n"
174 "\n"
175 "\tduk_push_number(ctx, (duk_double_t)s);\n"
176 "\n"
177 "\treturn 1;\n");
178 break;
179
180 case WEBIDL_TYPE_BOOL:
181 outputf(outc,
182 "\tdom_exception exc;\n"
183 "\tbool b;\n"
184 "\n");
185 outputf(outc,
186 "\texc = dom_%s_get_%s((struct dom_%s *)((node_private_t*)priv)->node, &b);\n",
187 interfacee->class_name,
188 atributee->property_name,
189 interfacee->class_name);
190 outputf(outc,
191 "\tif (exc != DOM_NO_ERR) {\n"
192 "\t\treturn 0;\n"
193 "\t}\n"
194 "\n"
195 "\tduk_push_boolean(ctx, b);\n"
196 "\n"
197 "\treturn 1;\n");
198 break;
199
200 case WEBIDL_TYPE_USER:
201 res = output_generated_attribute_user_getter(outc,
202 interfacee,
203 atributee);
204 break;
205
206 default:
207 res = -1;
208 break;
209
210 }
211
212 if (res >= 0) {
214 "Generated: getter %s::%s();",
215 interfacee->name, atributee->name);
216 }
217
218 return res;
219}
220
221static int
222output_generated_attribute_user_setter(struct opctx *outc,
223 struct ir_entry *interfacee,
224 struct ir_attribute_entry *atributee)
225{
226 UNUSED(interfacee);
227
228 if ((atributee->typev[0].name != NULL) &&
229 strlen(atributee->typev[0].name) >= 12 &&
230 strcmp(atributee->typev[0].name + strlen(atributee->typev[0].name) - 12,
231 "EventHandler") == 0) {
232
233 /* this can generate for onxxx event handlers */
234 if ((atributee->name[0] != 'o') ||
235 (atributee->name[1] != 'n')) {
236 return -1; /* not onxxx */
237 }
238
239 if (interfacee->u.interface.primary_global) {
240 outputf(outc,
241 "\tdom_element *et = NULL;\n");
242 } else {
243 outputf(outc,
244 "\tdom_element *et = (dom_element *)(((node_private_t *)priv)->node);\n");
245 }
246
247 outputf(outc,
248 "\t/* handlerfn */\n"
249 "\tduk_push_this(ctx);\n"
250 "\t/* handlerfn this */\n"
251 "\tduk_get_prop_string(ctx, -1, HANDLER_MAGIC);\n"
252 "\t/* handlerfn this handlers */\n"
253 "\tduk_push_lstring(ctx, \"%s\", %ld);\n"
254 "\t/* handlerfn this handlers %s */\n"
255 "\tduk_dup(ctx, -4);\n"
256 "\t/* handlerfn this handlers %s handlerfn */\n"
257 "\tduk_put_prop(ctx, -3);\n"
258 "\t/* handlerfn this handlers */\n"
259 "\tdukky_register_event_listener_for(ctx, et,\n"
260 "\t\tcorestring_dom_%s, false);\n"
261 "\treturn 0;\n",
262 atributee->name + 2,
263 strlen(atributee->name + 2),
264 atributee->name + 2,
265 atributee->name + 2,
266 atributee->name + 2);
267 return 0;
268 }
269 return -1;
270}
271
272
273/* exported function documented in duk-libdom.h */
274int
276 struct ir_entry *interfacee,
277 struct ir_attribute_entry *atributee)
278{
279 int res = 0;
280
281 /* generation can only cope with a single type on the attribute */
282 if (atributee->typec != 1) {
283 return -1;
284 }
285
286 switch (atributee->typev[0].base) {
288 outputf(outc,
289 "\tdom_exception exc;\n"
290 "\tdom_string *str;\n"
291 "\tduk_size_t slen;\n"
292 "\tconst char *s;\n");
293 if ((atributee->treatnullas != NULL) &&
294 (strcmp(atributee->treatnullas, "EmptyString") == 0)) {
295 outputf(outc,
296 "\tif (duk_is_null(ctx, 0)) {\n"
297 "\t\ts = \"\";\n"
298 "\t\tslen = 0;\n"
299 "\t} else {\n"
300 "\t\ts = duk_safe_to_lstring(ctx, 0, &slen);\n"
301 "\t}\n");
302 } else {
303 outputf(outc,
304 "\ts = duk_safe_to_lstring(ctx, 0, &slen);\n");
305 }
306 outputf(outc,
307 "\n"
308 "\texc = dom_string_create((const uint8_t *)s, slen, &str);\n"
309 "\tif (exc != DOM_NO_ERR) {\n"
310 "\t\treturn 0;\n"
311 "\t}\n"
312 "\n");
313 outputf(outc,
314 "\texc = dom_%s_set_%s((struct dom_%s *)((node_private_t*)priv)->node, str);\n",
315 interfacee->class_name,
316 atributee->property_name,
317 interfacee->class_name);
318 outputf(outc,
319 "\tdom_string_unref(str);\n"
320 "\tif (exc != DOM_NO_ERR) {\n"
321 "\t\treturn 0;\n"
322 "\t}\n"
323 "\n"
324 "\treturn 0;\n");
325 break;
326
327 case WEBIDL_TYPE_LONG:
328 if (atributee->typev[0].modifier == WEBIDL_TYPE_MODIFIER_UNSIGNED) {
329 outputf(outc,
330 "\tdom_exception exc;\n"
331 "\tdom_ulong l;\n"
332 "\n"
333 "\tl = duk_get_uint(ctx, 0);\n"
334 "\n");
335 } else {
336 outputf(outc,
337 "\tdom_exception exc;\n"
338 "\tdom_long l;\n"
339 "\n"
340 "\tl = duk_get_int(ctx, 0);\n"
341 "\n");
342 }
343 outputf(outc,
344 "\texc = dom_%s_set_%s((struct dom_%s *)((node_private_t*)priv)->node, l);\n",
345 interfacee->class_name,
346 atributee->property_name,
347 interfacee->class_name);
348 outputf(outc,
349 "\tif (exc != DOM_NO_ERR) {\n"
350 "\t\treturn 0;\n"
351 "\t}\n"
352 "\n"
353 "\treturn 0;\n");
354 break;
355
357 if (atributee->typev[0].modifier == WEBIDL_TYPE_MODIFIER_UNSIGNED) {
358 outputf(outc,
359 "\tdom_exception exc;\n"
360 "\tdom_ushort s;\n"
361 "\n"
362 "\ts = duk_get_uint(ctx, 0);\n"
363 "\n");
364 } else {
365 outputf(outc,
366 "\tdom_exception exc;\n"
367 "\tdom_short s;\n"
368 "\n"
369 "\ts = duk_get_int(ctx, 0);\n"
370 "\n");
371 }
372 outputf(outc,
373 "\texc = dom_%s_set_%s((struct dom_%s *)((node_private_t*)priv)->node, s);\n",
374 interfacee->class_name,
375 atributee->property_name,
376 interfacee->class_name);
377 outputf(outc,
378 "\tif (exc != DOM_NO_ERR) {\n"
379 "\t\treturn 0;\n"
380 "\t}\n"
381 "\n"
382 "\treturn 0;\n");
383 break;
384
385 case WEBIDL_TYPE_BOOL:
386 outputf(outc,
387 "\tdom_exception exc;\n"
388 "\tbool b;\n"
389 "\n"
390 "\tb = duk_get_boolean(ctx, 0);\n"
391 "\n");
392 outputf(outc,
393 "\texc = dom_%s_set_%s((struct dom_%s *)((node_private_t*)priv)->node, b);\n",
394 interfacee->class_name,
395 atributee->property_name,
396 interfacee->class_name);
397 outputf(outc,
398 "\tif (exc != DOM_NO_ERR) {\n"
399 "\t\treturn 0;\n"
400 "\t}\n"
401 "\n"
402 "\treturn 0;\n");
403 break;
404
405 case WEBIDL_TYPE_USER:
406 res = output_generated_attribute_user_setter(outc,
407 interfacee,
408 atributee);
409 break;
410
411 default:
412 res = -1;
413 break;
414
415 }
416
417 if (res >= 0) {
419 "Generated: getter %s::%s();",
420 interfacee->name, atributee->name);
421 }
422
423 return res;
424}
int output_generated_attribute_setter(struct opctx *outc, struct ir_entry *interfacee, struct ir_attribute_entry *atributee)
int output_generated_attribute_getter(struct opctx *outc, struct ir_entry *interfacee, struct ir_attribute_entry *atributee)
@ WARNING_GENERATED
Definition options.h:32
#define WARN(flags, msg, args...)
Definition options.h:37
int outputf(struct opctx *opctx, const char *fmt,...)
Definition output.c:66
Definition ir.h:63
const char * treatnullas
Definition ir.h:72
struct ir_type_entry * typev
Definition ir.h:68
int typec
Definition ir.h:67
char * property_name
Definition ir.h:77
const char * name
Definition ir.h:64
Definition ir.h:134
char * class_name
Definition ir.h:160
const char * name
Definition ir.h:135
struct ir_interface_entry interface
Definition ir.h:143
union ir_entry::@2 u
bool primary_global
Definition ir.h:99
enum webidl_type_modifier modifier
Definition ir.h:55
const char * name
Definition ir.h:57
enum webidl_type base
Definition ir.h:54
bool nullable
Definition ir.h:56
Definition output.c:17
#define UNUSED(x)
Definition utils.h:50
@ WEBIDL_TYPE_SHORT
Definition webidl-ast.h:59
@ WEBIDL_TYPE_STRING
Definition webidl-ast.h:62
@ WEBIDL_TYPE_BOOL
Definition webidl-ast.h:54
@ WEBIDL_TYPE_USER
Definition webidl-ast.h:53
@ WEBIDL_TYPE_LONG
Definition webidl-ast.h:60
@ WEBIDL_TYPE_MODIFIER_UNSIGNED
Definition webidl-ast.h:72