ictk.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 872 行 · 第 1/2 页
ERL
872 行
%% ``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(ictk).%% Toplevel generation functions-export([reg_gen/3, unreg_gen/3]).%% Utilities-export([get_IR_ID/3, get_IR_VSN/3, register_name/1, unregister_name/1]).-import(ic_forms, [get_id2/1, get_body/1, get_idlist/1]).-import(ic_util, [mk_name/2, mk_oe_name/2, to_atom/1, to_list/1]).-import(ic_codegen, [emit/2, emit/3, nl/1]).-include("icforms.hrl").-include("ic.hrl").%%--------------------------------------------------------------------%%%% IFR Registration Generation%%%%%%---------------------------------------------------------------------define(IFRID(G), mk_name(G, "IFR")).-define(VARID(G), mk_name(G, "VAR")).-define(IFRMOD, orber_ifr).reg_gen(G, N, X) -> S = ic_genobj:tktab(G), Light = ic_options:get_opt(G, light_ifr), init_var(), case ic_genobj:is_stubfile_open(G) of true when Light == false -> Var = ?IFRID(G), Fd = ic_genobj:stubfiled(G), nl(Fd), nl(Fd), nl(Fd), emit(Fd, "~p() ->\n", [to_atom(register_name(G))]), emit(Fd, " ~s = ~p:find_repository(),\n", [Var, ?IFRMOD]), nl(Fd), %% Write call function that checks if included %% modules and interfaces are created. emit(Fd, " register_tests(~s),\n",[?IFRID(G)]), reg2(G, S, N, Var, X), nl(Fd), emit(Fd, " ok.\n"), %% Write general register test function. register_tests(Fd,G), %% Write functopn that registers modules only if %% they are not registered. register_if_unregistered(Fd); true when Light == true -> Fd = ic_genobj:stubfiled(G), nl(Fd), nl(Fd), nl(Fd), Regname = to_atom(register_name(G)), emit(Fd, "~p() ->\n\t~p([]).\n\n", [Regname, Regname]), emit(Fd, "~p(OE_Options) ->\n\t~p:add_items(?MODULE, OE_Options,\n\t[", [Regname, ?IFRMOD]), reg_light(G, N, X), emit(Fd, "ok]),\n\tok.\n"); false -> ok end.reg_light(G, N, X) when list(X) -> reg_light_list(G, N, X);reg_light(G, N, X) when record(X, module) -> reg_light_list(G, [get_id2(X) | N], get_body(X));reg_light(G, N, X) when record(X, struct) -> emit(ic_genobj:stubfiled(G), "{~p, ~p, struct},\n\t", [get_IR_ID(G, N, X), get_module(X, N)]);reg_light(G, N, X) when record(X, except) -> emit(ic_genobj:stubfiled(G), "{~p, ~p, except},\n\t", [get_IR_ID(G, N, X), get_module(X, N)]);reg_light(G, N, X) when record(X, union) -> emit(ic_genobj:stubfiled(G), "{~p, ~p, union},\n\t", [get_IR_ID(G, N, X), get_module(X, N)]);reg_light(G, N, X) when record(X, interface) -> emit(ic_genobj:stubfiled(G), "{~p, ~p, interface},\n\t", [get_IR_ID(G, N, X), get_module(X, N)]), reg_light_list(G, [get_id2(X)|N], get_body(X));reg_light(_G, _N, _X) -> ok.get_module(X, N) -> List = [get_id2(X) | N], list_to_atom(lists:foldl(fun(E, Acc) -> E++"_"++Acc end, hd(List), tl(List))).%% This function filters off all "#include <FileName>.idl" code that %% come along from preprocessor and scanner. Produces code ONLY for%% the actuall file. See ticket OTP-2133reg_light_list(_G, _N, []) -> [];reg_light_list(G, N, List ) -> CurrentFileName = ic_genobj:idlfile(G), reg_light_list(G, N, {CurrentFileName,true}, List).%% The filter function + loop reg_light_list(_G, _N, {_CFN, _Status}, []) -> [];reg_light_list(G, N, {CFN,Status}, [X | Xs]) -> case Status of true -> case X of {preproc,_,{_,_,_FileName},[{_,_,"1"}]} -> reg_light_list(G, N, {CFN,false}, Xs); _ -> reg_light(G, N, X), reg_light_list(G, N, {CFN,Status}, Xs) end; false -> case X of {preproc,_,{_,_,CFN},[{_,_,"2"}]} -> reg_light(G, N, X), reg_light_list(G, N, {CFN,true}, Xs); _ -> reg_light_list(G, N, {CFN,Status}, Xs) end end.%% reg2 is top level registration reg2(G, S, N, Var, X) -> reg2(G, S, N, "Repository_create_", Var, X).reg2(G, S, N, C, V, X) when list(X) -> reg2_list(G, S, N, C, V, X);reg2(G, S, N, C, V, X) when record(X, module) -> NewV = r_emit2(G, S, N, C, V, X, "", []), reg2_list(G, S, [get_id2(X) | N], "ModuleDef_create_", NewV, get_body(X));reg2(G, S, N, C, V, X) when record(X, const) -> r_emit2(G, S, N, C, V, X, ", ~s, ~p", [get_idltype(G, S, N, X), {X#const.tk, X#const.val}]);reg2(G, S, N, C, V, X) when record(X, struct) -> do_struct(G, S, N, C, V, X, ic_forms:get_tk(X));reg2(G, S, N, C, V, X) when record(X, except) -> do_except(G, S, N, C, V, X, ic_forms:get_tk(X));reg2(G, S, N, C, V, X) when record(X, union) -> do_union(G, S, N, C, V, X, ic_forms:get_tk(X));reg2(G, S, N, C, V, X) when record(X, enum) -> r_emit2(G, S, N, C, V, X, ", ~p", [get_enum_member_list(G, S, N, get_body(X))]);reg2(G, S, N, C, V, X) when record(X, typedef) -> do_typedef(G, S, N, C, V, X), look_for_types(G, S, N, C, V, get_body(X));reg2(G, S, N, C, V, X) when record(X, attr) -> XX = #id_of{type=X}, lists:foreach(fun(Id) -> r_emit2(G, S, N, C, V, XX#id_of{id=Id}, ", ~s, ~p", [get_idltype(G, S, N, X), get_mode(G, N, X)]) end, get_idlist(X));reg2(G, S, N, C, V, X) when record(X, interface) -> N2 = [get_id2(X) | N], Body = get_body(X), BIs = get_base_interfaces(G,X), %% produce code for the interface inheritance NewV = r_emit2(G, S, N, C, V, X, ", " ++ BIs,[]), reg2_list(G, S, N2, "InterfaceDef_create_", NewV, Body);reg2(G, S, N, C, V, X) when record(X, op) -> r_emit2(G, S, N, C, V, X, ", ~s, ~p, [~s], [~s], ~p", [get_idltype(G, S, N, X), get_mode(G, N, X), get_params(G, S, N, X#op.params), get_exceptions(G, S, N, X), get_context(G, S, N, X)]);reg2(_G, _S, _N, _C, _V, X) when record(X, preproc) -> ok;reg2(_G, _S, _N, _C, _V, X) when record(X, pragma) -> ok;reg2(_G, _S, _N, _C, _V, _X) -> ok.%% This function filters off all "#include <FileName>.idl" code that %% come along from preprocessor and scanner. Produces code ONLY for%% the actuall file. See ticket OTP-2133reg2_list(_G, _S, _N, _C, _V, []) -> [];reg2_list(G, S, N, C, V, List ) -> CurrentFileName = ic_genobj:idlfile(G), reg2_list(G, S, N, C, V, {CurrentFileName,true}, List).%% The filter function + loop reg2_list(_G, _S, _N, _C, _V, {_CFN, _Status}, []) -> [];reg2_list(G, S, N, C, V, {CFN,Status}, [X | Xs]) -> case Status of true -> case X of {preproc,_,{_,_,_FileName},[{_,_,"1"}]} -> reg2_list(G, S, N, C, V, {CFN,false}, Xs); _ -> F = reg2(G, S, N, C, V, X), [F | reg2_list(G, S, N, C, V, {CFN,Status}, Xs)] end; false -> case X of {preproc,_,{_,_,CFN},[{_,_,"2"}]} -> F = reg2(G, S, N, C, V, X), [F | reg2_list(G, S, N, C, V, {CFN,true}, Xs)]; _ -> reg2_list(G, S, N, C, V, {CFN,Status}, Xs) end end.%% General registration testsregister_tests(Fd,G) -> IfrId = ?IFRID(G), emit(Fd,"\n\n%% General IFR registration checks.\n", []), emit(Fd,"register_tests(~s)->\n",[IfrId]), emit(Fd," re_register_test(~s),\n",[IfrId]), emit(Fd," include_reg_test(~s).\n\n",[IfrId]), emit(Fd,"\n%% IFR type Re-registration checks.\n", []), case ic_pragma:fetchRandomLocalType(G) of {ok,TypeId} -> emit(Fd,"re_register_test(~s)->\n",[IfrId]), emit(Fd," case orber_ifr:'Repository_lookup_id'(~s,~p) of\n", [IfrId,TypeId]), emit(Fd," [] ->\n true;\n",[]), emit(Fd," _ ->\n exit({allready_registered,~p})\n end.\n\n", [TypeId]); false -> emit(Fd,"re_register_test(_)-> true.\n",[]) end, emit(Fd,"~s",[check_include_regs(G)]).%% This function produces code for existance check over%% top level included modules and interfacescheck_include_regs(G) -> IfrId = ?IFRID(G), case ic_pragma:get_incl_refs(G) of none -> io_lib:format("\n%% No included idl-files detected.\n", []) ++ io_lib:format("include_reg_test(_~s) -> true.\n",[IfrId]); IMs -> io_lib:format("\n%% IFR registration checks for included idl files.\n", []) ++ io_lib:format("include_reg_test(~s) ->\n",[IfrId]) ++ check_incl_refs(G,IfrId,IMs) end.check_incl_refs(_,_,[]) -> io_lib:format(" true.\n",[]);check_incl_refs(G,IfrId,[[First]|Rest]) -> ModId = ic_pragma:scope2id(G,First), io_lib:format(" case orber_ifr:'Repository_lookup_id'(~s,~p) of~n", [IfrId,ModId]) ++ io_lib:format(" [] ->~n exit({unregistered,~p});~n", [ModId]) ++ io_lib:format(" _ ->~n true~n end,~n",[]) ++ check_incl_refs(G,IfrId,Rest).%% This function will return module ref, it will%% also register module if not registered.register_if_unregistered(Fd) -> emit(Fd, "\n\n%% Fetch top module reference, register if unregistered.\n"), emit(Fd, "oe_get_top_module(OE_IFR, ID, Name, Version) ->\n"), emit(Fd, " case orber_ifr:'Repository_lookup_id'(OE_IFR, ID) of\n"), emit(Fd, " [] ->\n"), emit(Fd, " orber_ifr:'Repository_create_module'(OE_IFR, ID, Name, Version);\n"), emit(Fd, " Mod ->\n"), emit(Fd, " Mod\n",[]), emit(Fd, " end.\n\n"), emit(Fd, "%% Fetch module reference, register if unregistered.\n"), emit(Fd, "oe_get_module(OE_IFR, OE_Parent, ID, Name, Version) ->\n"), emit(Fd, " case orber_ifr:'Repository_lookup_id'(OE_IFR, ID) of\n"), emit(Fd, " [] ->\n"), emit(Fd, " orber_ifr:'ModuleDef_create_module'(OE_Parent, ID, Name, Version);\n"), emit(Fd, " Mod ->\n"), emit(Fd, " Mod\n",[]), emit(Fd, " end.\n").do_typedef(G, S, N, C, V, X) -> case ic_genobj:is_stubfile_open(G) of false -> ok; true -> Fd = ic_genobj:stubfiled(G), Thing = get_thing_name(X), IR_VSN = get_IR_VSN(G, N, X), TK = ic_forms:get_tk(X), lists:foreach( fun(Id) -> r_emit_raw(G, X, Fd, "", C, Thing, V, get_IR_ID(G, N, Id), get_id2(Id), IR_VSN, ", ~s", [get_idltype_tk(G, S, N, ictype:maybe_array(G, S, N, Id, TK))]) end, get_idlist(X)) end.do_union(G, S, N, C, V, X, {tk_union, _IFRID, _Name, DiscrTK, _DefNr, L}) -> N2 = [get_id2(X) | N], r_emit2(G, S, N, C, V, X, ", ~s, [~s]", [get_idltype_tk(G, S, N, DiscrTK), get_union_member_def(G, S, N2, L)]), look_for_types(G, S, N2, C, V, get_body(X)).do_struct(G, S, N, C, V, X, {tk_struct, _IFRID, _Name, ElemList}) -> N2 = [get_id2(X) | N], r_emit2(G, S, N, C, V, X, ", [~s]", [get_member_def(G, S, N, ElemList)]), look_for_types(G, S, N2, C, V, get_body(X)).do_except(G, S, N, C, V, X, {tk_except, _IFRID, _Name, ElemList}) -> N2 = [get_id2(X) | N], r_emit2(G, S, N, C, V, X, ", [~s]", [get_member_def(G, S, N, ElemList)]), look_for_types(G, S, N2, C, V, get_body(X)).%% new_var finds an unused Erlang variable name by increasing a%% counter.new_var(_G) -> lists:flatten(["_OE_", integer_to_list(put(var_count, get(var_count) + 1))]).init_var() -> put(var_count, 1).%% Public interface. The name of the register function.register_name(G) -> mk_oe_name(G, "register").unregister_name(G) -> mk_oe_name(G, "unregister").look_for_types(G, S, N, C, V, L) when list(L) -> lists:foreach(fun(X) -> look_for_types(G, S, N, C, V, X) end, L);look_for_types(G, S, N, C, V, {_Name, TK}) -> % member look_for_types(G, S, N, C, V, TK);look_for_types(_G, _S, _N, _C, _V, {tk_union, _IFRID, _Name, _DT, _Def, _L}) -> ok;look_for_types(G, S, N, C, V, {_Label, _Name, TK}) -> % case_dcl look_for_types(G, S, N, C, V, TK);look_for_types(_G, _S, _N, _C, _V, {tk_struct, _IFRID, _Name, _L}) -> ok;look_for_types(_G, _S, _N, _C, _V, _X) -> ok. %% This function produces code for the interface inheritance registration.%% It produces a string that represents a list of function calls.%% This list becomes a list of object references when the main function%% "orber_ifr:ModuleDef_create_interface" is called.get_base_interfaces(G,X) -> case element(3,X) of [] -> "[]"; L -> "[" ++ lists:flatten( lists:foldl( fun(E, Acc) -> [call_fun_str(G,E), ", " | Acc] end, call_fun_str(G,hd(L)), tl(L) ) ) ++ "]" end.call_fun_str(G,S) -> lists:flatten( io_lib:format("orber_ifr:lookup_id(~s,\"~s\")", [ ?IFRID(G), ic_pragma:scope2id(G,S)] )).%%--------------------------------------------------------------------%%%% r_emit emits an IFR register function call. It returns a new%% variable (if further defs should be added to that one)%%%% G is genobj%%%% S is symbol table (ets)%%%% N is list of ids describing scope%%%% C is create stub (eg. "Repository_create_")%%%% V is variable name where current def should be added,%%%% X is the current def item,%%%% F and A is auxillary format and args that will be io_lib%% formatted and inserted as a string (don't forget to start with%% ", ")%%r_emit2(G, _S, N, C, V, X, F, A) -> case ic_genobj:is_stubfile_open(G) of false -> ok; true ->
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?