diff options
Diffstat (limited to 'lib/asn1/src/asn1ct_check.erl')
-rw-r--r-- | lib/asn1/src/asn1ct_check.erl | 172 |
1 files changed, 69 insertions, 103 deletions
diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl index e318477234..59e82b7a57 100644 --- a/lib/asn1/src/asn1ct_check.erl +++ b/lib/asn1/src/asn1ct_check.erl @@ -1,7 +1,8 @@ +%% vim: tabstop=8:shiftwidth=4 %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% Copyright Ericsson AB 1997-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -94,8 +95,8 @@ check(S,{Types,Values,ParameterizedTypes,Classes,Objects,ObjectSets}) -> _Perror = checkp(S,ParameterizedTypes,[]), % must do this before the templates are used %% table to save instances of parameterized objects,object sets - asn1ct:create_ets_table(parameterized_objects,[named_table]), - asn1ct:create_ets_table(inlined_objects,[named_table]), + asn1ct_table:new(parameterized_objects), + asn1ct_table:new(inlined_objects), Terror = checkt(S,Types,[]), @@ -144,17 +145,17 @@ check(S,{Types,Values,ParameterizedTypes,Classes,Objects,ObjectSets}) -> NewObjectSets, [],[],[]), ?dbg("checko finished with errors:~n~p~n~n",[Oerror]), - InlinedObjTuples = ets:tab2list(inlined_objects), + InlinedObjTuples = asn1ct_table:to_list(inlined_objects), InlinedObjects = lists:map(Element2,InlinedObjTuples), - ets:delete(inlined_objects), - ParameterizedElems = ets:tab2list(parameterized_objects), + asn1ct_table:delete(inlined_objects), + ParameterizedElems = asn1ct_table:to_list(parameterized_objects), ParObjectSets = lists:filter(fun({_OSName,objectset,_}) -> true; (_)-> false end,ParameterizedElems), ParObjectSetNames = lists:map(Element1,ParObjectSets), ParTypes = lists:filter(fun({_TypeName,type,_}) -> true; (_) -> false end, ParameterizedElems), ParTypesNames = lists:map(Element1,ParTypes), - ets:delete(parameterized_objects), + asn1ct_table:delete(parameterized_objects), put(asn1_reference,undefined), Exporterror = check_exports(S,S#state.module), @@ -4176,7 +4177,7 @@ check_constraint(S,{'SizeConstraint',Lb}) -> check_constraint(S,{'SingleValue', L}) when is_list(L) -> F = fun(A) -> resolv_value(S,A) end, - {'SingleValue',lists:map(F,L)}; + {'SingleValue',lists:sort(lists:map(F,L))}; check_constraint(S,{'SingleValue', V}) when is_integer(V) -> Val = resolv_value(S,V), @@ -4398,22 +4399,22 @@ constraint_union(_S,C) -> constraint_union1(S,[A={'ValueRange',_},union,B={'ValueRange',_}|Rest],Acc) -> AunionB = constraint_union_vr([A,B]), - constraint_union1(S,Rest,AunionB++Acc); + constraint_union1(S,Rest,Acc ++ AunionB); constraint_union1(S,[A={'SingleValue',_},union,B={'SingleValue',_}|Rest],Acc) -> AunionB = constraint_union_sv(S,[A,B]), - constraint_union1(S,Rest,AunionB++Acc); + constraint_union1(S,Rest,Acc ++ AunionB); constraint_union1(S,[A={'SingleValue',_},union,B={'ValueRange',_}|Rest],Acc) -> AunionB = union_sv_vr(S,A,B), - constraint_union1(S,Rest,AunionB++Acc); + constraint_union1(S,Rest,Acc ++ AunionB); constraint_union1(S,[A={'ValueRange',_},union,B={'SingleValue',_}|Rest],Acc) -> AunionB = union_sv_vr(S,B,A), - constraint_union1(S,Rest,AunionB++Acc); + constraint_union1(S,Rest,Acc ++ AunionB); constraint_union1(S,[union|Rest],Acc) -> %skip when unsupported constraints constraint_union1(S,Rest,Acc); constraint_union1(S,[A|Rest],Acc) -> constraint_union1(S,Rest,[A|Acc]); constraint_union1(_S,[],Acc) -> - lists:reverse(Acc). + Acc. constraint_union_sv(_S,SV) -> Values=lists:map(fun({_,V})->V end,SV), @@ -4466,63 +4467,33 @@ constraint_union_vr([{_,{_,Ub2}}|Rest],A=[{_,{_,Ub1}}|_Acc]) when Ub2=<Ub1-> constraint_union_vr([VR|Rest],Acc) -> constraint_union_vr(Rest,[VR|Acc]). -union_sv_vr(_S,C1={'SingleValue',SV},C2={'ValueRange',VR={Lb,Ub}}) +union_sv_vr(_S,{'SingleValue',SV},VR) when is_integer(SV) -> - case is_int_in_vr(SV,C2) of - true -> [C2]; - _ -> - case VR of - {'MIN',Ub} when SV==Ub+1 -> [{'ValueRange',{'MIN',SV}}]; - {Lb,'MAX'} when SV==Lb-1 -> [{'ValueRange',{SV,'MAX'}}]; - {Lb,Ub} when SV==Ub+1 -> [{'ValueRange',{Lb,SV}}]; - {Lb,Ub} when SV==Lb-1 -> [{'ValueRange',{SV,Ub}}]; - _ -> - [C1,C2] - end - end; -union_sv_vr(_S,C1={'SingleValue',SV},C2={'ValueRange',{_Lb,_Ub}}) + union_sv_vr(_S,{'SingleValue',[SV]},VR); +union_sv_vr(_S,{'SingleValue',SV},{'ValueRange',{VLb,VUb}}) when is_list(SV) -> - case lists:filter(fun(X)->is_int_in_vr(X,C2) end,SV) of - [] -> [C2]; - L -> - case expand_vr(L,C2) of - {[],C3} -> [C3]; - {L,C2} -> [C1,C2]; - {[Val],C3} -> [{'SingleValue',Val},C3]; - {L2,C3} -> [{'SingleValue',L2},C3] - end - end. - -expand_vr(L,VR={_,{Lb,Ub}}) -> - case lower_Lb(L,Lb) of - false -> - case higher_Ub(L,Ub) of - false -> - {L,VR}; - {L1,UbNew} -> - expand_vr(L1,{'ValueRange',{Lb,UbNew}}) - end; - {L1,LbNew} -> - expand_vr(L1,{'ValueRange',{LbNew,Ub}}) - end. - -lower_Lb(_,'MIN') -> - false; -lower_Lb(L,Lb) -> - remove_val_from_list(Lb - 1,L). - -higher_Ub(_,'MAX') -> - false; -higher_Ub(L,Ub) -> - remove_val_from_list(Ub + 1,L). + L = lists:sort(SV++[VLb,VUb]), + {Lb,L1} = case lists:member('MIN',L) of + true -> {'MIN',L--['MIN']}; % remove 'MIN' so it does not disturb + false -> {hd(L),tl(L)} + end, + Ub = case lists:member('MAX',L1) of + true -> 'MAX'; + false -> lists:last(L1) + end, + case SV of + [H] -> H; + _ -> SV + end, + %% for now we through away the Singlevalues so that they don't disturb + %% in the code generating phase (the effective Valuerange is already + %% calculated. If we want to keep the Singlevalues as well for + %% use in code gen phases we need to introduce a new representation + %% like {'ValueRange',{Lb,Ub},[ListOfRanges|AntiValues|Singlevalues] + %% These could be used to generate guards which allows only the specific + %% values , not the full range + [{'ValueRange',{Lb,Ub}}]. -remove_val_from_list(Val,List) -> - case lists:member(Val,List) of - true -> - {lists:delete(Val,List),Val}; - false -> - false - end. %% get_constraints/2 %% Arguments are a list of constraints, which has the format {key,value}, @@ -4923,12 +4894,7 @@ get_referenced(S,Emod,Ename,Pos) -> %% May be an imported entity in module Emod or Emod may not exist case asn1_db:dbget(Emod,'MODULE') of undefined -> - case parse_and_save(S,Emod) of - ok -> - get_referenced(S,Emod,Ename,Pos); - _ -> - throw({error,{asn1,{module_not_found,Emod}}}) - end; + throw({error,{asn1,{module_not_found,Emod}}}); _ -> NewS = update_state(S,Emod), get_imported(NewS,Ename,Emod,Pos) @@ -4970,13 +4936,7 @@ get_imported(S,Name,Module,Pos) -> parse_and_save(S,Imodule), case asn1_db:dbget(Imodule,'MODULE') of undefined -> - case parse_and_save(S,Imodule) of - ok -> - %% check with cover - get_referenced(S,Module,Name,Pos); - _ -> - throw({error,{asn1,{module_not_found,Imodule}}}) - end; + throw({error,{asn1,{module_not_found,Imodule}}}); Im when is_record(Im,module) -> case is_exported(Im,Name) of false -> @@ -5116,16 +5076,16 @@ renamed_reference(S,#'Externaltypereference'{type=Name,module=Module}) -> renamed_reference(S,Name,Module) -> %% first check if there is a renamed type in this module %% second check if any type was imported with this name - case ets:info(renamed_defs) of - undefined -> undefined; - _ -> - case ets:match(renamed_defs,{'$1',Name,Module}) of + case asn1ct_table:exists(renamed_defs) of + false -> undefined; + true -> + case asn1ct_table:match(renamed_defs, {'$1',Name,Module}) of [] -> - case ets:info(original_imports) of - undefined -> + case asn1ct_table:exists(original_imports) of + false -> undefined; - _ -> - case ets:match(original_imports,{Module,'$1'}) of + true -> + case asn1ct_table:match(original_imports, {Module,'$1'}) of [] -> undefined; [[ImportsList]] -> @@ -5253,6 +5213,9 @@ check_int(S,[{'NamedNumber',Id,Num}|T],Acc) when is_integer(Num) -> check_int(S,[{'NamedNumber',Id,{identifier,_,Name}}|T],Acc) -> Val = dbget_ex(S,S#state.mname,Name), check_int(S,[{'NamedNumber',Id,Val#valuedef.value}|T],Acc); +check_int(S,[{'NamedNumber',Id,{'Externalvaluereference',_,Mod,Name}}|T],Acc) -> + Val = dbget_ex(S,Mod,Name), + check_int(S,[{'NamedNumber',Id,Val#valuedef.value}|T],Acc); check_int(_S,[],Acc) -> lists:keysort(2,Acc). @@ -6002,17 +5965,12 @@ tag_nums_root2([],Ext,Root2) -> [0,Ext,Root2]. is_automatic_tagged_in_multi_file(Name) -> - case ets:info(automatic_tags) of - undefined -> + case asn1ct_table:exists(automatic_tags) of + false -> %% this case when not multifile compilation false; - _ -> -% case ets:member(automatic_tags,Name) of - case ets:lookup(automatic_tags,Name) of -% true -> -% true; -% _ -> -% false + true -> + case asn1ct_table:lookup(automatic_tags, Name) of [] -> false; _ -> true end @@ -6033,17 +5991,25 @@ generate_automatic_tags1([H|T],[TagNo|TagNos]) when is_record(H,'ComponentType') type={default,'IMPLICIT'}, form= 0 }]}, % PRIMITIVE [H#'ComponentType'{typespec=NewTs}|generate_automatic_tags1(T,[TagNo+1|TagNos])]; -generate_automatic_tags1([ExtMark|T],[_TagNo|TagNos]) -> % EXTENSIONMARK +generate_automatic_tags1([ExtMark = #'EXTENSIONMARK'{}|T],[_TagNo|TagNos]) -> [ExtMark | generate_automatic_tags1(T,TagNos)]; +generate_automatic_tags1([H|T],TagList) -> % ExtensionAdditionGroup etc are just ignored + [H | generate_automatic_tags1(T,TagList)]; generate_automatic_tags1([],_) -> []. -any_manual_tag([#'ComponentType'{typespec=#type{tag=[]}}|Rest]) -> - any_manual_tag(Rest); -any_manual_tag([#'EXTENSIONMARK'{}|Rest]) -> - any_manual_tag(Rest); -any_manual_tag([_|_Rest]) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Returns true if there is at least one ComponentType with a manually +%% specified tag. No manual tag is indicated by typespec=#type{tag=[]} +%% so we check if we find a tag =/= [] and return true in that case +%% all other things in the componentlist like (EXTENSIONMARK, +%% ExtensionAdditionGroup,...) except ComponentType is simply +%% ignored/skipped +any_manual_tag([#'ComponentType'{typespec=#type{tag=Tag}}|_Rest]) + when Tag =/= []-> true; +any_manual_tag([_|Rest]) -> + any_manual_tag(Rest); any_manual_tag([]) -> false. |