aboutsummaryrefslogtreecommitdiffstats
path: root/lib/asn1
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2013-03-26 11:51:59 +0100
committerBjörn Gustavsson <[email protected]>2013-05-31 14:52:22 +0200
commit8b68ddddd113ca304690136efb6889fc565aeb44 (patch)
tree49c02250e5d6a3a1073bdb83ef3f9ffd1fe968a3 /lib/asn1
parenta70395cd59e07a03ad003fa0cf166e1237151cb5 (diff)
downloadotp-8b68ddddd113ca304690136efb6889fc565aeb44.tar.gz
otp-8b68ddddd113ca304690136efb6889fc565aeb44.tar.bz2
otp-8b68ddddd113ca304690136efb6889fc565aeb44.zip
Clean up checking of values for ENUMERATEDs
Unify the code for checking an enumeration value named in a DEFAULT and in an ENUMERATED value. There is no need to handle those cases differently. That also will also make sure that the following works: E ::= ENUMERATED { x, ..., y } e E ::= x (Extensible ENUMERATEDs were not handled when defining values.) Always generate an error when an unknown enumeration value is given (used in a DEFAULT, a message would be printed, but the compilation would succeed). Also make sure that we always include the line number for the incorrect enumeration. Write a new test case and remove the extremely rudimentary value_bad_enum_test/1 test case.
Diffstat (limited to 'lib/asn1')
-rw-r--r--lib/asn1/src/asn1ct.erl2
-rw-r--r--lib/asn1/src/asn1ct_check.erl60
-rw-r--r--lib/asn1/test/asn1_SUITE.erl6
-rw-r--r--lib/asn1/test/asn1_SUITE_data/BadEnumValue1.asn8
-rw-r--r--lib/asn1/test/error_SUITE.erl35
5 files changed, 54 insertions, 57 deletions
diff --git a/lib/asn1/src/asn1ct.erl b/lib/asn1/src/asn1ct.erl
index 15aa4efe7d..8e71a5697c 100644
--- a/lib/asn1/src/asn1ct.erl
+++ b/lib/asn1/src/asn1ct.erl
@@ -559,6 +559,8 @@ get_pos_of_def(#pobjectdef{pos=Pos}) ->
Pos;
get_pos_of_def(#pobjectsetdef{pos=Pos}) ->
Pos;
+get_pos_of_def(#'Externalvaluereference'{pos=Pos}) ->
+ Pos;
get_pos_of_def(_) ->
undefined.
diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl
index 3c9e0dd8d2..ff583d2605 100644
--- a/lib/asn1/src/asn1ct_check.erl
+++ b/lib/asn1/src/asn1ct_check.erl
@@ -2151,8 +2151,7 @@ check_value(OldS=#state{recordtopname=TopName},V) when is_record(V,valuedef) ->
'REAL' ->
ok = validate_real(SVal,Value,Constr),
#newv{value=normalize_value(SVal,Vtype,Value,[])};
- {'ENUMERATED',NamedNumberList} ->
- ok=validate_enumerated(SVal,Value,NamedNumberList,Constr),
+ {'ENUMERATED',_} ->
#newv{value=normalize_value(SVal,Vtype,Value,[])};
'BOOLEAN'->
ok=validate_boolean(SVal,Value,Constr),
@@ -2511,23 +2510,6 @@ validate_objectdescriptor(_S,_Value,_Constr) ->
validate_real(_S,_Value,_Constr) ->
ok.
-validate_enumerated(S,Id,NamedNumberList,_Constr) when is_atom(Id) ->
- case lists:keysearch(Id,1,NamedNumberList) of
- {value,_} -> ok;
- false -> error({value,"unknown ENUMERATED",S})
- end;
-validate_enumerated(S,{identifier,_Pos,Id},NamedNumberList,_Constr) ->
- case lists:keysearch(Id,1,NamedNumberList) of
- {value,_} -> ok;
- false -> error({value,"unknown ENUMERATED",S})
- end;
-validate_enumerated(S,#'Externalvaluereference'{value=Id},
- NamedNumberList,_Constr) ->
- case lists:keysearch(Id,1,NamedNumberList) of
- {value,_} -> ok;
- false -> error({value,"unknown ENUMERATED",S})
- end.
-
validate_boolean(_S,_Value,_Constr) ->
ok.
@@ -2588,7 +2570,8 @@ normalize_value(_,_,mandatory,_) ->
mandatory;
normalize_value(_,_,'OPTIONAL',_) ->
'OPTIONAL';
-normalize_value(S,Type,{'DEFAULT',Value},NameList) ->
+normalize_value(S0, Type, {'DEFAULT',Value}, NameList) ->
+ S = S0#state{value=Value},
case catch get_canonic_type(S,Type,NameList) of
{'BOOLEAN',CType,_} ->
normalize_boolean(S,Value,CType);
@@ -2827,29 +2810,20 @@ normalize_objectdescriptor(Value) ->
normalize_real(Value) ->
Value.
-normalize_enumerated(S,#'Externalvaluereference'{value=V},CType)
- when is_list(CType) ->
- normalize_enumerated2(S,V,CType);
-normalize_enumerated(S,Value,CType) when is_atom(Value),is_list(CType) ->
- normalize_enumerated2(S,Value,CType);
-normalize_enumerated(S,{Name,EnumV},CType) when is_atom(Name) ->
- normalize_enumerated(S,EnumV,CType);
-normalize_enumerated(S,Value,{CType1,CType2}) when is_list(CType1), is_list(CType2)->
- normalize_enumerated(S,Value,CType1++CType2);
-normalize_enumerated(S,V,CType) ->
- asn1ct:warning("Enumerated unknown type ~p~n",[CType],S,
- "Enumerated unknown type"),
- V.
-normalize_enumerated2(S,V,Enum) ->
- case lists:keysearch(V,1,Enum) of
- {value,{Val,_}} -> Val;
- _ ->
- asn1ct:warning("enumerated value is not correct ~p~n",[V],S,
- "enumerated value is not correct"),
- V
+normalize_enumerated(S, Id, {Base,Ext}) ->
+ %% Extensible ENUMERATED.
+ normalize_enumerated(S, Id, Base++Ext);
+normalize_enumerated(S, #'Externalvaluereference'{value=Id},
+ NamedNumberList) ->
+ normalize_enumerated(S, Id, NamedNumberList);
+normalize_enumerated(S, Id, NamedNumberList) when is_atom(Id) ->
+ case lists:keymember(Id, 1, NamedNumberList) of
+ true ->
+ Id;
+ false ->
+ throw(asn1_error(S, S#state.value, {undefined,Id}))
end.
-
normalize_choice(S,{'CHOICE',{C,V}},CType,NameList) when is_atom(C) ->
case catch lists:keysearch(C,#'ComponentType'.name,CType) of
{value,#'ComponentType'{typespec=CT,name=Name}} ->
@@ -7014,9 +6988,13 @@ asn1_error(#state{mname=Where}, Item, Error) ->
format_error({already_defined,Name,PrevLine}) ->
io_lib:format("the name ~p has already been defined at line ~p",
[Name,PrevLine]);
+format_error({undefined,Name}) ->
+ io_lib:format("'~s' is referenced, but is not defined", [Name]);
format_error(Other) ->
io_lib:format("~p", [Other]).
+error({_,{structured_error,_,_,_}=SE,_}) ->
+ SE;
error({export,Msg,#state{mname=Mname,type=Ref,tname=Typename}}) ->
Pos = Ref#'Externaltypereference'.pos,
io:format("asn1error:~p:~p:~p~n~p~n",[Pos,Mname,Typename,Msg]),
diff --git a/lib/asn1/test/asn1_SUITE.erl b/lib/asn1/test/asn1_SUITE.erl
index 2b3ff07980..6be493320c 100644
--- a/lib/asn1/test/asn1_SUITE.erl
+++ b/lib/asn1/test/asn1_SUITE.erl
@@ -139,7 +139,6 @@ groups() ->
testSetOfCho,
testEnumExt,
value_test,
- value_bad_enum_test,
testSeq2738,
% Uses 'Constructed'
{group, [], [constructed,
@@ -741,11 +740,6 @@ value_test(Config, Rule, Opts) ->
{ok, _} = asn1ct:test('ObjIdValues', 'ObjIdType',
'ObjIdValues':'mobileDomainId'()).
-value_bad_enum_test(Config) ->
- {error, _} = asn1ct:compile(?config(data_dir, Config) ++
- "BadEnumValue1",
- [{outdir, ?config(case_dir, Config)}]).
-
constructed(Config) ->
test(Config, fun constructed/3, [ber]).
constructed(Config, Rule, Opts) ->
diff --git a/lib/asn1/test/asn1_SUITE_data/BadEnumValue1.asn b/lib/asn1/test/asn1_SUITE_data/BadEnumValue1.asn
deleted file mode 100644
index dbc224a74b..0000000000
--- a/lib/asn1/test/asn1_SUITE_data/BadEnumValue1.asn
+++ /dev/null
@@ -1,8 +0,0 @@
-BadEnumValue1 DEFINITIONS AUTOMATIC TAGS ::=
-
-BEGIN
-
-E3 ::= ENUMERATED {monday,thuesday(0)}
-enumWrongVal E3 ::= sunday
-
-END
diff --git a/lib/asn1/test/error_SUITE.erl b/lib/asn1/test/error_SUITE.erl
index 4dd4d58aad..a94a6d95a0 100644
--- a/lib/asn1/test/error_SUITE.erl
+++ b/lib/asn1/test/error_SUITE.erl
@@ -19,7 +19,7 @@
-module(error_SUITE).
-export([suite/0,all/0,groups/0,
- already_defined/1]).
+ already_defined/1,enumerated/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -29,7 +29,8 @@ all() ->
[{group,p}].
groups() ->
- [{p,parallel(),[already_defined]}].
+ [{p,parallel(),[already_defined,
+ enumerated]}].
parallel() ->
case erlang:system_info(schedulers) > 1 of
@@ -66,6 +67,36 @@ already_defined(Config) ->
} = run(P, Config),
ok.
+enumerated(Config) ->
+ M = 'Enumerated',
+ P = {M,
+ <<"Enumerated DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n"
+ " Enum ::= ENUMERATED { a, b, c }\n"
+ " e Enum ::= d\n"
+ " EnumExt ::= ENUMERATED { x, ..., y }\n"
+ " ext EnumExt ::= z\n"
+ " S1 ::= SEQUENCE {\n"
+ " ge1 Enum DEFAULT a,\n"
+ " ge2 EnumExt DEFAULT x,\n"
+ " ge3 EnumExt DEFAULT y,\n"
+ " e Enum DEFAULT aa\n"
+ " }\n"
+ " S2 ::= SEQUENCE {\n"
+ " e2 EnumExt DEFAULT xyz\n"
+ " }\n"
+ "END\n">>},
+ {error,
+ [
+ {structured_error,{'Enumerated',3},asn1ct_check,{undefined,d}},
+ {structured_error,{'Enumerated',5},asn1ct_check,{undefined,z}},
+ {structured_error,{'Enumerated',10},asn1ct_check,{undefined,aa}},
+ {structured_error,{'Enumerated',13},asn1ct_check,{undefined,xyz}}
+ ]
+ } = run(P, Config),
+ ok.
+
+
+
run({Mod,Spec}, Config) ->
Base = atom_to_list(Mod) ++ ".asn1",
File = filename:join(?config(priv_dir, Config), Base),