NativeEnumerated.c vars NULL init and check
[com/asn1c.git] / tests / tests-skeletons / check-PER-support.c
1 #include <assert.h>
2 #include <per_support.h>
3
4 static void put(asn_per_outp_t *po, size_t length) {
5     fprintf(stderr, "put(%zd)\n", length);
6     do {
7         int need_eom = 123;
8         ssize_t may_write = uper_put_length(po, length, &need_eom);
9         fprintf(stderr, "  put %zu\n", may_write);
10         assert(may_write >= 0);
11         assert((size_t)may_write <= length);
12         assert(need_eom != 123);
13         length -= may_write;
14         if(need_eom) {
15             assert(length == 0);
16             if(uper_put_length(po, 0, 0)) {
17                 assert(!"Unreachable");
18             }
19             fprintf(stderr, "  put EOM 0\n");
20         }
21     } while(length);
22     fprintf(stderr, "put(...) in %zu bits\n", po->nboff);
23     assert(po->nboff != 0);
24     assert(po->flushed_bytes == 0);
25 }
26
27 static size_t get(asn_per_outp_t *po) {
28     asn_bit_data_t data;
29     memset(&data, 0, sizeof(data));
30     data.buffer = po->tmpspace;
31     data.nboff = 0;
32     data.nbits = 8 * (po->buffer - po->tmpspace) + po->nboff;
33
34     fprintf(stderr, "get(): %s\n", asn_bit_data_string(&data));
35
36     size_t length = 0;
37     int repeat = 0;
38     do {
39         ssize_t n = uper_get_length(&data, -1, 0, &repeat);
40         fprintf(stderr, "  get = %zu +%zd\n", length, n);
41         assert(n >= 0);
42         length += n;
43     } while(repeat);
44     fprintf(stderr, "get() = %zu\n", length);
45
46     return length;
47 }
48
49 static void
50 check_round_trip(size_t length) {
51     fprintf(stderr, "\nRound-trip for %zu\n", length);
52     asn_per_outp_t po;
53
54     memset(&po, 0, sizeof(po));
55     po.buffer = po.tmpspace;
56     po.nbits = 8 * sizeof(po.tmpspace);
57
58     put(&po, length);
59     size_t recovered = get(&po);
60
61     assert(recovered == length);
62 }
63
64 /*
65  * Checks that we can get the PER length that we have just put,
66  * and receive the same value.
67  */
68 static void
69 check_round_trips() {
70     check_round_trip(0);
71     check_round_trip(1);
72     check_round_trip(127);
73     check_round_trip(128);
74     check_round_trip(129);
75     check_round_trip(255);
76     check_round_trip(256);
77     check_round_trip(65534);
78     check_round_trip(65535);
79     check_round_trip(65536);
80     check_round_trip(65538);
81     check_round_trip(128000);
82     for(size_t i = 1; i < 10; i++) {
83         check_round_trip(i*16384 - 1);
84         check_round_trip(i*16384);
85         check_round_trip(i*16384 + 1);
86     }
87 }
88
89 #define OK_UNREBASE(w, l, u, c) check_unrebase(__LINE__, 0, w, l, u, c)
90 #define NO_UNREBASE(w, l, u) check_unrebase(__LINE__, 1, w, l, u, 0)
91
92 static void
93 check_unrebase(int lineno, int expected_to_fail, unsigned long wire_value,
94                long lb, long ub, long control) {
95     fprintf(stderr, "%03d: Checking recovery of %lu (%ld..%ld)", lineno,
96             wire_value, lb, ub);
97     if(expected_to_fail) {
98         fprintf(stderr, " to FAIL\n");
99     } else {
100         fprintf(stderr, " into %ld\n", control);
101     }
102
103     long outcome;
104     int ret = per_long_range_unrebase(wire_value, lb, ub, &outcome);
105     if(ret == 0) {
106         assert(!expected_to_fail);
107     } else {
108         assert(expected_to_fail);
109         return;
110     }
111
112     assert(outcome == control);
113 }
114
115
116 #define OK_REBASE_ROUNDTRIP(v, l, u) \
117     check_range_rebase_round_trip(__LINE__, 0, v, l, u)
118
119 #define NO_REBASE_ROUNDTRIP(v, l, u) \
120     check_range_rebase_round_trip(__LINE__, 1, v, l, u)
121
122 static void
123 check_range_rebase_round_trip(int lineno, int expected_to_fail, long value,
124                               long lb, long ub) {
125     unsigned long wire_value;
126     int ret;
127
128     fprintf(stderr, "%03d: Rebase %ld into (%ld..%ld) %s\n", lineno, value, lb,
129             ub, expected_to_fail ? "FAIL" : "OK");
130
131     ret = per_long_range_rebase(value, lb, ub, &wire_value);
132     if(ret != 0) {
133         if(expected_to_fail) {
134             return;
135         } else {
136             fprintf(stderr, "%03d: Original %ld (%ld..%ld) failed to rebase\n",
137                     lineno, value, lb, ub);
138             assert(ret == 0);
139         }
140     } if(expected_to_fail) {
141         fprintf(
142             stderr,
143             "%03d: Original %ld (%ld..%ld) rebased to %lu where it shouldn't\n",
144             lineno, value, lb, ub, wire_value);
145         assert(expected_to_fail && ret == -1);
146     }
147
148     fprintf(stderr, "%03d: Recover %lu into (%ld..%ld)\n", lineno,
149             wire_value, lb, ub);
150
151     long recovered;
152     ret = per_long_range_unrebase(wire_value, lb, ub, &recovered);
153     if(ret != 0) {
154         fprintf(stderr, "%03d: Wire value %lu (%ld..%ld) failed to unrebase\n",
155                 lineno, wire_value, lb, ub);
156         assert(ret == 0);
157     }
158
159     if(value != recovered) {
160         fprintf(stderr,
161                 "%03d: Value %ld (%ld..%ld) failed to round-trip (=%ld)\n",
162                 lineno, value, lb, ub, recovered);
163         assert(value == recovered);
164     }
165
166 }
167
168 static void
169 check_range_rebase() {
170
171     OK_UNREBASE(0U, 0, 0, 0);
172     NO_UNREBASE(1U, 0, 0);
173     OK_UNREBASE(0, LONG_MAX, LONG_MAX, LONG_MAX);
174     NO_UNREBASE(1, LONG_MAX, LONG_MAX);
175     OK_UNREBASE(0, LONG_MAX-1, LONG_MAX-1, LONG_MAX-1);
176     NO_UNREBASE(1, LONG_MAX-1, LONG_MAX-1);
177
178     OK_REBASE_ROUNDTRIP(0, 0, 0);
179     OK_REBASE_ROUNDTRIP(0, 0, 1);
180     OK_REBASE_ROUNDTRIP(1, 0, 1);
181
182     NO_REBASE_ROUNDTRIP(-1, 0, 0);
183     NO_REBASE_ROUNDTRIP(1, 0, 0);
184     NO_REBASE_ROUNDTRIP(LONG_MIN, 0, 0);
185     NO_REBASE_ROUNDTRIP(LONG_MAX, 0, 0);
186
187     OK_REBASE_ROUNDTRIP(-2, -2, -1);
188     OK_REBASE_ROUNDTRIP(-1, -2, -1);
189     NO_REBASE_ROUNDTRIP(-3, -2, -1);
190     NO_REBASE_ROUNDTRIP(0, -2, -1);
191
192     OK_REBASE_ROUNDTRIP(LONG_MAX, LONG_MAX, LONG_MAX);
193     NO_REBASE_ROUNDTRIP(LONG_MAX-1, LONG_MAX, LONG_MAX);
194     NO_REBASE_ROUNDTRIP(0, LONG_MAX, LONG_MAX);
195     NO_REBASE_ROUNDTRIP(LONG_MIN, LONG_MAX, LONG_MAX);
196     NO_REBASE_ROUNDTRIP(LONG_MIN+1, LONG_MAX, LONG_MAX);
197
198     OK_REBASE_ROUNDTRIP(LONG_MIN, LONG_MIN, LONG_MIN);
199     NO_REBASE_ROUNDTRIP(LONG_MIN+1, LONG_MIN, LONG_MIN);
200     NO_REBASE_ROUNDTRIP(0, LONG_MIN, LONG_MIN);
201     NO_REBASE_ROUNDTRIP(LONG_MAX-1, LONG_MIN, LONG_MIN);
202     NO_REBASE_ROUNDTRIP(LONG_MAX, LONG_MIN, LONG_MIN);
203     OK_REBASE_ROUNDTRIP(LONG_MAX-10, LONG_MAX-10, LONG_MAX-5);
204     OK_REBASE_ROUNDTRIP(LONG_MAX-5, LONG_MAX-10, LONG_MAX-5);
205     OK_REBASE_ROUNDTRIP(LONG_MAX-7, LONG_MAX-10, LONG_MAX-5);
206     NO_REBASE_ROUNDTRIP(LONG_MAX-4, LONG_MAX-10, LONG_MAX-5);
207
208     NO_REBASE_ROUNDTRIP(LONG_MIN, LONG_MIN+1, LONG_MIN+2);
209     OK_REBASE_ROUNDTRIP(LONG_MIN+1, LONG_MIN+1, LONG_MIN+2);
210     OK_REBASE_ROUNDTRIP(LONG_MIN+2, LONG_MIN+1, LONG_MIN+2);
211     NO_REBASE_ROUNDTRIP(LONG_MIN+3, LONG_MIN+1, LONG_MIN+2);
212     OK_REBASE_ROUNDTRIP(LONG_MIN, LONG_MIN, LONG_MIN+1);
213     OK_REBASE_ROUNDTRIP(LONG_MIN+1, LONG_MIN, 0);
214     OK_REBASE_ROUNDTRIP(LONG_MIN+1, LONG_MIN, LONG_MIN+1);
215     NO_REBASE_ROUNDTRIP(LONG_MIN+2, LONG_MIN, LONG_MIN+1);
216
217     OK_REBASE_ROUNDTRIP(-1, -1, 1);
218     OK_REBASE_ROUNDTRIP(0, -1, 1);
219     OK_REBASE_ROUNDTRIP(1, -1, 1);
220
221     NO_REBASE_ROUNDTRIP(-2, -1, 1);
222     NO_REBASE_ROUNDTRIP(2, -1, 1);
223     NO_REBASE_ROUNDTRIP(LONG_MIN, -1, 1);
224     NO_REBASE_ROUNDTRIP(LONG_MAX, -1, 1);
225
226     OK_REBASE_ROUNDTRIP(-1, LONG_MIN, LONG_MAX);
227     OK_REBASE_ROUNDTRIP(0, LONG_MIN, LONG_MAX);
228     OK_REBASE_ROUNDTRIP(1, LONG_MIN, LONG_MAX);
229     OK_REBASE_ROUNDTRIP(LONG_MIN, LONG_MIN, LONG_MAX);
230     OK_REBASE_ROUNDTRIP(LONG_MAX, LONG_MIN, LONG_MAX);
231
232 #ifndef  EXPLICIT_32BIT
233     if(sizeof(long) == 8) {
234         OK_REBASE_ROUNDTRIP(0, LONG_MIN, LONG_MAX);
235
236         /* Too wide range, would not fit uint32_t */
237         OK_REBASE_ROUNDTRIP(INT32_MIN, (long)INT32_MIN - 1,
238                             (long)INT32_MAX + 1);
239         OK_REBASE_ROUNDTRIP(INT32_MAX, (long)INT32_MIN - 1,
240                             (long)INT32_MAX + 1);
241         OK_REBASE_ROUNDTRIP((long)INT32_MIN - 1, (long)INT32_MIN - 1,
242                             (long)INT32_MAX + 1);
243         OK_REBASE_ROUNDTRIP((long)INT32_MAX + 1, (long)INT32_MIN - 1,
244                             (long)INT32_MAX + 1);
245         NO_REBASE_ROUNDTRIP(LONG_MIN, (long)INT32_MIN - 1,
246                             (long)INT32_MAX + 1);
247         NO_REBASE_ROUNDTRIP(LONG_MAX, (long)INT32_MIN - 1,
248                             (long)INT32_MAX + 1);
249
250         NO_REBASE_ROUNDTRIP(((long)INT32_MIN)-1, INT32_MIN, INT32_MAX);
251         NO_REBASE_ROUNDTRIP(((long)INT32_MAX)+1, INT32_MIN, INT32_MAX);
252         NO_REBASE_ROUNDTRIP(LONG_MIN, INT32_MIN, INT32_MAX);
253         NO_REBASE_ROUNDTRIP(LONG_MAX, INT32_MIN, INT32_MAX);
254     }
255 #endif
256
257     OK_REBASE_ROUNDTRIP(-1, LONG_MIN + 1, LONG_MAX - 1);
258     OK_REBASE_ROUNDTRIP(0, LONG_MIN + 1, LONG_MAX - 1);
259     OK_REBASE_ROUNDTRIP(-1, LONG_MIN + 1, LONG_MAX - 1);
260     OK_REBASE_ROUNDTRIP(LONG_MIN + 1, LONG_MIN + 1, LONG_MAX - 1);
261     OK_REBASE_ROUNDTRIP(LONG_MAX - 1, LONG_MIN + 1, LONG_MAX - 1);
262     NO_REBASE_ROUNDTRIP(LONG_MIN, LONG_MIN + 1, LONG_MAX - 1);
263     NO_REBASE_ROUNDTRIP(LONG_MAX, LONG_MIN + 1, LONG_MAX - 1);
264
265     if(sizeof(long) == 8) {
266         NO_REBASE_ROUNDTRIP(LONG_MIN, INT32_MIN + 1, INT32_MAX - 1);
267         NO_REBASE_ROUNDTRIP(LONG_MAX, INT32_MIN + 1, INT32_MAX - 1);
268     }
269 }
270
271 int main() {
272
273     check_range_rebase();
274     check_round_trips();
275
276 }
277