ic_pragma.erl

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

ERL
1,956
字号
mk_alias(G,PragmaId,ScopedId) ->    %io:format("~nMaking alias -> ~p~n",[PragmaId]),    S = ic_genobj:pragmatab(G),    insert(S,{alias,ScopedId,PragmaId}).%% This is used to find out if the object described with%% the scoped id is created. If this is the case, it should%% be registered as an alias and the identity of the object %% is returned. Otherwize "none" is returned.get_alias(G,ScopedId) ->    S = ic_genobj:pragmatab(G),    case ets:match(S,{alias,ScopedId,'$1'}) of	[] ->	    none;	[[IfrId]] ->	    %io:format("~nFound alias -> ~p~n",[IfrId]),	    IfrId    end.%% Returns the alias id or constructs an idscope2id(G,ScopedId) ->    case get_alias(G,ScopedId) of	none ->	    case is_included(G,ScopedId) of		true -> %% File included		    get_included_IR_ID(G,ScopedId);		false -> %% File local		    NewIfrId = mk_id(ScopedId),    % Create a "standard" id		    mk_alias(G,NewIfrId,ScopedId), % Create an alias		    NewIfrId	    end;	IfrId ->	    IfrId    end.is_included(G,ScopedId) ->    S = ic_genobj:pragmatab(G),    Name = ic_util:to_undersc(ScopedId),    case ets:match(S,{file_data_included,'_','_','_','_','_',Name,'_','_'}) of	[[]] ->	    true;	_ ->	    false    end.get_included_IR_ID(G,ScopedId) ->    S = ic_genobj:pragmatab(G),    ScopedName = ic_util:to_undersc(ScopedId),    [[Scope,Name,LNr]] = ets:match(S,{file_data_included,'_','_','_','$3','$4',ScopedName,'_','$7'}),    {Prefix,Vsn,Id} = pragma_cover(S,Name,Scope,LNr),    case Id of	none ->	    case Prefix of		none ->		    IR_ID = 			lists:flatten(io_lib:format("IDL:~s:~s",[ScopedName, Vsn])),		    ic_pragma:mk_alias(G,IR_ID,ScopedId),		    IR_ID;		_ ->		    IR_ID = 			lists:flatten(io_lib:format("IDL:~s:~s",[Prefix ++ "/" ++ ScopedName, Vsn])),		    ic_pragma:mk_alias(G,IR_ID,ScopedId),		    IR_ID	    end;	_ ->	    ic_pragma:mk_alias(G,Id,ScopedId),	    Id    end.	    %% Returns the scope for objectid2scope(G,IfrId) ->    S = ic_genobj:pragmatab(G),    case lookup(S,alias) of	[] ->	    mk_scope(IfrId);	AliasList ->	    case keysearch(IfrId,3,AliasList) of		false ->		    mk_scope(IfrId);		{value,{alias,ScopedId,_}} ->		    ScopedId	    end    end.%% Returns a "standard" IDL ID by getting the scope listmk_id(ScopedId) ->    "IDL:" ++ ic_pragma:slashify(ScopedId) ++ ":" ++ default_version().%% Returns the scope of an object when getting a "standard" IDL IDmk_scope(IfrId) ->    [_,Body,_] = tokens(IfrId,":"),    reverse(tokens(Body,"/")).%% This is used to note the exact compiled file  %% under pragma creation. There are two options, the %% main file or files included by the main file. This%% just denotes the CURRENT file, the main file or%% the included ones. A very usual field is the file%% path that shows the include path of the file init_idlfile(G,S) ->    IdlFile = idlfile(G),    insert(S,{file,IdlFile,[]}).set_idlfile(S,FileName) ->    FilePath = get_filepath(S),    case FilePath of	[] ->	    ets:delete(S,file),	    insert(S,{file,FileName,[FileName|FilePath]});	_ ->	    case hd(FilePath) of		[] ->		    ets:delete(S,file),		    insert(S,{file,FileName,[FileName|FilePath]});		_ ->		    case tl(FilePath) of			[] ->			    ets:delete(S,file),			    insert(S,{file,FileName,[FileName|FilePath]});			_ ->			    case hd(tl(FilePath)) of				[] ->				    ets:delete(S,file),				    insert(S,{file,FileName,[FileName|FilePath]});				FileName ->				    ets:delete(S,file),				    insert(S,{dependency,FilePath}), % Add dependency branch				    insert(S,{file,FileName,tl(FilePath)});				_ ->				    ets:delete(S,file),				    insert(S,{file,FileName,[FileName|FilePath]})			    end		    end	    end    end.get_idlfile(S) ->    [FT] = lookup(S,file),    element(2,FT).get_filepath(S) ->    [FT] = lookup(S,file),    element(3,FT).%% This returns a list of file names%% that direct or indirect the current%% compiled file is depended on.get_dependencies(G) ->    S = ic_genobj:pragmatab(G),    case lookup(S,dependency) of	[] ->	    [];	Dependencies ->	    {get_idlfile(S),get_dependencies(Dependencies,[])}    end.get_dependencies([],Dependencies) ->    no_doubles(Dependencies);get_dependencies([{dependency,Path}|Tail],Current) ->    get_dependencies(Tail,[hd(Path)|Current]).no_doubles(List) ->    no_doubles(List,[]).no_doubles([],NoDoubles) ->    NoDoubles;no_doubles([X|Xs],Current) ->    case member(X,Xs) of	true ->	    no_doubles(Xs,Current);	false ->	    no_doubles(Xs,[X|Current])    end.%% Pragma compilation status initializationinit_pragma_status(S) ->        insert(S,{status,true,0}).%% Pragma compilation status set to failure%% and count up the number of errorsset_compilation_failure(S) ->    [{status,_,ErrorNr}] = lookup(S,status),    ets:delete(S,status),    insert(S,{status,false,ErrorNr+1}).%% Pragma compilation status set to lookupget_pragma_compilation_status(S) ->    [Status] = lookup(S,status),    element(2,Status).%% Pragma error numberget_pragma_error_nr(S) ->    [Status] = lookup(S,status),    element(3,Status).%% Short check is_short(N_str) when list(N_str) ->    case is_short_decimal_str(N_str) of	true ->	    true;	false ->	    false    end;is_short(N) when integer(N)->    (N < 65535) and (N > -65536);is_short(_) -> false.%% Check if the string is a%% list of characters representing%% a short. Avoid crash !.is_short_decimal_str(N_str) ->    case is_decimal_str(N_str) of	true ->	    N = list_to_integer(N_str),	    (N < 65535) and (N > -65536); 	false ->	    false    end.%% Check if the string is a%% list of characters representing%% decimals.is_decimal_str([]) ->    true;is_decimal_str([First|Rest]) ->    case is_decimal_char(First) of        true ->            is_decimal_str(Rest);        false ->            false    end.%% True if D is a character %% representing a decimal (0-9).is_decimal_char(D) ->    case (48=<D) and (D=<57) of	true ->	    true;	false ->	    false    end.%% Prints out all the tableprint_tab(G) ->    io:format("~nPragmaTab = ~p~n",[ets:tab2list(ic_genobj:pragmatab(G))]).list_to_term(List) ->    case catch erl_scan:string(List) of	{ok, Tokens, _} ->	    case erl_parse:parse_term(Tokens ++ [{dot, 1}]) of		{ok,Term} ->		    Term;		_ ->		    error	    end;	_ ->	    error    end.%% Cleanup all other code options for a specified scope%% in the same file, but the most dominant.cleanup_codeOptions(G,S,ScopedId) ->    case ets:match(S,{codeopt,ScopedId,'$1','$2',idlfile(G),'$4'}) of	[] ->	    %% No codeOpt directive is placed inside the	    %% currently compiled file. Try to find other            %% directives located in included files. 	    true;	List -> 	    %% A codeOpt directive is placed inside the	    %% currently compiled file. This dominates            %% all other directives. 	    CodeOption = best_positioned_codeOpt(List),	    %% Remove code options that do not affect 	    %% the code production (redundant) 	    remove_redundant_codeOpt(S,[ScopedId|CodeOption])    end.%% Best positioned is the codeopt located %% "highest" on the SAME file, the one with %% lowest line number. best_positioned_codeOpt([X|Xs]) ->     best_positioned_codeOpt(Xs,X).best_positioned_codeOpt([],Found) ->    Found;best_positioned_codeOpt([X|Xs],Current) ->    case hd(tl(X)) > hd(tl(Current)) of	true ->	    best_positioned_codeOpt(Xs,Current);	false ->	    best_positioned_codeOpt(Xs,X)    end.remove_redundant_codeOpt(S,[ScopedId,CodeOption,LNr,FilePath]) ->    ets:match_delete(S,{codeopt,ScopedId,'$1','$2','$3','$4'}),    ets:insert(S,{codeopt,ScopedId,CodeOption,LNr,last(FilePath),FilePath}).add_inh_data(G,InclScope,X) ->    S = ic_genobj:pragmatab(G),    case X#interface.inherit of	[] ->	    true;	[InhBody] -> 	    Scope = [get_id2(X)|InclScope],	    insert(S,{inherits,Scope,InhBody});	InhList ->	    add_inh_data(G, S, InclScope, X, InhList)    end.add_inh_data(_,_,_,_,[]) ->    true;add_inh_data(G, S, InclScope, X, [InhBody|InhBodies]) ->	    Scope = [get_id2(X)|InclScope],    insert(S, {inherits,Scope,InhBody}),    add_inh_data(G, S, InclScope, X, InhBodies).%% Returns a default broker datadefaultBrokerData(G) ->    {to_atom(ic_genobj:impl(G)),transparent}.%% Loops through the form and sdds inheritence data preproc(G, N, [X|Xs]) when record(X, interface) ->    %% Add inheritence data to pragmatab    ic_pragma:add_inh_data(G,N,X),    N2 = [get_id2(X) | N],    preproc(G, N2, get_body(X)),    lists:foreach(fun({_Name, Body}) -> preproc(G, N2, Body) end, 		  X#interface.inherit_body),     preproc(G, N, Xs);preproc(G,N,[X|Xs]) when record(X, module) ->    N2 = [get_id2(X) | N],    preproc(G, N2, get_body(X)),    preproc(G,N,Xs);preproc(G,N,[_X|Xs]) ->    preproc(G,N,Xs);preproc(_G, _N, []) ->    ok.%% Returns a tuple / list of tuples { Mod, Type } %% Does not check overridence because it is the %% top scope for the module to be produced and%% cannot be overriden.getBrokerData(G,X,Scope) ->    S = ic_genobj:pragmatab(G),    cleanup_codeOptions(G,S,Scope),    %% Check if it is an operation denoted    case isOperation(S,Scope) of	%% Yes, check options	true ->	    %% Look if there is a specific code option on top file	    case hasSpecificCodeoptionOnTopFile(S,ic_genobj:idlfile(G),Scope) of		true ->		    %% Yes, let it work		    getBrokerData(G,S,X,Scope,[Scope],[]);		false ->		    %% No, try to see if there is codeoption on top file		    case hasNonSpecificCodeoptionOnTopFile(S,ic_genobj:idlfile(G)) of			true ->			    %% Yes, override every other specific code option			    [_H|T] = Scope,			    getBrokerData(G,S,X,Scope,[T],[]);			false ->			    %% No, let inherited specific code options work			    getBrokerData(G,S,X,Scope,[Scope],[])		    end	    end;	%% No, continue	false ->	    getBrokerData(G,S,X,Scope,[Scope],[])    end.%% Returns a tuple / list of tuples { Mod, Type }%% Inside loop, uses overridence. getBrokerData(G,X,RS,Scope,CSF) ->    S = ic_genobj:pragmatab(G),    cleanup_codeOptions(G,S,Scope),    OvScope = overridedFrom(S,RS,Scope),    getBrokerData(G,S,X,RS,[OvScope],[OvScope|CSF]).getBrokerData(G,S,X,RS,[[[First]|Rest]],CSF) when integer(First) ->    Scope = [[First]|Rest],    case ets:match(S,{codeopt,Scope,'$1','_','_','_'}) of	[] ->	    case ets:match(S,{inherits,Scope,'$1'}) of		[] -> %% No inheritence, no pragma codeopt		    defaultBrokerData(G); %% Default		[InhScope] ->		    getBrokerData(G,S,X,RS,InhScope,CSF);		InhList ->		    getBrokerDataInh(G,S,X,RS,Scope,CSF,InhList)	    end;	[[{broker,{Module,Type}}]] -> %% A branch only, with pragma codeopt	    {Module,Type};	List -> %% Multiple branches with pragma codeopt	    flatten(List)    end;getBrokerData(G,S,X,RS,[[[First]|Rest]],CSF) ->    getBrokerDataLoop(G,S,X,RS,[[First]|Rest],CSF);getBrokerData(G,S,X,RS,[Scope],CSF) ->   %io:format(" 1"),    case ets:match(S,{codeopt,Scope,'$1','_','_','_'}) of	[] ->	   %io:format(" 2"),	    case ets:match(S,{inherits,Scope,'$1'}) of		[] -> %% No inheritence, no pragma codeopt		   %io:format(" 5"),		    defaultBrokerData(G); %% Default		[InhScope] ->		   %io:format(" 6"),		    getBrokerData(G,S,X,RS,InhScope,CSF);		InhList ->		   %io:format(" 7"),		    getBrokerDataInh(G,S,X,RS,Scope,CSF,InhList)	    end;	[[{broker,{Module,Type}}]] -> %% A branch only, with pragma codeopt	   %io:format(" 3"),	    {Module,Type};	List -> %% Multiple branches with pragma codeopt	   %io:format(" 4"),	    flatten(List)    end.%% Special treatment when X is an operationgetBrokerDataInh(G,S,X,RS,Scope,CSF,InhList) when record(X,op)->   %io:format(" 8"),    case ets:match(S,{op,get_id2(X),'$1','_','_'}) of	[] ->	   %io:format(" 10"),	    CleanList = remove_inherited(S,InhList),	    getBrokerDataLoop(G,S,X,RS,CleanList,CSF);		[[Scope]] ->	   %io:format(" 11"),	    CleanList = remove_inherited(S,InhList),	    getBrokerDataLoop(G,S,X,RS,CleanList,CSF);   	[[OpScope]] ->	   %io:format(" 12"),	    case member([OpScope],InhList) of 		true ->		   %io:format(" 14"),		    %% No inherited scopes		    getBrokerData(G,X,RS,OpScope,CSF);			false ->		   %io:format(" 15"),

⌨️ 快捷键说明

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