1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 1998-2020. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20%%
21
22-module(icunion).
23
24-import(ic_codegen, [emit/2, emit/3, emit/4, emit_c_enc_rpt/4, emit_c_dec_rpt/4]).
25-import(ic_cbe, [mk_c_type/3, mk_c_type/4]).
26
27-include("icforms.hrl").
28-include("ic.hrl").
29
30%%-----------------------------------------------------------------
31%% External exports
32%%-----------------------------------------------------------------
33-export([union_gen/4]).
34
35%%-----------------------------------------------------------------
36%% Internal exports
37%%-----------------------------------------------------------------
38-export([]).
39
40union_gen(G, N, X, c) when is_record(X, union) ->
41    emit_c_union(G, N, X);
42union_gen(_G, _N, _X, _L) ->
43    ok.
44
45
46%% Emits the union
47emit_c_union(G, N, X) ->
48    %%io:format("Rec = ~p\n",[X]),
49    case ic_genobj:is_hrlfile_open(G) of
50	true ->
51
52	    %% Sort Union Default = put it last in case list
53	    NewX = #union{ id = X#union.id,
54			   type = X#union.type,
55			   body = mvDefaultToTail(X#union.body),
56			   tk = X#union.tk },
57
58	    UnionScope = [ic_forms:get_id2(NewX) | N],
59
60	    case ic_pragma:is_local(G,UnionScope) of
61
62		true ->
63
64		    HFd = ic_genobj:hrlfiled(G),
65		    emit_c_union_values(G, N, NewX, HFd),
66		    UnionName = ic_util:to_undersc(UnionScope),
67
68		    emit(HFd, "\n#ifndef __~s__\n",[ictype:to_uppercase(UnionName)]),
69		    emit(HFd, "#define __~s__\n",[ictype:to_uppercase(UnionName)]),
70		    ic_codegen:mcomment_light(HFd,
71					      [io_lib:format("Union definition: ~s",
72							     [UnionName])],
73					      c),
74		    emit(HFd, "typedef struct {\n"),
75		    emit(HFd, "  ~s _d;\n", [get_c_union_discriminator(G, N, NewX)]),
76		    emit(HFd, "  union {\n"),
77		    emit_c_union_values_decl(G, N, NewX, HFd),
78		    emit(HFd, "  } _u;\n"),
79		    emit(HFd, "} ~s;\n\n", [UnionName]),
80
81		    emit(HFd, "int ~s~s(CORBA_Environment *oe_env, int*, int*);\n",
82			 [ic_util:mk_oe_name(G, "sizecalc_"), UnionName]),
83		    emit(HFd, "int ~s~s(CORBA_Environment *oe_env, ~s*);\n",
84			 [ic_util:mk_oe_name(G, "encode_"), UnionName, UnionName]),
85		    emit(HFd, "int ~s~s(CORBA_Environment *oe_env, char *, int*, ~s*);\n",
86			 [ic_util:mk_oe_name(G, "decode_"), UnionName, UnionName]),
87		    emit(HFd, "\n#endif\n\n"),
88		    create_c_union_file(G, N, NewX, UnionName);
89
90		false -> %% Do not generate included types att all.
91		    ok
92	    end;
93	false ->
94	    ok
95    end.
96
97
98
99%% Loops over union members and creates members typedefs
100emit_c_union_values(G, N, X, Fd) ->
101    emit_c_union_values_loop(G, N, X, Fd, X#union.body).
102
103emit_c_union_values_loop(G, N, X, Fd, [CU]) ->
104    case CU of
105	{case_dcl,_,Id,Type} ->
106	    case Id of
107		{array, _AID, _SZ} -> % Check for arrays
108		    mk_array_file(G,N,X,Id,Type,Fd);
109		_ ->              % Elementary types or seq/struct
110		    ok
111	    end;
112	_ ->
113	    error
114    end;
115emit_c_union_values_loop(G, N, X, Fd, [CU |CUs]) ->
116    case CU of
117	{case_dcl,_,Id,Type} ->
118	    case Id of
119		{array, _AID, _SZ} -> % Check for arrays
120		    mk_array_file(G,N,X,Id,Type,Fd);
121		_ ->              % Elementary types or seq/struct
122		    emit_c_union_values_loop(G, N, X, Fd, CUs)
123	    end;
124	_ ->
125	    error
126    end.
127
128
129%% Loops over union members and declares members inside union structure
130emit_c_union_values_decl(G, N, X, Fd) ->
131    emit_c_union_values_decl_loop(G, N, X, Fd, X#union.body).
132
133emit_c_union_values_decl_loop(G, N, X, Fd, [CU]) ->
134    case CU of
135	{case_dcl,_,Id,Type} ->
136	    case Id of
137		{array, _AID, _SZ} -> % Check for arrays
138		    mk_array_decl(G,N,X,Id,Type,Fd);
139		_ ->              % Elementary types or seq/struct
140		    mk_union_member_decl(G,N,X,Id,Type,Fd),
141		    ok
142	    end;
143	_ ->
144	    error
145    end;
146emit_c_union_values_decl_loop(G, N, X, Fd, [CU |CUs]) ->
147    case CU of
148	{case_dcl,_,Id,Type} ->
149	    case Id of
150		{array, _AID, _SZ} -> % Check for arrays
151		    mk_array_decl(G,N,X,Id,Type,Fd),
152		    emit_c_union_values_decl_loop(G, N, X, Fd, CUs);
153		_ ->              % Elementary types or seq/struct
154		    mk_union_member_decl(G,N,X,Id,Type,Fd),
155		    emit_c_union_values_decl_loop(G, N, X, Fd, CUs)
156	    end;
157	_ ->
158	    error
159    end.
160
161
162%% Makes the declaration for the array in union
163mk_array_decl(G,N,X,Id,Type,Fd) ->
164    emit(Fd, "    ~s ~s;\n",
165	 [getCaseTypeStr(G,N,X,Id,Type),
166	  mk_array_name(Id)]).
167
168mk_array_name({array,Id,D}) ->
169    ic_forms:get_id2(Id) ++ mk_array_dim(D).
170
171mk_array_dim([]) ->
172    "";
173mk_array_dim([{_,_,Dim}|Dims]) ->
174    "[" ++ Dim ++ "]" ++ mk_array_dim(Dims).
175
176
177%% Creates the array file
178mk_array_file(G,N,X,{array,AID,SZ},Type,HFd) ->
179    ArrayName = ic_util:to_undersc([ic_forms:get_id2(AID),ic_forms:get_id2(X) | N]),
180    ArrayDim =  extract_array_dim(SZ),
181    emit(HFd, "\n#ifndef __~s__\n",[ictype:to_uppercase(ArrayName)]),
182    emit(HFd, "#define __~s__\n\n",[ictype:to_uppercase(ArrayName)]),
183    icstruct:create_c_array_coding_file(G,
184					N,
185					{ArrayName,ArrayDim},
186					Type,
187					no_typedef),
188    emit(HFd, "\n#endif\n\n").
189
190extract_array_dim([{_,_,Dim}]) ->
191    [Dim];
192extract_array_dim([{_,_,Dim}|Dims]) ->
193    [Dim | extract_array_dim(Dims)].
194
195
196%% Makes the declaration for the member in union
197mk_union_member_decl(G,N,X,Id,Type,Fd) ->
198    emit(Fd, "    ~s ~s;\n",
199	 [getCaseTypeStr(G,N,X,Id,Type),
200	  ic_forms:get_id2(Id)]).
201
202
203
204
205%% File utilities
206create_c_union_file(G, N, X, UnionName) ->
207
208    {Fd , SName} = open_c_coding_file(G, UnionName),
209    _HFd = ic_genobj:hrlfiled(G), %% Write on stubfile header
210    HrlFName = filename:basename(ic_genobj:include_file(G)),
211    ic_codegen:emit_stub_head(G, Fd, SName, c),
212    emit(Fd, "#include \"~s\"\n\n",[HrlFName]),
213
214    %%  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
215    %%  Fd = ic_genobj:stubfiled(G), %% Write on stubfile
216    %%  HFd = ic_genobj:hrlfiled(G), %% Write on stubfile header
217    %%  HrlFName = filename:basename(ic_genobj:include_file(G)),
218    %%  emit(Fd, "#include \"~s\"\n\n",[HrlFName]),
219    %%  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
220
221    put(op_variable_count, 0),
222    put(tmp_declarations, []),
223
224    %% Write generated code on file
225    emit_union_sizecount(G, N, X, Fd, UnionName),
226    emit_union_encode(G, N, X, Fd, UnionName),
227    emit_union_decode(G, N, X, Fd, UnionName),
228    file:close(Fd).
229
230open_c_coding_file(G, Name) ->
231    SName = string:concat(ic_util:mk_oe_name(G, "code_"), Name),
232    FName =
233        ic_file:join(ic_options:get_opt(G, stubdir),ic_file:add_dot_c(SName)),
234    case file:open(FName, [write]) of
235        {ok, Fd} ->
236            {Fd, SName};
237        Other ->
238            exit(Other)
239    end.
240
241
242
243
244get_c_union_discriminator(G, N, X) ->
245    case getDiscrStr(G, N, X#union.type) of
246	error ->
247	    ic_error:fatal_error(G, {illegal_typecode_for_c, X#union.type, N});
248	DiscrStr ->
249	    case ic_code:get_basetype(G, DiscrStr) of
250		{short, _} ->
251		    "CORBA_short";
252		{unsigned,{short, _}} ->
253		    "CORBA_unsigned_short";
254		{long, _} ->
255		    "CORBA_long";
256		{unsigned,{long, _}} ->
257		    "CORBA_unsigned_long";
258		{boolean,_} ->
259		    "CORBA_boolean";
260		{char,_} ->
261		    "CORBA_char";
262		{enum, EnumType} ->
263		    EnumType;
264		_ ->
265		    DiscrStr
266	    end
267    end.
268
269getDiscrStr(G, N, S) when element(1, S) == scoped_id ->
270    case ic_symtab:get_full_scoped_name(G, N, S) of
271	{FSN, _, tk_short, _} ->
272	    ic_util:to_undersc(FSN);
273	{FSN, _, tk_ushort, _} ->
274	    ic_util:to_undersc(FSN);
275	{FSN, _, tk_long, _} ->
276	    ic_util:to_undersc(FSN);
277	{FSN, _, tk_ulong, _} ->
278	    ic_util:to_undersc(FSN);
279	{FSN, _, tk_boolean, _} ->
280	    ic_util:to_undersc(FSN);
281	{FSN, _, tk_char, _} ->
282	    ic_util:to_undersc(FSN);
283	{FSN, _, {tk_enum,_,_,_}, _} ->
284	    ic_util:to_undersc(FSN);
285	_ ->
286	    error
287    end;
288getDiscrStr(_G, N, X) ->
289    case X of
290	{short,_} ->
291	    "CORBA_short";
292	{unsigned,{short,_}} ->
293	    "CORBA_unsigned_short";
294	{long, _} ->
295	    "CORBA_long";
296	{unsigned,{long,_}} ->
297	    "CORBA_unsigned_long";
298	{boolean,_} ->
299	    "CORBA_boolean";
300	{char,_} ->
301	    "CORBA_char";
302	{enum,TID,_,_} ->
303	    ic_util:to_undersc([ic_forms:get_id2(TID) | N]);
304	_ ->
305	    error
306    end.
307
308
309
310
311getCaseTypeStr(G, N, X, I, T) when element(1, T) == scoped_id ->
312    case catch ic_symtab:get_full_scoped_name(G, N, T) of
313	{FSN, _, _, _} ->
314	    BT = ic_code:get_basetype(G, ic_util:to_undersc(FSN)),
315	    case isList(BT) of
316		true ->
317		    BT;
318		false ->
319		    case BT of
320			{short,_} ->
321			    "CORBA_short";
322			{unsigned,{short,_}} ->
323			    "CORBA_unsigned_short";
324			{long, _} ->
325			    "CORBA_long";
326			{unsigned,{long,_}} ->
327			    "CORBA_unsigned_long";
328			{float,_} ->
329			    "CORBA_float";
330			{double,_} ->
331			    "CORBA_double";
332			{boolean,_} ->
333			    "CORBA_boolean";
334			{char,_} ->
335			    "CORBA_char";
336			{wchar,_} ->
337			    "CORBA_wchar";
338			{octet,_} ->
339			    "CORBA_octet";
340			{string,_} ->
341			    "CORBA_char*";
342			{wstring,_} ->
343			    "CORBA_wchar*";
344			{sequence,_,_} ->
345			    ic_util:to_undersc([ic_forms:get_id2(I), ic_forms:get_id2(X) | N]);
346			{struct,SID,_,_} ->
347			    ic_util:to_undersc([ic_forms:get_id2(SID), ic_forms:get_id2(X) | N]);
348			{enum,EID} ->
349			    EID;
350			{any, _} -> %% Fix for any type
351			    "CORBA_long";
352			_ ->
353			    %%io:format("BT = ~p~n",[BT]),
354			    error
355		    end
356	    end
357    end;
358getCaseTypeStr(_G, N, X, I, T) ->
359    case T of
360	{short,_} ->
361	    "CORBA_short";
362	{unsigned,{short,_}} ->
363	    "CORBA_unsigned_short";
364	{long, _} ->
365	    "CORBA_long";
366	{unsigned,{long,_}} ->
367	    "CORBA_unsigned_long";
368	{float,_} ->
369	    "CORBA_float";
370	{double,_} ->
371	    "CORBA_double";
372	{boolean,_} ->
373	    "CORBA_boolean";
374	{char,_} ->
375	    "CORBA_char";
376	{wchar,_} ->
377	    "CORBA_wchar";
378	{octet,_} ->
379	    "CORBA_octet";
380	{string,_} ->
381	    "CORBA_char*";
382	{wstring,_} ->
383	    "CORBA_wchar*";
384	{sequence,_,_} ->
385	    ic_util:to_undersc([ic_forms:get_id2(I), ic_forms:get_id2(X) | N]);
386	{struct,SID,_,_} ->
387	    ic_util:to_undersc([ic_forms:get_id2(SID), ic_forms:get_id2(X) | N]);
388	{union,UID,_,_,_} ->
389	    ic_util:to_undersc([ic_forms:get_id2(UID), ic_forms:get_id2(X) | N]);
390	{any, _} -> %% Fix for any type
391	    "CORBA_long";
392	_ ->
393	    error
394    end.
395
396isList(L) when is_list(L) ->
397    true;
398isList(_) ->
399    false.
400
401%%
402%%  Sizecount facilities
403%%
404emit_union_sizecount(G, N, X, Fd, UnionName) ->
405    emit(Fd, "int ~s~s(CORBA_Environment *oe_env, int* oe_size_count_index, int* oe_size) {\n\n",
406	 [ic_util:mk_oe_name(G, "sizecalc_"), UnionName]),
407
408    emit(Fd, "  int oe_malloc_size = 0;\n"),
409    emit(Fd, "  int oe_error_code = 0;\n"),
410    emit(Fd, "  int oe_type = 0;\n"),
411    emit(Fd, "  int oe_tmp = 0;\n"),
412    emit_union_discr_var_decl(G, N, X, Fd),
413
414    ic_codegen:nl(Fd),
415    emit(Fd, "  if(*oe_size == 0)\n",[]),
416    AlignName = lists:concat(["*oe_size + sizeof(",UnionName,")"]),
417    emit(Fd, "    *oe_size = ~s;\n\n", [ic_util:mk_align(AlignName)]),
418
419    emit(Fd, "  if ((oe_error_code = ei_get_type(oe_env->_inbuf, oe_size_count_index, &oe_type, &oe_tmp)) < 0) {\n"),
420    emit_c_dec_rpt(Fd, "    ", "ei_get_type", []),
421    emit(Fd, "    return oe_error_code;\n  }\n"),
422
423    %%emit(Fd, "  if (oe_tmp != 3)\n"),
424    %%emit(Fd, "    return -1;\n\n"),
425
426    emit(Fd, "  if ((oe_error_code = ei_decode_tuple_header(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
427    emit_c_dec_rpt(Fd, "    ", "ei_decode_tuple_header", []),
428    emit(Fd, "    return oe_error_code;\n  }\n"),
429    emit(Fd, "  if ((oe_error_code = ei_decode_atom(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n", []),
430    emit_c_dec_rpt(Fd, "    ", "ei_decode_atom", []),
431    emit(Fd, "    return oe_error_code;\n  }\n"),
432
433    emit_c_union_discr_sizecount(G, N, X, Fd),
434    emit(Fd, "  /* Calculate union size */\n"),
435    emit(Fd, "  switch(oe_discr) {\n"),
436
437    emit_c_union_loop(G, N, X, Fd, X#union.body, sizecalc),
438    emit(Fd, "  }\n\n"),
439
440    emit(Fd, "  *oe_size = ~s;\n",[ic_util:mk_align("*oe_size+oe_malloc_size")]),
441    emit(Fd, "  return 0;\n"),
442    emit(Fd, "}\n\n\n").
443
444
445emit_union_discr_var_decl(G, N, X, Fd) ->
446    UD = get_c_union_discriminator(G, N, X),
447    case UD of
448	"CORBA_short" ->
449	    emit(Fd, "  long oe_discr = 0;\n");
450	"CORBA_unsigned_short" ->
451	    emit(Fd, "  unsigned long oe_discr = 0;\n");
452	"CORBA_long" ->
453	    emit(Fd, "  long oe_discr = 0;\n");
454	"CORBA_unsigned_long" ->
455	    emit(Fd, "  unsigned long oe_discr = 0;\n");
456	"CORBA_boolean" ->
457	    emit(Fd, "  int oe_discr = 0;\n"),
458	    emit(Fd, "  char oe_bool[256];\n");
459	"CORBA_char" ->
460	    emit(Fd, "  char oe_discr = 0;\n");
461	_T ->
462	    emit(Fd, "  int oe_dummy = 0;\n"),
463	    emit(Fd, "  ~s oe_discr = 0;\n",[UD])
464    end.
465
466
467emit_c_union_discr_sizecount(G, N, X, Fd) ->
468    emit(Fd, "  /* Calculate discriminator size */\n"),
469    UD = get_c_union_discriminator(G, N, X),
470    case UD of
471	"CORBA_short" ->
472	    emit(Fd, "  if ((oe_error_code = ei_decode_long(oe_env->_inbuf, oe_size_count_index, &oe_discr)) < 0) {\n"),
473	    emit_c_dec_rpt(Fd, "    ", "ei_decode_long", []),
474	    emit(Fd, "    return oe_error_code;\n  }\n");
475	"CORBA_unsigned_short" ->
476	    emit(Fd, "  if ((oe_error_code = ei_decode_ulong(oe_env->_inbuf, oe_size_count_index, &oe_discr)) < 0) {\n"),
477	    emit_c_dec_rpt(Fd, "    ", "ei_decode_ulong", []),
478	    emit(Fd, "    return oe_error_code;\n  }\n");
479	"CORBA_long" ->
480	    emit(Fd, "  if ((oe_error_code = ei_decode_long(oe_env->_inbuf, oe_size_count_index, &oe_discr)) < 0) {\n"),
481	    emit_c_dec_rpt(Fd, "    ", "ei_decode_long", []),
482	    emit(Fd, "    return oe_error_code;\n  }\n");
483	"CORBA_unsigned_long" ->
484	    emit(Fd, "  if ((oe_error_code = ei_decode_ulong(oe_env->_inbuf, oe_size_count_index, &oe_discr)) < 0) {\n"),
485	    emit_c_dec_rpt(Fd, "    ", "ei_decode_ulong", []),
486	    emit(Fd, "    return oe_error_code;\n  }\n");
487	"CORBA_boolean" ->
488	    emit(Fd, "  if ((oe_error_code = ei_decode_atom(oe_env->_inbuf, oe_size_count_index, oe_bool)) < 0) {\n"),
489	    emit_c_dec_rpt(Fd, "    ", "ei_decode_atom", []),
490	    emit(Fd, "    return oe_error_code;\n  }\n"),
491	    emit(Fd, "  if (strcmp(oe_bool, \"false\") == 0) {\n"),
492	    emit(Fd, "    oe_discr = 0;\n"),
493	    emit(Fd, "  }\n"),
494	    emit(Fd, "  else if (strcmp(oe_bool, \"true\") == 0) {\n"),
495	    emit(Fd, "    oe_discr = 1;\n"),
496	    emit(Fd, "  }\n"),
497	    emit(Fd, "  else {\n"),
498	    emit_c_dec_rpt(Fd, "    ", "not boolean", []),
499	    emit(Fd, "    return -1;\n  }\n");
500
501	"CORBA_char" ->
502	    emit(Fd, "  if ((oe_error_code = ei_decode_char(oe_env->_inbuf, oe_size_count_index, &oe_discr)) < 0) {\n"),
503	    emit_c_dec_rpt(Fd, "    ", "ei_decode_char", []),
504	    emit(Fd, "    return oe_error_code;\n  }\n");
505	T ->
506	    emit(Fd, "  oe_tmp = *oe_size_count_index;\n"),
507	    emit(Fd, "  if ((oe_error_code = oe_sizecalc_~s(oe_env, oe_size_count_index, &oe_malloc_size)) < 0) {\n", [T]),
508	    ?emit_c_dec_rpt(Fd, "    ", "oe_size_calc_~s", [T]),
509	    emit(Fd, "    return oe_error_code;\n  }\n"),
510
511	    emit(Fd, "  *oe_size_count_index = oe_tmp;\n"),
512	    emit(Fd, "  oe_tmp = oe_env->_iin;\n"),
513	    emit(Fd, "  oe_env->_iin = *oe_size_count_index;\n"),
514	    emit(Fd, "  if ((oe_error_code = oe_decode_~s(oe_env, NULL, &oe_dummy, &oe_discr)) < 0) {\n", [T]),
515	    ?emit_c_dec_rpt(Fd, "    ", "oe_decode_~s", [T]),
516	    emit(Fd, "    return oe_error_code;\n  }\n"),
517
518	    emit(Fd, "  *oe_size_count_index = oe_env->_iin;\n"),
519	    emit(Fd, "  oe_env->_iin = oe_tmp;\n\n")
520    end.
521
522
523
524emit_c_union_loop(G, N, X, Fd, CaseList, Case) ->
525    emit_c_union_loop(G, N, X, Fd, CaseList, false, Case).
526
527emit_c_union_loop(G, N, X, Fd, [], GotDefaultCase, Case) ->
528    case GotDefaultCase of
529	false ->
530	    emit_c_union_valueless_discriminator(G, N, X, Fd, Case)
531    end;
532emit_c_union_loop(G, N, X, Fd, [CU|CUs], GotDefaultCase, Case) ->
533    case CU of
534	{case_dcl,CaseList,I,T} ->
535	    GotDefaultCase = emit_c_union_case(G, N, X, Fd, I, T, CaseList, Case),
536	    emit_c_union_loop(G, N, X, Fd, CUs, GotDefaultCase, Case);
537	_ ->
538	    error
539    end.
540
541emit_c_union_valueless_discriminator(_G, _N, _X, Fd, Case) ->
542    emit(Fd, "  default:\n"),
543    case Case of
544	sizecalc ->
545	    emit(Fd, "    {\n"),
546	    emit(Fd, "      char oe_undefined[15];\n\n"),
547	    emit(Fd, "      if ((oe_error_code = ei_decode_atom(oe_env->_inbuf, "
548		 "oe_size_count_index, oe_undefined)) < 0) {\n"),
549	    emit_c_dec_rpt(Fd, "        ", "ei_decode_atom", []),
550	    emit(Fd, "        return oe_error_code;\n      }\n"),
551	    emit(Fd, "    }\n");
552	encode ->
553	    emit(Fd, "    if ((oe_error_code = oe_ei_encode_atom(oe_env, \"undefined\")) < 0) {\n"),
554	    emit_c_enc_rpt(Fd, "      ", "oe_ei_encode_atom", []),
555	    emit(Fd, "      return oe_error_code;\n      }\n"),
556	    emit(Fd, "    break;\n");
557	decode ->
558	    emit(Fd, "    {\n"),
559	    emit(Fd, "      char oe_undefined[15];\n\n"),
560	    emit(Fd, "      if ((oe_error_code = ei_decode_atom(oe_env->_inbuf, &oe_env->_iin, "
561		 "oe_undefined)) < 0) {\n"),
562	    emit_c_dec_rpt(Fd, "        ", "ei_decode_atom", []),
563	    emit(Fd, "        return oe_error_code;\n      }\n"),
564	    emit(Fd, "      if (strcmp(oe_undefined, \"undefined\") != 0) {\n"),
565	    emit_c_dec_rpt(Fd, "        ", "undefined", []),
566	    emit(Fd, "        return -1;\n      }\n"),
567	    emit(Fd, "    }\n")
568    end.
569
570
571emit_c_union_case(G, N, X, Fd, I, T, [{default,_}], Case) ->
572    emit(Fd, "  default:\n"),
573    case Case of
574	sizecalc ->
575	    getCaseTypeSizecalc(G, N, X, Fd, I, T);
576	encode ->
577	    getCaseTypeEncode(G, N, X, Fd, I, T);
578	decode ->
579	    getCaseTypeDecode(G, N, X, Fd, I, T)
580    end,
581    true;
582emit_c_union_case(G, N, X, Fd, I, T, [{Bool,_}], Case) -> %% Boolean discriminator
583    case Bool of
584	'TRUE' ->
585	    emit(Fd, "  case 1:\n");
586	'FALSE' ->
587	    emit(Fd, "  case 0:\n")
588    end,
589    case Case of
590	sizecalc ->
591	    getCaseTypeSizecalc(G, N, X, Fd, I, T);
592	encode ->
593	    getCaseTypeEncode(G, N, X, Fd, I, T);
594	decode ->
595	    getCaseTypeDecode(G, N, X, Fd, I, T)
596    end,
597    emit(Fd, "    break;\n\n"),
598    false;
599emit_c_union_case(G, N, X, Fd, I, T, [{Bool,_}|Rest], Case) -> %% Boolean discriminator
600    case Bool of
601	'TRUE' ->
602	    emit(Fd, "  case 1:\n");
603	'FALSE' ->
604	    emit(Fd, "  case 0:\n")
605    end,
606    emit_c_union_case(G, N, X, Fd, I, T, Rest, Case),
607    false;
608emit_c_union_case(G, N, X, Fd, I, T, [{_,_,NrStr}], Case) -> %% Integer type discriminator
609    case get_c_union_discriminator(G, N, X) of
610	"CORBA_char" ->
611	    emit(Fd, "  case \'~s\':\n",[NrStr]);
612	_ ->
613	    emit(Fd, "  case ~s:\n",[NrStr])
614    end,
615    case Case of
616	sizecalc ->
617	    getCaseTypeSizecalc(G, N, X, Fd, I, T);
618	encode ->
619	    getCaseTypeEncode(G, N, X, Fd, I, T);
620	decode ->
621	    getCaseTypeDecode(G, N, X, Fd, I, T)
622    end,
623    emit(Fd, "    break;\n\n"),
624    false;
625emit_c_union_case(G, N, X, Fd, I, T, [{_,_,NrStr}|Rest], Case) -> %% Integer type discriminator
626    emit(Fd, "  case ~s:\n",[NrStr]),
627    emit_c_union_case(G, N, X, Fd, I, T, Rest, Case),
628    false;
629emit_c_union_case(G, N, X, Fd, I, T, [{scoped_id,_,_,[EID]}], Case) -> %% Enumerant type discriminator
630    SID = ic_util:to_undersc([EID|get_c_union_discriminator_scope(G, N, X)]),
631    %%io:format("SID = ~p~n",[SID]),
632    emit(Fd, "  case ~s:\n",[SID]),
633    case Case of
634	sizecalc ->
635	    getCaseTypeSizecalc(G, N, X, Fd, I, T);
636	encode ->
637	    getCaseTypeEncode(G, N, X, Fd, I, T);
638	decode ->
639	    getCaseTypeDecode(G, N, X, Fd, I, T)
640    end,
641    emit(Fd, "    break;\n\n"),
642    false;
643emit_c_union_case(G, N, X, Fd, I, T, [{scoped_id,_,_,[EID]}|Rest], Case) -> %% Enumerant type discriminator
644    SID = ic_util:to_undersc([EID|get_c_union_discriminator_scope(G, N, X)]),
645    %%io:format("SID = ~p~n",[SID]),
646    emit(Fd, "  case ~s:\n",[SID]),
647    emit_c_union_case(G, N, X, Fd, I, T, Rest, Case),
648    false.
649
650
651%%
652%% Returns the enumerant discriminator scope
653%%
654get_c_union_discriminator_scope(G, N, X) ->
655    {FullScopedName, _, _TK, _} = ic_symtab:get_full_scoped_name(G, N, X#union.type),
656    BT = case ic_code:get_basetype(G, ic_util:to_undersc(FullScopedName)) of
657	     {enum,ST} ->
658		 ST;
659	     Other ->
660		 Other
661	 end,
662    tl(lists:reverse(string:tokens(BT,"_"))). %% Ugly work arround
663
664
665
666
667
668getCaseTypeSizecalc(G, N, X, Fd, I, T) when element(1, T) == scoped_id ->
669    case ic_fetch:member2type(G,X,I) of
670	ushort ->
671	    emit(Fd, "    if ((oe_error_code = ei_decode_ulong(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
672	    ?emit_c_dec_rpt(Fd, "      ", "ushort:ei_decode_ulong", []),
673	    emit(Fd, "      return oe_error_code;\n    }\n");
674	ulong ->
675	    emit(Fd, "    if ((oe_error_code = ei_decode_ulong(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
676	    ?emit_c_dec_rpt(Fd, "      ", "ulong:ei_decode_ulong", []),
677	    emit(Fd, "      return oe_error_code;\n    }\n");
678	short ->
679	    emit(Fd, "    if ((oe_error_code = ei_decode_long(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
680	    ?emit_c_dec_rpt(Fd, "      ", "short:ei_decode_long", []),
681	    emit(Fd, "      return oe_error_code;\n    }\n");
682	long ->
683	    emit(Fd, "    if ((oe_error_code = ei_decode_long(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
684	    ?emit_c_dec_rpt(Fd, "      ", "long:ei_decode_long", []),
685	    emit(Fd, "      return oe_error_code;\n    }\n");
686	float ->
687	    emit(Fd, "   if ((oe_error_code = ei_decode_double(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
688	    ?emit_c_dec_rpt(Fd, "      ", "float:ei_decode_double", []),
689	    emit(Fd, "      return oe_error_code;\n    }\n");
690	double ->
691	    emit(Fd, "    if ((oe_error_code = ei_decode_double(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
692	    ?emit_c_dec_rpt(Fd, "      ", "double:ei_decode_double", []),
693	    emit(Fd, "      return oe_error_code;\n    }\n");
694	boolean ->
695	    emit(Fd, "    if ((oe_error_code = ei_decode_atom(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
696	    ?emit_c_dec_rpt(Fd, "      ", "boolean:ei_decode_atom", []),
697	    emit(Fd, "      return oe_error_code;\n    }\n");
698	char ->
699	    emit(Fd, "    if ((oe_error_code = ei_decode_char(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
700	    ?emit_c_dec_rpt(Fd, "      ", "char:ei_decode_char", []),
701	    emit(Fd, "      return oe_error_code;\n    }\n");
702	octet ->
703	    emit(Fd, "    if ((oe_error_code = ei_decode_char(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
704	    ?emit_c_dec_rpt(Fd, "      ", "octet:ei_decode_char", []),
705	    emit(Fd, "      return oe_error_code;\n    }\n");
706	string ->
707	    emit(Fd, "    if ((oe_error_code = ei_get_type(oe_env->_inbuf, oe_size_count_index, &oe_type, &oe_tmp)) < 0) {\n"),
708	    ?emit_c_dec_rpt(Fd, "      ", "ei_get_type", []),
709	    emit(Fd, "      return oe_error_code;\n    }\n"),
710	    emit(Fd, "    if ((oe_error_code = ei_decode_string(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
711	    ?emit_c_dec_rpt(Fd, "      ", "ei_decode_string", []),
712	    emit(Fd, "      return oe_error_code;\n    }\n"),
713	    emit(Fd, "    oe_malloc_size = ~s;\n",[ic_util:mk_align("oe_malloc_size+oe_tmp+1")]);
714	any -> %% Fix for any type
715	    emit(Fd, "    if ((oe_error_code = ei_decode_long(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
716	    ?emit_c_dec_rpt(Fd, "      ", "ei_decode_long", []),
717	    emit(Fd, "      return oe_error_code;\n    }\n");
718
719	_ ->
720	    case getCaseTypeStr(G, N, X, I, T) of
721		"erlang_pid" ->
722		    emit(Fd, "  if ((oe_error_code = ei_decode_pid(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n",
723			 []),
724		    ?emit_c_dec_rpt(Fd, "    ", "ei_decode_pid", []),
725		    emit(Fd, "    return oe_error_code;\n    }\n");
726		"erlang_port" ->
727		    emit(Fd, "  if ((oe_error_code = ei_decode_port(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n",
728			 []),
729		    ?emit_c_dec_rpt(Fd, "    ", "ei_decode_port", []),
730		    emit(Fd, "    return oe_error_code;\n    }\n");
731		"erlang_ref" ->
732		    emit(Fd, "  if ((oe_error_code = ei_decode_ref(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n",
733			 []),
734		    ?emit_c_dec_rpt(Fd, "    ", "ei_decode_ref", []),
735		    emit(Fd, "    return oe_error_code;\n    }\n");
736		"erlang_term" ->
737		    emit(Fd, "  if ((oe_error_code = ic_decode_term(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n",
738			 []),
739		    ?emit_c_dec_rpt(Fd, "    ", "ic_decode_term", []),
740		    emit(Fd, "    return oe_error_code;\n    }\n");
741
742		Other ->
743
744		    emit(Fd, "    if ((oe_error_code = oe_sizecalc_~s(oe_env, oe_size_count_index, &oe_malloc_size)) < 0) {\n",
745			 [Other]),
746		    ?emit_c_dec_rpt(Fd, "      ", "oe_sizecalc_~s", [Other]),
747		    emit(Fd, "      return oe_error_code;\n    }\n")
748	    end
749    end;
750getCaseTypeSizecalc(G, N, X, Fd, I, T) ->
751    case I of
752	{array,_,_}  ->
753	    ArrayName = ic_util:to_undersc([ic_forms:get_id2(I),ic_forms:get_id2(X) | N]),
754	    emit(Fd, "    if ((oe_error_code = oe_sizecalc_~s(oe_env, oe_size_count_index, &oe_malloc_size)) < 0) {\n",
755		 [ArrayName]),
756	    ?emit_c_dec_rpt(Fd, "      ", "oe_sizecalc_~s", [ArrayName]),
757	    emit(Fd, "      return oe_error_code;\n    }\n");
758	_ ->
759	    case T of
760		{short,_} ->
761		    emit(Fd, "    if ((oe_error_code = ei_decode_long(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
762		    ?emit_c_dec_rpt(Fd, "      ", "short:ei_decode_long", []),
763		    emit(Fd, "      return oe_error_code;\n    }\n");
764		{unsigned,{short,_}} ->
765		    emit(Fd, "    if ((oe_error_code = ei_decode_ulong(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
766		    ?emit_c_dec_rpt(Fd, "      ", "ushort:ei_decode_ulong", []),
767		    emit(Fd, "      return oe_error_code;\n    }\n");
768		{long, _} ->
769		    emit(Fd, "    if ((oe_error_code = ei_decode_long(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
770		    ?emit_c_dec_rpt(Fd, "      ", "long:ei_decode_long", []),
771		    emit(Fd, "      return oe_error_code;\n    }\n");
772		{unsigned,{long,_}} ->
773		    emit(Fd, "    if ((oe_error_code = ei_decode_ulong(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
774		    ?emit_c_dec_rpt(Fd, "      ", "ulong:ei_decode_ulong", []),
775		    emit(Fd, "      return oe_error_code;\n    }\n");
776		{float,_} ->
777		    emit(Fd, "    if ((oe_error_code = ei_decode_double(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
778		    ?emit_c_dec_rpt(Fd, "      ", "float:ei_decode_double", []),
779		    emit(Fd, "      return oe_error_code;\n    }");
780		{double,_} ->
781		    emit(Fd, "    if ((oe_error_code = ei_decode_double(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
782		    ?emit_c_dec_rpt(Fd, "      ", "double:ei_decode_double", []),
783		    emit(Fd, "      return oe_error_code;\n    }\n");
784		{boolean,_} ->
785		    emit(Fd, "    if ((oe_error_code = ei_decode_atom(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
786		    ?emit_c_dec_rpt(Fd, "      ", "boolean:ei_decode_atom", []),
787		    emit(Fd, "      return oe_error_code;\n    }\n");
788		{char,_} ->
789		    emit(Fd, "    if ((oe_error_code = ei_decode_char(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
790		    ?emit_c_dec_rpt(Fd, "      ", "char:ei_decode_char", []),
791		    emit(Fd, "      return oe_error_code;\n    }\n");
792		{octet,_} ->
793		    emit(Fd, "    if ((oe_error_code = ei_decode_char(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
794		    ?emit_c_dec_rpt(Fd, "      ", "octet:ei_decode_char", []),
795		    emit(Fd, "      return oe_error_code;\n    }\n");
796		{string,_} ->
797		    emit(Fd, "    if ((oe_error_code = ei_get_type(oe_env->_inbuf, oe_size_count_index, &oe_type, &oe_tmp)) < 0) {\n"),
798		    ?emit_c_dec_rpt(Fd, "      ", "ei_get_type", []),
799		    emit(Fd, "      return oe_error_code;\n    }\n"),
800		    emit(Fd, "    if ((oe_error_code = ei_decode_string(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
801		    ?emit_c_dec_rpt(Fd, "      ", "ei_decode_string", []),
802		    emit(Fd, "      return oe_error_code;\n    }\n"),
803		    emit(Fd, "    oe_malloc_size = ~s;\n",[ic_util:mk_align("oe_malloc_size+oe_tmp+1")]);
804		{sequence,_,_} ->
805		    SeqName = ic_util:to_undersc([ic_forms:get_id2(I), ic_forms:get_id2(X) | N]),
806		    emit(Fd, "    if ((oe_error_code = oe_sizecalc_~s(oe_env, oe_size_count_index, &oe_malloc_size)) < 0) {\n",
807			 [SeqName]),
808		    ?emit_c_dec_rpt(Fd, "      ", "sequence:oe_sizecalc_~s", [SeqName]),
809		    emit(Fd, "      return oe_error_code;\n    }\n");
810		{struct,SID,_,_} ->
811		    StructName = ic_util:to_undersc([ic_forms:get_id2(SID), ic_forms:get_id2(X) | N]),
812		    emit(Fd, "    if ((oe_error_code = oe_sizecalc_~s(oe_env, oe_size_count_index, &oe_malloc_size)) < 0) {\n",
813			 [StructName]),
814		    ?emit_c_dec_rpt(Fd, "      ", "struct:oe_sizecalc_~s", [StructName]),
815		    emit(Fd, "      return oe_error_code;\n    }\n");
816		{union,UID,_,_,_} ->
817		    UnionName = ic_util:to_undersc([ic_forms:get_id2(UID), ic_forms:get_id2(X) | N]),
818		    emit(Fd, "    if ((oe_error_code = oe_sizecalc_~s(oe_env, oe_size_count_index, &oe_malloc_size)) < 0) {\n",
819			 [UnionName]),
820		    ?emit_c_dec_rpt(Fd, "      ", "union:oe_sizecalce_~s", [UnionName]),
821		    emit(Fd, "      return oe_error_code;\n    }\n");
822		{any, _} -> %% Fix for any type
823		    emit(Fd, "    if ((oe_error_code = ei_decode_long(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"),
824		    ?emit_c_dec_rpt(Fd, "      ", "any:ei_decode_long", []),
825		    emit(Fd, "      return oe_error_code;\n    }\n");
826		_ ->
827		    ic_error:fatal_error(G, {illegal_typecode_for_c, T, N})
828	    end
829    end.
830
831
832
833
834
835%%
836%% Encode facilities
837%%
838emit_union_encode(G, N, X, Fd, UnionName) ->
839    emit(Fd, "int ~s~s(CORBA_Environment *oe_env, ~s* oe_rec) {\n\n",
840	 [ic_util:mk_oe_name(G, "encode_"), UnionName, UnionName]),
841
842    emit(Fd, "  int oe_error_code = 0;\n\n"),
843
844    emit(Fd, "  if ((oe_error_code = oe_ei_encode_tuple_header(oe_env, 3)) < 0) {\n"),
845    emit_c_enc_rpt(Fd, "    ", "oe_ei_encode_tuple_header", []),
846    emit(Fd, "    return oe_error_code;\n  }\n"),
847
848    emit(Fd, "  if ((oe_error_code = oe_ei_encode_atom(oe_env, \"~s\")) < 0) {\n",
849	 [UnionName]),
850    emit_c_enc_rpt(Fd, "    ", "oe_ei_encode_atom", []),
851    emit(Fd, "    return oe_error_code;\n  }\n"),
852
853    emit_c_union_discr_encode(G, N, X, Fd),
854    emit(Fd, "  /* Encode union */\n"),
855    emit(Fd, "  switch(oe_rec->_d) {\n"),
856    emit_c_union_loop(G, N, X, Fd, X#union.body, encode),
857    emit(Fd, "  }\n\n"),
858    emit(Fd, "  return 0;\n"),
859    emit(Fd, "}\n\n\n").
860
861
862emit_c_union_discr_encode(G, N, X, Fd) ->
863    emit(Fd, "  /* Encode descriminator */\n"),
864    UD = get_c_union_discriminator(G, N, X),
865    case UD of
866	"CORBA_short" ->
867	    emit(Fd, "  if ((oe_error_code = oe_ei_encode_long(oe_env, oe_rec->_d)) < 0) {\n"),
868	    emit_c_enc_rpt(Fd, "    ", "oe_ei_encode_long", []),
869	    emit(Fd, "    return oe_error_code;\n  }\n");
870	"CORBA_unsigned_short" ->
871	    emit(Fd, "  if ((oe_error_code = oe_ei_encode_ulong(oe_env, oe_rec->_d)) < 0) {\n"),
872	    emit_c_enc_rpt(Fd, "    ", "oe_ei_encode_ulong", []),
873	    emit(Fd, "    return oe_error_code;\n  }\n");
874	"CORBA_long" ->
875	    emit(Fd, "  if ((oe_error_code = oe_ei_encode_long(oe_env, oe_rec->_d)) < 0) {\n"),
876	    emit_c_enc_rpt(Fd, "    ", "oe_ei_encode_long", []),
877	    emit(Fd, "    return oe_error_code;\n  }\n");
878	"CORBA_unsigned_long" ->
879	    emit(Fd, "  if ((oe_error_code = oe_ei_encode_ulong(oe_env, oe_rec->_d)) < 0) {\n"),
880	    emit_c_enc_rpt(Fd, "    ", "oe_ei_encode_ulong", []),
881	    emit(Fd, "    return oe_error_code;\n  }\n");
882	"CORBA_boolean" ->
883	    emit(Fd, "  switch(oe_rec->_d) {\n"),
884	    emit(Fd, "  case 0:\n"),
885	    emit(Fd, "    if ((oe_error_code = oe_ei_encode_atom(oe_env, \"false\")) < 0) {\n"),
886	    emit_c_enc_rpt(Fd, "      ", "oe_ei_encode_atom", []),
887	    emit(Fd, "      return oe_error_code;\n    }\n"),
888	    emit(Fd, "    break;\n"),
889	    emit(Fd, "  case 1:\n"),
890	    emit(Fd, "    if ((oe_error_code = oe_ei_encode_atom(oe_env, \"true\")) < 0) {\n"),
891	    emit_c_enc_rpt(Fd, "      ", "oe_ei_encode_atom", []),
892	    emit(Fd, "      return oe_error_code;\n    }\n"),
893	    emit(Fd, "    break;\n"),
894	    emit(Fd, "  default:\n"),
895	    emit_c_enc_rpt(Fd, "    ", "boolean failure", []),
896	    emit(Fd, "    return -1;\n"),
897	    emit(Fd, "  }\n\n");
898	"CORBA_char" ->
899	    emit(Fd, "  if ((oe_error_code = oe_ei_encode_char(oe_env, oe_rec->_d)) < 0) {\n"),
900	    emit_c_enc_rpt(Fd, "    ", "oe_ei_encode_char", []),
901	    emit(Fd, "    return oe_error_code;\n  }\n");
902	T ->
903	    emit(Fd, "  if ((oe_error_code = oe_encode_~s(oe_env, oe_rec->_d)) < 0) {\n", [T]),
904	    ?emit_c_enc_rpt(Fd, "    ", "oe_encode_~s", [T]),
905	    emit(Fd, "    return oe_error_code;\n  }\n")
906    end.
907
908
909getCaseTypeEncode(G, N, X, Fd, I, T) when element(1, T) == scoped_id ->
910    case ic_fetch:member2type(G,X,I) of
911	ushort ->
912	    emit(Fd, "    if ((oe_error_code = oe_ei_encode_ulong(oe_env, oe_rec->_u.~s)) < 0) {\n",
913		 [ic_forms:get_id2(I)]),
914	    ?emit_c_enc_rpt(Fd, "      ", "ushort:oe_ei_encode_ulong", []),
915	    emit(Fd, "      return oe_error_code;\n    }\n");
916	ulong ->
917	    emit(Fd, "    if ((oe_error_code = oe_ei_encode_ulong(oe_env, oe_rec->_u.~s)) < 0) {\n",
918		 [ic_forms:get_id2(I)]),
919	    ?emit_c_enc_rpt(Fd, "      ", "ulong:oe_ei_encode_ulong", []),
920	    emit(Fd, "      return oe_error_code;\n    }\n");
921	short ->
922	    emit(Fd, "    if ((oe_error_code = oe_ei_encode_long(oe_env, oe_rec->_u.~s)) < 0) {\n",
923		 [ic_forms:get_id2(I)]),
924	    ?emit_c_enc_rpt(Fd, "      ", "short:oe_ei_encode_long", []),
925	    emit(Fd, "      return oe_error_code;\n    }\n");
926	long ->
927	    emit(Fd, "    if ((oe_error_code = oe_ei_encode_long(oe_env, oe_rec->_u.~s)) < 0) {\n",
928		 [ic_forms:get_id2(I)]),
929	    ?emit_c_enc_rpt(Fd, "      ", "long:oe_ei_encode_long", []),
930	    emit(Fd, "      return oe_error_code;\n    }\n");
931	float ->
932	    emit(Fd, "   if ((oe_error_code = oe_ei_encode_double(oe_env, oe_rec->_u.~s)) < 0) {\n",
933		 [ic_forms:get_id2(I)]),
934	    ?emit_c_enc_rpt(Fd, "      ", "float:oe_ei_encode_double", []),
935	    emit(Fd, "      return oe_error_code;\n    }\n");
936	double ->
937	    emit(Fd, "    if ((oe_error_code = oe_ei_encode_double(oe_env, oe_rec->_u.~s)) < 0) {\n",
938		 [ic_forms:get_id2(I)]),
939	    ?emit_c_enc_rpt(Fd, "      ", "double:oe_ei_encode_double", []),
940	    emit(Fd, "      return oe_error_code;\n    }\n");
941	boolean ->
942	    emit(Fd, "    switch(oe_rec->_u.~s) {\n",[ic_forms:get_id2(I)]),
943	    emit(Fd, "    case 0:\n"),
944	    emit(Fd, "      if ((oe_error_code = oe_ei_encode_atom(oe_env, \"false\")) < 0) {\n"),
945	    ?emit_c_enc_rpt(Fd, "        ", "boolean:oe_ei_encode_atom", []),
946	    emit(Fd, "        return oe_error_code;\n      }\n"),
947	    emit(Fd, "      break;\n"),
948	    emit(Fd, "    case 1:\n"),
949	    emit(Fd, "      if ((oe_error_code = oe_ei_encode_atom(oe_env, \"true\")) < 0) {\n"),
950	    ?emit_c_enc_rpt(Fd, "        ", "boolean:oe_ei_encode_atom", []),
951	    emit(Fd, "        return oe_error_code;\n      }\n"),
952	    emit(Fd, "      break;\n"),
953	    emit(Fd, "    default:\n"),
954	    ?emit_c_enc_rpt(Fd, "      ", "boolean failure", []),
955	    emit(Fd, "      return -1;\n"),
956	    emit(Fd, "    }\n");
957	char ->
958	    emit(Fd, "    if ((oe_error_code = oe_ei_encode_char(oe_env, oe_rec->_u.~s)) < 0) {\n",
959		 [ic_forms:get_id2(I)]),
960	    ?emit_c_enc_rpt(Fd, "      ", "char:oe_ei_encode_char", []),
961	    emit(Fd, "      return oe_error_code;\n    }\n");
962	octet ->
963	    emit(Fd, "    if ((oe_error_code = oe_ei_encode_char(oe_env, oe_rec->_u.~s)) < 0) {\n",
964		 [ic_forms:get_id2(I)]),
965	    ?emit_c_enc_rpt(Fd, "      ", "octet:oe_ei_encode_char", []),
966	    emit(Fd, "      return oe_error_code;\n    }\n");
967	string ->
968	    emit(Fd, "    if ((oe_error_code = oe_ei_encode_string(oe_env, oe_rec->_u.~s)) < 0) {\n",
969		 [ic_forms:get_id2(I)]),
970	    ?emit_c_enc_rpt(Fd, "      ", "oe_ei_encode_string", []),
971	    emit(Fd, "      return oe_error_code;\n    }\n");
972	struct ->
973	    case ic_cbe:mk_c_type(G, N, T, evaluate_not) of
974		"erlang_pid" ->
975		    emit(Fd, "  if ((oe_error_code = oe_ei_encode_pid(oe_env, &oe_rec->_u.~s)) < 0) {\n",
976			 [ic_forms:get_id2(I)]),
977		    ?emit_c_enc_rpt(Fd, "    ", "oe_ei_encode_pid", []),
978		    emit(Fd, "    return oe_error_code;\n  }\n");
979		"erlang_port" ->
980		    emit(Fd, "  if ((oe_error_code = oe_ei_encode_port(oe_env, &oe_rec->_u.~s)) < 0) {\n",
981			 [ic_forms:get_id2(I)]),
982		    ?emit_c_enc_rpt(Fd, "    ", "oe_ei_encode_port", []),
983		    emit(Fd, "    return oe_error_code;\n  }\n");
984		"erlang_ref" ->
985		    emit(Fd, "  if ((oe_error_code = oe_ei_encode_ref(oe_env, &oe_rec->_u.~s)) < 0) {\n",
986			 [ic_forms:get_id2(I)]),
987		    ?emit_c_enc_rpt(Fd, "    ", "oe_ei_encode_ref", []),
988		    emit(Fd, "    return oe_error_code;\n  }\n");
989		"ic_erlang_term*" ->
990		    emit(Fd, "  if ((oe_error_code = oe_ic_encode_term(oe_env, &oe_rec->_u.~s)) < 0) {\n",
991			 [ic_forms:get_id2(I)]),
992		    ?emit_c_enc_rpt(Fd, "    ", "oe_ic_encode_term", []),
993		    emit(Fd, "    return oe_error_code;\n  }\n");
994		_ ->
995		    emit(Fd, "  if ((oe_error_code = oe_encode_~s(oe_env, &oe_rec->_u.~s)) < 0) {\n",
996			 [getCaseTypeStr(G, N, X, I, T), ic_forms:get_id2(I)]),
997		    ?emit_c_enc_rpt(Fd, "    ", "oe_encode_~s",
998				    [getCaseTypeStr(G, N, X, I, T)]),
999		    emit(Fd, "    return oe_error_code;\n  }\n")
1000	    end;
1001	sequence ->
1002	    emit(Fd, "    if ((oe_error_code = oe_encode_~s(oe_env, &oe_rec->_u.~s)) < 0) {\n",
1003		 [getCaseTypeStr(G, N, X, I, T),ic_forms:get_id2(I)]),
1004	    ?emit_c_enc_rpt(Fd, "      ", "sequence:oe_encode_~s",
1005			    [getCaseTypeStr(G, N, X, I, T)]),
1006	    emit(Fd, "      return oe_error_code;\n    }\n");
1007	array ->
1008	    emit(Fd, "    if ((oe_error_code = oe_encode_~s(oe_env, oe_rec->_u.~s)) < 0) {\n",
1009		 [getCaseTypeStr(G, N, X, I, T),ic_forms:get_id2(I)]),
1010	    ?emit_c_enc_rpt(Fd, "      ", "array:oe_encode_~s",
1011			    [getCaseTypeStr(G, N, X, I, T)]),
1012	    emit(Fd, "      return oe_error_code;\n    }\n");
1013	union ->
1014	    emit(Fd, "    if ((oe_error_code = oe_encode_~s(oe_env, &oe_rec->_u.~s)) < 0) {\n",
1015		 [getCaseTypeStr(G, N, X, I, T),ic_forms:get_id2(I)]),
1016	    ?emit_c_enc_rpt(Fd, "      ", "union:oe_encode_~s",
1017			    [getCaseTypeStr(G, N, X, I, T)]),
1018	    emit(Fd, "      return oe_error_code;\n    }\n");
1019	enum ->
1020	    emit(Fd, "    if ((oe_error_code = oe_encode_~s(oe_env, oe_rec->_u.~s)) < 0) {\n",
1021		 [getCaseTypeStr(G, N, X, I, T),ic_forms:get_id2(I)]),
1022	    ?emit_c_enc_rpt(Fd, "      ", "enum:oe_encode_~s",
1023			    [getCaseTypeStr(G, N, X, I, T)]),
1024	    emit(Fd, "      return oe_error_code;\n    }\n");
1025	any -> %% Fix for any type
1026	    emit(Fd, "    if ((oe_error_code = oe_ei_encode_long(oe_env, oe_rec->_u.~s)) < 0) {\n",
1027		 [ic_forms:get_id2(I)]),
1028	    ?emit_c_enc_rpt(Fd, "      ", "enum:oe_ei_encodelong", []),
1029	    emit(Fd, "      return oe_error_code;\n    }\n");
1030	_ ->
1031	    ic_error:fatal_error(G, {illegal_typecode_for_c, T, N})
1032    end;
1033getCaseTypeEncode(G, N, X, Fd, I, T) ->
1034    case I of
1035	{array,AID,_} ->
1036	    ArrayName = ic_util:to_undersc([ic_forms:get_id2(AID),ic_forms:get_id2(X) | N]),
1037	    emit(Fd, "    if ((oe_error_code = oe_encode_~s(oe_env, oe_rec->_u.~s)) < 0) {\n",
1038		 [ArrayName,ic_forms:get_id2(AID)]),
1039	    ?emit_c_enc_rpt(Fd, "      ", "array:oe_encode_~s", [ArrayName]),
1040	    emit(Fd, "      return oe_error_code;\n    }\n");
1041	_ ->
1042	    case T of
1043		{short,_} ->
1044		    emit(Fd, "    if ((oe_error_code = oe_ei_encode_long(oe_env, oe_rec->_u.~s)) < 0) {\n",
1045			 [ic_forms:get_id2(I)]),
1046		    ?emit_c_enc_rpt(Fd, "      ", "short:oe_ei_encode_long", []),
1047		    emit(Fd, "      return oe_error_code;\n    }\n");
1048		{unsigned,{short,_}} ->
1049		    emit(Fd, "    if ((oe_error_code = oe_ei_encode_ulong(oe_env, oe_rec->_u.~s)) < 0) {\n",
1050			 [ic_forms:get_id2(I)]),
1051		    ?emit_c_enc_rpt(Fd, "      ", "ushort:oe_ei_encode_ulong", []),
1052		    emit(Fd, "      return oe_error_code;\n    }\n");
1053		{long, _} ->
1054		    emit(Fd, "    if ((oe_error_code = oe_ei_encode_long(oe_env, oe_rec->_u.~s)) < 0) {\n",
1055			 [ic_forms:get_id2(I)]),
1056		    ?emit_c_enc_rpt(Fd, "      ", "long:oe_ei_encode_long", []),
1057		    emit(Fd, "      return oe_error_code;\n    }\n");
1058		{unsigned,{long,_}} ->
1059		    emit(Fd, "    if ((oe_error_code = oe_ei_encode_ulong(oe_env, oe_rec->_u.~s)) < 0) {\n",
1060			 [ic_forms:get_id2(I)]),
1061		    ?emit_c_enc_rpt(Fd, "      ", "ulong:oe_ei_encode_ulong", []),
1062		    emit(Fd, "      return oe_error_code;\n    }\n");
1063		{float,_} ->
1064		    emit(Fd, "    if ((oe_error_code = oe_ei_encode_double(oe_env, oe_rec->_u.~s)) < 0) {\n",
1065			 [ic_forms:get_id2(I)]),
1066		    ?emit_c_enc_rpt(Fd, "      ", "float:oe_ei_encode_double", []),
1067		    emit(Fd, "      return oe_error_code;\n    }\n");
1068		{double,_} ->
1069		    emit(Fd, "    if ((oe_error_code = oe_ei_encode_double(oe_env, oe_rec->_u.~s)) < 0) {\n",
1070			 [ic_forms:get_id2(I)]),
1071		    ?emit_c_enc_rpt(Fd, "      ", "double:oe_ei_encode_double", []),
1072		    emit(Fd, "      return oe_error_code;\n    }\n");
1073		{boolean,_} ->
1074		    emit(Fd, "    switch(oe_rec->_u.~s) {\n",[ic_forms:get_id2(I)]),
1075		    emit(Fd, "    case 0:\n"),
1076		    emit(Fd, "      if ((oe_error_code = oe_ei_encode_atom(oe_env, \"false\")) < 0) {\n"),
1077		    ?emit_c_enc_rpt(Fd, "        ", "boolean:oe_ei_encode_atom", []),
1078		    emit(Fd, "        return oe_error_code;\n      }\n"),
1079		    emit(Fd, "      break;\n"),
1080		    emit(Fd, "    case 1:\n"),
1081		    emit(Fd, "      if ((oe_error_code = oe_ei_encode_atom(oe_env, \"true\")) < 0) {\n"),
1082		    ?emit_c_enc_rpt(Fd, "        ", "boolean:oe_ei_encode_atom", []),
1083		    emit(Fd, "        return oe_error_code;\n      }\n"),
1084		    emit(Fd, "      break;\n"),
1085		    emit(Fd, "    default:\n"),
1086		    ?emit_c_enc_rpt(Fd, "      ", "boolean failure", []),
1087		    emit(Fd, "      return -1;\n"),
1088		    emit(Fd, "    }\n");
1089		{char,_} ->
1090		    emit(Fd, "    if ((oe_error_code = oe_ei_encode_char(oe_env, oe_rec->_u.~s)) < 0) {\n",
1091			 [ic_forms:get_id2(I)]),
1092		    ?emit_c_enc_rpt(Fd, "      ", "char:oe_ei_encode_char", []),
1093		    emit(Fd, "      return oe_error_code;\n    }\n");
1094		{octet,_} ->
1095		    emit(Fd, "    if ((oe_error_code = oe_ei_encode_char(oe_env, oe_rec->_u.~s)) < 0) {\n",
1096			 [ic_forms:get_id2(I)]),
1097		    ?emit_c_enc_rpt(Fd, "      ", "octet:oe_ei_encode_char", []),
1098		    emit(Fd, "      return oe_error_code;\n    }\n");
1099		{string,_} ->
1100		    emit(Fd, "    if ((oe_error_code = oe_ei_encode_string(oe_env, oe_rec->_u.~s)) < 0) {\n",
1101			 [ic_forms:get_id2(I)]),
1102		    ?emit_c_enc_rpt(Fd, "      ", "oe_ei_encode_string", []),
1103		    emit(Fd, "      return oe_error_code;\n    }\n");
1104		{sequence,_,_} ->
1105		    SeqName = ic_util:to_undersc([ic_forms:get_id2(I), ic_forms:get_id2(X) | N]),
1106		    emit(Fd, "    if ((oe_error_code = oe_encode_~s(oe_env, &oe_rec->_u.~s)) < 0) {\n",
1107			 [SeqName,ic_forms:get_id2(I)]),
1108		    ?emit_c_enc_rpt(Fd, "      ", "sequence:oe_encode_~s", [SeqName]),
1109		    emit(Fd, "      return oe_error_code;\n    }\n");
1110		{struct,SID,_,_} ->
1111		    StructName = ic_util:to_undersc([ic_forms:get_id2(SID), ic_forms:get_id2(X) | N]),
1112		    emit(Fd, "    if ((oe_error_code = oe_encode_~s(oe_env, &oe_rec->_u.~s)) < 0) {\n",
1113			 [StructName,ic_forms:get_id2(I)]),
1114		    ?emit_c_enc_rpt(Fd, "      ", "struct:oe_encode_~s", [StructName]),
1115		    emit(Fd, "      return oe_error_code;\n    }\n");
1116		{union,UID,_,_,_} ->
1117		    UnionName = ic_util:to_undersc([ic_forms:get_id2(UID), ic_forms:get_id2(X) | N]),
1118		    emit(Fd, "    if ((oe_error_code = oe_encode_~s(oe_env, &oe_rec->_u.~s)) < 0) {\n",
1119			 [UnionName,ic_forms:get_id2(I)]),
1120		    ?emit_c_enc_rpt(Fd, "      ", "union:oe_encode_~s", [UnionName]),
1121		    emit(Fd, "      return oe_error_code;\n    }\n");
1122		_ ->
1123		    ic_error:fatal_error(G, {illegal_typecode_for_c, T, N})
1124	    end
1125    end.
1126
1127
1128
1129
1130%%
1131%% Decode facilities
1132%%
1133emit_union_decode(G, N, X, Fd, UnionName) ->
1134    emit(Fd, "int ~s~s(CORBA_Environment *oe_env, char *oe_first, int* oe_index, ~s* oe_rec) {\n\n",
1135	 [ic_util:mk_oe_name(G, "decode_"), UnionName, UnionName]),
1136
1137    emit(Fd, "  int oe_error_code = 0;\n"),
1138    emit(Fd, "  int oe_tmp = 0;\n"),
1139    emit(Fd, "  char oe_union_name[256];\n\n"),
1140
1141    emit(Fd, "  if((char*) oe_rec == oe_first)\n",[]),
1142    AlignName = lists:concat(["*oe_index + sizeof(",UnionName,")"]),
1143    emit(Fd, "    *oe_index = ~s;\n\n", [ic_util:mk_align(AlignName)]),
1144
1145    emit(Fd, "  if ((oe_error_code = ei_decode_tuple_header(oe_env->_inbuf, &oe_env->_iin, &oe_tmp)) < 0) {\n"),
1146    emit_c_dec_rpt(Fd, "    ", "ei_decode_tuple_header", []),
1147    emit(Fd, "    return oe_error_code;\n  }\n"),
1148
1149    emit(Fd, "  if ((oe_error_code = ei_decode_atom(oe_env->_inbuf, &oe_env->_iin, oe_union_name)) < 0) {\n"),
1150    emit_c_dec_rpt(Fd, "    ", "ei_decode_atom", []),
1151    emit(Fd, "    return oe_error_code;\n  }\n"),
1152
1153    emit_c_union_discr_decode(G, N, X, Fd),
1154    emit(Fd, "  /* Decode union */\n"),
1155    emit(Fd, "  switch(oe_rec->_d) {\n"),
1156    emit_c_union_loop(G, N, X, Fd, X#union.body, decode),
1157    emit(Fd, "  }\n\n"),
1158
1159    emit(Fd, "  *oe_index = ~s;\n", [ic_util:mk_align("*oe_index")]),
1160    emit(Fd, "  return 0;\n"),
1161    emit(Fd, "}\n\n\n").
1162
1163
1164emit_c_union_discr_decode(G, N, X, Fd) ->
1165    emit(Fd, "  /* Decode descriminator */\n"),
1166    UD = get_c_union_discriminator(G, N, X),
1167    case UD of
1168	"CORBA_short" ->
1169	    emit(Fd, "  {\n"),
1170	    emit(Fd, "    long oe_long;\n"),
1171	    emit(Fd, "    if ((oe_error_code = ei_decode_long(oe_env->_inbuf, &oe_env->_iin, &oe_long)) < 0) {\n"),
1172	    emit_c_dec_rpt(Fd, "      ", "short:ei_decode_long", []),
1173	    emit(Fd, "      return oe_error_code;\n    }\n"),
1174	    emit(Fd, "    oe_rec->_d = (short) oe_long;\n\n"),
1175	    emit(Fd, "    if (oe_rec->_d !=  oe_long)\n      return -1;\n"),
1176	    emit(Fd, "  }\n\n");
1177	"CORBA_unsigned_short" ->
1178	    emit(Fd, "  {\n"),
1179	    emit(Fd, "    unsigned long oe_ulong;\n"),
1180	    emit(Fd, "    if ((oe_error_code = ei_decode_ulong(oe_env->_inbuf, &oe_env->_iin, &oe_ulong)) < 0) {\n"),
1181	    emit_c_dec_rpt(Fd, "      ", "unshort:ei_decode_ulong", []),
1182	    emit(Fd, "      return oe_error_code;\n    }\n"),
1183	    emit(Fd, "    oe_rec->_d = (unsigned short) oe_ulong;\n\n"),
1184	    emit(Fd, "    if (oe_rec->_d !=  oe_ulong)\n      return -1;\n"),
1185	    emit(Fd, "  }\n\n");
1186	"CORBA_long" ->
1187	    emit(Fd, "  if ((oe_error_code = ei_decode_long(oe_env->_inbuf, &oe_env->_iin, &oe_rec->_d)) < 0) {\n"),
1188	    emit_c_dec_rpt(Fd, "    ", "long:ei_decode_long", []),
1189	    emit(Fd, "    return oe_error_code;\n  }\n");
1190	"CORBA_unsigned_long" ->
1191	    emit(Fd, "  if ((oe_error_code = ei_decode_ulong(oe_env->_inbuf, &oe_env->_iin, &oe_rec->_d)) < 0) {\n"),
1192	    emit_c_dec_rpt(Fd, "    ", "ulong:ei_decode_ulong", []),
1193	    emit(Fd, "    return oe_error_code;\n  }\n");
1194	"CORBA_boolean" ->
1195	    emit(Fd, "  {\n"),
1196	    emit(Fd, "    char oe_bool[25];\n\n"),
1197	    emit(Fd, "    if ((oe_error_code = ei_decode_atom(oe_env->_inbuf, &oe_env->_iin, oe_bool)) < 0) {\n"),
1198	    emit_c_dec_rpt(Fd, "      ", "boolean:ei_decode_atom", []),
1199	    emit(Fd, "      return oe_error_code;\n    }\n"),
1200	    emit(Fd, "    if (strcmp(oe_bool, \"false\") == 0) {\n"),
1201	    emit(Fd, "      oe_rec->_d = 0;\n"),
1202	    emit(Fd, "    }else if (strcmp(oe_bool, \"true\") == 0) {\n"),
1203	    emit(Fd, "      oe_rec->_d = 1;\n"),
1204	    emit(Fd, "    } else {\n"),
1205	    emit_c_dec_rpt(Fd, "      ", "boolean failure", []),
1206	    emit(Fd, "      return -1;\n    }\n"),
1207	    emit(Fd, "  }\n\n");
1208	"CORBA_char" ->
1209	    emit(Fd, "  if ((oe_error_code = ei_decode_char(oe_env->_inbuf, &oe_env->_iin, &oe_rec->_d)) < 0) {\n"),
1210	    emit_c_dec_rpt(Fd, "    ", "char:ei_decode_char", []),
1211	    emit(Fd, "    return oe_error_code;\n  }\n");
1212	T ->
1213	    emit(Fd, "  if ((oe_error_code = oe_decode_~s(oe_env, oe_first, oe_index, &oe_rec->_d)) < 0) {\n",
1214		 [T]),
1215	    ?emit_c_dec_rpt(Fd, "    ", "oe_decode_~s", [T]),
1216	    emit(Fd, "    return oe_error_code;\n  }\n")
1217    end.
1218
1219
1220
1221getCaseTypeDecode(G, N, X, Fd, I, T) when element(1, T) == scoped_id ->
1222    case ic_fetch:member2type(G,X,I) of
1223	ushort ->
1224	    emit(Fd, "    {\n"),
1225	    emit(Fd, "      unsigned long oe_ulong;\n"),
1226	    emit(Fd, "      if ((oe_error_code = ei_decode_ulong(oe_env->_inbuf, &oe_env->_iin, &oe_ulong)) < 0) {\n"),
1227	    ?emit_c_dec_rpt(Fd, "        ", "ushort:ei_decode_ulong", []),
1228	    emit(Fd, "        return oe_error_code;\n      }\n"),
1229	    emit(Fd, "      oe_rec->_u.~s = (unsigned short) oe_ulong;\n\n",[ic_forms:get_id2(I)]),
1230	    emit(Fd, "      if (oe_rec->_u.~s !=  oe_ulong)\n        return -1;\n",[ic_forms:get_id2(I)]),
1231	    emit(Fd, "    }\n");
1232	ulong ->
1233	    emit(Fd, "    if ((oe_error_code = ei_decode_ulong(oe_env->_inbuf, &oe_env->_iin, &oe_rec->_u.~s)) < 0) {\n",
1234		 [ic_forms:get_id2(I)]),
1235	    ?emit_c_dec_rpt(Fd, "      ", "ulong:ei_decode_ulong", []),
1236	    emit(Fd, "      return oe_error_code;\n    }\n");
1237	short ->
1238	    emit(Fd, "    {\n"),
1239	    emit(Fd, "      long oe_long;\n"),
1240	    emit(Fd, "      if ((oe_error_code = ei_decode_long(oe_env->_inbuf, &oe_env->_iin, &oe_long)) < 0) {\n"),
1241	    ?emit_c_dec_rpt(Fd, "        ", "short:ei_decode_long", []),
1242	    emit(Fd, "        return oe_error_code;\n      }\n"),
1243	    emit(Fd, "      oe_rec->_u.~s = (short) oe_long;\n\n",[ic_forms:get_id2(I)]),
1244	    emit(Fd, "      if (oe_rec->_u.~s !=  oe_long)\n        return -1;\n",[ic_forms:get_id2(I)]),
1245	    emit(Fd, "    }\n");
1246	long ->
1247	    emit(Fd, "    if ((oe_error_code = ei_decode_long(oe_env->_inbuf, &oe_env->_iin, &oe_rec->_u.~s)) < 0) {\n",
1248		 [ic_forms:get_id2(I)]),
1249	    ?emit_c_dec_rpt(Fd, "    ", "long:ei_decode_long", []),
1250	    emit(Fd, "    return oe_error_code;\n    }\n");
1251	float ->
1252	    emit(Fd, "    {\n"),
1253	    emit(Fd, "      double oe_double;\n"),
1254	    emit(Fd, "      if ((oe_error_code = ei_decode_double(oe_env->_inbuf, &oe_env->_iin, &oe_double)) < 0) {\n"),
1255	    ?emit_c_dec_rpt(Fd, "        ", "float:ei_decode_double", []),
1256	    emit(Fd, "        return oe_error_code;\n      }\n"),
1257	    emit(Fd, "      oe_rec->_u.~s = (float) oe_double;\n",[ic_forms:get_id2(I)]),
1258	    emit(Fd, "    }\n");
1259	double ->
1260	    emit(Fd, "    if ((oe_error_code = ei_decode_double(oe_env->_inbuf, &oe_env->_iin, &oe_rec->_u.~s)) < 0) {\n",
1261		 [ic_forms:get_id2(I)]),
1262	    ?emit_c_dec_rpt(Fd, "      ", "double:ei_decode_double", []),
1263	    emit(Fd, "      return oe_error_code;\n    }\n");
1264	boolean ->
1265	    emit(Fd, "    {\n"),
1266	    emit(Fd, "      char oe_bool[25];\n\n"),
1267	    emit(Fd, "      if ((oe_error_code = ei_decode_atom(oe_env->_inbuf, &oe_env->_iin, oe_bool)) < 0) {\n"),
1268	    ?emit_c_dec_rpt(Fd, "        ", "boolean:ei_decode_atom", []),
1269	    emit(Fd, "        return oe_error_code;\n      }\n"),
1270	    emit(Fd, "      if (strcmp(oe_bool, \"false\") == 0) {\n"),
1271	    emit(Fd, "        oe_rec->_u.~s = 0;\n",[ic_forms:get_id2(I)]),
1272	    emit(Fd, "      } else if (strcmp(oe_bool, \"true\") == 0) {\n"),
1273	    emit(Fd, "        oe_rec->_u.~s = 1;\n",[ic_forms:get_id2(I)]),
1274	    emit(Fd, "      } else {\n"),
1275	    ?emit_c_dec_rpt(Fd, "        ", "boolean failure", []),
1276	    emit(Fd, "        return -1;\n        }\n"),
1277	    emit(Fd, "    }\n");
1278	char ->
1279	    emit(Fd, "    if ((oe_error_code = ei_decode_char(oe_env->_inbuf, &oe_env->_iin, &oe_rec->_u.~s)) < 0) {\n",
1280		 [ic_forms:get_id2(I)]),
1281	    ?emit_c_dec_rpt(Fd, "      ", "char:ei_decode_char", []),
1282	    emit(Fd, "      return oe_error_code;\n    }\n");
1283	octet ->
1284	    emit(Fd, "    if ((oe_error_code = ei_decode_char(oe_env->_inbuf, &oe_env->_iin, &oe_rec->_u.~s)) < 0) {\n",
1285		 [ic_forms:get_id2(I)]),
1286	    ?emit_c_dec_rpt(Fd, "      ", "octet:ei_decode_char", []),
1287	    emit(Fd, "      return oe_error_code;\n    }\n");
1288	string ->
1289	    emit(Fd, "    {\n"),
1290	    emit(Fd, "      int oe_type = 0;\n"),
1291	    emit(Fd, "      int oe_string_ctr = 0;\n\n"),
1292
1293	    emit(Fd, "      (int) ei_get_type(oe_env->_inbuf, &oe_env->_iin, &oe_type, &oe_string_ctr);\n\n"),
1294
1295	    emit(Fd, "      oe_rec->_u.~s = (void *) (oe_first + *oe_index);\n\n",[ic_forms:get_id2(I)]),
1296
1297	    emit(Fd, "      if ((oe_error_code = ei_decode_string(oe_env->_inbuf, &oe_env->_iin, oe_rec->_u.~s)) < 0) {\n",
1298		 [ic_forms:get_id2(I)]),
1299	    ?emit_c_dec_rpt(Fd, "        ", "ei_decode_string", []),
1300	    emit(Fd, "        return oe_error_code;\n      }\n"),
1301
1302	    emit(Fd, "      *oe_index = ~s;\n",[ic_util:mk_align("*oe_index+oe_string_ctr+1")]),
1303	    emit(Fd, "    }\n");
1304	struct ->
1305	    case ic_cbe:mk_c_type(G, N, T, evaluate_not) of
1306		"erlang_pid" ->
1307		    emit(Fd, "  if ((oe_error_code = ei_decode_pid(oe_env->_inbuf, &oe_env->_iin, &oe_rec->_u.~s)) < 0) {\n",
1308			 [ic_forms:get_id2(I)]),
1309		    ?emit_c_dec_rpt(Fd, "    ", "ei_decode_pid", []),
1310		    emit(Fd, "    return oe_error_code;\n  }\n");
1311		"erlang_port" ->
1312		    emit(Fd, "  if ((oe_error_code = ei_decode_port(oe_env->_inbuf, &oe_env->_iin, &oe_rec->_u.~s)) < 0) {\n",
1313			 [ic_forms:get_id2(I)]),
1314		    ?emit_c_dec_rpt(Fd, "    ", "ei_decode_port", []),
1315		    emit(Fd, "    return oe_error_code;\n  }\n");
1316		"erlang_ref" ->
1317		    emit(Fd, "  if ((oe_error_code = ei_decode_ref(oe_env->_inbuf, &oe_env->_iin, &oe_rec->_u.~s)) < 0) {\n",
1318			 [ic_forms:get_id2(I)]),
1319		    ?emit_c_dec_rpt(Fd, "    ", "ei_decode_ref", []),
1320		    emit(Fd, "    return oe_error_code;\n  }\n");
1321		"ic_erlang_term*" ->
1322		    emit(Fd, "  if ((oe_error_code = ic_decode_term(oe_env->_inbuf, &oe_env->_iin, &oe_rec->_u.~s)) < 0) {\n",
1323			 [ic_forms:get_id2(I)]),
1324		    ?emit_c_dec_rpt(Fd, "    ", "ic_decode_term", []),
1325		    emit(Fd, "    return oe_error_code;\n  }\n");
1326
1327		_ ->
1328		    emit(Fd, "  if ((oe_error_code = oe_decode_~s(oe_env, oe_first, oe_index, &oe_rec->_u.~s)) < 0) {\n",
1329			 [getCaseTypeStr(G, N, X, I, T),ic_forms:get_id2(I)]),
1330		    ?emit_c_dec_rpt(Fd, "    ", "oe_decode_~s",
1331				    [getCaseTypeStr(G, N, X, I, T)]),
1332		    emit(Fd, "    return oe_error_code;\n  }\n")
1333	    end;
1334	sequence ->
1335	    emit(Fd, "  if ((oe_error_code = oe_decode_~s(oe_env, oe_first, oe_index, &oe_rec->_u.~s)) < 0) {\n",
1336		 [getCaseTypeStr(G, N, X, I, T),ic_forms:get_id2(I)]),
1337	    ?emit_c_dec_rpt(Fd, "    ", "sequence:oe_decode_~s",
1338			    [getCaseTypeStr(G, N, X, I, T)]),
1339	    emit(Fd, "    return oe_error_code;\n  }\n");
1340	array ->
1341	    emit(Fd, "  if ((oe_error_code = oe_decode_~s(oe_env, oe_first, oe_index, oe_rec->_u.~s)) < 0) {\n",
1342		 [getCaseTypeStr(G, N, X, I, T),ic_forms:get_id2(I)]),
1343	    ?emit_c_dec_rpt(Fd, "    ", "array:oe_decode_~s", [getCaseTypeStr(G, N, X, I, T)]),
1344	    emit(Fd, "    return oe_error_code;\n  }\n");
1345	union ->
1346	    emit(Fd, "  if ((oe_error_code = oe_decode_~s(oe_env, oe_first, oe_index, &oe_rec->_u.~s)) < 0) {\n",
1347		 [getCaseTypeStr(G, N, X, I, T),ic_forms:get_id2(I)]),
1348	    ?emit_c_dec_rpt(Fd, "    ", "union:oe_decode_~s", [getCaseTypeStr(G, N, X, I, T)]),
1349	    emit(Fd, "    return oe_error_code;\n  }\n");
1350	enum ->
1351	    emit(Fd, "  if ((oe_error_code = oe_decode_~s(oe_env, oe_first, oe_index, &oe_rec->_u.~s)) < 0) {\n",
1352		 [getCaseTypeStr(G, N, X, I, T),ic_forms:get_id2(I)]),
1353	    ?emit_c_dec_rpt(Fd, "    ", "enum:oe_decode_~s", [getCaseTypeStr(G, N, X, I, T)]),
1354	    emit(Fd, "    return oe_error_code;\n  }\n");
1355	any -> %% Fix for any type
1356	    emit(Fd, "  if ((oe_error_code = ei_decode_long(oe_env->_inbuf, &oe_env->_iin, &oe_rec->_u.~s)) < 0) {\n",
1357		 [ic_forms:get_id2(I)]),
1358	    ?emit_c_dec_rpt(Fd, "    ", "any:ei_decodelong", []),
1359	    emit(Fd, "    return oe_error_code;\n  }\n");
1360	_ ->
1361	    ic_error:fatal_error(G, {illegal_typecode_for_c, T, N})
1362    end;
1363getCaseTypeDecode(G, N, X, Fd, I, T) ->
1364    case I of
1365	{array,AID,_} ->
1366	    ArrayName = ic_util:to_undersc([ic_forms:get_id2(AID),ic_forms:get_id2(X) | N]),
1367	    emit(Fd, "    if ((oe_error_code = oe_decode_~s(oe_env, oe_first, oe_index, oe_rec->_u.~s)) < 0) {\n",
1368		 [ArrayName,ic_forms:get_id2(AID)]),
1369	    ?emit_c_dec_rpt(Fd, "      ", "array:oe_decode_~s", [ArrayName]),
1370	    emit(Fd, "      return oe_error_code;\n    }\n");
1371	_ ->
1372	    case T of
1373		{short,_} ->
1374		    emit(Fd, "    {\n"),
1375		    emit(Fd, "      long oe_long;\n"),
1376		    emit(Fd, "      if ((oe_error_code = ei_decode_long(oe_env->_inbuf, &oe_env->_iin, &oe_long)) < 0) {\n"),
1377		    ?emit_c_dec_rpt(Fd, "        ", "short:ei_decode_long", []),
1378		    emit(Fd, "        return oe_error_code;\n      }\n"),
1379		    emit(Fd, "      oe_rec->_u.~s = (short) oe_long;\n\n",[ic_forms:get_id2(I)]),
1380		    emit(Fd, "      if (oe_rec->_u.~s !=  oe_long)\n        return -1;\n",[ic_forms:get_id2(I)]),
1381		    emit(Fd, "    }\n");
1382		{unsigned,{short,_}} ->
1383		    emit(Fd, "    {\n"),
1384		    emit(Fd, "      unsigned long oe_ulong;\n"),
1385		    emit(Fd, "      if ((oe_error_code = ei_decode_ulong(oe_env->_inbuf, &oe_env->_iin, &oe_ulong)) < 0) {\n"),
1386		    ?emit_c_dec_rpt(Fd, "        ", "ushort:ei_decode_ulong", []),
1387		    emit(Fd, "        return oe_error_code;\n      }\n"),
1388		    emit(Fd, "      oe_rec->_u.~s = (unsigned short) oe_ulong;\n\n",[ic_forms:get_id2(I)]),
1389		    emit(Fd, "      if (oe_rec->_u.~s !=  oe_ulong)\n        return -1;\n",[ic_forms:get_id2(I)]),
1390		    emit(Fd, "    }\n");
1391		{long, _} ->
1392		    emit(Fd, "    if ((oe_error_code = ei_decode_long(oe_env->_inbuf, &oe_env->_iin, &oe_rec->_u.~s)) < 0) {\n",
1393			 [ic_forms:get_id2(I)]),
1394		    ?emit_c_dec_rpt(Fd, "      ", "long:ei_decode_long", []),
1395		    emit(Fd, "      return oe_error_code;\n    }\n");
1396		{unsigned,{long,_}} ->
1397		    emit(Fd, "    if ((oe_error_code = ei_decode_ulong(oe_env->_inbuf, &oe_env->_iin, &oe_rec->_u.~s)) < 0) {\n",
1398			 [ic_forms:get_id2(I)]),
1399		    ?emit_c_dec_rpt(Fd, "      ", "ulong:ei_decode_ulong", []),
1400		    emit(Fd, "      return oe_error_code;\n    }\n");
1401		{float,_} ->
1402		    emit(Fd, "    {\n"),
1403		    emit(Fd, "      double oe_double;\n"),
1404		    emit(Fd, "      if ((oe_error_code = ei_decode_double(oe_env->_inbuf, &oe_env->_iin, &oe_double)) < 0) {\n"),
1405		    ?emit_c_dec_rpt(Fd, "        ", "float:ei_decode_double", []),
1406		    emit(Fd, "        return oe_error_code;\n      }\n"),
1407		    emit(Fd, "      oe_rec->_u.~s = (float) oe_double;\n",[ic_forms:get_id2(I)]),
1408		    emit(Fd, "    }\n");
1409		{double,_} ->
1410		    emit(Fd, "    if ((oe_error_code = ei_decode_double(oe_env->_inbuf, &oe_env->_iin, &oe_rec->_u.~s)) < 0) {\n",
1411			 [ic_forms:get_id2(I)]),
1412		    ?emit_c_dec_rpt(Fd, "      ", "dobule:ei_decode_double", []),
1413		    emit(Fd, "      return oe_error_code;\n    }\n");
1414		{boolean,_} ->
1415		    emit(Fd, "    {\n"),
1416		    emit(Fd, "      char oe_bool[25];\n\n"),
1417		    emit(Fd, "      if ((oe_error_code = ei_decode_atom(oe_env->_inbuf, &oe_env->_iin, oe_bool)) < 0) {\n"),
1418		    ?emit_c_dec_rpt(Fd, "        ", "boolean:ei_decode_atom", []),
1419		    emit(Fd, "        return oe_error_code;\n      }\n"),
1420		    emit(Fd, "      if (strcmp(oe_bool, \"false\") == 0) {\n"),
1421		    emit(Fd, "        oe_rec->_u.~s = 0;\n",[ic_forms:get_id2(I)]),
1422		    emit(Fd, "      } else if (strcmp(oe_bool, \"true\") == 0) {\n"),
1423		    emit(Fd, "        oe_rec->_u.~s = 1;\n",[ic_forms:get_id2(I)]),
1424		    emit(Fd, "      } else {\n"),
1425		    ?emit_c_dec_rpt(Fd, "        ", "boolean failure", []),
1426		    emit(Fd, "        return -1;\n  }\n"),
1427		    emit(Fd, "    }\n");
1428		{char,_} ->
1429		    emit(Fd, "    if ((oe_error_code = ei_decode_char(oe_env->_inbuf, &oe_env->_iin, &oe_rec->_u.~s)) < 0) {\n",
1430			 [ic_forms:get_id2(I)]),
1431		    ?emit_c_dec_rpt(Fd, "      ", "char:ei_decode_char", []),
1432		    emit(Fd, "      return oe_error_code;\n    }\n");
1433		{octet,_} ->
1434		    emit(Fd, "    if ((oe_error_code = ei_decode_char(oe_env->_inbuf, &oe_env->_iin, &oe_rec->_u.~s)) < 0) {\n",
1435			 [ic_forms:get_id2(I)]),
1436		    emit(Fd, "      return oe_error_code;\n    }\n");
1437		{string,_} ->
1438		    emit(Fd, "    {\n"),
1439		    emit(Fd, "      int oe_type = 0;\n"),
1440		    emit(Fd, "      int oe_string_ctr = 0;\n\n"),
1441
1442		    emit(Fd, "      (int) ei_get_type(oe_env->_inbuf, &oe_env->_iin, &oe_type, &oe_string_ctr);\n\n"),
1443
1444		    emit(Fd, "      oe_rec->_u.~s = (void *) (oe_first + *oe_index);\n\n",[ic_forms:get_id2(I)]),
1445
1446		    emit(Fd, "      if ((oe_error_code = ei_decode_string(oe_env->_inbuf, &oe_env->_iin, oe_rec->_u.~s)) < 0) {\n",
1447			 [ic_forms:get_id2(I)]),
1448		    ?emit_c_dec_rpt(Fd, "        ", "ei_decode_string", []),
1449		    emit(Fd, "        return oe_error_code;\n      }\n"),
1450
1451		    emit(Fd, "      *oe_index = ~s;\n",[ic_util:mk_align("*oe_index+oe_string_ctr+1")]),
1452		    emit(Fd, "    }\n");
1453		{sequence,_,_} ->
1454		    SeqName = ic_util:to_undersc([ic_forms:get_id2(I), ic_forms:get_id2(X) | N]),
1455		    emit(Fd, "    if ((oe_error_code = oe_decode_~s(oe_env, oe_first, oe_index, &oe_rec->_u.~s)) < 0) {\n",
1456			 [SeqName,ic_forms:get_id2(I)]),
1457		    ?emit_c_dec_rpt(Fd, "      ", "sequence:oe_decode_~s", [SeqName]),
1458		    emit(Fd, "      return oe_error_code;\n    }\n");
1459		{struct,SID,_,_} ->
1460		    StructName = ic_util:to_undersc([ic_forms:get_id2(SID), ic_forms:get_id2(X) | N]),
1461		    emit(Fd, "    if ((oe_error_code = oe_decode_~s(oe_env, oe_first, oe_index, &oe_rec->_u.~s)) < 0) {\n",
1462			 [StructName,ic_forms:get_id2(I)]),
1463		    ?emit_c_dec_rpt(Fd, "      ", "struct:oe_decode_~s", [StructName]),
1464		    emit(Fd, "      return oe_error_code;\n    }\n");
1465		{union,UID,_,_,_} ->
1466		    UnionName = ic_util:to_undersc([ic_forms:get_id2(UID), ic_forms:get_id2(X) | N]),
1467		    emit(Fd, "    if ((oe_error_code = oe_decode_~s(oe_env, oe_first, oe_index, &oe_rec->_u.~s)) < 0) {\n",
1468			 [UnionName,ic_forms:get_id2(I)]),
1469		    ?emit_c_dec_rpt(Fd, "      ", "union:oe_decode_~s", [UnionName]),
1470		    emit(Fd, "      return oe_error_code;\n    }");
1471		_ ->
1472		    ic_error:fatal_error(G, {illegal_typecode_for_c, T, N})
1473	    end
1474    end.
1475
1476mvDefaultToTail(CDclL) ->
1477    mvDefaultToTail(CDclL,[],[]).
1478
1479
1480mvDefaultToTail([], F, FD) ->
1481    lists:reverse(F) ++ FD;
1482mvDefaultToTail([{case_dcl,CaseList,I,T}|Rest], Found, FoundDefault) ->
1483    case lists:keysearch(default, 1, CaseList) of
1484	{value,Default} ->
1485	    NewCaseList = lists:delete(Default, CaseList) ++ [Default],
1486	    mvDefaultToTail(Rest, Found, [{case_dcl,NewCaseList,I,T}|FoundDefault]);
1487	false ->
1488	    mvDefaultToTail(Rest, [{case_dcl,CaseList,I,T}|Found], FoundDefault)
1489    end.
1490
1491
1492