aboutsummaryrefslogtreecommitdiffstats
path: root/lib/asn1/src
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2017-02-17 09:48:24 +0100
committerBjörn Gustavsson <[email protected]>2017-02-17 09:48:24 +0100
commit5b80964cabcb5ec6c7961d3714fa9ed4bdcc6585 (patch)
tree3d80164c898123395e2aa653f34a72afc0c6e950 /lib/asn1/src
parent4499687a325178727a7be62124c1ca52f59b1287 (diff)
parent390d197044d39c0805dd3060f0c58ae8b5458239 (diff)
downloadotp-5b80964cabcb5ec6c7961d3714fa9ed4bdcc6585.tar.gz
otp-5b80964cabcb5ec6c7961d3714fa9ed4bdcc6585.tar.bz2
otp-5b80964cabcb5ec6c7961d3714fa9ed4bdcc6585.zip
Merge branch 'bjorn/asn1/clean-up-asn1ct_gen'
* bjorn/asn1/clean-up-asn1ct_gen: asn1ct_gen: Clean up handling of dispatch generation Package abstract code in a record for code generation asn1ct_gen: Polish the file header asn1ct_gen: Clean up generation of .hrl file header asn1ct_gen: Clean up generation records in .hrl file asn1ct_gen: Clean up generation of -export directives asn1ct_gen: Clean up generation of values
Diffstat (limited to 'lib/asn1/src')
-rw-r--r--lib/asn1/src/asn1_records.hrl11
-rw-r--r--lib/asn1/src/asn1ct.erl24
-rw-r--r--lib/asn1/src/asn1ct_gen.erl385
3 files changed, 171 insertions, 249 deletions
diff --git a/lib/asn1/src/asn1_records.hrl b/lib/asn1/src/asn1_records.hrl
index d3d76f9566..06a9e3ab03 100644
--- a/lib/asn1/src/asn1_records.hrl
+++ b/lib/asn1/src/asn1_records.hrl
@@ -108,6 +108,17 @@
options=[] :: [any()]
}).
+%% Abstract intermediate representation.
+-record(abst,
+ {name :: module(), %Name of module.
+ types, %Types.
+ values, %Values.
+ ptypes, %Parameterized types.
+ classes, %Classes.
+ objects, %Objects.
+ objsets %Object sets.
+ }).
+
%% state record used by back-end at partial decode
%% active is set to 'yes' when a partial decode function is generated.
%% prefix is set to 'dec-inc-' or 'dec-partial-' is for
diff --git a/lib/asn1/src/asn1ct.erl b/lib/asn1/src/asn1ct.erl
index d27f8897af..9f77a557e5 100644
--- a/lib/asn1/src/asn1ct.erl
+++ b/lib/asn1/src/asn1ct.erl
@@ -236,12 +236,8 @@ abs_listing(#st{code={M,_},outfile=OutFile}) ->
generate_pass(#st{code=Code,outfile=OutFile,erule=Erule,opts=Opts}=St0) ->
St = St0#st{code=undefined}, %Reclaim heap space
- case generate(Code, OutFile, Erule, Opts) of
- {error,Reason} ->
- {error,St#st{error=Reason}};
- ok ->
- {ok,St}
- end.
+ generate(Code, OutFile, Erule, Opts),
+ {ok,St}.
compile_pass(#st{outfile=OutFile,opts=Opts0}=St) ->
asn1_db:dbstop(), %Reclaim memory.
@@ -834,7 +830,11 @@ delete_double_of_symbol1([],Acc) ->
%%***********************************
-generate({M,GenTOrV}, OutFile, EncodingRule, Options) ->
+generate({M,CodeTuple}, OutFile, EncodingRule, Options) ->
+ {Types,Values,Ptypes,Classes,Objects,ObjectSets} = CodeTuple,
+ Code = #abst{name=M#module.name,
+ types=Types,values=Values,ptypes=Ptypes,
+ classes=Classes,objects=Objects,objsets=ObjectSets},
debug_on(Options),
setup_bit_string_format(Options),
setup_legacy_erlang_types(Options),
@@ -854,19 +854,13 @@ generate({M,GenTOrV}, OutFile, EncodingRule, Options) ->
"Error in configuration file")
end,
- Res = case catch asn1ct_gen:pgen(OutFile, Gen, M#module.name, GenTOrV) of
- {'EXIT',Reason2} ->
- error("~p~n",[Reason2],Options),
- {error,Reason2};
- _ ->
- ok
- end,
+ asn1ct_gen:pgen(OutFile, Gen, Code),
debug_off(Options),
cleanup_bit_string_format(),
erase(tlv_format), % used in ber
erase(class_default_type),% used in ber
asn1ct_table:delete(check_functions),
- Res.
+ ok.
init_gen_record(EncodingRule, Options) ->
Erule = case EncodingRule of
diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl
index 4fa830d7d9..9943bd056a 100644
--- a/lib/asn1/src/asn1ct_gen.erl
+++ b/lib/asn1/src/asn1ct_gen.erl
@@ -37,7 +37,7 @@
get_record_name_prefix/1,
conform_value/2,
named_bitstring_value/2]).
--export([pgen/4,
+-export([pgen/3,
mk_var/1,
un_hyphen_var/1]).
-export([gen_encode_constructed/4,
@@ -50,14 +50,13 @@
%% Generate Erlang module (.erl) and (.hrl) file corresponding to
%% an ASN.1 module. The .hrl file is only generated if necessary.
--spec pgen(Outfile, Gen, Module, Contents) -> 'ok' when
+-spec pgen(Outfile, Gen, Code) -> 'ok' when
Outfile :: any(),
Gen :: #gen{},
- Module :: module(),
- Contents :: tuple().
+ Code :: #abst{}.
-pgen(OutFile, #gen{options=Options}=Gen, Module, Contents) ->
- {Types,_Values,_Ptypes,_Classes,_Objects,_ObjectSets} = Contents,
+pgen(OutFile, #gen{options=Options}=Gen, Code) ->
+ #abst{name=Module,types=Types} = Code,
N2nConvEnums = [CName|| {n2n,CName} <- Options],
case N2nConvEnums -- Types of
[] ->
@@ -66,18 +65,18 @@ pgen(OutFile, #gen{options=Options}=Gen, Module, Contents) ->
exit({"Non existing ENUMERATION types used in n2n option",
UnmatchedTypes})
end,
- put(outfile,OutFile),
+ put(outfile, OutFile),
put(currmod, Module),
- HrlGenerated = pgen_hrl(Gen, Module, Contents),
+ HrlGenerated = pgen_hrl(Gen, Code),
asn1ct_name:start(),
ErlFile = lists:concat([OutFile,".erl"]),
_ = open_output_file(ErlFile),
asn1ct_func:start_link(),
gen_head(Gen, Module, HrlGenerated),
- pgen_exports(Gen, Module, Contents),
- pgen_dispatcher(Gen, Contents),
+ pgen_exports(Gen, Code),
+ pgen_dispatcher(Gen, Types),
pgen_info(),
- pgen_typeorval(Gen, Module, N2nConvEnums, Contents),
+ pgen_typeorval(Gen, N2nConvEnums, Code),
pgen_partial_incomplete_decode(Gen),
emit([nl,
"%%%",nl,
@@ -88,7 +87,8 @@ pgen(OutFile, #gen{options=Options}=Gen, Module, Contents) ->
asn1ct_func:generate(Fd),
close_output_file(),
_ = erase(outfile),
- asn1ct:verbose("--~p--~n", [{generated,ErlFile}], Gen).
+ asn1ct:verbose("--~p--~n", [{generated,ErlFile}], Gen),
+ ok.
dialyzer_suppressions(Erules) ->
emit([nl,
@@ -96,20 +96,27 @@ dialyzer_suppressions(Erules) ->
Rtmod = ct_gen_module(Erules),
Rtmod:dialyzer_suppressions(Erules).
-pgen_typeorval(Erules,Module,N2nConvEnums,{Types,Values,_Ptypes,_Classes,Objects,ObjectSets}) ->
+pgen_typeorval(Erules, N2nConvEnums, Code) ->
+ #abst{name=Module,types=Types,values=Values,
+ objects=Objects,objsets=ObjectSets} = Code,
Rtmod = ct_gen_module(Erules),
pgen_types(Rtmod,Erules,N2nConvEnums,Module,Types),
- pgen_values(Erules,Module,Values),
+ pgen_values(Values, Module),
pgen_objects(Rtmod,Erules,Module,Objects),
pgen_objectsets(Rtmod,Erules,Module,ObjectSets),
pgen_partial_decode(Rtmod,Erules,Module).
-pgen_values(_,_,[]) ->
- true;
-pgen_values(Erules,Module,[H|T]) ->
- Valuedef = asn1_db:dbget(Module,H),
- gen_value(Valuedef),
- pgen_values(Erules,Module,T).
+%% Generate a function 'V'/0 for each Value V defined in the ASN.1 module.
+%% The function returns the value in an Erlang representation which can be
+%% used as input to the runtime encode functions.
+
+pgen_values([H|T], Module) ->
+ #valuedef{name=Name,value=Value} = asn1_db:dbget(Module, H),
+ emit([{asis,Name},"() ->",nl,
+ {asis,Value},".",nl,nl]),
+ pgen_values(T, Module);
+pgen_values([], _) ->
+ ok.
pgen_types(_, _, _, _, []) ->
true;
@@ -573,18 +580,6 @@ un_hyphen_var([H|T]) ->
un_hyphen_var([]) ->
[].
-%% Generate value functions ***************
-%% ****************************************
-%% Generates a function 'V'/0 for each Value V defined in the ASN.1 module
-%% the function returns the value in an Erlang representation which can be
-%% used as input to the runtime encode functions
-
-gen_value(Value) when is_record(Value,valuedef) ->
-%% io:format(" ~w ",[Value#valuedef.name]),
- emit({"'",Value#valuedef.name,"'() ->",nl}),
- V = Value#valuedef.value,
- emit([{asis,V},".",nl,nl]).
-
gen_encode_constructed(Erules,Typename,InnerType,D) when is_record(D,type) ->
Rtmod = ct_constructed_module(Erules),
case InnerType of
@@ -649,79 +644,32 @@ gen_decode_constructed(Erules,Typename,InnerType,D) when is_record(D,typedef) ->
gen_decode_constructed(Erules,Typename,InnerType,D#typedef.typespec).
-pgen_exports(#gen{options=Options}=Gen, _Module, Contents) ->
- {Types,Values,_,_,Objects,ObjectSets} = Contents,
+pgen_exports(#gen{options=Options}=Gen, Code) ->
+ #abst{types=Types,values=Values,objects=Objects,objsets=ObjectSets} = Code,
emit(["-export([encoding_rule/0,maps/0,bit_string_format/0,",nl,
" legacy_erlang_types/0]).",nl]),
emit(["-export([",{asis,?SUPPRESSION_FUNC},"/1]).",nl]),
- case Types of
- [] -> ok;
- _ ->
- emit({"-export([",nl}),
- case Gen of
- #gen{erule=ber} ->
- gen_exports1(Types,"enc_",2);
- _ ->
- gen_exports1(Types,"enc_",1)
- end,
- emit({"-export([",nl}),
- case Gen of
- #gen{erule=ber} ->
- gen_exports1(Types, "dec_", 2);
- _ ->
- gen_exports1(Types, "dec_", 1)
- end
- end,
- case [X || {n2n,X} <- Options] of
- [] -> ok;
- A2nNames ->
- emit({"-export([",nl}),
- gen_exports1(A2nNames,"name2num_",1),
- emit({"-export([",nl}),
- gen_exports1(A2nNames,"num2name_",1)
- end,
- case Values of
- [] -> ok;
- _ ->
- emit({"-export([",nl}),
- gen_exports1(Values,"",0)
- end,
- case Objects of
- [] -> ok;
- _ ->
- case Gen of
- #gen{erule=per} ->
- ok;
- #gen{erule=ber} ->
- emit({"-export([",nl}),
- gen_exports1(Objects,"enc_",3),
- emit({"-export([",nl}),
- gen_exports1(Objects,"dec_",3)
- end
- end,
- case ObjectSets of
- [] -> ok;
- _ ->
- case Gen of
- #gen{erule=per} ->
- ok;
- #gen{erule=ber} ->
- emit({"-export([",nl}),
- gen_exports1(ObjectSets, "getenc_",1),
- emit({"-export([",nl}),
- gen_exports1(ObjectSets, "getdec_",1)
- end
+ case Gen of
+ #gen{erule=ber} ->
+ gen_exports(Types, "enc_", 2),
+ gen_exports(Types, "dec_", 2),
+ gen_exports(Objects, "enc_", 3),
+ gen_exports(Objects, "dec_", 3),
+ gen_exports(ObjectSets, "getenc_", 1),
+ gen_exports(ObjectSets, "getdec_", 1);
+ #gen{erule=per} ->
+ gen_exports(Types, "enc_", 1),
+ gen_exports(Types, "dec_", 1)
end,
- emit({"-export([info/0]).",nl}),
- gen_partial_inc_decode_exports(),
- gen_selected_decode_exports(),
- emit({nl,nl}).
-gen_exports1([F1,F2|T],Prefix,Arity) ->
- emit({"'",Prefix,F1,"'/",Arity,com,nl}),
- gen_exports1([F2|T],Prefix,Arity);
-gen_exports1([Flast|_T],Prefix,Arity) ->
- emit({"'",Prefix,Flast,"'/",Arity,nl,"]).",nl,nl}).
+ A2nNames = [X || {n2n,X} <- Options],
+ gen_exports(A2nNames, "name2num_", 1),
+ gen_exports(A2nNames, "num2name_", 1),
+
+ gen_exports(Values, "", 0),
+ emit(["-export([info/0]).",nl,nl]),
+ gen_partial_inc_decode_exports(),
+ gen_selected_decode_exports().
gen_partial_inc_decode_exports() ->
case {asn1ct:read_config_data(partial_incomplete_decode),
@@ -730,49 +678,36 @@ gen_partial_inc_decode_exports() ->
ok;
{_,undefined} ->
ok;
- {Data,_} ->
- gen_partial_inc_decode_exports0(Data),
- emit(["-export([decode_part/2]).",nl])
+ {Data0,_} ->
+ Data = [Name || {Name,_,_} <- Data0],
+ gen_exports(Data, "", 1),
+ emit(["-export([decode_part/2]).",nl,nl])
end.
-gen_partial_inc_decode_exports0([]) ->
- ok;
-gen_partial_inc_decode_exports0([{Name,_,_}|Rest]) ->
- emit(["-export([",Name,"/1"]),
- gen_partial_inc_decode_exports1(Rest);
-gen_partial_inc_decode_exports0([_|Rest]) ->
- gen_partial_inc_decode_exports0(Rest).
-
-gen_partial_inc_decode_exports1([]) ->
- emit(["]).",nl]);
-gen_partial_inc_decode_exports1([{Name,_,_}|Rest]) ->
- emit([", ",Name,"/1"]),
- gen_partial_inc_decode_exports1(Rest);
-gen_partial_inc_decode_exports1([_|Rest]) ->
- gen_partial_inc_decode_exports1(Rest).
-
gen_selected_decode_exports() ->
case asn1ct:get_gen_state_field(type_pattern) of
undefined ->
ok;
- L ->
- gen_selected_decode_exports(L)
+ Data0 ->
+ Data = [Name || {Name,_} <- Data0],
+ gen_exports(Data, "", 1)
end.
-gen_selected_decode_exports([]) ->
+gen_exports([], _Prefix, _Arity) ->
ok;
-gen_selected_decode_exports([{FuncName,_}|Rest]) ->
- emit(["-export([",FuncName,"/1"]),
- gen_selected_decode_exports1(Rest).
-gen_selected_decode_exports1([]) ->
- emit(["]).",nl,nl]);
-gen_selected_decode_exports1([{FuncName,_}|Rest]) ->
- emit([",",nl," ",FuncName,"/1"]),
- gen_selected_decode_exports1(Rest).
-
-pgen_dispatcher(Erules, {[],_Values,_,_,_Objects,_ObjectSets}) ->
+gen_exports([_|_]=L0, Prefix, Arity) ->
+ FF = fun(F0) ->
+ F = list_to_atom(lists:concat([Prefix,F0])),
+ [{asis,F},"/",Arity]
+ end,
+ L = lists:join(",\n", [FF(F) || F <- L0]),
+ emit(["-export([",nl,
+ L,nl,
+ "]).",nl,nl]).
+
+pgen_dispatcher(Erules, []) ->
gen_info_functions(Erules);
-pgen_dispatcher(Gen, {Types,_Values,_,_,_Objects,_ObjectSets}) ->
+pgen_dispatcher(Gen, Types) ->
emit(["-export([encode/2,decode/2]).",nl,nl]),
gen_info_functions(Gen),
@@ -812,7 +747,7 @@ pgen_dispatcher(Gen, {Types,_Values,_,_,_Objects,_ObjectSets}) ->
false -> "Data"
end,
- emit(["decode(Type,",Data,") ->",nl]),
+ emit(["decode(Type, ",Data,") ->",nl]),
DecWrap =
case {Gen,ReturnRest} of
{#gen{erule=ber},false} ->
@@ -847,17 +782,10 @@ pgen_dispatcher(Gen, {Types,_Values,_,_,_Objects,_ObjectSets}) ->
end,
gen_decode_partial_incomplete(Gen),
+ gen_partial_inc_dispatcher(Gen),
- case Gen of
- #gen{erule=ber} ->
- gen_dispatcher(Types,"encode_disp","enc_",""),
- gen_dispatcher(Types,"decode_disp","dec_",""),
- gen_partial_inc_dispatcher();
- #gen{} ->
- gen_dispatcher(Types,"encode_disp","enc_",""),
- gen_dispatcher(Types,"decode_disp","dec_","")
- end,
- emit([nl,nl]).
+ gen_dispatcher(Types, "encode_disp", "enc_"),
+ gen_dispatcher(Types, "decode_disp", "dec_").
result_line(NoOkWrapper, Items) ->
S = [" "|case NoOkWrapper of
@@ -942,7 +870,7 @@ gen_decode_partial_incomplete(#gen{erule=ber}) ->
gen_decode_partial_incomplete(#gen{}) ->
ok.
-gen_partial_inc_dispatcher() ->
+gen_partial_inc_dispatcher(#gen{erule=ber}) ->
case {asn1ct:read_config_data(partial_incomplete_decode),
asn1ct:get_gen_state_field(inc_type_pattern)} of
{undefined,_} ->
@@ -952,7 +880,9 @@ gen_partial_inc_dispatcher() ->
{Data1,Data2} ->
% io:format("partial_incomplete_decode: ~p~ninc_type_pattern: ~p~n",[Data,Data2]),
gen_partial_inc_dispatcher(Data1, Data2, "")
- end.
+ end;
+gen_partial_inc_dispatcher(#gen{}) ->
+ ok.
gen_partial_inc_dispatcher([{FuncName,TopType,_Pattern}|Rest], TypePattern, Sep) ->
TPattern =
@@ -976,12 +906,18 @@ gen_partial_inc_dispatcher([{FuncName,TopType,_Pattern}|Rest], TypePattern, Sep)
gen_partial_inc_dispatcher([], _, _) ->
emit([".",nl]).
-gen_dispatcher([F1,F2|T],FuncName,Prefix,ExtraArg) ->
- emit([FuncName,"('",F1,"',Data) -> '",Prefix,F1,"'(Data",ExtraArg,")",";",nl]),
- gen_dispatcher([F2|T],FuncName,Prefix,ExtraArg);
-gen_dispatcher([Flast|_T],FuncName,Prefix,ExtraArg) ->
- emit([FuncName,"('",Flast,"',Data) -> '",Prefix,Flast,"'(Data",ExtraArg,")",";",nl]),
- emit([FuncName,"(","Type",",_Data) -> exit({error,{asn1,{undefined_type,Type}}}).",nl,nl,nl]).
+gen_dispatcher(L, DispFunc, Prefix) ->
+ gen_dispatcher_1(L, DispFunc, Prefix),
+ emit([DispFunc,"(","Type",", _Data) ->"
+ " exit({error,{asn1,{undefined_type,Type}}}).",nl,nl]).
+
+gen_dispatcher_1([F|T], FuncName, Prefix) ->
+ Func = list_to_atom(lists:concat([Prefix,F])),
+ emit([FuncName,"(",{asis,F},", Data) -> ",
+ {asis,Func},"(Data)",";",nl]),
+ gen_dispatcher_1(T, FuncName, Prefix);
+gen_dispatcher_1([], _, _) ->
+ ok.
pgen_info() ->
emit(["info() ->",nl,
@@ -1100,8 +1036,8 @@ open_output_file(F) ->
close_output_file() ->
ok = file:close(erase(gen_file_out)).
-pgen_hrl(#gen{pack=record}=Gen, Module, Contents) ->
- {Types,Values,Ptypes,_,_,_} = Contents,
+pgen_hrl(#gen{pack=record}=Gen, Code) ->
+ #abst{name=Module,types=Types,values=Values,ptypes=Ptypes} = Code,
Ret =
case pgen_hrltypes(Gen, Module, Ptypes++Types, 0) of
0 ->
@@ -1129,7 +1065,7 @@ pgen_hrl(#gen{pack=record}=Gen, Module, Contents) ->
Gen),
Y
end;
-pgen_hrl(#gen{pack=map}, _, _) ->
+pgen_hrl(#gen{pack=map}, _) ->
0.
pgen_macros(_,_,[]) ->
@@ -1215,55 +1151,16 @@ gen_record(Gen, TorPtype, Name, #type{}=Type, Num) ->
0 -> open_hrl(get(outfile),get(currmod));
_ -> true
end,
- Prefix = get_record_name_prefix(Gen),
- emit({"-record('",Prefix,list2name(Name),"',{",nl}),
- RootList = case CompList of
- _ when is_list(CompList) ->
- CompList;
- {Rl,_} -> Rl;
- {Rl1,_Ext,_Rl2} -> Rl1
- end,
- gen_record2(Name,'SEQUENCE',RootList),
- NewCompList =
+ do_gen_record(Gen, Name, CompList),
+ NewCompList =
case CompList of
{CompList1,[]} ->
- emit({"}). % with extension mark",nl,nl}),
CompList1;
{Tr,ExtensionList2} ->
- case Tr of
- [] -> true;
- _ -> emit({",",nl})
- end,
- emit({"%% with extensions",nl}),
- gen_record2(Name, 'SEQUENCE', ExtensionList2,
- "", ext),
- emit({"}).",nl,nl}),
Tr ++ ExtensionList2;
{Rootl1,Extl,Rootl2} ->
- case Rootl1 =/= [] andalso Extl++Rootl2 =/= [] of
- true -> emit([com]);
- false -> ok
- end,
- case Rootl1 of
- [_|_] -> emit([nl]);
- [] -> ok
- end,
- emit(["%% with extensions",nl]),
- gen_record2(Name,'SEQUENCE',Extl,"",ext),
- case Extl =/= [] andalso Rootl2 =/= [] of
- true -> emit([com]);
- false -> ok
- end,
- case Extl of
- [_|_] -> emit([nl]);
- [] -> ok
- end,
- emit(["%% end of extensions",nl]),
- gen_record2(Name,'SEQUENCE',Rootl2,"",noext),
- emit(["}).",nl,nl]),
Rootl1++Extl++Rootl2;
- _ ->
- emit({"}).",nl,nl}),
+ _ ->
CompList
end,
gen_record(Gen, TorPtype, Name, NewCompList, Num+1);
@@ -1275,6 +1172,51 @@ gen_record(Gen, TorPtype, Name, #type{}=Type, Num) ->
gen_record(_, _, _, _, NumRecords) -> % skip CLASS etc for now.
NumRecords.
+do_gen_record(Gen, Name, CL0) ->
+ CL = case CL0 of
+ {Root,[]} ->
+ Root ++ [{comment,"with extension mark"}];
+ {Root,Ext} ->
+ Root ++ [{comment,"with exensions"}] ++
+ only_components(Ext);
+ {Root1,Ext,Root2} ->
+ Root1 ++ [{comment,"with exensions"}] ++
+ only_components(Ext) ++
+ [{comment,"end of extensions"}] ++ Root2;
+ _ when is_list(CL0) ->
+ CL0
+ end,
+ Prefix = get_record_name_prefix(Gen),
+ emit(["-record('",Prefix,list2name(Name),"', {"] ++
+ do_gen_record_1(CL) ++
+ [nl,"}).",nl,nl]).
+
+only_components(CL) ->
+ [C || #'ComponentType'{}=C <- CL].
+
+do_gen_record_1([#'ComponentType'{name=Name,prop=Prop}|T]) ->
+ Val = case Prop of
+ 'OPTIONAL' ->
+ " = asn1_NOVALUE";
+ {'DEFAULT',_} ->
+ " = asn1_DEFAULT";
+ _ ->
+ []
+ end,
+ Com = case needs_trailing_comma(T) of
+ true -> [com];
+ false -> []
+ end,
+ [nl," ",{asis,Name},Val,Com|do_gen_record_1(T)];
+do_gen_record_1([{comment,Text}|T]) ->
+ [nl," %% ",Text|do_gen_record_1(T)];
+do_gen_record_1([]) ->
+ [].
+
+needs_trailing_comma([#'ComponentType'{}|_]) -> true;
+needs_trailing_comma([_|T]) -> needs_trailing_comma(T);
+needs_trailing_comma([]) -> false.
+
gen_head(#gen{options=Options}=Gen, Mod, Hrl) ->
Name = case Gen of
#gen{erule=per,aligned=false} ->
@@ -1285,15 +1227,15 @@ gen_head(#gen{options=Options}=Gen, Mod, Hrl) ->
"BER"
end,
emit(["%% Generated by the Erlang ASN.1 ",Name,
- "compiler. Version:",asn1ct:vsn(),nl,
- "%% Purpose: encoder and decoder of the types in ",Mod,nl,nl,
- "-module('",Mod,"').",nl]),
- put(currmod,Mod),
- emit({"-compile(nowarn_unused_vars).",nl}),
- emit({"-dialyzer(no_improper_lists).",nl}),
+ " compiler. Version: ",asn1ct:vsn(),nl,
+ "%% Purpose: Encoding and decoding of the types in ",
+ Mod,".",nl,nl,
+ "-module('",Mod,"').",nl,
+ "-compile(nowarn_unused_vars).",nl,
+ "-dialyzer(no_improper_lists).",nl]),
case Hrl of
0 -> ok;
- _ -> emit({"-include(\"",Mod,".hrl\").",nl})
+ _ -> emit(["-include(\"",Mod,".hrl\").",nl])
end,
emit(["-asn1_info([{vsn,'",asn1ct:vsn(),"'},",nl,
" {module,'",Mod,"'},",nl,
@@ -1301,36 +1243,11 @@ gen_head(#gen{options=Options}=Gen, Mod, Hrl) ->
gen_hrlhead(Mod) ->
- emit({"%% Generated by the Erlang ASN.1 compiler version:",asn1ct:vsn(),nl}),
- emit({"%% Purpose: Erlang record definitions for each named and unnamed",nl}),
- emit({"%% SEQUENCE and SET, and macro definitions for each value",nl}),
- emit({"%% definition,in module ",Mod,nl,nl}),
- emit({nl,nl}).
-
-gen_record2(Name,SeqOrSet,Comps) ->
- gen_record2(Name,SeqOrSet,Comps,"",noext).
-
-gen_record2(_Name,_SeqOrSet,[],_Com,_Extension) ->
- true;
-gen_record2(_Name,_SeqOrSet,[H = #'ComponentType'{name=Cname}],Com,Extension) ->
- emit(Com),
- emit({asis,Cname}),
- gen_record_default(H, Extension);
-gen_record2(Name,SeqOrSet,[H = #'ComponentType'{name=Cname}|T],Com, Extension) ->
- emit(Com),
- emit({asis,Cname}),
- gen_record_default(H, Extension),
- gen_record2(Name,SeqOrSet,T,", ", Extension);
-gen_record2(Name,SeqOrSet,[_|T],Com,Extension) ->
- %% skip EXTENSIONMARK, ExtensionAdditionGroup and other markers
- gen_record2(Name,SeqOrSet,T,Com,Extension).
-
-gen_record_default(#'ComponentType'{prop='OPTIONAL'}, _)->
- emit(" = asn1_NOVALUE");
-gen_record_default(#'ComponentType'{prop={'DEFAULT',_}}, _)->
- emit(" = asn1_DEFAULT");
-gen_record_default(_, _) ->
- true.
+ emit(["%% Generated by the Erlang ASN.1 compiler. Version: ",
+ asn1ct:vsn(),nl,
+ "%% Purpose: Erlang record definitions for each named and unnamed",nl,
+ "%% SEQUENCE and SET, and macro definitions for each value",nl,
+ "%% definition in module ",Mod,".",nl,nl]).
%% May only be a list or a two-tuple.
to_textual_order({Root,Ext}) ->