]> rtime.felk.cvut.cz Git - frescor/forb.git/blob - forb-idl/forb-idl-c-typecode.c
b267ff288b03518d44461a724f3a6772cc4f8238
[frescor/forb.git] / forb-idl / forb-idl-c-typecode.c
1 #include "forb-idl-c-backend.h"
2
3 #include <string.h>
4
5 typedef struct {
6         IDL_tree     ts;
7         char        *structname;
8         char        *substructname;
9         int          array_gen_ctr;
10 } CBETCGenInfo;
11
12 static int random_id = 0;
13
14 static char *forb_generate_tcstruct_name (IDL_tree     ts);
15 static void  cbe_tc_generate              (OIDL_C_Info *ci, CBETCGenInfo *tci);
16
17 void
18 forb_output_typecode (OIDL_C_Info *ci,
19                        IDL_tree     node)
20 {
21         CBETCGenInfo tci;
22
23         switch (IDL_NODE_TYPE (node)) {
24         case IDLN_TYPE_DCL:
25         case IDLN_TYPE_STRUCT:
26         case IDLN_TYPE_UNION:
27         case IDLN_TYPE_ENUM:
28         case IDLN_EXCEPT_DCL:
29         case IDLN_TYPE_SEQUENCE:
30         case IDLN_INTERFACE:
31                 break;
32         default:
33                 g_error ("You can't produce a typecode for a %s", 
34                          IDL_tree_type_names[IDL_NODE_TYPE (node)]);
35         }
36
37         tci.ts            = node;
38         tci.structname    = forb_generate_tcstruct_name (node);
39         tci.substructname = NULL;
40         tci.array_gen_ctr = 0;
41
42         cbe_tc_generate (ci, &tci);
43
44         g_free (tci.structname);
45 }
46
47 static char *
48 forb_generate_tcstruct_name (IDL_tree node)
49 {
50         GString *tmpstr;
51         char    *retval;
52
53         tmpstr = g_string_new (NULL);
54
55         switch (IDL_NODE_TYPE (node)) {
56         case IDLN_TYPE_INTEGER:
57         case IDLN_TYPE_ANY:
58         case IDLN_TYPE_STRING:
59         case IDLN_TYPE_WIDE_STRING:
60         case IDLN_TYPE_CHAR:
61         case IDLN_TYPE_WIDE_CHAR:
62         case IDLN_TYPE_FLOAT:
63         case IDLN_TYPE_BOOLEAN:
64         case IDLN_TYPE_OCTET:
65         case IDLN_TYPE_SEQUENCE:
66         case IDLN_TYPE_STRUCT:
67         case IDLN_TYPE_UNION:
68         case IDLN_TYPE_ENUM:
69         case IDLN_IDENT:
70         case IDLN_EXCEPT_DCL:
71         case IDLN_INTERFACE:
72         case IDLN_FORWARD_DCL:
73         case IDLN_TYPE_OBJECT: {
74                 char *typespec = forb_cbe_get_typespec_str (node);
75
76                 g_string_printf (tmpstr, "TC_%s", typespec);
77
78                 g_free (typespec);
79                 }
80                 break;
81         default:
82                 g_string_printf (tmpstr, "anonTC_%d", random_id++);
83                 break;
84         }
85
86         retval = tmpstr->str;
87         g_string_free (tmpstr, FALSE);
88
89         return retval;
90 }
91
92 static void
93 forb_output_tcstruct_anon_subnames_array (FILE *fh, IDL_tree node, int subnames_id)
94 {
95         IDL_tree l;
96
97         switch (IDL_NODE_TYPE (node)) {
98         case IDLN_TYPE_ENUM:
99                 if (!IDL_TYPE_ENUM (node).enumerator_list)
100                         break;
101
102                 fprintf (fh, "static const char *anon_subnames_array%d[] = {", subnames_id);
103
104                 for (l = IDL_TYPE_ENUM (node).enumerator_list; l; l = IDL_LIST (l).next) {
105                         g_assert (IDL_NODE_TYPE (IDL_LIST (l).data) == IDLN_IDENT);
106
107                         fprintf (fh, "\"%s\"", IDL_IDENT (IDL_LIST (l).data).str );
108                         if (IDL_LIST (l).next)
109                                 fprintf (fh, ", ");
110                 }
111
112                 fprintf (fh, "};\n");
113                 break;
114         case IDLN_EXCEPT_DCL:
115         case IDLN_TYPE_STRUCT:
116                 if (!IDL_TYPE_STRUCT (node).member_list)
117                         break;
118
119                 fprintf (fh, "static const char *anon_subnames_array%d[] = {", subnames_id);
120
121                 for (l = IDL_TYPE_STRUCT (node).member_list; l; l = IDL_LIST (l).next) {
122                         IDL_tree dcl;
123
124                         g_assert (IDL_NODE_TYPE (IDL_LIST (l).data) == IDLN_MEMBER);
125
126                         for (dcl = IDL_MEMBER (IDL_LIST (l).data).dcls; dcl;
127                              dcl = IDL_LIST (dcl).next) {
128                                 IDL_tree p = IDL_LIST (dcl).data;
129
130                                 g_assert (IDL_NODE_TYPE (p) == IDLN_IDENT ||
131                                           IDL_NODE_TYPE (p) == IDLN_TYPE_ARRAY);
132
133                                 if (IDL_NODE_TYPE (p) == IDLN_IDENT)
134                                         fprintf (fh, "\"%s\"", IDL_IDENT (p).str);
135
136                                 else /* IDLN_TYPE_ARRAY */
137                                         fprintf (fh, "\"%s\"", 
138                                                  IDL_IDENT (IDL_TYPE_ARRAY (p).ident).str);
139         
140                                 if (IDL_LIST (dcl).next || IDL_LIST (l).next)
141                                         fprintf (fh, ", ");
142                         }
143                 }
144
145                 fprintf (fh, "};\n");
146                 break;
147         case IDLN_TYPE_UNION:
148                 if (!IDL_TYPE_UNION (node).switch_body)
149                         break;
150
151                 fprintf (fh, "static const char * anon_subnames_array%d[] = {", subnames_id);
152
153                 for (l = IDL_TYPE_UNION (node).switch_body; l; l = IDL_LIST (l).next) {
154                         IDL_tree dcl, label;
155                         const char *subname;
156
157                         g_assert (IDL_NODE_TYPE (IDL_LIST (l).data) == IDLN_CASE_STMT);
158
159                         dcl = IDL_LIST (IDL_MEMBER (
160                                 IDL_CASE_STMT (IDL_LIST (l).data).element_spec).dcls).data;
161
162                         g_assert (IDL_NODE_TYPE (dcl) == IDLN_IDENT ||
163                                   IDL_NODE_TYPE (dcl) == IDLN_TYPE_ARRAY);
164
165                         if (IDL_NODE_TYPE (dcl) == IDLN_IDENT)
166                                 subname = IDL_IDENT (dcl).str;
167                         else /* IDLN_TYPE_ARRAY */
168                                 subname = IDL_IDENT (IDL_TYPE_ARRAY (dcl).ident).str;
169
170                         /* output the name once for each label */
171                         for (label = IDL_CASE_STMT (IDL_LIST (l).data).labels;
172                              label != NULL; label = IDL_LIST (label).next) {
173                                 fprintf (fh, "\"%s\"", subname);
174                                 if (IDL_LIST (label).next)
175                                         fprintf (fh, ", ");
176                         }
177
178                         if (IDL_LIST (l).next)
179                                 fprintf (fh, ", ");
180                 }
181                 fprintf (fh, "};\n");
182                 break;
183         default:
184                 break;
185         }
186 }
187
188 static void
189 forb_output_tcstruct_anon_subtypes_array (FILE     *fh,
190                                            IDL_tree  node,
191                                            int       subtypes_id,
192                                            char     *substructname)
193 {
194         IDL_tree l;
195
196         switch (IDL_NODE_TYPE (node)) {
197         case IDLN_EXCEPT_DCL:
198         case IDLN_TYPE_STRUCT:
199                 if (!IDL_TYPE_STRUCT (node).member_list)
200                         break;
201
202                 fprintf (fh, "static FORB2_MAYBE_CONST CORBA_TypeCode anon_subtypes_array%d[] = {",
203                          subtypes_id);
204
205                 for (l = IDL_TYPE_STRUCT (node).member_list; l; l = IDL_LIST (l).next) {
206                         IDL_tree  dcl;
207                         char     *tmpstr;
208
209                         dcl = IDL_MEMBER (IDL_LIST (l).data).type_spec;
210
211                         switch (IDL_NODE_TYPE (dcl)) {
212                         case IDLN_IDENT:
213                         case IDLN_INTERFACE:
214                         case IDLN_TYPE_OBJECT:
215                         case IDLN_FORWARD_DCL:
216                                 dcl = forb_cbe_get_typespec (dcl);
217
218                                 if (IDL_NODE_DECLSPEC (dcl) & IDLF_DECLSPEC_PIDL &&
219                                    (IDL_NODE_TYPE (dcl) == IDLN_INTERFACE ||
220                                     IDL_NODE_TYPE (dcl) == IDLN_FORWARD_DCL))
221                                         tmpstr = g_strdup ("Object");
222                                 else
223                                         tmpstr = forb_cbe_get_typespec_str (
224                                                         IDL_MEMBER (IDL_LIST (l).data).type_spec);
225                                 break;
226                         default:
227                                 tmpstr = forb_cbe_get_typespec_str (
228                                                 IDL_MEMBER (IDL_LIST (l).data).type_spec);
229                                 break;
230                         }
231
232                         g_assert (IDL_NODE_TYPE (IDL_LIST (l).data) == IDLN_MEMBER);
233
234                         for (dcl = IDL_MEMBER (IDL_LIST (l).data).dcls; dcl;
235                              dcl = IDL_LIST (dcl).next) {
236
237                                 fprintf (fh, "(CORBA_TypeCode)&TC_%s_struct", tmpstr);
238
239                                 if (IDL_LIST (dcl).next || IDL_LIST (l).next)
240                                         fprintf (fh, ", ");
241                         }
242
243                         g_free (tmpstr);
244                 }
245
246                 fprintf (fh, "};\n");
247
248                 break;
249         case IDLN_TYPE_UNION:
250                 if (!IDL_TYPE_UNION (node).switch_body)
251                         break;
252
253                 fprintf (fh, "static FORB2_MAYBE_CONST CORBA_TypeCode anon_subtypes_array%d[] = {", subtypes_id);
254
255                 for (l = IDL_TYPE_UNION (node).switch_body; l; l = IDL_LIST (l).next) {
256                         IDL_tree  label, dcl;
257                         char     *tmpstr;
258
259                         g_assert (IDL_NODE_TYPE (IDL_LIST (l).data) == IDLN_CASE_STMT);
260
261                         dcl = IDL_MEMBER (IDL_CASE_STMT (IDL_LIST (l).data).element_spec).type_spec;
262
263                         switch (IDL_NODE_TYPE (forb_cbe_get_typespec (dcl))) {
264                         case IDLN_INTERFACE:
265                         case IDLN_FORWARD_DCL:
266                                 if (IDL_NODE_DECLSPEC (dcl) & IDLF_DECLSPEC_PIDL)
267                                         tmpstr = g_strdup ( "Object");
268                                 else
269                                         tmpstr = forb_cbe_get_typespec_str (dcl);
270                                 break;
271                         default:
272                                 tmpstr = forb_cbe_get_typespec_str (dcl);
273                                 break;
274                         }
275
276                         for (label = IDL_CASE_STMT (IDL_LIST (l).data).labels; label;
277                              label = IDL_LIST (label).next) {
278                                 fprintf (fh, "(CORBA_TypeCode)&TC_%s_struct", tmpstr);
279
280                                 if (IDL_LIST (label).next || IDL_LIST (l).next)
281                                         fprintf (fh, ", ");
282                         }
283
284                         g_free (tmpstr);
285                 }
286
287                 fprintf (fh, "};\n");
288
289                 break;
290         case IDLN_TYPE_SEQUENCE: {
291                 IDL_tree  seqts;
292                 char     *tmpstr;
293
294                 seqts = forb_cbe_get_typespec (IDL_TYPE_SEQUENCE (node).simple_type_spec);
295
296                 fprintf (fh, "static FORB2_MAYBE_CONST CORBA_TypeCode anon_subtypes_array%d[] = ", subtypes_id);
297
298                 switch (IDL_NODE_TYPE (seqts)) {
299                 case IDLN_INTERFACE:
300                 case IDLN_FORWARD_DCL:
301                         if (IDL_NODE_DECLSPEC (seqts) && IDLF_DECLSPEC_PIDL)
302                                 tmpstr = g_strdup ("Object");
303                         else
304                                 tmpstr = forb_cbe_get_typespec_str (
305                                                 IDL_TYPE_SEQUENCE (node).simple_type_spec);
306                         break;
307                 default:
308                         tmpstr = forb_cbe_get_typespec_str (
309                                                 IDL_TYPE_SEQUENCE (node).simple_type_spec);
310                         break;
311                 }
312
313                 fprintf (fh, "{(CORBA_TypeCode)&TC_%s_struct};\n", tmpstr);
314                 g_free (tmpstr);
315
316                 }
317                 break;
318         case IDLN_TYPE_ARRAY:
319         case IDLN_IDENT:
320                 fprintf (fh, "static FORB2_MAYBE_CONST CORBA_TypeCode anon_subtypes_array%d[] = ", subtypes_id);
321                 fprintf (fh, "{(CORBA_TypeCode)&%s_struct};\n", substructname);
322                 break;
323         default:
324                 break;
325         }
326 }
327
328 static int
329 forb_output_tcstruct_anon_sublabels_array (FILE     *fh, 
330                                             IDL_tree  node,
331                                             int       sublabels_id)
332 {
333         IDL_tree l, label;
334         int      index = 0;
335         int      default_index = -1;
336
337         if (IDL_NODE_TYPE (node) != IDLN_TYPE_UNION ||
338             !IDL_TYPE_UNION (node).switch_body)
339                 return default_index;
340
341         fprintf (fh, "static FORB2_MAYBE_CONST CORBA_long anon_sublabels_array%d[] = {", sublabels_id);
342
343         for (l = IDL_TYPE_UNION (node).switch_body; l; l = IDL_LIST (l).next)
344                 for (label = IDL_CASE_STMT (IDL_LIST (l).data).labels; label;
345                      label = IDL_LIST (label).next, index++) {
346
347                         if (IDL_LIST (label).data) {
348                                 fprintf (fh, "(CORBA_long) ");
349
350                                 forb_cbe_write_const (fh, IDL_LIST (label).data);
351
352                         } else { /* default case */
353                                 fprintf (fh, "-1");
354                                 default_index = index;
355                         }
356
357                         if (IDL_LIST (label).next || IDL_LIST (l).next)
358                                 fprintf (fh, ", ");
359                 }
360
361         fprintf (fh, "};\n");
362
363         return default_index;
364 }
365
366 static void
367 forb_output_tcstruct_parent (FILE *fh)
368 {
369         fprintf (fh, "{&Forb_TypeCode_epv, FORB_REFCOUNT_STATIC}");
370 }
371
372 static void
373 forb_output_tcstruct_kind (FILE *fh, IDL_tree node, int array_gen_ctr)
374 {
375         switch (IDL_NODE_TYPE (node)) {
376         case IDLN_TYPE_ARRAY:
377                 if (array_gen_ctr)
378                         fprintf (fh, "CORBA_tk_array");
379                 else
380                         fprintf (fh, "CORBA_tk_alias");
381                 break;
382         case IDLN_IDENT:
383                 fprintf (fh, "CORBA_tk_alias");
384                 break;
385         case IDLN_TYPE_STRUCT:
386                 fprintf (fh, "CORBA_tk_struct");
387                 break;
388         case IDLN_TYPE_UNION:
389                 fprintf (fh, "CORBA_tk_union");
390                 break;
391         case IDLN_TYPE_ENUM:
392                 fprintf (fh, "CORBA_tk_enum");
393                 break;
394         case IDLN_TYPE_OBJECT:
395         case IDLN_INTERFACE:
396         case IDLN_FORWARD_DCL:
397                 fprintf (fh, "CORBA_tk_objref");
398                 break;
399         case IDLN_EXCEPT_DCL:
400                 fprintf (fh, "CORBA_tk_except");
401                 break;
402         case IDLN_TYPE_INTEGER:
403                 fprintf (fh, "CORBA_tk_");
404
405                 if (!IDL_TYPE_INTEGER (node).f_signed)
406                         fprintf (fh, "u");
407
408                 switch (IDL_TYPE_INTEGER (node).f_type) {
409                 case IDL_INTEGER_TYPE_SHORT:
410                         fprintf (fh, "short");
411                         break;
412                 case IDL_INTEGER_TYPE_LONG:
413                         fprintf (fh, "long");
414                         break;
415                 case IDL_INTEGER_TYPE_LONGLONG:
416                         fprintf (fh, "longlong");
417                         break;
418                 }
419                 break;
420         case IDLN_TYPE_FLOAT:
421                 fprintf (fh, "CORBA_tk_");
422
423                 switch (IDL_TYPE_FLOAT (node).f_type) {
424                 case IDL_FLOAT_TYPE_FLOAT:
425                         fprintf (fh, "float");
426                         break;
427                 case IDL_FLOAT_TYPE_DOUBLE:
428                         fprintf (fh, "double");
429                         break;
430                 case IDL_FLOAT_TYPE_LONGDOUBLE:
431                         fprintf (fh, "longdouble");
432                         break;
433                 }
434                 break;
435         case IDLN_TYPE_BOOLEAN:
436                 fprintf (fh, "CORBA_tk_boolean");
437                 break;
438         case IDLN_TYPE_OCTET:
439                 fprintf (fh, "CORBA_tk_octet");
440                 break;
441         case IDLN_TYPE_STRING:
442                 fprintf (fh, "CORBA_tk_string");
443                 break;
444         case IDLN_TYPE_WIDE_STRING:
445                 fprintf (fh, "CORBA_tk_wstring");
446                 break;
447         case IDLN_TYPE_CHAR:
448                 fprintf (fh, "CORBA_tk_char");
449                 break;
450         case IDLN_TYPE_WIDE_CHAR:
451                 fprintf (fh, "CORBA_tk_wchar");
452                 break;
453         case IDLN_TYPE_ANY:
454                 fprintf (fh, "CORBA_tk_any");
455                 break;
456         case IDLN_TYPE_SEQUENCE:
457                 fprintf (fh, "CORBA_tk_sequence");
458                 break;
459         default:
460                 g_message ("Type %s has no tk constant!",
461                            IDL_tree_type_names[IDL_NODE_TYPE (node)]);
462         }
463 }
464
465 static void
466 forb_output_tcstruct_name (FILE *fh, IDL_tree node, int array_gen_ctr)
467 {
468         switch (IDL_NODE_TYPE (node)) {
469         case IDLN_TYPE_STRUCT:
470                 fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_TYPE_STRUCT (node).ident).str);
471                 break;
472         case IDLN_TYPE_UNION:
473                 fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_TYPE_UNION (node).ident).str);
474                 break;
475         case IDLN_TYPE_ENUM:
476                 fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_TYPE_ENUM (node).ident).str);
477                 break;
478         case IDLN_INTERFACE:
479         case IDLN_FORWARD_DCL:
480                 fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_INTERFACE (node).ident).str);
481                 break;
482         case IDLN_EXCEPT_DCL:
483                 fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_EXCEPT_DCL (node).ident).str);
484                 break;
485         case IDLN_IDENT:
486                 fprintf (fh, "(char *)\"%s\"", IDL_IDENT (node).str);
487                 break;
488         case IDLN_TYPE_ARRAY:
489                 if (!array_gen_ctr)
490                         fprintf (fh, "(char *)\"%s\"", 
491                                  IDL_IDENT (IDL_TYPE_ARRAY (node).ident).str);
492                 else
493                         fprintf (fh, "NULL");
494                 break;
495         default:
496                 fprintf (fh, "NULL");
497                 break;
498         }
499 }
500
501 static void
502 forb_output_tcstruct_repo_id (FILE *fh, IDL_tree node, int array_gen_ctr)
503 {
504         switch (IDL_NODE_TYPE (node)) {
505         case IDLN_TYPE_STRUCT:
506                 fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_TYPE_STRUCT (node).ident).repo_id);
507                 break;
508         case IDLN_TYPE_UNION:
509                 fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_TYPE_UNION (node).ident).repo_id);
510                 break;
511         case IDLN_TYPE_ENUM:
512                 fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_TYPE_ENUM (node).ident).repo_id);
513                 break;
514         case IDLN_INTERFACE:
515         case IDLN_FORWARD_DCL:
516                 fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_INTERFACE (node).ident).repo_id);
517                 break;
518         case IDLN_EXCEPT_DCL:
519                 fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_EXCEPT_DCL (node).ident).repo_id);
520                 break;
521         case IDLN_IDENT:
522                 fprintf (fh, "(char *)\"%s\"", IDL_IDENT (node).repo_id);
523                 break;
524         case IDLN_TYPE_ARRAY:
525                 if (!array_gen_ctr)
526                         fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_TYPE_ARRAY (node).ident).repo_id);
527                 else
528                         fprintf (fh, "NULL");
529                 break;
530         default:
531                 fprintf (fh, "NULL");
532                 break;
533         }
534 }
535
536 static void
537 forb_output_tcstruct_length (FILE *fh, IDL_tree node, int array_gen_ctr)
538 {
539         int length = 0;
540
541         switch (IDL_NODE_TYPE (node)) {
542         case IDLN_TYPE_SEQUENCE:
543                 if (IDL_TYPE_SEQUENCE (node).positive_int_const)
544                         length = IDL_INTEGER (IDL_TYPE_SEQUENCE (node).positive_int_const).value;
545                 break;
546         case IDLN_TYPE_STRING:
547                 if (IDL_TYPE_STRING (node).positive_int_const)
548                         length = IDL_INTEGER (IDL_TYPE_STRING (node).positive_int_const).value;
549                 break;
550         case IDLN_TYPE_WIDE_STRING:
551                 if (IDL_TYPE_WIDE_STRING (node).positive_int_const)
552                         length = IDL_INTEGER (IDL_TYPE_STRING (node).positive_int_const).value;
553                 break;
554         case IDLN_TYPE_ARRAY:
555                 if (array_gen_ctr) {
556                         IDL_tree sizer;
557
558                         sizer = IDL_list_nth (IDL_TYPE_ARRAY (node).size_list,
559                                               array_gen_ctr - 1);
560
561                         g_assert (IDL_NODE_TYPE (IDL_LIST (sizer).data) == IDLN_INTEGER);
562
563                         length = IDL_INTEGER (IDL_LIST (sizer).data).value;
564                 }
565                 break;
566         default:
567                 length = 0;
568                 break;
569         }
570
571         fprintf (fh, "%d", length);
572 }
573
574 static void
575 forb_output_tcstruct_sub_parts (FILE *fh, IDL_tree node)
576 {
577         int length = 0;
578
579         switch (IDL_NODE_TYPE (node)) {
580         case IDLN_TYPE_STRUCT:
581         case IDLN_EXCEPT_DCL: {
582                 IDL_tree l;
583
584                 for (l = IDL_TYPE_STRUCT (node).member_list; l; l = IDL_LIST (l).next) {
585                         IDL_tree member;
586
587                         member = IDL_LIST (l).data;
588
589                         g_assert (IDL_NODE_TYPE (member) == IDLN_MEMBER);
590
591                         length += IDL_list_length (IDL_MEMBER (member).dcls);
592                 }
593                 }
594                 break;
595         case IDLN_TYPE_UNION: {
596                 IDL_tree l;
597
598                 for (l = IDL_TYPE_UNION (node).switch_body; l; l = IDL_LIST (l).next) {
599                         IDL_tree case_stmt;
600
601                         case_stmt = IDL_LIST (l).data;
602
603                         g_assert (IDL_NODE_TYPE (case_stmt) == IDLN_CASE_STMT);
604
605                         length += IDL_list_length (IDL_CASE_STMT (case_stmt).labels);
606                 }
607                 }
608                 break;
609         case IDLN_TYPE_ENUM:
610                 length = IDL_list_length (IDL_TYPE_ENUM (node).enumerator_list);
611                 break;
612         case IDLN_IDENT:
613         case IDLN_TYPE_SEQUENCE:
614         case IDLN_TYPE_ARRAY:
615                 length = 1;
616                 break;
617         default:
618                 length = 0;
619                 break;
620         }
621
622         fprintf (fh, "%d\n", length);
623 }
624
625 static void
626 forb_output_tcstruct_subnames (FILE *fh, IDL_tree node, int subnames_id)
627 {
628         switch (IDL_NODE_TYPE (node)) {
629         case IDLN_TYPE_ENUM:
630                 if (IDL_TYPE_ENUM (node).enumerator_list)
631                         fprintf (fh, "(char **)anon_subnames_array%d", subnames_id);
632                 else
633                         fprintf (fh, "NULL");
634                 break;
635         case IDLN_TYPE_UNION:
636                 if (IDL_TYPE_UNION (node).switch_body)
637                         fprintf (fh, "(char **)anon_subnames_array%d", subnames_id);
638                 else
639                         fprintf (fh, "NULL");
640                 break;
641         case IDLN_TYPE_STRUCT:
642         case IDLN_EXCEPT_DCL:
643                 if (IDL_TYPE_STRUCT (node).member_list)
644                         fprintf (fh, "(char **)anon_subnames_array%d", subnames_id);
645                 else
646                         fprintf (fh, "NULL");
647                 break;
648         default:
649                 fprintf (fh, "NULL");
650                 break;
651         }
652 }
653
654 static void
655 forb_output_tcstruct_subtypes (FILE *fh, IDL_tree node, int subtypes_id)
656 {
657         switch (IDL_NODE_TYPE (node)) {
658         case IDLN_EXCEPT_DCL:
659         case IDLN_TYPE_STRUCT:
660                 if (IDL_TYPE_STRUCT (node).member_list)
661                         fprintf (fh, "(CORBA_TypeCode *)anon_subtypes_array%d", subtypes_id);
662                 else
663                         fprintf (fh, "NULL");
664                 break;
665         case IDLN_TYPE_UNION:
666                 if (IDL_TYPE_UNION (node).switch_body)
667                         fprintf (fh, "(CORBA_TypeCode *)anon_subtypes_array%d", subtypes_id);
668                 else
669                         fprintf (fh, "NULL");
670                 break;
671         case IDLN_TYPE_SEQUENCE:
672         case IDLN_TYPE_ARRAY:
673         case IDLN_IDENT:
674                 fprintf (fh, "(CORBA_TypeCode *)anon_subtypes_array%d", subtypes_id);
675                 break;
676         default:
677                 fprintf (fh, "NULL");
678                 break;
679         }
680 }
681
682 static void
683 forb_output_tcstruct_sublabels (FILE *fh, IDL_tree node, int sublabels_id)
684 {
685         switch (IDL_NODE_TYPE (node)) {
686         case IDLN_TYPE_UNION:
687                 fprintf (fh, "(CORBA_long *)anon_sublabels_array%d", sublabels_id);
688                 break;
689         default:
690                 fprintf (fh, "NULL");
691                 break;
692         }
693 }
694
695 static void
696 forb_output_tcstruct_discriminator (FILE *fh, IDL_tree node)
697 {
698         switch (IDL_NODE_TYPE (node)) {
699         case IDLN_TYPE_UNION: {
700                 char *switch_type_spec_str;
701
702                 switch_type_spec_str = 
703                         forb_cbe_get_typespec_str (IDL_TYPE_UNION (node).switch_type_spec);
704
705                 fprintf (fh, "(CORBA_TypeCode)&TC_%s_struct", switch_type_spec_str);
706
707                 g_free (switch_type_spec_str);
708                 }
709                 break;
710         default:
711                 fprintf (fh, "CORBA_OBJECT_NIL");
712                 break;
713         }
714 }
715
716 static void
717 forb_output_tcstruct_recurse_depth (FILE *fh)
718 {
719         fprintf (fh, "0");
720 }
721
722 static void
723 forb_output_tcstruct_default_index (FILE *fh, int union_default_index)
724 {
725         fprintf (fh, "%d", union_default_index);
726 }
727
728 static void
729 forb_output_tcstruct_digits_scale (FILE *fh, IDL_tree node)
730 {
731         if (IDL_NODE_TYPE (node) == IDLN_TYPE_FIXED) {
732                 fprintf (fh, "%" IDL_LL "d, %" IDL_LL "d" ,
733                          IDL_INTEGER (IDL_TYPE_FIXED (node).positive_int_const).value,
734                          IDL_INTEGER (IDL_TYPE_FIXED (node).integer_lit).value);
735         }
736         else
737                 fprintf (fh, "0, 0");
738 }
739
740 static void
741 forb_add_align (GSList **max, const char *str)
742 {
743         GSList *l;
744
745         for (l = *max; l; l = l->next) {
746                 if (!strcmp (l->data, str))
747                         return;
748         }
749         *max = g_slist_prepend (*max, (gpointer) str);
750 }
751
752 static GSList *
753 forb_find_c_align (GSList *max, IDL_tree node)
754 {
755         node = forb_cbe_get_typespec (node);    
756
757         switch (IDL_NODE_TYPE (node)) {
758         case IDLN_TYPE_INTEGER:
759                 switch (IDL_TYPE_INTEGER (node).f_type) {
760                 case IDL_INTEGER_TYPE_SHORT:
761                         forb_add_align (&max, "FORB_ALIGNOF_CORBA_SHORT");
762                         break;
763                 case IDL_INTEGER_TYPE_LONG:
764                         forb_add_align (&max, "FORB_ALIGNOF_CORBA_LONG");
765                         break;
766                 case IDL_INTEGER_TYPE_LONGLONG:
767                         forb_add_align (&max, "FORB_ALIGNOF_CORBA_LONG_LONG");
768                         break;
769                 }
770                 break;
771         case IDLN_TYPE_FLOAT:
772                 switch (IDL_TYPE_FLOAT (node).f_type) {
773                 case IDL_FLOAT_TYPE_FLOAT:
774                         forb_add_align (&max, "FORB_ALIGNOF_CORBA_FLOAT");
775                         break;
776                 case IDL_FLOAT_TYPE_DOUBLE:
777                         forb_add_align (&max, "FORB_ALIGNOF_CORBA_DOUBLE");
778                         break;
779                 case IDL_FLOAT_TYPE_LONGDOUBLE:
780                         forb_add_align (&max, "FORB_ALIGNOF_CORBA_LONG_DOUBLE");
781                         break;
782                 }
783                 break;
784         case IDLN_TYPE_ENUM:
785                 forb_add_align (&max, "FORB_ALIGNOF_CORBA_LONG");
786                 break;
787         case IDLN_TYPE_CHAR: /* drop through */
788         case IDLN_TYPE_BOOLEAN:
789         case IDLN_TYPE_OCTET:
790                 forb_add_align (&max, "FORB_ALIGNOF_CORBA_CHAR");
791                 break;
792         case IDLN_TYPE_WIDE_CHAR:
793                 forb_add_align (&max, "FORB_ALIGNOF_CORBA_SHORT");
794                 break;
795         case IDLN_TYPE_UNION: {
796                 IDL_tree l = IDL_TYPE_UNION (node).switch_body;
797
798                 forb_add_align (&max, "FORB_ALIGNOF_CORBA_STRUCT");
799
800                 for (; l; l = IDL_LIST (l).next) {
801                         IDL_tree subtype = IDL_MEMBER (IDL_CASE_STMT (
802                                 IDL_LIST (l).data).element_spec).type_spec;
803                         max = forb_find_c_align (max, subtype);
804                 }
805                 break;
806         }
807         case IDLN_EXCEPT_DCL: /* drop through */
808         case IDLN_TYPE_STRUCT: {
809                 IDL_tree l = IDL_TYPE_STRUCT (node).member_list;
810                                         
811                 for (; l; l = IDL_LIST (l).next) {
812                         IDL_tree member = IDL_MEMBER (IDL_LIST (l).data).type_spec;
813
814                         max = forb_find_c_align (max, member);
815                 }
816                 break;
817         }
818         case IDLN_TYPE_STRING: /* drop through */
819         case IDLN_TYPE_WIDE_STRING:
820         case IDLN_TYPE_OBJECT:
821         case IDLN_TYPE_TYPECODE:
822         case IDLN_FORWARD_DCL:
823         case IDLN_INTERFACE:
824                 forb_add_align (&max, "FORB_ALIGNOF_CORBA_POINTER");
825                 break;
826         case IDLN_TYPE_ARRAY: {
827                 IDL_tree subtype = IDL_TYPE_DCL (
828                         IDL_get_parent_node (node, IDLN_TYPE_DCL, NULL)).type_spec;
829                 max = forb_find_c_align (max, subtype);
830                 break;
831         }
832         case IDLN_TYPE_SEQUENCE:
833                 forb_add_align (&max, "FORB_ALIGNOF_CORBA_STRUCT");
834                 forb_add_align (&max, "FORB_ALIGNOF_CORBA_LONG");
835                 forb_add_align (&max, "FORB_ALIGNOF_CORBA_POINTER");
836                 break;
837         case IDLN_TYPE_ANY:
838                 forb_add_align (&max, "FORB_ALIGNOF_CORBA_STRUCT");
839                 forb_add_align (&max, "FORB_ALIGNOF_CORBA_POINTER");
840                 break;
841         default:
842                 g_error ("Can't find alignment %s\n", 
843                          IDL_tree_type_names[IDL_NODE_TYPE (node)]);
844                 break;
845         }
846
847         return max;
848 }
849
850 static void
851 forb_output_tcstruct_c_align (FILE *fh, IDL_tree node)
852 {
853         GSList *max;
854         GString *str = g_string_sized_new (120);
855
856         max = forb_find_c_align (NULL, node);
857
858         if (!max)
859                 g_string_append (str, "1");
860
861         else if (!max->next)
862                 g_string_append (str, max->data);
863
864         else {
865                 int i = 0;
866                 GSList *l;
867
868                 for (l = max; l; l = l->next) {
869                         g_string_append (str, "MAX (");
870                         g_string_append (str, l->data);
871                         g_string_append (str, ", ");
872                         i++;
873                 }
874                 
875                 g_string_append (str, "1");
876                 for (; i > 0; i--)
877                         g_string_append_c (str, ')');
878         }
879
880         fprintf (fh, "%s", str->str);
881
882         g_string_free (str, TRUE);
883 }
884
885 static void
886 cbe_tc_generate (OIDL_C_Info  *ci,
887                  CBETCGenInfo *tci)
888 {
889         CBETCGenInfo  subtci;
890         IDL_tree      curitem;
891         char         *ctmp;
892         int           union_default_index = -1,
893                       subnames_id  = random_id++,
894                       subtypes_id  = random_id++,
895                       sublabels_id = random_id++;
896
897         if (strncmp (tci->structname, "anon", 4)) {
898                 fprintf (ci->fh, "#if ");
899                 forb_cbe_id_cond_hack (ci->fh, "TC_IMPL",
900                                         tci->structname, ci->c_base_name);
901                 fprintf (ci->fh, " && !defined(TC_DEF_%s)\n", tci->structname);
902                 fprintf (ci->fh, "#define TC_DEF_%s 1\n", tci->structname);
903         }
904
905         if (IDL_NODE_TYPE (tci->ts) == IDLN_TYPE_DCL) {
906                 subtci = *tci;
907
908                 curitem = IDL_TYPE_DCL (tci->ts).type_spec;
909                 subtci.substructname = ctmp = forb_generate_tcstruct_name (curitem);
910
911                 /* 
912                  * The only type not already defined elsewhere
913                  * that can be in the left half of a TypeCode.
914                  */
915                 if (IDL_NODE_TYPE (curitem) == IDLN_TYPE_SEQUENCE) {
916                         subtci.structname = ctmp;
917                         subtci.ts         = curitem;
918                         cbe_tc_generate (ci, &subtci);
919                 }
920
921                 for (curitem = IDL_TYPE_DCL (tci->ts).dcls; curitem;
922                      curitem = IDL_LIST (curitem).next) {
923                         subtci.ts = IDL_LIST (curitem).data;
924
925                         if (IDL_NODE_TYPE (subtci.ts) == IDLN_TYPE_ARRAY)
926                                 subtci.structname = forb_generate_tcstruct_name (
927                                                         IDL_TYPE_ARRAY (subtci.ts).ident);
928                         else
929                                 subtci.structname = forb_generate_tcstruct_name (subtci.ts);
930
931                         cbe_tc_generate (ci, &subtci);
932                         g_free (subtci.structname);
933                 }
934
935         g_free (ctmp);
936         return;
937         }
938
939         /* Do magic here - nesting of typecodes for arrays */
940         if (IDL_NODE_TYPE (tci->ts) == IDLN_TYPE_ARRAY && 
941             (IDL_list_length (IDL_TYPE_ARRAY (tci->ts).size_list) > tci->array_gen_ctr)) {
942
943                 curitem = IDL_list_nth (IDL_TYPE_ARRAY (tci->ts).size_list,
944                                         tci->array_gen_ctr - 1);
945
946                 subtci = *tci;
947                 subtci.structname = ctmp = forb_generate_tcstruct_name (curitem);
948                 subtci.array_gen_ctr++;
949
950                 cbe_tc_generate (ci, &subtci);
951
952                 tci->substructname = ctmp; /* FIXME: memory leak */
953         }
954
955         forb_output_tcstruct_anon_subnames_array  (ci->fh, tci->ts, subnames_id);
956         forb_output_tcstruct_anon_subtypes_array  (ci->fh, tci->ts, subtypes_id,
957                                                     tci->substructname);
958
959         union_default_index = forb_output_tcstruct_anon_sublabels_array (
960                                         ci->fh, tci->ts, sublabels_id);
961
962         if (!strncmp (tci->structname, "anon", 4))
963                 fprintf (ci->fh, "static ");
964         else {
965                 fprintf (ci->fh, "#ifdef FORB_IDL_C_IMODULE_%s\n",
966                          ci->c_base_name);
967                 fprintf (ci->fh, "static\n");
968                 fprintf (ci->fh, "#endif\n");
969         }
970
971         fprintf (ci->fh, "FORB2_MAYBE_CONST struct CORBA_TypeCode_struct %s_struct = {\n",
972                                 tci->structname);
973
974         forb_output_tcstruct_parent (ci->fh);
975
976         fprintf (ci->fh, ",\n");
977
978         forb_output_tcstruct_kind (ci->fh, tci->ts, tci->array_gen_ctr);
979
980         fprintf (ci->fh, ",\n");
981
982         /* flags */
983         fprintf (ci->fh, "0,\n");
984
985         /* c_length */
986         fprintf (ci->fh, "0,\n");
987
988         forb_output_tcstruct_c_align (ci->fh, tci->ts);
989
990         fprintf (ci->fh, ",\n");
991
992         forb_output_tcstruct_length (ci->fh, tci->ts, tci->array_gen_ctr);
993
994         fprintf (ci->fh, ",\n");
995
996         forb_output_tcstruct_sub_parts (ci->fh, tci->ts);
997
998         fprintf (ci->fh, ",\n");
999
1000         forb_output_tcstruct_subtypes (ci->fh, tci->ts, subtypes_id);
1001
1002         fprintf (ci->fh, ",\n");
1003
1004         forb_output_tcstruct_discriminator (ci->fh, tci->ts);
1005
1006         fprintf (ci->fh, ",\n");
1007
1008         forb_output_tcstruct_name (ci->fh, tci->ts, tci->array_gen_ctr);
1009
1010         fprintf (ci->fh, ",\n");
1011
1012         forb_output_tcstruct_repo_id (ci->fh, tci->ts, tci->array_gen_ctr);
1013
1014         fprintf (ci->fh, ",\n");
1015
1016         forb_output_tcstruct_subnames (ci->fh, tci->ts, subnames_id);
1017
1018         fprintf (ci->fh, ",\n");
1019
1020         forb_output_tcstruct_sublabels (ci->fh, tci->ts, sublabels_id);
1021
1022         fprintf (ci->fh, ",\n");
1023
1024         forb_output_tcstruct_default_index (ci->fh, union_default_index);
1025
1026         fprintf (ci->fh, ",\n");
1027
1028         forb_output_tcstruct_recurse_depth (ci->fh);
1029
1030         fprintf (ci->fh, ",\n");
1031
1032         forb_output_tcstruct_digits_scale (ci->fh, tci->ts);
1033
1034         fprintf (ci->fh, "\n};\n");
1035
1036         if (strncmp (tci->structname, "anon", 4))
1037                 fprintf (ci->fh, "#endif\n");
1038 }