diff options
author | Dan Gudmundsson <[email protected]> | 2014-12-04 16:29:09 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2015-01-12 12:22:58 +0100 |
commit | e38bb8064a13679fb42c12fd2ec26268d24ddb41 (patch) | |
tree | 1accc56b47019680d90d5042130f0985163ffe36 | |
parent | b320ccf10becb894c2b325da69a65b316189b4a6 (diff) | |
download | otp-e38bb8064a13679fb42c12fd2ec26268d24ddb41.tar.gz otp-e38bb8064a13679fb42c12fd2ec26268d24ddb41.tar.bz2 otp-e38bb8064a13679fb42c12fd2ec26268d24ddb41.zip |
Further improve error handling for instatiation of parameterized types
-rw-r--r-- | lib/asn1/src/asn1ct_check.erl | 35 | ||||
-rw-r--r-- | lib/asn1/test/error_SUITE.erl | 17 |
2 files changed, 29 insertions, 23 deletions
diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl index 23794f789a..0f73f21582 100644 --- a/lib/asn1/src/asn1ct_check.erl +++ b/lib/asn1/src/asn1ct_check.erl @@ -1183,19 +1183,13 @@ instantiate_po(S=#state{parameters=_OldArgs},_ClassDef,Object,ArgsList) when is_ %% on the right side of the assignment, %% ArgsList is the list of actual parameters, i.e. real objects instantiate_pos(S=#state{parameters=_OldArgs},ClassRef,ObjectSetDef,ArgsList) -> -% ClassName = ClassDef#classdef.name, FormalParams = get_pt_args(ObjectSetDef), OSet = case get_pt_spec(ObjectSetDef) of - {valueset,Set} -> -% #'ObjectSet'{class=name2Extref(S#state.mname, -% ClassName),set=Set}; - #'ObjectSet'{class=ClassRef,set=Set}; - Set when is_record(Set,'ObjectSet') -> Set; - _ -> - error({type,"parameterized object set failure",S}) + {valueset,Set} -> #'ObjectSet'{class=ClassRef,set=Set}; + Set when is_record(Set,'ObjectSet') -> Set; + _ -> asn1_error(S, invalid_objectset) end, MatchedArgs = match_args(S,FormalParams,ArgsList,[]), -% NewS = S#state{type=ObjectSetDef,parameters=MatchedArgs++OldArgs}, NewS = S#state{type=ObjectSetDef,parameters=MatchedArgs}, check_object(NewS,ObjectSetDef,OSet). @@ -3050,9 +3044,9 @@ notify_if_not_ptype(S,#pobjectsetdef{class=Cl}) -> _ -> throw(pobjectsetdef) end; -notify_if_not_ptype(_S,PT) -> - throw({error,{"supposed to be a parameterized type",PT}}). -% fix me +notify_if_not_ptype(S, PT) -> + asn1_error(S, {param_bad_type, error_value(PT)}). + instantiate_ptype(S,Ptypedef,ParaList) -> #ptypedef{args=Args,typespec=Type} = Ptypedef, NewType = check_ptype(S,Ptypedef,Type#type{inlined=yes}), @@ -4082,9 +4076,10 @@ match_parameter(_S, {valueset,#type{def=#'Externaltypereference'{type=Name}}}, %% When a parameter is a parameterized element it has to be %% instantiated now! match_parameter(S, {valueset,T=#type{def={pt,_,_Args}}}, _Ps) -> - case catch check_type(S,#typedef{name=S#state.tname,typespec=T},T) of - pobjectsetdef -> - + try check_type(S,#typedef{name=S#state.tname,typespec=T},T) of + #type{def=Ts} -> + Ts + catch pobjectsetdef -> {_,ObjRef,_Params} = T#type.def, {_,ObjDef}=get_referenced_type(S,ObjRef), %%ObjDef is a pvaluesetdef where the type field holds the class @@ -4102,11 +4097,9 @@ match_parameter(S, {valueset,T=#type{def={pt,_,_Args}}}, _Ps) -> ObjectSet = #'ObjectSet'{class=RightClassRef,set=T}, ObjSpec = check_object(S,#typedef{typespec=ObjectSet},ObjectSet), Name = list_to_atom(asn1ct_gen:list2name([get_datastr_name(ObjDef)|S#state.recordtopname])), - save_object_set_instance(S,Name,ObjSpec); - pvaluesetdef -> error({pvaluesetdef,"parameterized valueset",S}); - {error,_Reason} -> error({type,"error in parameter",S}); - Ts when is_record(Ts,type) -> Ts#type.def + save_object_set_instance(S,Name,ObjSpec) end; + %% same as previous, only depends on order of parsing match_parameter(S, {valueset,{pos,{objectset,_,POSref},Args}}, Ps) -> match_parameter(S, {valueset,#type{def={pt,POSref,Args}}}, Ps); @@ -5853,6 +5846,8 @@ format_error({invalid_bit_number,Bit}) -> io_lib:format("the bit number '~p' is invalid", [Bit]); format_error(invalid_table_constraint) -> "the table constraint is not an object set"; +format_error(invalid_objectset) -> + "expecting an object set"; format_error({implicit_tag_before,Kind}) -> "illegal implicit tag before " ++ case Kind of @@ -5873,6 +5868,8 @@ format_error(multiple_uniqs) -> "implementation limitation: only one UNIQUE field is allowed in CLASS"; format_error({namelist_redefinition,Name}) -> io_lib:format("the name '~s' can not be redefined", [Name]); +format_error({param_bad_type, Ref}) -> + io_lib:format("'~p' is not a parameterized type", [Ref]); format_error(param_wrong_number_of_arguments) -> "wrong number of arguments"; format_error(reversed_range) -> diff --git a/lib/asn1/test/error_SUITE.erl b/lib/asn1/test/error_SUITE.erl index 331d3607af..2960304193 100644 --- a/lib/asn1/test/error_SUITE.erl +++ b/lib/asn1/test/error_SUITE.erl @@ -284,6 +284,7 @@ objects(Config) -> " obj4 SMALL ::= { &code 42 }\n" " InvalidSet CL ::= { obj1 }\n" " obj5 CL ::= {}\n" + " ErrSet ::= PT{ {PT{inst}}}\n" " CL ::= CLASS {\n" " &code INTEGER UNIQUE,\n" @@ -299,6 +300,9 @@ objects(Config) -> " &code INTEGER UNIQUE,\n" " &i INTEGER\n" " }\n" + + " PT{SMALL:Small} ::= SEQUENCE { a SMALL.&code ({Small}) }\n" + " inst SMALL ::= {&code 42, &i 4711}\n" "END\n">>}, {error, [ @@ -316,7 +320,8 @@ objects(Config) -> {structured_error,{M,7},asn1ct_check, {missing_mandatory_fields, ['Data','Set','VarTypeValue',code,enum,object, - vartypevalue],obj5}} + vartypevalue],obj5}}, + {structured_error,{M,8},asn1ct_check,invalid_objectset} ] } = run(P, Config), ok. @@ -486,13 +491,17 @@ parameterization(Config) -> " P{T1,T2} ::= SEQUENCE { a T1, b T2 }\n" " S ::= P{OCTET STRING}\n" + " Seq ::= SEQUENCE { a INTEGER }\n" + " Sbad ::= Seq{INTEGER}\n" + "END\n">>}, {error, [{structured_error,{M,2},asn1ct_check, {illegal_typereference,lowercase}}, - {structured_error, - {M,4}, - asn1ct_check,param_wrong_number_of_arguments} + {structured_error,{M,4},asn1ct_check, + param_wrong_number_of_arguments}, + {structured_error,{M,6},asn1ct_check, + {param_bad_type, 'Seq'}} ] } = run(P, Config), ok. |