ictype.erl

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

ERL
1,412
字号
check_switch_tk(_G, _S, _N, _X, tk_longlong) -> true; %% LLONGcheck_switch_tk(_G, _S, _N, _X, tk_short) -> true;check_switch_tk(_G, _S, _N, _X, tk_ushort) -> true;check_switch_tk(_G, _S, _N, _X, tk_ulong) -> true;check_switch_tk(_G, _S, _N, _X, tk_ulonglong) -> true;  %% ULLONGcheck_switch_tk(_G, _S, _N, _X, tk_boolean) -> true;check_switch_tk(_G, _S, _N, _X, tk_char) -> true;check_switch_tk(_G, _S, _N, _X, tk_wchar) -> true;  %% WCHARcheck_switch_tk(_G, _S, _N, _X, TK) when element(1, TK) == tk_enum -> true;check_switch_tk(G, _S, _N, X, TK) -> ic_error:error(G, {illegal_switch_t, X, TK}),				     false.%% Lookup a namename_lookup(G, S, N, X) ->    case scoped_lookup(G, S, N, X) of	T when tuple(T) -> element(1, T)    end.lookup(G, S, N, X, Id) ->    N2 = Id ++ N,    ?DBG("  Trying ~p ...~n", [N2]),    case ets:lookup(S, N2) of	[] ->	    	    case look_for_interface(G, S, [hd(N2)], tl(N2)) of		%% First attempt: filtering inherited members !		[{_, member, _, _}] ->	    		    case look_for_interface(G, S, [hd(N)], tl(N2)) of			[T] -> 			    ?DBG("    --  found ~p~n", [T]), 			    T;			_ ->			    lookup(G, S, tl(N), X, Id)		    end;		%%		[T] -> 		    ?DBG("    --  found ~p~n", [T]), 		    T;		_ ->		    if  N == [] -> 			    ic_error:error(G, {tk_not_found, X});			true ->			    lookup(G, S, tl(N), X, Id)		    end	    end;	%% Second attempt: filtering members !	[{_, member, _, _}] ->	    	    case look_for_interface(G, S, [hd(N2)], tl(N2)) of		[T] -> 		    ?DBG("    --  found ~p~n", [T]), 		    T;		_ ->		    if  N == [] -> 			    ic_error:error(G, {tk_not_found, X});			true ->			    lookup(G, S, tl(N), X, Id)		    end	    end;	%%	[T] -> 	    ?DBG("    --  found ~p~n", [T]),	    T    end.look_for_interface(_G, _S, _Hd, []) ->     false;look_for_interface(G, S, Hd, Tl) ->    case ets:lookup(S, Tl) of	[{_, interface, _TK, Inh}] -> 	    case look_in_inherit(G, S, Hd, Inh) of		%% gather_inherit(G, S, Inh, [])) of		[X] when tuple(X) -> 		    [X];		_ -> 		    look_for_interface(G, S, Hd ++ [hd(Tl)], tl(Tl))	    end;	_ -> 	    look_for_interface(G, S, Hd ++ [hd(Tl)], tl(Tl))    end.look_in_inherit(G, S, Id, [I | Is]) ->    case ets:lookup(S, Id ++ I) of	[X] when tuple(X) -> 	    [X];	[] ->  	    look_in_inherit(G, S, Id, Is)    end;look_in_inherit(_G, _S, _Id, []) ->     false.%% L is a list of namesmk_uppercase(L) ->    lists:map(fun(Z) -> lists:map(fun(X) when X>=$a, X=<$z -> X-$a+$A;				     (X) -> X end, Z) end, L).%%--------------------------------------------------------------------%%%% Inheritance stuff%%%%%%--------------------------------------------------------------------%% InhBody is an accumulating parametercalc_inherit_body(G, N, OrigBody, [X|Xs], InhBody) ->    case ic_symtab:retrieve(G, X) of	Intf when record(Intf, interface) ->	    Body = filter_body(G, X, ic_forms:get_body(Intf), N, OrigBody, InhBody),	    calc_inherit_body(G, N, OrigBody, Xs, [{X, Body} | InhBody]);	XXX ->	    io:format("Oops, not found ~p~n", [XXX]),	    calc_inherit_body(G, N, OrigBody, Xs, InhBody)    end;calc_inherit_body(_G, _N, _OrigBody, [], InhBody) -> lists:reverse(InhBody).filter_body(G, XPath, [X | Xs], OrigPath, OrigBody, InhBody) ->    case complex_body_member(G, XPath, X, OrigPath, OrigBody, InhBody) of	true -> 	    %%io:format("NOT adding ~p~n", [ic_forms:get_id2(X)]),	    filter_body(G, XPath, Xs, OrigPath, OrigBody, InhBody);	{false, NewX} ->			% For those with idlist	    %%io:format("Adding from idlist~n", []),	    [NewX | filter_body(G, XPath, Xs, OrigPath, OrigBody, InhBody)];	false ->	    %%io:format("Adding: ~p~n", [ic_forms:get_id2(X)]),	    [X | filter_body(G, XPath, Xs, OrigPath, OrigBody, InhBody)]    end;filter_body(_G, _XPath, [], _OrigPath, _OrigBody, _InhBody) -> [].complex_body_member(G, XPath, X, OrigPath, OrigBody, InhBody) ->    case has_idlist(X) of	true ->	    idlist_member(G, XPath, X, OrigPath, OrigBody, InhBody);	false ->	    straight_member(G, XPath, X, OrigPath, OrigBody, InhBody)    end.idlist_member(G, XPath, X, OrigPath, OrigBody, InhBody) ->        XX = #id_of{type=X},    F = fun(Id) ->		not(straight_member(G, XPath, XX#id_of{id=Id}, OrigPath,				    OrigBody, InhBody))	end,    case lists:filter(F, ic_forms:get_idlist(X)) of	[] -> 	    true;	IdList ->%%%	    io:format("Idlist added: ~p~n",[IdList]),	    {false, replace_idlist(X, IdList)}    end.straight_member(G, XPath, X, OrigPath, OrigBody, InhBody) ->    %%io:format("straight member: ~p~n", [ic_forms:get_id2(X)]),    case body_member(G, XPath, X, OrigPath, OrigBody) of	true ->	    true;	false -> 	    inh_body_member(G, XPath, X, InhBody)    end.inh_body_member(G, XPath, X, [{Name, Body} | InhBody]) ->    case body_member(G, XPath, X, Name, Body) of	true ->	    true;	false -> 	    inh_body_member(G, XPath, X, InhBody)    end;inh_body_member(_G, _XPath, _X, []) -> false.body_member(G, XPath, X, YPath, [Y|Ys]) ->    case has_idlist(Y) of	true -> 	    YY = #id_of{type=Y},	    case list_and(fun(Y2) -> 				  not(is_equal(G, XPath, X, YPath, 					       YY#id_of{id=Y2})) end,			  ic_forms:get_idlist(Y)) of		true -> 		    body_member(G, XPath, X, YPath, Ys);		false ->		    true	    end;	false ->	    case is_equal(G, XPath, X, YPath, Y) of		false ->		    body_member(G, XPath, X, YPath, Ys);		true ->		    true	    end    end;body_member(_G, _XPath, _X, _YPath, []) -> false.is_equal(G, XPath, X, YPath, Y) ->    case {ic_forms:get_id2(X), ic_forms:get_id2(Y)} of	{ID, ID} ->	    collision(G, XPath, X, YPath, Y),	    true;	_ -> 	    false    end.%% X is the new item, Y is the old one. So it is X that collides with%% Y and Y shadows X.collision(G, XPath, X, YPath, Y) ->    I1 = get_beef(X),						%    I2 = get_beef(Y),    if record(I1, op) -> %%, record(I2, op) ->	    ic_error:error(G, {inherit_name_collision, 			       {YPath, Y}, {XPath, X}});       record(I1, attr) -> %%, record(I2, attr) ->	    ic_error:error(G, {inherit_name_collision, 			       {YPath, Y}, {XPath, X}});       true ->	    ?ifopt(G, warn_name_shadow, 		   ic_error:warn(G, {inherit_name_shadow, 				     {YPath, Y}, {XPath, X}}))    end.has_idlist(X) when record(X, typedef) -> true;has_idlist(X) when record(X, member) -> true;has_idlist(X) when record(X, case_dcl) -> true;has_idlist(X) when record(X, attr) -> true;has_idlist(_) -> false.replace_idlist(X, IdList) when record(X, typedef) -> X#typedef{id=IdList};replace_idlist(X, IdList) when record(X, attr) -> X#attr{id=IdList}.get_beef(X) when record(X, id_of) -> X#id_of.type;get_beef(X) -> X.%% And among all elements in listlist_and(F, [X|Xs]) ->    case F(X) of	true -> list_and(F, Xs);	false -> false    end;list_and(_F, []) -> true.%%--------------------------------------------------------------------%%%%	resolve_inherit shall return a list of resolved inheritances,%%	that is all names replaced with their global names.%%inherit_resolve(G, S, N, [X|Rest], Out) ->    case scoped_lookup(G, S, N, X) of	{Name, _T, _TK, Inh} ->	    case lists:member(Name, Out) of		true -> 		    inherit_resolve(G, S, N, Rest, Out);		false ->		    case unique_append(Inh, [Name|Out]) of			error ->			    ic_error:error(G, {inherit_resolve, X, Name}),			    inherit_resolve(G, S, N, Rest, []);			UA ->			    inherit_resolve(G, S, N, Rest, UA)		    end	    end;	_ -> inherit_resolve(G, S, N, Rest, Out)    end;inherit_resolve(_G, _S, _N, [], Out) -> lists:reverse(Out).unique_append([X|Xs], L) ->    case lists:member(X, L) of	true -> unique_append(Xs, L);	false -> unique_append(Xs, [X|L])    end;unique_append([], L) -> L;%% Error unique_append(_, _L) -> error.%%--------------------------------------------------------------------%%%%	Utilities%%%% Must preserve order, therefore had to write my own (instead of lists:map)check_list(G, S, N, [X|Xs]) ->    X1 = check(G, S, N, X),    [X1 | check_list(G, S, N, Xs)];check_list(_G, _S, _N, []) -> [].filter( [] ) ->    error;filter( [I | Is ] ) ->    case I of	{ _, member, { _, TKINFO }, _ } ->	    fetchType( TKINFO );        { _, struct, _, _ } ->	    struct;	{ _, typedef, TKINFO, _ } ->	    fetchType( TKINFO );	{ _, module, _, _ } ->	    module;	{ _, interface, _, _ } ->	    interface;	{ _, op, _, _ } ->	    op;	{ _,enum, _, _ } ->	    enum;	{ _, spellcheck } ->	    filter( Is );	_ ->	    error    end.fetchType( { tk_sequence, _, _ } ) ->    sequence;fetchType( { tk_array, _, _ } ) ->    array;fetchType( { tk_struct, _, _, _} ) ->    struct;fetchType( { tk_string, _} ) ->    string;fetchType( { tk_wstring, _} ) ->  %% WSTRING    wstring;fetchType( { tk_fixed, _, _} ) ->    fixed;fetchType( tk_short ) ->    short;fetchType( tk_long ) ->    long;fetchType( tk_longlong ) ->  %% LLONG    longlong;fetchType( tk_ushort ) ->    ushort;fetchType( tk_ulong ) ->    ulong;fetchType( tk_ulonglong ) ->  %% ULLONG    ulonglong;fetchType( tk_float ) ->    float;fetchType( tk_double ) ->    double;fetchType( tk_boolean ) ->    boolean;fetchType( tk_char ) ->    char;fetchType( tk_wchar ) ->  %% WCHAR    wchar;fetchType( tk_octet ) ->    octet;fetchType( { tk_enum, _, _, _ } ) ->    enum;fetchType( { tk_union, _, _, _, _, _ } ) ->    union;fetchType( tk_any ) ->    any;fetchType( _ ) ->    error.%% Z is a single nameto_uppercase(Z) ->    lists:map(fun(X) when X>=$a, X=<$z -> X-$a+$A;		 (X) -> X end, Z).%%------------------------------------------------------------%%%% Always fetchs TK of a record.%%%%------------------------------------------------------------fetchTk(G,N,X) ->    case ic_forms:get_tk(X) of        undefined ->            searchTk(G,ictk:get_IR_ID(G, N, X));        TK ->            TK    end.%%------------------------------------------------------------%%%% seek type code when not accessible by get_tk/1%%%%------------------------------------------------------------searchTk(G,IR_ID) ->    S = ic_genobj:tktab(G),    case catch searchTk(S,IR_ID,typedef) of        {value,TK} ->            TK;        _ -> %% false / exit            case catch searchTk(S,IR_ID,struct) of                {value,TK} ->                    TK;                _  ->  %% false / exit                    case catch searchTk(S,IR_ID,union) of                        {value,TK} ->                            TK;                        _ ->                            undefined                    end            end    end.searchTk(S,IR_ID,Type) ->    L = lists:flatten(ets:match(S,{'_',Type,'$1','_'})),    case lists:keysearch(IR_ID,2,L) of        {value,TK} ->            {value,TK};        false ->            searchInsideTks(L,IR_ID)    end.searchInsideTks([],_IR_ID) ->    false;searchInsideTks([{tk_array,TK,_}|Xs],IR_ID) ->    case searchIncludedTk(TK,IR_ID) of        {value,TK} ->            {value,TK};        false ->            searchInsideTks(Xs,IR_ID)    end.searchIncludedTk({tk_array,TK,_},IR_ID) ->    searchIncludedTk(TK,IR_ID);searchIncludedTk({tk_sequence,TK,_},IR_ID) ->    searchIncludedTk(TK,IR_ID);searchIncludedTk(TK, _IR_ID) when atom(TK) ->    false;searchIncludedTk(TK,IR_ID) ->    case element(2,TK) == IR_ID of        true ->            {value,TK};        false ->            false    end.        

⌨️ 快捷键说明

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