1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2012-2016. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20 21-module(prepare_templates). 22-export([gen_asn1ct_rtt/1,gen_asn1ct_eval/1]). 23 24gen_asn1ct_rtt(Ms) -> 25 {ok,Fd} = file:open("asn1ct_rtt.erl", [write]), 26 io:format(Fd, 27 "%% Generated by ~s. DO NOT EDIT THIS FILE.\n" 28 "%%\n" 29 "%% Input files:\n", [?MODULE]), 30 [io:put_chars(Fd, ["%% ",M,$\n]) || M <- Ms], 31 io:nl(Fd), 32 io:put_chars(Fd, 33 "-module(asn1ct_rtt).\n" 34 "-export([assert_defined/1,dependencies/1,code/0]).\n" 35 "\n"), 36 Forms = lists:sort(lists:append([abstract(M) || M <- Ms])), 37 Exp = lists:sort(exports(Forms)), 38 defined(Fd, Exp), 39 io:nl(Fd), 40 Calls = calls(Forms), 41 R = sofs:relation(Calls), 42 Fam0 = sofs:relation_to_family(R), 43 Fam = sofs:to_external(Fam0), 44 dependencies(Fd, Fam), 45 io:nl(Fd), 46 Funcs = [begin 47 Bin = list_to_binary([$\n|erl_pp:function(Func)]), 48 {{M,F,A},Bin} 49 end || {M,{function,_,F,A,_}=Func} <- Forms], 50 io:format(Fd, "code() ->\n~p.\n\n", [Funcs]), 51 ok = file:close(Fd), 52 halt(0). 53 54gen_asn1ct_eval([File]) -> 55 Output = filename:rootname(File, ".funcs") ++ ".erl", 56 {ok,Fd} = file:open(Output, [write]), 57 {ok,Funcs} = file:consult(File), 58 asn1ct_func:start_link(), 59 [asn1ct_func:need(MFA) || MFA <- Funcs], 60 io:format(Fd, 61 "%% Generated by ~s. DO NOT EDIT THIS FILE.\n" 62 "%%\n" 63 "%% Input file: ~s\n\n", [?MODULE,File]), 64 io:format(Fd, "-module(~s).\n", [filename:rootname(File)]), 65 gen_asn1ct_eval_exp(Fd, Funcs), 66 asn1ct_func:generate(Fd), 67 ok = file:close(Fd), 68 halt(0). 69 70gen_asn1ct_eval_exp(Fd, Funcs) -> 71 io:put_chars(Fd, "-export(["), 72 gen_asn1ct_eval_exp_1(Fd, Funcs, ""), 73 io:put_chars(Fd, "]).\n"). 74 75gen_asn1ct_eval_exp_1(Fd, [{_,F,A}|T], Sep) -> 76 io:put_chars(Fd, Sep), 77 io:format(Fd, "~p/~p", [F,A]), 78 gen_asn1ct_eval_exp_1(Fd, T, ",\n"); 79gen_asn1ct_eval_exp_1(_, [], _) -> ok. 80 81defined(Fd, [H|T]) -> 82 io:format(Fd, "assert_defined(~p) -> ok", [H]), 83 case T of 84 [] -> 85 io:put_chars(Fd, ".\n"); 86 [_|_] -> 87 io:put_chars(Fd, ";\n"), 88 defined(Fd, T) 89 end. 90 91dependencies(Fd, [{K,V}|T]) -> 92 io:format(Fd, "dependencies(~p) ->\n~p;\n", [K,V]), 93 dependencies(Fd, T); 94dependencies(Fd, []) -> 95 io:put_chars(Fd, "dependencies(_) -> [].\n"). 96 97abstract(File) -> 98 {ok,{M0,[{abstract_code,Abstract}]}} = 99 beam_lib:chunks(File, [abstract_code]), 100 {raw_abstract_v1,Forms} = Abstract, 101 M = module(M0), 102 [{M,F} || F <- Forms]. 103 104module(M0) -> 105 "asn1rtt_" ++ M = atom_to_list(M0), 106 list_to_atom(M). 107 108exports([{M,{attribute,_,export,L}}|T]) -> 109 [{M,F,A} || {F,A} <- L] ++ exports(T); 110exports([_|T]) -> 111 exports(T); 112exports([]) -> []. 113 114calls([{M,{function,_,F,A,Body}}|T]) -> 115 MFA = {M,F,A}, 116 case find_calls(Body, M) -- [MFA] of 117 [] -> 118 calls(T); 119 [_|_]=Calls -> 120 [{MFA,Callee} || Callee <- Calls] ++ calls(T) 121 end; 122calls([_|T]) -> 123 calls(T); 124calls([]) -> []. 125 126find_calls([{call,_,{atom,_,F},Args}|T], M) -> 127 Calls = find_calls(Args, M) ++ find_calls(T, M), 128 Arity = length(Args), 129 case is_bif(F, Arity) of 130 false -> 131 [{M,F,Arity}|Calls]; 132 true -> 133 Calls 134 end; 135find_calls([{'fun',_,{function,F,A}}|T], M) -> 136 [{M,F,A}|find_calls(T, M)]; 137find_calls([H|T], M) -> 138 find_calls(H, M) ++ find_calls(T, M); 139find_calls(Tuple, M) when is_tuple(Tuple) -> 140 find_calls(tuple_to_list(Tuple), M); 141find_calls(_, _) -> []. 142 143is_bif(F, Arity) -> 144 erl_internal:bif(F, Arity). 145