1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2014-2018. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20%% 21 22-module(testUniqueObjectSets). 23-export([main/3]). 24 25%% Run-time function called by the generated code. 26seq_roundtrip(I, D0) -> 27 M = 'UniqueObjectSets', 28 try 29 {ok,Enc} = M:encode('Seq', {'Seq',I,D0}), 30 asn1_test_lib:map_roundtrip(M, 'Seq', Enc), 31 {ok,{'Seq',I,D}} = M:decode('Seq', Enc), 32 D 33 catch C:E:Stk -> 34 io:format("FAILED: ~p ~p\n", [I,D0]), 35 erlang:raise(C, E, Stk) 36 end. 37 38types() -> 39 [{"CHOICE { a INTEGER, b BIT STRING }", {b,<<42:3>>}}, 40 {"INTEGER",42}, 41 {"SEQUENCE {a OCTET STRING}",{'_',<<"abc">>}}, 42 {"SEQUENCE {b BOOLEAN, ...}",{'_',true}}, 43 {"SEQUENCE {b BOOLEAN, ..., s IA5String, ..., e ENUMERATED { x, y, z}}", 44 {'_',false,"string",y}}, 45 {"SET {a BIT STRING}",{'_',<<1:17>>}}, 46 {"SEQUENCE OF INTEGER",[-19,0,555,777]}, 47 {"SET OF BOOLEAN",[true,false,true]}, 48 {"SEQUENCE OF SEQUENCE {x INTEGER (0..7)}",[{'_',7},{'_',0}]}, 49 {"SET OF SEQUENCE {x INTEGER (0..7)}",[{'_',7},{'_',0}]} 50 ]. 51 52main(_,jer,_) -> ok; 53main(CaseDir, Rule, Opts) -> 54 D0 = types(), 55 {D1,_} = lists:mapfoldl(fun({T,S}, I) -> 56 {{I,T,S},I+1} 57 end, 1, D0), 58 Types = [gen_types(I, Type) || {I,Type,_} <- D1], 59 Set = [gen_set_items(I, T) || {I,T,_} <- D1], 60 Objs = [gen_obj(I) || {I,_,_} <- D1], 61 DupObjs = [gen_dup_obj(I, T) || {I,T,_} <- D1], 62 DupObjRefs0 = [gen_dup_obj_refs(I) || {I,_,_} <- D1], 63 DupObjRefs = lists:join(" |\n", DupObjRefs0), 64 Asn1Spec = 'UniqueObjectSets', 65 A = ["UniqueObjectSets DEFINITIONS AUTOMATIC TAGS ::=\n", 66 "BEGIN\n\n", 67 "TEST-UNIQUE ::= CLASS {\n" 68 " &id INTEGER UNIQUE,\n" 69 " &Type OPTIONAL\n" 70 "}\n" 71 "WITH SYNTAX {IDENTIFIED BY &id [TYPE &Type]}\n", 72 $\n, 73 "DUP-CONTAINER ::= CLASS {\n" 74 " &id INTEGER UNIQUE,\n" 75 " &data TEST-UNIQUE\n" 76 "} WITH SYNTAX {\n" 77 " ID &id, &data\n" 78 "}\n", 79 $\n, 80 Types,$\n, 81 "UniqSet TEST-UNIQUE ::= {\n", 82 Set, 83 " DupSet-1 |\n", 84 " DupSet-2, ...\n", 85 "}\n\n", 86 Objs,$\n, 87 DupObjs,$\n, 88 "DupSet-1 TEST-UNIQUE ::= {\n", 89 DupObjRefs,$\n, 90 "}\n\n", 91 "DupSet-2 TEST-UNIQUE ::= {\n", 92 DupObjRefs,",...\n", 93 "}\n\n", 94 "Seq ::= SEQUENCE {\n" 95 " id TEST-UNIQUE.&id ({UniqSet}),\n" 96 " type TEST-UNIQUE.&Type ({UniqSet}{@id})\n" 97 "}\n" 98 "END\n"], 99 Asn1File = filename:join(CaseDir, atom_to_list(Asn1Spec)++".asn1"), 100 ok = file:write_file(Asn1File, A), 101 102 TestModule = 'unique_object_sets', 103 Test0 = [gen_test(I, Data) || {I,_,Data} <- D1], 104 Test = ["-module(",atom_to_list(TestModule),").\n" 105 "-export([main/1]).\n" 106 "\n" 107 "main(SeqRoundtrip) ->\n", 108 " ",atom_to_list(Rule)," = '",atom_to_list(Asn1Spec), 109 "':encoding_rule(),\n", 110 Test0, 111 " ok.\n" 112 ], 113 ErlFile = filename:join(CaseDir, atom_to_list(TestModule)++".erl"), 114 ok = file:write_file(ErlFile, Test), 115 116 io:format("~s\n~s\n", [Asn1File,ErlFile]), 117 case Rule of 118 per -> 119 io:put_chars([A,$\n,Test,$\n]); 120 _ -> 121 ok 122 end, 123 124 ok = asn1ct:compile(Asn1File, [Rule,{outdir,CaseDir}|Opts]), 125 {ok,TestModule} = c:c(ErlFile, [{outdir,CaseDir}]), 126 TestModule:main(fun seq_roundtrip/2), 127 ok. 128 129gen_types(I, Type) -> 130 io_lib:format("AType~p ::= ~s\n", [I,Type]). 131 132gen_set_items(I, T) -> 133 io_lib:format(" {IDENTIFIED BY ~p TYPE AType~p} |\n" 134 " {IDENTIFIED BY ~p TYPE AType~p} |\n" 135 " {IDENTIFIED BY ~p TYPE ~s} |\n" 136 " obj-~p |\n\n", 137 [I,I,I,I,I,T,I]). 138 139gen_obj(I) -> 140 io_lib:format("obj-~p TEST-UNIQUE ::= {IDENTIFIED BY ~p TYPE AType~p}\n", 141 [I,I,I]). 142 143gen_dup_obj(I, T) -> 144 io_lib:format("dup-obj-~p DUP-CONTAINER ::= " 145 "{ID ~p, {IDENTIFIED BY ~p TYPE ~s}}\n", 146 [I,I,I+1000,T]). 147 148gen_dup_obj_refs(I) -> 149 io_lib:format("dup-obj-~p.&data", [I]). 150 151gen_test(I, Data) -> 152 io_lib:format(" ~s = SeqRoundtrip(~p, ~p),\n", 153 [match_term(Data),I,Data]). 154 155match_term('_') -> 156 "_"; 157match_term([H|T]=L) -> 158 case is_intlist(L) of 159 true -> 160 io_lib:format("~p", [L]); 161 false -> 162 ["[",match_term(H),"|",match_term(T),"]"] 163 end; 164match_term(Tuple) when is_tuple(Tuple) -> 165 ["{",match_term_tuple(Tuple, 1),"}"]; 166match_term(Other) -> 167 io_lib:format("~p", [Other]). 168 169match_term_tuple(T, I) when I =< tuple_size(T) -> 170 [match_term(element(I, T)), 171 if I < tuple_size(T) -> ","; 172 true -> "" end|match_term_tuple(T, I+1)]; 173match_term_tuple(_, _) -> 174 []. 175 176is_intlist(L) -> 177 lists:all(fun is_integer/1, L). 178