~ubuntu-branches/ubuntu/natty/orbit2/natty

« back to all changes in this revision

Viewing changes to src/idl-compiler/orbit-idl-c-skels.c

  • Committer: Bazaar Package Importer
  • Author(s): Chris Waters
  • Date: 2002-03-25 17:24:03 UTC
  • Revision ID: james.westby@ubuntu.com-20020325172403-8lexv63608acfqgt
Tags: upstream-2.3.107
ImportĀ upstreamĀ versionĀ 2.3.107

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "config.h"
 
2
#include <string.h>
 
3
#include "orbit-idl-c-backend.h"
 
4
 
 
5
typedef struct {
 
6
  OIDL_C_Info *ci;
 
7
  GSList *oplist;
 
8
  gint curlevel;
 
9
  gboolean small;
 
10
} CBESkelInterfaceTraverseInfo;
 
11
 
 
12
typedef struct {
 
13
  char *iface_id;
 
14
  char *opname;
 
15
  IDL_tree op;
 
16
  int      idx;
 
17
} CBESkelOpInfo;
 
18
 
 
19
static void ck_output_skels(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci, int *idx);
 
20
static void ck_output_poastuff(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
 
21
 
 
22
void
 
23
orbit_idl_output_c_skeletons(OIDL_Output_Tree *tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
 
24
{
 
25
  fprintf(ci->fh, "/*\n"
 
26
                   " * This file was generated by orbit-idl - DO NOT EDIT!\n"
 
27
                   " */\n\n");
 
28
  fprintf(ci->fh, "#include <string.h>\n");
 
29
  fprintf(ci->fh, "#define ORBIT2_STUBS_API\n");
 
30
  fprintf(ci->fh, "#include \"%s.h\"\n\n", ci->base_name);
 
31
 
 
32
  ck_output_skels(tree->tree, rinfo, ci, NULL);
 
33
  ck_output_poastuff(tree->tree, rinfo, ci);
 
34
}
 
35
 
 
36
static void ck_output_skel(IDL_tree tree, OIDL_C_Info *ci);
 
37
static void ck_output_small_skel(IDL_tree tree, OIDL_C_Info *ci, int *idx);
 
38
static void ck_output_except(IDL_tree tree, OIDL_C_Info *ci);
 
39
 
 
40
static void
 
41
ck_output_skels(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci, int *idx)
 
42
{
 
43
  if ( !tree || (tree->declspec & IDLF_DECLSPEC_PIDL) )
 
44
    return;
 
45
 
 
46
 
 
47
  switch(IDL_NODE_TYPE(tree)) {
 
48
  case IDLN_MODULE:
 
49
    ck_output_skels(IDL_MODULE(tree).definition_list, rinfo, ci, idx);
 
50
    break;
 
51
  case IDLN_LIST:
 
52
    {
 
53
      IDL_tree sub;
 
54
      for(sub = tree; sub; sub = IDL_LIST(sub).next) {
 
55
        ck_output_skels(IDL_LIST(sub).data, rinfo, ci, idx);
 
56
      }
 
57
    }
 
58
    break;
 
59
  case IDLN_ATTR_DCL:
 
60
    {
 
61
      OIDL_Attr_Info *ai = tree->data;
 
62
 
 
63
      IDL_tree curitem;
 
64
      
 
65
      for(curitem = IDL_ATTR_DCL(tree).simple_declarations; curitem; curitem = IDL_LIST(curitem).next) {
 
66
        ai = IDL_LIST(curitem).data->data;
 
67
        
 
68
        ck_output_skels(ai->op1, rinfo, ci, idx);
 
69
        if(ai->op2)
 
70
          ck_output_skels(ai->op2, rinfo, ci, idx);
 
71
      }
 
72
    }
 
73
    break;
 
74
  case IDLN_INTERFACE: {
 
75
    int real_idx = 0;  
 
76
    ck_output_skels(IDL_INTERFACE(tree).body, rinfo, ci, &real_idx);
 
77
    break;
 
78
  }
 
79
  case IDLN_OP_DCL:
 
80
    if (rinfo->small_skels)
 
81
      ck_output_small_skel(tree, ci, idx);
 
82
    else
 
83
      ck_output_skel(tree, ci);
 
84
    break;
 
85
  case IDLN_EXCEPT_DCL:
 
86
    if (!rinfo->small_skels)
 
87
      ck_output_except(tree, ci);
 
88
    break;
 
89
  default:
 
90
    break;
 
91
  }
 
92
}
 
93
 
 
94
 
 
95
static void
 
96
cbe_print_var_dcl(FILE *of, IDL_tree tree)
 
97
{
 
98
    IDL_tree            rawts = NULL /* Quiet gcc */, ts;
 
99
    IDL_ParamRole       role = 0 /* Quiet gcc */;
 
100
    gchar               *id = NULL /* Quiet gcc */, *ts_str;
 
101
    gboolean            isSlice;
 
102
    int                 n;
 
103
 
 
104
    if (IDL_NODE_TYPE(tree) == IDLN_OP_DCL) {
 
105
        rawts = IDL_OP_DCL(tree).op_type_spec;
 
106
        role = DATA_RETURN;
 
107
        id = "_ORBIT_retval";
 
108
    } else if (IDL_NODE_TYPE(tree) == IDLN_PARAM_DCL) {
 
109
        rawts = IDL_PARAM_DCL(tree).param_type_spec;
 
110
        role = oidl_attr_to_paramrole(IDL_PARAM_DCL(tree).attr);
 
111
        id = IDL_IDENT(IDL_PARAM_DCL(tree).simple_declarator).str;
 
112
    } else
 
113
      g_error("Unexpected tree node");
 
114
 
 
115
    ts = orbit_cbe_get_typespec( rawts );
 
116
    ts_str = orbit_cbe_get_typespec_str(ts);
 
117
    n = oidl_param_info(ts, role, &isSlice);
 
118
 
 
119
    if ( IDL_NODE_TYPE(ts)==IDLN_TYPE_ARRAY )
 
120
      {
 
121
        if ( isSlice==0 ) {
 
122
          g_assert( n==0 );
 
123
          fprintf(of, "%s %s;\n", ts_str, id);
 
124
        } else {
 
125
          if ( n==1 ) {
 
126
            fprintf(of, "%s_slice *%s;\n", ts_str, id);
 
127
          } else {
 
128
            g_assert( n==2 );
 
129
            fprintf(of, "%s_slice *_ref_%s; %s_slice **%s = &_ref_%s;\n", ts_str, id, ts_str, id, id);
 
130
          }
 
131
        }
 
132
      }
 
133
    else
 
134
      {
 
135
        switch(n)
 
136
          {
 
137
          case 0:
 
138
            fprintf(of, "%s %s;\n", ts_str, id);
 
139
            break;
 
140
          case 1:
 
141
            if ( role == DATA_RETURN)
 
142
              fprintf(of, "%s *%s;\n", ts_str, id);
 
143
            else
 
144
              fprintf(of, "%s _val_%s; %s *%s = &_val_%s;\n", ts_str, id, ts_str, id, id);
 
145
            break;
 
146
          case 2:
 
147
            fprintf(of, "%s *_ref_%s; %s **%s = &_ref_%s;\n", ts_str, id, ts_str, id, id);
 
148
            break; 
 
149
          default:
 
150
            g_assert_not_reached();
 
151
            break;
 
152
          }
 
153
      }
 
154
    g_free(ts_str);
 
155
}
 
156
 
 
157
static void
 
158
cbe_skel_op_dcl_print_call_param(IDL_tree tree, OIDL_C_Info *ci)
 
159
{
 
160
  gchar *id = IDL_IDENT(IDL_PARAM_DCL(tree).simple_declarator).str;
 
161
  IDL_tree ts;
 
162
 
 
163
  ts = orbit_cbe_get_typespec(IDL_PARAM_DCL(tree).param_type_spec);
 
164
  if ( IDL_NODE_TYPE(ts)==IDLN_TYPE_ARRAY 
 
165
       && IDL_PARAM_DCL(tree).attr == IDL_PARAM_IN) {
 
166
    gchar *ts_str = orbit_cbe_get_typespec_str(ts);
 
167
    fprintf(ci->fh, "(const %s_slice*)", ts_str);
 
168
    g_free(ts_str);
 
169
  }
 
170
  fprintf(ci->fh, "%s", id);
 
171
}
 
172
 
 
173
static void cbe_skel_op_params_free(IDL_tree tree, OIDL_C_Info *ci);
 
174
static void cbe_skel_op_dcl_print_call_param(IDL_tree tree, OIDL_C_Info *ci);
 
175
 
 
176
static void
 
177
ck_output_skel(IDL_tree tree, OIDL_C_Info *ci)
 
178
{
 
179
  char *opname, *ifname;
 
180
  IDL_tree intf, curitem;
 
181
  OIDL_Op_Info *oi;
 
182
 
 
183
  intf = IDL_get_parent_node(tree, IDLN_INTERFACE, NULL);
 
184
 
 
185
  opname = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_OP_DCL(tree).ident), "_", 0);
 
186
  ifname = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(intf).ident), "_", 0);
 
187
 
 
188
  fprintf(ci->fh, "void _ORBIT_skel_%s(POA_%s * _ORBIT_servant, GIOPRecvBuffer *_ORBIT_recv_buffer, CORBA_Environment *ev, ",
 
189
          opname, ifname);
 
190
  orbit_cbe_op_write_proto(ci->fh, tree, "_impl_", TRUE);
 
191
  fprintf(ci->fh, ")\n");
 
192
  fprintf(ci->fh, "{\n");
 
193
  fprintf(ci->fh, "register guchar *_ORBIT_buf_end G_GNUC_UNUSED = _ORBIT_recv_buffer->end;\n");
 
194
 
 
195
  oi = tree->data;
 
196
 
 
197
  if(IDL_OP_DCL(tree).op_type_spec)
 
198
    cbe_print_var_dcl(ci->fh, tree);
 
199
  for(curitem = IDL_OP_DCL(tree).parameter_dcls; curitem; curitem = IDL_LIST(curitem).next) {
 
200
    IDL_tree param = IDL_LIST(curitem).data;
 
201
    cbe_print_var_dcl(ci->fh, param);
 
202
  }
 
203
 
 
204
  if(IDL_OP_DCL(tree).context_expr)
 
205
    fprintf(ci->fh, "struct CORBA_Context_type _ctx;\n");
 
206
 
 
207
  if(oi->in_skels) {
 
208
    fprintf(ci->fh, "{ /* demarshalling */\n");
 
209
    fprintf(ci->fh, "register guchar *_ORBIT_curptr G_GNUC_UNUSED;\n");
 
210
    
 
211
    orbit_cbe_alloc_tmpvars(oi->in_skels, ci);
 
212
    c_demarshalling_generate(oi->in_skels, ci, TRUE, FALSE);
 
213
    
 
214
    fprintf(ci->fh, "}\n");
 
215
  }
 
216
 
 
217
  if(IDL_OP_DCL(tree).op_type_spec)
 
218
    fprintf(ci->fh, "_ORBIT_retval = ");
 
219
  fprintf(ci->fh, "_impl_%s(_ORBIT_servant, ", IDL_IDENT(IDL_OP_DCL(tree).ident).str);
 
220
  for(curitem = IDL_OP_DCL(tree).parameter_dcls; curitem; curitem = IDL_LIST(curitem).next) {
 
221
    cbe_skel_op_dcl_print_call_param(IDL_LIST(curitem).data, ci);
 
222
    fprintf(ci->fh, ", ");
 
223
  }
 
224
  if(IDL_OP_DCL(tree).context_expr)
 
225
    fprintf(ci->fh, "&_ctx, ");
 
226
  fprintf(ci->fh, "ev);\n");
 
227
 
 
228
  if(!IDL_OP_DCL(tree).f_oneway) {
 
229
    fprintf(ci->fh, "{ /* marshalling */\n");
 
230
    fprintf(ci->fh, "register GIOPSendBuffer *_ORBIT_send_buffer;\n");
 
231
 
 
232
    fprintf(ci->fh, "_ORBIT_send_buffer = giop_send_buffer_use_reply(_ORBIT_recv_buffer->connection->giop_version,"
 
233
            "giop_recv_buffer_get_request_id(_ORBIT_recv_buffer), ev->_major);\n");
 
234
 
 
235
    fprintf(ci->fh, "if(_ORBIT_send_buffer) {\n");
 
236
    fprintf(ci->fh, "if (ev->_major == CORBA_NO_EXCEPTION) {\n");
 
237
    orbit_cbe_alloc_tmpvars(oi->out_skels, ci);
 
238
 
 
239
    c_marshalling_generate(oi->out_skels, ci, TRUE);
 
240
 
 
241
    if(IDL_OP_DCL(tree).raises_expr) {
 
242
      IDL_tree curitem;
 
243
      
 
244
      fprintf(ci->fh, "} else if (ev->_major == CORBA_USER_EXCEPTION) { \n");
 
245
      fprintf(ci->fh, "static const ORBit_exception_marshal_info _ORBIT_user_exceptions[] = { ");
 
246
      for(curitem = IDL_OP_DCL(tree).raises_expr; curitem;
 
247
          curitem = IDL_LIST(curitem).next) {
 
248
        char *id;
 
249
        IDL_tree curnode = IDL_LIST(curitem).data;
 
250
        
 
251
        id = orbit_cbe_get_typespec_str(curnode);
 
252
        fprintf(ci->fh, "{(const CORBA_TypeCode)&TC_%s_struct, (gpointer)_ORBIT_%s_marshal},",
 
253
                id, id);
 
254
        g_free(id);
 
255
      }
 
256
 
 
257
      fprintf(ci->fh, "{CORBA_OBJECT_NIL, NULL}};\n");
 
258
      fprintf(ci->fh, "ORBit_send_user_exception(_ORBIT_send_buffer, ev, _ORBIT_user_exceptions);\n");
 
259
    }
 
260
 
 
261
    fprintf(ci->fh, "} else\n");
 
262
    fprintf(ci->fh, "ORBit_send_system_exception(_ORBIT_send_buffer, ev);\n");
 
263
 
 
264
    fprintf(ci->fh, "giop_send_buffer_write(_ORBIT_send_buffer, _ORBIT_recv_buffer->connection);\n");
 
265
    fprintf(ci->fh, "giop_send_buffer_unuse(_ORBIT_send_buffer);\n");
 
266
    fprintf(ci->fh, "}\n");
 
267
 
 
268
    fprintf(ci->fh, "}\n");
 
269
  }
 
270
 
 
271
  cbe_skel_op_params_free(tree, ci);
 
272
 
 
273
  fprintf(ci->fh, "}\n");
 
274
 
 
275
  g_free(opname);
 
276
  g_free(ifname);
 
277
}
 
278
 
 
279
static void
 
280
ck_output_small_skel(IDL_tree tree, OIDL_C_Info *ci, int *idx)
 
281
{
 
282
  char *opname, *ifname;
 
283
  IDL_tree intf;
 
284
  gboolean has_args, has_retval;
 
285
 
 
286
  g_return_if_fail (idx != NULL);
 
287
 
 
288
  intf = IDL_get_parent_node(tree, IDLN_INTERFACE, NULL);
 
289
  has_args   = IDL_OP_DCL(tree).parameter_dcls != NULL;
 
290
  has_retval = IDL_OP_DCL(tree).op_type_spec != NULL;
 
291
 
 
292
  opname = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_OP_DCL(tree).ident), "_", 0);
 
293
  ifname = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(intf).ident), "_", 0);
 
294
 
 
295
  fprintf(ci->fh, "void _ORBIT_skel_small_%s("
 
296
          "POA_%s             *_o_servant, "
 
297
          "gpointer            _o_retval,"
 
298
          "gpointer           *_o_args,"
 
299
          "CORBA_Context       _o_ctx,"
 
300
          "CORBA_Environment  *_o_ev,\n", opname, ifname);
 
301
  orbit_cbe_op_write_proto(ci->fh, tree, "_impl_", TRUE);
 
302
  fprintf(ci->fh, ")\n");
 
303
  fprintf(ci->fh, "{\n");
 
304
 
 
305
  if(has_retval) {
 
306
    fprintf(ci->fh, "*(");
 
307
    orbit_cbe_write_param_typespec(ci->fh, tree);
 
308
    fprintf(ci->fh, " *)_o_retval = ");
 
309
  }
 
310
 
 
311
  fprintf(ci->fh, "_impl_%s(_o_servant, ", IDL_IDENT(IDL_OP_DCL(tree).ident).str);
 
312
  
 
313
  cbe_small_unflatten_args (tree, ci->fh, "_o_args");
 
314
 
 
315
  if(IDL_OP_DCL(tree).context_expr)
 
316
    fprintf(ci->fh, "_o_ctx, ");
 
317
 
 
318
  fprintf(ci->fh, "_o_ev);\n");
 
319
 
 
320
  fprintf (ci->fh, "}\n");
 
321
 
 
322
  g_free(opname);
 
323
  g_free(ifname);
 
324
 
 
325
  (*idx)++;
 
326
}
 
327
 
 
328
static void
 
329
ck_output_except(IDL_tree tree, OIDL_C_Info *ci)
 
330
{
 
331
  char *id;
 
332
  OIDL_Except_Info *ei;
 
333
 
 
334
  ei = tree->data;
 
335
  g_assert(ei);
 
336
 
 
337
  id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_EXCEPT_DCL(tree).ident), "_", 0);
 
338
 
 
339
  fprintf(ci->fh, "void\n_ORBIT_%s_marshal(GIOPSendBuffer *_ORBIT_send_buffer, CORBA_Environment *ev)\n", id);
 
340
  fprintf(ci->fh, "{\n");
 
341
  if(IDL_EXCEPT_DCL(tree).members) {
 
342
    orbit_cbe_alloc_tmpvars(ei->demarshal, ci);
 
343
    fprintf(ci->fh, "%s *_ORBIT_exdata = ev->_any._value;\n", id);
 
344
    c_marshalling_generate(ei->marshal, ci, FALSE);
 
345
  }
 
346
 
 
347
  fprintf(ci->fh, "}\n");
 
348
 
 
349
  g_free(id);
 
350
}
 
351
 
 
352
/** 
 
353
   NOTE: we no longer use {free_internal}. Instead, any data we
 
354
        do not want to free is tagged as such at run-time 
 
355
        at the time we reference it.
 
356
        See ORBit/docs/orbit-mem2.txt.
 
357
**/
 
358
static void
 
359
cbe_skel_param_subfree(IDL_tree tree, OIDL_C_Info *ci)
 
360
{
 
361
  char *id, *varname;
 
362
 
 
363
  if(IDL_NODE_TYPE(tree) != IDLN_PARAM_DCL) {
 
364
    id = orbit_cbe_get_typespec_str(tree);
 
365
    varname = "_ORBIT_retval";
 
366
  } else {
 
367
    id = orbit_cbe_get_typespec_str(IDL_PARAM_DCL(tree).param_type_spec);
 
368
    varname = IDL_IDENT(IDL_PARAM_DCL(tree).simple_declarator).str;
 
369
  }
 
370
  fprintf(ci->fh, "%s__freekids(%s, NULL);\n", id, varname);
 
371
  g_free(id);
 
372
}
 
373
 
 
374
void
 
375
cbe_op_retval_free(IDL_tree tree, OIDL_C_Info *ci)
 
376
{
 
377
  IDL_tree ts;
 
378
 
 
379
  ts = orbit_cbe_get_typespec(tree);
 
380
 
 
381
  switch(IDL_NODE_TYPE(ts)) {
 
382
  case IDLN_TYPE_UNION:
 
383
  case IDLN_TYPE_STRUCT:
 
384
    if(orbit_cbe_type_is_fixed_length(ts))
 
385
      return;
 
386
  case IDLN_TYPE_SEQUENCE:
 
387
  case IDLN_TYPE_STRING:
 
388
  case IDLN_TYPE_ARRAY:
 
389
  case IDLN_TYPE_ANY:
 
390
    break;
 
391
  case IDLN_TYPE_OBJECT:
 
392
  case IDLN_INTERFACE:
 
393
  case IDLN_FORWARD_DCL:
 
394
    fprintf(ci->fh, "CORBA_Object_release(" ORBIT_RETVAL_VAR_NAME ", ev);\n");
 
395
  default:
 
396
    return;
 
397
  }
 
398
 
 
399
  fprintf(ci->fh, "CORBA_free(" ORBIT_RETVAL_VAR_NAME ");\n");
 
400
}
 
401
 
 
402
static gboolean
 
403
cbe_skel_op_param_has_sequence(IDL_tree ts)
 
404
{
 
405
  gboolean has_seq = FALSE, subhas;
 
406
  IDL_tree curitem, sn;
 
407
 
 
408
  ts = orbit_cbe_get_typespec(ts);
 
409
 
 
410
  switch(IDL_NODE_TYPE(ts)) {
 
411
  case IDLN_TYPE_UNION:
 
412
    for(curitem = IDL_TYPE_UNION(ts).switch_body; curitem;
 
413
        curitem = IDL_LIST(curitem).next) {
 
414
      sn = IDL_MEMBER(IDL_CASE_STMT(IDL_LIST(curitem).data).element_spec).type_spec;
 
415
      subhas = cbe_skel_op_param_has_sequence(sn);
 
416
      has_seq = has_seq || subhas;
 
417
    }
 
418
    return has_seq;
 
419
    break;
 
420
  case IDLN_TYPE_STRUCT:
 
421
    for(curitem = IDL_TYPE_STRUCT(ts).member_list; curitem;
 
422
        curitem = IDL_LIST(curitem).next) {
 
423
      sn = IDL_MEMBER(IDL_LIST(curitem).data).type_spec;
 
424
      subhas = cbe_skel_op_param_has_sequence(sn);
 
425
      has_seq = has_seq || subhas;
 
426
    }
 
427
    return has_seq;
 
428
    break;
 
429
  case IDLN_TYPE_ARRAY:
 
430
    return cbe_skel_op_param_has_sequence(IDL_TYPE_DCL(IDL_get_parent_node(ts, IDLN_TYPE_DCL, NULL)).type_spec);
 
431
    break;
 
432
  case IDLN_TYPE_SEQUENCE:
 
433
    return TRUE;
 
434
  default:
 
435
    return FALSE;
 
436
  }
 
437
}
 
438
 
 
439
void
 
440
cbe_op_param_free(IDL_tree tree, OIDL_C_Info *ci, gboolean is_skels)
 
441
{
 
442
  IDL_tree ts;
 
443
 
 
444
  ts = orbit_cbe_get_typespec(tree);
 
445
  if ( orbit_cbe_type_is_fixed_length(ts) )
 
446
        return;
 
447
 
 
448
  switch(IDL_PARAM_DCL(tree).attr) {
 
449
  case IDL_PARAM_IN:
 
450
    if(is_skels)
 
451
      switch(IDL_NODE_TYPE(ts)) {
 
452
      case IDLN_TYPE_UNION:
 
453
      case IDLN_TYPE_STRUCT:
 
454
      case IDLN_TYPE_ARRAY:
 
455
      case IDLN_TYPE_ANY:
 
456
      case IDLN_TYPE_SEQUENCE:
 
457
        /* ANY and SEQUENCE always have allocated sub-memory that must
 
458
         * be freed, regardless of the underlying types */
 
459
        cbe_skel_param_subfree(tree, ci);
 
460
        break;
 
461
      case IDLN_TYPE_OBJECT:
 
462
      case IDLN_INTERFACE:
 
463
      case IDLN_FORWARD_DCL:
 
464
        fprintf(ci->fh, "CORBA_Object_release(%s, ev);\n",
 
465
                IDL_IDENT(IDL_PARAM_DCL(tree).simple_declarator).str);
 
466
        break;
 
467
      default:
 
468
        break;
 
469
      }
 
470
    break;
 
471
  case IDL_PARAM_OUT:
 
472
    switch(IDL_NODE_TYPE(ts)) {
 
473
    case IDLN_TYPE_OBJECT:
 
474
    case IDLN_INTERFACE:
 
475
      fprintf(ci->fh, "CORBA_Object_release(*%s, ev);\n",
 
476
              IDL_IDENT(IDL_PARAM_DCL(tree).simple_declarator).str);
 
477
      break;
 
478
    default:
 
479
      fprintf(ci->fh, "CORBA_free(*%s);\n",
 
480
              IDL_IDENT(IDL_PARAM_DCL(tree).simple_declarator).str);
 
481
    }
 
482
    break;
 
483
  case IDL_PARAM_INOUT:
 
484
    switch(IDL_NODE_TYPE(ts)) {
 
485
    case IDLN_TYPE_OBJECT:
 
486
    case IDLN_INTERFACE:
 
487
      fprintf(ci->fh, "CORBA_Object_release(*%s, ev);\n",
 
488
              IDL_IDENT(IDL_PARAM_DCL(tree).simple_declarator).str);
 
489
      break;
 
490
    default:
 
491
      cbe_skel_param_subfree(tree, ci);
 
492
      break;
 
493
    }
 
494
    break;
 
495
  }
 
496
 
 
497
}
 
498
 
 
499
static void
 
500
cbe_skel_op_params_free(IDL_tree tree, OIDL_C_Info *ci)
 
501
{
 
502
  IDL_tree curitem;
 
503
 
 
504
  /* We have to free the params from last to first */
 
505
  fprintf(ci->fh, "if(ev->_major == CORBA_NO_EXCEPTION)\n{\n");
 
506
  for(curitem = IDL_list_nth(IDL_OP_DCL(tree).parameter_dcls, IDL_list_length(IDL_OP_DCL(tree).parameter_dcls) - 1);
 
507
      curitem; curitem = IDL_LIST(curitem).prev)
 
508
    {
 
509
      IDL_tree param;
 
510
 
 
511
      param = IDL_LIST(curitem).data;
 
512
      if(IDL_PARAM_DCL(param).attr == IDL_PARAM_OUT)
 
513
        cbe_op_param_free(param, ci, TRUE);
 
514
    }
 
515
 
 
516
  if(IDL_OP_DCL(tree).op_type_spec)
 
517
    cbe_op_retval_free(IDL_OP_DCL(tree).op_type_spec, ci);
 
518
  fprintf(ci->fh, "}\n");
 
519
 
 
520
  /* Concious decision made to not send back an exception to report the problem - if they are sending us total junk,
 
521
     then it is probably not even a compliant ORB that needs to know. The real reason is that it would complicate the
 
522
     code a lot, just to handle this corner case */
 
523
  if(IDL_OP_DCL(tree).context_expr)
 
524
    fprintf(ci->fh, "_context_demarshal_error: ORBit_Context_server_free(&_ctx);\n");
 
525
  for(curitem = IDL_list_nth(IDL_OP_DCL(tree).parameter_dcls, IDL_list_length(IDL_OP_DCL(tree).parameter_dcls) - 1);
 
526
      curitem; curitem = IDL_LIST(curitem).prev)
 
527
    {
 
528
      IDL_tree param;
 
529
 
 
530
      param = IDL_LIST(curitem).data;
 
531
      if(IDL_PARAM_DCL(param).attr != IDL_PARAM_OUT)
 
532
        {
 
533
          fprintf(ci->fh, "%s_demarshal_error:\n", IDL_IDENT(IDL_PARAM_DCL(param).simple_declarator).str);
 
534
          cbe_op_param_free(param, ci, TRUE);
 
535
        }
 
536
    }
 
537
  if(IDL_OP_DCL(tree).parameter_dcls)
 
538
    fprintf(ci->fh, "_ORBIT_demarshal_error:\n");
 
539
}
 
540
 
 
541
 
 
542
/*****************************************/
 
543
static void cbe_skel_do_interface(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
 
544
 
 
545
static void
 
546
ck_output_poastuff(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
 
547
{
 
548
  if( !tree || (tree->declspec & IDLF_DECLSPEC_PIDL)!=0 ) 
 
549
    return;
 
550
 
 
551
  switch(IDL_NODE_TYPE(tree)) {
 
552
  case IDLN_MODULE:
 
553
    ck_output_poastuff(IDL_MODULE(tree).definition_list, rinfo, ci);
 
554
    break;
 
555
  case IDLN_LIST:
 
556
    {
 
557
      IDL_tree sub;
 
558
      for(sub = tree; sub; sub = IDL_LIST(sub).next) {
 
559
        ck_output_poastuff(IDL_LIST(sub).data, rinfo, ci);
 
560
      }
 
561
    }
 
562
    break;
 
563
  case IDLN_INTERFACE:
 
564
    cbe_skel_do_interface(tree, rinfo, ci);
 
565
    break;
 
566
  default:
 
567
    break;
 
568
  }
 
569
}
 
570
 
 
571
/* Blatantly copied from the old IDL compiler. (A few fixes to the
 
572
   get_skel generation stuff to do proper checking of the opname...) */
 
573
 
 
574
#if 0
 
575
static void
 
576
cbe_skel_print_skelptr(FILE *of, IDL_tree tree)
 
577
{
 
578
  char *id = NULL;
 
579
  IDL_tree curitem;
 
580
 
 
581
  switch(IDL_NODE_TYPE(tree)) {
 
582
  case IDLN_OP_DCL:
 
583
    id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_OP_DCL(tree).ident),
 
584
                                 "_", 0);
 
585
    fprintf(of, "  skel_%s,\n", id);
 
586
    break;
 
587
  case IDLN_ATTR_DCL:
 
588
    id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(IDL_get_parent_node(tree, IDLN_INTERFACE, NULL)).ident),
 
589
                                 "_", 0);
 
590
    for(curitem = IDL_ATTR_DCL(tree).simple_declarations;
 
591
        curitem; curitem = IDL_LIST(curitem).data) {
 
592
      fprintf(of, "  skel_%s__get_%s,\n", id,
 
593
              IDL_IDENT(IDL_LIST(curitem).data).str);
 
594
      if(!IDL_ATTR_DCL(tree).f_readonly)
 
595
        fprintf(of, "  skel_%s__set_%s,\n", id,
 
596
                IDL_IDENT(IDL_LIST(curitem).data).str);
 
597
    }
 
598
    break;
 
599
  default:
 
600
    break;
 
601
  }
 
602
  g_free(id);
 
603
}
 
604
#endif
 
605
 
 
606
static gint
 
607
cbe_skel_compare_op_dcls(CBESkelOpInfo *op1, CBESkelOpInfo *op2)
 
608
{
 
609
  return strcmp(op1->opname, op2->opname);
 
610
}
 
611
 
 
612
static void
 
613
cbe_skel_free_op_info(CBESkelOpInfo *op)
 
614
{
 
615
  g_free(op->opname);
 
616
  g_free(op->iface_id);
 
617
  g_free(op);
 
618
}
 
619
 
 
620
static void
 
621
cbe_skel_interface_add_relayer(IDL_tree intf, CBESkelInterfaceTraverseInfo *iti)
 
622
{
 
623
  CBESkelOpInfo *newopi;
 
624
  IDL_tree curitem, curdcl, curattr, curattrdcl;
 
625
  char *iface_id;
 
626
  int   idx = 0;
 
627
 
 
628
  iface_id =
 
629
    IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(intf).ident),
 
630
                            "_", 0);
 
631
 
 
632
  for(curitem = IDL_INTERFACE(intf).body; curitem;
 
633
      curitem = IDL_LIST(curitem).next) {
 
634
    curdcl = IDL_LIST(curitem).data;
 
635
 
 
636
    switch(IDL_NODE_TYPE(curdcl)) {
 
637
    case IDLN_OP_DCL:
 
638
      newopi = g_new0(CBESkelOpInfo, 1);
 
639
      newopi->iface_id = g_strdup(iface_id);
 
640
      newopi->opname = g_strdup(IDL_IDENT(IDL_OP_DCL(curdcl).ident).str);
 
641
      newopi->idx = idx++;
 
642
      iti->oplist = g_slist_insert_sorted(iti->oplist, newopi,
 
643
                                          (GCompareFunc)cbe_skel_compare_op_dcls);
 
644
      break;
 
645
    case IDLN_ATTR_DCL:
 
646
      for(curattr = IDL_ATTR_DCL(curdcl).simple_declarations;
 
647
          curattr; curattr = IDL_LIST(curattr).next) {
 
648
        curattrdcl = IDL_LIST(curattr).data;
 
649
 
 
650
        newopi = g_new0(CBESkelOpInfo, 1);
 
651
        newopi->iface_id = g_strdup(iface_id);
 
652
        newopi->opname = g_strdup_printf("_get_%s", IDL_IDENT(curattrdcl).str);
 
653
        newopi->idx = idx++;
 
654
        iti->oplist = g_slist_insert_sorted(iti->oplist, newopi,
 
655
                                            (GCompareFunc)cbe_skel_compare_op_dcls);
 
656
        if(!IDL_ATTR_DCL(curdcl).f_readonly) {
 
657
          newopi = g_new0(CBESkelOpInfo, 1);
 
658
          newopi->iface_id = g_strdup(iface_id);
 
659
          newopi->opname = g_strdup_printf("_set_%s", IDL_IDENT(curattrdcl).str);
 
660
          newopi->idx = idx++;
 
661
          iti->oplist = g_slist_insert_sorted(iti->oplist, newopi,
 
662
                                              (GCompareFunc)cbe_skel_compare_op_dcls);
 
663
        }
 
664
      }
 
665
      break;
 
666
    default:
 
667
      break;
 
668
    }
 
669
  }
 
670
 
 
671
  g_free(iface_id);
 
672
}
 
673
 
 
674
static void
 
675
cbe_skel_interface_print_relayers(const CBESkelInterfaceTraverseInfo *iti)
 
676
{
 
677
  CBESkelInterfaceTraverseInfo subiti = *iti;
 
678
  GSList *curnode;
 
679
  CBESkelOpInfo *opi;
 
680
  char curchar;
 
681
 
 
682
  curnode = iti->oplist;
 
683
  subiti.curlevel = iti->curlevel+1;
 
684
  fprintf(iti->ci->fh, "switch(opname[%d]) {\n", iti->curlevel);
 
685
  while(curnode) {
 
686
    opi = (CBESkelOpInfo *)curnode->data;
 
687
    if(iti->curlevel > strlen(opi->opname)) {
 
688
      curnode = g_slist_next(curnode);
 
689
      continue;
 
690
    }
 
691
    curchar = opi->opname[iti->curlevel];
 
692
    if(curchar)
 
693
      fprintf(iti->ci->fh, "case '%c':\n", curchar);
 
694
    else
 
695
      fprintf(iti->ci->fh, "case '\\0':\n");
 
696
    subiti.oplist = NULL;
 
697
    while(curnode && ((CBESkelOpInfo *)curnode->data)->opname[iti->curlevel]
 
698
          == curchar) {
 
699
      subiti.oplist = g_slist_append(subiti.oplist, curnode->data);
 
700
      curnode = g_slist_next(curnode);
 
701
    }
 
702
 
 
703
    if(g_slist_length(subiti.oplist) > 1) {
 
704
      if(curchar)
 
705
        cbe_skel_interface_print_relayers(&subiti);
 
706
      else
 
707
        g_error("two ops with same name!!!!");
 
708
    } else {
 
709
      if(strlen(opi->opname + iti->curlevel))
 
710
        fprintf(iti->ci->fh, "if(strcmp((opname + %d), \"%s\")) break;\n",
 
711
                iti->curlevel + 1, opi->opname + iti->curlevel+1);
 
712
      fprintf(iti->ci->fh, "*impl = (gpointer)servant->vepv->%s_epv->%s;\n",
 
713
              opi->iface_id, opi->opname);
 
714
      if (iti->small) {
 
715
        fprintf(iti->ci->fh, "*m_data = (gpointer)&%s__iinterface.methods._buffer [%d];\n",
 
716
                opi->iface_id, opi->idx);
 
717
        fprintf(iti->ci->fh, "return (ORBitSmallSkeleton)_ORBIT_skel_small_%s_%s;\n",
 
718
                opi->iface_id, opi->opname);
 
719
      } else
 
720
        fprintf(iti->ci->fh, "return (ORBitSkeleton)_ORBIT_skel_%s_%s;\n",
 
721
                opi->iface_id, opi->opname);
 
722
    }
 
723
    fprintf(iti->ci->fh, "break;\n");
 
724
    g_slist_free(subiti.oplist);
 
725
  }
 
726
  fprintf(iti->ci->fh, "default: break; \n}\n");
 
727
}
 
728
 
 
729
static void
 
730
cbe_skel_interface_print_relayer(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
 
731
{
 
732
  char *id;
 
733
  CBESkelInterfaceTraverseInfo iti;
 
734
 
 
735
  id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(tree).ident), "_", 0);
 
736
  if (rinfo->small_skels) {
 
737
    fprintf(ci->fh, "static ORBitSmallSkeleton get_skel_small_%s(POA_%s *servant,\nconst char *opname,"
 
738
            "gpointer *m_data, gpointer *impl)\n{\n", id, id);
 
739
  } else {
 
740
    fprintf(ci->fh, "static ORBitSkeleton get_skel_%s(POA_%s *servant,\nGIOPRecvBuffer *_ORBIT_recv_buffer,\ngpointer *impl)\n{\n", id, id);
 
741
    fprintf(ci->fh, "gchar *opname = giop_recv_buffer_get_opname(_ORBIT_recv_buffer);\n\n");
 
742
  }
 
743
 
 
744
  iti.ci = ci;
 
745
  iti.oplist = NULL;
 
746
  iti.curlevel = 0;
 
747
  iti.small = rinfo->small_skels;
 
748
 
 
749
  IDL_tree_traverse_parents(tree,
 
750
                            (GFunc)cbe_skel_interface_add_relayer, &iti);
 
751
 
 
752
  cbe_skel_interface_print_relayers(&iti);
 
753
 
 
754
  g_slist_foreach(iti.oplist, (GFunc)cbe_skel_free_op_info, NULL);
 
755
  g_slist_free(iti.oplist);
 
756
 
 
757
  fprintf(ci->fh, "return NULL;\n");
 
758
  fprintf(ci->fh, "}\n\n");
 
759
 
 
760
  g_free(id);
 
761
}
 
762
 
 
763
#if 0
 
764
static void
 
765
cbe_skel_interface_print_initializer(IDL_tree node,
 
766
                                     OIDL_C_Info *ci)
 
767
{
 
768
  char *id;
 
769
 
 
770
  g_assert(IDL_NODE_TYPE(node) == IDLN_INTERFACE);
 
771
 
 
772
  /* Print the operations defined for this interface, but in current's
 
773
     namespace */
 
774
 
 
775
  id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(node).ident),
 
776
                               "_", 0);
 
777
 
 
778
  fprintf(ci->fh, "obj->vepv[%s__classid] = servant->vepv->%s_epv;\n", id, id);
 
779
 
 
780
  g_free(id);
 
781
}
 
782
#endif
 
783
 
 
784
static void
 
785
cbe_skel_interface_print_vepvmap_line(IDL_tree node, OIDL_C_Info *ci)
 
786
{
 
787
  char *id;
 
788
  id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(node).ident),
 
789
                               "_", 0);
 
790
  fprintf(ci->fh, "class_info.vepvmap[%s__classid]"
 
791
    " = (((char*)&(fakevepv->%s_epv)) - ((char*)(fakevepv)))/sizeof(GFunc);\n",
 
792
    id, id);
 
793
  g_free(id);
 
794
}
 
795
 
 
796
static void
 
797
cbe_skel_do_interface(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
 
798
{
 
799
  char *id, *id2;
 
800
  IDL_tree curitem, pnt;
 
801
  int i;
 
802
 
 
803
  /* PIDL methods dont have normal skel functions. */
 
804
  for ( pnt=tree; pnt; pnt=IDL_NODE_UP(pnt) ) {
 
805
      if ( pnt->declspec & IDLF_DECLSPEC_PIDL )
 
806
        return;
 
807
  }
 
808
 
 
809
  id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(tree).ident), "_", 0);
 
810
 
 
811
  cbe_skel_interface_print_relayer(tree, rinfo, ci);
 
812
 
 
813
  fprintf(ci->fh,
 
814
          "void POA_%s__init(PortableServer_Servant servant,\nCORBA_Environment *env)\n",
 
815
          id);
 
816
  fprintf(ci->fh, "{\n");
 
817
  fprintf(ci->fh,"  static PortableServer_ClassInfo class_info = {");
 
818
 
 
819
  if (rinfo->small_skels)
 
820
          fprintf(ci->fh, "NULL, (ORBit_small_impl_finder)&get_skel_small_%s, ", id);
 
821
  else
 
822
          fprintf(ci->fh, "(ORBit_impl_finder)&get_skel_%s, NULL, ", id);
 
823
 
 
824
  fprintf(ci->fh,"\"%s\", &%s__classid, NULL, &%s__iinterface};\n",
 
825
          IDL_IDENT(IDL_INTERFACE(tree).ident).repo_id, id, id);
 
826
  fprintf(ci->fh, "   POA_%s__vepv *fakevepv = NULL;", id);
 
827
 
 
828
  {
 
829
        const char *finref = 
 
830
                "((PortableServer_ServantBase*)servant)->vepv[0]->finalize";
 
831
        fprintf(ci->fh, "if ( %s == 0 ) { ", finref);
 
832
        fprintf(ci->fh, "%s = POA_%s__fini;\n", finref, id);
 
833
        fprintf(ci->fh, "}\n");
 
834
  }
 
835
  fprintf(ci->fh,
 
836
          "  PortableServer_ServantBase__init(((PortableServer_ServantBase *)servant), env);\n");
 
837
 
 
838
  for(curitem = IDL_INTERFACE(tree).inheritance_spec; curitem;
 
839
      curitem = IDL_LIST(curitem).next) {
 
840
    id2 = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_LIST(curitem).data),
 
841
                                  "_", 0);
 
842
    fprintf(ci->fh, "  POA_%s__init(servant, env);\n", id2);
 
843
    g_free(id2);
 
844
  }
 
845
  /* registering after other __inits() makes the classids increment nicely. */
 
846
  fprintf(ci->fh, "  ORBit_classinfo_register(&class_info);\n");
 
847
  /* Set classinfo after other __inits() for most derived interface. */
 
848
  fprintf(ci->fh, "  ORBIT_SERVANT_SET_CLASSINFO(servant,&class_info);\n");
 
849
  fprintf(ci->fh, "\nif (!class_info.vepvmap) {\n");
 
850
  fprintf(ci->fh, "   class_info.vepvmap = g_new0 (ORBit_VepvIdx, %s__classid + 1);\n", id);
 
851
  IDL_tree_traverse_parents(tree, (GFunc) cbe_skel_interface_print_vepvmap_line, ci);
 
852
  fprintf(ci->fh, "}\n");
 
853
 
 
854
  fprintf(ci->fh, "}\n\n");
 
855
 
 
856
  fprintf(ci->fh,
 
857
          "void POA_%s__fini(PortableServer_Servant servant,\nCORBA_Environment *env)\n",
 
858
          id);
 
859
  fprintf(ci->fh, "{\n");
 
860
  if(IDL_INTERFACE(tree).inheritance_spec)
 
861
    {
 
862
      for(i = IDL_list_length(IDL_INTERFACE(tree).inheritance_spec) - 1;
 
863
          i >= 0; i--) {
 
864
        curitem = IDL_list_nth(IDL_INTERFACE(tree).inheritance_spec, i);
 
865
        id2 = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_LIST(curitem).data),
 
866
                                      "_", 0);
 
867
        /* XXX fixme - this is going to call ServantBase__fini multiple times */
 
868
        fprintf(ci->fh, "  POA_%s__fini(servant, env);\n",
 
869
                id2);
 
870
        g_free(id2);
 
871
      }
 
872
    }
 
873
  fprintf(ci->fh, "  PortableServer_ServantBase__fini(servant, env);\n");
 
874
  fprintf(ci->fh, "}\n\n");
 
875
 
 
876
  g_free(id);
 
877
}