1 /**************************************************************************
2
3 util.c
4
5 Copyright (C) 1998, 1999 Andrew T. Veliath
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public
18 License along with this library; if not, write to the Free
19 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 $Id$
22
23 ***************************************************************************/
24 #include <assert.h>
25 #include <stdarg.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <ctype.h>
29 #include <string.h>
30 #include <errno.h>
31 #ifdef HAVE_UNISTD_H
32 # include <unistd.h>
33 #endif
34
35 #include "rename.h"
36 #include "util.h"
37
38 #ifdef G_OS_WIN32
39 #include <fcntl.h>
40 #include <direct.h>
41 #define popen _popen
42 #define pclose _pclose
43 #endif
44
45 const char *IDL_tree_type_names[] = {
46 "IDLN_NONE",
47 "IDLN_ANY",
48 "IDLN_LIST",
49 "IDLN_GENTREE",
50 "IDLN_INTEGER",
51 "IDLN_STRING",
52 "IDLN_WIDE_STRING",
53 "IDLN_CHAR",
54 "IDLN_WIDE_CHAR",
55 "IDLN_FIXED",
56 "IDLN_FLOAT",
57 "IDLN_BOOLEAN",
58 "IDLN_IDENT",
59 "IDLN_TYPE_DCL",
60 "IDLN_CONST_DCL",
61 "IDLN_EXCEPT_DCL",
62 "IDLN_ATTR_DCL",
63 "IDLN_OP_DCL",
64 "IDLN_PARAM_DCL",
65 "IDLN_FORWARD_DCL",
66 "IDLN_TYPE_INTEGER",
67 "IDLN_TYPE_FLOAT",
68 "IDLN_TYPE_FIXED",
69 "IDLN_TYPE_CHAR",
70 "IDLN_TYPE_WIDE_CHAR",
71 "IDLN_TYPE_STRING",
72 "IDLN_TYPE_WIDE_STRING",
73 "IDLN_TYPE_BOOLEAN",
74 "IDLN_TYPE_OCTET",
75 "IDLN_TYPE_ANY",
76 "IDLN_TYPE_OBJECT",
77 "IDLN_TYPE_TYPECODE",
78 "IDLN_TYPE_ENUM",
79 "IDLN_TYPE_SEQUENCE",
80 "IDLN_TYPE_ARRAY",
81 "IDLN_TYPE_STRUCT",
82 "IDLN_TYPE_UNION",
83 "IDLN_MEMBER",
84 "IDLN_NATIVE",
85 "IDLN_CASE_STMT",
86 "IDLN_INTERFACE",
87 "IDLN_MODULE",
88 "IDLN_BINOP",
89 "IDLN_UNARYOP",
90 "IDLN_CODEFRAG",
91 /* IDLN_LAST */
92 };
93
94 int __IDL_check_type_casts = FALSE;
95 #ifndef HAVE_CPP_PIPE_STDIN
96 const char * __IDL_tmp_filename = NULL;
97 #endif
98 const char * __IDL_real_filename = NULL;
99 char * __IDL_cur_filename = NULL;
100 int __IDL_cur_line;
101 GHashTable * __IDL_filename_hash;
102 IDL_fileinfo * __IDL_cur_fileinfo;
103 GHashTable * __IDL_structunion_ht;
104 int __IDL_inhibits;
105 int __IDL_typecodes_as_tok;
106 int __IDL_pidl;
107 IDL_tree __IDL_root;
108 IDL_ns __IDL_root_ns;
109 int __IDL_is_okay;
110 int __IDL_is_parsing;
111 unsigned long __IDL_flags;
112 unsigned long __IDL_flagsi;
113 gpointer __IDL_inputcb_user_data;
114 IDL_input_callback __IDL_inputcb;
115 GSList * __IDL_new_ident_comments;
116 static int __IDL_max_msg_level;
117 static int __IDL_nerrors, __IDL_nwarnings;
118 static IDL_msg_callback __IDL_msgcb;
119
120 /* Case-insensitive version of g_str_hash */
IDL_strcase_hash(gconstpointer v)121 guint IDL_strcase_hash (gconstpointer v)
122 {
123 const char *p;
124 guint h = 0, g;
125
126 for (p = (char *) v; *p != '\0'; ++p) {
127 h = (h << 4) + isupper ((int)*p) ? tolower (*p) : *p;
128 if ((g = h & 0xf0000000)) {
129 h = h ^ (g >> 24);
130 h = h ^ g;
131 }
132 }
133
134 return h /* % M */;
135 }
136
IDL_strcase_equal(gconstpointer a,gconstpointer b)137 gint IDL_strcase_equal (gconstpointer a, gconstpointer b)
138 {
139 return g_ascii_strcasecmp (a, b) == 0;
140 }
141
IDL_strcase_cmp(gconstpointer a,gconstpointer b)142 gint IDL_strcase_cmp (gconstpointer a, gconstpointer b)
143 {
144 return g_ascii_strcasecmp (a, b);
145 }
146
my_strcmp(IDL_tree p,IDL_tree q)147 static int my_strcmp (IDL_tree p, IDL_tree q)
148 {
149 const char *a = IDL_IDENT (p).str;
150 const char *b = IDL_IDENT (q).str;
151 int cmp = IDL_strcase_cmp (a, b);
152
153 if (__IDL_is_parsing &&
154 cmp == 0 &&
155 strcmp (a, b) != 0 &&
156 !(IDL_IDENT (p)._flags & IDLF_IDENT_CASE_MISMATCH_HIT ||
157 IDL_IDENT (q)._flags & IDLF_IDENT_CASE_MISMATCH_HIT)) {
158 IDL_tree_warning (p, IDL_WARNING1, "Case mismatch between `%s'", a);
159 IDL_tree_warning (q, IDL_WARNING1, "and `%s'", b);
160 yywarning (IDL_WARNING1,
161 "(Identifiers should be case-consistent after initial declaration)");
162 IDL_IDENT (p)._flags |= IDLF_IDENT_CASE_MISMATCH_HIT;
163 IDL_IDENT (q)._flags |= IDLF_IDENT_CASE_MISMATCH_HIT;
164 }
165
166 return cmp;
167 }
168
IDL_ident_hash(gconstpointer v)169 guint IDL_ident_hash (gconstpointer v)
170 {
171 return IDL_strcase_hash (IDL_IDENT ((IDL_tree) v).str);
172 }
173
IDL_ident_equal(gconstpointer a,gconstpointer b)174 gint IDL_ident_equal (gconstpointer a, gconstpointer b)
175 {
176 return my_strcmp ((IDL_tree) a, (IDL_tree) b) == 0;
177 }
178
IDL_ident_cmp(gconstpointer a,gconstpointer b)179 gint IDL_ident_cmp (gconstpointer a, gconstpointer b)
180 {
181 return my_strcmp ((IDL_tree) a, (IDL_tree) b);
182 }
183
IDL_get_libver_string(void)184 const char *IDL_get_libver_string (void)
185 {
186 return LIBIDL_VERSION;
187 }
188
IDL_get_IDLver_string(void)189 const char *IDL_get_IDLver_string (void)
190 {
191 return "2.2";
192 }
193
IDL_tree_optimize(IDL_tree * p,IDL_ns ns)194 static void IDL_tree_optimize (IDL_tree *p, IDL_ns ns)
195 {
196 if (!(__IDL_flags & IDLF_IGNORE_FORWARDS))
197 IDL_tree_process_forward_dcls (p, ns);
198 if (!(__IDL_flags & IDLF_INHIBIT_TAG_ONLY))
199 IDL_tree_remove_inhibits (p, ns);
200 IDL_tree_remove_empty_modules (p, ns);
201 }
202
IDL_parse_setup(unsigned long parse_flags,int max_msg_level)203 static void IDL_parse_setup(unsigned long parse_flags, int max_msg_level) {
204 if (parse_flags & IDLF_XPIDL)
205 parse_flags |= IDLF_PROPERTIES;
206
207 __IDL_max_msg_level = max_msg_level;
208 __IDL_nerrors = __IDL_nwarnings = 0;
209 __IDL_inhibits = 0;
210 __IDL_typecodes_as_tok = (parse_flags & IDLF_TYPECODES) ? 1 : 0;
211 __IDL_pidl = (parse_flags & IDLF_XPIDL) ? 1 : 0;
212 __IDL_flags = parse_flags;
213 __IDL_flagsi = 0;
214 __IDL_is_parsing = TRUE;
215 __IDL_is_okay = TRUE;
216 __IDL_new_ident_comments = NULL;
217 }
218
IDL_parse_filename(const char * filename,const char * cpp_args,IDL_msg_callback msg_cb,IDL_tree * tree,IDL_ns * ns,unsigned long parse_flags,int max_msg_level)219 int IDL_parse_filename (const char *filename, const char *cpp_args,
220 IDL_msg_callback msg_cb, IDL_tree *tree, IDL_ns *ns,
221 unsigned long parse_flags, int max_msg_level)
222 {
223 extern void __IDL_lex_init (void);
224 extern void __IDL_lex_cleanup (void);
225 extern int yyparse (void);
226 extern FILE *__IDL_in;
227 FILE *input;
228 char *cmd;
229 #ifdef HAVE_CPP_PIPE_STDIN
230 char *fmt = CPP_PROGRAM " - %s%s %s < \"%s\" %s";
231 char *wd;
232 #else
233 char *fmt = CPP_PROGRAM " -I%s %s \"%s\" %s";
234 char cwd[2048];
235 #ifdef HAVE_SYMLINK
236 char *s, *tmpfilename;
237 gchar *linkto;
238 #else
239 const char *tmpfilename;
240 #endif
241 #endif
242
243 #ifndef G_OS_WIN32
244 char *cpperrs = (parse_flags & IDLF_SHOW_CPP_ERRORS)
245 ? "" : "2>/dev/null";
246 #else
247 char *cpperrs = "";
248 #endif
249 GSList *slist;
250 int rv;
251
252 #if 0 && defined(YYDEBUG)
253 {
254 extern int __IDL_debug;
255 __IDL_debug = 1;
256 }
257 #endif
258
259 if (!filename || !tree) {
260 errno = EINVAL;
261 return -1;
262 }
263
264 #ifdef HAVE_ACCESS
265 if (access (filename, R_OK))
266 return -1;
267 #endif
268
269 #ifdef HAVE_CPP_PIPE_STDIN
270 wd = g_path_get_dirname (filename);
271
272 cmd = g_strdup_printf (fmt, "-I", wd, cpp_args ? cpp_args : "",
273 filename, cpperrs);
274
275 g_free (wd);
276 #else
277 if (!getcwd (cwd, sizeof (cwd)))
278 return -1;
279
280 #ifdef HAVE_SYMLINK
281 s = tmpnam (NULL);
282 if (s == NULL)
283 return -1;
284
285 if (g_path_is_absolute (filename)) {
286 linkto = g_strdup (filename);
287 } else {
288 linkto = g_strconcat (cwd, "/", filename, NULL);
289 }
290
291 tmpfilename = g_strconcat (s, ".c", NULL);
292
293 if (symlink (linkto, tmpfilename) < 0) {
294 g_free (linkto);
295 g_free (tmpfilename);
296 return -1;
297 }
298 g_free (linkto);
299 #else
300 tmpfilename = filename;
301 #endif
302
303 cmd = g_strdup_printf (fmt, cwd, cpp_args ? cpp_args : "",
304 tmpfilename, cpperrs);
305 #endif
306
307 /* Many versions of cpp do evil translating internal
308 * strings, producing bogus output, so clobber LC_ALL */
309 putenv ("LC_ALL=C");
310
311 #ifdef HAVE_POPEN
312 #if defined (G_OS_WIN32) && !defined (_MSC_VER)
313 if (!(parse_flags & IDLF_SHOW_CPP_ERRORS)) {
314 int save_stderr = dup (2);
315 int null = open ("NUL:", O_WRONLY);
316 dup2 (null, 2);
317 input = popen (cmd, "r");
318 close (2);
319 close (null);
320 dup2 (save_stderr, 2);
321 close (save_stderr);
322 } else
323 input = popen (cmd, "r");
324 #else
325 input = popen (cmd, "r");
326 #endif
327 #else
328 #error Must have popen
329 #endif
330 g_free (cmd);
331
332 if (input == NULL || ferror (input)) {
333 #if !defined (HAVE_CPP_PIPE_STDIN) && defined (HAVE_SYMLINK)
334 g_free (tmpfilename);
335 #endif
336 return IDL_ERROR;
337 }
338
339 IDL_parse_setup(parse_flags, max_msg_level);
340
341 __IDL_in = input;
342 __IDL_msgcb = msg_cb;
343 __IDL_root_ns = IDL_ns_new ();
344 __IDL_lex_init ();
345
346 __IDL_real_filename = filename;
347 #ifndef HAVE_CPP_PIPE_STDIN
348 __IDL_tmp_filename = tmpfilename;
349 #endif
350 __IDL_filename_hash = IDL_NS (__IDL_root_ns).filename_hash;
351 __IDL_structunion_ht = g_hash_table_new (g_direct_hash, g_direct_equal);
352 rv = yyparse ();
353 g_hash_table_destroy (__IDL_structunion_ht);
354 __IDL_is_parsing = FALSE;
355 __IDL_lex_cleanup ();
356 __IDL_parser_reset ();
357 __IDL_real_filename = NULL;
358 #ifndef HAVE_CPP_PIPE_STDIN
359 __IDL_tmp_filename = NULL;
360 #endif
361 #ifdef HAVE_POPEN
362 pclose (input);
363 #else
364 fclose (input);
365 #endif
366 #if !defined (HAVE_CPP_PIPE_STDIN) && defined (HAVE_SYMLINK)
367 unlink (tmpfilename);
368 g_free (tmpfilename);
369 #endif
370 for (slist = __IDL_new_ident_comments; slist; slist = slist->next)
371 g_free (slist->data);
372 g_slist_free (__IDL_new_ident_comments);
373
374 if (__IDL_root != NULL) {
375 IDL_tree_optimize (&__IDL_root, __IDL_root_ns);
376
377 if (__IDL_root == NULL)
378 yyerror ("File empty after optimization");
379 }
380
381 __IDL_msgcb = NULL;
382
383 if (rv != 0 || !__IDL_is_okay) {
384 *tree = NULL;
385
386 if (ns)
387 *ns = NULL;
388
389 return IDL_ERROR;
390 }
391
392 if (__IDL_flags & IDLF_PREFIX_FILENAME)
393 IDL_ns_prefix (__IDL_root_ns, filename);
394
395 *tree = __IDL_root;
396
397 if (ns)
398 *ns = __IDL_root_ns;
399 else
400 IDL_ns_free (__IDL_root_ns);
401
402 return IDL_SUCCESS;
403 }
404
IDL_parse_filename_with_input(const char * filename,IDL_input_callback input_cb,gpointer input_cb_user_data,IDL_msg_callback msg_cb,IDL_tree * tree,IDL_ns * ns,unsigned long parse_flags,int max_msg_level)405 int IDL_parse_filename_with_input (const char *filename,
406 IDL_input_callback input_cb,
407 gpointer input_cb_user_data,
408 IDL_msg_callback msg_cb,
409 IDL_tree *tree, IDL_ns *ns,
410 unsigned long parse_flags,
411 int max_msg_level)
412 {
413 extern void __IDL_lex_init (void);
414 extern void __IDL_lex_cleanup (void);
415 extern int yyparse (void);
416 union IDL_input_data data;
417 GSList *slist;
418 int rv;
419
420 if (!filename || !input_cb || !tree) {
421 errno = EINVAL;
422 return -1;
423 }
424
425 IDL_parse_setup(parse_flags, max_msg_level);
426
427 __IDL_msgcb = msg_cb;
428 __IDL_root_ns = IDL_ns_new ();
429
430 __IDL_lex_init ();
431 __IDL_inputcb = input_cb;
432 __IDL_inputcb_user_data = input_cb_user_data;
433
434 __IDL_real_filename = filename;
435 #ifndef HAVE_CPP_PIPE_STDIN
436 __IDL_tmp_filename = NULL;
437 #endif
438 __IDL_filename_hash = IDL_NS (__IDL_root_ns).filename_hash;
439 data.init.filename = filename;
440 if ((*__IDL_inputcb) (
441 IDL_INPUT_REASON_INIT, &data, __IDL_inputcb_user_data)) {
442 IDL_ns_free (__IDL_root_ns);
443 __IDL_lex_cleanup ();
444 __IDL_real_filename = NULL;
445 return -1;
446 }
447 __IDL_structunion_ht = g_hash_table_new (g_direct_hash, g_direct_equal);
448 rv = yyparse ();
449 g_hash_table_destroy (__IDL_structunion_ht);
450 __IDL_is_parsing = FALSE;
451 __IDL_lex_cleanup ();
452 __IDL_parser_reset ();
453 __IDL_real_filename = NULL;
454 for (slist = __IDL_new_ident_comments; slist; slist = slist->next)
455 g_free (slist->data);
456 g_slist_free (__IDL_new_ident_comments);
457
458 if (__IDL_root != NULL) {
459 IDL_tree_optimize (&__IDL_root, __IDL_root_ns);
460
461 if (__IDL_root == NULL)
462 yyerror ("File empty after optimization");
463 }
464
465 __IDL_msgcb = NULL;
466
467 if (rv != 0 || !__IDL_is_okay) {
468 *tree = NULL;
469
470 if (ns)
471 *ns = NULL;
472
473 (*__IDL_inputcb) (
474 IDL_INPUT_REASON_ABORT, NULL, __IDL_inputcb_user_data);
475
476 return IDL_ERROR;
477 }
478
479 (*__IDL_inputcb) (IDL_INPUT_REASON_FINISH, NULL, __IDL_inputcb_user_data);
480
481 if (__IDL_flags & IDLF_PREFIX_FILENAME)
482 IDL_ns_prefix (__IDL_root_ns, filename);
483
484 *tree = __IDL_root;
485
486 if (ns)
487 *ns = __IDL_root_ns;
488 else
489 IDL_ns_free (__IDL_root_ns);
490
491 return IDL_SUCCESS;
492 }
493
yyerrorl(const char * s,int ofs)494 void yyerrorl (const char *s, int ofs)
495 {
496 int line = __IDL_cur_line - 1 + ofs;
497 gchar *freeme = NULL, *filename = NULL;
498
499 if (__IDL_cur_filename) {
500 #ifdef HAVE_CPP_PIPE_STDIN
501 filename = __IDL_cur_filename;
502 #else
503 freeme = filename = g_path_get_basename (__IDL_cur_filename);
504 #endif
505 } else
506 line = -1;
507
508 ++__IDL_nerrors;
509 __IDL_is_okay = FALSE;
510
511 /* Errors are counted, even if not printed */
512 if (__IDL_max_msg_level < IDL_ERROR) {
513 g_free (freeme);
514 return;
515 }
516
517 if (__IDL_msgcb)
518 (*__IDL_msgcb)(IDL_ERROR, __IDL_nerrors, line, filename, s);
519 else {
520 if (line > 0)
521 fprintf (stderr, "%s:%d: Error: %s\n", filename, line, s);
522 else
523 fprintf (stderr, "Error: %s\n", s);
524 }
525 g_free (freeme);
526 }
527
yywarningl(int level,const char * s,int ofs)528 void yywarningl (int level, const char *s, int ofs)
529 {
530 int line = __IDL_cur_line - 1 + ofs;
531 gchar *freeme = NULL, *filename = NULL;
532
533 /* Unprinted warnings are not counted */
534 if (__IDL_max_msg_level < level)
535 return;
536
537 if (__IDL_cur_filename) {
538 #ifdef HAVE_CPP_PIPE_STDIN
539 filename = __IDL_cur_filename;
540 #else
541 freeme = filename = g_path_get_basename (__IDL_cur_filename);
542 #endif
543 } else
544 line = -1;
545
546 ++__IDL_nwarnings;
547
548 if (__IDL_msgcb)
549 (*__IDL_msgcb)(level, __IDL_nwarnings, line, filename, s);
550 else {
551 if (line > 0)
552 fprintf (stderr, "%s:%d: Warning: %s\n", filename, line, s);
553 else
554 fprintf (stderr, "Warning: %s\n", s);
555 }
556 g_free (freeme);
557 }
558
yyerror(const char * s)559 void yyerror (const char *s)
560 {
561 yyerrorl (s, 0);
562 }
563
yywarning(int level,const char * s)564 void yywarning (int level, const char *s)
565 {
566 yywarningl (level, s, 0);
567 }
568
yyerrorlv(const char * fmt,int ofs,...)569 void yyerrorlv (const char *fmt, int ofs, ...)
570 {
571 gchar *msg;
572 va_list args;
573
574 va_start (args, ofs);
575
576 msg = g_strdup_vprintf (fmt, args);
577 yyerrorl (msg, ofs);
578
579 va_end (args);
580
581 g_free (msg);
582 }
583
yywarninglv(int level,const char * fmt,int ofs,...)584 void yywarninglv (int level, const char *fmt, int ofs, ...)
585 {
586 gchar *msg;
587 va_list args;
588
589 va_start (args, ofs);
590
591 msg = g_strdup_vprintf (fmt, args);
592 yywarningl (level, msg, ofs);
593
594 va_end (args);
595
596 g_free (msg);
597 }
598
yyerrorv(const char * fmt,...)599 void yyerrorv (const char *fmt, ...)
600 {
601 gchar *msg;
602 va_list args;
603
604 va_start (args, fmt);
605
606 msg = g_strdup_vprintf (fmt, args);
607 yyerror (msg);
608
609 va_end (args);
610
611 g_free (msg);
612 }
613
yywarningv(int level,const char * fmt,...)614 void yywarningv (int level, const char *fmt, ...)
615 {
616 gchar *msg;
617 va_list args;
618
619 va_start (args, fmt);
620
621 msg = g_strdup_vprintf (fmt, args);
622 yywarning (level, msg);
623
624 va_end (args);
625
626 g_free (msg);
627 }
628
IDL_tree_error(IDL_tree p,const char * fmt,...)629 void IDL_tree_error (IDL_tree p, const char *fmt, ...)
630 {
631 char *file_save = __IDL_cur_filename;
632 int line_save = __IDL_cur_line;
633 gchar *msg;
634 va_list args;
635
636 if (p) {
637 __IDL_cur_filename = p->_file;
638 __IDL_cur_line = p->_line;
639 } else {
640 __IDL_cur_filename = NULL;
641 __IDL_cur_line = -1;
642 }
643
644 va_start (args, fmt);
645
646 msg = g_strdup_vprintf (fmt, args);
647 yyerror (msg);
648
649 va_end (args);
650
651 g_free (msg);
652
653 __IDL_cur_filename = file_save;
654 __IDL_cur_line = line_save;
655 }
656
IDL_tree_warning(IDL_tree p,int level,const char * fmt,...)657 void IDL_tree_warning (IDL_tree p, int level, const char *fmt, ...)
658 {
659 char *file_save = __IDL_cur_filename;
660 int line_save = __IDL_cur_line;
661 gchar *msg;
662 va_list args;
663
664 if (p) {
665 __IDL_cur_filename = p->_file;
666 __IDL_cur_line = p->_line;
667 } else {
668 __IDL_cur_filename = NULL;
669 __IDL_cur_line = -1;
670 }
671
672 va_start (args, fmt);
673
674 msg = g_strdup_vprintf (fmt, args);
675 yywarning (level, msg);
676
677 va_end (args);
678
679 g_free (msg);
680
681 __IDL_cur_filename = file_save;
682 __IDL_cur_line = line_save;
683 }
684
IDL_tree_get_node_info(IDL_tree p,char ** what,char ** who)685 int IDL_tree_get_node_info (IDL_tree p, char **what, char **who)
686 {
687 int dienow = 0;
688
689 assert (what != NULL);
690 assert (who != NULL);
691
692 switch (IDL_NODE_TYPE (p)) {
693 case IDLN_TYPE_STRUCT:
694 *what = "structure definition";
695 *who = IDL_IDENT (IDL_TYPE_STRUCT (p).ident).str;
696 break;
697
698 case IDLN_TYPE_UNION:
699 *what = "union definition";
700 *who = IDL_IDENT (IDL_TYPE_UNION (p).ident).str;
701 break;
702
703 case IDLN_TYPE_ARRAY:
704 *what = "array";
705 *who = IDL_IDENT (IDL_TYPE_ARRAY (p).ident).str;
706 break;
707
708 case IDLN_TYPE_ENUM:
709 *what = "enumeration definition";
710 *who = IDL_IDENT (IDL_TYPE_ENUM (p).ident).str;
711 break;
712
713 case IDLN_IDENT:
714 *what = "identifier";
715 *who = IDL_IDENT (p).str;
716 break;
717
718 case IDLN_TYPE_DCL:
719 *what = "type definition";
720 assert (IDL_TYPE_DCL (p).dcls != NULL);
721 assert (IDL_NODE_TYPE (IDL_TYPE_DCL (p).dcls) == IDLN_LIST);
722 assert (IDL_LIST (IDL_TYPE_DCL (p).dcls)._tail != NULL);
723 assert (IDL_NODE_TYPE (IDL_LIST (IDL_TYPE_DCL (p).dcls)._tail) == IDLN_LIST);
724 *who = IDL_IDENT (IDL_LIST (IDL_LIST (IDL_TYPE_DCL (p).dcls)._tail).data).str;
725 break;
726
727 case IDLN_MEMBER:
728 *what = "member declaration";
729 assert (IDL_MEMBER (p).dcls != NULL);
730 assert (IDL_NODE_TYPE (IDL_MEMBER (p).dcls) == IDLN_LIST);
731 assert (IDL_LIST (IDL_MEMBER (p).dcls)._tail != NULL);
732 assert (IDL_NODE_TYPE (IDL_LIST (IDL_MEMBER (p).dcls)._tail) == IDLN_LIST);
733 *who = IDL_IDENT (IDL_LIST (IDL_LIST (IDL_MEMBER (p).dcls)._tail).data).str;
734 break;
735
736 case IDLN_NATIVE:
737 *what = "native declaration";
738 assert (IDL_NATIVE (p).ident != NULL);
739 assert (IDL_NODE_TYPE (IDL_NATIVE (p).ident) == IDLN_IDENT);
740 *who = IDL_IDENT (IDL_NATIVE (p).ident).str;
741 break;
742
743 case IDLN_LIST:
744 if (!IDL_LIST (p).data)
745 break;
746 dienow = IDL_tree_get_node_info (IDL_LIST (p).data, what, who);
747 break;
748
749 case IDLN_ATTR_DCL:
750 *what = "interface attribute";
751 assert (IDL_ATTR_DCL (p).simple_declarations != NULL);
752 assert (IDL_NODE_TYPE (IDL_ATTR_DCL (p).simple_declarations) == IDLN_LIST);
753 assert (IDL_LIST (IDL_ATTR_DCL (p).simple_declarations)._tail != NULL);
754 assert (IDL_NODE_TYPE (IDL_LIST (
755 IDL_ATTR_DCL (p).simple_declarations)._tail) == IDLN_LIST);
756 *who = IDL_IDENT (IDL_LIST (IDL_LIST (
757 IDL_ATTR_DCL (p).simple_declarations)._tail).data).str;
758 break;
759
760 case IDLN_PARAM_DCL:
761 *what = "operation parameter";
762 assert (IDL_PARAM_DCL (p).simple_declarator != NULL);
763 assert (IDL_NODE_TYPE (IDL_PARAM_DCL (p).simple_declarator) == IDLN_IDENT);
764 *who = IDL_IDENT (IDL_PARAM_DCL (p).simple_declarator).str;
765 break;
766
767 case IDLN_CONST_DCL:
768 *what = "constant declaration for";
769 *who = IDL_IDENT (IDL_CONST_DCL (p).ident).str;
770 break;
771
772 case IDLN_EXCEPT_DCL:
773 *what = "exception";
774 *who = IDL_IDENT (IDL_EXCEPT_DCL (p).ident).str;
775 break;
776
777 case IDLN_OP_DCL:
778 *what = "interface operation";
779 *who = IDL_IDENT (IDL_OP_DCL (p).ident).str;
780 break;
781
782 case IDLN_MODULE:
783 *what = "module";
784 *who = IDL_IDENT (IDL_MODULE (p).ident).str;
785 break;
786
787 case IDLN_FORWARD_DCL:
788 *what = "forward declaration";
789 *who = IDL_IDENT (IDL_FORWARD_DCL (p).ident).str;
790 break;
791
792 case IDLN_INTERFACE:
793 *what = "interface";
794 *who = IDL_IDENT (IDL_INTERFACE (p).ident).str;
795 break;
796
797 default:
798 g_warning ("Node type: %s\n", IDL_NODE_TYPE_NAME (p));
799 *what = "unknown (internal error)";
800 break;
801 }
802
803 return dienow;
804 }
805
IDL_node_new(IDL_tree_type type)806 static IDL_tree IDL_node_new (IDL_tree_type type)
807 {
808 IDL_tree p;
809
810 p = g_new0 (IDL_tree_node, 1);
811 if (p == NULL) {
812 yyerror ("IDL_node_new: memory exhausted");
813 return NULL;
814 }
815
816 IDL_NODE_TYPE (p) = type;
817 IDL_NODE_REFS (p) = 1;
818
819 p->_file = __IDL_cur_filename;
820 p->_line = __IDL_cur_line;
821
822 return p;
823 }
824
__IDL_assign_up_node(IDL_tree up,IDL_tree node)825 void __IDL_assign_up_node (IDL_tree up, IDL_tree node)
826 {
827 if (node == NULL)
828 return;
829
830 assert (node != up);
831
832 switch (IDL_NODE_TYPE (node)) {
833 case IDLN_LIST:
834 if (IDL_NODE_UP (node) == NULL)
835 for (; node != NULL; node = IDL_LIST (node).next)
836 IDL_NODE_UP (node) = up;
837 break;
838
839 default:
840 if (IDL_NODE_UP (node) == NULL)
841 IDL_NODE_UP (node) = up;
842 break;
843 }
844 }
845
__IDL_assign_location(IDL_tree node,IDL_tree from_node)846 void __IDL_assign_location (IDL_tree node, IDL_tree from_node)
847 {
848 assert (node != NULL);
849
850 if (from_node) {
851 node->_file = from_node->_file;
852 node->_line = from_node->_line;
853 }
854 }
855
__IDL_assign_this_location(IDL_tree node,char * filename,int line)856 void __IDL_assign_this_location (IDL_tree node, char *filename, int line)
857 {
858 assert (node != NULL);
859
860 node->_file = filename;
861 node->_line = line;
862 }
863
IDL_list_new(IDL_tree data)864 IDL_tree IDL_list_new (IDL_tree data)
865 {
866 IDL_tree p = IDL_node_new (IDLN_LIST);
867
868 __IDL_assign_up_node (p, data);
869 IDL_LIST (p).data = data;
870 IDL_LIST (p)._tail = p;
871
872 return p;
873 }
874
IDL_list_concat(IDL_tree orig,IDL_tree append)875 IDL_tree IDL_list_concat (IDL_tree orig, IDL_tree append)
876 {
877 IDL_tree p;
878
879 if (orig == NULL)
880 return append;
881
882 if (append == NULL)
883 return orig;
884
885 IDL_LIST (IDL_LIST (orig)._tail).next = append;
886 IDL_LIST (append).prev = IDL_LIST (orig)._tail;
887 IDL_LIST (orig)._tail = IDL_LIST (append)._tail;
888
889 /* Set tails on original */
890 for (p = IDL_LIST (orig).next; p && p != append; p = IDL_LIST (p).next)
891 IDL_LIST (p)._tail = IDL_LIST (orig)._tail;
892
893 /* Set up nodes on appended list */
894 for (p = append; p; p = IDL_LIST (p).next)
895 IDL_NODE_UP (p) = IDL_NODE_UP (orig);
896
897 return orig;
898 }
899
IDL_list_remove(IDL_tree list,IDL_tree p)900 IDL_tree IDL_list_remove (IDL_tree list, IDL_tree p)
901 {
902 IDL_tree new_list = list;
903
904 if (IDL_LIST (p).prev == NULL) {
905 assert (list == p);
906 new_list = IDL_LIST (p).next;
907 if (new_list)
908 IDL_LIST (new_list).prev = NULL;
909 } else {
910 IDL_tree prev = IDL_LIST (p).prev;
911 IDL_tree next = IDL_LIST (p).next;
912
913 IDL_LIST (prev).next = next;
914 if (next)
915 IDL_LIST (next).prev = prev;
916 }
917
918 IDL_LIST (p).prev = NULL;
919 IDL_LIST (p).next = NULL;
920 IDL_LIST (p)._tail = p;
921
922 /* Not all tails updated... */
923
924 return new_list;
925 }
926
IDL_gentree_new(GHashFunc hash_func,GCompareFunc key_compare_func,IDL_tree data)927 IDL_tree IDL_gentree_new (GHashFunc hash_func, GCompareFunc key_compare_func, IDL_tree data)
928 {
929 IDL_tree p = IDL_node_new (IDLN_GENTREE);
930
931 __IDL_assign_up_node (p, data);
932 IDL_GENTREE (p).data = data;
933 IDL_GENTREE (p).hash_func = hash_func;
934 IDL_GENTREE (p).key_compare_func = key_compare_func;
935 IDL_GENTREE (p).siblings = g_hash_table_new (hash_func, key_compare_func);
936 IDL_GENTREE (p).children = g_hash_table_new (hash_func, key_compare_func);
937
938 g_hash_table_insert (IDL_GENTREE (p).siblings, data, p);
939
940 return p;
941 }
942
IDL_gentree_new_sibling(IDL_tree from,IDL_tree data)943 IDL_tree IDL_gentree_new_sibling (IDL_tree from, IDL_tree data)
944 {
945 IDL_tree p = IDL_node_new (IDLN_GENTREE);
946
947 __IDL_assign_up_node (p, data);
948 IDL_GENTREE (p).data = data;
949 IDL_GENTREE (p).hash_func = IDL_GENTREE (from).hash_func;
950 IDL_GENTREE (p).key_compare_func = IDL_GENTREE (from).key_compare_func;
951 IDL_GENTREE (p).siblings = IDL_GENTREE (from).siblings;
952 IDL_GENTREE (p).children = g_hash_table_new (IDL_GENTREE (from).hash_func,
953 IDL_GENTREE (from).key_compare_func);
954
955 return p;
956 }
957
IDL_integer_new(IDL_longlong_t value)958 IDL_tree IDL_integer_new (IDL_longlong_t value)
959 {
960 IDL_tree p = IDL_node_new (IDLN_INTEGER);
961
962 IDL_INTEGER (p).value = value;
963
964 return p;
965 }
966
IDL_string_new(char * value)967 IDL_tree IDL_string_new (char *value)
968 {
969 IDL_tree p = IDL_node_new (IDLN_STRING);
970
971 IDL_STRING (p).value = value;
972
973 return p;
974 }
975
IDL_wide_string_new(wchar_t * value)976 IDL_tree IDL_wide_string_new (wchar_t *value)
977 {
978 IDL_tree p = IDL_node_new (IDLN_WIDE_STRING);
979
980 IDL_WIDE_STRING (p).value = value;
981
982 return p;
983 }
984
IDL_char_new(char * value)985 IDL_tree IDL_char_new (char *value)
986 {
987 IDL_tree p = IDL_node_new (IDLN_CHAR);
988
989 IDL_CHAR (p).value = value;
990
991 return p;
992 }
993
IDL_wide_char_new(wchar_t * value)994 IDL_tree IDL_wide_char_new (wchar_t *value)
995 {
996 IDL_tree p = IDL_node_new (IDLN_WIDE_CHAR);
997
998 IDL_WIDE_CHAR (p).value = value;
999
1000 return p;
1001 }
1002
IDL_fixed_new(char * value)1003 IDL_tree IDL_fixed_new (char *value)
1004 {
1005 IDL_tree p = IDL_node_new (IDLN_FIXED);
1006
1007 IDL_FIXED (p).value = value;
1008
1009 return p;
1010 }
1011
IDL_float_new(double value)1012 IDL_tree IDL_float_new (double value)
1013 {
1014 IDL_tree p = IDL_node_new (IDLN_FLOAT);
1015
1016 IDL_FLOAT (p).value = value;
1017
1018 return p;
1019 }
1020
IDL_boolean_new(unsigned value)1021 IDL_tree IDL_boolean_new (unsigned value)
1022 {
1023 IDL_tree p = IDL_node_new (IDLN_BOOLEAN);
1024
1025 IDL_BOOLEAN (p).value = value;
1026
1027 return p;
1028 }
1029
IDL_ident_new(char * str)1030 IDL_tree IDL_ident_new (char *str)
1031 {
1032 IDL_tree p = IDL_node_new (IDLN_IDENT);
1033
1034 IDL_IDENT (p).str = str;
1035
1036 return p;
1037 }
1038
IDL_member_new(IDL_tree type_spec,IDL_tree dcls)1039 IDL_tree IDL_member_new (IDL_tree type_spec, IDL_tree dcls)
1040 {
1041 IDL_tree p = IDL_node_new (IDLN_MEMBER);
1042
1043 __IDL_assign_up_node (p, type_spec);
1044 __IDL_assign_up_node (p, dcls);
1045 IDL_MEMBER (p).type_spec = type_spec;
1046 IDL_MEMBER (p).dcls = dcls;
1047
1048 return p;
1049 }
1050
IDL_native_new(IDL_tree ident)1051 IDL_tree IDL_native_new (IDL_tree ident)
1052 {
1053 IDL_tree p = IDL_node_new (IDLN_NATIVE);
1054
1055 __IDL_assign_up_node (p, ident);
1056 __IDL_assign_location (p, ident);
1057 IDL_NATIVE (p).ident = ident;
1058
1059 return p;
1060 }
1061
IDL_type_dcl_new(IDL_tree type_spec,IDL_tree dcls)1062 IDL_tree IDL_type_dcl_new (IDL_tree type_spec, IDL_tree dcls)
1063 {
1064 IDL_tree p = IDL_node_new (IDLN_TYPE_DCL);
1065
1066 __IDL_assign_up_node (p, type_spec);
1067 __IDL_assign_up_node (p, dcls);
1068 __IDL_assign_location (p, IDL_LIST (dcls).data);
1069 IDL_TYPE_DCL (p).type_spec = type_spec;
1070 IDL_TYPE_DCL (p).dcls = dcls;
1071
1072 return p;
1073 }
1074
IDL_type_float_new(enum IDL_float_type f_type)1075 IDL_tree IDL_type_float_new (enum IDL_float_type f_type)
1076 {
1077 IDL_tree p = IDL_node_new (IDLN_TYPE_FLOAT);
1078
1079 IDL_TYPE_FLOAT (p).f_type = f_type;
1080
1081 return p;
1082 }
1083
IDL_type_fixed_new(IDL_tree positive_int_const,IDL_tree integer_lit)1084 IDL_tree IDL_type_fixed_new (IDL_tree positive_int_const,
1085 IDL_tree integer_lit)
1086 {
1087 IDL_tree p = IDL_node_new (IDLN_TYPE_FIXED);
1088
1089 __IDL_assign_up_node (p, positive_int_const);
1090 __IDL_assign_up_node (p, integer_lit);
1091 IDL_TYPE_FIXED (p).positive_int_const = positive_int_const;
1092 IDL_TYPE_FIXED (p).integer_lit = integer_lit;
1093
1094 return p;
1095 }
1096
IDL_type_integer_new(unsigned f_signed,enum IDL_integer_type f_type)1097 IDL_tree IDL_type_integer_new (unsigned f_signed, enum IDL_integer_type f_type)
1098 {
1099 IDL_tree p = IDL_node_new (IDLN_TYPE_INTEGER);
1100
1101 IDL_TYPE_INTEGER (p).f_signed = f_signed;
1102 IDL_TYPE_INTEGER (p).f_type = f_type;
1103
1104 return p;
1105 }
1106
IDL_type_char_new(void)1107 IDL_tree IDL_type_char_new (void)
1108 {
1109 return IDL_node_new (IDLN_TYPE_CHAR);
1110 }
1111
IDL_type_wide_char_new(void)1112 IDL_tree IDL_type_wide_char_new (void)
1113 {
1114 return IDL_node_new (IDLN_TYPE_WIDE_CHAR);
1115 }
1116
IDL_type_boolean_new(void)1117 IDL_tree IDL_type_boolean_new (void)
1118 {
1119 return IDL_node_new (IDLN_TYPE_BOOLEAN);
1120 }
1121
IDL_type_octet_new(void)1122 IDL_tree IDL_type_octet_new (void)
1123 {
1124 return IDL_node_new (IDLN_TYPE_OCTET);
1125 }
1126
IDL_type_any_new(void)1127 IDL_tree IDL_type_any_new (void)
1128 {
1129 return IDL_node_new (IDLN_TYPE_ANY);
1130 }
1131
IDL_type_object_new(void)1132 IDL_tree IDL_type_object_new (void)
1133 {
1134 return IDL_node_new (IDLN_TYPE_OBJECT);
1135 }
1136
IDL_type_typecode_new(void)1137 IDL_tree IDL_type_typecode_new (void)
1138 {
1139 return IDL_node_new (IDLN_TYPE_TYPECODE);
1140 }
1141
IDL_type_string_new(IDL_tree positive_int_const)1142 IDL_tree IDL_type_string_new (IDL_tree positive_int_const)
1143 {
1144 IDL_tree p = IDL_node_new (IDLN_TYPE_STRING);
1145
1146 __IDL_assign_up_node (p, positive_int_const);
1147 IDL_TYPE_STRING (p).positive_int_const = positive_int_const;
1148
1149 return p;
1150 }
1151
IDL_type_wide_string_new(IDL_tree positive_int_const)1152 IDL_tree IDL_type_wide_string_new (IDL_tree positive_int_const)
1153 {
1154 IDL_tree p = IDL_node_new (IDLN_TYPE_WIDE_STRING);
1155
1156 __IDL_assign_up_node (p, positive_int_const);
1157 IDL_TYPE_WIDE_STRING (p).positive_int_const = positive_int_const;
1158
1159 return p;
1160 }
1161
IDL_type_array_new(IDL_tree ident,IDL_tree size_list)1162 IDL_tree IDL_type_array_new (IDL_tree ident,
1163 IDL_tree size_list)
1164 {
1165 IDL_tree p = IDL_node_new (IDLN_TYPE_ARRAY);
1166
1167 __IDL_assign_up_node (p, ident);
1168 __IDL_assign_up_node (p, size_list);
1169 __IDL_assign_location (p, ident);
1170 IDL_TYPE_ARRAY (p).ident = ident;
1171 IDL_TYPE_ARRAY (p).size_list = size_list;
1172
1173 return p;
1174 }
1175
IDL_type_sequence_new(IDL_tree simple_type_spec,IDL_tree positive_int_const)1176 IDL_tree IDL_type_sequence_new (IDL_tree simple_type_spec,
1177 IDL_tree positive_int_const)
1178 {
1179 IDL_tree p = IDL_node_new (IDLN_TYPE_SEQUENCE);
1180
1181 __IDL_assign_up_node (p, simple_type_spec);
1182 __IDL_assign_up_node (p, positive_int_const);
1183 IDL_TYPE_SEQUENCE (p).simple_type_spec = simple_type_spec;
1184 IDL_TYPE_SEQUENCE (p).positive_int_const = positive_int_const;
1185
1186 return p;
1187 }
1188
IDL_type_struct_new(IDL_tree ident,IDL_tree member_list)1189 IDL_tree IDL_type_struct_new (IDL_tree ident, IDL_tree member_list)
1190 {
1191 IDL_tree p = IDL_node_new (IDLN_TYPE_STRUCT);
1192
1193 __IDL_assign_up_node (p, ident);
1194 __IDL_assign_up_node (p, member_list);
1195 __IDL_assign_location (p, ident);
1196 IDL_TYPE_STRUCT (p).ident = ident;
1197 IDL_TYPE_STRUCT (p).member_list = member_list;
1198
1199 return p;
1200 }
1201
IDL_type_union_new(IDL_tree ident,IDL_tree switch_type_spec,IDL_tree switch_body)1202 IDL_tree IDL_type_union_new (IDL_tree ident, IDL_tree switch_type_spec, IDL_tree switch_body)
1203 {
1204 IDL_tree p = IDL_node_new (IDLN_TYPE_UNION);
1205
1206 __IDL_assign_up_node (p, ident);
1207 __IDL_assign_up_node (p, switch_type_spec);
1208 __IDL_assign_up_node (p, switch_body);
1209 __IDL_assign_location (p, ident);
1210 IDL_TYPE_UNION (p).ident = ident;
1211 IDL_TYPE_UNION (p).switch_type_spec = switch_type_spec;
1212 IDL_TYPE_UNION (p).switch_body = switch_body;
1213
1214 return p;
1215 }
1216
IDL_type_enum_new(IDL_tree ident,IDL_tree enumerator_list)1217 IDL_tree IDL_type_enum_new (IDL_tree ident, IDL_tree enumerator_list)
1218 {
1219 IDL_tree p = IDL_node_new (IDLN_TYPE_ENUM);
1220
1221 __IDL_assign_up_node (p, ident);
1222 __IDL_assign_up_node (p, enumerator_list);
1223 __IDL_assign_location (p, ident);
1224 IDL_TYPE_ENUM (p).ident = ident;
1225 IDL_TYPE_ENUM (p).enumerator_list = enumerator_list;
1226
1227 return p;
1228 }
1229
IDL_case_stmt_new(IDL_tree labels,IDL_tree element_spec)1230 IDL_tree IDL_case_stmt_new (IDL_tree labels, IDL_tree element_spec)
1231 {
1232 IDL_tree p = IDL_node_new (IDLN_CASE_STMT);
1233
1234 __IDL_assign_up_node (p, labels);
1235 __IDL_assign_up_node (p, element_spec);
1236 IDL_CASE_STMT (p).labels = labels;
1237 IDL_CASE_STMT (p).element_spec = element_spec;
1238
1239 return p;
1240 }
1241
IDL_interface_new(IDL_tree ident,IDL_tree inheritance_spec,IDL_tree body)1242 IDL_tree IDL_interface_new (IDL_tree ident, IDL_tree inheritance_spec, IDL_tree body)
1243 {
1244 IDL_tree p = IDL_node_new (IDLN_INTERFACE);
1245
1246 /* Make sure the up node points to the interface */
1247 if (ident && IDL_NODE_UP (ident) &&
1248 IDL_NODE_TYPE (IDL_NODE_UP (ident)) != IDLN_INTERFACE)
1249 IDL_NODE_UP (ident) = NULL;
1250 __IDL_assign_up_node (p, ident);
1251 __IDL_assign_up_node (p, inheritance_spec);
1252 __IDL_assign_up_node (p, body);
1253 IDL_INTERFACE (p).ident = ident;
1254 IDL_INTERFACE (p).inheritance_spec = inheritance_spec;
1255 IDL_INTERFACE (p).body = body;
1256
1257 return p;
1258 }
1259
IDL_module_new(IDL_tree ident,IDL_tree definition_list)1260 IDL_tree IDL_module_new (IDL_tree ident, IDL_tree definition_list)
1261 {
1262 IDL_tree p = IDL_node_new (IDLN_MODULE);
1263
1264 __IDL_assign_up_node (p, ident);
1265 __IDL_assign_up_node (p, definition_list);
1266 __IDL_assign_location (p, ident);
1267 IDL_MODULE (p).ident = ident;
1268 IDL_MODULE (p).definition_list = definition_list;
1269
1270 return p;
1271 }
1272
IDL_binop_new(enum IDL_binop op,IDL_tree left,IDL_tree right)1273 IDL_tree IDL_binop_new (enum IDL_binop op, IDL_tree left, IDL_tree right)
1274 {
1275 IDL_tree p = IDL_node_new (IDLN_BINOP);
1276
1277 __IDL_assign_up_node (p, left);
1278 __IDL_assign_up_node (p, right);
1279 IDL_BINOP (p).op = op;
1280 IDL_BINOP (p).left = left;
1281 IDL_BINOP (p).right = right;
1282
1283 return p;
1284 }
1285
IDL_unaryop_new(enum IDL_unaryop op,IDL_tree operand)1286 IDL_tree IDL_unaryop_new (enum IDL_unaryop op, IDL_tree operand)
1287 {
1288 IDL_tree p = IDL_node_new (IDLN_UNARYOP);
1289
1290 __IDL_assign_up_node (p, operand);
1291 IDL_UNARYOP (p).op = op;
1292 IDL_UNARYOP (p).operand = operand;
1293
1294 return p;
1295 }
1296
IDL_codefrag_new(char * desc,GSList * lines)1297 IDL_tree IDL_codefrag_new (char *desc, GSList *lines)
1298 {
1299 IDL_tree p = IDL_node_new (IDLN_CODEFRAG);
1300
1301 IDL_CODEFRAG (p).desc = desc;
1302 IDL_CODEFRAG (p).lines = lines;
1303
1304 return p;
1305 }
1306
IDL_srcfile_new(char * filename,int seenCnt,gboolean isTop,gboolean wasInhibit)1307 IDL_tree IDL_srcfile_new (char *filename, int seenCnt, gboolean isTop, gboolean wasInhibit)
1308 {
1309 IDL_tree p = IDL_node_new (IDLN_SRCFILE);
1310 IDL_SRCFILE (p).filename = filename;
1311 IDL_SRCFILE (p).seenCnt = seenCnt;
1312 IDL_SRCFILE (p).isTop = isTop;
1313 IDL_SRCFILE (p).wasInhibit = wasInhibit;
1314
1315 return p;
1316 }
1317
IDL_const_dcl_new(IDL_tree const_type,IDL_tree ident,IDL_tree const_exp)1318 IDL_tree IDL_const_dcl_new (IDL_tree const_type, IDL_tree ident, IDL_tree const_exp)
1319 {
1320 IDL_tree p = IDL_node_new (IDLN_CONST_DCL);
1321
1322 __IDL_assign_up_node (p, const_type);
1323 __IDL_assign_up_node (p, ident);
1324 __IDL_assign_up_node (p, const_exp);
1325 __IDL_assign_location (p, ident);
1326 IDL_CONST_DCL (p).const_type = const_type;
1327 IDL_CONST_DCL (p).ident = ident;
1328 IDL_CONST_DCL (p).const_exp = const_exp;
1329
1330 return p;
1331 }
1332
IDL_except_dcl_new(IDL_tree ident,IDL_tree members)1333 IDL_tree IDL_except_dcl_new (IDL_tree ident, IDL_tree members)
1334 {
1335 IDL_tree p = IDL_node_new (IDLN_EXCEPT_DCL);
1336
1337 __IDL_assign_up_node (p, ident);
1338 __IDL_assign_up_node (p, members);
1339 __IDL_assign_location (p, ident);
1340 IDL_EXCEPT_DCL (p).ident = ident;
1341 IDL_EXCEPT_DCL (p).members = members;
1342
1343 return p;
1344 }
1345
IDL_attr_dcl_new(unsigned f_readonly,IDL_tree param_type_spec,IDL_tree simple_declarations)1346 IDL_tree IDL_attr_dcl_new (unsigned f_readonly,
1347 IDL_tree param_type_spec,
1348 IDL_tree simple_declarations)
1349 {
1350 IDL_tree p = IDL_node_new (IDLN_ATTR_DCL);
1351
1352 __IDL_assign_up_node (p, param_type_spec);
1353 __IDL_assign_up_node (p, simple_declarations);
1354 __IDL_assign_location (p, IDL_LIST (simple_declarations).data);
1355 IDL_ATTR_DCL (p).f_readonly = f_readonly;
1356 IDL_ATTR_DCL (p).param_type_spec = param_type_spec;
1357 IDL_ATTR_DCL (p).simple_declarations = simple_declarations;
1358
1359 return p;
1360 }
1361
IDL_op_dcl_new(unsigned f_oneway,IDL_tree op_type_spec,IDL_tree ident,IDL_tree parameter_dcls,IDL_tree raises_expr,IDL_tree context_expr)1362 IDL_tree IDL_op_dcl_new (unsigned f_oneway,
1363 IDL_tree op_type_spec,
1364 IDL_tree ident,
1365 IDL_tree parameter_dcls,
1366 IDL_tree raises_expr,
1367 IDL_tree context_expr)
1368 {
1369 IDL_tree p = IDL_node_new (IDLN_OP_DCL);
1370
1371 __IDL_assign_up_node (p, op_type_spec);
1372 __IDL_assign_up_node (p, ident);
1373 __IDL_assign_up_node (p, parameter_dcls);
1374 __IDL_assign_up_node (p, raises_expr);
1375 __IDL_assign_up_node (p, context_expr);
1376 __IDL_assign_location (p, ident);
1377 IDL_OP_DCL (p).f_oneway = f_oneway;
1378 IDL_OP_DCL (p).op_type_spec = op_type_spec;
1379 IDL_OP_DCL (p).ident = ident;
1380 IDL_OP_DCL (p).parameter_dcls = parameter_dcls;
1381 IDL_OP_DCL (p).raises_expr = raises_expr;
1382 IDL_OP_DCL (p).context_expr = context_expr;
1383
1384 return p;
1385 }
1386
IDL_param_dcl_new(enum IDL_param_attr attr,IDL_tree param_type_spec,IDL_tree simple_declarator)1387 IDL_tree IDL_param_dcl_new (enum IDL_param_attr attr,
1388 IDL_tree param_type_spec,
1389 IDL_tree simple_declarator)
1390 {
1391 IDL_tree p = IDL_node_new (IDLN_PARAM_DCL);
1392
1393 __IDL_assign_up_node (p, param_type_spec);
1394 __IDL_assign_up_node (p, simple_declarator);
1395 __IDL_assign_location (p, simple_declarator);
1396 IDL_PARAM_DCL (p).attr = attr;
1397 IDL_PARAM_DCL (p).param_type_spec = param_type_spec;
1398 IDL_PARAM_DCL (p).simple_declarator = simple_declarator;
1399
1400 return p;
1401 }
1402
IDL_forward_dcl_new(IDL_tree ident)1403 IDL_tree IDL_forward_dcl_new (IDL_tree ident)
1404 {
1405 IDL_tree p = IDL_node_new (IDLN_FORWARD_DCL);
1406
1407 __IDL_assign_up_node (p, ident);
1408 __IDL_assign_location (p, ident);
1409 IDL_FORWARD_DCL (p).ident = ident;
1410
1411 return p;
1412 }
1413
IDL_check_type_cast(const IDL_tree tree,IDL_tree_type type,const char * file,int line,const char * function)1414 IDL_tree IDL_check_type_cast (const IDL_tree tree, IDL_tree_type type,
1415 const char *file, int line, const char *function)
1416 {
1417 if (__IDL_check_type_casts) {
1418 if (tree == NULL) {
1419 g_warning ("file %s: line %d: (%s) invalid type cast attempt,"
1420 " NULL tree to %s\n",
1421 file, line, function,
1422 IDL_tree_type_names[type]);
1423 }
1424 else if (IDL_NODE_TYPE (tree) != type) {
1425 g_warning ("file %s: line %d: (%s) expected IDL tree type %s,"
1426 " but got %s\n",
1427 file, line, function,
1428 IDL_tree_type_names[type], IDL_NODE_TYPE_NAME (tree));
1429
1430 }
1431 }
1432 return tree;
1433 }
1434
IDL_gentree_chain_sibling(IDL_tree from,IDL_tree data)1435 IDL_tree IDL_gentree_chain_sibling (IDL_tree from, IDL_tree data)
1436 {
1437 IDL_tree p;
1438
1439 if (from == NULL)
1440 return NULL;
1441
1442 p = IDL_gentree_new_sibling (from, data);
1443 IDL_NODE_UP (p) = IDL_NODE_UP (from);
1444
1445 return p;
1446 }
1447
IDL_gentree_chain_child(IDL_tree from,IDL_tree data)1448 IDL_tree IDL_gentree_chain_child (IDL_tree from, IDL_tree data)
1449 {
1450 IDL_tree p;
1451
1452 if (from == NULL)
1453 return NULL;
1454
1455 p = IDL_gentree_new (IDL_GENTREE (from).hash_func,
1456 IDL_GENTREE (from).key_compare_func,
1457 data);
1458 IDL_NODE_UP (p) = from;
1459
1460 g_hash_table_insert (IDL_GENTREE (from).children, data, p);
1461
1462 return p;
1463 }
1464
IDL_get_parent_node(IDL_tree p,IDL_tree_type type,int * levels)1465 IDL_tree IDL_get_parent_node (IDL_tree p, IDL_tree_type type, int *levels)
1466 {
1467 int count = 0;
1468
1469 if (p == NULL)
1470 return NULL;
1471
1472 if (type == IDLN_ANY)
1473 return IDL_NODE_UP (p);
1474
1475 while (p != NULL && IDL_NODE_TYPE (p) != type) {
1476
1477 if (IDL_NODE_IS_SCOPED (p))
1478 ++count;
1479
1480 p = IDL_NODE_UP (p);
1481 }
1482
1483 if (p != NULL)
1484 if (levels != NULL)
1485 *levels = count;
1486
1487 return p;
1488 }
1489
IDL_tree_get_scope(IDL_tree p)1490 IDL_tree IDL_tree_get_scope (IDL_tree p)
1491 {
1492 g_return_val_if_fail (p != NULL, NULL);
1493
1494 if (IDL_NODE_TYPE (p) == IDLN_GENTREE)
1495 return p;
1496
1497 if (!IDL_NODE_IS_SCOPED (p)) {
1498 g_warning ("Node type %s isn't scoped", IDL_NODE_TYPE_NAME (p));
1499 return NULL;
1500 }
1501
1502 switch (IDL_NODE_TYPE (p)) {
1503 case IDLN_IDENT:
1504 return IDL_IDENT_TO_NS (p);
1505
1506 case IDLN_INTERFACE:
1507 return IDL_IDENT_TO_NS (IDL_INTERFACE (p).ident);
1508
1509 case IDLN_MODULE:
1510 return IDL_IDENT_TO_NS (IDL_MODULE (p).ident);
1511
1512 case IDLN_EXCEPT_DCL:
1513 return IDL_IDENT_TO_NS (IDL_EXCEPT_DCL (p).ident);
1514
1515 case IDLN_OP_DCL:
1516 return IDL_IDENT_TO_NS (IDL_OP_DCL (p).ident);
1517
1518 case IDLN_TYPE_ENUM:
1519 return IDL_IDENT_TO_NS (IDL_TYPE_ENUM (p).ident);
1520
1521 case IDLN_TYPE_STRUCT:
1522 return IDL_IDENT_TO_NS (IDL_TYPE_STRUCT (p).ident);
1523
1524 case IDLN_TYPE_UNION:
1525 return IDL_IDENT_TO_NS (IDL_TYPE_UNION (p).ident);
1526
1527 default:
1528 return NULL;
1529 }
1530 }
1531
1532 typedef struct {
1533 IDL_tree_func pre_tree_func;
1534 IDL_tree_func post_tree_func;
1535 gpointer user_data;
1536 } IDLTreeWalkRealData;
1537
IDL_tree_walk_real(IDL_tree_func_data * tfd,IDLTreeWalkRealData * data)1538 static void IDL_tree_walk_real (IDL_tree_func_data *tfd, IDLTreeWalkRealData *data)
1539 {
1540 IDL_tree_func_data down_tfd;
1541 gboolean recurse = TRUE;
1542 IDL_tree p, q;
1543
1544 if (tfd->tree == NULL)
1545 return;
1546
1547 tfd->state->bottom = tfd;
1548 tfd->step = 0;
1549 tfd->data = NULL;
1550
1551 if (data->pre_tree_func)
1552 recurse = (*data->pre_tree_func) (tfd, data->user_data);
1553 ++tfd->step;
1554
1555 down_tfd.state = tfd->state;
1556 down_tfd.up = tfd;
1557 down_tfd.level = tfd->level + 1;
1558
1559 p = tfd->tree;
1560
1561 if (recurse) switch (IDL_NODE_TYPE (p)) {
1562 case IDLN_INTEGER:
1563 case IDLN_STRING:
1564 case IDLN_CHAR:
1565 case IDLN_FIXED:
1566 case IDLN_FLOAT:
1567 case IDLN_BOOLEAN:
1568 case IDLN_IDENT:
1569 case IDLN_TYPE_WIDE_CHAR:
1570 case IDLN_TYPE_BOOLEAN:
1571 case IDLN_TYPE_OCTET:
1572 case IDLN_TYPE_ANY:
1573 case IDLN_TYPE_OBJECT:
1574 case IDLN_TYPE_TYPECODE:
1575 case IDLN_TYPE_FLOAT:
1576 case IDLN_TYPE_INTEGER:
1577 case IDLN_TYPE_CHAR:
1578 case IDLN_CODEFRAG:
1579 case IDLN_SRCFILE:
1580 break;
1581
1582 case IDLN_LIST:
1583 for (q = p; q; q = IDL_LIST (q).next) {
1584 down_tfd.tree = IDL_LIST (q).data;
1585 IDL_tree_walk_real (&down_tfd, data);
1586 }
1587 break;
1588
1589 case IDLN_GENTREE:
1590 g_error ("IDLN_GENTREE walk not implemented!");
1591 break;
1592
1593 case IDLN_MEMBER:
1594 down_tfd.tree = IDL_MEMBER (p).type_spec;
1595 IDL_tree_walk_real (&down_tfd, data);
1596 if ( (tfd->state->flags & IDL_WalkF_TypespecOnly)==0 ) {
1597 down_tfd.tree = IDL_MEMBER (p).dcls;
1598 IDL_tree_walk_real (&down_tfd, data);
1599 }
1600 break;
1601
1602 case IDLN_NATIVE:
1603 down_tfd.tree = IDL_NATIVE (p).ident;
1604 IDL_tree_walk_real (&down_tfd, data);
1605 break;
1606
1607 case IDLN_TYPE_DCL:
1608 down_tfd.tree = IDL_TYPE_DCL (p).type_spec;
1609 IDL_tree_walk_real (&down_tfd, data);
1610 if ( (tfd->state->flags & IDL_WalkF_TypespecOnly)==0 ) {
1611 down_tfd.tree = IDL_TYPE_DCL (p).dcls;
1612 IDL_tree_walk_real (&down_tfd, data);
1613 }
1614 break;
1615
1616 case IDLN_CONST_DCL:
1617 down_tfd.tree = IDL_CONST_DCL (p).const_type;
1618 IDL_tree_walk_real (&down_tfd, data);
1619 if ( (tfd->state->flags & IDL_WalkF_TypespecOnly)==0 ) {
1620 down_tfd.tree = IDL_CONST_DCL (p).ident;
1621 IDL_tree_walk_real (&down_tfd, data);
1622 down_tfd.tree = IDL_CONST_DCL (p).const_exp;
1623 IDL_tree_walk_real (&down_tfd, data);
1624 }
1625 break;
1626
1627 case IDLN_EXCEPT_DCL:
1628 if ( (tfd->state->flags & IDL_WalkF_TypespecOnly)==0 ) {
1629 down_tfd.tree = IDL_EXCEPT_DCL (p).ident;
1630 IDL_tree_walk_real (&down_tfd, data);
1631 }
1632 down_tfd.tree = IDL_EXCEPT_DCL (p).members;
1633 IDL_tree_walk_real (&down_tfd, data);
1634 break;
1635
1636 case IDLN_ATTR_DCL:
1637 down_tfd.tree = IDL_ATTR_DCL (p).param_type_spec;
1638 IDL_tree_walk_real (&down_tfd, data);
1639 if ( (tfd->state->flags & IDL_WalkF_TypespecOnly)==0 ) {
1640 down_tfd.tree = IDL_ATTR_DCL (p).simple_declarations;
1641 IDL_tree_walk_real (&down_tfd, data);
1642 }
1643 break;
1644
1645 case IDLN_OP_DCL:
1646 down_tfd.tree = IDL_OP_DCL (p).op_type_spec;
1647 IDL_tree_walk_real (&down_tfd, data);
1648 down_tfd.tree = IDL_OP_DCL (p).ident;
1649 IDL_tree_walk_real (&down_tfd, data);
1650 down_tfd.tree = IDL_OP_DCL (p).parameter_dcls;
1651 IDL_tree_walk_real (&down_tfd, data);
1652 down_tfd.tree = IDL_OP_DCL (p).raises_expr;
1653 IDL_tree_walk_real (&down_tfd, data);
1654 down_tfd.tree = IDL_OP_DCL (p).context_expr;
1655 IDL_tree_walk_real (&down_tfd, data);
1656 break;
1657
1658 case IDLN_PARAM_DCL:
1659 down_tfd.tree = IDL_PARAM_DCL (p).param_type_spec;
1660 IDL_tree_walk_real (&down_tfd, data);
1661 if ( (tfd->state->flags & IDL_WalkF_TypespecOnly)==0 ) {
1662 down_tfd.tree = IDL_PARAM_DCL (p).simple_declarator;
1663 IDL_tree_walk_real (&down_tfd, data);
1664 }
1665 break;
1666
1667 case IDLN_FORWARD_DCL:
1668 down_tfd.tree = IDL_FORWARD_DCL (p).ident;
1669 IDL_tree_walk_real (&down_tfd, data);
1670 break;
1671
1672 case IDLN_TYPE_FIXED:
1673 if ( (tfd->state->flags & IDL_WalkF_TypespecOnly)==0 ) {
1674 down_tfd.tree = IDL_TYPE_FIXED (p).positive_int_const;
1675 IDL_tree_walk_real (&down_tfd, data);
1676 down_tfd.tree = IDL_TYPE_FIXED (p).integer_lit;
1677 IDL_tree_walk_real (&down_tfd, data);
1678 }
1679 break;
1680
1681 case IDLN_TYPE_STRING:
1682 if ( (tfd->state->flags & IDL_WalkF_TypespecOnly)==0 ) {
1683 down_tfd.tree = IDL_TYPE_STRING (p).positive_int_const;
1684 IDL_tree_walk_real (&down_tfd, data);
1685 }
1686 break;
1687
1688 case IDLN_TYPE_WIDE_STRING:
1689 if ( (tfd->state->flags & IDL_WalkF_TypespecOnly)==0 ) {
1690 down_tfd.tree = IDL_TYPE_WIDE_STRING (p).positive_int_const;
1691 IDL_tree_walk_real (&down_tfd, data);
1692 }
1693 break;
1694
1695 case IDLN_TYPE_ENUM:
1696 if ( (tfd->state->flags & IDL_WalkF_TypespecOnly)==0 ) {
1697 down_tfd.tree = IDL_TYPE_ENUM (p).ident;
1698 IDL_tree_walk_real (&down_tfd, data);
1699 down_tfd.tree = IDL_TYPE_ENUM (p).enumerator_list;
1700 IDL_tree_walk_real (&down_tfd, data);
1701 }
1702 break;
1703
1704 case IDLN_TYPE_SEQUENCE:
1705 down_tfd.tree = IDL_TYPE_SEQUENCE (p).simple_type_spec;
1706 IDL_tree_walk_real (&down_tfd, data);
1707 if ( (tfd->state->flags & IDL_WalkF_TypespecOnly)==0 ) {
1708 down_tfd.tree = IDL_TYPE_SEQUENCE (p).positive_int_const;
1709 IDL_tree_walk_real (&down_tfd, data);
1710 }
1711 break;
1712
1713 case IDLN_TYPE_ARRAY:
1714 down_tfd.tree = IDL_TYPE_ARRAY (p).ident;
1715 IDL_tree_walk_real (&down_tfd, data);
1716 if ( (tfd->state->flags & IDL_WalkF_TypespecOnly)==0 ) {
1717 down_tfd.tree = IDL_TYPE_ARRAY (p).size_list;
1718 IDL_tree_walk_real (&down_tfd, data);
1719 }
1720 break;
1721
1722 case IDLN_TYPE_STRUCT:
1723 down_tfd.tree = IDL_TYPE_STRUCT (p).ident;
1724 IDL_tree_walk_real (&down_tfd, data);
1725 down_tfd.tree = IDL_TYPE_STRUCT (p).member_list;
1726 IDL_tree_walk_real (&down_tfd, data);
1727 break;
1728
1729 case IDLN_TYPE_UNION:
1730 down_tfd.tree = IDL_TYPE_UNION (p).ident;
1731 IDL_tree_walk_real (&down_tfd, data);
1732 down_tfd.tree = IDL_TYPE_UNION (p).switch_type_spec;
1733 IDL_tree_walk_real (&down_tfd, data);
1734 down_tfd.tree = IDL_TYPE_UNION (p).switch_body;
1735 IDL_tree_walk_real (&down_tfd, data);
1736 break;
1737
1738 case IDLN_CASE_STMT:
1739 down_tfd.tree = IDL_CASE_STMT (p).labels;
1740 IDL_tree_walk_real (&down_tfd, data);
1741 /* FIXME */
1742 down_tfd.tree = IDL_CASE_STMT (p).element_spec;
1743 IDL_tree_walk_real (&down_tfd, data);
1744 break;
1745
1746 case IDLN_INTERFACE:
1747 down_tfd.tree = IDL_INTERFACE (p).ident;
1748 IDL_tree_walk_real (&down_tfd, data);
1749 down_tfd.tree = IDL_INTERFACE (p).inheritance_spec;
1750 IDL_tree_walk_real (&down_tfd, data);
1751 down_tfd.tree = IDL_INTERFACE (p).body;
1752 IDL_tree_walk_real (&down_tfd, data);
1753 break;
1754
1755 case IDLN_MODULE:
1756 down_tfd.tree = IDL_MODULE (p).ident;
1757 IDL_tree_walk_real (&down_tfd, data);
1758 down_tfd.tree = IDL_MODULE (p).definition_list;
1759 IDL_tree_walk_real (&down_tfd, data);
1760 break;
1761
1762 case IDLN_BINOP:
1763 down_tfd.tree = IDL_BINOP (p).left;
1764 IDL_tree_walk_real (&down_tfd, data);
1765 down_tfd.tree = IDL_BINOP (p).right;
1766 IDL_tree_walk_real (&down_tfd, data);
1767 break;
1768
1769 case IDLN_UNARYOP:
1770 down_tfd.tree = IDL_UNARYOP (p).operand;
1771 IDL_tree_walk_real (&down_tfd, data);
1772 break;
1773
1774 default:
1775 g_warning ("IDL_tree_walk_real: unknown node type %s\n",
1776 IDL_NODE_TYPE_NAME (p));
1777 break;
1778 }
1779
1780 if (data->post_tree_func)
1781 (void) (*data->post_tree_func) (tfd, data->user_data);
1782
1783 tfd->state->bottom = tfd->up;
1784 }
1785
IDL_tree_walk2(IDL_tree p,IDL_tree_func_data * current,glong flags,IDL_tree_func pre_tree_func,IDL_tree_func post_tree_func,gpointer user_data)1786 void IDL_tree_walk2 (IDL_tree p, IDL_tree_func_data *current,
1787 glong flags,
1788 IDL_tree_func pre_tree_func, IDL_tree_func post_tree_func,
1789 gpointer user_data)
1790 {
1791 IDLTreeWalkRealData data;
1792 IDL_tree_func_state tfs;
1793 IDL_tree_func_data tfd;
1794
1795 g_return_if_fail (!(pre_tree_func == NULL && post_tree_func == NULL));
1796
1797 data.pre_tree_func = pre_tree_func;
1798 data.post_tree_func = post_tree_func;
1799 data.user_data = user_data;
1800
1801 tfs.up = current ? current->state : NULL;
1802 tfs.start = p;
1803 tfs.flags = flags;
1804
1805 tfd.level = 0;
1806 if (current) {
1807 tfd = *current;
1808 tfd.level = ((tfd.level / 1000)+1) * 1000;
1809 }
1810 tfd.state = &tfs;
1811 tfd.up = current;
1812 tfd.tree = p;
1813
1814 IDL_tree_walk_real (&tfd, &data);
1815 }
1816
IDL_tree_walk(IDL_tree p,IDL_tree_func_data * current,IDL_tree_func pre_tree_func,IDL_tree_func post_tree_func,gpointer user_data)1817 void IDL_tree_walk (IDL_tree p, IDL_tree_func_data *current,
1818 IDL_tree_func pre_tree_func, IDL_tree_func post_tree_func,
1819 gpointer user_data)
1820 {
1821 IDL_tree_walk2 (p, current, /*flags*/0,
1822 pre_tree_func, post_tree_func, user_data);
1823 }
1824
IDL_tree_walk_in_order(IDL_tree p,IDL_tree_func tree_func,gpointer user_data)1825 void IDL_tree_walk_in_order (IDL_tree p, IDL_tree_func tree_func, gpointer user_data)
1826 {
1827 IDL_tree_walk2 (p, NULL, /*flags*/0, tree_func, NULL, user_data);
1828 }
1829
1830 static void __IDL_tree_free (IDL_tree p);
1831
tree_free_but_this(IDL_tree data,IDL_tree p,IDL_tree this_one)1832 static int tree_free_but_this (IDL_tree data, IDL_tree p, IDL_tree this_one)
1833 {
1834 if (p == this_one)
1835 return TRUE;
1836
1837 __IDL_tree_free (p);
1838
1839 return TRUE;
1840 }
1841
property_free(char * key,char * value)1842 static void property_free (char *key, char *value)
1843 {
1844 g_free (key);
1845 g_free (value);
1846 }
1847
__IDL_free_properties(GHashTable * table)1848 void __IDL_free_properties (GHashTable *table)
1849 {
1850 if (table) {
1851 g_hash_table_foreach (table, (GHFunc) property_free, NULL);
1852 g_hash_table_destroy (table);
1853 }
1854 }
1855
1856 /* Free associated node data, regardless of refcounts */
IDL_tree_free_real(IDL_tree p)1857 static void IDL_tree_free_real (IDL_tree p)
1858 {
1859 GSList *slist;
1860
1861 assert (p != NULL);
1862
1863 switch (IDL_NODE_TYPE (p)) {
1864 case IDLN_GENTREE:
1865 g_hash_table_foreach (IDL_GENTREE (p).children,
1866 (GHFunc) tree_free_but_this, NULL);
1867 g_hash_table_destroy (IDL_GENTREE (p).children);
1868 break;
1869
1870 case IDLN_FIXED:
1871 g_free (IDL_FIXED (p).value);
1872 break;
1873
1874 case IDLN_STRING:
1875 g_free (IDL_STRING (p).value);
1876 break;
1877
1878 case IDLN_WIDE_STRING:
1879 g_free (IDL_WIDE_STRING (p).value);
1880 break;
1881
1882 case IDLN_CHAR:
1883 g_free (IDL_CHAR (p).value);
1884 break;
1885
1886 case IDLN_WIDE_CHAR:
1887 g_free (IDL_WIDE_CHAR (p).value);
1888 break;
1889
1890 case IDLN_IDENT:
1891 g_free (IDL_IDENT (p).str);
1892 g_free (IDL_IDENT_REPO_ID (p));
1893 for (slist = IDL_IDENT (p).comments; slist; slist = slist->next)
1894 g_free (slist->data);
1895 g_slist_free (IDL_IDENT (p).comments);
1896 break;
1897
1898 case IDLN_NATIVE:
1899 g_free (IDL_NATIVE (p).user_type);
1900 break;
1901
1902 case IDLN_INTERFACE:
1903 break;
1904
1905 case IDLN_CODEFRAG:
1906 g_free (IDL_CODEFRAG (p).desc);
1907 for (slist = IDL_CODEFRAG (p).lines; slist; slist = slist->next)
1908 g_free (slist->data);
1909 g_slist_free (IDL_CODEFRAG (p).lines);
1910 break;
1911
1912 default:
1913 break;
1914 }
1915
1916 __IDL_free_properties (IDL_NODE_PROPERTIES (p));
1917
1918 g_free (p);
1919 }
1920
1921 /* Free node taking into account refcounts */
__IDL_tree_free(IDL_tree p)1922 static void __IDL_tree_free (IDL_tree p)
1923 {
1924 if (p == NULL)
1925 return;
1926
1927 if (--IDL_NODE_REFS (p) <= 0)
1928 IDL_tree_free_real (p);
1929 }
1930
1931 /* Free a set of references of an entire tree */
IDL_tree_free(IDL_tree p)1932 void IDL_tree_free (IDL_tree p)
1933 {
1934 IDL_tree q;
1935
1936 if (p == NULL)
1937 return;
1938
1939 switch (IDL_NODE_TYPE (p)) {
1940 case IDLN_INTEGER:
1941 case IDLN_FLOAT:
1942 case IDLN_BOOLEAN:
1943 case IDLN_TYPE_FLOAT:
1944 case IDLN_TYPE_INTEGER:
1945 case IDLN_TYPE_CHAR:
1946 case IDLN_TYPE_WIDE_CHAR:
1947 case IDLN_TYPE_BOOLEAN:
1948 case IDLN_TYPE_OCTET:
1949 case IDLN_TYPE_ANY:
1950 case IDLN_TYPE_OBJECT:
1951 case IDLN_TYPE_TYPECODE:
1952 case IDLN_FIXED:
1953 case IDLN_STRING:
1954 case IDLN_WIDE_STRING:
1955 case IDLN_CHAR:
1956 case IDLN_WIDE_CHAR:
1957 case IDLN_IDENT:
1958 case IDLN_CODEFRAG:
1959 case IDLN_SRCFILE:
1960 __IDL_tree_free (p);
1961 break;
1962
1963 case IDLN_LIST:
1964 while (p) {
1965 IDL_tree_free (IDL_LIST (p).data);
1966 q = IDL_LIST (p).next;
1967 __IDL_tree_free (p);
1968 p = q;
1969 }
1970 break;
1971
1972 case IDLN_GENTREE:
1973 g_hash_table_foreach (IDL_GENTREE (p).siblings,
1974 (GHFunc) tree_free_but_this, p);
1975 g_hash_table_destroy (IDL_GENTREE (p).siblings);
1976 __IDL_tree_free (p);
1977 break;
1978
1979 case IDLN_MEMBER:
1980 IDL_tree_free (IDL_MEMBER (p).type_spec);
1981 IDL_tree_free (IDL_MEMBER (p).dcls);
1982 __IDL_tree_free (p);
1983 break;
1984
1985 case IDLN_NATIVE:
1986 IDL_tree_free (IDL_NATIVE (p).ident);
1987 __IDL_tree_free (p);
1988 break;
1989
1990 case IDLN_TYPE_ENUM:
1991 IDL_tree_free (IDL_TYPE_ENUM (p).ident);
1992 IDL_tree_free (IDL_TYPE_ENUM (p).enumerator_list);
1993 __IDL_tree_free (p);
1994 break;
1995
1996 case IDLN_TYPE_SEQUENCE:
1997 IDL_tree_free (IDL_TYPE_SEQUENCE (p).simple_type_spec);
1998 IDL_tree_free (IDL_TYPE_SEQUENCE (p).positive_int_const);
1999 __IDL_tree_free (p);
2000 break;
2001
2002 case IDLN_TYPE_ARRAY:
2003 IDL_tree_free (IDL_TYPE_ARRAY (p).ident);
2004 IDL_tree_free (IDL_TYPE_ARRAY (p).size_list);
2005 __IDL_tree_free (p);
2006 break;
2007
2008 case IDLN_TYPE_STRUCT:
2009 IDL_tree_free (IDL_TYPE_STRUCT (p).ident);
2010 IDL_tree_free (IDL_TYPE_STRUCT (p).member_list);
2011 __IDL_tree_free (p);
2012 break;
2013
2014 case IDLN_TYPE_UNION:
2015 IDL_tree_free (IDL_TYPE_UNION (p).ident);
2016 IDL_tree_free (IDL_TYPE_UNION (p).switch_type_spec);
2017 IDL_tree_free (IDL_TYPE_UNION (p).switch_body);
2018 __IDL_tree_free (p);
2019 break;
2020
2021 case IDLN_TYPE_DCL:
2022 IDL_tree_free (IDL_TYPE_DCL (p).type_spec);
2023 IDL_tree_free (IDL_TYPE_DCL (p).dcls);
2024 __IDL_tree_free (p);
2025 break;
2026
2027 case IDLN_CONST_DCL:
2028 IDL_tree_free (IDL_CONST_DCL (p).const_type);
2029 IDL_tree_free (IDL_CONST_DCL (p).ident);
2030 IDL_tree_free (IDL_CONST_DCL (p).const_exp);
2031 __IDL_tree_free (p);
2032 break;
2033
2034 case IDLN_EXCEPT_DCL:
2035 IDL_tree_free (IDL_EXCEPT_DCL (p).ident);
2036 IDL_tree_free (IDL_EXCEPT_DCL (p).members);
2037 __IDL_tree_free (p);
2038 break;
2039
2040 case IDLN_ATTR_DCL:
2041 IDL_tree_free (IDL_ATTR_DCL (p).param_type_spec);
2042 IDL_tree_free (IDL_ATTR_DCL (p).simple_declarations);
2043 __IDL_tree_free (p);
2044 break;
2045
2046 case IDLN_OP_DCL:
2047 IDL_tree_free (IDL_OP_DCL (p).op_type_spec);
2048 IDL_tree_free (IDL_OP_DCL (p).ident);
2049 IDL_tree_free (IDL_OP_DCL (p).parameter_dcls);
2050 IDL_tree_free (IDL_OP_DCL (p).raises_expr);
2051 IDL_tree_free (IDL_OP_DCL (p).context_expr);
2052 __IDL_tree_free (p);
2053 break;
2054
2055 case IDLN_PARAM_DCL:
2056 IDL_tree_free (IDL_PARAM_DCL (p).param_type_spec);
2057 IDL_tree_free (IDL_PARAM_DCL (p).simple_declarator);
2058 __IDL_tree_free (p);
2059 break;
2060
2061 case IDLN_FORWARD_DCL:
2062 IDL_tree_free (IDL_FORWARD_DCL (p).ident);
2063 __IDL_tree_free (p);
2064 break;
2065
2066 case IDLN_TYPE_STRING:
2067 IDL_tree_free (IDL_TYPE_STRING (p).positive_int_const);
2068 __IDL_tree_free (p);
2069 break;
2070
2071 case IDLN_TYPE_WIDE_STRING:
2072 IDL_tree_free (IDL_TYPE_WIDE_STRING (p).positive_int_const);
2073 __IDL_tree_free (p);
2074 break;
2075
2076 case IDLN_TYPE_FIXED:
2077 IDL_tree_free (IDL_TYPE_FIXED (p).positive_int_const);
2078 IDL_tree_free (IDL_TYPE_FIXED (p).integer_lit);
2079 __IDL_tree_free (p);
2080 break;
2081
2082 case IDLN_CASE_STMT:
2083 IDL_tree_free (IDL_CASE_STMT (p).labels);
2084 IDL_tree_free (IDL_CASE_STMT (p).element_spec);
2085 __IDL_tree_free (p);
2086 break;
2087
2088 case IDLN_INTERFACE:
2089 IDL_tree_free (IDL_INTERFACE (p).ident);
2090 IDL_tree_free (IDL_INTERFACE (p).inheritance_spec);
2091 IDL_tree_free (IDL_INTERFACE (p).body);
2092 __IDL_tree_free (p);
2093 break;
2094
2095 case IDLN_MODULE:
2096 IDL_tree_free (IDL_MODULE (p).ident);
2097 IDL_tree_free (IDL_MODULE (p).definition_list);
2098 __IDL_tree_free (p);
2099 break;
2100
2101 case IDLN_BINOP:
2102 IDL_tree_free (IDL_BINOP (p).left);
2103 IDL_tree_free (IDL_BINOP (p).right);
2104 __IDL_tree_free (p);
2105 break;
2106
2107 case IDLN_UNARYOP:
2108 IDL_tree_free (IDL_UNARYOP (p).operand);
2109 __IDL_tree_free (p);
2110 break;
2111
2112 default:
2113 g_warning ("Free unknown node: %d\n", IDL_NODE_TYPE (p));
2114 break;
2115 }
2116 }
2117
2118 #define C_ESC(a,b) case a: *p++ = b; ++s; break
IDL_do_escapes(const char * s)2119 gchar *IDL_do_escapes (const char *s)
2120 {
2121 char *p, *q;
2122
2123 if (!s)
2124 return NULL;
2125
2126 p = q = g_malloc (strlen (s) + 1);
2127
2128 while (*s) {
2129 if (*s != '\\') {
2130 *p++ = *s++;
2131 continue;
2132 }
2133 ++s;
2134 if (*s == 'x') {
2135 char hex[3];
2136 int n;
2137 hex[0] = 0;
2138 ++s;
2139 sscanf (s, "%2[0-9a-fA-F]", hex);
2140 s += strlen (hex);
2141 sscanf (hex, "%x", &n);
2142 *p++ = n;
2143 continue;
2144 }
2145 if (*s >= '0' && *s <= '7') {
2146 char oct[4];
2147 int n;
2148 oct[0] = 0;
2149 sscanf (s, "%3[0-7]", oct);
2150 s += strlen (oct);
2151 sscanf (oct, "%o", &n);
2152 *p++ = n;
2153 continue;
2154 }
2155 switch (*s) {
2156 C_ESC ('n','\n');
2157 C_ESC ('t','\t');
2158 C_ESC ('v','\v');
2159 C_ESC ('b','\b');
2160 C_ESC ('r','\r');
2161 C_ESC ('f','\f');
2162 C_ESC ('a','\a');
2163 C_ESC ('\\','\\');
2164 C_ESC ('?','?');
2165 C_ESC ('\'','\'');
2166 C_ESC ('"','"');
2167 }
2168 }
2169 *p = 0;
2170
2171 return q;
2172 }
2173
IDL_list_length(IDL_tree list)2174 int IDL_list_length (IDL_tree list)
2175 {
2176 IDL_tree curitem;
2177 int length;
2178
2179 for (curitem = list, length = 0; curitem;
2180 curitem = IDL_LIST (curitem).next)
2181 length++;
2182
2183 return length;
2184 }
2185
IDL_list_nth(IDL_tree list,int n)2186 IDL_tree IDL_list_nth (IDL_tree list, int n)
2187 {
2188 IDL_tree curitem;
2189 int i;
2190
2191 for (curitem = list, i = 0; i < n && curitem;
2192 curitem = IDL_LIST (curitem).next, i++) ;
2193
2194 return curitem;
2195 }
2196
IDL_tree_property_get(IDL_tree tree,const char * key)2197 const char *IDL_tree_property_get (IDL_tree tree, const char *key)
2198 {
2199 g_return_val_if_fail (tree != NULL, NULL);
2200 g_return_val_if_fail (key != NULL, NULL);
2201
2202 if (!IDL_NODE_PROPERTIES (tree))
2203 return NULL;
2204
2205 return g_hash_table_lookup (IDL_NODE_PROPERTIES (tree), key);
2206 }
2207
IDL_tree_property_set(IDL_tree tree,const char * key,const char * value)2208 void IDL_tree_property_set (IDL_tree tree, const char *key, const char *value)
2209 {
2210 g_return_if_fail (tree != NULL);
2211 g_return_if_fail (key != NULL);
2212
2213 if (!IDL_NODE_PROPERTIES (tree))
2214 IDL_NODE_PROPERTIES (tree) = g_hash_table_new (
2215 IDL_strcase_hash, IDL_strcase_equal);
2216 else if (IDL_tree_property_get (tree, key))
2217 IDL_tree_property_remove (tree, key);
2218
2219 g_hash_table_insert (IDL_NODE_PROPERTIES (tree), g_strdup (key), g_strdup (value));
2220 }
2221
IDL_tree_property_remove(IDL_tree tree,const char * key)2222 gboolean IDL_tree_property_remove (IDL_tree tree, const char *key)
2223 {
2224 gboolean removed = FALSE;
2225 char *val;
2226
2227 g_return_val_if_fail (tree != NULL, FALSE);
2228 g_return_val_if_fail (key != NULL, FALSE);
2229
2230 if (!IDL_NODE_PROPERTIES (tree))
2231 return FALSE;
2232
2233 if ((val = g_hash_table_lookup (IDL_NODE_PROPERTIES (tree), key))) {
2234 g_hash_table_remove (IDL_NODE_PROPERTIES (tree), key);
2235 g_free (val);
2236 removed = TRUE;
2237 }
2238
2239 return removed;
2240 }
2241
property_set(char * key,char * value,IDL_tree tree)2242 static void property_set (char *key, char *value, IDL_tree tree)
2243 {
2244 IDL_tree_property_set (tree, key, value);
2245 }
2246
IDL_tree_properties_copy(IDL_tree from_tree,IDL_tree to_tree)2247 void IDL_tree_properties_copy (IDL_tree from_tree, IDL_tree to_tree)
2248 {
2249 g_return_if_fail (from_tree != NULL);
2250 g_return_if_fail (to_tree != NULL);
2251
2252 if (IDL_NODE_PROPERTIES (from_tree))
2253 g_hash_table_foreach (IDL_NODE_PROPERTIES (from_tree),
2254 (GHFunc) property_set, to_tree);
2255 }
2256
2257 typedef struct {
2258 IDL_tree *root;
2259 GHashTable *removed_nodes;
2260 } RemoveListNodeData;
2261
remove_list_node(IDL_tree p,IDL_tree * list_head,RemoveListNodeData * data)2262 static int remove_list_node (IDL_tree p, IDL_tree *list_head, RemoveListNodeData *data)
2263 {
2264 assert (p != NULL);
2265 assert (IDL_NODE_TYPE (p) == IDLN_LIST);
2266
2267 if (list_head)
2268 *list_head = IDL_list_remove (*list_head, p);
2269 else
2270 *data->root = IDL_list_remove (*data->root, p);
2271
2272 if (data->removed_nodes) {
2273 if (!g_hash_table_lookup_extended (data->removed_nodes, p, NULL, NULL))
2274 g_hash_table_insert (data->removed_nodes, p, p);
2275 /*
2276 We shouldn't need this since we have removed it from the tree,
2277 but we might need it for multiple declspec (inhibits) in the same
2278 subtree.
2279 IDL_tree_walk_in_order (p, (IDL_tree_func) inc_node_ref, NULL);
2280 */
2281 } else
2282 IDL_tree_free (p);
2283
2284 return TRUE;
2285 }
2286
2287 /* Forward Declaration Resolution */
load_forward_dcls(IDL_tree_func_data * tfd,GHashTable * table)2288 static int load_forward_dcls (IDL_tree_func_data *tfd, GHashTable *table)
2289 {
2290 if (IDL_NODE_TYPE (tfd->tree) == IDLN_FORWARD_DCL) {
2291 char *s = IDL_ns_ident_to_qstring (IDL_FORWARD_DCL (tfd->tree).ident, "::", 0);
2292
2293 if (!g_hash_table_lookup_extended (table, s, NULL, NULL))
2294 g_hash_table_insert (table, s, tfd->tree);
2295 else
2296 g_free (s);
2297 }
2298
2299 return TRUE;
2300 }
2301
resolve_forward_dcls(IDL_tree_func_data * tfd,GHashTable * table)2302 static int resolve_forward_dcls (IDL_tree_func_data *tfd, GHashTable *table)
2303 {
2304 if (IDL_NODE_TYPE (tfd->tree) == IDLN_INTERFACE) {
2305 char *orig, *s = IDL_ns_ident_to_qstring (IDL_INTERFACE (tfd->tree).ident, "::", 0);
2306
2307 if (g_hash_table_lookup_extended (table, s, (gpointer)&orig, NULL)) {
2308 g_hash_table_remove (table, orig);
2309 g_free (orig);
2310 }
2311 g_free (s);
2312 }
2313
2314 return TRUE;
2315 }
2316
print_unresolved_forward_dcls(char * s,IDL_tree p)2317 static int print_unresolved_forward_dcls (char *s, IDL_tree p)
2318 {
2319 if (__IDL_flags & IDLF_PEDANTIC)
2320 IDL_tree_error (p, "Unresolved forward declaration `%s'", s);
2321 else
2322 IDL_tree_warning (p,
2323 IDL_WARNING1, "Unresolved forward declaration `%s'", s);
2324 g_free (s);
2325
2326 return TRUE;
2327 }
2328
IDL_tree_process_forward_dcls(IDL_tree * p,IDL_ns ns)2329 void IDL_tree_process_forward_dcls (IDL_tree *p, IDL_ns ns)
2330 {
2331 GHashTable *table = g_hash_table_new (IDL_strcase_hash, IDL_strcase_equal);
2332 gint total, resolved;
2333
2334 IDL_tree_walk_in_order (*p, (IDL_tree_func) load_forward_dcls, table);
2335 total = g_hash_table_size (table);
2336 IDL_tree_walk_in_order (*p, (IDL_tree_func) resolve_forward_dcls, table);
2337 resolved = total - g_hash_table_size (table);
2338 g_hash_table_foreach (table, (GHFunc) print_unresolved_forward_dcls, NULL);
2339 g_hash_table_destroy (table);
2340 if (__IDL_flags & IDLF_VERBOSE)
2341 g_message ("Forward declarations resolved: %d of %d", resolved, total);
2342 }
2343
2344 /* Inhibit Creation Removal */
load_inhibits(IDL_tree_func_data * tfd,GHashTable * table)2345 static int load_inhibits (IDL_tree_func_data *tfd, GHashTable *table)
2346 {
2347 IDL_tree p, q, *list_head;
2348
2349 p = tfd->tree;
2350
2351 if (p != NULL &&
2352 IDL_NODE_UP (p) &&
2353 IDL_NODE_TYPE (IDL_NODE_UP (p)) == IDLN_LIST &&
2354 IDL_NODE_DECLSPEC (p) & IDLF_DECLSPEC_INHIBIT &&
2355 !g_hash_table_lookup_extended (table, IDL_NODE_UP (p), NULL, NULL)) {
2356 list_head = NULL;
2357 q = IDL_NODE_UP (IDL_NODE_UP (p));
2358 if (q) {
2359 switch (IDL_NODE_TYPE (q)) {
2360 case IDLN_MODULE:
2361 list_head = &IDL_MODULE (q).definition_list;
2362 break;
2363
2364 case IDLN_INTERFACE:
2365 list_head = &IDL_INTERFACE (q).body;
2366 break;
2367
2368 default:
2369 g_warning ("Unhandled node %s in load_inhibits",
2370 IDL_NODE_TYPE_NAME (q));
2371 break;
2372 }
2373 }
2374 g_hash_table_insert (table, IDL_NODE_UP (p), list_head);
2375
2376 return FALSE;
2377 }
2378
2379 return TRUE;
2380 }
2381
IDL_tree_remove_inhibits(IDL_tree * tree,IDL_ns ns)2382 void IDL_tree_remove_inhibits (IDL_tree *tree, IDL_ns ns)
2383 {
2384 RemoveListNodeData data;
2385 GHashTable *table = g_hash_table_new (g_direct_hash, g_direct_equal);
2386 gint removed;
2387
2388 g_return_if_fail (tree != NULL);
2389 g_return_if_fail (ns != NULL);
2390
2391 IDL_tree_walk_in_order (*tree, (IDL_tree_func) load_inhibits, table);
2392 removed = g_hash_table_size (table);
2393 data.root = tree;
2394 data.removed_nodes = IDL_NS (ns).inhibits;
2395 g_hash_table_foreach (table, (GHFunc) remove_list_node, &data);
2396 g_hash_table_destroy (table);
2397 if (__IDL_flags & IDLF_VERBOSE)
2398 g_message ("Inhibited nodes removed: %d", removed);
2399 }
2400
2401 /* Multi-Pass Empty Module Removal */
load_empty_modules(IDL_tree_func_data * tfd,GHashTable * table)2402 static int load_empty_modules (IDL_tree_func_data *tfd, GHashTable *table)
2403 {
2404 IDL_tree p, q, *list_head;
2405
2406 p = tfd->tree;
2407
2408 if (IDL_NODE_TYPE (p) == IDLN_MODULE &&
2409 IDL_MODULE (p).definition_list == NULL &&
2410 IDL_NODE_UP (p) &&
2411 IDL_NODE_TYPE (IDL_NODE_UP (p)) == IDLN_LIST &&
2412 !g_hash_table_lookup_extended (table, IDL_NODE_UP (p), NULL, NULL)) {
2413
2414 list_head = NULL;
2415 q = IDL_NODE_UP (IDL_NODE_UP (p));
2416 if (q) {
2417 assert (IDL_NODE_TYPE (q) == IDLN_MODULE);
2418 list_head = &IDL_MODULE (q).definition_list;
2419 }
2420 g_hash_table_insert (table, IDL_NODE_UP (p), list_head);
2421 }
2422
2423 return TRUE;
2424 }
2425
IDL_tree_remove_empty_modules(IDL_tree * p,IDL_ns ns)2426 void IDL_tree_remove_empty_modules (IDL_tree *p, IDL_ns ns)
2427 {
2428 RemoveListNodeData data;
2429 gboolean done = FALSE;
2430 gint removed = 0;
2431
2432 data.root = p;
2433 data.removed_nodes = NULL;
2434
2435 while (!done) {
2436 GHashTable *table = g_hash_table_new (g_direct_hash, g_direct_equal);
2437 IDL_tree_walk_in_order (*p, (IDL_tree_func) load_empty_modules, table);
2438 removed += g_hash_table_size (table);
2439 done = g_hash_table_size (table) == 0;
2440 g_hash_table_foreach (table, (GHFunc) remove_list_node, &data);
2441 g_hash_table_destroy (table);
2442 }
2443 if (__IDL_flags & IDLF_VERBOSE)
2444 g_message ("Empty modules removed: %d", removed);
2445 }
2446
2447 /*
2448 * IDL_tree to IDL backend
2449 */
2450
2451 #define DELIM_COMMA ", "
2452 #define DELIM_ARRAY "]["
2453 #define DELIM_SPACE " "
2454
2455 #define indent() ++data->ilev
2456 #define unindent() --data->ilev
2457 #define doindent() do { \
2458 int i; \
2459 if (!(data->flags & IDLF_OUTPUT_NO_NEWLINES)) \
2460 for (i = 0; i < data->ilev; ++i) { \
2461 switch (data->mode) { \
2462 case OUTPUT_FILE: \
2463 fputc ('\t', data->u.o); \
2464 break; \
2465 \
2466 case OUTPUT_STRING: \
2467 g_string_append_c (data->u.s, '\t'); \
2468 break; \
2469 \
2470 default: \
2471 break; \
2472 } \
2473 } \
2474 else if (data->ilev > 0) \
2475 dataf (data, DELIM_SPACE); \
2476 } while (0)
2477 #define nl() do { \
2478 if (!(data->flags & IDLF_OUTPUT_NO_NEWLINES)) { \
2479 switch (data->mode) { \
2480 case OUTPUT_FILE: \
2481 fputc ('\n', data->u.o); \
2482 break; \
2483 \
2484 case OUTPUT_STRING: \
2485 g_string_append_c (data->u.s, '\n'); \
2486 break; \
2487 \
2488 default: \
2489 break; \
2490 } \
2491 } \
2492 } while (0)
2493 #define save_flag(flagbit,val) do { \
2494 tfd->data = GUINT_TO_POINTER ( \
2495 GPOINTER_TO_UINT (tfd->data) | \
2496 (data->flagbit ? (1U << flagbit##bit) : 0)); \
2497 data->flagbit = val; \
2498 } while (0)
2499 #define restore_flag(flagbit) do { \
2500 data->flagbit = (GPOINTER_TO_UINT ( \
2501 tfd->data) >> flagbit##bit) & 1U; \
2502 } while (0)
2503
2504 typedef struct {
2505 IDL_ns ns;
2506 enum {
2507 OUTPUT_FILE,
2508 OUTPUT_STRING
2509 } mode;
2510 union {
2511 FILE *o;
2512 GString *s;
2513 } u;
2514 int ilev;
2515 unsigned long flags;
2516
2517 #define identsbit 0
2518 guint idents : 1;
2519
2520 #define literalsbit 1
2521 guint literals : 1;
2522
2523 #define inline_propsbit 2
2524 guint inline_props : 1;
2525
2526 #define su_defbit 3
2527 guint su_def : 1;
2528 } IDL_output_data;
2529
2530 static void dataf (IDL_output_data *data, const char *fmt, ...)
2531 G_GNUC_PRINTF (2, 3);
2532
2533 static void idataf (IDL_output_data *data, const char *fmt, ...)
2534 G_GNUC_PRINTF (2, 3);
2535
dataf(IDL_output_data * data,const char * fmt,...)2536 static void dataf (IDL_output_data *data, const char *fmt, ...)
2537 {
2538 gchar *buffer;
2539 va_list args;
2540
2541 va_start (args, fmt);
2542 switch (data->mode) {
2543 case OUTPUT_FILE:
2544 vfprintf (data->u.o, fmt, args);
2545 break;
2546
2547 case OUTPUT_STRING:
2548 buffer = g_strdup_vprintf (fmt, args);
2549 g_string_append (data->u.s, buffer);
2550 g_free (buffer);
2551 break;
2552
2553 default:
2554 break;
2555 }
2556 va_end (args);
2557 }
2558
idataf(IDL_output_data * data,const char * fmt,...)2559 static void idataf (IDL_output_data *data, const char *fmt, ...)
2560 {
2561 gchar *buffer;
2562 va_list args;
2563
2564 va_start (args, fmt);
2565 doindent ();
2566 switch (data->mode) {
2567 case OUTPUT_FILE:
2568 vfprintf (data->u.o, fmt, args);
2569 break;
2570
2571 case OUTPUT_STRING:
2572 buffer = g_strdup_vprintf (fmt, args);
2573 g_string_append (data->u.s, buffer);
2574 g_free (buffer);
2575 break;
2576
2577 default:
2578 break;
2579 }
2580 va_end (args);
2581 }
2582
2583 static gboolean IDL_emit_node_pre_func (IDL_tree_func_data *tfd, IDL_output_data *data);
2584 static gboolean IDL_emit_node_post_func (IDL_tree_func_data *tfd, IDL_output_data *data);
2585
2586 typedef struct {
2587 IDL_tree_func pre_func;
2588 IDL_tree_func post_func;
2589 IDL_tree_type type, type2;
2590 gboolean limit;
2591 IDL_output_data *data;
2592 const char *delim;
2593 gboolean hit;
2594 } IDL_output_delim_data;
2595
IDL_output_delim_match(IDL_tree_func_data * tfd,IDL_output_delim_data * delim)2596 static gboolean IDL_output_delim_match (IDL_tree_func_data *tfd, IDL_output_delim_data *delim)
2597 {
2598 return delim->type == IDLN_ANY ||
2599 IDL_NODE_TYPE (tfd->tree) == delim->type ||
2600 IDL_NODE_TYPE (tfd->tree) == delim->type2;
2601 }
2602
IDL_output_delim_pre(IDL_tree_func_data * tfd,IDL_output_delim_data * delim)2603 static gboolean IDL_output_delim_pre (IDL_tree_func_data *tfd, IDL_output_delim_data *delim)
2604 {
2605 if (IDL_output_delim_match (tfd, delim)) {
2606 if (delim->hit)
2607 dataf (delim->data, "%s", delim->delim);
2608 else
2609 delim->hit = TRUE;
2610 return delim->pre_func
2611 ? (*delim->pre_func) (tfd, delim->data)
2612 : TRUE;
2613 } else {
2614 if (!delim->limit)
2615 return delim->pre_func
2616 ? (*delim->pre_func) (tfd, delim->data)
2617 : TRUE;
2618 else
2619 return TRUE;
2620 }
2621 }
2622
IDL_output_delim_post(IDL_tree_func_data * tfd,IDL_output_delim_data * delim)2623 static gboolean IDL_output_delim_post (IDL_tree_func_data *tfd, IDL_output_delim_data *delim)
2624 {
2625 if (delim->limit && !IDL_output_delim_match (tfd, delim))
2626 return TRUE;
2627
2628 return delim->post_func
2629 ? (*delim->post_func) (tfd, delim->data)
2630 : TRUE;
2631 }
2632
IDL_output_delim(IDL_tree p,IDL_tree_func_data * current,IDL_output_data * data,IDL_tree_func pre_func,IDL_tree_func post_func,IDL_tree_type type,IDL_tree_type type2,gboolean limit,const char * str)2633 static void IDL_output_delim (IDL_tree p, IDL_tree_func_data *current,
2634 IDL_output_data *data,
2635 IDL_tree_func pre_func, IDL_tree_func post_func,
2636 IDL_tree_type type, IDL_tree_type type2,
2637 gboolean limit,
2638 const char *str)
2639 {
2640 IDL_output_delim_data delim;
2641
2642 delim.pre_func = pre_func;
2643 delim.post_func = post_func;
2644 delim.type = type;
2645 delim.type2 = type2;
2646 delim.limit = limit;
2647 delim.data = data;
2648 delim.hit = FALSE;
2649 delim.delim = str;
2650
2651 IDL_tree_walk2 (p, current, /*flags*/0,
2652 (IDL_tree_func) IDL_output_delim_pre,
2653 (IDL_tree_func) IDL_output_delim_post,
2654 &delim);
2655 }
2656
2657 typedef struct {
2658 IDL_output_data *data;
2659 gboolean hit;
2660 } IDL_property_emit_data;
2661
IDL_emit_IDL_property(const char * key,const char * value,IDL_property_emit_data * emit_data)2662 static void IDL_emit_IDL_property (const char *key, const char *value,
2663 IDL_property_emit_data *emit_data)
2664 {
2665 IDL_output_data *data = emit_data->data;
2666
2667 if (!emit_data->hit)
2668 emit_data->hit = TRUE;
2669 else
2670 dataf (emit_data->data, DELIM_COMMA);
2671 if (!data->inline_props) {
2672 nl ();
2673 doindent ();
2674 }
2675 if (value && *value)
2676 dataf (emit_data->data, "%s%s(%s)",
2677 key, DELIM_SPACE, value);
2678 else
2679 dataf (emit_data->data, "%s", key);
2680 }
2681
IDL_emit_IDL_properties(IDL_tree p,IDL_output_data * data)2682 static gboolean IDL_emit_IDL_properties (IDL_tree p, IDL_output_data *data)
2683 {
2684 IDL_property_emit_data emit_data;
2685
2686 if (IDL_NODE_PROPERTIES (p) &&
2687 data->flags & IDLF_OUTPUT_PROPERTIES &&
2688 g_hash_table_size (IDL_NODE_PROPERTIES (p)) > 0) {
2689 emit_data.data = data;
2690 emit_data.hit = FALSE;
2691 if (!data->inline_props)
2692 idataf (data, "[" DELIM_SPACE);
2693 else
2694 dataf (data, "[");
2695 indent ();
2696 g_hash_table_foreach (IDL_NODE_PROPERTIES (p),
2697 (GHFunc) IDL_emit_IDL_property,
2698 &emit_data);
2699 unindent ();
2700 if (!data->inline_props) {
2701 nl ();
2702 doindent ();
2703 }
2704 dataf (data, "]");
2705 if (!data->inline_props)
2706 nl ();
2707 else
2708 dataf (data, DELIM_SPACE);
2709 }
2710
2711 return TRUE;
2712 }
2713
IDL_emit_IDL_sc(IDL_tree_func_data * tfd,IDL_output_data * data)2714 static gboolean IDL_emit_IDL_sc (IDL_tree_func_data *tfd, IDL_output_data *data)
2715 {
2716 dataf (data, ";"); nl ();
2717
2718 return TRUE;
2719 }
2720
IDL_emit_IDL_indent(IDL_tree_func_data * tfd,IDL_output_data * data)2721 static gboolean IDL_emit_IDL_indent (IDL_tree_func_data *tfd, IDL_output_data *data)
2722 {
2723 doindent ();
2724
2725 return TRUE;
2726 }
2727
IDL_emit_IDL_curly_brace_open(IDL_tree_func_data * tfd,IDL_output_data * data)2728 static gboolean IDL_emit_IDL_curly_brace_open (IDL_tree_func_data *tfd, IDL_output_data *data)
2729 {
2730 dataf (data, "{"); nl (); indent ();
2731
2732 return TRUE;
2733 }
2734
IDL_emit_IDL_curly_brace_close(IDL_tree_func_data * tfd,IDL_output_data * data)2735 static gboolean IDL_emit_IDL_curly_brace_close (IDL_tree_func_data *tfd, IDL_output_data *data)
2736 {
2737 unindent (); idataf (data, "}");
2738
2739 return TRUE;
2740 }
2741
IDL_emit_IDL_curly_brace_close_sc(IDL_tree_func_data * tfd,IDL_output_data * data)2742 static gboolean IDL_emit_IDL_curly_brace_close_sc (IDL_tree_func_data *tfd, IDL_output_data *data)
2743 {
2744 IDL_emit_IDL_curly_brace_close (tfd, data);
2745 IDL_emit_IDL_sc (tfd, data);
2746
2747 return TRUE;
2748 }
2749
IDL_emit_IDL_ident_real(IDL_tree_func_data * tfd,IDL_output_data * data)2750 static gboolean IDL_emit_IDL_ident_real (IDL_tree_func_data *tfd, IDL_output_data *data)
2751 {
2752 IDL_tree_func_data *up_path;
2753 IDL_tree up_real, scope;
2754 char *s;
2755 int levels;
2756
2757 up_path = tfd;
2758 up_real = tfd->tree;
2759 while (up_path && up_real) {
2760 if (IDL_NODE_TYPE (up_path->tree) != IDL_NODE_TYPE (up_real))
2761 break;
2762 up_path = up_path->up;
2763 up_real = IDL_NODE_UP (up_real);
2764 }
2765
2766 assert (IDL_NODE_TYPE (tfd->tree) == IDLN_IDENT);
2767
2768 if (!up_real || data->flags & IDLF_OUTPUT_NO_QUALIFY_IDENTS) {
2769 /* TODO: If the IDENT is also a keyword, escape it by
2770 prepending an underscore. */
2771 dataf (data, "%s", IDL_IDENT (tfd->tree).str);
2772 } else {
2773 if (up_path == NULL) {
2774 levels = 0;
2775 } else {
2776 /* Determine minimal required levels of scoping */
2777 scope = up_path->tree ? up_path->tree : up_real;
2778 levels = IDL_ns_scope_levels_from_here (data->ns, tfd->tree, scope);
2779 }
2780 s = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS (tfd->tree), "::", levels);
2781 dataf (data, "%s", s);
2782 g_free (s);
2783 }
2784
2785 return TRUE;
2786 }
2787
IDL_emit_IDL_ident_pre(IDL_tree_func_data * tfd,IDL_output_data * data)2788 static gboolean IDL_emit_IDL_ident_pre (IDL_tree_func_data *tfd, IDL_output_data *data)
2789 {
2790 if (data->idents)
2791 IDL_emit_IDL_ident_real (tfd, data);
2792
2793 return TRUE;
2794 }
2795
IDL_emit_IDL_ident_force_pre(IDL_tree_func_data * tfd,IDL_output_data * data)2796 static gboolean IDL_emit_IDL_ident_force_pre (IDL_tree_func_data *tfd, IDL_output_data *data)
2797 {
2798 IDL_emit_IDL_ident_real (tfd, data);
2799
2800 return TRUE;
2801 }
2802
IDL_emit_IDL_ident(IDL_tree ident,IDL_tree_func_data * tfd,IDL_output_data * data)2803 static gboolean IDL_emit_IDL_ident (IDL_tree ident, IDL_tree_func_data *tfd, IDL_output_data *data)
2804 {
2805 IDL_tree_walk2 (ident, tfd, /*flags*/0,
2806 (IDL_tree_func) IDL_emit_IDL_ident_real, NULL,
2807 data);
2808
2809 return TRUE;
2810 }
2811
IDL_emit_IDL_literal(IDL_tree p,IDL_output_data * data)2812 static gboolean IDL_emit_IDL_literal (IDL_tree p, IDL_output_data *data)
2813 {
2814 switch (IDL_NODE_TYPE (p)) {
2815 case IDLN_FLOAT:
2816 dataf (data, "%f", IDL_FLOAT (p).value);
2817 break;
2818
2819 case IDLN_INTEGER:
2820 /* FIXME: sign */
2821 dataf (data, "%" IDL_LL "d", IDL_INTEGER (p).value);
2822 break;
2823
2824 case IDLN_FIXED:
2825 dataf (data, "%s", IDL_FIXED (p).value);
2826 break;
2827
2828 case IDLN_CHAR:
2829 dataf (data, "'%s'", IDL_CHAR (p).value);
2830 break;
2831
2832 case IDLN_WIDE_CHAR:
2833 /* dataf (data, "'%s'", IDL_WIDE_CHAR (p).value); */
2834 g_warning ("IDL_emit_IDL_literal: %s is currently unhandled",
2835 "Wide character output");
2836 break;
2837
2838 case IDLN_BOOLEAN:
2839 dataf (data, "%s", IDL_BOOLEAN (p).value ? "TRUE" : "FALSE");
2840 break;
2841
2842 case IDLN_STRING:
2843 dataf (data, "\"%s\"", IDL_STRING (p).value);
2844 break;
2845
2846 case IDLN_WIDE_STRING:
2847 /* dataf (data, "\"%s\"", IDL_STRING (p).value); */
2848 g_warning ("IDL_emit_IDL_literal: %s is currently unhandled",
2849 "Wide string output");
2850 break;
2851
2852 default:
2853 g_warning ("Unhandled literal: %s", IDL_NODE_TYPE_NAME (p));
2854 break;
2855 }
2856
2857 return TRUE;
2858 }
2859
IDL_emit_IDL_literal_pre(IDL_tree_func_data * tfd,IDL_output_data * data)2860 static gboolean IDL_emit_IDL_literal_pre (IDL_tree_func_data *tfd, IDL_output_data *data)
2861 {
2862 if (data->literals)
2863 IDL_emit_IDL_literal (tfd->tree, data);
2864
2865 return TRUE;
2866 }
2867
IDL_emit_IDL_literal_force_pre(IDL_tree_func_data * tfd,IDL_output_data * data)2868 static gboolean IDL_emit_IDL_literal_force_pre (IDL_tree_func_data *tfd, IDL_output_data *data)
2869 {
2870 IDL_emit_IDL_literal (tfd->tree, data);
2871
2872 return TRUE;
2873 }
2874
IDL_emit_IDL_type_pre(IDL_tree_func_data * tfd,IDL_output_data * data)2875 static gboolean IDL_emit_IDL_type_pre (IDL_tree_func_data *tfd, IDL_output_data *data)
2876 {
2877 IDL_tree p, q;
2878
2879 p = tfd->tree;
2880
2881 switch (IDL_NODE_TYPE (p)) {
2882 case IDLN_IDENT:
2883 IDL_emit_IDL_ident (p, tfd, data);
2884 break;
2885
2886 case IDLN_TYPE_CHAR:
2887 dataf (data, "char");
2888 break;
2889
2890 case IDLN_TYPE_WIDE_CHAR:
2891 dataf (data, "wchar");
2892 break;
2893
2894 case IDLN_TYPE_BOOLEAN:
2895 dataf (data, "boolean");
2896 break;
2897
2898 case IDLN_TYPE_OCTET:
2899 dataf (data, "octet");
2900 break;
2901
2902 case IDLN_TYPE_ANY:
2903 dataf (data, "any");
2904 break;
2905
2906 case IDLN_TYPE_OBJECT:
2907 dataf (data, "Object");
2908 break;
2909
2910 case IDLN_TYPE_TYPECODE:
2911 dataf (data, "TypeCode");
2912 break;
2913
2914 case IDLN_TYPE_FLOAT:
2915 switch (IDL_TYPE_FLOAT (p).f_type) {
2916 case IDL_FLOAT_TYPE_FLOAT: dataf (data, "float"); break;
2917 case IDL_FLOAT_TYPE_DOUBLE: dataf (data, "double"); break;
2918 case IDL_FLOAT_TYPE_LONGDOUBLE: dataf (data, "long" DELIM_SPACE "double"); break;
2919 }
2920 break;
2921
2922 case IDLN_TYPE_FIXED:
2923 dataf (data, "fixed<");
2924 IDL_emit_IDL_literal (IDL_TYPE_FIXED (p).positive_int_const, data);
2925 dataf (data, DELIM_COMMA);
2926 IDL_emit_IDL_literal (IDL_TYPE_FIXED (p).integer_lit, data);
2927 dataf (data, ">");
2928 return FALSE;
2929
2930 case IDLN_TYPE_INTEGER:
2931 if (!IDL_TYPE_INTEGER (p).f_signed)
2932 dataf (data, "unsigned" DELIM_SPACE);
2933 switch (IDL_TYPE_INTEGER (p).f_type) {
2934 case IDL_INTEGER_TYPE_SHORT: dataf (data, "short"); break;
2935 case IDL_INTEGER_TYPE_LONG: dataf (data, "long"); break;
2936 case IDL_INTEGER_TYPE_LONGLONG: dataf (data, "long" DELIM_SPACE "long"); break;
2937 }
2938 break;
2939
2940 case IDLN_TYPE_STRING:
2941 case IDLN_TYPE_WIDE_STRING:
2942 if (IDL_NODE_TYPE (p) == IDLN_TYPE_STRING) {
2943 dataf (data, "string");
2944 q = IDL_TYPE_STRING (p).positive_int_const;
2945 } else {
2946 dataf (data, "wstring");
2947 q = IDL_TYPE_WIDE_STRING (p).positive_int_const;
2948 }
2949 if (q) {
2950 dataf (data, "<");
2951 if (IDL_NODE_TYPE (p) == IDLN_TYPE_STRING)
2952 IDL_emit_IDL_literal (
2953 IDL_TYPE_STRING (p).positive_int_const, data);
2954 else
2955 IDL_emit_IDL_literal (
2956 IDL_TYPE_WIDE_STRING (p).positive_int_const, data);
2957 dataf (data, ">");
2958 }
2959 return FALSE;
2960
2961 case IDLN_TYPE_ENUM:
2962 IDL_emit_IDL_indent (tfd, data);
2963 data->inline_props = TRUE;
2964 IDL_emit_IDL_properties (IDL_TYPE_ENUM (tfd->tree).ident, data);
2965 dataf (data, "enum" DELIM_SPACE);
2966 IDL_emit_IDL_ident (IDL_TYPE_ENUM (p).ident, tfd, data);
2967 dataf (data, DELIM_SPACE "{" DELIM_SPACE);
2968 IDL_output_delim (IDL_TYPE_ENUM (p).enumerator_list, tfd, data,
2969 (IDL_tree_func) IDL_emit_IDL_ident_force_pre, NULL,
2970 IDLN_IDENT, IDLN_NONE, TRUE, DELIM_COMMA);
2971 dataf (data, DELIM_SPACE "};"); nl ();
2972 return FALSE;
2973
2974 case IDLN_TYPE_ARRAY:
2975 IDL_emit_IDL_ident (IDL_TYPE_ARRAY (p).ident, tfd, data);
2976 dataf (data, "[");
2977 IDL_output_delim (IDL_TYPE_ARRAY (p).size_list, tfd, data,
2978 (IDL_tree_func) IDL_emit_IDL_literal_force_pre, NULL,
2979 IDLN_INTEGER, IDLN_NONE, TRUE, DELIM_ARRAY);
2980 dataf (data, "]");
2981 return FALSE;
2982
2983 case IDLN_TYPE_SEQUENCE:
2984 dataf (data, "sequence<");
2985 save_flag (idents, TRUE);
2986 IDL_tree_walk2 (IDL_TYPE_SEQUENCE (tfd->tree).simple_type_spec, tfd,/*flags*/0,
2987 (IDL_tree_func) IDL_emit_node_pre_func,
2988 (IDL_tree_func) IDL_emit_node_post_func,
2989 data);
2990 restore_flag (idents);
2991 if (IDL_TYPE_SEQUENCE (tfd->tree).positive_int_const) {
2992 dataf (data, DELIM_COMMA);
2993 IDL_emit_IDL_literal (
2994 IDL_TYPE_SEQUENCE (tfd->tree).positive_int_const, data);
2995 }
2996 dataf (data, ">");
2997 return FALSE;
2998
2999 case IDLN_TYPE_STRUCT:
3000 if (!data->su_def)
3001 doindent ();
3002 save_flag (su_def, TRUE);
3003 data->inline_props = TRUE;
3004 IDL_emit_IDL_properties (IDL_TYPE_STRUCT (tfd->tree).ident, data);
3005 dataf (data, "struct" DELIM_SPACE);
3006 IDL_emit_IDL_ident (IDL_TYPE_STRUCT (p).ident, tfd, data);
3007 dataf (data, DELIM_SPACE);
3008 IDL_emit_IDL_curly_brace_open (tfd, data);
3009 IDL_tree_walk2 (IDL_TYPE_STRUCT (p).member_list, tfd,/*flags*/0,
3010 (IDL_tree_func) IDL_emit_node_pre_func,
3011 (IDL_tree_func) IDL_emit_node_post_func,
3012 data);
3013 restore_flag (su_def);
3014 if (data->su_def)
3015 IDL_emit_IDL_curly_brace_close (tfd, data);
3016 else
3017 IDL_emit_IDL_curly_brace_close_sc (tfd, data);
3018 return FALSE;
3019
3020 case IDLN_TYPE_UNION:
3021 if (!data->su_def)
3022 doindent ();
3023 save_flag (su_def, TRUE);
3024 data->inline_props = TRUE;
3025 IDL_emit_IDL_properties (IDL_TYPE_UNION (tfd->tree).ident, data);
3026 dataf (data, "union" DELIM_SPACE);
3027 IDL_emit_IDL_ident (IDL_TYPE_UNION (p).ident, tfd, data);
3028 dataf (data, DELIM_SPACE);
3029 dataf (data, "switch" DELIM_SPACE "(");
3030 save_flag (idents, TRUE);
3031 IDL_tree_walk2 (IDL_TYPE_UNION (p).switch_type_spec, tfd,/*flags*/0,
3032 (IDL_tree_func) IDL_emit_node_pre_func,
3033 (IDL_tree_func) IDL_emit_node_post_func,
3034 data);
3035 restore_flag (idents);
3036 dataf (data, ")" DELIM_SPACE "{"); nl ();
3037 IDL_tree_walk2 (IDL_TYPE_UNION (p).switch_body, tfd,/*flags*/0,
3038 (IDL_tree_func) IDL_emit_node_pre_func,
3039 (IDL_tree_func) IDL_emit_node_post_func,
3040 data);
3041 restore_flag (su_def);
3042 if (data->su_def)
3043 idataf (data, "}");
3044 else {
3045 idataf (data, "};");
3046 nl ();
3047 }
3048 return FALSE;
3049
3050 default:
3051 break;
3052 }
3053
3054 return TRUE;
3055 }
3056
IDL_emit_IDL_module_all(IDL_tree_func_data * tfd,IDL_output_data * data)3057 static gboolean IDL_emit_IDL_module_all (IDL_tree_func_data *tfd, IDL_output_data *data)
3058 {
3059 if (tfd->step == 0) {
3060 idataf (data, "module" DELIM_SPACE);
3061 IDL_emit_IDL_ident (IDL_MODULE (tfd->tree).ident, tfd, data);
3062 dataf (data, DELIM_SPACE);
3063 IDL_emit_IDL_curly_brace_open (tfd, data);
3064 save_flag (idents, FALSE);
3065 } else {
3066 restore_flag (idents);
3067 IDL_emit_IDL_curly_brace_close_sc (tfd, data);
3068 }
3069
3070 return TRUE;
3071 }
3072
IDL_emit_IDL_interface_all(IDL_tree_func_data * tfd,IDL_output_data * data)3073 static gboolean IDL_emit_IDL_interface_all (IDL_tree_func_data *tfd, IDL_output_data *data)
3074 {
3075 if (tfd->step == 0) {
3076 data->inline_props = FALSE;
3077 IDL_emit_IDL_properties (IDL_INTERFACE (tfd->tree).ident, data);
3078 idataf (data, "interface" DELIM_SPACE);
3079 IDL_emit_IDL_ident (IDL_INTERFACE (tfd->tree).ident, tfd, data);
3080 dataf (data, DELIM_SPACE);
3081 if (IDL_INTERFACE (tfd->tree).inheritance_spec) {
3082 dataf (data, ":" DELIM_SPACE);
3083 IDL_output_delim (IDL_INTERFACE (tfd->tree).inheritance_spec, tfd, data,
3084 (IDL_tree_func) IDL_emit_IDL_ident_force_pre, NULL,
3085 IDLN_IDENT, IDLN_NONE, TRUE, DELIM_COMMA);
3086 dataf (data, DELIM_SPACE);
3087 }
3088 IDL_emit_IDL_curly_brace_open (tfd, data);
3089 save_flag (idents, FALSE);
3090 } else {
3091 restore_flag (idents);
3092 IDL_emit_IDL_curly_brace_close_sc (tfd, data);
3093 }
3094
3095 return TRUE;
3096 }
3097
IDL_emit_IDL_forward_dcl_pre(IDL_tree_func_data * tfd,IDL_output_data * data)3098 static gboolean IDL_emit_IDL_forward_dcl_pre (IDL_tree_func_data *tfd, IDL_output_data *data)
3099 {
3100 idataf (data, "interface" DELIM_SPACE);
3101 IDL_emit_IDL_ident (IDL_FORWARD_DCL (tfd->tree).ident, tfd, data);
3102
3103 return TRUE;
3104 }
3105
IDL_emit_IDL_attr_dcl_pre(IDL_tree_func_data * tfd,IDL_output_data * data)3106 static gboolean IDL_emit_IDL_attr_dcl_pre (IDL_tree_func_data *tfd, IDL_output_data *data)
3107 {
3108 IDL_emit_IDL_indent (tfd, data);
3109 data->inline_props = TRUE;
3110 IDL_emit_IDL_properties (IDL_LIST (IDL_ATTR_DCL (tfd->tree).simple_declarations).data,
3111 data);
3112 if (IDL_ATTR_DCL (tfd->tree).f_readonly) dataf (data, "readonly" DELIM_SPACE);
3113 dataf (data, "attribute" DELIM_SPACE);
3114 save_flag (idents, TRUE);
3115 IDL_tree_walk2 (IDL_ATTR_DCL (tfd->tree).param_type_spec, tfd,/*flags*/0,
3116 (IDL_tree_func) IDL_emit_node_pre_func,
3117 (IDL_tree_func) IDL_emit_node_post_func,
3118 data);
3119 restore_flag (idents);
3120 dataf (data, DELIM_SPACE);
3121 IDL_output_delim (IDL_ATTR_DCL (tfd->tree).simple_declarations, tfd, data,
3122 (IDL_tree_func) IDL_emit_IDL_ident_force_pre, NULL,
3123 IDLN_IDENT, IDLN_NONE, TRUE, DELIM_COMMA);
3124 IDL_emit_IDL_sc (tfd, data);
3125
3126 return FALSE;
3127 }
3128
IDL_emit_IDL_op_dcl_pre(IDL_tree_func_data * tfd,IDL_output_data * data)3129 static gboolean IDL_emit_IDL_op_dcl_pre (IDL_tree_func_data *tfd, IDL_output_data *data)
3130 {
3131 IDL_emit_IDL_indent (tfd, data);
3132 data->inline_props = TRUE;
3133 IDL_emit_IDL_properties (IDL_OP_DCL (tfd->tree).ident, data);
3134 if (IDL_OP_DCL (tfd->tree).f_oneway) dataf (data, "oneway" DELIM_SPACE);
3135 if (IDL_OP_DCL (tfd->tree).op_type_spec) {
3136 save_flag (idents, TRUE);
3137 IDL_tree_walk2 (IDL_OP_DCL (tfd->tree).op_type_spec, tfd,/*flags*/0,
3138 (IDL_tree_func) IDL_emit_node_pre_func,
3139 (IDL_tree_func) IDL_emit_node_post_func,
3140 data);
3141 restore_flag (idents);
3142 } else
3143 dataf (data, "void");
3144 dataf (data, DELIM_SPACE "%s" DELIM_SPACE "(",
3145 IDL_IDENT (IDL_OP_DCL (tfd->tree).ident).str);
3146 if (IDL_OP_DCL (tfd->tree).parameter_dcls)
3147 IDL_output_delim (IDL_OP_DCL (tfd->tree).parameter_dcls, tfd, data,
3148 (IDL_tree_func) IDL_emit_node_pre_func,
3149 (IDL_tree_func) IDL_emit_node_post_func,
3150 IDLN_PARAM_DCL, IDLN_NONE, FALSE, DELIM_COMMA);
3151 if (IDL_OP_DCL (tfd->tree).f_varargs)
3152 dataf (data, DELIM_COMMA "...");
3153 dataf (data, ")");
3154 if (IDL_OP_DCL (tfd->tree).raises_expr) {
3155 nl (); indent ();
3156 idataf (data, DELIM_SPACE "raises" DELIM_SPACE "(");
3157 IDL_output_delim (IDL_OP_DCL (tfd->tree).raises_expr, tfd, data,
3158 (IDL_tree_func) IDL_emit_IDL_ident_force_pre, NULL,
3159 IDLN_IDENT, IDLN_NONE, TRUE, DELIM_COMMA);
3160 dataf (data, ")");
3161 unindent ();
3162 }
3163 if (IDL_OP_DCL (tfd->tree).context_expr) {
3164 nl (); indent ();
3165 idataf (data, DELIM_SPACE "context" DELIM_SPACE "(");
3166 IDL_output_delim (IDL_OP_DCL (tfd->tree).context_expr, tfd, data,
3167 (IDL_tree_func) IDL_emit_IDL_literal_force_pre, NULL,
3168 IDLN_STRING, IDLN_NONE, TRUE, DELIM_COMMA);
3169 dataf (data, ")");
3170 unindent ();
3171 }
3172 IDL_emit_IDL_sc (tfd, data);
3173
3174 return FALSE;
3175 }
3176
IDL_emit_IDL_param_dcl_pre(IDL_tree_func_data * tfd,IDL_output_data * data)3177 static gboolean IDL_emit_IDL_param_dcl_pre (IDL_tree_func_data *tfd, IDL_output_data *data)
3178 {
3179 data->inline_props = TRUE;
3180 IDL_emit_IDL_properties (IDL_PARAM_DCL (tfd->tree).simple_declarator, data);
3181 switch (IDL_PARAM_DCL (tfd->tree).attr) {
3182 case IDL_PARAM_IN: dataf (data, "in" DELIM_SPACE); break;
3183 case IDL_PARAM_OUT: dataf (data, "out" DELIM_SPACE); break;
3184 case IDL_PARAM_INOUT: dataf (data, "inout" DELIM_SPACE); break;
3185 }
3186 save_flag (idents, TRUE);
3187 IDL_tree_walk2 (IDL_PARAM_DCL (tfd->tree).param_type_spec, tfd,/*flags*/0,
3188 (IDL_tree_func) IDL_emit_node_pre_func,
3189 (IDL_tree_func) IDL_emit_node_post_func,
3190 data);
3191 restore_flag (idents);
3192 dataf (data, DELIM_SPACE);
3193 IDL_emit_IDL_ident (IDL_PARAM_DCL (tfd->tree).simple_declarator, tfd, data);
3194
3195 return FALSE;
3196 }
3197
IDL_emit_IDL_type_dcl_pre(IDL_tree_func_data * tfd,IDL_output_data * data)3198 static gboolean IDL_emit_IDL_type_dcl_pre (IDL_tree_func_data *tfd, IDL_output_data *data)
3199 {
3200 IDL_tree_func_data down_tfd;
3201 IDL_tree q;
3202
3203 IDL_emit_IDL_indent (tfd, data);
3204 data->inline_props = TRUE;
3205 IDL_emit_IDL_properties (IDL_LIST (IDL_TYPE_DCL (tfd->tree).dcls).data, data);
3206 dataf (data, "typedef" DELIM_SPACE);
3207 save_flag (idents, TRUE);
3208 save_flag (su_def, TRUE);
3209 IDL_tree_walk2 (IDL_TYPE_DCL (tfd->tree).type_spec, tfd,/*flags*/0,
3210 (IDL_tree_func) IDL_emit_node_pre_func,
3211 (IDL_tree_func) IDL_emit_node_post_func,
3212 data);
3213 dataf (data, DELIM_SPACE);
3214 down_tfd = *tfd;
3215 down_tfd.up = tfd;
3216 for (q = IDL_TYPE_DCL (tfd->tree).dcls; q; q = IDL_LIST (q).next) {
3217 down_tfd.tree = q;
3218 IDL_tree_walk2 (IDL_LIST (q).data, &down_tfd,/*flags*/0,
3219 (IDL_tree_func) IDL_emit_node_pre_func,
3220 (IDL_tree_func) IDL_emit_node_post_func,
3221 data);
3222 if (IDL_LIST (q).next)
3223 dataf (data, DELIM_COMMA);
3224 }
3225 restore_flag (idents);
3226 restore_flag (su_def);
3227 IDL_emit_IDL_sc (tfd, data);
3228
3229 return FALSE;
3230 }
3231
IDL_emit_IDL_const_dcl_pre(IDL_tree_func_data * tfd,IDL_output_data * data)3232 static gboolean IDL_emit_IDL_const_dcl_pre (IDL_tree_func_data *tfd, IDL_output_data *data)
3233 {
3234 idataf (data, "const" DELIM_SPACE);
3235 save_flag (idents, TRUE);
3236 IDL_tree_walk2 (IDL_CONST_DCL (tfd->tree).const_type, tfd,/*flags*/0,
3237 (IDL_tree_func) IDL_emit_node_pre_func,
3238 (IDL_tree_func) IDL_emit_node_post_func,
3239 data);
3240 restore_flag (idents);
3241 dataf (data, DELIM_SPACE);
3242 IDL_emit_IDL_ident (IDL_CONST_DCL (tfd->tree).ident, tfd, data);
3243 dataf (data, DELIM_SPACE "=" DELIM_SPACE);
3244 save_flag (literals, TRUE);
3245 IDL_tree_walk2 (IDL_CONST_DCL (tfd->tree).const_exp, tfd,/*flags*/0,
3246 (IDL_tree_func) IDL_emit_node_pre_func,
3247 (IDL_tree_func) IDL_emit_node_post_func,
3248 data);
3249 restore_flag (literals);
3250 IDL_emit_IDL_sc (tfd, data);
3251
3252 return FALSE;
3253 }
3254
IDL_emit_IDL_except_dcl_pre(IDL_tree_func_data * tfd,IDL_output_data * data)3255 static gboolean IDL_emit_IDL_except_dcl_pre (IDL_tree_func_data *tfd, IDL_output_data *data)
3256 {
3257 idataf (data, "exception" DELIM_SPACE);
3258 IDL_emit_IDL_ident (IDL_EXCEPT_DCL (tfd->tree).ident, tfd, data);
3259 dataf (data, DELIM_SPACE);
3260 IDL_emit_IDL_curly_brace_open (tfd, data);
3261
3262 return TRUE;
3263 }
3264
IDL_emit_IDL_native_pre(IDL_tree_func_data * tfd,IDL_output_data * data)3265 static gboolean IDL_emit_IDL_native_pre (IDL_tree_func_data *tfd, IDL_output_data *data)
3266 {
3267 IDL_emit_IDL_indent (tfd, data);
3268 data->inline_props = TRUE;
3269 IDL_emit_IDL_properties (IDL_NATIVE (tfd->tree).ident, data);
3270 dataf (data, "native" DELIM_SPACE);
3271 IDL_emit_IDL_ident (IDL_NATIVE (tfd->tree).ident, tfd, data);
3272 if (IDL_NATIVE (tfd->tree).user_type)
3273 dataf (data, DELIM_SPACE "(%s)", IDL_NATIVE (tfd->tree).user_type);
3274 IDL_emit_IDL_sc (tfd, data);
3275
3276 return TRUE;
3277 }
3278
IDL_emit_IDL_case_stmt_pre(IDL_tree_func_data * tfd,IDL_output_data * data)3279 static gboolean IDL_emit_IDL_case_stmt_pre (IDL_tree_func_data *tfd, IDL_output_data *data)
3280 {
3281 IDL_tree_func_data down_tfd;
3282 IDL_tree q;
3283
3284 save_flag (idents, TRUE);
3285 save_flag (literals, TRUE);
3286 down_tfd = *tfd;
3287 down_tfd.up = tfd;
3288 for (q = IDL_CASE_STMT (tfd->tree).labels; q; q = IDL_LIST (q).next) {
3289 if (IDL_LIST (q).data) {
3290 down_tfd.tree = q;
3291 idataf (data, "case" DELIM_SPACE);
3292 IDL_tree_walk2 (IDL_LIST (q).data, &down_tfd,/*flags*/0,
3293 (IDL_tree_func) IDL_emit_node_pre_func,
3294 (IDL_tree_func) IDL_emit_node_post_func,
3295 data);
3296 dataf (data, ":");
3297 } else
3298 idataf (data, "default:");
3299 nl ();
3300 }
3301 restore_flag (literals);
3302 restore_flag (idents);
3303 indent ();
3304
3305 return FALSE;
3306 }
3307
IDL_emit_IDL_case_stmt_post(IDL_tree_func_data * tfd,IDL_output_data * data)3308 static gboolean IDL_emit_IDL_case_stmt_post (IDL_tree_func_data *tfd, IDL_output_data *data)
3309 {
3310 IDL_tree_walk2 (IDL_CASE_STMT (tfd->tree).element_spec, tfd, /*flags*/0,
3311 (IDL_tree_func) IDL_emit_node_pre_func,
3312 (IDL_tree_func) IDL_emit_node_post_func,
3313 data);
3314 unindent ();
3315
3316 return FALSE;
3317 }
3318
IDL_emit_IDL_member_pre(IDL_tree_func_data * tfd,IDL_output_data * data)3319 static gboolean IDL_emit_IDL_member_pre (IDL_tree_func_data *tfd, IDL_output_data *data)
3320 {
3321 IDL_emit_IDL_indent (tfd, data);
3322 save_flag (idents, TRUE);
3323 IDL_tree_walk2 (IDL_MEMBER (tfd->tree).type_spec, tfd, /*flags*/0,
3324 (IDL_tree_func) IDL_emit_node_pre_func,
3325 (IDL_tree_func) IDL_emit_node_post_func,
3326 data);
3327 restore_flag (idents);
3328
3329 return FALSE;
3330 }
3331
IDL_emit_IDL_member_post(IDL_tree_func_data * tfd,IDL_output_data * data)3332 static gboolean IDL_emit_IDL_member_post (IDL_tree_func_data *tfd, IDL_output_data *data)
3333 {
3334 dataf (data, DELIM_SPACE);
3335 IDL_output_delim (IDL_MEMBER (tfd->tree).dcls, tfd, data,
3336 (IDL_tree_func) IDL_emit_IDL_type_pre, NULL,
3337 IDLN_IDENT, IDLN_TYPE_ARRAY, FALSE, DELIM_COMMA);
3338 IDL_emit_IDL_sc (tfd, data);
3339
3340 return TRUE;
3341 }
3342
IDL_emit_IDL_codefrag_pre(IDL_tree_func_data * tfd,IDL_output_data * data)3343 static gboolean IDL_emit_IDL_codefrag_pre (IDL_tree_func_data *tfd, IDL_output_data *data)
3344 {
3345 if (data->flags & IDLF_OUTPUT_CODEFRAGS) {
3346 GSList *slist;
3347
3348 dataf (data, "%%{ %s", IDL_CODEFRAG (tfd->tree).desc); nl ();
3349 for (slist = IDL_CODEFRAG (tfd->tree).lines; slist; slist = slist->next) {
3350 dataf (data, "%s", (char *) slist->data); nl ();
3351 }
3352 dataf (data, "%%}"); nl ();
3353 }
3354
3355 return TRUE;
3356 }
3357
3358 struct IDL_emit_node {
3359 IDL_tree_func pre;
3360 IDL_tree_func post;
3361 };
3362
IDL_get_IDL_emission_table(void)3363 static struct IDL_emit_node * IDL_get_IDL_emission_table (void)
3364 {
3365 static gboolean initialized = FALSE;
3366 static struct IDL_emit_node table[IDLN_LAST];
3367 struct IDL_emit_node *s;
3368
3369 if (!initialized) {
3370
3371 s = &table[IDLN_MODULE];
3372 s->pre = s->post = (IDL_tree_func) IDL_emit_IDL_module_all;
3373
3374 s = &table[IDLN_INTERFACE];
3375 s->pre = s->post = (IDL_tree_func) IDL_emit_IDL_interface_all;
3376
3377 s = &table[IDLN_FORWARD_DCL];
3378 s->pre = (IDL_tree_func) IDL_emit_IDL_forward_dcl_pre;
3379 s->post = (IDL_tree_func) IDL_emit_IDL_sc;
3380
3381 s = &table[IDLN_ATTR_DCL];
3382 s->pre = (IDL_tree_func) IDL_emit_IDL_attr_dcl_pre;
3383
3384 s = &table[IDLN_OP_DCL];
3385 s->pre = (IDL_tree_func) IDL_emit_IDL_op_dcl_pre;
3386
3387 s = &table[IDLN_PARAM_DCL];
3388 s->pre = (IDL_tree_func) IDL_emit_IDL_param_dcl_pre;
3389
3390 s = &table[IDLN_TYPE_DCL];
3391 s->pre = (IDL_tree_func) IDL_emit_IDL_type_dcl_pre;
3392
3393 s = &table[IDLN_CONST_DCL];
3394 s->pre = (IDL_tree_func) IDL_emit_IDL_const_dcl_pre;
3395
3396 s = &table[IDLN_EXCEPT_DCL];
3397 s->pre = (IDL_tree_func) IDL_emit_IDL_except_dcl_pre;
3398 s->post = (IDL_tree_func) IDL_emit_IDL_curly_brace_close_sc;
3399
3400 s = &table[IDLN_MEMBER];
3401 s->pre = (IDL_tree_func) IDL_emit_IDL_member_pre;
3402 s->post = (IDL_tree_func) IDL_emit_IDL_member_post;
3403
3404 s = &table[IDLN_NATIVE];
3405 s->pre = (IDL_tree_func) IDL_emit_IDL_native_pre;
3406
3407 s = &table[IDLN_CASE_STMT];
3408 s->pre = (IDL_tree_func) IDL_emit_IDL_case_stmt_pre;
3409 s->post = (IDL_tree_func) IDL_emit_IDL_case_stmt_post;
3410
3411 s = &table[IDLN_IDENT];
3412 s->pre = (IDL_tree_func) IDL_emit_IDL_ident_pre;
3413
3414 s = &table[IDLN_CODEFRAG];
3415 s->pre = (IDL_tree_func) IDL_emit_IDL_codefrag_pre;
3416
3417 table[IDLN_TYPE_FLOAT].pre =
3418 table[IDLN_TYPE_CHAR].pre =
3419 table[IDLN_TYPE_WIDE_CHAR].pre =
3420 table[IDLN_TYPE_BOOLEAN].pre =
3421 table[IDLN_TYPE_OCTET].pre =
3422 table[IDLN_TYPE_ANY].pre =
3423 table[IDLN_TYPE_OBJECT].pre =
3424 table[IDLN_TYPE_TYPECODE].pre =
3425 table[IDLN_TYPE_FIXED].pre =
3426 table[IDLN_TYPE_INTEGER].pre =
3427 table[IDLN_TYPE_STRING].pre =
3428 table[IDLN_TYPE_WIDE_STRING].pre =
3429 table[IDLN_TYPE_ENUM].pre =
3430 table[IDLN_TYPE_ARRAY].pre =
3431 table[IDLN_TYPE_SEQUENCE].pre =
3432 table[IDLN_TYPE_STRUCT].pre =
3433 table[IDLN_TYPE_UNION].pre = (IDL_tree_func) IDL_emit_IDL_type_pre;
3434
3435 table[IDLN_FLOAT].pre =
3436 table[IDLN_INTEGER].pre =
3437 table[IDLN_FIXED].pre =
3438 table[IDLN_CHAR].pre =
3439 table[IDLN_WIDE_CHAR].pre =
3440 table[IDLN_BOOLEAN].pre =
3441 table[IDLN_STRING].pre =
3442 table[IDLN_WIDE_STRING].pre = (IDL_tree_func) IDL_emit_IDL_literal_pre;
3443
3444 initialized = TRUE;
3445 }
3446
3447 return table;
3448 }
3449
IDL_emit_node_pre_func(IDL_tree_func_data * tfd,IDL_output_data * data)3450 static gboolean IDL_emit_node_pre_func (IDL_tree_func_data *tfd, IDL_output_data *data)
3451 {
3452 const struct IDL_emit_node * const s =
3453 &IDL_get_IDL_emission_table () [IDL_NODE_TYPE (tfd->tree)];
3454
3455 if (s->pre)
3456 return (*s->pre) (tfd, data);
3457
3458 return TRUE;
3459 }
3460
IDL_emit_node_post_func(IDL_tree_func_data * tfd,IDL_output_data * data)3461 static gboolean IDL_emit_node_post_func (IDL_tree_func_data *tfd, IDL_output_data *data)
3462 {
3463 const struct IDL_emit_node * const s =
3464 &IDL_get_IDL_emission_table () [IDL_NODE_TYPE (tfd->tree)];
3465
3466 if (s->post)
3467 return (*s->post) (tfd, data);
3468
3469 return TRUE;
3470 }
3471
IDL_tree_to_IDL(IDL_tree p,IDL_ns ns,FILE * output,unsigned long output_flags)3472 void IDL_tree_to_IDL (IDL_tree p, IDL_ns ns, FILE *output, unsigned long output_flags)
3473 {
3474 IDL_output_data data;
3475
3476 g_return_if_fail (output != NULL);
3477
3478 data.ns = ns;
3479 data.mode = OUTPUT_FILE;
3480 data.u.o = output;
3481 data.flags = output_flags;
3482 data.ilev = 0;
3483 data.idents = TRUE;
3484 data.literals = TRUE;
3485 data.inline_props = TRUE;
3486 data.su_def = FALSE;
3487
3488 if (ns == NULL)
3489 data.flags |= IDLF_OUTPUT_NO_QUALIFY_IDENTS;
3490
3491 IDL_tree_walk2 (p, NULL, /*flags*/0,
3492 (IDL_tree_func) IDL_emit_node_pre_func,
3493 (IDL_tree_func) IDL_emit_node_post_func,
3494 &data);
3495 }
3496
IDL_tree_to_IDL_string(IDL_tree p,IDL_ns ns,unsigned long output_flags)3497 GString *IDL_tree_to_IDL_string (IDL_tree p, IDL_ns ns, unsigned long output_flags)
3498 {
3499 IDL_output_data data;
3500
3501 data.ns = ns;
3502 data.mode = OUTPUT_STRING;
3503 data.u.s = g_string_new (NULL);
3504 data.flags = output_flags;
3505 data.ilev = 0;
3506 data.idents = TRUE;
3507 data.literals = TRUE;
3508 data.inline_props = TRUE;
3509 data.su_def = FALSE;
3510
3511 if (ns == NULL)
3512 data.flags |= IDLF_OUTPUT_NO_QUALIFY_IDENTS;
3513
3514 IDL_tree_walk2 (p, NULL, /*flags*/0,
3515 (IDL_tree_func) IDL_emit_node_pre_func,
3516 (IDL_tree_func) IDL_emit_node_post_func,
3517 &data);
3518
3519 return data.u.s;
3520 }
3521
3522 typedef struct {
3523 IDL_tree searchNode;
3524 gboolean found;
3525 } ContainsNodeWalkerInfo;
3526
3527 static gboolean
contains_node_walker(IDL_tree_func_data * tfd,gpointer data)3528 contains_node_walker (IDL_tree_func_data *tfd, gpointer data) {
3529 ContainsNodeWalkerInfo *info = data;
3530 /* skip root! */
3531 if (tfd->up != NULL && tfd->tree == info->searchNode) {
3532 info->found = TRUE;
3533 return FALSE;
3534 }
3535 return TRUE; /* continue walking */
3536 }
3537
IDL_tree_contains_node(IDL_tree tree,IDL_tree node)3538 gboolean IDL_tree_contains_node(IDL_tree tree, IDL_tree node) {
3539 ContainsNodeWalkerInfo info;
3540 info.searchNode = node;
3541 info.found = 0;
3542 IDL_tree_walk2 (tree, /*curwalk*/NULL, /*flags*/0,
3543 /*pre*/contains_node_walker, /*post*/NULL, &info);
3544 return info.found;
3545 }
3546
3547 struct IDL_recursive_walker_info {
3548 GSList *ident_list;
3549 gboolean recursive;
3550 };
3551
3552 /*
3553 * IDL_tree_is_recursive_walker_pre:
3554 * @walk_frame: a #IDL_tree_func_data structure
3555 * @user_data: a #IDL_recursive_walker_info structure.
3556 *
3557 * If the current node in the parse tree is a structure or union
3558 * add its IDLN_IDENT to the ident list contained in @user_data;
3559 *
3560 * If the current node in the parse tree is a sequence, check to
3561 * see if the sequence element type is on the list of IDLN_IDENTs.
3562 *
3563 * Return value: %FALSE if recursion is detected - this stops the
3564 * walk to the parse tree -, %TRUE otherwise.
3565 */
3566 static gboolean
IDL_tree_is_recursive_walker_pre(IDL_tree_func_data * walk_frame,gpointer user_data)3567 IDL_tree_is_recursive_walker_pre (IDL_tree_func_data *walk_frame,
3568 gpointer user_data)
3569 {
3570 struct IDL_recursive_walker_info *info = user_data;
3571 IDL_tree node = walk_frame->tree;
3572
3573 switch (IDL_NODE_TYPE (node)) {
3574 case IDLN_TYPE_STRUCT:
3575 case IDLN_TYPE_UNION:
3576 info->ident_list = g_slist_prepend (info->ident_list,
3577 IDL_TYPE_STRUCT (node).ident);
3578 break;
3579 case IDLN_TYPE_SEQUENCE: {
3580 IDL_tree seq_type = IDL_TYPE_SEQUENCE (node).simple_type_spec;
3581 GSList *l = info->ident_list;
3582
3583 if (IDL_NODE_TYPE (seq_type) != IDLN_IDENT)
3584 break;
3585
3586 g_assert (IDL_IDENT (seq_type).repo_id);
3587
3588 for (; l; l = l->next) {
3589 IDL_tree n = (IDL_tree)l->data;
3590
3591 g_assert (IDL_IDENT (n).repo_id);
3592
3593 if (!strcmp (IDL_IDENT (n).repo_id,
3594 IDL_IDENT (seq_type).repo_id)) {
3595
3596 info->recursive = TRUE;
3597 return FALSE;
3598 }
3599 }
3600 }
3601 break;
3602 default:
3603 break;
3604 }
3605
3606 return TRUE;
3607 }
3608
3609 /*
3610 * IDL_tree_is_recursive_walker_post:
3611 * @walk_frame: a #IDL_tree_func_data structure
3612 * @user_data: a #IDL_recursive_walker_info structure.
3613 *
3614 * If the current node in the parse tree is a structure or
3615 * union, remove the IDLN_IDENT from the ident list.
3616 *
3617 * Return value: %TRUE.
3618 */
3619 static gboolean
IDL_tree_is_recursive_walker_post(IDL_tree_func_data * walk_frame,gpointer user_data)3620 IDL_tree_is_recursive_walker_post (IDL_tree_func_data *walk_frame,
3621 gpointer user_data)
3622 {
3623 struct IDL_recursive_walker_info *info = user_data;
3624 IDL_tree node = walk_frame->tree;
3625
3626 switch (IDL_NODE_TYPE (node)) {
3627 case IDLN_TYPE_STRUCT:
3628 case IDLN_TYPE_UNION: {
3629 GSList *link = info->ident_list;
3630
3631 g_assert (((IDL_tree)link->data) == IDL_TYPE_STRUCT (node).ident);
3632
3633 info->ident_list = g_slist_remove_link (info->ident_list,
3634 link);
3635 g_slist_free_1 (link);
3636 }
3637 break;
3638 default:
3639 break;
3640 }
3641
3642 return TRUE;
3643 }
3644
3645 /*
3646 * IDL_tree_is_recursive:
3647 * @tree: a #IDL_tree.
3648 * @hasRecur: dummy argument, not used, deprecated, compatibility cruft.
3649 *
3650 * Checks whether or not @tree contains recursive types.
3651 *
3652 * Recursive types may only be constructed using structs/unions which
3653 * contain sequences that hold the parent struct/union type.
3654 *
3655 * Return value: %TRUE if @tree contains recursive types,
3656 * %FALSE otherwise.
3657 */
3658 gboolean
IDL_tree_is_recursive(IDL_tree tree,gpointer dummy)3659 IDL_tree_is_recursive (IDL_tree tree, gpointer dummy)
3660 {
3661 struct IDL_recursive_walker_info info;
3662
3663 info.ident_list = NULL;
3664 info.recursive = FALSE;
3665
3666 IDL_tree_walk2 (tree, NULL, IDL_WalkF_TypespecOnly,
3667 IDL_tree_is_recursive_walker_pre,
3668 IDL_tree_is_recursive_walker_post,
3669 &info);
3670
3671 g_assert (!info.ident_list);
3672
3673 return info.recursive;
3674 }
3675
3676 /*
3677 * Local variables:
3678 * mode: C
3679 * c-basic-offset: 8
3680 * tab-width: 8
3681 * indent-tabs-mode: t
3682 * End:
3683 */
3684