a71fe40c33fc1958389823084f338997f779aa6b
[ccan] / ccan / opt / test / run-helpers.c
1 #include "config.h"
2 #include <stdio.h>
3 #include <ccan/tap/tap.h>
4 #include <setjmp.h>
5 #include <stdlib.h>
6 #include <limits.h>
7 #include "utils.h"
8
9 /* We don't actually want it to exit... */
10 static jmp_buf exited;
11 #define exit(status) longjmp(exited, (status) + 1)
12
13 #define printf saved_printf
14 static int saved_printf(const char *fmt, ...);
15
16 #define fprintf saved_fprintf
17 static int saved_fprintf(FILE *ignored, const char *fmt, ...);
18
19 #define vfprintf(f, fmt, ap) saved_vprintf(fmt, ap)
20 static int saved_vprintf(const char *fmt, va_list ap);
21
22 #define malloc(size) saved_malloc(size)
23 static void *saved_malloc(size_t size);
24
25 #include <ccan/opt/helpers.c>
26 #include <ccan/opt/opt.c>
27 #include <ccan/opt/usage.c>
28 #include <ccan/opt/parse.c>
29
30 static void reset_options(void)
31 {
32         free(opt_table);
33         opt_table = NULL;
34         opt_count = opt_num_short = opt_num_short_arg = opt_num_long = 0;
35 }
36
37 static char *output = NULL;
38
39 static int saved_vprintf(const char *fmt, va_list ap)
40 {
41         char *p;
42         int ret = vasprintf(&p, fmt, ap);
43
44         if (output) {
45                 output = realloc(output, strlen(output) + strlen(p) + 1);
46                 strcat(output, p);
47                 free(p);
48         } else
49                 output = p;
50         return ret;
51 }
52
53 static int saved_printf(const char *fmt, ...)
54 {
55         va_list ap;
56         int ret;
57
58         va_start(ap, fmt);
59         ret = saved_vprintf(fmt, ap);
60         va_end(ap);
61         return ret;
62 }       
63
64 static int saved_fprintf(FILE *ignored, const char *fmt, ...)
65 {
66         va_list ap;
67         int ret;
68
69         va_start(ap, fmt);
70         ret = saved_vprintf(fmt, ap);
71         va_end(ap);
72         return ret;
73 }       
74
75 #undef malloc
76 static void *last_allocation;
77 static void *saved_malloc(size_t size)
78 {
79         return last_allocation = malloc(size);
80 }
81
82 /* Test helpers. */
83 int main(int argc, char *argv[])
84 {
85         plan_tests(334);
86
87         /* opt_set_bool */
88         {
89                 bool arg = false;
90                 reset_options();
91                 opt_register_noarg("-a", opt_set_bool, &arg, "");
92                 ok1(parse_args(&argc, &argv, "-a", NULL));
93                 ok1(arg);
94                 opt_register_arg("-b", opt_set_bool_arg, NULL, &arg, "");
95                 ok1(parse_args(&argc, &argv, "-b", "no", NULL));
96                 ok1(!arg);
97                 ok1(parse_args(&argc, &argv, "-b", "yes", NULL));
98                 ok1(arg);
99                 ok1(parse_args(&argc, &argv, "-b", "false", NULL));
100                 ok1(!arg);
101                 ok1(parse_args(&argc, &argv, "-b", "true", NULL));
102                 ok1(arg);
103                 ok1(!parse_args(&argc, &argv, "-b", "unknown", NULL));
104                 ok1(arg);
105                 ok1(strstr(err_output, ": -b: Invalid argument 'unknown'"));
106         }
107         /* opt_set_invbool */
108         {
109                 bool arg = true;
110                 reset_options();
111                 opt_register_noarg("-a", opt_set_invbool, &arg, "");
112                 ok1(parse_args(&argc, &argv, "-a", NULL));
113                 ok1(!arg);
114                 opt_register_arg("-b", opt_set_invbool_arg, NULL,
115                                  &arg, "");
116                 ok1(parse_args(&argc, &argv, "-b", "no", NULL));
117                 ok1(arg);
118                 ok1(parse_args(&argc, &argv, "-b", "yes", NULL));
119                 ok1(!arg);
120                 ok1(parse_args(&argc, &argv, "-b", "false", NULL));
121                 ok1(arg);
122                 ok1(parse_args(&argc, &argv, "-b", "true", NULL));
123                 ok1(!arg);
124                 ok1(!parse_args(&argc, &argv, "-b", "unknown", NULL));
125                 ok1(!arg);
126                 ok1(strstr(err_output, ": -b: Invalid argument 'unknown'"));
127         }
128         /* opt_set_charp */
129         {
130                 char *arg = (char *)"wrong";
131                 reset_options();
132                 opt_register_arg("-a", opt_set_charp, NULL, &arg, "All");
133                 ok1(parse_args(&argc, &argv, "-a", "string", NULL));
134                 ok1(strcmp(arg, "string") == 0);
135         }
136         /* opt_set_intval */
137         {
138                 int arg = 1000;
139                 reset_options();
140                 opt_register_arg("-a", opt_set_intval, NULL, &arg, "All");
141                 ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
142                 ok1(arg == 9999);
143                 ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
144                 ok1(arg == -9999);
145                 ok1(parse_args(&argc, &argv, "-a", "0", NULL));
146                 ok1(arg == 0);
147                 ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
148                 if (sizeof(int) == 4)
149                         ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
150                 else
151                         fail("Handle other int sizes");
152         }
153         /* opt_set_uintval */
154         {
155                 unsigned int arg = 1000;
156                 reset_options();
157                 opt_register_arg("-a", opt_set_uintval, NULL, &arg, "All");
158                 ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
159                 ok1(arg == 9999);
160                 ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
161                 ok1(parse_args(&argc, &argv, "-a", "0", NULL));
162                 ok1(arg == 0);
163                 ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
164                 ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
165                 if (ULONG_MAX == UINT_MAX) {
166                         pass("Can't test overflow");
167                         pass("Can't test error message");
168                 } else {
169                         char buf[30];
170                         sprintf(buf, "%lu", ULONG_MAX);
171                         ok1(!parse_args(&argc, &argv, "-a", buf, NULL));
172                         ok1(strstr(err_output, ": -a: value '")
173                             && strstr(err_output, buf)
174                             && strstr(err_output, "' does not fit into an integer"));
175                 }
176         }
177         /* opt_set_longval */
178         {
179                 long int arg = 1000;
180                 reset_options();
181                 opt_register_arg("-a", opt_set_longval, NULL, &arg, "All");
182                 ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
183                 ok1(arg == 9999);
184                 ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
185                 ok1(arg == -9999);
186                 ok1(parse_args(&argc, &argv, "-a", "0", NULL));
187                 ok1(arg == 0);
188                 ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
189                 if (sizeof(long) == 4)
190                         ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
191                 else if (sizeof(long)== 8)
192                         ok1(!parse_args(&argc, &argv, "-a", "18446744073709551616", NULL));
193                 else
194                         fail("FIXME: Handle other long sizes");
195         }
196         /* opt_set_ulongval */
197         {
198                 unsigned long int arg = 1000;
199                 reset_options();
200                 opt_register_arg("-a", opt_set_ulongval, NULL, &arg, "All");
201                 ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
202                 ok1(arg == 9999);
203                 ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
204                 ok1(parse_args(&argc, &argv, "-a", "0", NULL));
205                 ok1(arg == 0);
206                 ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
207                 if (sizeof(long) == 4)
208                         ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
209                 else if (sizeof(long)== 8)
210                         ok1(!parse_args(&argc, &argv, "-a", "18446744073709551616", NULL));
211                 else
212                         fail("FIXME: Handle other long sizes");
213         }
214
215         {
216                 const long long k = 1024;
217                 const long long M = k * k;
218                 const long long G = k * k * k;
219                 const long long T = k * k * k * k;
220                 const long long P = k * k * k * k * k;
221                 const long long E = k * k * k * k * k * k;
222
223                 /* opt_set_uintval_bi */
224                 {
225                         unsigned int arg = 1000;
226                         reset_options();
227                         opt_register_arg("-a", opt_set_uintval_bi, NULL,
228                                          &arg, "All");
229                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
230                         ok1(arg == 9999);
231                         ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
232                         ok1(parse_args(&argc, &argv, "-a", "0", NULL));
233                         ok1(arg == 0);
234                         arg = 1;
235                         ok1(parse_args(&argc, &argv, "-a", "0k", NULL));
236                         ok1(arg == 0);
237                         arg = 1;
238                         ok1(parse_args(&argc, &argv, "-a", "0P", NULL));
239                         ok1(arg == 0);
240                         ok1(!parse_args(&argc, &argv, "-a", "3Q", NULL));
241                         ok1(parse_args(&argc, &argv, "-a", "30k", NULL));
242                         ok1(arg == 30 * k);
243                         ok1(!parse_args(&argc, &argv, "-a", "-1K", NULL));
244         }
245
246                 /* opt_set_intval_bi */
247                 {
248                         int arg = 1000;
249                         reset_options();
250                         opt_register_arg("-a", opt_set_intval_bi, NULL,
251                                          &arg, "All");
252                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
253                         ok1(arg == 9999);
254                         ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
255                         ok1(arg == -9999);
256                         ok1(parse_args(&argc, &argv, "-a", "0", NULL));
257                         ok1(arg == 0);
258                         arg = 1;
259                         ok1(parse_args(&argc, &argv, "-a", "0k", NULL));
260                         ok1(arg == 0);
261                         arg = 1;
262                         ok1(parse_args(&argc, &argv, "-a", "0P", NULL));
263                         ok1(arg == 0);
264                         ok1(!parse_args(&argc, &argv, "-a", "3Q", NULL));
265                         ok1(parse_args(&argc, &argv, "-a", "30k", NULL));
266                         ok1(arg == 30 * k);
267                         ok1(parse_args(&argc, &argv, "-a", "-1K", NULL));
268                         ok1(arg == -1 * k);
269                 }
270
271
272                 /* opt_set_ulongval_bi */
273                 {
274                         unsigned long int arg = 1000;
275
276                         reset_options();
277                         opt_register_arg("-a", opt_set_ulongval_bi, NULL,
278                                          &arg, "All");
279                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
280                         ok1(arg == 9999);
281                         ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
282                         ok1(parse_args(&argc, &argv, "-a", "0", NULL));
283                         ok1(arg == 0);
284                         arg = 1;
285                         ok1(parse_args(&argc, &argv, "-a", "0P", NULL));
286                         ok1(arg == 0);
287                         ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL));
288                         ok1(parse_args(&argc, &argv, "-a", "100k", NULL));
289                         ok1(arg == 100 * k);
290                         ok1(parse_args(&argc, &argv, "-a", "1K", NULL));
291                         ok1(arg == 1 * k);
292                         ok1(parse_args(&argc, &argv, "-a", "99M", NULL));
293                         ok1(arg == 99 * M);
294                         /*note, 2999M > max signed 32 bit long, 1 << 31*/
295                         ok1(parse_args(&argc, &argv, "-a", "2999m", NULL));
296                         ok1(arg == 2999 * M);
297                         ok1(parse_args(&argc, &argv, "-a", "1G", NULL));
298                         ok1(arg == 1 * G);
299                         ok1(!parse_args(&argc, &argv, "-a", "-1G", NULL));
300                         if (sizeof(long) == 4){
301                                 ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
302                                 ok1(!parse_args(&argc, &argv, "-a", "1T", NULL));
303                                 ok1(!parse_args(&argc, &argv, "-a", "1E", NULL));
304                         }
305                         else if (sizeof(long) == 8){
306                                 ok1(!parse_args(&argc, &argv, "-a",
307                                                 "18446744073709551616", NULL));
308                                 ok1(!parse_args(&argc, &argv, "-a", "8E", NULL));
309                                 ok1(parse_args(&argc, &argv, "-a", "3E", NULL));
310                         }
311                         else
312                                 fail("FIXME: Handle other long sizes");
313                 }
314
315                 /* opt_set_longval_bi */
316                 {
317                         long int arg = 1000;
318
319                         reset_options();
320                         opt_register_arg("-a", opt_set_longval_bi, NULL,
321                                          &arg, "All");
322                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
323                         ok1(arg == 9999);
324                         ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
325                         ok1(arg == -9999);
326                         ok1(parse_args(&argc, &argv, "-a", "0P", NULL));
327                         ok1(arg == 0);
328                         ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
329                         ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL));
330                         ok1(parse_args(&argc, &argv, "-a", "100k", NULL));
331                         ok1(arg == 100 * k);
332                         ok1(parse_args(&argc, &argv, "-a", "-100k", NULL));
333                         ok1(arg == -100 * k);
334                         ok1(parse_args(&argc, &argv, "-a", "1K", NULL));
335                         ok1(arg == 1 * k);
336                         ok1(parse_args(&argc, &argv, "-a", "99M", NULL));
337                         ok1(arg == 99 * M);
338                         ok1(parse_args(&argc, &argv, "-a", "1G", NULL));
339                         ok1(arg == 1 * G);
340                         ok1(parse_args(&argc, &argv, "-a", "-1G", NULL));
341                         ok1(arg == -1 * G);
342                         if (sizeof(long) == 4){
343                                 ok1(!parse_args(&argc, &argv, "-a", "2147483648", NULL));
344                                 ok1(!parse_args(&argc, &argv, "-a", "2G", NULL));
345                                 ok1(!parse_args(&argc, &argv, "-a", "2048m", NULL));
346                                 ok1(!parse_args(&argc, &argv, "-a", "1T", NULL));
347                                 ok1(!parse_args(&argc, &argv, "-a", "1E", NULL));
348                         }
349                         else if (sizeof(long) == 8){
350                                 ok1(!parse_args(&argc, &argv, "-a",
351                                                 "9223372036854775808", NULL));
352                                 ok1(parse_args(&argc, &argv, "-a", "3E", NULL));
353                                 ok1(arg == 3 * E);
354                                 ok1(parse_args(&argc, &argv, "-a", "123T", NULL));
355                                 ok1(arg == 123 * T);
356                         }
357                         else
358                                 fail("FIXME: Handle other long sizes");
359                 }
360
361
362                 /* opt_set_longlongval_bi */
363                 {
364                         long long int arg = 1000;
365                         reset_options();
366                         opt_register_arg("-a", opt_set_longlongval_bi, NULL,
367                                          &arg, "All");
368                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
369                         ok1(arg == 9999);
370                         ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
371                         ok1(arg == -9999);
372                         ok1(parse_args(&argc, &argv, "-a", "0P", NULL));
373                         ok1(arg == 0);
374                         ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
375                         ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL));
376                         ok1(!parse_args(&argc, &argv, "-a", "1kk", NULL));
377                         ok1(parse_args(&argc, &argv, "-a", "100k", NULL));
378                         ok1(arg == 100 * k);
379                         ok1(parse_args(&argc, &argv, "-a", "-100k", NULL));
380                         ok1(arg == -100 * k);
381                         ok1(parse_args(&argc, &argv, "-a", "1K", NULL));
382                         ok1(arg == 1 * k);
383                         ok1(parse_args(&argc, &argv, "-a", "-333333M", NULL));
384                         ok1(arg == -333333 * M);
385                         ok1(parse_args(&argc, &argv, "-a", "1G", NULL));
386                         ok1(arg == 1 * G);
387                         ok1(parse_args(&argc, &argv, "-a", "1024t", NULL));
388                         ok1(arg == 1024 * T);
389                         ok1(parse_args(&argc, &argv, "-a", "123P", NULL));
390                         ok1(arg == 123 * P);
391                         ok1(parse_args(&argc, &argv, "-a", "-3E", NULL));
392                         ok1(arg == -3 * E);
393
394                         if (sizeof(long long) == 8){
395                                 ok1(!parse_args(&argc, &argv, "-a",
396                                                 "9223372036854775808", NULL));
397                                 /*8E and 922337.. are both 1 << 63*/
398                                 ok1(!parse_args(&argc, &argv, "-a", "8E", NULL));
399                         }
400                         else
401                                 fail("FIXME: Handle other long long int"
402                                      " sizes (specifically %lu bytes)",
403                                      sizeof(long long));
404                 }
405                 /* opt_set_ulonglongval_bi */
406                 {
407                         unsigned long long int arg = 1000;
408                         reset_options();
409                         opt_register_arg("-a", opt_set_ulonglongval_bi, NULL,
410                                          &arg, "All");
411                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
412                         ok1(arg == 9999);
413                         ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
414                         ok1(parse_args(&argc, &argv, "-a", "0", NULL));
415                         ok1(arg == 0);
416                         ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL));
417                         ok1(!parse_args(&argc, &argv, "-a", "1kk", NULL));
418                         ok1(parse_args(&argc, &argv, "-a", "100G", NULL));
419                         ok1(arg == 100 * G);
420                         ok1(!parse_args(&argc, &argv, "-a", "-100G", NULL));
421                         ok1(parse_args(&argc, &argv, "-a", "8191P", NULL));
422                         ok1(arg == 8191 * P);
423                 }
424         }
425
426         {
427                 const long long k = 1000;
428                 const long long M = k * k;
429                 const long long G = k * k * k;
430                 const long long T = k * k * k * k;
431                 const long long P = k * k * k * k * k;
432                 const long long E = k * k * k * k * k * k;
433
434                 /* opt_set_uintval_si */
435                 {
436                         unsigned int arg = 1000;
437                         reset_options();
438                         opt_register_arg("-a", opt_set_uintval_si, NULL,
439                                          &arg, "All");
440                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
441                         ok1(arg == 9999);
442                         ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
443                         ok1(parse_args(&argc, &argv, "-a", "0", NULL));
444                         ok1(arg == 0);
445                         arg = 1;
446                         ok1(parse_args(&argc, &argv, "-a", "0k", NULL));
447                         ok1(arg == 0);
448                         arg = 1;
449                         ok1(parse_args(&argc, &argv, "-a", "0P", NULL));
450                         ok1(arg == 0);
451                         ok1(!parse_args(&argc, &argv, "-a", "3Q", NULL));
452                         ok1(parse_args(&argc, &argv, "-a", "30k", NULL));
453                         ok1(arg == 30 * k);
454                         ok1(!parse_args(&argc, &argv, "-a", "-1K", NULL));
455                         if (sizeof(unsigned int) < 8)
456                                 ok1(!parse_args(&argc, &argv, "-a", "1E", NULL));
457                         else
458                                 pass("can't test int truncation when int is so huge");
459         }
460
461                 /* opt_set_intval_si */
462                 {
463                         int arg = 1000;
464                         reset_options();
465                         opt_register_arg("-a", opt_set_intval_si, NULL,
466                                          &arg, "All");
467                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
468                         ok1(arg == 9999);
469                         ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
470                         ok1(arg == -9999);
471                         ok1(parse_args(&argc, &argv, "-a", "0", NULL));
472                         ok1(arg == 0);
473                         arg = 1;
474                         ok1(parse_args(&argc, &argv, "-a", "0k", NULL));
475                         ok1(arg == 0);
476                         arg = 1;
477                         ok1(parse_args(&argc, &argv, "-a", "0P", NULL));
478                         ok1(arg == 0);
479                         ok1(!parse_args(&argc, &argv, "-a", "", NULL));
480                         ok1(!parse_args(&argc, &argv, "-a", "3Q", NULL));
481                         ok1(parse_args(&argc, &argv, "-a", "30k", NULL));
482                         ok1(arg == 30 * k);
483                         ok1(parse_args(&argc, &argv, "-a", "-1K", NULL));
484                         ok1(arg == -1 * k);
485                         if (sizeof(int) < 8)
486                                 ok1(!parse_args(&argc, &argv, "-a", "1E", NULL));
487                         else
488                                 pass("can't test int truncation when int is so huge");
489                 }
490
491
492                 /* opt_set_ulongval_si */
493                 {
494                         unsigned long long int arg = 1000;
495
496                         reset_options();
497                         opt_register_arg("-a", opt_set_ulongval_si, NULL,
498                                          &arg, "All");
499                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
500                         ok1(arg == 9999);
501                         ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
502                         ok1(parse_args(&argc, &argv, "-a", "0P", NULL));
503                         ok1(arg == 0);
504                         ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
505                         ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL));
506                         ok1(parse_args(&argc, &argv, "-a", "100k", NULL));
507                         ok1(arg == 100 * k);
508                         ok1(parse_args(&argc, &argv, "-a", "1K", NULL));
509                         ok1(arg == 1 * k);
510                         ok1(parse_args(&argc, &argv, "-a", "99M", NULL));
511                         ok1(arg == 99 * M);
512                         /*note, 2999M > max signed 32 bit long, 1 << 31*/
513                         ok1(parse_args(&argc, &argv, "-a", "2999m", NULL));
514                         ok1(arg == 2999 * M);
515                         ok1(parse_args(&argc, &argv, "-a", "1G", NULL));
516                         ok1(arg == 1 * G);
517                         ok1(!parse_args(&argc, &argv, "-a", "-1G", NULL));
518                         ok1(parse_args(&argc, &argv, "-a", "4G", NULL));
519                         ok1(arg == 4000000000);
520                         if (sizeof(long) == 4){
521                                 ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
522                                 ok1(!parse_args(&argc, &argv, "-a", "4295M", NULL));
523                                 ok1(!parse_args(&argc, &argv, "-a", "1T", NULL));
524                                 ok1(!parse_args(&argc, &argv, "-a", "1E", NULL));
525                         }
526                         else if (sizeof(long)== 8){
527                                 ok1(!parse_args(&argc, &argv, "-a",
528                                                 "18446744073709551616", NULL));
529                                 ok1(parse_args(&argc, &argv, "-a", "9E", NULL));
530                                 ok1(arg == 9000000000000000000ULL);
531                                 ok1(!parse_args(&argc, &argv, "-a", "19E", NULL));
532                         }
533                         else
534                                 fail("FIXME: Handle other long sizes");
535                 }
536
537                 /* opt_set_longval_si */
538                 {
539                         long int arg = 1000;
540
541                         reset_options();
542                         opt_register_arg("-a", opt_set_longval_si, NULL,
543                                          &arg, "All");
544                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
545                         ok1(arg == 9999);
546                         ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
547                         ok1(arg == -9999);
548                         ok1(parse_args(&argc, &argv, "-a", "0P", NULL));
549                         ok1(arg == 0);
550                         ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
551                         ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL));
552                         ok1(parse_args(&argc, &argv, "-a", "100k", NULL));
553                         ok1(arg == 100 * k);
554                         ok1(parse_args(&argc, &argv, "-a", "-100k", NULL));
555                         ok1(arg == -100 * k);
556                         ok1(parse_args(&argc, &argv, "-a", "1K", NULL));
557                         ok1(arg == 1 * k);
558                         ok1(parse_args(&argc, &argv, "-a", "99M", NULL));
559                         ok1(arg == 99 * M);
560                         ok1(parse_args(&argc, &argv, "-a", "1G", NULL));
561                         ok1(arg == 1 * G);
562                         ok1(parse_args(&argc, &argv, "-a", "-1G", NULL));
563                         ok1(arg == -1 * G);
564                         if (sizeof(long) == 4){
565                                 ok1(!parse_args(&argc, &argv, "-a", "2147483648", NULL));
566                                 ok1(!parse_args(&argc, &argv, "-a", "4G", NULL));
567                                 ok1(!parse_args(&argc, &argv, "-a", "1T", NULL));
568                                 ok1(!parse_args(&argc, &argv, "-a", "1E", NULL));
569                                 ok1(parse_args(&argc, &argv, "-a", "1999m", NULL));
570                                 ok1(arg == 1999 * M);
571                         }
572                         else if (sizeof(long)== 8){
573                                 ok1(!parse_args(&argc, &argv, "-a",
574                                                 "9223372036854775808", NULL));
575                                 ok1(!parse_args(&argc, &argv, "-a", "9224P", NULL));
576                                 ok1(parse_args(&argc, &argv, "-a", "9E", NULL));
577                                 ok1(arg == 9 * E);
578                                 ok1(parse_args(&argc, &argv, "-a", "123T", NULL));
579                                 ok1(arg == 123 * T);
580                         }
581                         else
582                                 fail("FIXME: Handle other long sizes");
583                 }
584
585
586                 /* opt_set_longlongval_si */
587                 {
588                         long long int arg = 1000;
589                         reset_options();
590                         opt_register_arg("-a", opt_set_longlongval_si, NULL,
591                                          &arg, "All");
592                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
593                         ok1(arg == 9999);
594                         ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
595                         ok1(arg == -9999);
596                         ok1(parse_args(&argc, &argv, "-a", "0T", NULL));
597                         ok1(arg == 0);
598                         ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
599                         ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL));
600                         ok1(!parse_args(&argc, &argv, "-a", "1kk", NULL));
601                         ok1(parse_args(&argc, &argv, "-a", "100k", NULL));
602                         ok1(arg == 100 * k);
603                         ok1(parse_args(&argc, &argv, "-a", "-100k", NULL));
604                         ok1(arg == -100 * k);
605                         ok1(parse_args(&argc, &argv, "-a", "1K", NULL));
606                         ok1(arg == 1 * k);
607                         ok1(parse_args(&argc, &argv, "-a", "-333333M", NULL));
608                         ok1(arg == -333333 * M);
609                         ok1(parse_args(&argc, &argv, "-a", "1G", NULL));
610                         ok1(arg == 1 * G);
611                         ok1(parse_args(&argc, &argv, "-a", "1024t", NULL));
612                         ok1(arg == 1024 * T);
613                         ok1(parse_args(&argc, &argv, "-a", "123P", NULL));
614                         ok1(arg == 123 * P);
615                         ok1(parse_args(&argc, &argv, "-a", "-3E", NULL));
616                         ok1(arg == -3 * E);
617                         ok1(parse_args(&argc, &argv, "-a", "8E", NULL));
618                         if (sizeof(long long) == 8){
619                                 ok1(!parse_args(&argc, &argv, "-a",
620                                                 "9223372036854775808", NULL));
621                                 ok1(!parse_args(&argc, &argv, "-a",
622                                                 "10E", NULL));
623                         }
624                         else
625                                 fail("FIXME: Handle other long long int"
626                                      " sizes (specifically %lu bytes)",
627                                      sizeof(long long));
628
629                 }
630                 /* opt_set_ulonglongval_si */
631                 {
632                         unsigned long long int arg = 1000;
633                         reset_options();
634                         opt_register_arg("-a", opt_set_ulonglongval_si, NULL,
635                                          &arg, "All");
636                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
637                         ok1(arg == 9999);
638                         ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
639                         ok1(parse_args(&argc, &argv, "-a", "0", NULL));
640                         ok1(arg == 0);
641                         ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL));
642                         ok1(!parse_args(&argc, &argv, "-a", "1kk", NULL));
643                         ok1(parse_args(&argc, &argv, "-a", "100G", NULL));
644                         ok1(arg == 100 * G);
645                         ok1(!parse_args(&argc, &argv, "-a", "-100G", NULL));
646                         ok1(parse_args(&argc, &argv, "-a", "8E", NULL));
647                 }
648         }
649
650
651         /* opt_inc_intval */
652         {
653                 int arg = 1000;
654                 reset_options();
655                 opt_register_noarg("-a", opt_inc_intval, &arg, "");
656                 ok1(parse_args(&argc, &argv, "-a", NULL));
657                 ok1(arg == 1001);
658                 ok1(parse_args(&argc, &argv, "-a", "-a", NULL));
659                 ok1(arg == 1003);
660                 ok1(parse_args(&argc, &argv, "-aa", NULL));
661                 ok1(arg == 1005);
662         }
663
664         /* opt_show_version_and_exit. */
665         {
666                 int exitval;
667                 reset_options();
668                 opt_register_noarg("-a",
669                                    opt_version_and_exit, "1.2.3", "");
670                 /* parse_args allocates argv */
671                 free(argv);
672
673                 argc = 2;
674                 argv = malloc(sizeof(argv[0]) * 3);
675                 argv[0] = "thisprog";
676                 argv[1] = "-a";
677                 argv[2] = NULL;
678
679                 exitval = setjmp(exited);
680                 if (exitval == 0) {
681                         opt_parse(&argc, argv, save_err_output);
682                         fail("opt_show_version_and_exit returned?");
683                 } else {
684                         ok1(exitval - 1 == 0);
685                 }
686                 ok1(strcmp(output, "1.2.3\n") == 0);
687                 free(output);
688                 free(argv);
689                 output = NULL;
690         }
691
692         /* opt_usage_and_exit. */
693         {
694                 int exitval;
695                 reset_options();
696                 opt_register_noarg("-a",
697                                    opt_usage_and_exit, "[args]", "");
698
699                 argc = 2;
700                 argv = malloc(sizeof(argv[0]) * 3);
701                 argv[0] = "thisprog";
702                 argv[1] = "-a";
703                 argv[2] = NULL;
704
705                 exitval = setjmp(exited);
706                 if (exitval == 0) {
707                         opt_parse(&argc, argv, save_err_output);
708                         fail("opt_usage_and_exit returned?");
709                 } else {
710                         ok1(exitval - 1 == 0);
711                 }
712                 ok1(strstr(output, "[args]"));
713                 ok1(strstr(output, argv[0]));
714                 ok1(strstr(output, "[-a]"));
715                 free(output);
716                 free(argv);
717                 /* It exits without freeing usage string. */
718                 free(last_allocation);
719                 output = NULL;
720         }
721
722         /* opt_show_bool */
723         {
724                 bool b;
725                 char buf[OPT_SHOW_LEN+2] = { 0 };
726                 buf[OPT_SHOW_LEN] = '!';
727
728                 b = true;
729                 opt_show_bool(buf, &b);
730                 ok1(strcmp(buf, "true") == 0);
731                 ok1(buf[OPT_SHOW_LEN] == '!');
732
733                 b = false;
734                 opt_show_bool(buf, &b);
735                 ok1(strcmp(buf, "false") == 0);
736                 ok1(buf[OPT_SHOW_LEN] == '!');
737         }
738
739         /* opt_show_invbool */
740         {
741                 bool b;
742                 char buf[OPT_SHOW_LEN+2] = { 0 };
743                 buf[OPT_SHOW_LEN] = '!';
744
745                 b = true;
746                 opt_show_invbool(buf, &b);
747                 ok1(strcmp(buf, "false") == 0);
748                 ok1(buf[OPT_SHOW_LEN] == '!');
749
750                 b = false;
751                 opt_show_invbool(buf, &b);
752                 ok1(strcmp(buf, "true") == 0);
753                 ok1(buf[OPT_SHOW_LEN] == '!');
754         }
755
756         /* opt_show_charp */
757         {
758                 char str[OPT_SHOW_LEN*2], *p;
759                 char buf[OPT_SHOW_LEN+2] = { 0 };
760                 buf[OPT_SHOW_LEN] = '!';
761
762                 /* Short test. */
763                 p = str;
764                 strcpy(p, "short");
765                 opt_show_charp(buf, &p);
766                 ok1(strcmp(buf, "\"short\"") == 0);
767                 ok1(buf[OPT_SHOW_LEN] == '!');
768
769                 /* Truncate test. */
770                 memset(p, 'x', OPT_SHOW_LEN*2);
771                 p[OPT_SHOW_LEN*2-1] = '\0';
772                 opt_show_charp(buf, &p);
773                 ok1(buf[0] == '"');
774                 ok1(buf[OPT_SHOW_LEN-1] == '"');
775                 ok1(buf[OPT_SHOW_LEN] == '!');
776                 ok1(strspn(buf+1, "x") == OPT_SHOW_LEN-2);
777         }
778
779         /* opt_show_intval */
780         {
781                 int i;
782                 char buf[OPT_SHOW_LEN+2] = { 0 };
783                 buf[OPT_SHOW_LEN] = '!';
784
785                 i = -77;
786                 opt_show_intval(buf, &i);
787                 ok1(strcmp(buf, "-77") == 0);
788                 ok1(buf[OPT_SHOW_LEN] == '!');
789
790                 i = 77;
791                 opt_show_intval(buf, &i);
792                 ok1(strcmp(buf, "77") == 0);
793                 ok1(buf[OPT_SHOW_LEN] == '!');
794         }
795
796         /* opt_show_uintval */
797         {
798                 unsigned int ui;
799                 char buf[OPT_SHOW_LEN+2] = { 0 };
800                 buf[OPT_SHOW_LEN] = '!';
801
802                 ui = 4294967295U;
803                 opt_show_uintval(buf, &ui);
804                 ok1(strcmp(buf, "4294967295") == 0);
805                 ok1(buf[OPT_SHOW_LEN] == '!');
806         }
807
808         /* opt_show_longval */
809         {
810                 long l;
811                 char buf[OPT_SHOW_LEN+2] = { 0 };
812                 buf[OPT_SHOW_LEN] = '!';
813
814                 l = 1234567890L;
815                 opt_show_longval(buf, &l);
816                 ok1(strcmp(buf, "1234567890") == 0);
817                 ok1(buf[OPT_SHOW_LEN] == '!');
818         }
819
820         /* opt_show_ulongval */
821         {
822                 unsigned long ul;
823                 char buf[OPT_SHOW_LEN+2] = { 0 };
824                 buf[OPT_SHOW_LEN] = '!';
825
826                 ul = 4294967295UL;
827                 opt_show_ulongval(buf, &ul);
828                 ok1(strcmp(buf, "4294967295") == 0);
829                 ok1(buf[OPT_SHOW_LEN] == '!');
830         }
831
832         /* opt_log_stderr. */
833         {
834                 reset_options();
835                 opt_register_noarg("-a",
836                                    opt_usage_and_exit, "[args]", "");
837
838                 argc = 2;
839                 argv = malloc(sizeof(argv[0]) * 3);
840                 argv[0] = "thisprog";
841                 argv[1] = "--garbage";
842                 argv[2] = NULL;
843                 ok1(!opt_parse(&argc, argv, opt_log_stderr));
844                 ok1(!strcmp(output,
845                             "thisprog: --garbage: unrecognized option\n"));
846                 free(output);
847                 free(argv);
848                 output = NULL;
849         }
850
851         /* opt_log_stderr_exit. */
852         {
853                 int exitval;
854                 reset_options();
855                 opt_register_noarg("-a",
856                                    opt_usage_and_exit, "[args]", "");
857                 argc = 2;
858                 argv = malloc(sizeof(argv[0]) * 3);
859                 argv[0] = "thisprog";
860                 argv[1] = "--garbage";
861                 argv[2] = NULL;
862                 exitval = setjmp(exited);
863                 if (exitval == 0) {
864                         opt_parse(&argc, argv, opt_log_stderr_exit);
865                         fail("opt_log_stderr_exit returned?");
866                 } else {
867                         ok1(exitval - 1 == 1);
868                 }
869                 free(argv);
870                 ok1(!strcmp(output,
871                             "thisprog: --garbage: unrecognized option\n"));
872                 free(output);
873                 output = NULL;
874         }
875
876         //diag("%s\n", err_output);
877         return exit_status();
878 }