ic_codegen.erl

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

ERL
418
字号
%% ``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_codegen).-include_lib("ic/src/ic.hrl").-include_lib("ic/src/icforms.hrl").%%-----------------------------------------------------------------%% External exports%%------------------------------------------------------------------export([emit/2, emit/3]).-export([emit_c_enc_rpt/4, emit_c_dec_rpt/4]).-export([comment/2, comment/3, comment/4, comment_inlined/5, comment_prefixed/4]).-export([mcomment/2, mcomment/3, mcomment_inlined/5, mcomment_prefixed/3]).-export([mcomment_light/2, mcomment_light/3, mcomment_light_inlined/5, mcomment_light_prefixed/3]).-export([nl/1, export/2]).-export([record/5]).-export([emit_stub_head/4, emit_hrl_head/4, emit_hrl_foot/2]).%%-----------------------------------------------------------------%% Internal exports%%-----------------------------------------------------------------%%-----------------------------------------------------------------%% External functions%%-----------------------------------------------------------------%%--------------------------------------------------------------------%% Emit output as a formatted string, (old emit)%%--------------------------------------------------------------------emit(nil, _) -> ok;emit(Fd, Str) ->    file:write(Fd, Str).emit(nil, _, _) -> ok;emit(Fd, Fmt, Args) ->    file:write(Fd, io_lib:format(Fmt, Args)).emit_c_enc_rpt(Fd, Prefix, Fmt, Args) ->    emit(Fd, Prefix ++ "OE_RPT_ERR(\"Encode error: " ++ Fmt ++ "\");\n", Args).emit_c_dec_rpt(Fd, Prefix, Fmt, Args) ->    emit(Fd, Prefix ++ "OE_RPT_ERR(\"Decode error: " ++ Fmt ++ "\");\n", Args).%%--------------------------------------------------------------------%% Emit comments%%--------------------------------------------------------------------comment(Fd, C) ->    comment_prefixed(Fd, C, [], "%%").comment(Fd, C, A) ->    comment_prefixed(Fd, C, A, "%%").comment(Fd, C, A, c) ->     comment_inlined(Fd, C, A, "/*", "*/");comment(Fd, C, A, erl) ->     comment_prefixed(Fd, C, A, "%%");comment(Fd, C, A, java) ->     comment_prefixed(Fd, C, A, "//");%% Should be removed after a check if it's used !!!!! (LTH)comment(Fd, C, A, CommentSequence) when list(CommentSequence) ->    comment_prefixed(Fd, C, A, CommentSequence).comment_inlined(Fd, C, A, Start, End) ->     emit(Fd, Start ++ " " ++ C ++ " " ++ End ++"\n", A).comment_prefixed(Fd, C, A, Prefix) ->     emit(Fd, Prefix ++ " " ++ C ++ "\n", A).%%--------------------------------------------------------------------%% Emit multiline comments with nice delimiters%%--------------------------------------------------------------------mcomment(Fd, List) ->    mcomment_prefixed(Fd, List, "%%").mcomment(Fd, List, c) ->    mcomment_inlined(Fd, List, "/*", "*/", " *");mcomment(Fd, List, erl) ->    mcomment_prefixed(Fd, List, "%%");mcomment(Fd, List, java) ->    mcomment_prefixed(Fd, List, "//").mcomment_inlined(Fd, List, Start, End, Intermediate) ->    emit(Fd, Start ++	 "------------------------------------------------------------\n"),    emit(Fd, Intermediate ++ "\n"),    lists:foreach(fun(C) -> comment(Fd, C, [], Intermediate) end, List),    emit(Fd, Intermediate ++ "\n"),    emit(Fd, Intermediate ++	 "------------------------------------------------------------" ++ End ++ "\n"),    ok.mcomment_prefixed(Fd, List, Prefix) ->    emit(Fd, Prefix ++	 "------------------------------------------------------------\n"),    emit(Fd, Prefix ++ "\n"),    lists:foreach(fun(C) -> comment(Fd, C, [], Prefix) end, List),    emit(Fd, Prefix ++ "\n"),    emit(Fd, Prefix ++	 "------------------------------------------------------------\n"),    ok.%%--------------------------------------------------------------------%% Emit multiline comments with nice delimiters as above but a %% little lighter%%--------------------------------------------------------------------mcomment_light(Fd, List) ->    mcomment_light_prefixed(Fd, List, "%%").mcomment_light(Fd, List, c) ->    mcomment_light_inlined(Fd, List, "/*", " */", " *");mcomment_light(Fd, List, erl) ->    mcomment_light_prefixed(Fd, List, "%%");mcomment_light(Fd, List, java) ->    mcomment_light_prefixed(Fd, List, "//");%% Should be removed after a check if it's used !!!!! (LTH)mcomment_light(Fd, List, Prefix) when list(Prefix) ->    mcomment_light_prefixed(Fd, List, Prefix).    mcomment_light_inlined(Fd, List, Start, End, Intermediate) ->    emit(Fd, "\n" ++ Start ++ "\n"),    lists:foreach(fun(C) -> comment(Fd, C, [], Intermediate) end, List),    emit(Fd, End ++ "\n"),    ok.mcomment_light_prefixed(Fd, List, Prefix) ->    emit(Fd, Prefix),    lists:foreach(fun(C) -> comment(Fd, C, [], Prefix) end, List),    emit(Fd, Prefix ++ "\n"),    ok.%%--------------------------------------------------------------------%% New line%%--------------------------------------------------------------------nl(Fd) ->    emit(Fd, "\n").%%---------------------------------------------------------------------define(IFRIDFIELD(G), ic_util:mk_name(G, "ID")).%%--------------------------------------------------------------------%% Emit record definitions for erlang%%--------------------------------------------------------------------record(G, X, Name, _IFRID, Recs) when record(X, struct) ->    F = ic_genobj:hrlfiled(G),    emit(F, "-record(~p, {~p", [ic_util:to_atom(Name),hd(Recs)]),    lists:foreach(fun(Y) -> emit(F, ", ~p", [Y]) end, tl(Recs)),    emit(F, "}).\n");record(G, X, Name, _IFRID, _Recs) when record(X, union) ->    F = ic_genobj:hrlfiled(G),    emit(F, "-record(~p, {label, value}).\n",[ic_util:to_atom(Name)]);record(G, _X, Name, IFRID, Recs) when length(Recs) > 3 ->    F = ic_genobj:hrlfiled(G),    emit(F, "-record(~p,~n        {~p=~p", 	 [ic_util:to_atom(Name), ic_util:to_atom(?IFRIDFIELD(G)), IFRID]),    rec2(F, "", ", ", Recs),    emit(F, "}).\n");record(G, _X, Name, IFRID, Recs) ->    F = ic_genobj:hrlfiled(G),    emit(F, "-record(~p, {~p=~p", [ic_util:to_atom(Name),				   ic_util:to_atom(?IFRIDFIELD(G)),				     IFRID]),    lists:foreach(fun(Y) -> emit(F, ", ~p", [Y]) end, Recs),    emit(F, "}).\n").rec2(F, Align, Delim, [M1 , M2, M3 | Ms]) ->    emit(F, "~s~s~p, ~p, ~p", [Delim, Align, M1, M2, M3]),    rec2(F, "         ", ",\n", Ms);rec2(F, Align, Delim, [M1 , M2]) ->    emit(F, "~s~s~p, ~p", [Delim, Align, M1, M2]);rec2(F, Align, Delim, [M]) ->    emit(F, "~s~s~p", [Delim, Align, M]);rec2(_F, _Align, _Delim, []) ->    ok.%%--------------------------------------------------------------------%% Emit export lists for erlang%%--------------------------------------------------------------------export(F, [E1, E2, E3 | Exports]) ->    emit(F, "-export([~s]).\n", [exp_list([E1, E2, E3])]),    export(F, Exports);export(_F, []) -> ok;export(F, Exports) ->    emit(F, "-export([~s]).\n", [exp_list(Exports)]).exp_list([E1 | L]) ->    exp_to_string(E1) ++ 	lists:map(fun(E) -> ", " ++ exp_to_string(E) end, L).exp_to_string({F,N}) -> io_lib:format("~p/~p", [ic_util:to_atom(F), N]).%%--------------------------------------------------------------------%% Emit Stub file header%%--------------------------------------------------------------------emit_stub_head(_G, ignore, _Name, _) -> ignore;emit_stub_head(G, F1, Name, erlang) ->    mcomment(F1, stub_header(G, Name)),    nl(F1),    emit(F1, "-module(~p).\n", [list_to_atom(Name)]),    emit(F1, "-ic_compiled(~p).\n", [compiler_vsn(?COMPILERVSN)]),    emit(F1, "\n\n"), F1;emit_stub_head(G, F1, Name, erlang_template) ->    ic_erl_template:emit_header(G, F1, Name),    F1;emit_stub_head(_G, F1, _Name, erlang_template_no_gen) ->    F1;emit_stub_head(G, F1, Name, c) ->    mcomment(F1, stub_header(G, Name), c),    emit(F1, "int ic_compiled_~s_~s;\n", [compiler_vsn(?COMPILERVSN), Name]),    emit(F1, "\n\n"), F1;emit_stub_head(G, F1, Name, c_server) ->    CSName = [Name, "__s"],    mcomment(F1, stub_header(G, CSName), c),    emit(F1, "int ic_compiled_~s_~s;\n", [compiler_vsn(?COMPILERVSN), CSName]),    emit(F1, "\n\n"), F1;emit_stub_head(G, F1, Name, java) ->    mcomment(F1, stub_header(G, Name), java),    emit(F1, "\n\n"), F1.stub_header(G, Name) ->    ["Implementation stub file",     "",     io_lib:format("Target: ~s", [Name]),     io_lib:format("Source: ~s", [ic_genobj:idlfile(G)]),     io_lib:format("IC vsn: ~s", [?COMPILERVSN]),     "",     "This file is automatically generated. DO NOT EDIT IT."].compiler_vsn(Vsn) ->    lists:map(fun($.) -> $_;		 (C) -> C	      end, Vsn).%%--------------------------------------------------------------------%% Emit include file header%%--------------------------------------------------------------------%% Name is Fully scoped (undescore) name of interface or module    emit_hrl_head(_G, ignore, _Name, _) -> ignore;emit_hrl_head(G, Fd, Name, erlang) ->    mcomment(Fd, ["Erlang header file" |		  hrl_header(G, Name)]),    nl(Fd),    nl(Fd),    IfdefName = ic_util:to_uppercase(Name++"_HRL"),    emit(Fd, "-ifndef(~s).~n", [IfdefName]),    emit(Fd, "-define(~s, true).~n", [IfdefName]),    nl(Fd),    nl(Fd),    Fd;emit_hrl_head(G, Fd, Name, c) ->    mcomment(Fd, ["C header file" |		  hrl_header(G, Name)], c),    nl(Fd),    nl(Fd),    IfdefName = ic_util:to_uppercase(Name++"_H"),    emit(Fd, "#ifndef ~s~n", [IfdefName]),    emit(Fd, "#define ~s ~n", [IfdefName]),    nl(Fd),    nl(Fd),    Fd;emit_hrl_head(G, Fd, Name, c_server) ->    mcomment(Fd, ["C header file" | 		  hrl_header(G, [Name, "__s"])], c),    nl(Fd),    nl(Fd),    IfdefName = ic_util:to_uppercase(Name++"__S_H"),    emit(Fd, "#ifndef ~s~n", [IfdefName]),    emit(Fd, "#define ~s ~n", [IfdefName]),    nl(Fd),    nl(Fd),    Fd.hrl_header(G, Name) ->    ["",     io_lib:format("Target: ~s", [Name]),     io_lib:format("Source: ~s", [ic_genobj:idlfile(G)]),     io_lib:format("IC vsn: ~s", [?COMPILERVSN]),     "",     "This file is automatically generated. DO NOT EDIT IT."].%%--------------------------------------------------------------------%% Emit include file footer%%--------------------------------------------------------------------emit_hrl_foot(_G, erlang_template) ->    ok;emit_hrl_foot(_G, erlang_template_no_gen) ->    ok;emit_hrl_foot(G, erlang) ->    case ic_genobj:is_hrlfile_open(G) of	true ->	    Fd = ic_genobj:hrlfiled(G),	    nl(Fd),	    nl(Fd),	    emit(Fd, "-endif.\n"),	    nl(Fd),	    nl(Fd),	    Fd;	false ->	    ok    end;emit_hrl_foot(G, erlang_no_stub) ->    case ic_genobj:is_hrlfile_open(G) of	true ->	    Fd = ic_genobj:hrlfiled(G),	    nl(Fd),	    nl(Fd),	    emit(Fd, "-endif.\n"),	    nl(Fd),	    nl(Fd),	    Fd;	false ->	    ok    end;emit_hrl_foot(G, c) ->    case ic_genobj:is_hrlfile_open(G) of	true ->	    Fd = ic_genobj:hrlfiled(G),	    nl(Fd),	    nl(Fd),	    emit(Fd, "#ifdef __cplusplus\n"),            emit(Fd, "}\n"),            emit(Fd, "#endif\n"),            nl(Fd),	    emit(Fd, "#endif\n"),	    nl(Fd),	    nl(Fd),	    Fd;	false ->	    ok    end;emit_hrl_foot(G, c_server) ->    case ic_genobj:is_hrlfile_open(G) of	true ->	    Fd = ic_genobj:hrlfiled(G),	    nl(Fd),	    nl(Fd),	    emit(Fd, "#ifdef __cplusplus\n"),            emit(Fd, "}\n"),            emit(Fd, "#endif\n"),            nl(Fd),	    emit(Fd, "#endif\n"),	    nl(Fd),	    nl(Fd),	    Fd;	false ->	    ok    end;emit_hrl_foot(G, c_no_stub) ->    case ic_genobj:is_hrlfile_open(G) of	true ->	    Fd = ic_genobj:hrlfiled(G),	    nl(Fd),	    nl(Fd),	    emit(Fd, "#ifdef __cplusplus\n"),            emit(Fd, "}\n"),            emit(Fd, "#endif\n"),            nl(Fd),	    emit(Fd, "#endif\n"),	    nl(Fd),	    nl(Fd),	    Fd;	false ->	    ok    end;emit_hrl_foot(G, c_server_no_stub) ->    case ic_genobj:is_hrlfile_open(G) of	true ->	    Fd = ic_genobj:hrlfiled(G),	    nl(Fd),	    nl(Fd),	    emit(Fd, "#ifdef __cplusplus\n"),            emit(Fd, "}\n"),            emit(Fd, "#endif\n"),            nl(Fd),	    emit(Fd, "#endif\n"),	    nl(Fd),	    nl(Fd),	    Fd;	false ->	    ok    end.%%-----------------------------------------------------------------%% Internal functions%%-----------------------------------------------------------------

⌨️ 快捷键说明

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