opt: complete coverage, enhance opt_free_table.
[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 char *output = NULL;
31
32 static int saved_vprintf(const char *fmt, va_list ap)
33 {
34         char *p;
35         int ret = vasprintf(&p, fmt, ap);
36
37         if (output) {
38                 output = realloc(output, strlen(output) + strlen(p) + 1);
39                 strcat(output, p);
40                 free(p);
41         } else
42                 output = p;
43         return ret;
44 }
45
46 static int saved_printf(const char *fmt, ...)
47 {
48         va_list ap;
49         int ret;
50
51         va_start(ap, fmt);
52         ret = saved_vprintf(fmt, ap);
53         va_end(ap);
54         return ret;
55 }
56
57 static int saved_fprintf(FILE *ignored, const char *fmt, ...)
58 {
59         va_list ap;
60         int ret;
61
62         va_start(ap, fmt);
63         ret = saved_vprintf(fmt, ap);
64         va_end(ap);
65         return ret;
66 }
67
68 #undef malloc
69 static void *last_allocation;
70 static void *saved_malloc(size_t size)
71 {
72         return last_allocation = malloc(size);
73 }
74
75 /* Test helpers. */
76 int main(int argc, char *argv[])
77 {
78         plan_tests(452);
79
80         /* opt_set_bool */
81         {
82                 bool arg = false;
83                 reset_options();
84                 opt_register_noarg("-a", opt_set_bool, &arg, "");
85                 ok1(parse_args(&argc, &argv, "-a", NULL));
86                 ok1(arg);
87                 opt_register_arg("-b", opt_set_bool_arg, NULL, &arg, "");
88                 ok1(parse_args(&argc, &argv, "-b", "no", NULL));
89                 ok1(!arg);
90                 ok1(parse_args(&argc, &argv, "-b", "yes", NULL));
91                 ok1(arg);
92                 ok1(parse_args(&argc, &argv, "-b", "false", NULL));
93                 ok1(!arg);
94                 ok1(parse_args(&argc, &argv, "-b", "true", NULL));
95                 ok1(arg);
96                 ok1(!parse_args(&argc, &argv, "-b", "unknown", NULL));
97                 ok1(arg);
98                 ok1(strstr(err_output, ": -b: Invalid argument 'unknown'"));
99         }
100         /* opt_set_invbool */
101         {
102                 bool arg = true;
103                 reset_options();
104                 opt_register_noarg("-a", opt_set_invbool, &arg, "");
105                 ok1(parse_args(&argc, &argv, "-a", NULL));
106                 ok1(!arg);
107                 opt_register_arg("-b", opt_set_invbool_arg, NULL,
108                                  &arg, "");
109                 ok1(parse_args(&argc, &argv, "-b", "no", NULL));
110                 ok1(arg);
111                 ok1(parse_args(&argc, &argv, "-b", "yes", NULL));
112                 ok1(!arg);
113                 ok1(parse_args(&argc, &argv, "-b", "false", NULL));
114                 ok1(arg);
115                 ok1(parse_args(&argc, &argv, "-b", "true", NULL));
116                 ok1(!arg);
117                 ok1(!parse_args(&argc, &argv, "-b", "unknown", NULL));
118                 ok1(!arg);
119                 ok1(strstr(err_output, ": -b: Invalid argument 'unknown'"));
120         }
121         /* opt_set_charp */
122         {
123                 char *arg = (char *)"wrong";
124                 reset_options();
125                 opt_register_arg("-a", opt_set_charp, NULL, &arg, "All");
126                 ok1(parse_args(&argc, &argv, "-a", "string", NULL));
127                 ok1(strcmp(arg, "string") == 0);
128         }
129         /* opt_set_intval */
130         {
131                 int arg = 1000;
132                 reset_options();
133                 opt_register_arg("-a", opt_set_intval, NULL, &arg, "All");
134                 ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
135                 ok1(arg == 9999);
136                 ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
137                 ok1(arg == -9999);
138                 ok1(parse_args(&argc, &argv, "-a", "0", NULL));
139                 ok1(arg == 0);
140                 ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
141                 if (sizeof(int) == 4)
142                         ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
143                 else
144                         fail("Handle other int sizes");
145         }
146         /* opt_set_uintval */
147         {
148                 unsigned int arg = 1000;
149                 reset_options();
150                 opt_register_arg("-a", opt_set_uintval, NULL, &arg, "All");
151                 ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
152                 ok1(arg == 9999);
153                 ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
154                 ok1(parse_args(&argc, &argv, "-a", "0", NULL));
155                 ok1(arg == 0);
156                 ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
157                 ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
158                 if (ULONG_MAX == UINT_MAX) {
159                         pass("Can't test overflow");
160                         pass("Can't test error message");
161                 } else {
162                         char buf[30];
163                         sprintf(buf, "%lu", ULONG_MAX);
164                         ok1(!parse_args(&argc, &argv, "-a", buf, NULL));
165                         ok1(strstr(err_output, ": -a: value '")
166                             && strstr(err_output, buf)
167                             && strstr(err_output, "' does not fit into an integer"));
168                 }
169         }
170         /* opt_set_longval */
171         {
172                 long int arg = 1000;
173                 reset_options();
174                 opt_register_arg("-a", opt_set_longval, NULL, &arg, "All");
175                 ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
176                 ok1(arg == 9999);
177                 ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
178                 ok1(arg == -9999);
179                 ok1(parse_args(&argc, &argv, "-a", "0", NULL));
180                 ok1(arg == 0);
181                 ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
182                 if (sizeof(long) == 4)
183                         ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
184                 else if (sizeof(long)== 8)
185                         ok1(!parse_args(&argc, &argv, "-a", "18446744073709551616", NULL));
186                 else
187                         fail("FIXME: Handle other long sizes");
188         }
189         /* opt_set_ulongval */
190         {
191                 unsigned long int arg = 1000;
192                 reset_options();
193                 opt_register_arg("-a", opt_set_ulongval, NULL, &arg, "All");
194                 ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
195                 ok1(arg == 9999);
196                 ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
197                 ok1(parse_args(&argc, &argv, "-a", "0", NULL));
198                 ok1(arg == 0);
199                 ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
200                 if (sizeof(long) == 4)
201                         ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
202                 else if (sizeof(long)== 8)
203                         ok1(!parse_args(&argc, &argv, "-a", "18446744073709551616", NULL));
204                 else
205                         fail("FIXME: Handle other long sizes");
206         }
207
208         {
209                 const long long k = 1024;
210                 const long long M = k * k;
211                 const long long G = k * k * k;
212                 const long long T = k * k * k * k;
213                 const long long P = k * k * k * k * k;
214                 const long long E = k * k * k * k * k * k;
215
216                 /* opt_set_uintval_bi */
217                 {
218                         unsigned int arg = 1000;
219                         reset_options();
220                         opt_register_arg("-a", opt_set_uintval_bi, NULL,
221                                          &arg, "All");
222                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
223                         ok1(arg == 9999);
224                         ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
225                         ok1(parse_args(&argc, &argv, "-a", "0", NULL));
226                         ok1(arg == 0);
227                         arg = 1;
228                         ok1(parse_args(&argc, &argv, "-a", "0k", NULL));
229                         ok1(arg == 0);
230                         arg = 1;
231                         ok1(parse_args(&argc, &argv, "-a", "0P", NULL));
232                         ok1(arg == 0);
233                         ok1(!parse_args(&argc, &argv, "-a", "3Q", NULL));
234                         ok1(parse_args(&argc, &argv, "-a", "30k", NULL));
235                         ok1(arg == 30 * k);
236                         ok1(!parse_args(&argc, &argv, "-a", "-1K", NULL));
237         }
238
239                 /* opt_set_intval_bi */
240                 {
241                         int arg = 1000;
242                         reset_options();
243                         opt_register_arg("-a", opt_set_intval_bi, NULL,
244                                          &arg, "All");
245                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
246                         ok1(arg == 9999);
247                         ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
248                         ok1(arg == -9999);
249                         ok1(parse_args(&argc, &argv, "-a", "0", NULL));
250                         ok1(arg == 0);
251                         arg = 1;
252                         ok1(parse_args(&argc, &argv, "-a", "0k", NULL));
253                         ok1(arg == 0);
254                         arg = 1;
255                         ok1(parse_args(&argc, &argv, "-a", "0P", NULL));
256                         ok1(arg == 0);
257                         ok1(!parse_args(&argc, &argv, "-a", "3Q", NULL));
258                         ok1(parse_args(&argc, &argv, "-a", "30k", NULL));
259                         ok1(arg == 30 * k);
260                         ok1(parse_args(&argc, &argv, "-a", "-1K", NULL));
261                         ok1(arg == -1 * k);
262                 }
263
264
265                 /* opt_set_ulongval_bi */
266                 {
267                         unsigned long int arg = 1000;
268
269                         reset_options();
270                         opt_register_arg("-a", opt_set_ulongval_bi, NULL,
271                                          &arg, "All");
272                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
273                         ok1(arg == 9999);
274                         ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
275                         ok1(parse_args(&argc, &argv, "-a", "0", NULL));
276                         ok1(arg == 0);
277                         arg = 1;
278                         ok1(parse_args(&argc, &argv, "-a", "0P", NULL));
279                         ok1(arg == 0);
280                         ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL));
281                         ok1(parse_args(&argc, &argv, "-a", "100k", NULL));
282                         ok1(arg == 100 * k);
283                         ok1(parse_args(&argc, &argv, "-a", "1K", NULL));
284                         ok1(arg == 1 * k);
285                         ok1(parse_args(&argc, &argv, "-a", "99M", NULL));
286                         ok1(arg == 99 * M);
287                         /*note, 2999M > max signed 32 bit long, 1 << 31*/
288                         ok1(parse_args(&argc, &argv, "-a", "2999m", NULL));
289                         ok1(arg == 2999 * M);
290                         ok1(parse_args(&argc, &argv, "-a", "1G", NULL));
291                         ok1(arg == 1 * G);
292                         ok1(!parse_args(&argc, &argv, "-a", "-1G", NULL));
293                         if (sizeof(long) == 4){
294                                 ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
295                                 ok1(!parse_args(&argc, &argv, "-a", "1T", NULL));
296                                 ok1(!parse_args(&argc, &argv, "-a", "1E", NULL));
297                         }
298                         else if (sizeof(long) == 8){
299                                 ok1(!parse_args(&argc, &argv, "-a",
300                                                 "18446744073709551616", NULL));
301                                 ok1(!parse_args(&argc, &argv, "-a", "8E", NULL));
302                                 ok1(parse_args(&argc, &argv, "-a", "3E", NULL));
303                         }
304                         else
305                                 fail("FIXME: Handle other long sizes");
306                 }
307
308                 /* opt_set_longval_bi */
309                 {
310                         long int arg = 1000;
311
312                         reset_options();
313                         opt_register_arg("-a", opt_set_longval_bi, NULL,
314                                          &arg, "All");
315                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
316                         ok1(arg == 9999);
317                         ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
318                         ok1(arg == -9999);
319                         ok1(parse_args(&argc, &argv, "-a", "0P", NULL));
320                         ok1(arg == 0);
321                         ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
322                         ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL));
323                         ok1(parse_args(&argc, &argv, "-a", "100k", NULL));
324                         ok1(arg == 100 * k);
325                         ok1(parse_args(&argc, &argv, "-a", "-100k", NULL));
326                         ok1(arg == -100 * k);
327                         ok1(parse_args(&argc, &argv, "-a", "1K", NULL));
328                         ok1(arg == 1 * k);
329                         ok1(parse_args(&argc, &argv, "-a", "99M", NULL));
330                         ok1(arg == 99 * M);
331                         ok1(parse_args(&argc, &argv, "-a", "1G", NULL));
332                         ok1(arg == 1 * G);
333                         ok1(parse_args(&argc, &argv, "-a", "-1G", NULL));
334                         ok1(arg == -1 * G);
335                         if (sizeof(long) == 4){
336                                 ok1(!parse_args(&argc, &argv, "-a", "2147483648", NULL));
337                                 ok1(!parse_args(&argc, &argv, "-a", "2G", NULL));
338                                 ok1(!parse_args(&argc, &argv, "-a", "2048m", NULL));
339                                 ok1(!parse_args(&argc, &argv, "-a", "1T", NULL));
340                                 ok1(!parse_args(&argc, &argv, "-a", "1E", NULL));
341                         }
342                         else if (sizeof(long) == 8){
343                                 ok1(!parse_args(&argc, &argv, "-a",
344                                                 "9223372036854775808", NULL));
345                                 ok1(parse_args(&argc, &argv, "-a", "3E", NULL));
346                                 ok1(arg == 3 * E);
347                                 ok1(parse_args(&argc, &argv, "-a", "123T", NULL));
348                                 ok1(arg == 123 * T);
349                         }
350                         else
351                                 fail("FIXME: Handle other long sizes");
352                 }
353
354
355                 /* opt_set_longlongval_bi */
356                 {
357                         long long int arg = 1000;
358                         reset_options();
359                         opt_register_arg("-a", opt_set_longlongval_bi, NULL,
360                                          &arg, "All");
361                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
362                         ok1(arg == 9999);
363                         ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
364                         ok1(arg == -9999);
365                         ok1(parse_args(&argc, &argv, "-a", "0P", NULL));
366                         ok1(arg == 0);
367                         ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
368                         ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL));
369                         ok1(!parse_args(&argc, &argv, "-a", "1kk", NULL));
370                         ok1(parse_args(&argc, &argv, "-a", "100k", NULL));
371                         ok1(arg == 100 * k);
372                         ok1(parse_args(&argc, &argv, "-a", "-100k", NULL));
373                         ok1(arg == -100 * k);
374                         ok1(parse_args(&argc, &argv, "-a", "1K", NULL));
375                         ok1(arg == 1 * k);
376                         ok1(parse_args(&argc, &argv, "-a", "-333333M", NULL));
377                         ok1(arg == -333333 * M);
378                         ok1(parse_args(&argc, &argv, "-a", "1G", NULL));
379                         ok1(arg == 1 * G);
380                         ok1(parse_args(&argc, &argv, "-a", "1024t", NULL));
381                         ok1(arg == 1024 * T);
382                         ok1(parse_args(&argc, &argv, "-a", "123P", NULL));
383                         ok1(arg == 123 * P);
384                         ok1(parse_args(&argc, &argv, "-a", "-3E", NULL));
385                         ok1(arg == -3 * E);
386
387                         if (sizeof(long long) == 8){
388                                 ok1(!parse_args(&argc, &argv, "-a",
389                                                 "9223372036854775808", NULL));
390                                 /*8E and 922337.. are both 1 << 63*/
391                                 ok1(!parse_args(&argc, &argv, "-a", "8E", NULL));
392                         }
393                         else
394                                 fail("FIXME: Handle other long long int"
395                                      " sizes (specifically %zu bytes)",
396                                      sizeof(long long));
397                 }
398                 /* opt_set_ulonglongval_bi */
399                 {
400                         unsigned long long int arg = 1000;
401                         reset_options();
402                         opt_register_arg("-a", opt_set_ulonglongval_bi, NULL,
403                                          &arg, "All");
404                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
405                         ok1(arg == 9999);
406                         ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
407                         ok1(parse_args(&argc, &argv, "-a", "0", NULL));
408                         ok1(arg == 0);
409                         ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL));
410                         ok1(!parse_args(&argc, &argv, "-a", "1kk", NULL));
411                         ok1(parse_args(&argc, &argv, "-a", "100G", NULL));
412                         ok1(arg == 100 * G);
413                         ok1(!parse_args(&argc, &argv, "-a", "-100G", NULL));
414                         ok1(parse_args(&argc, &argv, "-a", "8191P", NULL));
415                         ok1(arg == 8191 * P);
416                 }
417
418                 /* opt_show_intval_bi */
419                 {
420                         int i;
421                         char buf[OPT_SHOW_LEN+2] = { 0 };
422                         buf[OPT_SHOW_LEN] = '!';
423                         i = -77;
424                         opt_show_intval_bi(buf, &i);
425                         ok1(strcmp(buf, "-77") == 0);
426                         i = 0;
427                         opt_show_intval_bi(buf, &i);
428                         ok1(strcmp(buf, "0") == 0);
429                         ok1(buf[OPT_SHOW_LEN] == '!');
430                         i = 77;
431                         opt_show_intval_bi(buf, &i);
432                         ok1(strcmp(buf, "77") == 0);
433                         ok1(buf[OPT_SHOW_LEN] == '!');
434                         i = -1234 * k;
435                         opt_show_intval_bi(buf, &i);
436                         ok1(strcmp(buf, "-1234k") == 0);
437                         ok1(buf[OPT_SHOW_LEN] == '!');
438                         i = 500 * M;
439                         opt_show_intval_bi(buf, &i);
440                         ok1(strcmp(buf, "500M") == 0);
441                         ok1(buf[OPT_SHOW_LEN] == '!');
442                         i = 1024 * M;
443                         opt_show_intval_bi(buf, &i);
444                         ok1(strcmp(buf, "1G") == 0);
445                         ok1(buf[OPT_SHOW_LEN] == '!');
446                 }
447
448                 /* opt_show_longval_bi */
449                 {
450                         long i;
451                         char buf[OPT_SHOW_LEN+2] = { 0 };
452                         buf[OPT_SHOW_LEN] = '!';
453                         i = -77;
454                         opt_show_longval_bi(buf, &i);
455                         ok1(strcmp(buf, "-77") == 0);
456                         ok1(buf[OPT_SHOW_LEN] == '!');
457                         i = 77;
458                         opt_show_longval_bi(buf, &i);
459                         ok1(strcmp(buf, "77") == 0);
460                         ok1(buf[OPT_SHOW_LEN] == '!');
461                         i = -1 * k;
462                         opt_show_longval_bi(buf, &i);
463                         ok1(strcmp(buf, "-1k") == 0);
464                         ok1(buf[OPT_SHOW_LEN] == '!');
465                         i = 500 * M;
466                         opt_show_longval_bi(buf, &i);
467                         ok1(strcmp(buf, "500M") == 0);
468                         ok1(buf[OPT_SHOW_LEN] == '!');
469                         i = 1024 * M;
470                         opt_show_longval_bi(buf, &i);
471                         ok1(strcmp(buf, "1G") == 0);
472                         ok1(buf[OPT_SHOW_LEN] == '!');
473                         i = 0;
474                         opt_show_longval_bi(buf, &i);
475                         ok1(strcmp(buf, "0") == 0);
476                         ok1(buf[OPT_SHOW_LEN] == '!');
477                 }
478
479                 /* opt_show_llongval_bi */
480                 {
481                         long long i;
482                         char buf[OPT_SHOW_LEN+2] = { 0 };
483                         buf[OPT_SHOW_LEN] = '!';
484                         i = -7777;
485                         opt_show_longlongval_bi(buf, &i);
486                         ok1(strcmp(buf, "-7777") == 0);
487                         ok1(buf[OPT_SHOW_LEN] == '!');
488                         i = 7777;
489                         opt_show_longlongval_bi(buf, &i);
490                         ok1(strcmp(buf, "7777") == 0);
491                         ok1(buf[OPT_SHOW_LEN] == '!');
492                         i = -10240000 * k;
493                         opt_show_longlongval_bi(buf, &i);
494                         ok1(strcmp(buf, "-10000M") == 0);
495                         ok1(buf[OPT_SHOW_LEN] == '!');
496                         i = 5 * P;
497                         opt_show_longlongval_bi(buf, &i);
498                         ok1(strcmp(buf, "5P") == 0);
499                         ok1(buf[OPT_SHOW_LEN] == '!');
500                         i = 1024 * P;
501                         opt_show_longlongval_bi(buf, &i);
502                         ok1(strcmp(buf, "1E") == 0);
503                         ok1(buf[OPT_SHOW_LEN] == '!');
504                 }
505
506                 /* opt_show_uintval_bi */
507                 {
508                         unsigned int i;
509                         char buf[OPT_SHOW_LEN+2] = { 0 };
510                         buf[OPT_SHOW_LEN] = '!';
511                         i = 77;
512                         opt_show_uintval_bi(buf, &i);
513                         ok1(strcmp(buf, "77") == 0);
514                         ok1(buf[OPT_SHOW_LEN] == '!');
515                         i = 1234 * k;
516                         opt_show_uintval_bi(buf, &i);
517                         ok1(strcmp(buf, "1234k") == 0);
518                         ok1(buf[OPT_SHOW_LEN] == '!');
519                         i = 500 * M;
520                         opt_show_uintval_bi(buf, &i);
521                         ok1(strcmp(buf, "500M") == 0);
522                         ok1(buf[OPT_SHOW_LEN] == '!');
523                         i = 1024 * M;
524                         opt_show_uintval_bi(buf, &i);
525                         ok1(strcmp(buf, "1G") == 0);
526                         ok1(buf[OPT_SHOW_LEN] == '!');
527                 }
528
529                 /* opt_show_ulongval_bi */
530                 {
531                         unsigned long i;
532                         char buf[OPT_SHOW_LEN+2] = { 0 };
533                         buf[OPT_SHOW_LEN] = '!';
534                         i = 77;
535                         opt_show_ulongval_bi(buf, &i);
536                         ok1(strcmp(buf, "77") == 0);
537                         ok1(buf[OPT_SHOW_LEN] == '!');
538                         i = k;
539                         opt_show_ulongval_bi(buf, &i);
540                         ok1(strcmp(buf, "1k") == 0);
541                         ok1(buf[OPT_SHOW_LEN] == '!');
542                         i = 500 * M;
543                         opt_show_ulongval_bi(buf, &i);
544                         ok1(strcmp(buf, "500M") == 0);
545                         ok1(buf[OPT_SHOW_LEN] == '!');
546                         i = 1024 * M;
547                         opt_show_ulongval_bi(buf, &i);
548                         ok1(strcmp(buf, "1G") == 0);
549                         ok1(buf[OPT_SHOW_LEN] == '!');
550                         i = 0;
551                         opt_show_ulongval_bi(buf, &i);
552                         ok1(strcmp(buf, "0") == 0);
553                         ok1(buf[OPT_SHOW_LEN] == '!');
554                 }
555
556                 /* opt_show_ullongval_bi */
557                 {
558                         long long i;
559                         char buf[OPT_SHOW_LEN+2] = { 0 };
560                         buf[OPT_SHOW_LEN] = '!';
561                         i = 7777;
562                         opt_show_ulonglongval_bi(buf, (unsigned long long *)&i);
563                         ok1(strcmp(buf, "7777") == 0);
564                         ok1(buf[OPT_SHOW_LEN] == '!');
565                         i = 10240000 * k;
566                         opt_show_ulonglongval_bi(buf, (unsigned long long *)&i);
567                         ok1(strcmp(buf, "10000M") == 0);
568                         ok1(buf[OPT_SHOW_LEN] == '!');
569                         i = 5 * P;
570                         opt_show_ulonglongval_bi(buf, (unsigned long long *)&i);
571                         ok1(strcmp(buf, "5P") == 0);
572                         ok1(buf[OPT_SHOW_LEN] == '!');
573                         i = 1024 * P;
574                         opt_show_ulonglongval_bi(buf, (unsigned long long *)&i);
575                         ok1(strcmp(buf, "1E") == 0);
576                         ok1(buf[OPT_SHOW_LEN] == '!');
577                 }
578         }
579
580         {
581                 const long long k = 1000;
582                 const long long M = k * k;
583                 const long long G = k * k * k;
584                 const long long T = k * k * k * k;
585                 const long long P = k * k * k * k * k;
586                 const long long E = k * k * k * k * k * k;
587
588                 /* opt_set_uintval_si */
589                 {
590                         unsigned int arg = 1000;
591                         reset_options();
592                         opt_register_arg("-a", opt_set_uintval_si, NULL,
593                                          &arg, "All");
594                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
595                         ok1(arg == 9999);
596                         ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
597                         ok1(parse_args(&argc, &argv, "-a", "0", NULL));
598                         ok1(arg == 0);
599                         arg = 1;
600                         ok1(parse_args(&argc, &argv, "-a", "0k", NULL));
601                         ok1(arg == 0);
602                         arg = 1;
603                         ok1(parse_args(&argc, &argv, "-a", "0P", NULL));
604                         ok1(arg == 0);
605                         ok1(!parse_args(&argc, &argv, "-a", "3Q", NULL));
606                         ok1(parse_args(&argc, &argv, "-a", "30k", NULL));
607                         ok1(arg == 30 * k);
608                         ok1(!parse_args(&argc, &argv, "-a", "-1K", NULL));
609                         if (sizeof(unsigned int) < 8)
610                                 ok1(!parse_args(&argc, &argv, "-a", "1E", NULL));
611                         else
612                                 pass("can't test int truncation when int is so huge");
613         }
614
615                 /* opt_set_intval_si */
616                 {
617                         int arg = 1000;
618                         reset_options();
619                         opt_register_arg("-a", opt_set_intval_si, NULL,
620                                          &arg, "All");
621                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
622                         ok1(arg == 9999);
623                         ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
624                         ok1(arg == -9999);
625                         ok1(parse_args(&argc, &argv, "-a", "0", NULL));
626                         ok1(arg == 0);
627                         arg = 1;
628                         ok1(parse_args(&argc, &argv, "-a", "0k", NULL));
629                         ok1(arg == 0);
630                         arg = 1;
631                         ok1(parse_args(&argc, &argv, "-a", "0P", NULL));
632                         ok1(arg == 0);
633                         ok1(!parse_args(&argc, &argv, "-a", "", NULL));
634                         ok1(!parse_args(&argc, &argv, "-a", "3Q", NULL));
635                         ok1(parse_args(&argc, &argv, "-a", "30k", NULL));
636                         ok1(arg == 30 * k);
637                         ok1(parse_args(&argc, &argv, "-a", "-1K", NULL));
638                         ok1(arg == -1 * k);
639                         if (sizeof(int) < 8)
640                                 ok1(!parse_args(&argc, &argv, "-a", "1E", NULL));
641                         else
642                                 pass("can't test int truncation when int is so huge");
643                 }
644
645
646                 /* opt_set_ulongval_si */
647                 {
648                         unsigned long int arg = 1000;
649
650                         reset_options();
651                         opt_register_arg("-a", opt_set_ulongval_si, NULL,
652                                          &arg, "All");
653                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
654                         ok1(arg == 9999);
655                         ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
656                         ok1(parse_args(&argc, &argv, "-a", "0P", NULL));
657                         ok1(arg == 0);
658                         ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
659                         ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL));
660                         ok1(parse_args(&argc, &argv, "-a", "100k", NULL));
661                         ok1(arg == 100 * k);
662                         ok1(parse_args(&argc, &argv, "-a", "1K", NULL));
663                         ok1(arg == 1 * k);
664                         ok1(parse_args(&argc, &argv, "-a", "99M", NULL));
665                         ok1(arg == 99 * M);
666                         /*note, 2999M > max signed 32 bit long, 1 << 31*/
667                         ok1(parse_args(&argc, &argv, "-a", "2999m", NULL));
668                         ok1(arg == 2999 * M);
669                         ok1(parse_args(&argc, &argv, "-a", "1G", NULL));
670                         ok1(arg == 1 * G);
671                         ok1(!parse_args(&argc, &argv, "-a", "-1G", NULL));
672                         ok1(parse_args(&argc, &argv, "-a", "4G", NULL));
673                         ok1(arg == 4000000000U);
674                         if (sizeof(long) == 4){
675                                 ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
676                                 ok1(!parse_args(&argc, &argv, "-a", "4295M", NULL));
677                                 ok1(!parse_args(&argc, &argv, "-a", "1T", NULL));
678                                 ok1(!parse_args(&argc, &argv, "-a", "1E", NULL));
679                         }
680                         else if (sizeof(long)== 8){
681                                 ok1(!parse_args(&argc, &argv, "-a",
682                                                 "18446744073709551616", NULL));
683                                 ok1(parse_args(&argc, &argv, "-a", "9E", NULL));
684                                 ok1(arg == 9000000000000000000ULL);
685                                 ok1(!parse_args(&argc, &argv, "-a", "19E", NULL));
686                         }
687                         else
688                                 fail("FIXME: Handle other long sizes");
689                 }
690
691                 /* opt_set_longval_si */
692                 {
693                         long int arg = 1000;
694
695                         reset_options();
696                         opt_register_arg("-a", opt_set_longval_si, NULL,
697                                          &arg, "All");
698                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
699                         ok1(arg == 9999);
700                         ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
701                         ok1(arg == -9999);
702                         ok1(parse_args(&argc, &argv, "-a", "0P", NULL));
703                         ok1(arg == 0);
704                         ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
705                         ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL));
706                         ok1(parse_args(&argc, &argv, "-a", "100k", NULL));
707                         ok1(arg == 100 * k);
708                         ok1(parse_args(&argc, &argv, "-a", "-100k", NULL));
709                         ok1(arg == -100 * k);
710                         ok1(parse_args(&argc, &argv, "-a", "1K", NULL));
711                         ok1(arg == 1 * k);
712                         ok1(parse_args(&argc, &argv, "-a", "99M", NULL));
713                         ok1(arg == 99 * M);
714                         ok1(parse_args(&argc, &argv, "-a", "1G", NULL));
715                         ok1(arg == 1 * G);
716                         ok1(parse_args(&argc, &argv, "-a", "-1G", NULL));
717                         ok1(arg == -1 * G);
718                         if (sizeof(long) == 4){
719                                 ok1(!parse_args(&argc, &argv, "-a", "2147483648", NULL));
720                                 ok1(!parse_args(&argc, &argv, "-a", "4G", NULL));
721                                 ok1(!parse_args(&argc, &argv, "-a", "1T", NULL));
722                                 ok1(!parse_args(&argc, &argv, "-a", "1E", NULL));
723                                 ok1(parse_args(&argc, &argv, "-a", "1999m", NULL));
724                                 ok1(arg == 1999 * M);
725                         }
726                         else if (sizeof(long)== 8){
727                                 ok1(!parse_args(&argc, &argv, "-a",
728                                                 "9223372036854775808", NULL));
729                                 ok1(!parse_args(&argc, &argv, "-a", "9224P", NULL));
730                                 ok1(parse_args(&argc, &argv, "-a", "9E", NULL));
731                                 ok1(arg == 9 * E);
732                                 ok1(parse_args(&argc, &argv, "-a", "123T", NULL));
733                                 ok1(arg == 123 * T);
734                         }
735                         else
736                                 fail("FIXME: Handle other long sizes");
737                 }
738
739
740                 /* opt_set_longlongval_si */
741                 {
742                         long long int arg = 1000;
743                         reset_options();
744                         opt_register_arg("-a", opt_set_longlongval_si, NULL,
745                                          &arg, "All");
746                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
747                         ok1(arg == 9999);
748                         ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
749                         ok1(arg == -9999);
750                         ok1(parse_args(&argc, &argv, "-a", "0T", NULL));
751                         ok1(arg == 0);
752                         ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
753                         ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL));
754                         ok1(!parse_args(&argc, &argv, "-a", "1kk", NULL));
755                         ok1(parse_args(&argc, &argv, "-a", "100k", NULL));
756                         ok1(arg == 100 * k);
757                         ok1(parse_args(&argc, &argv, "-a", "-100k", NULL));
758                         ok1(arg == -100 * k);
759                         ok1(parse_args(&argc, &argv, "-a", "1K", NULL));
760                         ok1(arg == 1 * k);
761                         ok1(parse_args(&argc, &argv, "-a", "-333333M", NULL));
762                         ok1(arg == -333333 * M);
763                         ok1(parse_args(&argc, &argv, "-a", "1G", NULL));
764                         ok1(arg == 1 * G);
765                         ok1(parse_args(&argc, &argv, "-a", "1024t", NULL));
766                         ok1(arg == 1024 * T);
767                         ok1(parse_args(&argc, &argv, "-a", "123P", NULL));
768                         ok1(arg == 123 * P);
769                         ok1(parse_args(&argc, &argv, "-a", "-3E", NULL));
770                         ok1(arg == -3 * E);
771                         ok1(parse_args(&argc, &argv, "-a", "8E", NULL));
772                         if (sizeof(long long) == 8){
773                                 ok1(!parse_args(&argc, &argv, "-a",
774                                                 "9223372036854775808", NULL));
775                                 ok1(!parse_args(&argc, &argv, "-a",
776                                                 "10E", NULL));
777                         }
778                         else
779                                 fail("FIXME: Handle other long long int"
780                                      " sizes (specifically %zu bytes)",
781                                      sizeof(long long));
782
783                 }
784                 /* opt_set_ulonglongval_si */
785                 {
786                         unsigned long long int arg = 1000;
787                         reset_options();
788                         opt_register_arg("-a", opt_set_ulonglongval_si, NULL,
789                                          &arg, "All");
790                         ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
791                         ok1(arg == 9999);
792                         ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
793                         ok1(parse_args(&argc, &argv, "-a", "0", NULL));
794                         ok1(arg == 0);
795                         ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL));
796                         ok1(!parse_args(&argc, &argv, "-a", "1kk", NULL));
797                         ok1(parse_args(&argc, &argv, "-a", "100G", NULL));
798                         ok1(arg == 100 * G);
799                         ok1(!parse_args(&argc, &argv, "-a", "-100G", NULL));
800                         ok1(parse_args(&argc, &argv, "-a", "8E", NULL));
801                 }
802                 /* opt_show_intval_si */
803                 {
804                         int i;
805                         char buf[OPT_SHOW_LEN+2] = { 0 };
806                         buf[OPT_SHOW_LEN] = '!';
807                         i = -77;
808                         opt_show_intval_si(buf, &i);
809                         ok1(strcmp(buf, "-77") == 0);
810                         i = 0;
811                         opt_show_intval_si(buf, &i);
812                         ok1(strcmp(buf, "0") == 0);
813                         ok1(buf[OPT_SHOW_LEN] == '!');
814                         i = 77;
815                         opt_show_intval_si(buf, &i);
816                         ok1(strcmp(buf, "77") == 0);
817                         ok1(buf[OPT_SHOW_LEN] == '!');
818                         i = -1234 * k;
819                         opt_show_intval_si(buf, &i);
820                         ok1(strcmp(buf, "-1234k") == 0);
821                         ok1(buf[OPT_SHOW_LEN] == '!');
822                         i = 500 * M;
823                         opt_show_intval_si(buf, &i);
824                         ok1(strcmp(buf, "500M") == 0);
825                         ok1(buf[OPT_SHOW_LEN] == '!');
826                         i = 1000 * M;
827                         opt_show_intval_si(buf, &i);
828                         ok1(strcmp(buf, "1G") == 0);
829                         ok1(buf[OPT_SHOW_LEN] == '!');
830                 }
831
832                 /* opt_show_longval_si */
833                 {
834                         long i;
835                         char buf[OPT_SHOW_LEN+2] = { 0 };
836                         buf[OPT_SHOW_LEN] = '!';
837                         i = -77;
838                         opt_show_longval_si(buf, &i);
839                         ok1(strcmp(buf, "-77") == 0);
840                         ok1(buf[OPT_SHOW_LEN] == '!');
841                         i = 77;
842                         opt_show_longval_si(buf, &i);
843                         ok1(strcmp(buf, "77") == 0);
844                         ok1(buf[OPT_SHOW_LEN] == '!');
845                         i = -1 * k;
846                         opt_show_longval_si(buf, &i);
847                         ok1(strcmp(buf, "-1k") == 0);
848                         ok1(buf[OPT_SHOW_LEN] == '!');
849                         i = 500 * M;
850                         opt_show_longval_si(buf, &i);
851                         ok1(strcmp(buf, "500M") == 0);
852                         ok1(buf[OPT_SHOW_LEN] == '!');
853                         i = 1000 * M;
854                         opt_show_longval_si(buf, &i);
855                         ok1(strcmp(buf, "1G") == 0);
856                         ok1(buf[OPT_SHOW_LEN] == '!');
857                         i = 0;
858                         opt_show_longval_si(buf, &i);
859                         ok1(strcmp(buf, "0") == 0);
860                         ok1(buf[OPT_SHOW_LEN] == '!');
861                 }
862
863                 /* opt_show_llongval_si */
864                 {
865                         long long i;
866                         char buf[OPT_SHOW_LEN+2] = { 0 };
867                         buf[OPT_SHOW_LEN] = '!';
868                         i = -7777;
869                         opt_show_longlongval_si(buf, &i);
870                         ok1(strcmp(buf, "-7777") == 0);
871                         ok1(buf[OPT_SHOW_LEN] == '!');
872                         i = 7777;
873                         opt_show_longlongval_si(buf, &i);
874                         ok1(strcmp(buf, "7777") == 0);
875                         ok1(buf[OPT_SHOW_LEN] == '!');
876                         i = -10240000 * k;
877                         opt_show_longlongval_si(buf, &i);
878                         ok1(strcmp(buf, "-10240M") == 0);
879                         ok1(buf[OPT_SHOW_LEN] == '!');
880                         i = 5 * P;
881                         opt_show_longlongval_si(buf, &i);
882                         ok1(strcmp(buf, "5P") == 0);
883                         ok1(buf[OPT_SHOW_LEN] == '!');
884                         i = 2000 * P;
885                         opt_show_longlongval_si(buf, &i);
886                         ok1(strcmp(buf, "2E") == 0);
887                         ok1(buf[OPT_SHOW_LEN] == '!');
888                 }
889
890                 /* opt_show_uintval_si */
891                 {
892                         unsigned int i;
893                         char buf[OPT_SHOW_LEN+2] = { 0 };
894                         buf[OPT_SHOW_LEN] = '!';
895                         i = 77;
896                         opt_show_uintval_si(buf, &i);
897                         ok1(strcmp(buf, "77") == 0);
898                         ok1(buf[OPT_SHOW_LEN] == '!');
899                         i = 1234 * k;
900                         opt_show_uintval_si(buf, &i);
901                         ok1(strcmp(buf, "1234k") == 0);
902                         ok1(buf[OPT_SHOW_LEN] == '!');
903                         i = 500 * M;
904                         opt_show_uintval_si(buf, &i);
905                         ok1(strcmp(buf, "500M") == 0);
906                         ok1(buf[OPT_SHOW_LEN] == '!');
907                         i = 1000 * M;
908                         opt_show_uintval_si(buf, &i);
909                         ok1(strcmp(buf, "1G") == 0);
910                         ok1(buf[OPT_SHOW_LEN] == '!');
911                 }
912
913                 /* opt_show_ulongval_si */
914                 {
915                         unsigned long i;
916                         char buf[OPT_SHOW_LEN+2] = { 0 };
917                         buf[OPT_SHOW_LEN] = '!';
918                         i = 77;
919                         opt_show_ulongval_si(buf, &i);
920                         ok1(strcmp(buf, "77") == 0);
921                         ok1(buf[OPT_SHOW_LEN] == '!');
922                         i = k;
923                         opt_show_ulongval_si(buf, &i);
924                         ok1(strcmp(buf, "1k") == 0);
925                         ok1(buf[OPT_SHOW_LEN] == '!');
926                         i = 500 * M;
927                         opt_show_ulongval_si(buf, &i);
928                         ok1(strcmp(buf, "500M") == 0);
929                         ok1(buf[OPT_SHOW_LEN] == '!');
930                         i = 1024 * M;
931                         opt_show_ulongval_si(buf, &i);
932                         ok1(strcmp(buf, "1024M") == 0);
933                         ok1(buf[OPT_SHOW_LEN] == '!');
934                         i = 0;
935                         opt_show_ulongval_si(buf, &i);
936                         ok1(strcmp(buf, "0") == 0);
937                         ok1(buf[OPT_SHOW_LEN] == '!');
938                 }
939
940                 /* opt_show_ullongval_si */
941                 {
942                         long long i;
943                         char buf[OPT_SHOW_LEN+2] = { 0 };
944                         buf[OPT_SHOW_LEN] = '!';
945                         i = 7777;
946                         opt_show_ulonglongval_si(buf, (unsigned long long *)&i);
947                         ok1(strcmp(buf, "7777") == 0);
948                         ok1(buf[OPT_SHOW_LEN] == '!');
949                         i = 10240000 * k;
950                         opt_show_ulonglongval_si(buf, (unsigned long long *)&i);
951                         ok1(strcmp(buf, "10240M") == 0);
952                         ok1(buf[OPT_SHOW_LEN] == '!');
953                         i = 5 * P;
954                         opt_show_ulonglongval_si(buf, (unsigned long long *)&i);
955                         ok1(strcmp(buf, "5P") == 0);
956                         ok1(buf[OPT_SHOW_LEN] == '!');
957                         i = 1000 * P;
958                         opt_show_ulonglongval_si(buf, (unsigned long long *)&i);
959                         ok1(strcmp(buf, "1E") == 0);
960                         ok1(buf[OPT_SHOW_LEN] == '!');
961                 }
962
963         }
964
965
966         /* opt_inc_intval */
967         {
968                 int arg = 1000;
969                 reset_options();
970                 opt_register_noarg("-a", opt_inc_intval, &arg, "");
971                 ok1(parse_args(&argc, &argv, "-a", NULL));
972                 ok1(arg == 1001);
973                 ok1(parse_args(&argc, &argv, "-a", "-a", NULL));
974                 ok1(arg == 1003);
975                 ok1(parse_args(&argc, &argv, "-aa", NULL));
976                 ok1(arg == 1005);
977         }
978
979         /* opt_show_version_and_exit. */
980         {
981                 int exitval;
982                 reset_options();
983                 opt_register_noarg("-a",
984                                    opt_version_and_exit, "1.2.3", "");
985                 /* parse_args allocates argv */
986                 free(argv);
987
988                 argc = 2;
989                 argv = malloc(sizeof(argv[0]) * 3);
990                 argv[0] = (char *)"thisprog";
991                 argv[1] = (char *)"-a";
992                 argv[2] = NULL;
993
994                 exitval = setjmp(exited);
995                 if (exitval == 0) {
996                         opt_parse(&argc, argv, save_err_output);
997                         fail("opt_show_version_and_exit returned?");
998                 } else {
999                         ok1(exitval - 1 == 0);
1000                 }
1001                 ok1(strcmp(output, "1.2.3\n") == 0);
1002                 free(output);
1003                 free(argv);
1004                 output = NULL;
1005         }
1006
1007         /* opt_usage_and_exit. */
1008         {
1009                 int exitval;
1010                 reset_options();
1011                 opt_register_noarg("-a",
1012                                    opt_usage_and_exit, "[args]", "");
1013
1014                 argc = 2;
1015                 argv = malloc(sizeof(argv[0]) * 3);
1016                 argv[0] = (char *)"thisprog";
1017                 argv[1] = (char *)"-a";
1018                 argv[2] = NULL;
1019
1020                 exitval = setjmp(exited);
1021                 if (exitval == 0) {
1022                         opt_parse(&argc, argv, save_err_output);
1023                         fail("opt_usage_and_exit returned?");
1024                 } else {
1025                         ok1(exitval - 1 == 0);
1026                 }
1027                 ok1(strstr(output, "[args]"));
1028                 ok1(strstr(output, argv[0]));
1029                 ok1(strstr(output, "[-a]"));
1030                 free(output);
1031                 free(argv);
1032                 /* It exits without freeing usage string. */
1033                 free(last_allocation);
1034                 output = NULL;
1035         }
1036
1037         /* opt_show_bool */
1038         {
1039                 bool b;
1040                 char buf[OPT_SHOW_LEN+2] = { 0 };
1041                 buf[OPT_SHOW_LEN] = '!';
1042
1043                 b = true;
1044                 opt_show_bool(buf, &b);
1045                 ok1(strcmp(buf, "true") == 0);
1046                 ok1(buf[OPT_SHOW_LEN] == '!');
1047
1048                 b = false;
1049                 opt_show_bool(buf, &b);
1050                 ok1(strcmp(buf, "false") == 0);
1051                 ok1(buf[OPT_SHOW_LEN] == '!');
1052         }
1053
1054         /* opt_show_invbool */
1055         {
1056                 bool b;
1057                 char buf[OPT_SHOW_LEN+2] = { 0 };
1058                 buf[OPT_SHOW_LEN] = '!';
1059
1060                 b = true;
1061                 opt_show_invbool(buf, &b);
1062                 ok1(strcmp(buf, "false") == 0);
1063                 ok1(buf[OPT_SHOW_LEN] == '!');
1064
1065                 b = false;
1066                 opt_show_invbool(buf, &b);
1067                 ok1(strcmp(buf, "true") == 0);
1068                 ok1(buf[OPT_SHOW_LEN] == '!');
1069         }
1070
1071         /* opt_show_charp */
1072         {
1073                 char str[OPT_SHOW_LEN*2], *p;
1074                 char buf[OPT_SHOW_LEN+2] = { 0 };
1075                 buf[OPT_SHOW_LEN] = '!';
1076
1077                 /* Short test. */
1078                 p = str;
1079                 strcpy(p, "short");
1080                 opt_show_charp(buf, &p);
1081                 ok1(strcmp(buf, "\"short\"") == 0);
1082                 ok1(buf[OPT_SHOW_LEN] == '!');
1083
1084                 /* Truncate test. */
1085                 memset(p, 'x', OPT_SHOW_LEN*2);
1086                 p[OPT_SHOW_LEN*2-1] = '\0';
1087                 opt_show_charp(buf, &p);
1088                 ok1(buf[0] == '"');
1089                 ok1(buf[OPT_SHOW_LEN-1] == '"');
1090                 ok1(buf[OPT_SHOW_LEN] == '!');
1091                 ok1(strspn(buf+1, "x") == OPT_SHOW_LEN-2);
1092         }
1093
1094         /* opt_show_intval */
1095         {
1096                 int i;
1097                 char buf[OPT_SHOW_LEN+2] = { 0 };
1098                 buf[OPT_SHOW_LEN] = '!';
1099
1100                 i = -77;
1101                 opt_show_intval(buf, &i);
1102                 ok1(strcmp(buf, "-77") == 0);
1103                 ok1(buf[OPT_SHOW_LEN] == '!');
1104
1105                 i = 77;
1106                 opt_show_intval(buf, &i);
1107                 ok1(strcmp(buf, "77") == 0);
1108                 ok1(buf[OPT_SHOW_LEN] == '!');
1109         }
1110
1111         /* opt_show_uintval */
1112         {
1113                 unsigned int ui;
1114                 char buf[OPT_SHOW_LEN+2] = { 0 };
1115                 buf[OPT_SHOW_LEN] = '!';
1116
1117                 ui = 4294967295U;
1118                 opt_show_uintval(buf, &ui);
1119                 ok1(strcmp(buf, "4294967295") == 0);
1120                 ok1(buf[OPT_SHOW_LEN] == '!');
1121         }
1122
1123         /* opt_show_longval */
1124         {
1125                 long l;
1126                 char buf[OPT_SHOW_LEN+2] = { 0 };
1127                 buf[OPT_SHOW_LEN] = '!';
1128
1129                 l = 1234567890L;
1130                 opt_show_longval(buf, &l);
1131                 ok1(strcmp(buf, "1234567890") == 0);
1132                 ok1(buf[OPT_SHOW_LEN] == '!');
1133         }
1134
1135         /* opt_show_ulongval */
1136         {
1137                 unsigned long ul;
1138                 char buf[OPT_SHOW_LEN+2] = { 0 };
1139                 buf[OPT_SHOW_LEN] = '!';
1140
1141                 ul = 4294967295UL;
1142                 opt_show_ulongval(buf, &ul);
1143                 ok1(strcmp(buf, "4294967295") == 0);
1144                 ok1(buf[OPT_SHOW_LEN] == '!');
1145         }
1146
1147         /* opt_log_stderr. */
1148         {
1149                 reset_options();
1150                 opt_register_noarg("-a",
1151                                    opt_usage_and_exit, "[args]", "");
1152
1153                 argc = 2;
1154                 argv = malloc(sizeof(argv[0]) * 3);
1155                 argv[0] = (char *)"thisprog";
1156                 argv[1] = (char *)"--garbage";
1157                 argv[2] = NULL;
1158                 ok1(!opt_parse(&argc, argv, opt_log_stderr));
1159                 ok1(!strcmp(output,
1160                             "thisprog: --garbage: unrecognized option\n"));
1161                 free(output);
1162                 free(argv);
1163                 output = NULL;
1164         }
1165
1166         /* opt_log_stderr_exit. */
1167         {
1168                 int exitval;
1169                 reset_options();
1170                 opt_register_noarg("-a",
1171                                    opt_usage_and_exit, "[args]", "");
1172                 argc = 2;
1173                 argv = malloc(sizeof(argv[0]) * 3);
1174                 argv[0] = (char *)"thisprog";
1175                 argv[1] = (char *)"--garbage";
1176                 argv[2] = NULL;
1177                 exitval = setjmp(exited);
1178                 if (exitval == 0) {
1179                         opt_parse(&argc, argv, opt_log_stderr_exit);
1180                         fail("opt_log_stderr_exit returned?");
1181                 } else {
1182                         ok1(exitval - 1 == 1);
1183                 }
1184                 free(argv);
1185                 ok1(!strcmp(output,
1186                             "thisprog: --garbage: unrecognized option\n"));
1187                 free(output);
1188                 output = NULL;
1189         }
1190
1191         //diag("%s\n", err_output);
1192         return exit_status();
1193 }