aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ic/src/ic_erl_template.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ic/src/ic_erl_template.erl')
-rw-r--r--lib/ic/src/ic_erl_template.erl639
1 files changed, 639 insertions, 0 deletions
diff --git a/lib/ic/src/ic_erl_template.erl b/lib/ic/src/ic_erl_template.erl
new file mode 100644
index 0000000000..f5983a53bd
--- /dev/null
+++ b/lib/ic/src/ic_erl_template.erl
@@ -0,0 +1,639 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%%
+%% 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 online 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.
+%%
+%% %CopyrightEnd%
+%%
+%%
+-module(ic_erl_template).
+
+
+-export([do_gen/3, emit_header/3]).
+
+-import(ic_codegen, [emit/2, emit/3, nl/1]).
+
+-include("icforms.hrl").
+-include("ic.hrl").
+
+-include_lib("stdlib/include/erl_compile.hrl").
+
+-define(TAB, " ").
+-define(TAB2, "% ").
+
+-define(TEMPLATE_1_A,
+ "%%----------------------------------------------------------------------\n"
+ "%% <LICENSE>\n"
+ "%% \n"
+ "%% $Id$\n"
+ "%%\n"
+ "%%----------------------------------------------------------------------\n"
+ "%% Module : ~s.erl\n"
+ "%% \n"
+ "%% Source : ~s\n"
+ "%% \n"
+ "%% Description : \n"
+ "%% \n"
+ "%% Creation date: ~s\n"
+ "%%\n"
+ "%%----------------------------------------------------------------------\n"
+ "-module(~p).\n\n").
+
+-define(TEMPLATE_1_B,
+ "%%----------------------------------------------------------------------\n"
+ "%% Internal Exports\n"
+ "%%----------------------------------------------------------------------\n"
+ "-export([init/1,\n"
+ " terminate/2,\n"
+ " code_change/3,\n"
+ " handle_info/2]).\n\n"
+ "%%----------------------------------------------------------------------\n"
+ "%% Include Files\n"
+ "%%----------------------------------------------------------------------\n"
+ "\n\n"
+ "%%----------------------------------------------------------------------\n"
+ "%% Macros\n"
+ "%%----------------------------------------------------------------------\n"
+ "\n\n"
+ "%%----------------------------------------------------------------------\n"
+ "%% Records\n"
+ "%%----------------------------------------------------------------------\n"
+ "-record(state, {}).\n\n"
+ "%%======================================================================\n"
+ "%% API Functions\n"
+ "%%======================================================================\n").
+
+-define(TEMPLATE_1_C,
+ "%%======================================================================\n"
+ "%% Internal Functions\n"
+ "%%======================================================================\n"
+ "%%----------------------------------------------------------------------\n"
+ "%% Function : init/1\n"
+ "%% Arguments : Env = term()\n"
+ "%% Returns : {ok, State} |\n"
+ "%% {ok, State, Timeout} |\n"
+ "%% ignore |\n"
+ "%% {stop, Reason}\n"
+ "%% Raises : -\n"
+ "%% Description: Initiates the server\n"
+ "%%----------------------------------------------------------------------\n"
+ "init(_Env) ->\n"
+ "\t{ok, #state{}}.\n\n\n"
+ "%%----------------------------------------------------------------------\n"
+ "%% Function : terminate/2\n"
+ "%% Arguments : Reason = normal | shutdown | term()\n"
+ "%% State = term()\n"
+ "%% Returns : ok\n"
+ "%% Raises : -\n"
+ "%% Description: Invoked when the object is terminating.\n"
+ "%%----------------------------------------------------------------------\n"
+ "terminate(_Reason, _State) ->\n"
+ "\tok.\n\n\n"
+ "%%----------------------------------------------------------------------\n"
+ "%% Function : code_change/3\n"
+ "%% Arguments : OldVsn = undefined | term()\n"
+ "%% State = NewState = term()\n"
+ "%% Extra = term()\n"
+ "%% Returns : {ok, NewState}\n"
+ "%% Raises : -\n"
+ "%% Description: Invoked when the object should update its internal state\n"
+ "%% due to code replacement.\n"
+ "%%----------------------------------------------------------------------\n"
+ "code_change(_OldVsn, State, _Extra) ->\n"
+ "\t{ok, State}.\n\n\n"
+ "%%----------------------------------------------------------------------\n"
+ "%% Function : handle_info/2\n"
+ "%% Arguments : Info = normal | shutdown | term()\n"
+ "%% State = NewState = term()\n"
+ "%% Returns : {noreply, NewState} |\n"
+ "%% {noreply, NewState, Timeout} |\n"
+ "%% {stop, Reason, NewState}\n"
+ "%% Raises : -\n"
+ "%% Description: Invoked when, for example, the server traps exits.\n"
+ "%%----------------------------------------------------------------------\n"
+ "handle_info(_Info, State) ->\n"
+ "\t{noreply, State}.\n\n\n").
+
+-define(TEMPLATE_2_A,
+ "%%% #0. BASIC INFORMATION\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "%%% %CCaseFile : ~s.erl %\n"
+ "%%% Author : \n"
+ "%%% Description : \n"
+ "%%%\n"
+ "%%% Modules used: \n"
+ "%%%\n"
+ "%%%\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "-module(~p).\n"
+ "-author('unknown').\n"
+ "-id('').\n"
+ "-vsn('').\n"
+ "-date('~s').\n\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "%%% Template Id: <ID>\n"
+ "%%%\n"
+ "%%% #Copyright (C) 2004\n"
+ "%%% by <COMPANY>\n"
+ "%%% <ADDRESS>\n"
+ "%%% <OTHER INFORMATION>\n"
+ "%%% \n"
+ "%%% <LICENSE>\n"
+ "%%% \n"
+ "%%% \n"
+ "%%% ----------------------------------------------------------------------\n"
+ "%%% #1. REVISION LOG\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "%%% Rev Date Name What\n"
+ "%%% ----- ------- -------- --------------------------\n"
+ "%%% \n"
+ "%%% ----------------------------------------------------------------------\n"
+ "%%%\n"
+ "%%% \n"
+ "%%% #2. EXPORT LISTS\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "%%% #2.1 EXPORTED INTERFACE FUNCTIONS\n"
+ "%%% ----------------------------------------------------------------------\n").
+
+-define(TEMPLATE_2_B,
+ "%%% ----------------------------------------------------------------------\n"
+ "%%% #2.2 EXPORTED INTERNAL FUNCTIONS\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "-export([init/1,\n"
+ " terminate/2,\n"
+ " code_change/3,\n"
+ " handle_info/2]).\n\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "%%% #2.3 INCLUDE FILES\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "\n\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "%%% #2.4 MACROS\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "\n\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "%%% #2.5 RECORDS\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "-record(state, {}).\n\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "%%% #3. CODE\n"
+ "%%% #---------------------------------------------------------------------\n"
+ "%%% #3.1 CODE FOR EXPORTED INTERFACE FUNCTIONS\n"
+ "%%% #---------------------------------------------------------------------\n").
+
+-define(TEMPLATE_2_C,
+ "%%% ----------------------------------------------------------------------\n"
+ "%%% #3.3 CODE FOR INTERNAL FUNCTIONS\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "%%% # init/1\n"
+ "%%% Input : Env = term()\n"
+ "%%% Output : {ok, State} |\n"
+ "%%% {ok, State, Timeout} |\n"
+ "%%% ignore |\n"
+ "%%% {stop, Reason}\n"
+ "%%% Exceptions : -\n"
+ "%%% Description: Initiates the server\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "init(_Env) ->\n"
+ "\t{ok, #state{}}.\n\n\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "%%% # terminate/2\n"
+ "%%% Input : Reason = normal | shutdown | term()\n"
+ "%%% State = term()\n"
+ "%%% Output : ok\n"
+ "%%% Exceptions : -\n"
+ "%%% Description: Invoked when the object is terminating.\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "terminate(_Reason, _State) ->\n"
+ "\tok.\n\n\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "%%% # code_change/3\n"
+ "%%% Input : OldVsn = undefined | term()\n"
+ "%%% State = NewState = term()\n"
+ "%%% Extra = term()\n"
+ "%%% Output : {ok, NewState}\n"
+ "%%% Exceptions : -\n"
+ "%%% Description: Invoked when the object should update its internal state\n"
+ "%%% due to code replacement.\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "code_change(_OldVsn, State, _Extra) ->\n"
+ "\t{ok, State}.\n\n\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "%%% # handle_info/2\n"
+ "%%% Input : Info = normal | shutdown | term()\n"
+ "%%% State = NewState = term()\n"
+ "%%% Output : {noreply, NewState} |\n"
+ "%%% {noreply, NewState, Timeout} |\n"
+ "%%% {stop, Reason, NewState}\n"
+ "%%% Exceptions : -\n"
+ "%%% Description: Invoked when, for example, the server traps exits.\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "handle_info(_Info, State) ->\n"
+ "\t{noreply, State}.\n\n\n"
+ "%%% ----------------------------------------------------------------------\n"
+ "%%% #4 CODE FOR TEMPORARY CORRECTIONS\n"
+ "%%% ----------------------------------------------------------------------\n\n").
+
+
+%%------------------------------------------------------------
+%%
+%% Generate the client side Erlang stubs.
+%%
+%% Each module is generated to a separate file.
+%%
+%% Export declarations for all interface functions must be
+%% generated. Each function then needs to generate a function head and
+%% a body. IDL parameters must be converted into Erlang parameters
+%% (variables, capitalised) and a type signature list must be
+%% generated (for later encode/decode).
+%%
+%%------------------------------------------------------------
+do_gen(G, _File, Form) ->
+ gen_head(G, [], Form),
+ gen(G, [], Form).
+
+
+gen(G, N, [X|Xs]) when is_record(X, preproc) ->
+ NewG = ic:handle_preproc(G, N, X#preproc.cat, X),
+ gen(NewG, N, Xs);
+gen(G, N, [X|Xs]) when is_record(X, module) ->
+ G2 = ic_file:filename_push(G, N, X, erlang_template_no_gen),
+ N2 = [ic_forms:get_id2(X) | N],
+ gen_head(G2, N2, X),
+ gen(G2, N2, ic_forms:get_body(X)),
+ G3 = ic_file:filename_pop(G2, erlang_template_no_gen),
+ gen(G3, N, Xs);
+gen(G, N, [X|Xs]) when is_record(X, interface) ->
+ G2 = ic_file:filename_push(G, N, X, erlang_template),
+ N2 = [ic_forms:get_id2(X) | N],
+ gen_head(G2, N2, X),
+ gen(G2, N2, ic_forms:get_body(X)),
+ lists:foreach(fun({_Name, Body}) -> gen(G2, N2, Body) end,
+ X#interface.inherit_body),
+ Fd = ic_genobj:stubfiled(G2),
+ case get_template_version(G2) of
+ ?IC_FLAG_TEMPLATE_2 ->
+ emit(Fd, ?TEMPLATE_2_C, []);
+ _ ->
+ emit(Fd, ?TEMPLATE_1_C, [])
+ end,
+ G3 = ic_file:filename_pop(G2, erlang_template),
+ gen(G3, N, Xs);
+gen(G, N, [X|Xs]) when is_record(X, op) ->
+ {Name, InArgNames, OutArgNames, Reply} = extract_info(X),
+ emit_function(G, N, X, ic_genobj:is_stubfile_open(G),
+ ic_forms:is_oneway(X), Name, InArgNames, OutArgNames, Reply),
+ gen(G, N, Xs);
+gen(G, N, [X|Xs]) when is_record(X, attr) ->
+ emit_attr(G, N, X, ic_genobj:is_stubfile_open(G), fun emit_function/9),
+ gen(G, N, Xs);
+gen(G, N, [_X|Xs]) ->
+ gen(G, N, Xs);
+gen(_G, _N, []) ->
+ ok.
+
+%% Module Header
+emit_header(G, Fd, Name) ->
+ Date = get_date(),
+ case get_template_version(G) of
+ ?IC_FLAG_TEMPLATE_2 ->
+ emit(Fd, ?TEMPLATE_2_A, [Name, list_to_atom(Name), Date]);
+ _ ->
+ IDLFile = ic_genobj:idlfile(G),
+ emit(Fd, ?TEMPLATE_1_A, [Name, IDLFile, Date, list_to_atom(Name)])
+ end.
+
+
+emit_attr(G, N, X, Open, F) ->
+ XX = #id_of{type=X},
+ lists:foreach(fun(Id) ->
+ X2 = XX#id_of{id=Id},
+ IsOneWay = ic_forms:is_oneway(X2),
+ {Get, Set} = mk_attr_func_names(N, ic_forms:get_id(Id)),
+ F(G, N, X2, Open, IsOneWay, Get, [], [],
+ [{ic_util:mk_var(ic_forms:get_id(Id)),
+ ic_forms:get_tk(X)}]),
+ case X#attr.readonly of
+ {readonly, _} ->
+ ok;
+ _ ->
+ F(G, N, X2, Open, IsOneWay, Set,
+ [{ic_util:mk_var(ic_forms:get_id(Id)),
+ ic_forms:get_tk(X)}], [], ["ok"])
+ end
+ end, ic_forms:get_idlist(X)).
+
+
+%% The automaticly generated get and set operation names for an
+%% attribute.
+mk_attr_func_names(_Scope, Name) ->
+ {"_get_" ++ Name, "_set_" ++ Name}.
+
+
+extract_info(X) when is_record(X, op) ->
+ Name = ic_forms:get_id2(X),
+ InArgs = ic:filter_params([in,inout], X#op.params),
+ OutArgs = ic:filter_params([out,inout], X#op.params),
+ Reply = case ic_forms:get_tk(X) of
+ tk_void ->
+ ["ok"];
+ Type ->
+ [{"OE_Reply", Type}]
+ end,
+ InArgsTypeList =
+ [{ic_util:mk_var(ic_forms:get_id(InArg#param.id)),
+ ic_forms:get_tk(InArg)} || InArg <- InArgs ],
+ OutArgsTypeList =
+ [{ic_util:mk_var(ic_forms:get_id(OutArg#param.id)),
+ ic_forms:get_tk(OutArg)} || OutArg <- OutArgs ],
+ {Name, InArgsTypeList, OutArgsTypeList, Reply}.
+
+get_template_version(G) ->
+ case ic_options:get_opt(G, flags) of
+ Flags when is_integer(Flags) ->
+ case ?IC_FLAG_TEST(Flags, ?IC_FLAG_TEMPLATE_2) of
+ true ->
+ ?IC_FLAG_TEMPLATE_2;
+ false ->
+ ?IC_FLAG_TEMPLATE_1
+ end;
+ _ ->
+ ?IC_FLAG_TEMPLATE_1
+ end.
+
+
+get_date() ->
+ {{Y,M,D}, _} = calendar:now_to_datetime(now()),
+ if
+ M < 10, D < 10 ->
+ lists:concat([Y, "-0", M, "-0",D]);
+ M < 10 ->
+ lists:concat([Y, "-0", M, "-", D]);
+ D < 10 ->
+ lists:concat([Y, "-", M, "-0", D]);
+ true ->
+ lists:concat([Y, "-", M, "-", D])
+ end.
+
+
+%%------------------------------------------------------------
+%%
+%% Export stuff
+%%
+%% Gathering of all names that should be exported from a stub
+%% file.
+%%
+
+
+gen_head_special(G, N, X) when is_record(X, interface) ->
+ Fd = ic_genobj:stubfiled(G),
+ lists:foreach(fun({_Name, Body}) ->
+ ic_codegen:export(Fd, exp_top(G, N, Body, []))
+ end, X#interface.inherit_body),
+ nl(Fd),
+ ok;
+gen_head_special(_G, _N, _X) ->
+ ok.
+
+
+%% Generate all export declarations
+gen_head(G, N, X) ->
+ case ic_genobj:is_stubfile_open(G) of
+ true ->
+ Fd = ic_genobj:stubfiled(G),
+ ic_codegen:export(Fd, exp_top(G, N, X, [])),
+ gen_head_special(G, N, X),
+ case get_template_version(G) of
+ ?IC_FLAG_TEMPLATE_2 ->
+ emit(Fd, ?TEMPLATE_2_B, []);
+ _ ->
+ emit(Fd, ?TEMPLATE_1_B, [])
+ end;
+ false ->
+ ok
+ end.
+
+exp_top(_G, _N, X, Acc) when element(1, X) == preproc ->
+ Acc;
+exp_top(G, N, L, Acc) when is_list(L) ->
+ exp_list(G, N, L, Acc);
+exp_top(G, N, M, Acc) when is_record(M, module) ->
+ exp_list(G, N, ic_forms:get_body(M), Acc);
+exp_top(G, N, I, Acc) when is_record(I, interface) ->
+ exp_list(G, N, ic_forms:get_body(I), Acc);
+exp_top(G, N, X, Acc) ->
+ exp3(G, N, X, Acc).
+
+exp3(G, N, Op, Acc) when is_record(Op, op) ->
+ FuncName = ic_forms:get_id(Op#op.id),
+ Arity = length(ic:filter_params([in, inout], Op#op.params)) + 1 +
+ count_extras(G, N, Op),
+ [{FuncName, Arity} | Acc];
+exp3(G, N, A, Acc) when is_record(A, attr) ->
+ Extra = count_extras(G, N, A),
+ lists:foldr(fun(Id, Acc2) ->
+ {Get, Set} = mk_attr_func_names([], ic_forms:get_id(Id)),
+ case A#attr.readonly of
+ {readonly, _} ->
+ [{Get, 1 + Extra} | Acc2];
+ _ ->
+ [{Get, 1 + Extra}, {Set, 2 + Extra} | Acc2]
+ end
+ end, Acc, ic_forms:get_idlist(A));
+exp3(_G, _N, _X, Acc) ->
+ Acc.
+
+exp_list(G, N, L, OrigAcc) ->
+ lists:foldr(fun(X, Acc) ->
+ exp3(G, N, X, Acc)
+ end, OrigAcc, L).
+
+count_extras(G, N, Op) ->
+ case {use_this(G, N, Op), use_from(G, N, Op)} of
+ {[], []} ->
+ 0;
+ {[], _} ->
+ 1;
+ {_, []} ->
+ 1;
+ _ ->
+ 2
+ end.
+
+%%------------------------------------------------------------
+%%
+%% Emit stuff
+%%
+%% Low level generation primitives
+%%
+
+emit_function(_G, _N, _X, false, _, _, _, _, _) ->
+ ok;
+emit_function(G, N, X, true, false, Name, InArgs, OutArgs, Reply) ->
+ Fd = ic_genobj:stubfiled(G),
+ This = use_this(G, N, Name),
+ From = use_from(G, N, Name),
+ State = ["State"],
+ Vers = get_template_version(G),
+ case OutArgs of
+ [] ->
+ ReplyString = create_string(Reply),
+ emit_function_header(G, Fd, X, N, Name, create_extra(This, From, Vers),
+ InArgs, length(InArgs), OutArgs, Reply,
+ ReplyString, Vers),
+ emit(Fd, "~p(~s) ->\n\t{reply, ~s, State}.\n\n",
+ [ic_util:to_atom(Name), create_string(This ++ From ++ State ++ InArgs),
+ ReplyString]);
+ _ ->
+ ReplyString = "{" ++ create_string(Reply ++ OutArgs) ++ "}",
+ emit_function_header(G, Fd, X, N, Name, create_extra(This, From, Vers),
+ InArgs, length(InArgs), OutArgs, Reply,
+ ReplyString, Vers),
+ emit(Fd, "~p(~s) ->\n\t{reply, ~s, State}.\n\n",
+ [ic_util:to_atom(Name), create_string(This ++ From ++ State ++ InArgs),
+ ReplyString])
+ end;
+emit_function(G, N, X, true, true, Name, InArgs, _OutArgs, _Reply) ->
+ Fd = ic_genobj:stubfiled(G),
+ This = use_this(G, N, Name),
+ State = ["State"],
+ Vers = get_template_version(G),
+ emit_function_header(G, Fd, X, N, Name, create_extra(This, [], Vers),
+ InArgs, length(InArgs), "", "", "", Vers),
+ emit(Fd, "~p(~s) ->\n\t{noreply, State}.\n\n",
+ [ic_util:to_atom(Name), create_string(This ++ State ++ InArgs)]).
+
+create_string([]) ->
+ "";
+create_string([{Name, _Type}|T]) ->
+ Name ++ create_string2(T);
+create_string([Name|T]) ->
+ Name ++ create_string2(T).
+
+create_string2([{Name, _Type}|T]) ->
+ ", " ++ Name ++ create_string2(T);
+create_string2([Name|T]) ->
+ ", " ++ Name ++ create_string2(T);
+create_string2([]) ->
+ "".
+
+create_extra([], [], _Vers) ->
+ {"State - term()", 1};
+create_extra([], _From, ?IC_FLAG_TEMPLATE_2) ->
+ {"OE_From - term()\n%%% " ++ ?TAB ++ "State - term()", 2};
+create_extra([], _From, _Vers) ->
+ {"OE_From - term()\n%% " ++ ?TAB ++ "State - term()", 2};
+create_extra(_This, [], ?IC_FLAG_TEMPLATE_2) ->
+ {"OE_This - #objref{} (i.e., self())\n%%% " ++ ?TAB ++ "State - term()", 2};
+create_extra(_This, [], _Vers) ->
+ {"OE_This - #objref{} (i.e., self())\n%% " ++ ?TAB ++ "State - term()", 2};
+create_extra(_This, _From, ?IC_FLAG_TEMPLATE_2) ->
+ {"OE_This - #objref{} (i.e., self())\n%%% " ++ ?TAB ++
+ "OE_From - term()\n%%% " ++ ?TAB ++ "State - term()", 3};
+create_extra(_This, _From, _Vers) ->
+ {"OE_This - #objref{} (i.e., self())\n%% " ++ ?TAB ++
+ "OE_From - term()\n%% " ++ ?TAB ++ "State - term()", 3}.
+
+use_this(G, N, OpName) ->
+ FullOp = ic_util:to_colon([OpName|N]),
+ FullIntf = ic_util:to_colon(N),
+ case {ic_options:get_opt(G, {this, FullIntf}),
+ ic_options:get_opt(G, {this, FullOp}),
+ ic_options:get_opt(G, {this, true})} of
+ {_, force_false, _} ->
+ [];
+ {force_false, false, _} ->
+ [];
+ {false, false, false} ->
+ [];
+ _ ->
+ ["OE_This"]
+ end.
+
+use_from(G, N, OpName) ->
+ FullOp = ic_util:to_colon([OpName|N]),
+ FullIntf = ic_util:to_colon(N),
+ case {ic_options:get_opt(G, {from, FullIntf}),
+ ic_options:get_opt(G, {from, FullOp}),
+ ic_options:get_opt(G, {from, true})} of
+ {_, force_false, _} ->
+ [];
+ {force_false, false, _} ->
+ [];
+ {false, false, false} ->
+ [];
+ _ ->
+ ["OE_From"]
+ end.
+
+
+emit_function_header(G, Fd, X, N, Name, {Extra, ExtraNo}, InP, Arity, OutP,
+ Reply, ReplyString, ?IC_FLAG_TEMPLATE_2) ->
+ emit(Fd,
+ "%%% ----------------------------------------------------------------------\n"
+ "%%% # ~p/~p\n"
+ "%%% Input : ~s\n",
+ [ic_util:to_atom(Name), (ExtraNo+Arity), Extra]),
+ ic_code:type_expand_all(G, N, X, Fd, ?TAB2, InP),
+ case Reply of
+ ["ok"] ->
+ emit(Fd, "%%% Output : ReturnValue = ~s\n", [ReplyString]);
+ _ ->
+ emit(Fd, "%%% Output : ReturnValue = ~s\n", [ReplyString]),
+ ic_code:type_expand_all(G, N, X, Fd, "% ", Reply)
+ end,
+ ic_code:type_expand_all(G, N, X, Fd, ?TAB2, OutP),
+ emit(Fd,
+ "%%% Exceptions : ~s\n"
+ "%%% Description: \n"
+ "%%% ----------------------------------------------------------------------\n",
+ [get_raises(X, ?IC_FLAG_TEMPLATE_2)]);
+emit_function_header(G, Fd, X, N, Name, {Extra, ExtraNo}, InP, Arity, OutP,
+ Reply, ReplyString, Vers) ->
+ emit(Fd,
+ "%%----------------------------------------------------------------------\n"
+ "%% Function : ~p/~p\n"
+ "%% Arguments : ~s\n",
+ [ic_util:to_atom(Name), (ExtraNo+Arity), Extra]),
+ ic_code:type_expand_all(G, N, X, Fd, ?TAB, InP),
+ case Reply of
+ ["ok"] ->
+ emit(Fd, "%% Returns : ReturnValue = ~s\n", [ReplyString]);
+ _ ->
+ emit(Fd, "%% Returns : ReturnValue = ~s\n", [ReplyString]),
+ ic_code:type_expand_all(G, N, X, Fd, " ", Reply)
+ end,
+ ic_code:type_expand_all(G, N, X, Fd, ?TAB, OutP),
+ emit(Fd,
+ "%% Raises : ~s\n"
+ "%% Description: \n"
+ "%%----------------------------------------------------------------------\n",
+ [get_raises(X, Vers)]).
+
+get_raises(#op{raises = []}, _Vers) ->
+ "";
+get_raises(#op{raises = ExcList}, Vers) ->
+ get_raises2(ExcList, [], Vers);
+get_raises(_X, _Vers) ->
+ [].
+
+get_raises2([H], Acc, _Vers) ->
+ lists:flatten(lists:reverse([ic_util:to_colon(H)|Acc]));
+get_raises2([H|T], Acc, ?IC_FLAG_TEMPLATE_2) ->
+ get_raises2(T, ["\n%%% ", ic_util:to_colon(H) |Acc],
+ ?IC_FLAG_TEMPLATE_2);
+get_raises2([H|T], Acc, _Vers) ->
+ get_raises2(T, ["\n%% ", ic_util:to_colon(H) |Acc], _Vers).
+