26
26
-export([encode/2, encode/3, decode/3]).
27
27
-export([test/1, test/2, test/3, value/2]).
28
28
%% Application internal exports
29
-export([compile_asn/3,compile_asn1/3,compile_py/3,compile/3,value/1,vsn/0,
29
-export([compile_asn/3,compile_asn1/3,compile_py/3,compile/3,compile_inline/4,
30
31
create_ets_table/2,get_name_of_def/1,get_pos_of_def/1]).
31
32
-export([read_config_data/1,get_gen_state_field/1,get_gen_state/0,
32
33
partial_inc_dec_toptype/1,save_gen_state/1,update_gen_state/2,
84
85
[ber_bin_v2|Options--[ber_bin]];
87
case (catch input_file_type(File)) of
88
{single_file,PrefixedFile} ->
89
(catch compile1(PrefixedFile,Options1));
88
Options2 = includes(File,Options1),
89
Includes=[I||{i,I}<-Options2],
90
case (catch input_file_type(File,Includes)) of
91
{single_file,SuffixedFile} -> %% "e.g. "/tmp/File.asn"
92
(catch compile1(SuffixedFile,Options2));
90
93
{multiple_files_file,SetBase,FileName} ->
91
FileList = get_file_list(FileName),
92
(catch compile_set(SetBase,filename:dirname(FileName),
94
FileList = get_file_list(FileName,Includes),
95
io:format("FileList: ~p~n",[FileList]),
96
case [X||{inline,X}<-Options2] of
98
(catch compile_set(SetBase,filename:dirname(FileName),
102
[filename:rootname(filename:basename(X))||X<-FileList],
103
(catch compile_inline(OutputName,filename:dirname(FileName),NewFileList,Options2))
94
105
Err = {input_file_error,_Reason} ->
106
118
Includes = [I || {i,I} <- Options],
107
119
EncodingRule = get_rule(Options),
108
120
create_ets_table(asn1_functab,[named_table]),
109
Continue1 = scan({true,true},File,Options),
121
Continue1 = scan(File,Options),
110
122
Continue2 = parse(Continue1,File,Options),
111
123
Continue3 = check(Continue2,File,OutFile,Includes,EncodingRule,
112
124
DbFile,Options,[]),
114
126
delete_tables([asn1_functab]),
115
127
compile_erl(Continue4,OutFile,Options).
117
130
%%****************************************************************************%%
118
131
%% functions dealing with compiling of several input files to one output file %%
119
132
%%****************************************************************************%%
136
%% compiles a number of modules, merges the resulting erlang modules with
137
%% the appropriate run-time modules so the resulting module contains all
138
%% run-time asn1 functionality. Then compiles the resulting file to beam code.
139
%% The merging is done by the igor module. If this function is used in older
140
%% versions than R10B the igor module, part of user contribution syntax_tools,
141
%% must be provided. It is possible to pass options for the ASN1 compiler
144
%% Modules -> [filename()]
145
%% Options -> [term()]
146
%% filename() -> file:filename()
147
compile_inline(Name,DirName,Modules,Options) ->
149
case {lists:member(optimize,Options),lists:member(ber_bin,Options)} of
151
[ber_bin_v2|Options--[ber_bin]];
155
Fun = fun(M)-> compile(filename:join([DirName,M]),Options1) end,
156
lists:foreach(Fun,Modules),
157
RTmodule = get_runtime_mod(Options1),
158
IgorOptions = igorify_options(remove_asn_flags(Options1)),
159
io:format("*****~nName: ~p~nModules: ~p~nIgorOptions: ~p~n*****",
160
[Name,Modules++RTmodule,IgorOptions]),
161
case catch igor:merge(Name,Modules++RTmodule,[{preprocess,true},{stubs,false}]++IgorOptions) of
162
{'EXIT',{undef,Reason}} -> %% module igor first in R10B
163
io:format("Module igor in syntax_tools must be available:~n~p~n",
165
{error,'no_compilation'};
167
{error,'no_compilation'};
169
io:format("compiling output module: ~p~n",[Name]),
170
erl_compile(generated_file(Name,IgorOptions),Options1)
173
%% compile_set/4 merges and compiles a number of asn1 modules
174
%% specified in a .set.asn file to one .erl file.
120
175
compile_set(SetBase,DirName,Files,Options) when list(hd(Files)),list(Options) ->
121
176
%% case when there are several input files in a list
122
177
io:format("Erlang ASN.1 version ~p compiling ~p ~n",[?vsn,Files]),
636
691
scan_set(DirName,Files,Options) ->
639
case scan({true,true},filename:join([DirName,F]),Options) of
694
case scan(filename:join([DirName,F]),Options) of
640
695
{false,{error,Reason}} ->
641
696
throw({error,{'scan error in file:',F,Reason}});
642
697
{TrueOrFalse,Res} ->
807
case get_input_file(Module,[SourceDir|Includes]) of
808
{file,PrefixedFile} ->
809
case dbfile_uptodate(PrefixedFile,Options1) of
860
case get_input_file(Module,[SourceDir|Includes]) of
861
%% search for asn1 source
862
{file,SuffixedASN1source} ->
863
case dbfile_uptodate(SuffixedASN1source,Options1) of
811
parse_and_save1(PrefixedFile,Options1);
865
parse_and_save1(SuffixedASN1source,Options1,Includes);
869
io:format("Warning: could not do a consistency check of the ~p file: no asn1 source file was found.~n",[lists:concat([Module,".asn1db"])]),
815
870
{error,{asn1,input_file_error,Err}}
817
parse_and_save1(File,Options) ->
872
parse_and_save1(File,Options,Includes) ->
818
873
Ext = filename:extension(File),
819
874
Base = filename:basename(File,Ext),
820
875
DbFile = outfile(Base,"asn1db",Options),
821
Includes = [I || {i,I} <- Options],
822
Continue1 = scan({true,true},File,Options),
876
Continue1 = scan(File,Options),
824
878
case parse(Continue1,File,Options) of
825
879
{true,Mod} -> Mod;
827
exit({error,{asn1,File,"no such file or directory"}})
881
%% io:format("~p~nnow I die!!!!!!!!!!!~n",[File]),
882
exit({error,{asn1,File,"no such file"}})
829
start(["."|Includes]),
884
% start(["."|Includes]),
830
886
case asn1ct_check:storeindb(M) of
832
888
asn1_db:dbsave(DbFile,M#module.name)
837
893
get_input_file(Module,[I|Includes]) ->
838
894
case (catch input_file_type(filename:join([I,Module]))) of
839
895
{single_file,FileName} ->
840
case file:read_file_info(FileName) of
896
%% case file:read_file_info(FileName) of
843
_ -> get_input_file(Module,Includes)
899
%% _ -> get_input_file(Module,Includes)
846
902
get_input_file(Module,Includes)
897
951
compile_erl({false,Result},_,_) ->
954
input_file_type(Name,I) ->
955
case input_file_type(Name) of
956
{error,_} -> input_file_type2(filename:basename(Name),I);
957
Err={input_file_error,_} -> Err;
960
input_file_type2(Name,[I|Is]) ->
961
case input_file_type(filename:join([I,Name])) of
962
{error,_} -> input_file_type2(Name,Is);
963
Err={input_file_error,_} -> Err;
966
input_file_type2(Name,[]) ->
967
input_file_type(Name).
900
969
input_file_type([]) ->
902
971
input_file_type(File) ->
910
979
{ok,_FileInfo} ->
911
980
{single_file, lists:concat([File,".asn"])};
913
{single_file, lists:concat([File,".py"])}
982
case file:read_file_info(lists:concat([File,".py"])) of
984
{single_file, lists:concat([File,".py"])};
917
991
case read_config_file(File,asn1_module) of
918
992
{ok,Asn1Module} ->
919
put(asn1_config_file,File),
993
% put(asn1_config_file,File),
920
994
input_file_type(Asn1Module);
925
Base = filename:basename(File,Asn1PFix),
926
case filename:extension(Base) of
929
SetPFix when (SetPFix == ".set") ->
930
{multiple_files_file,
931
list_to_atom(filename:basename(Base,SetPFix)),
934
throw({input_file_error,{'Bad input file',File}})
999
Base = filename:basename(File,Asn1SFix),
1001
case filename:extension(Base) of
1004
SetSFix when (SetSFix == ".set") ->
1005
{multiple_files_file,
1006
list_to_atom(filename:basename(Base,SetSFix)),
1009
throw({input_file_error,{'Bad input file',File}})
1011
%% check that the file exists
1012
case file:read_file_info(File) of
938
get_file_list(File) ->
1018
get_file_list(File,Includes) ->
939
1019
case file:open(File,read) of
940
1020
{error,Reason} ->
941
1021
{error,{File,file:format_error(Reason)}};
943
get_file_list1(Stream,[])
1023
get_file_list1(Stream,filename:dirname(File),Includes,[])
946
get_file_list1(Stream,Acc) ->
1026
get_file_list1(Stream,Dir,Includes,Acc) ->
947
1027
Ret = io:get_line(Stream,''),
950
1030
file:close(Stream),
951
1031
lists:reverse(Acc);
954
case (catch input_file_type(lists:delete($\n,FileName))) of
1034
case (catch input_file_type(filename:join([Dir,lists:delete($\n,FileName)]),Includes)) of
955
1035
{empty_name,[]} -> [];
956
1036
{single_file,Name} -> [Name];
957
{multiple_files_file,Name} ->
959
Err = {input_file_error,_Reason} ->
1037
{multiple_files_file,_,Name} ->
1038
get_file_list(Name,Includes);
962
get_file_list1(Stream,PrefixedNameList++Acc)
1042
get_file_list1(Stream,Dir,Includes,SuffixedNameList++Acc)
965
1045
get_rule(Options) ->
1057
get_runtime_mod(Options) ->
1059
case get_rule(Options) of
1060
per -> ["asn1rt_per_v1.erl"];
1061
ber -> ["asn1rt_ber_bin.erl"];
1063
case lists:member(optimize,Options) of
1064
true -> ["asn1rt_per_bin_rt2ct.erl"];
1065
_ -> ["asn1rt_per_bin.erl"]
1067
ber_bin -> ["asn1rt_ber_bin.erl"];
1068
ber_bin_v2 -> ["asn1rt_ber_bin_v2.erl"]
1070
RtMod1++["asn1rt_check.erl","asn1rt_driver_handler.erl"].
977
1073
erl_compile(OutFile,Options) ->
978
1074
% io:format("Options:~n~p~n",[Options]),
979
1075
case lists:member(noobj,Options) of
1111
igorify_options(Options) ->
1112
case lists:keysearch(outdir,1,Options) of
1114
Options1 = lists:keydelete(outdir,1,Options),
1115
[{dir,Dir}|Options1];
1120
generated_file(Name,Options) ->
1121
case lists:keysearch(dir,1,Options) of
1123
filename:join([Dir,filename:basename(Name)]);
1015
1128
debug_off(_Options) ->
1016
1129
erase(asndebug),
1017
1130
erase(asn_keyed_list).
1020
outfile(Base, Ext, Opts) when atom(Ext) ->
1021
outfile(Base, atom_to_list(Ext), Opts);
1022
1133
outfile(Base, Ext, Opts) ->
1134
% io:format("Opts. ~p~n",[Opts]),
1023
1135
Obase = case lists:keysearch(outdir, 1, Opts) of
1024
1136
{value, {outdir, Odir}} -> filename:join(Odir, Base);
1025
1137
_NotFound -> Base % Not found or bad format
1031
1143
lists:concat([Obase,".",Ext])
1146
includes(File,Options) ->
1147
case filename:dirname(File) of
1152
case lists:member({i,"."},Options) of
1153
false -> Options ++ [{i,"."}];
1156
case lists:member({i,Dir}, Options) of
1157
false -> Options2 ++ [{i,Dir}];
1034
1162
%% compile(AbsFileName, Options)
1035
1163
%% Compile entry point for erl_compile.
1437
1565
% [CommandList,SelectedDecode]),
1439
1567
create_partial_inc_decode_gen_info(M#module.name,ExclusiveDecode),
1440
%% io:format("partial_incomplete_decode = ~p~n",[CommandList2]),
1568
% io:format("partial_incomplete_decode = ~p~n",[CommandList2]),
1441
1569
Part_inc_tlv_tags = tag_format(ber_bin_v2,Options,CommandList2),
1442
1570
% io:format("partial_incomplete_decode: tlv_tags = ~p~n",[Part_inc_tlv_tags]),
1443
1571
save_config(partial_incomplete_decode,Part_inc_tlv_tags),
1953
2081
get_config_info(CfgList,InfoType) ->
1958
case lists:keysearch(InfoType,1,CfgList) of
1959
{value,{InfoType,Value}} ->
2082
case lists:keysearch(InfoType,1,CfgList) of
2083
{value,{InfoType,Value}} ->
1966
2089
%% save_config/2 saves the Info with the key Key
2251
2374
%% adds Data to gen_refed_funcs field in gen_state.
2252
2375
add_generated_refed_func(Data) ->
2253
L = get_gen_state_field(gen_refed_funcs),
2254
update_gen_state(gen_refed_funcs,[Data|L]).
2376
case is_function_generated(Data) of
2380
L = get_gen_state_field(gen_refed_funcs),
2381
update_gen_state(gen_refed_funcs,[Data|L])
2256
2384
next_refed_func() ->
2257
2385
case get_gen_state_field(tobe_refed_funcs) of