ic_pragma.erl

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

ERL
1,956
字号
%% Finds out which pragma PREFIX that affects %% the scope Scopepragma_prefix(G,Scope,Object) ->    pragma_prefix_cover(ic_genobj:pragmatab(G),get_id2(Object),Scope,get_line(Object)).%% Finds out which pragma PREFIX that affects %% the scope Scopepragma_prefix_cover(PragmaTab,Name,Scope,LineNr) ->    case lookup(PragmaTab,prefix) of	[] ->	    none;	PragmaPrefixList ->	    FilteredPragmaPrefixList = 		filter_pragma_prefix_list(PragmaTab,Name,Scope,PragmaPrefixList),	    case most_local(FilteredPragmaPrefixList,Scope) of		[] ->		    none;		MostLocalList ->	    		    case dominant_prefix(MostLocalList,LineNr) of			none ->			    none;			%% Just filter empty pragma prefix			{prefix,{pragma,{_,_,_},_,{'<string_literal>',_,[]}},_,_,_,_} ->			    none;			DP ->			    %% Return the scoped id (reversed list of                            %% path elements, but remember to remove                             %% '[]' that represents the top level   			    slashify(lists:sublist(Scope, 1,						   length(Scope) - length(element(4,DP))) ++				     [ element(3,element(4,element(2,DP)))])		    end	    end    end.%% Returns a slashified name, [I1, M1] becomes "M1/I1"slashify(List) -> lists:foldl(fun(X, Acc) -> X++"/"++Acc end, 			      hd(List), tl(List)).%% Finds out which pragma VERSION that affects %% the scope Scopepragma_version(G,Scope,Object) ->    pragma_version_cover(ic_genobj:pragmatab(G),get_id2(Object),Scope,get_line(Object)).%% Finds out which pragma VERSION that affects %% the scope Scopepragma_version_cover(PragmaTab,Name,Scope,LineNr) ->    case lookup(PragmaTab,version) of	[] ->	    default_version();	PragmaVersionList ->	    case all_actual_for_version_or_id( PragmaVersionList, Name ) of		[] ->		    default_version();		ActualVersionList ->		    case most_local(ActualVersionList,Scope) of			[] ->			    default_version();			MostLocalList ->			    case dominant_version(MostLocalList,LineNr) of				DV ->				    element(4,element(2,DV))			    end		    end	    end    end.default_version() -> "1.0".    %% Finds out which pragma ID that affects %% the scope Scopepragma_id(G,Scope,Object) ->    pragma_id_cover(ic_genobj:pragmatab(G),get_id2(Object),Scope,get_line(Object)).%% Finds out which pragma ID that affects %% the scope Scopepragma_id_cover(PragmaTab,Name,Scope,LineNr) ->    case lookup(PragmaTab,id) of	[] ->	    none;	PragmaIdList ->	    case all_actual_for_version_or_id( PragmaIdList, Name ) of		[] ->		    none;		ActualIdList ->		    case most_local(ActualIdList,Scope) of			[] ->			    none;			MostLocalList ->	    			    case dominant_id(MostLocalList,LineNr) of				PI ->				    element(3,element(4,element(2,PI)))			    end		    end	    end    end.    %% Finds out which pragma VERSION ( or ID ) that %% that affects the scope object with name NAMEall_actual_for_version_or_id(NList, Name) ->    all_actual_for_version_or_id( NList, [], Name ).all_actual_for_version_or_id([], Actual, _) ->    Actual;all_actual_for_version_or_id([First|Rest], Found, Name) ->    case is_actual_for_version_or_id(First,Name) of	true ->	    all_actual_for_version_or_id(Rest, [First|Found], Name);	false ->	    all_actual_for_version_or_id(Rest, Found, Name)    end.is_actual_for_version_or_id( Current, Name ) ->    case element(3,element(3,element(2,Current))) of	Name ->	    true;	OtherName ->	    suffix([Name],tokens(OtherName,"::"))    end.%% Find the most locally defind pragmas%% to the scope SCOPEmost_local( SList, Scope ) ->    case SList of	[] ->	    [];	[First|Rest] ->	    case suffix( element(4,First), Scope ) of		true ->		    most_local( Rest, First, Scope, [First] );		false ->		    most_local( Rest, Scope )	    end    end.%% Returns a list of all pragmas found in the %% same scope. Should choose the right one by looking %% att the  position of the pragma in relation to%% the current object..... ( For hairy cases ).  most_local( SList, Current, Scope, AllFound ) ->    case SList of	[] ->	    AllFound;	[First|Rest] ->	    FirstScope = element(4,First),	    case suffix( FirstScope, Scope ) of		true ->		    CurrentScope = element(4,Current),		    case suffix( CurrentScope, FirstScope ) of			true -> 			    case length( CurrentScope ) == length( FirstScope ) of 				true -> %% SAME SCOPE ! KEEP BOTH				    most_local( Rest, Current, Scope, [First|AllFound] );				false -> 				    most_local( Rest, First, Scope, [First] )			    end;			false ->			    most_local( Rest, Current, Scope, AllFound )		    end;		false -> 		    most_local( Rest, Current, Scope, AllFound )	    end    end.%% Find the most dominant prefix pragmas%% located onto the SAME scope. Now%% we look att the line number, the position%% on the file. dominant_prefix(SList,LineNr) ->    case SList of 	[First|Rest] ->	    dominant_prefix(Rest,First,LineNr)    end.dominant_prefix([],{prefix,X,PLNr,N,F,T},LineNr) ->    case LineNr > PLNr of	true ->	    {prefix,X,PLNr,N,F,T};	false ->	    none    end;dominant_prefix([{prefix,FX,FPLNr,FN,F1,T1}|Rest],{prefix,CX,CPLNr,CN,F2,T2},LineNr) ->    case LineNr > FPLNr of % Check if FIRST before the object 	true -> 	    case FPLNr > CPLNr of % Check if FIRST after CURRENT		true ->		    dominant_prefix(Rest,{prefix,FX,FPLNr,FN,F1,T1},LineNr);		false ->		    dominant_prefix(Rest,{prefix,CX,CPLNr,CN,F2,T2},LineNr)	    end;	false -> % FIRST does not affect the object	    dominant_prefix(Rest,{prefix,CX,CPLNr,CN,F2,T2},LineNr)    end.%% Find the most dominant version pragmas%% located onto the SAME scope. Now%% we look att the line number, the position%% on the file. dominant_version(SList,LineNr) ->    case SList of 	[First|Rest] ->	    dominant_version(Rest,First,LineNr)    end.dominant_version([],Current,_) -> Current;dominant_version([{version,FX,FPLNr,FN,F1,T1}|Rest],{version,CX,CPLNr,CN,F2,T2},LineNr) ->    case FPLNr > CPLNr of % Check if FIRST after CURRENT	true ->	    dominant_version(Rest,{prefix,FX,FPLNr,FN,F1,T1},LineNr);	false ->	    dominant_version(Rest,{prefix,CX,CPLNr,CN,F2,T2},LineNr)    end.%% Find the most dominant id pragmas%% located onto the SAME scope. Now%% we look att the line number, the position%% on the file. dominant_id(SList,LineNr) ->    case SList of 	[First|Rest] ->	    dominant_id(Rest,First,LineNr)    end.dominant_id([],Current,_) -> Current;dominant_id([{id,FX,FPLNr,FN,F1,T1}|Rest],{id,CX,CPLNr,CN,F2,T2},LineNr) ->    case FPLNr > CPLNr of % Check if FIRST after CURRENT	true ->	    dominant_id(Rest,{id,FX,FPLNr,FN,F1,T1},LineNr);	false ->	    dominant_id(Rest,{id,CX,CPLNr,CN,F2,T2},LineNr)    end.%% This registers a module defined inside the file or%% an included file. A tuple that describes the module%% is added to the table. %% Observe that the modules registered are ONLY those%% who are in the top level, not definedd inside others !mk_ref(G,Name,Type) ->    case length(Name) > 1 of	true -> %% The interface is NOT defined att top level	    true;	false ->	    S = ic_genobj:pragmatab(G),	    File = get_idlfile(S), % The current file or an included one.	    case idlfile(G) of % The current file to be compiled.		File ->		    insert(S,{Type,Name,File,local});		_ ->		    insert(S,{Type,Name,File,included})	    end    end.%% The same as mk_ref/3 but this registers everything with %% all vital information available inside files.%% Registers ESSENTIAL data for included filesmk_file_data(G,X,Scope,Type) ->    S = ic_genobj:pragmatab(G),    Name = get_id2(X),    PreprocFile = get_idlfile(S), % The current file or an included one.    CompFile = idlfile(G), % The current file compiled    Depth = length(Scope), % The depth of the scope    ScopedName = ic_util:to_undersc([Name|Scope]),    Line = ic_forms:get_line(X),    case PreprocFile of 	CompFile ->	    insert(S,{file_data_local,CompFile,CompFile,Type,Scope,Name,ScopedName,Depth,Line});	PreprocFile ->	    insert(S,{file_data_included,PreprocFile,CompFile,Type,Scope,Name,ScopedName,Depth,Line})    end.%% Return a list with all the headers from%% the local file that represent the module%% or interface that is preciding the currentget_local_c_headers(G,X) ->    S = ic_genobj:pragmatab(G),    Local = lookup(S,file_data_local),    FoundLocal = get_local_c_headers(X,Local,Local),    no_doubles(FoundLocal).get_local_c_headers(X,Local,Local) ->     get_local_c_headers(X,Local,Local,[]).get_local_c_headers(_X,[],_All,Found) ->    Found;get_local_c_headers(X,[{file_data_local,_PF_idl,_,module,_,_,SN,_,Line}|Hs],All,Found)->    case ic_forms:get_line(X) > Line of	true ->	    get_local_c_headers(X,Hs,All,[SN|Found]);	false ->	    get_local_c_headers(X,Hs,All,Found)    end;get_local_c_headers(X,[{file_data_local,_PF_idl,_,interface,_,_,SN,_,Line}|Hs],All,Found)->    case ic_forms:get_line(X) > Line of	true ->	    get_local_c_headers(X,Hs,All,[SN|Found]);	false ->	    get_local_c_headers(X,Hs,All,Found)    end;get_local_c_headers(X,[_|Hs],All,Found) ->    get_local_c_headers(X,Hs,All,Found).%% Return a list with all the headers from%% the included file that represent the module%% or interface that have to be includedget_included_c_headers(G) ->    S = ic_genobj:pragmatab(G),    Included = lookup(S,file_data_included),    FoundIncluded = get_included_c_headers(Included,Included),    no_doubles(FoundIncluded).get_included_c_headers(Included,Included) ->     get_included_c_headers(Included,Included,[]).get_included_c_headers([],_All,Found) ->    Found;get_included_c_headers([{file_data_included,PF_idl,_CF_idl,T,_S,_N,SN,0,_}|Hs],All,Found) ->    Len = length(PF_idl),    FN = string:sub_string(PF_idl,1,Len-4),    case only_top_level(PF_idl,All) of	true ->	    %%	    L = string:tokens(FN,"/"),	    FN2 = lists:last(L),	    %%	    get_included_c_headers(Hs,All,["oe_"++FN2|Found]);	false ->	    case T of		module ->		    case contains_interface(PF_idl,All) of			true ->			    %%			    L = string:tokens(FN,"/"),			    FN2 = lists:last(L),			    %%			    get_included_c_headers(Hs,All,["oe_"++FN2|Found]);			false ->			    get_included_c_headers(Hs,All,[SN|Found])		    end;	        interface ->		    case contains_interface(PF_idl,All) of			true ->			    %%			    L = string:tokens(FN,"/"),			    FN2 = lists:last(L),			    %%			    get_included_c_headers(Hs,All,["oe_"++FN2|Found]);			false ->			    get_included_c_headers(Hs,All,[SN|Found])		    end;		_ ->		    get_included_c_headers(Hs,All,["oe_"++FN|Found])	    end    end;get_included_c_headers([{file_data_included,_PF_idl,_,module,_,_,SN,_,_}|Hs],All,Found)->    get_included_c_headers(Hs,All,[SN|Found]);get_included_c_headers([{file_data_included,_PF_idl,_,interface,_,_,SN,_,_}|Hs],All,Found)->    get_included_c_headers(Hs,All,[SN|Found]);get_included_c_headers([_|Hs],All,Found) ->    get_included_c_headers(Hs,All,Found).%% Help functions for the aboveonly_top_level(_PF_idl,[]) ->    true;only_top_level(PF_idl,[H|Hs]) ->    case element(2,H) of	PF_idl ->	    case element(8,H) > 0 of		true ->		    false;		false ->		    only_top_level(PF_idl,Hs)	    end;	_ ->	    only_top_level(PF_idl,Hs)    end.	contains_interface(_PF_idl,[]) ->    false;contains_interface(PF_idl,[H|Hs]) ->    case element(2,H) of	PF_idl ->	    case element(4,H) of		interface ->		    case element(8,H) > 0 of			true ->			    true;			false ->			    contains_interface(PF_idl,Hs)		    end;		_ ->		    contains_interface(PF_idl,Hs)	    end;	_ ->	    contains_interface(PF_idl,Hs)    end.    %% This returns a list of everything defined in an included file.get_incl_refs(G) ->    S = ic_genobj:pragmatab(G),        RefList = 	ets:match(S,{mod_ref,'$0','_',included}) ++	ets:match(S,{ifc_ref,'$0','_',included}) ++	ets:match(S,{const_ref,'$0','_',included}) ++	ets:match(S,{typedef_ref,'$0','_',included}) ++	ets:match(S,{except_ref,'$0','_',included}) ++	ets:match(S,{struct_ref,'$0','_',included}) ++	ets:match(S,{union_ref,'$0','_',included}) ++	ets:match(S,{enum_ref,'$0','_',included}) ++	ets:match(S,{attr_ref,'$0','_',included}),    case RefList of	[] ->	    none;	_ ->	    RefList    end.%% This returns a list of everything locally defined.get_local_refs(G) ->    S = ic_genobj:pragmatab(G),    RefList = 	ets:match(S,{mod_ref,'$0','_',local}) ++	ets:match(S,{ifc_ref,'$0','_',local}) ++	ets:match(S,{const_ref,'$0','_',local}) ++	ets:match(S,{typedef_ref,'$0','_',local}) ++	ets:match(S,{except_ref,'$0','_',local}) ++	ets:match(S,{struct_ref,'$0','_',local}) ++	ets:match(S,{union_ref,'$0','_',local}) ++	ets:match(S,{enum_ref,'$0','_',local}) ++	ets:match(S,{attr_ref,'$0','_',local}),    case RefList of	[] ->	    none;	_ ->	    RefList    end.%% This is intented to be used for solving the identification%% problem introduced by pragmas. It creates aliases between%% scoped and "final" identities.

⌨️ 快捷键说明

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