icunion.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,489 行 · 第 1/5 页
ERL
1,489 行
%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %% $Id$%%-module(icunion).-import(ic_codegen, [emit/2, emit/3, emit/4, emit_c_enc_rpt/4, emit_c_dec_rpt/4]).-import(ic_cbe, [mk_c_type/3, mk_c_type/4]).-include("icforms.hrl").-include("ic.hrl").%%-----------------------------------------------------------------%% External exports%%------------------------------------------------------------------export([union_gen/4]).%%-----------------------------------------------------------------%% Internal exports%%------------------------------------------------------------------export([]).union_gen(G, N, X, c) when record(X, union) -> emit_c_union(G, N, X);union_gen(_G, _N, _X, _L) -> ok.%% Emits the unionemit_c_union(G, N, X) -> %%io:format("Rec = ~p\n",[X]), case ic_genobj:is_hrlfile_open(G) of true -> %% Sort Union Default = put it last in case list NewX = #union{ id = X#union.id, type = X#union.type, body = mvDefaultToTail(X#union.body), tk = X#union.tk }, UnionScope = [ic_forms:get_id2(NewX) | N], case ic_pragma:is_local(G,UnionScope) of true -> HFd = ic_genobj:hrlfiled(G), emit_c_union_values(G, N, NewX, HFd), UnionName = ic_util:to_undersc(UnionScope), emit(HFd, "\n#ifndef __~s__\n",[ictype:to_uppercase(UnionName)]), emit(HFd, "#define __~s__\n",[ictype:to_uppercase(UnionName)]), ic_codegen:mcomment_light(HFd, [io_lib:format("Union definition: ~s", [UnionName])], c), emit(HFd, "typedef struct {\n"), emit(HFd, " ~s _d;\n", [get_c_union_discriminator(G, N, NewX)]), emit(HFd, " union {\n"), emit_c_union_values_decl(G, N, NewX, HFd), emit(HFd, " } _u;\n"), emit(HFd, "} ~s;\n\n", [UnionName]), emit(HFd, "int ~s~s(CORBA_Environment *oe_env, int*, int*);\n", [ic_util:mk_oe_name(G, "sizecalc_"), UnionName]), emit(HFd, "int ~s~s(CORBA_Environment *oe_env, ~s*);\n", [ic_util:mk_oe_name(G, "encode_"), UnionName, UnionName]), emit(HFd, "int ~s~s(CORBA_Environment *oe_env, char *, int*, ~s*);\n", [ic_util:mk_oe_name(G, "decode_"), UnionName, UnionName]), emit(HFd, "\n#endif\n\n"), create_c_union_file(G, N, NewX, UnionName); false -> %% Do not generate included types att all. ok end; false -> ok end.%% Loops over union members and creates members typedefsemit_c_union_values(G, N, X, Fd) -> emit_c_union_values_loop(G, N, X, Fd, X#union.body).emit_c_union_values_loop(G, N, X, Fd, [CU]) -> case CU of {case_dcl,_,Id,Type} -> case Id of {array, _AID, _SZ} -> % Check for arrays mk_array_file(G,N,X,Id,Type,Fd); _ -> % Elementary types or seq/struct ok end; _ -> error end;emit_c_union_values_loop(G, N, X, Fd, [CU |CUs]) -> case CU of {case_dcl,_,Id,Type} -> case Id of {array, _AID, _SZ} -> % Check for arrays mk_array_file(G,N,X,Id,Type,Fd); _ -> % Elementary types or seq/struct emit_c_union_values_loop(G, N, X, Fd, CUs) end; _ -> error end.%% Loops over union members and declares members inside union structureemit_c_union_values_decl(G, N, X, Fd) -> emit_c_union_values_decl_loop(G, N, X, Fd, X#union.body).emit_c_union_values_decl_loop(G, N, X, Fd, [CU]) -> case CU of {case_dcl,_,Id,Type} -> case Id of {array, _AID, _SZ} -> % Check for arrays mk_array_decl(G,N,X,Id,Type,Fd); _ -> % Elementary types or seq/struct mk_union_member_decl(G,N,X,Id,Type,Fd), ok end; _ -> error end;emit_c_union_values_decl_loop(G, N, X, Fd, [CU |CUs]) -> case CU of {case_dcl,_,Id,Type} -> case Id of {array, _AID, _SZ} -> % Check for arrays mk_array_decl(G,N,X,Id,Type,Fd), emit_c_union_values_decl_loop(G, N, X, Fd, CUs); _ -> % Elementary types or seq/struct mk_union_member_decl(G,N,X,Id,Type,Fd), emit_c_union_values_decl_loop(G, N, X, Fd, CUs) end; _ -> error end.%% Makes the declaration for the array in unionmk_array_decl(G,N,X,Id,Type,Fd) -> emit(Fd, " ~s ~s;\n", [getCaseTypeStr(G,N,X,Id,Type), mk_array_name(Id)]).mk_array_name({array,Id,D}) -> ic_forms:get_id2(Id) ++ mk_array_dim(D).mk_array_dim([]) -> "";mk_array_dim([{_,_,Dim}|Dims]) -> "[" ++ Dim ++ "]" ++ mk_array_dim(Dims).%% Creates the array file mk_array_file(G,N,X,{array,AID,SZ},Type,HFd) -> ArrayName = ic_util:to_undersc([ic_forms:get_id2(AID),ic_forms:get_id2(X) | N]), ArrayDim = extract_array_dim(SZ), emit(HFd, "\n#ifndef __~s__\n",[ictype:to_uppercase(ArrayName)]), emit(HFd, "#define __~s__\n\n",[ictype:to_uppercase(ArrayName)]), icstruct:create_c_array_coding_file(G, N, {ArrayName,ArrayDim}, Type, no_typedef), emit(HFd, "\n#endif\n\n").extract_array_dim([{_,_,Dim}]) -> [Dim];extract_array_dim([{_,_,Dim}|Dims]) -> [Dim | extract_array_dim(Dims)].%% Makes the declaration for the member in unionmk_union_member_decl(G,N,X,Id,Type,Fd) -> emit(Fd, " ~s ~s;\n", [getCaseTypeStr(G,N,X,Id,Type), ic_forms:get_id2(Id)]).%% File utilitiescreate_c_union_file(G, N, X, UnionName) -> {Fd , SName} = open_c_coding_file(G, UnionName), _HFd = ic_genobj:hrlfiled(G), %% Write on stubfile header HrlFName = filename:basename(ic_genobj:include_file(G)), ic_codegen:emit_stub_head(G, Fd, SName, c), emit(Fd, "#include \"~s\"\n\n",[HrlFName]), %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Fd = ic_genobj:stubfiled(G), %% Write on stubfile %% HFd = ic_genobj:hrlfiled(G), %% Write on stubfile header %% HrlFName = filename:basename(ic_genobj:include_file(G)), %% emit(Fd, "#include \"~s\"\n\n",[HrlFName]), %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% put(op_variable_count, 0), put(tmp_declarations, []), %% Write generated code on file emit_union_sizecount(G, N, X, Fd, UnionName), emit_union_encode(G, N, X, Fd, UnionName), emit_union_decode(G, N, X, Fd, UnionName), file:close(Fd).open_c_coding_file(G, Name) -> SName = string:concat(ic_util:mk_oe_name(G, "code_"), Name), FName = ic_file:join(ic_options:get_opt(G, stubdir),ic_file:add_dot_c(SName)), case file:rawopen(FName, {binary, write}) of {ok, Fd} -> {Fd, SName}; Other -> exit(Other) end.get_c_union_discriminator(G, N, X) -> case getDiscrStr(G, N, X#union.type) of error -> ic_error:fatal_error(G, {illegal_typecode_for_c, X#union.type, N}); DiscrStr -> case ic_code:get_basetype(G, DiscrStr) of {short, _} -> "CORBA_short"; {unsigned,{short, _}} -> "CORBA_unsigned_short"; {long, _} -> "CORBA_long"; {unsigned,{long, _}} -> "CORBA_unsigned_long"; {boolean,_} -> "CORBA_boolean"; {char,_} -> "CORBA_char"; {enum, EnumType} -> EnumType; _ -> DiscrStr end end.getDiscrStr(G, N, S) when element(1, S) == scoped_id -> case ic_symtab:get_full_scoped_name(G, N, S) of {FSN, _, tk_short, _} -> ic_util:to_undersc(FSN); {FSN, _, tk_ushort, _} -> ic_util:to_undersc(FSN); {FSN, _, tk_long, _} -> ic_util:to_undersc(FSN); {FSN, _, tk_ulong, _} -> ic_util:to_undersc(FSN); {FSN, _, tk_boolean, _} -> ic_util:to_undersc(FSN); {FSN, _, tk_char, _} -> ic_util:to_undersc(FSN); {FSN, _, {tk_enum,_,_,_}, _} -> ic_util:to_undersc(FSN); _ -> error end;getDiscrStr(_G, N, X) -> case X of {short,_} -> "CORBA_short"; {unsigned,{short,_}} -> "CORBA_unsigned_short"; {long, _} -> "CORBA_long"; {unsigned,{long,_}} -> "CORBA_unsigned_long"; {boolean,_} -> "CORBA_boolean"; {char,_} -> "CORBA_char";
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?