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