ic_code.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 583 行 · 第 1/2 页

ERL
583
字号
%% ``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(ic_code).-include_lib("ic/src/ic.hrl").-include_lib("ic/src/icforms.hrl").%%-----------------------------------------------------------------%% External exports%%------------------------------------------------------------------export([get_basetype/2, insert_typedef/3, codeDirective/2]).-export([gen_includes/3, gen_includes/4, mk_list/1]).-export([type_expand_op/4, type_expand_handle_op/4]).-export([ type_expand_op_exec/4, type_expand_all/6, type_expand/7]).-export([type_expand_null/3, type_expand_void/3, type_expand_float/3, type_expand_double/3]).-export([type_expand_short/3, type_expand_ushort/3, type_expand_long/3, type_expand_ulong/3]).-export([type_expand_longlong/3, type_expand_ulonglong/3]).-export([type_expand_char/3, type_expand_wchar/3, type_expand_boolean/3]).-export([type_expand_octet/3, type_expand_any/3,  type_expand_wstring/3]).-export([type_expand_object/3, type_expand_string/3, type_expand_struct/7, type_expand_union/7]).-export([type_expand_enum/4, type_expand_sequence/7, type_expand_array/7, type_expand_error/3]).-export([type_expand_struct_rule/3, type_expand_union_rule/2, type_expand_enum_rule/4]).-export([type_expand_enum_elements/3, type_expand_longdouble/3, type_expand_typecode/3]).-export([type_expand_principal/3, type_expand_exception/7]).%%-----------------------------------------------------------------%% External functions%%-----------------------------------------------------------------%%-------------------------------------------------------------------------------------%%%% Trackrecording of generated sequence type structs, thist is just used for C today.%%%%-------------------------------------------------------------------------------------get_basetype(G, MyId) ->    case ?lookup(ic_genobj:typedeftab(G), MyId) of	[] ->	     MyId;	X ->	    get_basetype(G, X)    end.insert_typedef(_G, "erlang_term", _) ->    ok;insert_typedef(G, MyId, DefinedAsId) ->    ?insert(ic_genobj:typedeftab(G), MyId, DefinedAsId).codeDirective(G,X) ->    case produceCode(X) of        true ->            case ic_options:get_opt(G, be) of                c_genserv ->                    c;		c_client ->		    c;		c_server ->		    c_server;                _ ->                    erlang            end;        false ->            case ic_options:get_opt(G, be) of                              c_genserv ->                    c_no_stub;		c_client ->		    c_no_stub;		c_server ->		    c_server_no_stub;                _ ->                    erlang_no_stub            end    end.%% Checks if X should produce codeproduceCode(X) when record(X, module) ->    case ic_forms:get_body(X) of        [] ->            true;        List ->            produceModuleCode(List)    end;produceCode(_X) ->        false.    produceModuleCode([]) ->    false;produceModuleCode([X|_Xs]) when record(X, const) ->    true;produceModuleCode([_X|Xs]) ->    produceModuleCode(Xs). %% Includes needed c file headers for included idl filesgen_includes(Fd,G,Type) ->    case Type of	c_client ->	    IncludeList = 		ic_pragma:get_included_c_headers(G),	    gen_includes_loop(Fd,IncludeList,Type);	c_server ->	    IncludeList = 		ic_pragma:get_included_c_headers(G),	    gen_includes_loop(Fd,IncludeList,Type);	_ ->	    ok    end,    ic_codegen:nl(Fd),    ic_codegen:emit(Fd, "#ifdef __cplusplus\n"),    ic_codegen:emit(Fd, "extern \"C\" {\n"),    ic_codegen:emit(Fd, "#endif\n\n").%% Includes needed c file headers for local interfacesgen_includes(Fd,G,X,Type) ->    case Type of	c_client ->	    IncludeList = 		ic_pragma:get_local_c_headers(G,X),	    gen_includes_loop(Fd,IncludeList,Type);	c_server ->	    IncludeList = 		ic_pragma:get_local_c_headers(G,X),	    gen_includes_loop(Fd,IncludeList,Type);	_ ->	    ok    end,    ic_codegen:nl(Fd),    ic_codegen:emit(Fd, "#ifdef __cplusplus\n"),    ic_codegen:emit(Fd, "extern \"C\" {\n"),    ic_codegen:emit(Fd, "#endif\n\n").gen_includes_loop(_,[],_) ->    ok;gen_includes_loop(Fd,[I|Is],Type) ->    L = string:tokens(I,"/"),    File = lists:last(L),    case File of	"erlang" -> % Erlang is NOT generated that way !	    gen_includes_loop(Fd,Is,Type);	"oe_erlang" -> % Erlang is NOT generated that way !	    gen_includes_loop(Fd,Is,Type);	_ ->	    case Type of		c_client ->		    ic_codegen:emit(Fd, "#include \"~s.h\"\n", [File]);		c_server ->		    ic_codegen:emit(Fd, "#include \"~s__s.h\"\n", [File])	    end,	    gen_includes_loop(Fd,Is,Type)    end.%%%% Used in NOC only%%%%%% Type expand on function head comments%%type_expand_op(G,N,X,Fd) ->    case catch type_expand_op_exec(G,N,X,Fd) of	{'EXIT',_Reason} ->	    ic_codegen:nl(Fd),	    ic_codegen:emit(Fd,"%% Error under type expansion, does not affect generated code.~n",[]),	    ic_codegen:emit(Fd,"%%------------------------------------------------------------~n",[]);	_ ->	    ic_codegen:emit(Fd,"%%------------------------------------------------------------~n",[])    end.type_expand_op_exec(G,N,X,Fd) ->    InArgs = ic:filter_params([in,inout], X#op.params),    OutArgs = ic:filter_params([out,inout], X#op.params),    ParamNr = length(InArgs)+1,    Tabs = "",        ic_codegen:nl(Fd),    ic_codegen:emit(Fd,"%%------------------------------------------------------------~n",[]),     case ic_forms:is_oneway(X) of	false ->	    ic_codegen:emit(Fd,"%% Operation: ~s/~p~n",[ic_forms:get_id2(X),ParamNr]);	true ->	    ic_codegen:emit(Fd,"%% Operation: ~s/~p  (oneway)~n",[ic_forms:get_id2(X),ParamNr])    end,    if  X#op.raises == [] -> [];	true ->	    ic_codegen:emit(Fd,"%%~n",[]),	    RaisesList=["%% Raises: " ++ 			mk_list(lists:map(fun(E) -> ic_util:to_colon(E) end, 					  X#op.raises))],	    ic_codegen:emit(Fd,RaisesList,[]),	    ic_codegen:nl(Fd)    end,    %% Print argument names    ic_codegen:emit(Fd,"%%\n",[]),    InArgNames = ["OE_Ref"]++[ic_util:mk_var(ic_forms:get_id(InArg#param.id)) || InArg <- InArgs ],    OutArgNames = ["Ret"]++[ic_util:mk_var(ic_forms:get_id(OutArg#param.id)) || OutArg <- OutArgs ],    case length(InArgNames) > 1 of	true ->	    ic_codegen:emit(Fd,"%% Input value(s)  : ~s~n",[mk_list(InArgNames)]);	false ->	    ic_codegen:emit(Fd,"%% Input value     : ~s~n",[mk_list(InArgNames)])    end,    case length(OutArgNames) > 1 of	true ->	    ic_codegen:emit(Fd,"%% Return value(s) : ~s~n",[mk_list(OutArgNames)]);	false ->	    ic_codegen:emit(Fd,"%% Return value    : ~s~n",[mk_list(OutArgNames)])    end,    ic_codegen:emit(Fd,"%%\n",[]),    InArgsTypeList = 	[{ic_util:mk_var(ic_forms:get_id(InArg#param.id)),ic_forms:get_tk(InArg)} || InArg <- InArgs ],    case InArgsTypeList of	[] -> %% no input parameters	    ok;	_ ->	    ic_codegen:emit(Fd,"%%                                             --input-params-~n",[]),	    type_expand_all(G,N,X,Fd,Tabs,InArgsTypeList)    end,    ReturnTypeList =[{"Ret",X#op.tk}],    ic_codegen:emit(Fd,"%%                                             --return-value-~n",[]),    type_expand_all(G,N,X,Fd,Tabs,ReturnTypeList),    OutArgsTypeList = 	[{ic_util:mk_var(ic_forms:get_id(OutArg#param.id)),ic_forms:get_tk(OutArg)} || OutArg <- OutArgs ],     case OutArgsTypeList of	[] -> %% no input parameters	    ok;	_ ->	    ic_codegen:emit(Fd,"%%                                             -output-values-~n",[]),	    type_expand_all(G,N,X,Fd,Tabs,OutArgsTypeList)    end.type_expand_handle_op(G,N,X,Fd) ->    case catch type_expand_handle_op_exec(G,N,X,Fd) of	{'EXIT',_Reason} ->	    ic_codegen:nl(Fd),	    ic_codegen:emit(Fd,"%% Error under type expansion, does not affect generated code.~n",[]),	    ic_codegen:emit(Fd,"%%------------------------------------------------------------~n",[]);	_ ->	    ic_codegen:emit(Fd,"%%------------------------------------------------------------~n",[])    end.type_expand_handle_op_exec(_G,_N,X,Fd) ->    InArgs = ic:filter_params([in,inout], X#op.params),    ParamNr = length(InArgs)+1,        ic_codegen:nl(Fd),    ic_codegen:emit(Fd,"%%------------------------------------------------------------~n",[]),    case ic_forms:is_oneway(X) of	false ->	    ic_codegen:emit(Fd,"%% Handle operation: handle_call/3~n",[]);	true ->	    ic_codegen:emit(Fd,"%% Handle operation: handle_cast/3~n",[])    end,    ic_codegen:emit(Fd,"%%~n",[]),    ic_codegen:emit(Fd,"%% Used for operation ~s/~p implementation~n",[ic_forms:get_id2(X),ParamNr]).

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?