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 + -
显示快捷键?