1 /* AST generator for the WEB IDL parser
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 2012 Vincent Sanders <vince@netsurf-browser.org>
7 */
8
9 #include <stdbool.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <errno.h>
14 #include <stdarg.h>
15
16 #include "utils.h"
17 #include "webidl-ast.h"
18 #include "options.h"
19
20 /**
21 * standard IO handle for parse trace logging.
22 */
23 static FILE *webidl_parsetracef;
24
25 extern int webidl_debug;
26 extern int webidl__flex_debug;
27 extern void webidl_restart(FILE*);
28 extern int webidl_parse(struct webidl_node **webidl_ast);
29
30 struct webidl_node {
31 enum webidl_node_type type; /* the type of the node */
32 struct webidl_node *l; /* link to the next sibling node */
33 union {
34 void *value;
35 struct webidl_node *node; /* node has a list of nodes */
36 char *text; /* node data is text */
37 float *flt;
38 int number; /* node data is an integer */
39 } r;
40 };
41
42 /* insert node(s) at beginning of a list */
43 struct webidl_node *
webidl_node_prepend(struct webidl_node * list,struct webidl_node * inst)44 webidl_node_prepend(struct webidl_node *list, struct webidl_node *inst)
45 {
46 struct webidl_node *end = inst;
47
48 if (inst == NULL) {
49 return list; /* no node to prepend - return existing list */
50 }
51
52 /* find end of inserted node list */
53 while (end->l != NULL) {
54 end = end->l;
55 }
56
57 end->l = list;
58
59 return inst;
60 }
61
62 /* append node at end of a list */
63 struct webidl_node *
webidl_node_append(struct webidl_node * list,struct webidl_node * node)64 webidl_node_append(struct webidl_node *list, struct webidl_node *node)
65 {
66 struct webidl_node *cur = list;
67
68 if (cur == NULL) {
69 return node; /* no existing list so just return node */
70 }
71
72 while (cur->l != NULL) {
73 cur = cur->l;
74 }
75 cur->l = node;
76
77 return list;
78 }
79
80 /* prepend list to a nodes list
81 *
82 * inserts a list into the beginning of a nodes r list
83 *
84 * CAUTION: if the \a node element is not a node type the node will not be added
85 */
86 struct webidl_node *
webidl_node_add(struct webidl_node * node,struct webidl_node * list)87 webidl_node_add(struct webidl_node *node, struct webidl_node *list)
88 {
89 if (node == NULL) {
90 return list;
91 }
92
93 /* this does not use webidl_node_getnode() as it cannot
94 * determine between an empty node and a node which is not a
95 * list type
96 */
97 switch (node->type) {
98 case WEBIDL_NODE_TYPE_ROOT:
99 case WEBIDL_NODE_TYPE_INTERFACE:
100 case WEBIDL_NODE_TYPE_DICTIONARY:
101 case WEBIDL_NODE_TYPE_LIST:
102 case WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE:
103 case WEBIDL_NODE_TYPE_ATTRIBUTE:
104 case WEBIDL_NODE_TYPE_OPERATION:
105 case WEBIDL_NODE_TYPE_OPTIONAL:
106 case WEBIDL_NODE_TYPE_ARGUMENT:
107 case WEBIDL_NODE_TYPE_TYPE:
108 case WEBIDL_NODE_TYPE_CONST:
109 break;
110
111 default:
112 /* not a node type node */
113 return list;
114 }
115
116 node->r.node = webidl_node_prepend(node->r.node, list);
117
118 return node;
119 }
120
121
122 struct webidl_node *
123 /* exported interface documented in webidl-ast.h */
webidl_node_new(enum webidl_node_type type,struct webidl_node * l,void * r)124 webidl_node_new(enum webidl_node_type type,
125 struct webidl_node *l,
126 void *r)
127 {
128 struct webidl_node *nn;
129 nn = calloc(1, sizeof(struct webidl_node));
130 nn->type = type;
131 nn->l = l;
132 nn->r.value = r;
133 return nn;
134 }
135
136 /* exported interface documented in webidl-ast.h */
137 struct webidl_node *
webidl_new_number_node(enum webidl_node_type type,struct webidl_node * l,int number)138 webidl_new_number_node(enum webidl_node_type type,
139 struct webidl_node *l,
140 int number)
141 {
142 struct webidl_node *nn;
143 nn = calloc(1, sizeof(struct webidl_node));
144 nn->type = type;
145 nn->l = l;
146 nn->r.number = number;
147 return nn;
148 }
149
150
151 int
webidl_node_for_each_type(struct webidl_node * node,enum webidl_node_type type,webidl_callback_t * cb,void * ctx)152 webidl_node_for_each_type(struct webidl_node *node,
153 enum webidl_node_type type,
154 webidl_callback_t *cb,
155 void *ctx)
156 {
157 int ret;
158
159 if (node == NULL) {
160 return -1;
161 }
162 if (node->l != NULL) {
163 ret = webidl_node_for_each_type(node->l, type, cb, ctx);
164 if (ret != 0) {
165 return ret;
166 }
167 }
168 if (node->type == type) {
169 return cb(node, ctx);
170 }
171
172 return 0;
173 }
174
175 /* exported interface defined in webidl-ast.h */
webidl_cmp_node_type(struct webidl_node * node,void * ctx)176 int webidl_cmp_node_type(struct webidl_node *node, void *ctx)
177 {
178 if (node->type == (enum webidl_node_type)ctx)
179 return 1;
180 return 0;
181 }
182
webidl_enumerate_node(struct webidl_node * node,void * ctx)183 static int webidl_enumerate_node(struct webidl_node *node, void *ctx)
184 {
185 UNUSED(node);
186 (*((int *)ctx))++;
187 return 0;
188 }
189
190 /* exported interface defined in nsgenbind-ast.h */
191 int
webidl_node_enumerate_type(struct webidl_node * node,enum webidl_node_type type)192 webidl_node_enumerate_type(struct webidl_node *node,
193 enum webidl_node_type type)
194 {
195 int count = 0;
196 webidl_node_for_each_type(node,
197 type,
198 webidl_enumerate_node,
199 &count);
200 return count;
201 }
202
203 /* exported interface defined in webidl-ast.h */
204 struct webidl_node *
webidl_node_find(struct webidl_node * node,struct webidl_node * prev,webidl_callback_t * cb,void * ctx)205 webidl_node_find(struct webidl_node *node,
206 struct webidl_node *prev,
207 webidl_callback_t *cb,
208 void *ctx)
209 {
210 struct webidl_node *ret;
211
212 if ((node == NULL) || (node == prev)) {
213 return NULL;
214 }
215
216 if (node->l != prev) {
217 ret = webidl_node_find(node->l, prev, cb, ctx);
218 if (ret != NULL) {
219 return ret;
220 }
221 }
222
223 if (cb(node, ctx) != 0) {
224 return node;
225 }
226
227 return NULL;
228 }
229
230
231 /* exported interface defined in webidl-ast.h */
232 struct webidl_node *
webidl_node_find_type(struct webidl_node * node,struct webidl_node * prev,enum webidl_node_type type)233 webidl_node_find_type(struct webidl_node *node,
234 struct webidl_node *prev,
235 enum webidl_node_type type)
236 {
237 return webidl_node_find(node,
238 prev,
239 webidl_cmp_node_type,
240 (void *)type);
241 }
242
243
244 /* exported interface defined in webidl-ast.h */
245 struct webidl_node *
webidl_node_find_type_ident(struct webidl_node * root_node,enum webidl_node_type type,const char * ident)246 webidl_node_find_type_ident(struct webidl_node *root_node,
247 enum webidl_node_type type,
248 const char *ident)
249 {
250 struct webidl_node *node;
251 struct webidl_node *ident_node;
252
253 node = webidl_node_find_type(root_node, NULL, type);
254
255 while (node != NULL) {
256
257 ident_node = webidl_node_find_type(webidl_node_getnode(node),
258 NULL,
259 WEBIDL_NODE_TYPE_IDENT);
260 if (ident_node != NULL) {
261 if (strcmp(ident_node->r.text, ident) == 0)
262 break;
263 }
264
265 node = webidl_node_find_type(root_node, node, type);
266
267 }
268 return node;
269 }
270
271
272 /* exported interface defined in webidl-ast.h */
webidl_node_gettext(struct webidl_node * node)273 char *webidl_node_gettext(struct webidl_node *node)
274 {
275 if (node != NULL) {
276
277 switch(node->type) {
278 case WEBIDL_NODE_TYPE_IDENT:
279 case WEBIDL_NODE_TYPE_INHERITANCE:
280 case WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS:
281 case WEBIDL_NODE_TYPE_LITERAL_STRING:
282 return node->r.text;
283
284 default:
285 break;
286 }
287 }
288 return NULL;
289 }
290
291 /* exported interface defined in webidl-ast.h */
292 int *
webidl_node_getint(struct webidl_node * node)293 webidl_node_getint(struct webidl_node *node)
294 {
295 if (node != NULL) {
296 switch(node->type) {
297 case WEBIDL_NODE_TYPE_MODIFIER:
298 case WEBIDL_NODE_TYPE_TYPE_BASE:
299 case WEBIDL_NODE_TYPE_LITERAL_INT:
300 case WEBIDL_NODE_TYPE_SPECIAL:
301 case WEBIDL_NODE_TYPE_LITERAL_BOOL:
302 return &node->r.number;
303
304 default:
305 break;
306 }
307 }
308 return NULL;
309 }
310
311 /* exported interface defined in webidl-ast.h */
312 float *
webidl_node_getfloat(struct webidl_node * node)313 webidl_node_getfloat(struct webidl_node *node)
314 {
315 if (node != NULL) {
316 switch(node->type) {
317 case WEBIDL_NODE_TYPE_LITERAL_FLOAT:
318 return node->r.flt;
319
320 default:
321 break;
322 }
323 }
324 return NULL;
325 }
326
327 /* exported interface defined in webidl-ast.h */
webidl_node_gettype(struct webidl_node * node)328 enum webidl_node_type webidl_node_gettype(struct webidl_node *node)
329 {
330 return node->type;
331 }
332
333
334 /* exported interface defined in webidl-ast.h */
webidl_node_getnode(struct webidl_node * node)335 struct webidl_node *webidl_node_getnode(struct webidl_node *node)
336 {
337 if (node != NULL) {
338 switch (node->type) {
339 case WEBIDL_NODE_TYPE_ROOT:
340 case WEBIDL_NODE_TYPE_INTERFACE:
341 case WEBIDL_NODE_TYPE_DICTIONARY:
342 case WEBIDL_NODE_TYPE_LIST:
343 case WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE:
344 case WEBIDL_NODE_TYPE_ATTRIBUTE:
345 case WEBIDL_NODE_TYPE_OPERATION:
346 case WEBIDL_NODE_TYPE_OPTIONAL:
347 case WEBIDL_NODE_TYPE_ARGUMENT:
348 case WEBIDL_NODE_TYPE_TYPE:
349 case WEBIDL_NODE_TYPE_CONST:
350 return node->r.node;
351 default:
352 break;
353 }
354 }
355 return NULL;
356
357 }
358
359 /* exported interface defined in webidl-ast.h */
webidl_node_type_to_str(enum webidl_node_type type)360 static const char *webidl_node_type_to_str(enum webidl_node_type type)
361 {
362 switch(type) {
363 case WEBIDL_NODE_TYPE_ROOT:
364 return "root";
365
366 case WEBIDL_NODE_TYPE_IDENT:
367 return "Ident";
368
369 case WEBIDL_NODE_TYPE_INHERITANCE:
370 return "Inherit";
371
372 case WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS:
373 return "Implements";
374
375 case WEBIDL_NODE_TYPE_INTERFACE:
376 return "Interface";
377
378 case WEBIDL_NODE_TYPE_DICTIONARY:
379 return "Dictionary";
380
381 case WEBIDL_NODE_TYPE_LIST:
382 return "List";
383
384 case WEBIDL_NODE_TYPE_ATTRIBUTE:
385 return "Attribute";
386
387 case WEBIDL_NODE_TYPE_OPERATION:
388 return "Operation";
389
390 case WEBIDL_NODE_TYPE_OPTIONAL:
391 return "Optional";
392
393 case WEBIDL_NODE_TYPE_ARGUMENT:
394 return "Argument";
395
396 case WEBIDL_NODE_TYPE_ELLIPSIS:
397 return "Ellipsis";
398
399 case WEBIDL_NODE_TYPE_TYPE:
400 return "Type";
401
402 case WEBIDL_NODE_TYPE_TYPE_BASE:
403 return "Base";
404
405 case WEBIDL_NODE_TYPE_TYPE_NULLABLE:
406 return "Nullable";
407
408 case WEBIDL_NODE_TYPE_TYPE_ARRAY:
409 return "Array";
410
411 case WEBIDL_NODE_TYPE_MODIFIER:
412 return "Modifier";
413
414 case WEBIDL_NODE_TYPE_CONST:
415 return "Const";
416
417 case WEBIDL_NODE_TYPE_LITERAL_NULL:
418 return "Literal (null)";
419
420 case WEBIDL_NODE_TYPE_LITERAL_INT:
421 return "Literal (int)";
422
423 case WEBIDL_NODE_TYPE_LITERAL_BOOL:
424 return "Literal (bool)";
425
426 case WEBIDL_NODE_TYPE_LITERAL_FLOAT:
427 return "Literal (float)";
428
429 case WEBIDL_NODE_TYPE_LITERAL_STRING:
430 return "Literal (string)";
431
432 case WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE:
433 return "Extended Attribute";
434
435 case WEBIDL_NODE_TYPE_SPECIAL:
436 return "Special";
437
438 default:
439 return "Unknown";
440 }
441
442 }
443
444 /**
445 * dump an integer node type
446 */
447 static int
webidl_ast_dump_int(FILE * dumpf,struct webidl_node * node)448 webidl_ast_dump_int(FILE *dumpf, struct webidl_node *node)
449 {
450 switch(node->type) {
451 case WEBIDL_NODE_TYPE_MODIFIER:
452 switch (node->r.number) {
453 case WEBIDL_TYPE_MODIFIER_NONE:
454 fprintf(dumpf, ": none\n");
455 break;
456
457 case WEBIDL_TYPE_MODIFIER_UNSIGNED:
458 fprintf(dumpf, ": unsigned\n");
459 break;
460
461 case WEBIDL_TYPE_MODIFIER_UNRESTRICTED:
462 fprintf(dumpf, ": unrestricted\n");
463 break;
464
465 case WEBIDL_TYPE_MODIFIER_READONLY:
466 fprintf(dumpf, ": readonly\n");
467 break;
468
469 case WEBIDL_TYPE_MODIFIER_STATIC:
470 fprintf(dumpf, ": static\n");
471 break;
472
473 case WEBIDL_TYPE_MODIFIER_INHERIT:
474 fprintf(dumpf, ": inherit\n");
475 break;
476
477 default:
478 fprintf(dumpf, ": %d\n", node->r.number);
479 break;
480 }
481 break;
482
483 case WEBIDL_NODE_TYPE_TYPE_BASE:
484 fprintf(dumpf, ": %s\n",
485 webidl_type_to_str(WEBIDL_TYPE_MODIFIER_NONE,
486 node->r.number));
487 break;
488
489 case WEBIDL_NODE_TYPE_SPECIAL:
490 switch (node->r.number) {
491 case WEBIDL_TYPE_SPECIAL_GETTER:
492 fprintf(dumpf, ": getter\n");
493 break;
494
495 case WEBIDL_TYPE_SPECIAL_SETTER:
496 fprintf(dumpf, ": setter\n");
497 break;
498
499 case WEBIDL_TYPE_SPECIAL_CREATOR:
500 fprintf(dumpf, ": creator\n");
501 break;
502
503 case WEBIDL_TYPE_SPECIAL_DELETER:
504 fprintf(dumpf, ": deleter\n");
505 break;
506
507 case WEBIDL_TYPE_SPECIAL_LEGACYCALLER:
508 fprintf(dumpf, ": legacy caller\n");
509 break;
510
511 default:
512 fprintf(dumpf, ": %d\n", node->r.number);
513 break;
514 }
515 break;
516
517 case WEBIDL_NODE_TYPE_LITERAL_BOOL:
518 if (node->r.number == 0) {
519 fprintf(dumpf, ": false\n");
520 } else {
521 fprintf(dumpf, ": true\n");
522 }
523 break;
524
525 case WEBIDL_NODE_TYPE_LITERAL_INT:
526 fprintf(dumpf, ": %d\n", node->r.number);
527 break;
528
529 default:
530 /* no value */
531 fprintf(dumpf, "\n");
532 break;
533 }
534
535 return 0;
536 }
537
538 /**
539 * Recursively dump the AST nodes increasing indent as appropriate
540 */
webidl_ast_dump(FILE * dumpf,struct webidl_node * node,int indent)541 static int webidl_ast_dump(FILE *dumpf, struct webidl_node *node, int indent)
542 {
543 const char *SPACES=" ";
544 char *txt;
545 while (node != NULL) {
546 fprintf(dumpf, "%.*s%s", indent, SPACES,
547 webidl_node_type_to_str(node->type));
548
549 txt = webidl_node_gettext(node);
550 if (txt == NULL) {
551 struct webidl_node *next;
552
553 next = webidl_node_getnode(node);
554
555 if (next != NULL) {
556 fprintf(dumpf, "\n");
557 webidl_ast_dump(dumpf, next, indent + 2);
558 } else {
559 /* not txt or node try an int */
560 webidl_ast_dump_int(dumpf, node);
561 }
562 } else {
563 fprintf(dumpf, ": \"%s\"\n", txt);
564 }
565 node = node->l;
566 }
567 return 0;
568 }
569
570 /* exported interface documented in webidl-ast.h */
webidl_dump_ast(struct webidl_node * node)571 int webidl_dump_ast(struct webidl_node *node)
572 {
573 FILE *dumpf;
574
575 /* only dump AST to file if required */
576 if (!options->debug) {
577 return 0;
578 }
579
580 dumpf = genb_fopen("webidl-ast", "w");
581 if (dumpf == NULL) {
582 return 2;
583 }
584
585 webidl_ast_dump(dumpf, node, 0);
586
587 fclose(dumpf);
588
589 return 0;
590 }
591
592 /* exported interface defined in webidl-ast.h */
idlopen(const char * filename)593 static FILE *idlopen(const char *filename)
594 {
595 FILE *idlfile;
596 char *fullname;
597 int fulllen;
598
599 if (options->idlpath == NULL) {
600 if (options->verbose) {
601 printf("Opening IDL file %s\n", filename);
602 }
603 return fopen(filename, "r");
604 }
605
606 fulllen = strlen(options->idlpath) + strlen(filename) + 2;
607 fullname = malloc(fulllen);
608 snprintf(fullname, fulllen, "%s/%s", options->idlpath, filename);
609 if (options->verbose) {
610 printf("Opening IDL file %s\n", fullname);
611 }
612 idlfile = fopen(fullname, "r");
613 free(fullname);
614
615 return idlfile;
616 }
617
618 /* exported interface defined in webidl-ast.h */
webidl_parsefile(char * filename,struct webidl_node ** webidl_ast)619 int webidl_parsefile(char *filename, struct webidl_node **webidl_ast)
620 {
621 FILE *idlfile;
622 int ret;
623
624 idlfile = idlopen(filename);
625 if (!idlfile) {
626 fprintf(stderr, "Error opening %s: %s\n",
627 filename,
628 strerror(errno));
629 return 2;
630 }
631
632 /* if debugging enabled enable parser tracing and send to file */
633 if (options->debug) {
634 char *tracename;
635 int tracenamelen;
636 webidl_debug = 1;
637 webidl__flex_debug = 1;
638
639 tracenamelen = SLEN("webidl--trace") + strlen(filename) + 1;
640 tracename = malloc(tracenamelen);
641 snprintf(tracename, tracenamelen,"webidl-%s-trace", filename);
642 webidl_parsetracef = genb_fopen(tracename, "w");
643 free(tracename);
644 } else {
645 webidl_parsetracef = NULL;
646 }
647
648 /* set flex to read from file */
649 webidl_restart(idlfile);
650
651 /* parse the file */
652 ret = webidl_parse(webidl_ast);
653
654 /* close tracefile if open */
655 if (webidl_parsetracef != NULL) {
656 fclose(webidl_parsetracef);
657 }
658 return ret;
659 }
660
661 /* exported interface defined in webidl-ast.h */
webidl_fprintf(FILE * stream,const char * format,...)662 int webidl_fprintf(FILE *stream, const char *format, ...)
663 {
664 va_list ap;
665 int ret;
666
667 va_start(ap, format);
668
669 if (webidl_parsetracef == NULL) {
670 ret = vfprintf(stream, format, ap);
671 } else {
672 ret = vfprintf(webidl_parsetracef, format, ap);
673 }
674 va_end(ap);
675
676 return ret;
677 }
678
679 /* unlink a child node from a parent */
680 static int
webidl_unlink(struct webidl_node * parent,struct webidl_node * node)681 webidl_unlink(struct webidl_node *parent, struct webidl_node *node)
682 {
683 struct webidl_node *child;
684
685 child = webidl_node_getnode(parent);
686 if (child == NULL) {
687 /* parent does not have children to remove node from */
688 return -1;
689 }
690
691 if (child == node) {
692 /* parent is pointing at the node we want to remove */
693 parent->r.node = node->l; /* point parent at next sibing */
694 node->l = NULL;
695 return 0;
696 }
697
698 while (child->l != NULL) {
699 if (child->l == node) {
700 /* found node, unlink from list */
701 child->l = node->l;
702 node->l = NULL;
703 return 0;
704 }
705 child = child->l;
706 }
707 return -1; /* failed to remove node */
708 }
709
implements_copy_nodes(struct webidl_node * src_node,struct webidl_node * dst_node)710 static int implements_copy_nodes(struct webidl_node *src_node,
711 struct webidl_node *dst_node)
712 {
713 struct webidl_node *src;
714 struct webidl_node *dst;
715
716 src = webidl_node_getnode(src_node);
717 dst = webidl_node_getnode(dst_node);
718
719 while (src != NULL) {
720 if (src->type == WEBIDL_NODE_TYPE_LIST) {
721 /** @todo technicaly this should copy WEBIDL_NODE_TYPE_INHERITANCE */
722 dst = webidl_node_new(src->type, dst, src->r.text);
723 }
724 src = src->l;
725 }
726
727 dst_node->r.node = dst;
728
729 return 0;
730 }
731
732 static int
intercalate_implements(struct webidl_node * interface_node,void * ctx)733 intercalate_implements(struct webidl_node *interface_node, void *ctx)
734 {
735 struct webidl_node *implements_node;
736 struct webidl_node *implements_interface_node;
737 struct webidl_node *webidl_ast = ctx;
738
739 implements_node = webidl_node_find_type(
740 webidl_node_getnode(interface_node),
741 NULL,
742 WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS);
743 while (implements_node != NULL) {
744
745 implements_interface_node = webidl_node_find_type_ident(
746 webidl_ast,
747 WEBIDL_NODE_TYPE_INTERFACE,
748 webidl_node_gettext(implements_node));
749
750 /* recurse, ensuring all subordinate interfaces have
751 * their implements intercalated first
752 */
753 intercalate_implements(implements_interface_node, webidl_ast);
754
755 implements_copy_nodes(implements_interface_node, interface_node);
756
757 /* once we have copied the implemntation remove entry */
758 webidl_unlink(interface_node, implements_node);
759
760 implements_node = webidl_node_find_type(
761 webidl_node_getnode(interface_node),
762 implements_node,
763 WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS);
764 }
765 return 0;
766 }
767
768 /* exported interface defined in webidl-ast.h */
webidl_intercalate_implements(struct webidl_node * webidl_ast)769 int webidl_intercalate_implements(struct webidl_node *webidl_ast)
770 {
771 int res = 0;
772 if (webidl_ast != NULL) {
773 /* for each interface:
774 * for each implements entry:
775 * find interface from implemets
776 * recusrse into that interface
777 * copy the interface into this one
778 */
779 res = webidl_node_for_each_type(webidl_ast,
780 WEBIDL_NODE_TYPE_INTERFACE,
781 intercalate_implements,
782 webidl_ast);
783 }
784 return res;
785 }
786
787 /* exported interface defined in webidl-ast.h */
webidl_type_to_str(enum webidl_type_modifier m,enum webidl_type t)788 const char *webidl_type_to_str(enum webidl_type_modifier m, enum webidl_type t)
789 {
790 switch (t) {
791 case WEBIDL_TYPE_ANY: /**< 0 - The type is unconstrained */
792 return "any";
793
794 case WEBIDL_TYPE_USER: /**< 1 - The type is a dictionary or interface */
795 return "user";
796
797 case WEBIDL_TYPE_BOOL: /**< 2 - The type is boolean */
798 return "boolean";
799
800 case WEBIDL_TYPE_BYTE: /**< 3 - The type is a byte */
801 return "byte";
802
803 case WEBIDL_TYPE_OCTET: /**< 4 - The type is a octet */
804 return "octet";
805
806 case WEBIDL_TYPE_FLOAT: /**< 5 - The type is a float point number */
807 return "float";
808
809 case WEBIDL_TYPE_DOUBLE: /**< 6 - The type is a double */
810 return "double";
811
812 case WEBIDL_TYPE_SHORT: /**< 7 - The type is a signed 16bit */
813 if (m == WEBIDL_TYPE_MODIFIER_UNSIGNED) {
814 return "unsigned short";
815 } else {
816 return "short";
817 }
818
819 case WEBIDL_TYPE_LONG: /**< 8 - The type is a signed 32bit */
820 if (m == WEBIDL_TYPE_MODIFIER_UNSIGNED) {
821 return "unsigned long";
822 } else {
823 return "long";
824 }
825
826 case WEBIDL_TYPE_LONGLONG: /**< 9 - The type is a signed 64bit */
827 return "long long";
828
829 case WEBIDL_TYPE_STRING: /**< 10 - The type is a string */
830 return "string";
831
832 case WEBIDL_TYPE_SEQUENCE: /**< 11 - The type is a sequence */
833 return "sequence";
834
835 case WEBIDL_TYPE_OBJECT: /**< 12 - The type is a object */
836 return "object";
837
838 case WEBIDL_TYPE_DATE: /**< 13 - The type is a date */
839 return "date";
840
841 case WEBIDL_TYPE_VOID: /**< 14 - The type is void */
842 return "void";
843 }
844 return "Unknown";
845 }
846