ic.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 413 行

ERL
413
字号
%% ``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).-export([sgen/1, gen/1, gen/2, help/0, compile/3]).%%------------------------------------------------------------%%%% Internal stuff%%%%-------------------------------------------------------------export([filter_params/2, handle_preproc/4, do_gen/4]).-import(lists, [foldr/3]).-include("icforms.hrl").-include("ic.hrl").-include_lib("stdlib/include/erl_compile.hrl").-export([make_erl_options/1]).			% For erlc-export([main/3, do_scan/1, do_parse/2, do_type/2]).%%------------------------------------------------------------%%%% Entry point%%%%------------------------------------------------------------%% compile(AbsFileName, Outfile, Options)%%   Compile entry point for erl_compile.compile(File, _OutFile, Options) ->    case gen(File, make_erl_options(Options)) of	ok -> ok;	Other -> Other    end.%% Entry for the -s switchsgen(ArgList) ->%%%    io:format("sgen called w ~p~n", [ArgList]),    apply(?MODULE, gen, ArgList).gen(File) ->    gen(File, []).gen(File, Opts) ->    G = ic_genobj:new(Opts),    IdlFile = ic_file:add_dot_idl(File),    case ic_options:get_opt(G, show_opts) of	true ->	    io:format("Opts: ~p~n", [ic_options:which_opts(G)]);	_ -> ok    end,    ic_genobj:set_idlfile(G, IdlFile),    case catch gen2(G, File, Opts) of	{_, {'EXIT', R}} -> 	    ic_genobj:free_table_space(G), %% Free space for all ETS tables	    io:format("Fatal error : ~p~n",[R]),	    error;	{_, {'EXIT', _, R}} -> 	    ic_genobj:free_table_space(G), %% Free space for all ETS tables	    io:format("Fatal error : ~p~n",[R]),	    error;	{'EXIT', R} -> 	    ic_genobj:free_table_space(G), %% Free space for all ETS tables	    io:format("Fatal error : ~p~n",[R]),	    error;	{'EXIT', _, R} -> 	    ic_genobj:free_table_space(G), %% Free space for all ETS tables	    io:format("Fatal error : ~p~n",[R]),	    error;		%% In this case, the pragma registration         %% found errors so this should return error.	error ->	    ic_genobj:free_table_space(G), %% Free space for all ETS tables	    error;	_ -> 	    X = ic_error:return(G),	    ic_genobj:free_table_space(G), %% Free space for all ETS tables	    X    end.gen2(G, File, Opts) ->    case ic_options:get_opt(G, time) of	true -> 	    time("TOTAL                ", ic, main, [G, File, Opts]);	_ -> 	    case main(G, File, Opts) of		error ->		    error;		_ ->		    ok	    end    end.do_gen(erl_corba, G, File, T) ->    ic_erlbe:do_gen(G, File, T);do_gen(erl_template, G, File, T) ->    ic_erl_template:do_gen(G, File, T);do_gen(erl_genserv, G, File, T) ->    ic_erlbe:do_gen(G, File, T);do_gen(c_genserv, G, File, T) ->    ic_cclient:do_gen(G, File, T);do_gen(noc, G, File, T) ->    ic_noc:do_gen(G, File, T);do_gen(erl_plain, G, File, T) ->    ic_plainbe:do_gen(G, File, T);do_gen(c_server, G, File, T) ->    ic_cserver:do_gen(G, File, T);do_gen(c_client, G, File, T) ->    ic_cclient:do_gen(G, File, T);%% Java backenddo_gen(java, G, File, T) ->    ic_jbe:do_gen(G, File, T);%% No language choicedo_gen(_,_,_,_) ->     ok.do_scan(G) ->    icscan:scan(G, ic_genobj:idlfile(G)).    do_parse(G, Tokens) ->    case icparse:parse(Tokens) of	{ok, L} -> L;	X when element(1, X) == error -> 	    Err = element(2, X),	    ic_error:fatal_error(G, {parse_error, element(1, Err), 				  element(3, Err)});	X -> exit(X)    end.do_type(G, Form) ->    ictype:type_check(G, Form).	time(STR,M,F,A) ->    case timer:tc(M, F, A) of	{_, {'EXIT', R}} -> exit(R);	{_, {'EXIT', _, R}} -> exit(R);	{_, _X} when element(1, _X)==error -> throw(_X);	{_T, _R} -> 	    io:format("Time for ~s:  ~10.2f~n", [STR, _T/1000000]),	    _R    end.%% Filters parameters so that only those with certain attributes are%% seen. The filter parameter is a list of attributes that will be%% seen, ex. [in] or [inout, out]filter_params(Filter, Params) ->    lists:filter(fun(P) ->		    lists:member(get_param_attr(P#param.inout), Filter) end,		 Params).%% Access primitive to get the attribute name (and discard the line%% number).get_param_attr({A, _N}) -> A.%%%% Fixing the preproc directives%%handle_preproc(G, _N, line_nr, X) ->    Id = ic_forms:get_id2(X),    Flags = X#preproc.aux,    case Flags of	[] -> ic_genobj:push_file(G, Id);	_ ->	    foldr(fun({_, _, "1"}, Gprim) -> ic_genobj:push_file(Gprim, Id);		     ({_, _, "2"}, Gprim) -> ic_genobj:pop_file(Gprim, Id);		     ({_, _, "3"}, Gprim) -> ic_genobj:sys_file(Gprim, Id) end,		  G, Flags)    end;handle_preproc(G, _N, _Other, _X) ->    G.%%------------------------------------------------------------%%%% The help department%%%% %%%%------------------------------------------------------------help() ->    io:format("No help available at the moment~n", []),    ok.print_version_str(G) ->    case {ic_options:get_opt(G, silent), ic_options:get_opt(G, silent2)} of	{true, _} -> ok;	{_, true} -> ok;	_ -> 	    io:format("Erlang IDL compiler version ~s~n", [?COMPILERVSN])    end.%%%% Converts generic compiler options to specific options.%% %% Used by erlc%%make_erl_options(Opts) ->    %% This way of extracting will work even if the record passed    %% has more fields than known during compilation.    Includes1 = Opts#options.includes,    Defines = Opts#options.defines,    Outdir = Opts#options.outdir,    Warning = Opts#options.warning,    Verbose = Opts#options.verbose,    Specific = Opts#options.specific,    Optimize = Opts#options.optimize,    PreProc = 	lists:flatten(	  lists:map(fun(D) -> io_lib:format("-I~s ", [ic_util:to_list(D)]) end, 		    Includes1)++	  lists:map(	    fun ({Name, Value}) ->		    io_lib:format("-D~s=~s ", [ic_util:to_list(Name), ic_util:to_list(Value)]);		(Name) ->		    io_lib:format("-D~s ", [ic_util:to_list(Name)])	    end,	    Defines)),    Options =	case Verbose of	    true ->  [];	    false -> []	end ++	case Warning of	    0 -> [nowarn];	    _ -> ['Wall']	end ++	case Optimize of	    0 -> [];	    _ -> []	end,        Options++[{outdir, Outdir}, {preproc_flags, PreProc}]++Specific.%%%%%% NEW main, avoids memory fragmentation%%%main(G, File, _Opts) ->    print_version_str(G),    ?ifopt(G, time, io:format("File ~p compilation started  :   ~p/~p/~p ~p:~2.2.0p~n", 			      [ic_genobj:idlfile(G),			       element(1,date()),			       element(2, date()),			       element(3, date()),			       element(1, time()),			       element(2, time())])),    case ic_options:get_opt(G, help) of	true -> help();	_ ->	    scanning(G, File)    end.scanning(G, File) ->    S = ?ifopt2(G, time,	       time("input file scanning  ", ic, do_scan, [G]),	       ic:do_scan(G)),    ?ifopt2(G, tokens, io:format("TOKENS: ~p~n", [S]), 				 parsing(G, File, S)).parsing(G, File, S) ->    T = ?ifopt2(G, 		time, 		time("input file parsing   ", ic, do_parse, [G,S]),		ic:do_parse(G,S)),    ?ifopt2(G, form, io:format("PARSE FORM: ~p~n", [T]), 	     pragma(G, File, T)).pragma(G, File, T) ->    case ?ifopt2(G, 		 time,		 time("pragma registration  ", ic_pragma, pragma_reg, [G,T]),		 ic_pragma:pragma_reg(G,T)) of	%% All pragmas were succesfully applied	{ok,Clean} ->	    typing(G, File, Clean);       	error ->	    error    end.typing(G, File, Clean) ->    case catch ?ifopt2(G, 		       time,		       time("type code appliance  ", ic, do_type, [G,Clean]),		       ic:do_type(G,Clean)) of	{'EXIT',Reason} ->	    io:format("Error under type appliance : ~p~n",[Reason]),	    error;       	T2 ->	    	    ?ifopt2(G, tform, io:format("TYPE FORM: ~p~n", [T2]),		    generation(G, File, T2))    end.generation(G, File, T2) ->    case ic_options:get_opt(G, multiple_be) of	false ->	    single_generation(G, File, T2);	List ->	    OutDir = 		case ic_options:get_opt(G, outdir) of		    false -> 			[];		    Dir ->			Dir		end,	    	    case ic_options:get_opt(G, be) of		false ->		    ok;		Be ->		    %% Generate this first		    ic_options:add_opt(G,[{outdir,OutDir++atom_to_list(Be)}],true),		    single_generation(G, File, T2)	    end,	    multiple_generation(G, File, T2, OutDir, List)    end.multiple_generation(_G, _File, _T2, _RootDir, []) ->    ok;multiple_generation(G, File, T2, RootDir, [Be|Bes]) ->    ic_options:add_opt(G,[{outdir,RootDir++atom_to_list(Be)}],true),    ic_options:add_opt(G,[{be,Be}],true),    single_generation(G, File, T2),    case ic_error:get_error_count(G) of	0 ->	     multiple_generation(G,File,T2,RootDir,Bes);	 _ ->	     %% Errors reported, abort	     ok     end.single_generation(G, File, T2) ->    case ic_error:get_error_count(G) of	0 ->	    %% Check if user has sett backend option	    case ic_options:get_opt(G, be) of		false ->		    %% Use default backend option		    DefaultBe = ic_options:defaultBe(),		    ic_options:add_opt(G,[{be,DefaultBe}],true),		    		    ?ifopt2(G, 			    time,			    time("code generation      ", ic, do_gen, [DefaultBe, G, File, T2]),			    ic:do_gen(DefaultBe, G, File, T2));		Be ->		    %% Use user defined backend		    		    ?ifopt2(G, 			    time,			    time("code generation      ", ic, do_gen, [Be, G, File, T2]),			    ic:do_gen(Be, G, File, T2))	    end;	_ ->	    ok	    %% Does not matter    end.	

⌨️ 快捷键说明

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