From 509ccd85ef448f5843716d4b51a8b07f875cdfda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Mon, 25 Feb 2013 09:55:59 +0100 Subject: PER/UPER: Share all code except encoding of primitives The only code that is really different between the PER and UPER backends is encoding of primitive types. --- lib/asn1/src/asn1ct_gen.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/asn1/src/asn1ct_gen.erl') diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl index 76c4182160..c598dafc47 100644 --- a/lib/asn1/src/asn1ct_gen.erl +++ b/lib/asn1/src/asn1ct_gen.erl @@ -1902,7 +1902,7 @@ index2suffix(N) -> ct_gen_module(ber) -> asn1ct_gen_ber_bin_v2; ct_gen_module(per) -> - asn1ct_gen_per_rt2ct; + asn1ct_gen_per; ct_gen_module(uper) -> asn1ct_gen_per. -- cgit v1.2.3 From ab7f7f53dc75cdf6ff05abd5663b1c2add39963c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Mon, 25 Feb 2013 15:19:13 +0100 Subject: Eliminate general use of #typereference{} The record #typereference{} is only used internally within the asn1ct_parser2 module (the parser translates it to an #'Externaltypereference{} record). --- lib/asn1/src/asn1ct_gen.erl | 3 --- 1 file changed, 3 deletions(-) (limited to 'lib/asn1/src/asn1ct_gen.erl') diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl index c598dafc47..956497a3d5 100644 --- a/lib/asn1/src/asn1ct_gen.erl +++ b/lib/asn1/src/asn1ct_gen.erl @@ -1671,7 +1671,6 @@ unify_if_string(PrimType) -> get_inner(A) when is_atom(A) -> A; get_inner(Ext) when is_record(Ext,'Externaltypereference') -> Ext; -get_inner(Tref) when is_record(Tref,typereference) -> Tref; get_inner({fixedtypevaluefield,_,Type}) -> if is_record(Type,type) -> @@ -1704,8 +1703,6 @@ get_inner(T) when is_tuple(T) -> type(X) when is_record(X,'Externaltypereference') -> X; -type(X) when is_record(X,typereference) -> - X; type('ASN1_OPEN_TYPE') -> 'ASN1_OPEN_TYPE'; type({fixedtypevaluefield,_Name,Type}) when is_record(Type,type) -> -- cgit v1.2.3 From 7767bb01374427a6a09a2655de1a53a5ffe1d673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Mon, 4 Mar 2013 19:50:00 +0100 Subject: Get rid of 'ANY' in the backends asn1ct_check has translated all occurrences of 'ANY' to 'ASN1_OPEN_TYPE'. --- lib/asn1/src/asn1ct_gen.erl | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/asn1/src/asn1ct_gen.erl') diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl index 956497a3d5..249cde96b5 100644 --- a/lib/asn1/src/asn1ct_gen.erl +++ b/lib/asn1/src/asn1ct_gen.erl @@ -1737,7 +1737,6 @@ prim_bif(X) -> 'REAL', 'OBJECT IDENTIFIER', 'RELATIVE-OID', - 'ANY', 'NULL', 'BIT STRING' , 'OCTET STRING' , -- cgit v1.2.3 From 9d56389aa8fd0d366df7b0f666369d23cf946639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Thu, 7 Mar 2013 11:44:01 +0100 Subject: Generate one call to io:put_chars/2 for each call to asn1ct_gen:emit/1 asn1ct_gen:emit/1 used to make one call to io:put_chars/2 for each part of the term passed emit/1. By collecting all output into one iolist for each call emit/1 the time for running the entire asn1 test suite is reduced from about 460 seconds to 340 seconds on my computer. --- lib/asn1/src/asn1ct_gen.erl | 91 +++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 52 deletions(-) (limited to 'lib/asn1/src/asn1ct_gen.erl') diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl index 249cde96b5..a7a43b7426 100644 --- a/lib/asn1/src/asn1ct_gen.erl +++ b/lib/asn1/src/asn1ct_gen.erl @@ -1146,77 +1146,64 @@ demit(Term) -> end. % always generation +emit(Term) -> + io:put_chars(get(gen_file_out), do_emit(Term)). -emit({external,_M,T}) -> - emit(T); +do_emit({external,_M,T}) -> + do_emit(T); -emit({prev,Variable}) when is_atom(Variable) -> - emit({var,asn1ct_name:prev(Variable)}); +do_emit({prev,Variable}) when is_atom(Variable) -> + do_emit({var,asn1ct_name:prev(Variable)}); -emit({next,Variable}) when is_atom(Variable) -> - emit({var,asn1ct_name:next(Variable)}); +do_emit({next,Variable}) when is_atom(Variable) -> + do_emit({var,asn1ct_name:next(Variable)}); -emit({curr,Variable}) when is_atom(Variable) -> - emit({var,asn1ct_name:curr(Variable)}); +do_emit({curr,Variable}) when is_atom(Variable) -> + do_emit({var,asn1ct_name:curr(Variable)}); -emit({var,Variable}) when is_atom(Variable) -> +do_emit({var,Variable}) when is_atom(Variable) -> [Head|V] = atom_to_list(Variable), - emit([Head-32|V]); + [Head-32|V]; -emit({var,Variable}) -> +do_emit({var,Variable}) -> [Head|V] = Variable, - emit([Head-32|V]); + [Head-32|V]; -emit({asis,What}) -> - format(get(gen_file_out),"~w",[What]); +do_emit({asis,What}) -> + io_lib:format("~w", [What]); -emit({call,M,F,A}) -> - asn1ct_func:call(M, F, A); +do_emit({call,M,F,A}) -> + MFA = {M,F,length(A)}, + asn1ct_func:need(MFA), + [atom_to_list(F),"(",call_args(A, "")|")"]; -emit(nl) -> - nl(get(gen_file_out)); +do_emit(nl) -> + "\n"; -emit(com) -> - emit(","); +do_emit(com) -> + ","; -emit(tab) -> - put_chars(get(gen_file_out)," "); +do_emit(tab) -> + " "; -emit(What) when is_integer(What) -> - put_chars(get(gen_file_out),integer_to_list(What)); +do_emit(What) when is_integer(What) -> + integer_to_list(What); -emit(What) when is_list(What), is_integer(hd(What)) -> - put_chars(get(gen_file_out),What); +do_emit(What) when is_list(What), is_integer(hd(What)) -> + What; -emit(What) when is_atom(What) -> - put_chars(get(gen_file_out),atom_to_list(What)); +do_emit(What) when is_atom(What) -> + atom_to_list(What); -emit(What) when is_tuple(What) -> - emit_parts(tuple_to_list(What)); +do_emit(What) when is_tuple(What) -> + [do_emit(E) || E <- tuple_to_list(What)]; -emit(What) when is_list(What) -> - emit_parts(What); +do_emit(What) when is_list(What) -> + [do_emit(E) || E <- What]. -emit(X) -> - exit({'cant emit ',X}). - -emit_parts([]) -> true; -emit_parts([H|T]) -> - emit(H), - emit_parts(T). - -format(undefined,X,Y) -> - io:format(X,Y); -format(X,Y,Z) -> - io:format(X,Y,Z). - -nl(undefined) -> io:nl(); -nl(X) -> io:nl(X). - -put_chars(undefined,X) -> - io:put_chars(X); -put_chars(Y,X) -> - io:put_chars(Y,X). +call_args([A|As], Sep) -> + [Sep,do_emit(A)|call_args(As, ", ")]; +call_args([], _) -> []. fopen(F, ModeList) -> case file:open(F, ModeList) of -- cgit v1.2.3 From 77fde7589ae338efa15fecfb5f75ec9168fa921f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Thu, 7 Mar 2013 12:33:26 +0100 Subject: Open the output file in raw mode with delayed write This change brings down the execution time on my computer for the entire asn1 test suite from about 340 seconds to 310 seconds. --- lib/asn1/src/asn1ct_gen.erl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib/asn1/src/asn1ct_gen.erl') diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl index a7a43b7426..570f41f91d 100644 --- a/lib/asn1/src/asn1ct_gen.erl +++ b/lib/asn1/src/asn1ct_gen.erl @@ -75,7 +75,7 @@ pgen_module(OutFile,Erules,Module, HrlGenerated = pgen_hrl(Erules,Module,TypeOrVal,Options,Indent), asn1ct_name:start(), ErlFile = lists:concat([OutFile,".erl"]), - Fid = fopen(ErlFile,[write]), + Fid = fopen(ErlFile), put(gen_file_out,Fid), asn1ct_func:start_link(), gen_head(Erules,Module,HrlGenerated), @@ -1131,7 +1131,7 @@ pgen_info() -> open_hrl(OutFile,Module) -> File = lists:concat([OutFile,".hrl"]), - Fid = fopen(File,[write]), + Fid = fopen(File), put(gen_file_out,Fid), gen_hrlhead(Module). @@ -1147,7 +1147,7 @@ demit(Term) -> % always generation emit(Term) -> - io:put_chars(get(gen_file_out), do_emit(Term)). + ok = file:write(get(gen_file_out), do_emit(Term)). do_emit({external,_M,T}) -> do_emit(T); @@ -1205,8 +1205,8 @@ call_args([A|As], Sep) -> [Sep,do_emit(A)|call_args(As, ", ")]; call_args([], _) -> []. -fopen(F, ModeList) -> - case file:open(F, ModeList) of +fopen(F) -> + case file:open(F, [write,raw,delayed_write]) of {ok, Fd} -> Fd; {error, Reason} -> -- cgit v1.2.3 From c7ccb343abe2858ee4296cdd549b369423ac3b44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Sat, 9 Mar 2013 07:38:21 +0100 Subject: asn1ct, asn1ct_gen: Eliminate unused exports Stop export functions that are not called from outside their module. If the functions are not used at all, remove the functions too. The unused exports were found by running: xref:start(s). xref:add_application(s, code:lib_dir(asn1)). io:format("~p\n", [xref:analyze(s, exports_not_used)]). --- lib/asn1/src/asn1ct_gen.erl | 46 +-------------------------------------------- 1 file changed, 1 insertion(+), 45 deletions(-) (limited to 'lib/asn1/src/asn1ct_gen.erl') diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl index 570f41f91d..5cddaba52e 100644 --- a/lib/asn1/src/asn1ct_gen.erl +++ b/lib/asn1/src/asn1ct_gen.erl @@ -21,15 +21,9 @@ -include("asn1_records.hrl"). --export([pgen_exports/3, - pgen_hrl/5, - gen_head/3, - demit/1, +-export([demit/1, emit/1, get_inner/1,type/1,def_to_tag/1,prim_bif/1, - type_from_object/1, - get_typefromobject/1,get_fieldcategory/2, - get_classfieldcategory/2, list2name/1, list2rname/1, constructed_suffix/2, @@ -41,7 +35,6 @@ index2suffix/1, get_record_name_prefix/0]). -export([pgen/5, - pgen_module/6, mk_var/1, un_hyphen_var/1]). -export([gen_encode_constructed/4, @@ -1767,15 +1760,6 @@ def_to_tag(Def) -> %% Information Object Class -type_from_object(X) -> - case (catch lists:last(element(2,X))) of - {'EXIT',_} -> - {notype,X}; - Normal -> - Normal - end. - - get_fieldtype([],_FieldName)-> {no_type,no_name}; get_fieldtype([Field|Rest],FieldName) -> @@ -1791,34 +1775,6 @@ get_fieldtype([Field|Rest],FieldName) -> get_fieldtype(Rest,FieldName) end. -get_fieldcategory([],_FieldName) -> - no_cat; -get_fieldcategory([Field|Rest],FieldName) -> - case element(2,Field) of - FieldName -> - element(1,Field); - _ -> - get_fieldcategory(Rest,FieldName) - end. - -get_typefromobject(Type) when is_record(Type,type) -> - case Type#type.def of - {{objectclass,_,_},TypeFrObj} when is_list(TypeFrObj) -> - {_,FieldName} = lists:last(TypeFrObj), - FieldName; - _ -> - {no_field} - end. - -get_classfieldcategory(Type,FieldName) -> - case (catch Type#type.def) of - {{obejctclass,Fields,_},_} -> - get_fieldcategory(Fields,FieldName); - {'EXIT',_} -> - no_cat; - _ -> - no_cat - end. %% Information Object Class %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -- cgit v1.2.3 From f4e25971233abdc0fe8872cb8d7b5113d4198a3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Tue, 12 Mar 2013 16:45:16 +0100 Subject: Eliminate the {notype,_} return value from asn1ct_gen:type/1 The last clause in asn1ct_gen:type/1 does a catched call to type2/1. If the type2/1 fails {notype,X} is returned. Since the body of type2/1 essentially is: case lists:member(X, [...]) of true -> {primitive,bif}; false -> case lists:member(X, [...]) of true -> {constructed,bif}; false -> {undefined,user} end end there is no way that type2/1 can fail. Therefore, we can eliminate the catch and put the body of type2/1 into the last clause of type/1. We can also eliminate the code in the callers of type/1 that match {notype,X}. --- lib/asn1/src/asn1ct_gen.erl | 9 --------- 1 file changed, 9 deletions(-) (limited to 'lib/asn1/src/asn1ct_gen.erl') diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl index 5cddaba52e..978ac280dd 100644 --- a/lib/asn1/src/asn1ct_gen.erl +++ b/lib/asn1/src/asn1ct_gen.erl @@ -1690,15 +1690,6 @@ type({fixedtypevaluefield,_Name,Type}) when is_record(Type,type) -> type({typefield,_}) -> 'ASN1_OPEN_TYPE'; type(X) -> - %% io:format("asn1_types:type(~p)~n",[X]), - case catch type2(X) of - {'EXIT',_} -> - {notype,X}; - Normal -> - Normal - end. - -type2(X) -> case prim_bif(X) of true -> {primitive,bif}; -- cgit v1.2.3 From 4001ac2a291e26d9fa912dbeefbe92278aceb345 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Tue, 9 Apr 2013 07:23:40 +0200 Subject: PER: Generate code for deep table constraints at compile-time For the PER backends, generate code for accessing deep table constraints at compile-time in the same way as is done for BER. While at it, remove the complicated indentation code. Also modernize the test suite and add a test for a deeper nested constraint. --- lib/asn1/src/asn1ct_gen.erl | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) (limited to 'lib/asn1/src/asn1ct_gen.erl') diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl index 978ac280dd..9095e145a3 100644 --- a/lib/asn1/src/asn1ct_gen.erl +++ b/lib/asn1/src/asn1ct_gen.erl @@ -108,8 +108,7 @@ pgen_values(Erules,Module,[H|T]) -> gen_value(Valuedef), pgen_values(Erules,Module,T). -pgen_types(_,_,_,Module,[]) -> - gen_value_match(Module), +pgen_types(_, _, _, _, []) -> true; pgen_types(Rtmod,Erules,N2nConvEnums,Module,[H|T]) -> asn1ct_name:clear(), @@ -573,22 +572,6 @@ gen_types(Erules,Tname,Type) when is_record(Type,type) -> asn1ct_name:clear(), Rtmod:gen_decode(Erules,Tname,Type). -gen_value_match(Module) -> - case get(value_match) of - {true,Module} -> - emit(["value_match([{Index,Cname}|Rest],Value) ->",nl, - " Value2 =",nl, - " case element(Index,Value) of",nl, - " {Cname,Val2} -> Val2;",nl, - " X -> X",nl, - " end,",nl, - " value_match(Rest,Value2);",nl, - "value_match([],Value) ->",nl, - " Value.",nl]); - _ -> ok - end, - put(value_match,undefined). - gen_check_defaultval(Erules,Module,[{Name,Type}|Rest]) -> gen_check_func(Name,Type), gen_check_defaultval(Erules,Module,Rest); -- cgit v1.2.3