ic_pragma.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,956 行 · 第 1/4 页
ERL
1,956 行
%% ``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_pragma).-export([pragma_reg/2,pragma_cover/3]).-export([pragma_prefix/3,pragma_version/3,pragma_id/3]).-export([mk_alias/3,get_alias/2,scope2id/2,id2scope/2,mk_scope/1]).-export([mk_ref/3,get_incl_refs/1,get_local_refs/1]).-export([get_dependencies/1, add_inh_data/3, preproc/3]).-export([getBrokerData/3,defaultBrokerData/1,list_to_term/1]).-export([get_local_c_headers/2,get_included_c_headers/1,is_inherited_by/3]).-export([no_doubles/1,fetchRandomLocalType/1,fetchLocalOperationNames/2]).-export([is_local/2]).%% Debug-export([print_tab/1,slashify/1,is_short/1]).-import(lists,[suffix/2,delete/2,reverse/1,keysearch/3,member/2,last/1,flatten/1]).-import(string,[tokens/2]).-import(ets,[insert/2,lookup/2]).-import(ic_forms, [get_id2/1, get_body/1, get_line/1]).-import(ic_util, [to_atom/1]).-import(ic_genobj, [idlfile/1]).-import(ic_options, [get_opt/2]).-include("icforms.hrl").-include("ic.hrl").%% Initialization of the pragma table and%% start of pragma registration. %% NOTE : this pragma registration is build%% as a separate stage under compilation.%% If it is to be optimised, it should be %% embodied in one of other compiling stages. pragma_reg(G,X) -> S = ic_genobj:pragmatab(G), init_idlfile(G,S), init_pragma_status(S), registerOptions(G,S), pragma_reg_all(G, S, [], X), denote_specific_code_opts(G), %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% case get_pragma_compilation_status(S) of true -> %% Remove ugly pragmas from form PragmaCleanForm = cleanup(X), {ok,PragmaCleanForm}; false -> ErrorNr = get_pragma_error_nr(S), %% Just print the number of errors found case ErrorNr > 1 of true -> io:format("There were ~p errors found on file ~p~n", [ErrorNr,get_idlfile(S)]), error; false -> io:format("There were ~p error found on file ~p~n", [ErrorNr,get_idlfile(S)]), error end end.registerOptions(G,S) -> OptList = ets:tab2list(ic_genobj:optiontab(G)), registerOptions(G,S,OptList).registerOptions(_G,_S,[]) -> true;registerOptions(G,S,[{{option,{broker,Scope}},{Mod,Type}}|Rest]) -> insert(S, {codeopt, reverse(tokens(Scope,":")), {broker,{Mod,Type}}, -1, nil, nil}), registerOptions(G,S,Rest);registerOptions(G,S,[_|Rest]) -> registerOptions(G,S,Rest).%% Decide if to apply pragmas%% by checking backend switchapplyPragmasInBe(G) -> case get_opt(G, be) of erl_plain -> false; _ -> true end.%% Decide if the code option directive%% is allowed to change backendapplyCodeOpt(G) -> case get_opt(G, be) of erl_corba -> %% Does not support codeopt false; erl_plain -> %% Does not support codeopt false; c_native -> %% Does not support codeopt false; _ -> true end.%% This removes all pragma records from the form.%% When debugged, it can be enbodied in pragma_reg_all.cleanup([],C) -> C;cleanup([X|Xs],CSF) -> cleanup(Xs, CSF++cleanup(X)).cleanup(X) when list(X) -> cleanup(X,[]);cleanup(X) when record(X, preproc) -> [X];cleanup(X) when record(X, pragma) -> [];cleanup(X) when record(X, op) -> % Clean inside operation parameters [ X#op{params = cleanup(X#op.params,[])}];cleanup(X) when record(X, module) -> % Clean inside module body [ X#module{body = cleanup(X#module.body,[])}];cleanup(X) when record(X, interface) -> % Clean inside interface body [ X#interface{body = cleanup(X#interface.body,[])}];cleanup(X) when record(X, except) -> % Clean inside exception body [ X#except{body = cleanup(X#except.body,[])}];cleanup(X) when record(X, struct) -> % Clean inside struct body [ X#struct{body = cleanup(X#struct.body,[])}];cleanup(X) when record(X, case_dcl) -> % Clean inside union body [ X#case_dcl{label = cleanup(X#case_dcl.label,[])}];cleanup(X) when record(X, union) -> % Clean inside union body [ X#union{body = cleanup(X#union.body,[])}];cleanup(X) when record(X, enum) -> % Clean inside enum body [ X#enum{body = cleanup(X#enum.body,[])}];cleanup(X) -> [X].%% pragma_reg_all is top level registration for pragmas pragma_reg_all(_G, _S, _N, []) -> ok;pragma_reg_all(G, S, N, [X|Xs]) -> pragma_reg(G, S, N, X), pragma_reg_all(G, S, N, Xs).%% pragma_reg is top level registration for pragmas pragma_reg(G, S, N, X) when list(X) -> pragma_reg_list(G, S, N, X);pragma_reg(_G, S, _N, X) when element(1, X) == preproc -> case X#preproc.aux of [{_, _, "1"}] -> IncludeEntryLNr = get_line(X#preproc.id), IncludeFileName = element(3,element(3,X)), insert(S,{includes,get_idlfile(S),IncludeFileName,IncludeEntryLNr}); _Other -> ok end, set_idlfile(S,element(3,element(3,X)));pragma_reg(G, S, N, X) when element(1, X) == pragma -> case applyPragmasInBe(G) of %% Pragmas are allowed to be %% applied in this this backend. true -> File = get_idlfile(S), % The current file or an included one. Type = case idlfile(G) of % Local/Included flag File -> local; _ -> included end, %% Register pragmas into pragmatab. case X of {pragma,{_,LineNr,"prefix"}, _To, _Apply} -> insert(S,{prefix,X,LineNr,N,File,Type}); {pragma,{_,_,"ID"},_,_} -> pragma_reg_ID(G, S, N, X); {pragma,{_,_,"version"},_,_} -> pragma_reg_version(G, S, N, X ); {pragma,{_,_,"CODEOPT"},_,_} -> pragma_reg_codeOpt(G,S,N,X); {pragma,{_,LineNr,BadPragma}, _To, _Apply} -> io:format("Warning : on file ~p :~n",[get_idlfile(S)]), io:format(" Unknown pragma directive ~p on line ~p, ignored.~n", [BadPragma,LineNr]) end; %% Pragmas are not to be applied in %% this backend, ignore all pragmas. false -> true end, ok;pragma_reg(G, S, N, X) when record(X, module) -> mk_ref(G,[get_id2(X) | N],mod_ref), mk_file_data(G,X,N,module), pragma_reg_all(G, S, [get_id2(X) | N], get_body(X));pragma_reg(G, S, N, X) when record(X, interface) -> mk_ref(G,[get_id2(X) | N],ifc_ref), mk_file_data(G,X,N,interface), pragma_reg_all(G, S, [get_id2(X) | N], get_body(X));pragma_reg(G, S, N, X) when record(X, op) -> %% Add operation in table insert(S,{op, get_id2(X), N, get_idlfile(S), get_filepath(S)}), mk_file_data(G,X,N,op), pragma_reg_all(G, S, N, X#op.params);pragma_reg(G, S, N, X) when record(X, except) -> mk_ref(G,[get_id2(X) | N],except_ref), mk_file_data(G,X,N,except), pragma_reg_all(G, S, N, X#except.body);pragma_reg(G, _S, N, X) when record(X, const) -> mk_ref(G,[get_id2(X) | N],const_ref), mk_file_data(G,X,N,const);pragma_reg(G, _S, N, X) when record(X, typedef) -> XX = #id_of{type=X}, lists:foreach(fun(Id) -> mk_ref(G,[get_id2(Id) | N],typedef_ref), mk_file_data(G,XX#id_of{id=Id},N,typedef) end, ic_forms:get_idlist(X));pragma_reg(G, S, N, X) when record(X, enum) -> mk_ref(G,[get_id2(X) | N],enum_ref), mk_file_data(G,X,N,enum), pragma_reg_all(G, S, N, X#enum.body);pragma_reg(G, S, N, X) when record(X, union) -> mk_ref(G,[get_id2(X) | N],union_ref), mk_file_data(G,X,N,union), pragma_reg_all(G, S, N, X#union.body);pragma_reg(G, S, N, X) when record(X, struct) -> mk_ref(G,[get_id2(X) | N],struct_ref), mk_file_data(G,X,N,struct), pragma_reg_all(G, S, N, X#struct.body);pragma_reg(G, _S, N, X) when record(X, attr) -> XX = #id_of{type=X}, lists:foreach(fun(Id) -> mk_ref(G,[get_id2(Id) | N],attr_ref), mk_file_data(G,XX#id_of{id=Id},N,attr) end, ic_forms:get_idlist(X)); pragma_reg(_G, _S, _N, _X) -> ok.pragma_reg_list(_G, _S, _N, []) -> ok;pragma_reg_list(G, S, N, List ) -> CurrentFileName = get_idlfile(S), pragma_reg_list(G, S, N, CurrentFileName, List).pragma_reg_list(_G, _S, _N, _CFN, []) -> ok;pragma_reg_list(G, S, N, CFN, [X | Xs]) -> case X of {preproc,_,{_,_,FileName},_} -> set_idlfile(S,FileName), pragma_reg(G, S, N, X), pragma_reg_list(G, S, N, FileName, Xs); _ -> pragma_reg(G, S, N, X), pragma_reg_list(G, S, N, CFN, Xs) end.pragma_reg_ID(G, S, N, X) -> {pragma,{_,LineNr,"ID"}, _To, Apply} = X, File = get_idlfile(S), % The current file or an included one. Type = case idlfile(G) of % Local/Included flag File -> local; _ -> included end, %% Check if ID is one of the allowed types : %% * OMG IDL %% * DCE UUID %% * LOCAL case tokens(element(3,Apply),":") of ["IDL",_,_] -> insert(S,{id,X,LineNr,N,File,Type}); ["DCE",_,VSN] -> case is_short(VSN) of true -> insert(S,{id,X,LineNr,N,File,Type}); false -> set_compilation_failure(S), io:format("Error on file ~p :~n",[get_idlfile(S)]), io:format(" Bad pragma ID ~p on line ~p,~n", [element(3,Apply),LineNr]), io:format(" the version part of ID is not a short integer.~n") end; ["LOCAL"|_] -> insert(S,{id,X,LineNr,N,File,Type}); _ -> set_compilation_failure(S), io:format("Error on file ~p :~n",[get_idlfile(S)]), io:format(" Bad pragma ID ~p on line ~p.~n", [element(3,Apply),LineNr]) end.pragma_reg_version(G, S, N, X) -> {pragma,{_,LineNr,"version"}, _To, Apply} = X, File = get_idlfile(S), % The current file or an included one. Type = case idlfile(G) of % Local/Included flag File -> local; _ -> included end, case tokens(Apply,".") of [Major,Minor] -> case is_short(Major) and is_short(Minor) of true -> insert(S,{version,X,LineNr,N,File,Type}); false -> set_compilation_failure(S), io:format("Error on file ~p :~n",[get_idlfile(S)]), io:format(" Bad pragma version ~p on line ~p,~n", [Apply,LineNr]), io:format(" the version is not valid.~n") end; _ -> set_compilation_failure(S), io:format("Error on file ~p :~n",[get_idlfile(S)]), io:format(" Bad pragma version ~p on line ~p,~n", [Apply,LineNr]), io:format(" the version is not valid.~n") end.pragma_reg_codeOpt(G, S, _N, {pragma,{_,LineNr,"CODEOPT"},_,Apply} )-> case applyCodeOpt(G) of true -> {_,_,OptionList_str} = Apply, case list_to_term(OptionList_str) of error -> ic_error:error(G,{pragma_code_opt_bad_option_list,LineNr}); OptionList -> case lists:keysearch(be,1,OptionList) of false -> %% Add the terms of the option list %% to the compiler option list applyCodeOpts(G,S,LineNr,OptionList); {value, {be,Type}} -> %% If backend is set from user, %% let the same backend be otherwize %% set backend by codeOpt directive case get_opt(G, be) of false -> %% Add the terms of the option list %% to the compiler option list applyCodeOpts(G,S,LineNr,OptionList); _ -> %% Add all the terms of the option list %% to the compiler option list but the %% backend option applyCodeOpts(G, S, LineNr, lists:delete({be,Type},OptionList)) end end end; false -> true end.applyCodeOpts(_,_,_,[]) -> true;applyCodeOpts(G,S,LNr,[{{broker,Scope},{M,T}}|Xs]) -> ScopedId = reverse(tokens(Scope,":")), case ets:match(S, {codeopt,ScopedId, '$1','$2','_','_'}) of [] -> %% Add pragma in table insert(S, {codeopt, ScopedId, {broker,{M,T}}, LNr, get_idlfile(S), get_filepath(S)}), %% Continue applyCodeOpts(G,S,LNr,Xs); _ -> %% Use the code option %% from user and continue applyCodeOpts(G,S,LNr,Xs) end;applyCodeOpts(G,S,LNr,[X|Xs]) -> case is_allowed_opt(X) of true -> %% Add that term of the option list %% to the compiler option list ic_options:add_opt(G, [X], true), %% Continue applyCodeOpts(G,S,LNr,Xs); false -> %% Print warning and continue io:format("Warning on file ~p :~n",[get_idlfile(S)]), io:format(" Bad option in pragma : ~p, ignored !~n",[X]), applyCodeOpts(G,S,LNr,Xs) end.is_allowed_opt({X,Y}) -> ic_options:allowed_opt(X,Y);is_allowed_opt(_X) -> false. %% Returns a tuple { PFX, VSN, ID }, that is the %% pragma prefix, version and id coverages of%% the scope SCOPE. This is done by use of the %% function pragma_cover/4.pragma_cover(G,Scope,Object) -> pragma_cover(ic_genobj:pragmatab(G),get_id2(Object),Scope,get_line(Object)).%% Returns a tuple { PFX, VSN, ID }, that is the %% pragma prefix, version and id coverages of%% the scope SCOPEpragma_cover(PragmaTab,Name,Scope,LineNr) -> PFX = pragma_prefix_cover(PragmaTab,Name,Scope,LineNr), VSN = pragma_version_cover(PragmaTab,Name,Scope,LineNr), ID = pragma_id_cover(PragmaTab,Name,Scope,LineNr), { PFX, VSN, ID }.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?