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