~ubuntu-branches/ubuntu/breezy/orbit2/breezy

« back to all changes in this revision

Viewing changes to src/services/imodule/orbit-imodule-utils.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2005-09-06 16:37:02 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20050906163702-hrqi0ctymth53bnn
Tags: 1:2.12.4-0ubuntu1
* New upstream version.
* debian/patches/100-compile-name-server.patch:
  - updated.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * orbit-imodule-utils.c:
 
3
 *
 
4
 * Copyright (C) 2002 Sun Microsystems, Inc.
 
5
 *                    Red Hat, Inc.
 
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
 
19
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
20
 * Boston, MA 02111-1307, USA.
 
21
 *
 
22
 * Authors:
 
23
 *     Mark McLoughlin <mark@skynet.ie>
 
24
 *     Elliot Lee <sopwith@redhat.com
 
25
 */
 
26
 
 
27
#include <string.h>
 
28
 
 
29
#include <orbit/orbit.h>
 
30
 
 
31
#include "orbit-imodule-utils.h"
 
32
#include "orbit-imodule-libidl-utils.h"
 
33
 
 
34
static CORBA_StructMemberSeq *
 
35
ORBit_imodule_get_struct_members (GHashTable        *typecodes,
 
36
                                  IDL_tree           tree,
 
37
                                  CORBA_Environment *ev)
 
38
{
 
39
        CORBA_StructMemberSeq *members;
 
40
        IDL_tree               l;
 
41
        int                    num_members = 0;
 
42
        int                    i;
 
43
 
 
44
        g_return_val_if_fail (IDL_NODE_TYPE (tree) == IDLN_TYPE_STRUCT ||
 
45
                              IDL_NODE_TYPE (tree) == IDLN_EXCEPT_DCL, NULL);
 
46
 
 
47
        for (l = IDL_TYPE_STRUCT (tree).member_list; l; l = IDL_LIST (l).next)
 
48
                num_members += IDL_list_length (IDL_MEMBER (IDL_LIST (l).data).dcls);
 
49
 
 
50
        members = CORBA_StructMemberSeq__alloc ();
 
51
 
 
52
        members->_length  = members->_maximum = num_members;
 
53
        members->_buffer  = CORBA_StructMemberSeq_allocbuf (members->_length);
 
54
        members->_release = CORBA_TRUE;
 
55
 
 
56
        for (i = 0, l = IDL_TYPE_STRUCT (tree).member_list; l; l = IDL_LIST (l).next) {
 
57
                CORBA_TypeCode subtc;
 
58
                IDL_tree       dcl;
 
59
 
 
60
                subtc = ORBit_imodule_get_typecode (
 
61
                                typecodes, IDL_MEMBER (IDL_LIST (l).data).type_spec);
 
62
 
 
63
                for (dcl = IDL_MEMBER (IDL_LIST (l).data).dcls; dcl;
 
64
                     dcl = IDL_LIST (dcl).next, i++) {
 
65
                        CORBA_StructMember *member = &members->_buffer [i];
 
66
                        CORBA_string        name;
 
67
 
 
68
                        if (IDL_NODE_TYPE (dcl) == IDLN_IDENT)
 
69
                                name = IDL_IDENT (dcl).str;
 
70
                        else /* IDLN_TYPE_ARRAY */
 
71
                                name = IDL_IDENT (IDL_TYPE_ARRAY (dcl).ident).str;
 
72
 
 
73
                        member->name     = CORBA_string_dup (name);
 
74
                        member->type     = (CORBA_TypeCode)
 
75
                                                CORBA_Object_duplicate ((CORBA_Object) subtc, ev);
 
76
                        member->type_def = CORBA_OBJECT_NIL; /* Not used? */
 
77
                }
 
78
 
 
79
                CORBA_Object_release ((CORBA_Object) subtc, ev);
 
80
        }
 
81
 
 
82
        g_assert (i == num_members);
 
83
 
 
84
        return members;
 
85
}
 
86
 
 
87
static void
 
88
ORBit_imodule_jam_int (IDL_tree src, CORBA_TypeCode tc, gpointer dest)
 
89
{
 
90
        CORBA_long val = 0;
 
91
 
 
92
        switch (IDL_NODE_TYPE (src)) {
 
93
        case IDLN_BOOLEAN:
 
94
                val = IDL_BOOLEAN (src).value ? 1 : 0;
 
95
                break;
 
96
        case IDLN_CHAR:
 
97
                val = IDL_CHAR (src).value [0];
 
98
                break;
 
99
        case IDLN_INTEGER:
 
100
                val = IDL_INTEGER (src).value;
 
101
                break;
 
102
        default:
 
103
                g_assert_not_reached ();
 
104
                break;
 
105
        }
 
106
 
 
107
        switch (tc->kind) {
 
108
        case CORBA_tk_boolean:
 
109
        case CORBA_tk_char:
 
110
        case CORBA_tk_octet:
 
111
                *(CORBA_boolean *) dest = val;
 
112
                break;
 
113
        case CORBA_tk_short:
 
114
        case CORBA_tk_ushort:
 
115
                *(CORBA_short *) dest = val;
 
116
                break;
 
117
        case CORBA_tk_long:
 
118
        case CORBA_tk_ulong:
 
119
                *(CORBA_long *) dest = val;
 
120
                break;
 
121
        default:
 
122
                g_assert_not_reached ();
 
123
                break;
 
124
        }
 
125
}
 
126
 
 
127
static void
 
128
ORBit_imodule_setup_label_any (CORBA_TypeCode  tc,
 
129
                               IDL_tree        node,
 
130
                               CORBA_any      *label)
 
131
{
 
132
        if (!node) { /* default case */
 
133
                label->_type = TC_CORBA_octet;
 
134
                label->_value = ORBit_small_alloc (TC_CORBA_octet);
 
135
                *(CORBA_octet *) label->_value = -1;
 
136
                return;
 
137
        }
 
138
 
 
139
        label->_type = (CORBA_TypeCode)
 
140
                                CORBA_Object_duplicate (
 
141
                                        (CORBA_Object) tc, NULL);
 
142
        label->_value = ORBit_small_alloc (tc);
 
143
 
 
144
        switch (IDL_NODE_TYPE (node)) {
 
145
        case IDLN_BOOLEAN:
 
146
        case IDLN_CHAR:
 
147
        case IDLN_INTEGER:
 
148
                ORBit_imodule_jam_int (node, tc, label->_value);
 
149
                break;
 
150
 
 
151
        case IDLN_FLOAT:
 
152
                g_assert (tc->kind == CORBA_tk_float);
 
153
                *(CORBA_float *) label->_value = IDL_FLOAT (node).value;
 
154
                break;
 
155
        case IDLN_BINOP:  /* drop through */
 
156
        case IDLN_UNARYOP: {
 
157
                IDL_tree val;
 
158
 
 
159
                if (IDL_NODE_TYPE (node) == IDLN_BINOP)
 
160
                        val = _IDL_binop_eval (IDL_BINOP (node).op,
 
161
                                               IDL_BINOP (node).left,
 
162
                                               IDL_BINOP (node).right);
 
163
                else
 
164
                        val = _IDL_unaryop_eval (IDL_BINOP (node).op,
 
165
                                               IDL_UNARYOP (node).operand);
 
166
 
 
167
                ORBit_imodule_jam_int (val, tc, label->_value);
 
168
                IDL_tree_free (val);
 
169
                break;
 
170
        }
 
171
        case IDLN_IDENT: {
 
172
                CORBA_long val;
 
173
 
 
174
                g_assert (label->_type->kind == CORBA_tk_enum);
 
175
                for (val = 0; val < label->_type->sub_parts; val++)
 
176
                        if (!strcmp (IDL_IDENT (node).str, label->_type->subnames [val]))
 
177
                                break;
 
178
                g_assert (val < label->_type->sub_parts);
 
179
                *(CORBA_long *) label->_value = val;
 
180
                break;
 
181
        }
 
182
        default:
 
183
                g_assert_not_reached ();
 
184
                break;
 
185
        }
 
186
}
 
187
 
 
188
static CORBA_UnionMemberSeq *
 
189
ORBit_imodule_get_union_members (GHashTable        *typecodes,
 
190
                                 IDL_tree           tree,
 
191
                                 CORBA_TypeCode     switchtc,
 
192
                                 CORBA_Environment *ev)
 
193
{
 
194
        CORBA_UnionMemberSeq *members;
 
195
        IDL_tree              l;
 
196
        int                   num_members = 0;
 
197
        int                   i;
 
198
 
 
199
        g_return_val_if_fail (IDL_NODE_TYPE (tree) == IDLN_TYPE_UNION, NULL);
 
200
 
 
201
        for (l = IDL_TYPE_UNION (tree).switch_body; l; l = IDL_LIST (l).next)
 
202
                num_members += IDL_list_length (IDL_CASE_STMT (IDL_LIST (l).data).labels);
 
203
 
 
204
        members = CORBA_UnionMemberSeq__alloc ();
 
205
 
 
206
        members->_length  = members->_maximum = num_members;
 
207
        members->_buffer  = CORBA_UnionMemberSeq_allocbuf (members->_length);
 
208
        members->_release = CORBA_TRUE;
 
209
 
 
210
        for (i = 0, l = IDL_TYPE_UNION (tree).switch_body; l; l = IDL_LIST (l).next) {
 
211
                CORBA_TypeCode subtc;
 
212
                IDL_tree       member, label, dcl;
 
213
 
 
214
                member = IDL_CASE_STMT (IDL_LIST (l).data).element_spec;
 
215
                g_assert (IDL_NODE_TYPE (member) == IDLN_MEMBER);
 
216
 
 
217
                subtc = ORBit_imodule_get_typecode (
 
218
                                typecodes, IDL_MEMBER (member).type_spec);
 
219
                dcl = IDL_LIST (IDL_MEMBER (member).dcls).data;
 
220
 
 
221
                for (label = IDL_CASE_STMT (IDL_LIST (l).data).labels; label;
 
222
                     label = IDL_LIST (label).next, i++) {
 
223
                        CORBA_UnionMember *umember = &members->_buffer [i];
 
224
 
 
225
                        ORBit_imodule_setup_label_any (
 
226
                                switchtc, IDL_LIST (label).data, &umember->label);
 
227
 
 
228
                        umember->label._release = CORBA_TRUE;
 
229
 
 
230
                        umember->name     = CORBA_string_dup (IDL_IDENT (dcl).str);
 
231
                        umember->type     = (CORBA_TypeCode)
 
232
                                                CORBA_Object_duplicate ((CORBA_Object) subtc, ev);
 
233
                        umember->type_def = CORBA_OBJECT_NIL; /* Not used? */
 
234
                }
 
235
 
 
236
                CORBA_Object_release ((CORBA_Object) subtc, ev);
 
237
        }
 
238
 
 
239
        g_assert (i == num_members);
 
240
 
 
241
        return members;
 
242
}
 
243
 
 
244
static CORBA_EnumMemberSeq *
 
245
ORBit_imodule_get_enum_members (IDL_tree           tree,
 
246
                                CORBA_Environment *ev)
 
247
{
 
248
        CORBA_EnumMemberSeq *members;
 
249
        IDL_tree             l;
 
250
        int                  num_members = 0;
 
251
        int                  i;
 
252
 
 
253
        g_return_val_if_fail (IDL_NODE_TYPE (tree) == IDLN_TYPE_ENUM, NULL);
 
254
 
 
255
        num_members = IDL_list_length (IDL_TYPE_ENUM (tree).enumerator_list);
 
256
 
 
257
        members = CORBA_EnumMemberSeq__alloc ();
 
258
 
 
259
        members->_length  = members->_maximum = num_members;
 
260
        members->_buffer  = CORBA_EnumMemberSeq_allocbuf (members->_length);
 
261
        members->_release = CORBA_TRUE;
 
262
 
 
263
        for (i = 0, l = IDL_TYPE_ENUM (tree).enumerator_list; l; i++, l = IDL_LIST (l).next)
 
264
                members->_buffer [i] = CORBA_string_dup (IDL_IDENT (IDL_LIST (l).data).str);
 
265
 
 
266
        g_assert (i == num_members);
 
267
 
 
268
        return members;
 
269
}
 
270
 
 
271
static CORBA_TypeCode
 
272
ORBit_imodule_lookup_typecode (GHashTable *typecodes,
 
273
                               const char *repo_id)
 
274
{
 
275
        if (!typecodes)
 
276
                return CORBA_OBJECT_NIL;
 
277
 
 
278
        return (CORBA_TypeCode) CORBA_Object_duplicate (
 
279
                                        g_hash_table_lookup (typecodes, repo_id),
 
280
                                        NULL);
 
281
}
 
282
 
 
283
static void
 
284
ORBit_imodule_register_typecode (GHashTable     *typecodes,
 
285
                                 const char     *repo_id,
 
286
                                 CORBA_TypeCode  tc)
 
287
{
 
288
        g_return_if_fail (g_hash_table_lookup (typecodes, repo_id) == NULL);
 
289
 
 
290
        g_hash_table_insert (
 
291
                typecodes, g_strdup (repo_id),
 
292
                CORBA_Object_duplicate ((CORBA_Object) tc, NULL));
 
293
}
 
294
 
 
295
GHashTable *
 
296
ORBit_imodule_new_typecodes (void)
 
297
{
 
298
        return g_hash_table_new_full (
 
299
                        g_str_hash, g_str_equal,
 
300
                        g_free,
 
301
                        (GDestroyNotify) CORBA_Object_release);
 
302
}
 
303
 
 
304
void
 
305
ORBit_imodule_free_typecodes (GHashTable *typecodes)
 
306
{
 
307
        g_hash_table_destroy (typecodes);
 
308
}
 
309
 
 
310
typedef struct {
 
311
        CORBA_sequence_CORBA_TypeCode *sequence;
 
312
        int                            iter;
 
313
} TypecodesHashIter;
 
314
 
 
315
static void
 
316
typecodes_hash_foreach (const char        *repo_id,
 
317
                        CORBA_TypeCode     tc,
 
318
                        TypecodesHashIter *iter)
 
319
{
 
320
        g_assert (iter->iter < iter->sequence->_length);
 
321
 
 
322
        iter->sequence->_buffer [iter->iter++] =
 
323
                (CORBA_TypeCode) CORBA_Object_duplicate ((CORBA_Object) tc, NULL);
 
324
}
 
325
 
 
326
CORBA_sequence_CORBA_TypeCode *
 
327
ORBit_imodule_get_typecodes_seq (GHashTable *typecodes)
 
328
{
 
329
        CORBA_sequence_CORBA_TypeCode *retval;
 
330
        TypecodesHashIter              iter;
 
331
 
 
332
        retval           = CORBA_sequence_CORBA_TypeCode__alloc ();
 
333
        retval->_length  = retval->_maximum = g_hash_table_size (typecodes);
 
334
        retval->_release = TRUE;
 
335
        retval->_buffer  = CORBA_sequence_CORBA_TypeCode_allocbuf (retval->_length);
 
336
 
 
337
        iter.sequence = retval;
 
338
        iter.iter     = 0;
 
339
 
 
340
        g_hash_table_foreach (typecodes, (GHFunc) typecodes_hash_foreach, &iter);
 
341
 
 
342
        g_assert (iter.iter == retval->_length);
 
343
 
 
344
        return retval;
 
345
}
 
346
 
 
347
IDL_tree
 
348
ORBit_imodule_get_typespec (IDL_tree tree)
 
349
{
 
350
        IDL_tree retval = NULL;
 
351
 
 
352
        if (!tree)
 
353
                return NULL;
 
354
 
 
355
        switch (IDL_NODE_TYPE (tree)) {
 
356
        case IDLN_TYPE_INTEGER:
 
357
        case IDLN_TYPE_FLOAT:
 
358
        case IDLN_TYPE_FIXED:
 
359
        case IDLN_TYPE_CHAR:
 
360
        case IDLN_TYPE_WIDE_CHAR:
 
361
        case IDLN_TYPE_STRING:
 
362
        case IDLN_TYPE_WIDE_STRING:
 
363
        case IDLN_TYPE_BOOLEAN:
 
364
        case IDLN_TYPE_OCTET:
 
365
        case IDLN_TYPE_ANY:
 
366
        case IDLN_TYPE_OBJECT:
 
367
        case IDLN_TYPE_ENUM:
 
368
        case IDLN_TYPE_SEQUENCE:
 
369
        case IDLN_TYPE_ARRAY:
 
370
        case IDLN_TYPE_STRUCT:
 
371
        case IDLN_TYPE_UNION:
 
372
        case IDLN_EXCEPT_DCL:
 
373
        case IDLN_FORWARD_DCL:
 
374
        case IDLN_INTERFACE:
 
375
        case IDLN_NATIVE:
 
376
        case IDLN_TYPE_TYPECODE:
 
377
                retval = tree;
 
378
                break;
 
379
        case IDLN_TYPE_DCL:
 
380
                retval = ORBit_imodule_get_typespec (
 
381
                                IDL_TYPE_DCL (tree).type_spec);
 
382
                break;
 
383
        case IDLN_PARAM_DCL:
 
384
                retval = ORBit_imodule_get_typespec (
 
385
                                IDL_PARAM_DCL (tree).param_type_spec);
 
386
                break;
 
387
        case IDLN_MEMBER:
 
388
                retval = ORBit_imodule_get_typespec (
 
389
                                IDL_MEMBER (tree).type_spec);
 
390
                break;
 
391
        case IDLN_LIST:
 
392
        case IDLN_IDENT:
 
393
                retval = ORBit_imodule_get_typespec (
 
394
                                IDL_get_parent_node (tree, IDLN_ANY, NULL));
 
395
                break;
 
396
        default:
 
397
                g_error ("Cannot get typespec for %s",
 
398
                                IDL_tree_type_names [IDL_NODE_TYPE (tree)]);
 
399
                break;
 
400
        }
 
401
 
 
402
        return retval;
 
403
}
 
404
 
 
405
static int
 
406
ORBit_imodule_find_c_align (IDL_tree node)
 
407
{
 
408
        int c_align = 1;
 
409
 
 
410
        node = ORBit_imodule_get_typespec (node);       
 
411
 
 
412
        switch (IDL_NODE_TYPE (node)) {
 
413
        case IDLN_TYPE_INTEGER:
 
414
                switch (IDL_TYPE_INTEGER (node).f_type) {
 
415
                case IDL_INTEGER_TYPE_SHORT:
 
416
                        c_align = ORBIT_ALIGNOF_CORBA_SHORT;
 
417
                        break;
 
418
                case IDL_INTEGER_TYPE_LONG:
 
419
                        c_align = ORBIT_ALIGNOF_CORBA_LONG;
 
420
                        break;
 
421
                case IDL_INTEGER_TYPE_LONGLONG:
 
422
                        c_align = ORBIT_ALIGNOF_CORBA_LONG_LONG;
 
423
                        break;
 
424
                }
 
425
                break;
 
426
        case IDLN_TYPE_FLOAT:
 
427
                switch (IDL_TYPE_FLOAT (node).f_type) {
 
428
                case IDL_FLOAT_TYPE_FLOAT:
 
429
                        c_align = ORBIT_ALIGNOF_CORBA_FLOAT;
 
430
                        break;
 
431
                case IDL_FLOAT_TYPE_DOUBLE:
 
432
                        c_align = ORBIT_ALIGNOF_CORBA_DOUBLE;
 
433
                        break;
 
434
                case IDL_FLOAT_TYPE_LONGDOUBLE:
 
435
                        c_align = ORBIT_ALIGNOF_CORBA_LONG_DOUBLE;
 
436
                        break;
 
437
                }
 
438
                break;
 
439
        case IDLN_TYPE_ENUM:
 
440
                c_align = ORBIT_ALIGNOF_CORBA_LONG;
 
441
                break;
 
442
        case IDLN_TYPE_CHAR: /* drop through */
 
443
        case IDLN_TYPE_BOOLEAN:
 
444
        case IDLN_TYPE_OCTET:
 
445
                c_align = ORBIT_ALIGNOF_CORBA_CHAR;
 
446
                break;
 
447
        case IDLN_TYPE_WIDE_CHAR:
 
448
                c_align = ORBIT_ALIGNOF_CORBA_SHORT;
 
449
                break;
 
450
        case IDLN_TYPE_UNION: {
 
451
                IDL_tree l = IDL_TYPE_UNION (node).switch_body;
 
452
 
 
453
                c_align = ORBIT_ALIGNOF_CORBA_STRUCT;
 
454
 
 
455
                for (; l; l = IDL_LIST (l).next) {
 
456
                        IDL_tree subtype = IDL_MEMBER (IDL_CASE_STMT (
 
457
                                        IDL_LIST (l).data).element_spec).type_spec;
 
458
 
 
459
                        c_align = MAX (c_align, ORBit_imodule_find_c_align (subtype));
 
460
                }
 
461
                }
 
462
                break;
 
463
        case IDLN_EXCEPT_DCL: /* drop through */
 
464
        case IDLN_TYPE_STRUCT: {
 
465
                IDL_tree l = IDL_TYPE_STRUCT (node).member_list;
 
466
                                        
 
467
                for (; l; l = IDL_LIST (l).next) {
 
468
                        IDL_tree member = IDL_MEMBER (IDL_LIST (l).data).type_spec;
 
469
 
 
470
                        c_align = MAX (c_align, ORBit_imodule_find_c_align (member));
 
471
                }
 
472
                }
 
473
                break;
 
474
        case IDLN_TYPE_STRING: /* drop through */
 
475
        case IDLN_TYPE_WIDE_STRING:
 
476
        case IDLN_TYPE_OBJECT:
 
477
        case IDLN_TYPE_TYPECODE:
 
478
        case IDLN_FORWARD_DCL:
 
479
        case IDLN_INTERFACE:
 
480
                c_align = ORBIT_ALIGNOF_CORBA_POINTER;
 
481
                break;
 
482
        case IDLN_TYPE_ARRAY: {
 
483
                IDL_tree subtype;
 
484
 
 
485
                subtype = IDL_TYPE_DCL (
 
486
                                IDL_get_parent_node (
 
487
                                        node, IDLN_TYPE_DCL, NULL)).type_spec;
 
488
 
 
489
                c_align = ORBit_imodule_find_c_align (subtype);
 
490
                }
 
491
                break;
 
492
        case IDLN_TYPE_SEQUENCE:
 
493
                c_align = MAX (MAX (ORBIT_ALIGNOF_CORBA_STRUCT,
 
494
                                    ORBIT_ALIGNOF_CORBA_LONG),
 
495
                                    ORBIT_ALIGNOF_CORBA_POINTER);
 
496
                break;
 
497
        case IDLN_TYPE_ANY:
 
498
                c_align =  MAX (ORBIT_ALIGNOF_CORBA_STRUCT,
 
499
                                ORBIT_ALIGNOF_CORBA_POINTER);
 
500
                break;
 
501
        default:
 
502
                g_error ("Can't find alignment %s\n", 
 
503
                         IDL_tree_type_names [IDL_NODE_TYPE (node)]);
 
504
                break;
 
505
        }
 
506
 
 
507
        return c_align;
 
508
}
 
509
 
 
510
CORBA_TypeCode
 
511
ORBit_imodule_get_typecode (GHashTable *typecodes,
 
512
                            IDL_tree    tree)
 
513
{
 
514
        CORBA_Environment env;
 
515
        CORBA_TypeCode    retval = CORBA_OBJECT_NIL;
 
516
 
 
517
        if (!tree)
 
518
                return CORBA_OBJECT_NIL;
 
519
 
 
520
        CORBA_exception_init (&env);
 
521
 
 
522
        switch (IDL_NODE_TYPE (tree)) {
 
523
        case IDLN_MEMBER:
 
524
                retval = ORBit_imodule_get_typecode (
 
525
                                typecodes, IDL_MEMBER (tree).type_spec);
 
526
                break;
 
527
        case IDLN_TYPE_ANY:
 
528
                retval = (CORBA_TypeCode)
 
529
                                CORBA_Object_duplicate (
 
530
                                        (CORBA_Object) TC_CORBA_any, NULL);
 
531
                break;
 
532
        case IDLN_TYPE_FLOAT:
 
533
                switch (IDL_TYPE_FLOAT (tree).f_type) {
 
534
                case IDL_FLOAT_TYPE_FLOAT:
 
535
                        retval = TC_CORBA_float;
 
536
                        break;
 
537
                case IDL_FLOAT_TYPE_DOUBLE:
 
538
                        retval = TC_CORBA_double;
 
539
                        break;
 
540
                case IDL_FLOAT_TYPE_LONGDOUBLE:
 
541
                        retval = TC_CORBA_long_double;
 
542
                        break;
 
543
                }
 
544
                break;
 
545
        case IDLN_TYPE_FIXED:
 
546
                retval = CORBA_ORB_create_fixed_tc (NULL, 
 
547
                                IDL_INTEGER (IDL_TYPE_FIXED (tree).positive_int_const).value,
 
548
                                IDL_INTEGER (IDL_TYPE_FIXED (tree).integer_lit).value, &env);
 
549
                break;
 
550
        case IDLN_TYPE_INTEGER:
 
551
                if (!IDL_TYPE_INTEGER (tree).f_signed)
 
552
                        switch (IDL_TYPE_INTEGER (tree).f_type) {
 
553
                        case IDL_INTEGER_TYPE_SHORT:
 
554
                                retval = TC_CORBA_unsigned_short;
 
555
                                break;
 
556
                        case IDL_INTEGER_TYPE_LONGLONG:
 
557
                                retval = TC_CORBA_unsigned_long_long;
 
558
                                break;
 
559
                        case IDL_INTEGER_TYPE_LONG:
 
560
                                retval = TC_CORBA_unsigned_long;
 
561
                                break;
 
562
                        default:
 
563
                                g_assert_not_reached ();
 
564
                        }
 
565
                else
 
566
                        switch (IDL_TYPE_INTEGER (tree).f_type) {
 
567
                        case IDL_INTEGER_TYPE_SHORT:
 
568
                                retval = TC_CORBA_short;
 
569
                                break;
 
570
                        case IDL_INTEGER_TYPE_LONGLONG:
 
571
                                retval = TC_CORBA_long_long;
 
572
                                break;
 
573
                        case IDL_INTEGER_TYPE_LONG:
 
574
                                retval = TC_CORBA_long;
 
575
                                break;
 
576
                        default:
 
577
                                g_assert_not_reached ();
 
578
                        }
 
579
                break;
 
580
        case IDLN_TYPE_STRING:
 
581
                retval = (CORBA_TypeCode)
 
582
                                CORBA_Object_duplicate (
 
583
                                        (CORBA_Object) TC_CORBA_string, NULL);
 
584
                break;
 
585
        case IDLN_TYPE_WIDE_STRING:
 
586
                retval = (CORBA_TypeCode)
 
587
                                CORBA_Object_duplicate (
 
588
                                        (CORBA_Object) TC_CORBA_wstring, NULL);
 
589
                break;
 
590
        case IDLN_TYPE_OCTET:
 
591
                retval = (CORBA_TypeCode)
 
592
                                CORBA_Object_duplicate (
 
593
                                        (CORBA_Object) TC_CORBA_octet, NULL);
 
594
                break;
 
595
        case IDLN_TYPE_CHAR:
 
596
                retval = (CORBA_TypeCode)
 
597
                                CORBA_Object_duplicate (
 
598
                                        (CORBA_Object) TC_CORBA_char, NULL);
 
599
                break;
 
600
        case IDLN_TYPE_WIDE_CHAR:
 
601
                retval = (CORBA_TypeCode)
 
602
                                CORBA_Object_duplicate (
 
603
                                        (CORBA_Object) TC_CORBA_wchar, NULL);
 
604
                break;
 
605
        case IDLN_TYPE_BOOLEAN:
 
606
                retval = (CORBA_TypeCode)
 
607
                                CORBA_Object_duplicate (
 
608
                                        (CORBA_Object) TC_CORBA_boolean, NULL);
 
609
                break;
 
610
        case IDLN_TYPE_STRUCT:
 
611
                retval = ORBit_imodule_lookup_typecode (
 
612
                                typecodes,
 
613
                                IDL_IDENT (IDL_TYPE_STRUCT (tree).ident).repo_id);
 
614
 
 
615
                if (!retval) {
 
616
                        CORBA_StructMemberSeq *members;
 
617
 
 
618
                        members = ORBit_imodule_get_struct_members (
 
619
                                                typecodes, tree, &env);
 
620
 
 
621
                        retval = CORBA_ORB_create_struct_tc (NULL,
 
622
                                        IDL_IDENT (IDL_TYPE_STRUCT (tree).ident).repo_id,
 
623
                                        IDL_IDENT (IDL_TYPE_STRUCT (tree).ident).str,
 
624
                                        members, &env);
 
625
 
 
626
                        ORBit_imodule_register_typecode (
 
627
                                typecodes,
 
628
                                IDL_IDENT (IDL_TYPE_STRUCT (tree).ident).repo_id, retval);
 
629
 
 
630
                        CORBA_free (members);
 
631
                }
 
632
                break;
 
633
        case IDLN_EXCEPT_DCL:
 
634
                retval = ORBit_imodule_lookup_typecode (
 
635
                                typecodes,
 
636
                                IDL_IDENT (IDL_EXCEPT_DCL (tree).ident).repo_id);
 
637
 
 
638
                if (!retval) {
 
639
                        CORBA_StructMemberSeq *members;
 
640
 
 
641
                        members = ORBit_imodule_get_struct_members (
 
642
                                                typecodes, tree, &env);
 
643
 
 
644
                        retval = CORBA_ORB_create_exception_tc (NULL,
 
645
                                        IDL_IDENT (IDL_EXCEPT_DCL (tree).ident).repo_id,
 
646
                                        IDL_IDENT (IDL_EXCEPT_DCL (tree).ident).str,
 
647
                                        members, &env);
 
648
 
 
649
                        ORBit_imodule_register_typecode (
 
650
                                typecodes,
 
651
                                IDL_IDENT (IDL_EXCEPT_DCL (tree).ident).repo_id, retval);
 
652
 
 
653
                        CORBA_free (members);
 
654
                }
 
655
                break;
 
656
        case IDLN_TYPE_ARRAY: {
 
657
                CORBA_TypeCode subtc;
 
658
                IDL_tree       sizer;
 
659
                IDL_tree       type_dcl;
 
660
 
 
661
                sizer = IDL_list_nth (IDL_TYPE_ARRAY (tree).size_list,
 
662
                                      IDL_list_length (IDL_TYPE_ARRAY (tree).size_list) - 1);
 
663
                g_assert (IDL_NODE_TYPE (IDL_LIST (sizer).data) == IDLN_INTEGER);
 
664
 
 
665
                type_dcl = IDL_NODE_UP (IDL_NODE_UP (tree));
 
666
                g_assert (IDL_NODE_TYPE (type_dcl) == IDLN_TYPE_DCL);
 
667
 
 
668
                subtc = ORBit_imodule_get_typecode (
 
669
                                typecodes, IDL_TYPE_DCL (type_dcl).type_spec),
 
670
                retval = CORBA_ORB_create_array_tc (NULL,
 
671
                                IDL_INTEGER (IDL_LIST (sizer).data).value,
 
672
                                subtc, &env);
 
673
                retval->c_align = subtc->c_align;
 
674
                CORBA_Object_release ((CORBA_Object) subtc, NULL);
 
675
 
 
676
                for (sizer = IDL_LIST (sizer).prev; sizer; sizer = IDL_LIST (sizer).prev) {
 
677
                        subtc = retval;
 
678
                        retval = CORBA_ORB_create_array_tc (NULL,
 
679
                                        IDL_INTEGER (IDL_LIST (sizer).data).value,
 
680
                                        subtc, &env);
 
681
                        retval->c_align = subtc->c_align;
 
682
                        CORBA_Object_release ((CORBA_Object) subtc, NULL);
 
683
                }
 
684
 
 
685
                subtc = retval;
 
686
                retval = ORBit_imodule_create_alias_typecode (
 
687
                                typecodes, IDL_TYPE_ARRAY (tree).ident, subtc);
 
688
                CORBA_Object_release ((CORBA_Object) subtc, NULL);
 
689
                }
 
690
                break;
 
691
        case IDLN_TYPE_UNION:
 
692
                retval = ORBit_imodule_lookup_typecode (
 
693
                                typecodes,
 
694
                                IDL_IDENT (IDL_TYPE_UNION (tree).ident).repo_id);
 
695
                
 
696
                if (!retval) {
 
697
                        CORBA_UnionMemberSeq *members;
 
698
                        CORBA_TypeCode        switchtc;
 
699
 
 
700
                        switchtc = ORBit_imodule_get_typecode (
 
701
                                        typecodes, IDL_TYPE_UNION (tree).switch_type_spec);
 
702
 
 
703
                        members = ORBit_imodule_get_union_members (
 
704
                                                typecodes, tree, switchtc, &env);
 
705
                        retval = CORBA_ORB_create_union_tc (NULL,
 
706
                                        IDL_IDENT (IDL_TYPE_UNION (tree).ident).repo_id,
 
707
                                        IDL_IDENT (IDL_TYPE_UNION (tree).ident).str,
 
708
                                        switchtc, members, &env);
 
709
 
 
710
                        CORBA_Object_release ((CORBA_Object) switchtc, NULL);
 
711
 
 
712
                        ORBit_imodule_register_typecode (
 
713
                                typecodes,
 
714
                                IDL_IDENT (IDL_TYPE_UNION (tree).ident).repo_id, retval);
 
715
 
 
716
                        CORBA_free (members);
 
717
                }
 
718
                break;
 
719
        case IDLN_TYPE_ENUM:
 
720
                retval = ORBit_imodule_lookup_typecode (
 
721
                                typecodes,
 
722
                                IDL_IDENT (IDL_TYPE_ENUM (tree).ident).repo_id);
 
723
                if (!retval) {
 
724
                        CORBA_EnumMemberSeq *members;
 
725
 
 
726
                        members = ORBit_imodule_get_enum_members (tree, &env);
 
727
 
 
728
                        retval = CORBA_ORB_create_enum_tc (NULL,
 
729
                                        IDL_IDENT (IDL_TYPE_ENUM (tree).ident).repo_id,
 
730
                                        IDL_IDENT (IDL_TYPE_ENUM (tree).ident).str,
 
731
                                        members, &env);
 
732
 
 
733
                        ORBit_imodule_register_typecode (
 
734
                                typecodes,
 
735
                                IDL_IDENT (IDL_TYPE_ENUM (tree).ident).repo_id, retval);
 
736
 
 
737
                        CORBA_free (members);
 
738
                }
 
739
                break;
 
740
        case IDLN_IDENT:
 
741
                retval = ORBit_imodule_lookup_typecode (
 
742
                                typecodes, IDL_IDENT (tree).repo_id);
 
743
                g_assert (retval != NULL);
 
744
                break;
 
745
        case IDLN_TYPE_SEQUENCE: {
 
746
                CORBA_TypeCode subtc;
 
747
                int            bound = 0;
 
748
 
 
749
                if (IDL_TYPE_SEQUENCE (tree).positive_int_const)
 
750
                        bound = IDL_INTEGER (IDL_TYPE_SEQUENCE (tree).positive_int_const).value;
 
751
 
 
752
                subtc = ORBit_imodule_get_typecode (
 
753
                                typecodes, IDL_TYPE_SEQUENCE (tree).simple_type_spec),
 
754
                retval = CORBA_ORB_create_sequence_tc (NULL,
 
755
                                bound, subtc, &env);
 
756
                CORBA_Object_release ((CORBA_Object) subtc, NULL);
 
757
                /*
 
758
                 * FIXME: and what about recursive sequences?
 
759
                 */
 
760
                }
 
761
                break;
 
762
        case IDLN_FORWARD_DCL:
 
763
        case IDLN_INTERFACE:
 
764
                retval = ORBit_imodule_lookup_typecode (
 
765
                                typecodes,
 
766
                                IDL_IDENT (IDL_TYPE_ENUM (tree).ident).repo_id);
 
767
                if (!retval) {
 
768
                        retval = CORBA_ORB_create_interface_tc (NULL,
 
769
                                        IDL_IDENT (IDL_TYPE_ENUM (tree).ident).repo_id,
 
770
                                        IDL_IDENT (IDL_TYPE_ENUM (tree).ident).str,
 
771
                                        &env);
 
772
 
 
773
                        ORBit_imodule_register_typecode (
 
774
                                typecodes,
 
775
                                IDL_IDENT (IDL_TYPE_ENUM (tree).ident).repo_id, retval);
 
776
                }
 
777
                break;
 
778
        case IDLN_TYPE_OBJECT:
 
779
                retval = (CORBA_TypeCode)
 
780
                                CORBA_Object_duplicate (
 
781
                                        (CORBA_Object) TC_CORBA_Object, NULL);
 
782
                break;
 
783
        case IDLN_TYPE_TYPECODE:
 
784
                retval = (CORBA_TypeCode)
 
785
                                CORBA_Object_duplicate (
 
786
                                        (CORBA_Object) TC_CORBA_TypeCode, NULL);
 
787
                break;
 
788
        default:
 
789
                g_error ("We were asked to get a typecode for a %s",
 
790
                         IDL_tree_type_names [IDL_NODE_TYPE (tree)]);
 
791
                break;
 
792
        }
 
793
 
 
794
        if (retval && retval->c_align == 0)
 
795
                retval->c_align = ORBit_imodule_find_c_align (tree);
 
796
 
 
797
        if (env._major != CORBA_NO_EXCEPTION)
 
798
                g_warning ("ORBit_imodule_get_typecode: exception %s", env._id);
 
799
 
 
800
        CORBA_exception_free (&env);
 
801
 
 
802
        return retval;
 
803
}
 
804
 
 
805
CORBA_TypeCode
 
806
ORBit_imodule_create_alias_typecode (GHashTable    *typecodes,
 
807
                                     IDL_tree       tree,
 
808
                                     CORBA_TypeCode original_type)
 
809
{
 
810
        CORBA_Environment env;
 
811
        CORBA_TypeCode    retval;
 
812
 
 
813
        CORBA_exception_init (&env);
 
814
 
 
815
        g_return_val_if_fail (IDL_NODE_TYPE (tree) == IDLN_IDENT, NULL);
 
816
        g_return_val_if_fail (g_hash_table_lookup (typecodes,
 
817
                                                   IDL_IDENT (tree).repo_id) == NULL, NULL);
 
818
 
 
819
        retval = CORBA_ORB_create_alias_tc (NULL,
 
820
                        IDL_IDENT (tree).repo_id,
 
821
                        IDL_IDENT (tree).str,
 
822
                        original_type, &env);
 
823
 
 
824
        ORBit_imodule_register_typecode (
 
825
                        typecodes, IDL_IDENT (tree).repo_id, retval);
 
826
 
 
827
        if (env._major != CORBA_NO_EXCEPTION)
 
828
                g_warning ("ORBit_imodule_create_alias_typecode: exception %s", env._id);
 
829
 
 
830
        CORBA_exception_free (&env);
 
831
 
 
832
        return retval;
 
833
}
 
834
 
 
835
gboolean
 
836
ORBit_imodule_type_is_fixed_length (IDL_tree tree)
 
837
{
 
838
        gboolean is_fixed = TRUE;
 
839
        IDL_tree iter;
 
840
        IDL_tree typespec;
 
841
 
 
842
        typespec = ORBit_imodule_get_typespec (tree);
 
843
 
 
844
        switch (IDL_NODE_TYPE (typespec)) {
 
845
        case IDLN_TYPE_FLOAT:
 
846
        case IDLN_TYPE_INTEGER:
 
847
        case IDLN_TYPE_ENUM:
 
848
        case IDLN_TYPE_CHAR:
 
849
        case IDLN_TYPE_WIDE_CHAR:
 
850
        case IDLN_TYPE_OCTET:
 
851
        case IDLN_TYPE_BOOLEAN:
 
852
                is_fixed = TRUE;
 
853
                break;
 
854
        case IDLN_TYPE_SEQUENCE:
 
855
        case IDLN_TYPE_STRING:
 
856
        case IDLN_TYPE_WIDE_STRING:
 
857
        case IDLN_TYPE_OBJECT:
 
858
        case IDLN_FORWARD_DCL:
 
859
        case IDLN_INTERFACE:
 
860
        case IDLN_TYPE_ANY:
 
861
        case IDLN_NATIVE:
 
862
        case IDLN_TYPE_TYPECODE:
 
863
                is_fixed = FALSE;
 
864
                break;
 
865
        case IDLN_TYPE_UNION:
 
866
                for (iter = IDL_TYPE_UNION (typespec).switch_body;
 
867
                     iter; iter = IDL_LIST (iter).next)
 
868
                        is_fixed &= ORBit_imodule_type_is_fixed_length (
 
869
                                        IDL_LIST (IDL_CASE_STMT (
 
870
                                                IDL_LIST (iter).data).element_spec).data);
 
871
                break;
 
872
        case IDLN_EXCEPT_DCL:
 
873
        case IDLN_TYPE_STRUCT:
 
874
                for (iter = IDL_TYPE_STRUCT (typespec).member_list;
 
875
                     iter; iter = IDL_LIST (iter).next)
 
876
                        is_fixed &= ORBit_imodule_type_is_fixed_length (IDL_LIST (iter).data);
 
877
                break;
 
878
        case IDLN_TYPE_ARRAY:
 
879
                is_fixed = ORBit_imodule_type_is_fixed_length (
 
880
                                IDL_TYPE_DCL (IDL_get_parent_node (
 
881
                                                typespec, IDLN_TYPE_DCL, NULL)).type_spec);
 
882
                break;
 
883
        case IDLN_TYPE_DCL:
 
884
                is_fixed = ORBit_imodule_type_is_fixed_length (
 
885
                                IDL_TYPE_DCL (typespec).type_spec);
 
886
                break;
 
887
        case IDLN_IDENT:
 
888
        case IDLN_LIST:
 
889
                is_fixed = ORBit_imodule_type_is_fixed_length (IDL_NODE_UP (typespec));
 
890
                break;
 
891
        case IDLN_MEMBER:
 
892
                is_fixed = ORBit_imodule_type_is_fixed_length (IDL_MEMBER (typespec).type_spec);
 
893
                break;
 
894
        default:
 
895
                g_error ("Cannot determine if type %s is fixed-length",
 
896
                                IDL_tree_type_names [IDL_NODE_TYPE (typespec)]);
 
897
                break;
 
898
        }
 
899
 
 
900
        return is_fixed;
 
901
}
 
902
 
 
903
static void
 
904
ORBit_imodule_traverse_helper (IDL_tree    tree,
 
905
                               GFunc       callback,
 
906
                               gpointer    user_data,
 
907
                               GHashTable *visited_nodes)
 
908
{
 
909
        IDL_tree curitem;
 
910
 
 
911
        if (g_hash_table_lookup (visited_nodes, tree))
 
912
                return;
 
913
 
 
914
        g_hash_table_insert (visited_nodes, tree, GINT_TO_POINTER (1));
 
915
 
 
916
        for (curitem = IDL_INTERFACE (tree).inheritance_spec; curitem;
 
917
             curitem = IDL_LIST (curitem).next)
 
918
                ORBit_imodule_traverse_helper (
 
919
                                IDL_get_parent_node (IDL_LIST (curitem).data, IDLN_INTERFACE, NULL),
 
920
                                callback, user_data, visited_nodes);
 
921
 
 
922
        callback (tree, user_data);
 
923
}
 
924
 
 
925
void
 
926
ORBit_imodule_traverse_parents (IDL_tree tree,
 
927
                                GFunc    callback,
 
928
                                gpointer user_data)
 
929
{
 
930
        GHashTable *visited_nodes = g_hash_table_new (NULL, g_direct_equal);
 
931
 
 
932
        g_return_if_fail (tree != NULL);
 
933
        g_return_if_fail (callback != NULL);
 
934
 
 
935
        if (IDL_NODE_TYPE (tree) != IDLN_INTERFACE)
 
936
                tree = IDL_get_parent_node (tree, IDLN_INTERFACE, NULL);
 
937
 
 
938
        if (!tree)
 
939
                return;
 
940
 
 
941
        ORBit_imodule_traverse_helper (tree, callback, user_data, visited_nodes);
 
942
 
 
943
        g_hash_table_destroy (visited_nodes);
 
944
}