glitch in the license text detected by hyazinthe, thank you!
[oweals/gnunet.git] / src / util / getopt_helpers.c
1 /*
2      This file is part of GNUnet
3      Copyright (C) 2006, 2011 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14 */
15
16 /**
17  * @file src/util/getopt_helpers.c
18  * @brief implements command line that sets option
19  * @author Christian Grothoff
20  */
21 #include "platform.h"
22 #include "gnunet_util_lib.h"
23
24 #define LOG(kind,...) GNUNET_log_from (kind, "util-getopt", __VA_ARGS__)
25
26
27 /**
28  * Print out program version (implements --version).
29  *
30  * @param ctx command line processing context
31  * @param scls additional closure (points to version string)
32  * @param option name of the option
33  * @param value not used (NULL)
34  * @return #GNUNET_NO (do not continue, not an error)
35  */
36 static int
37 print_version (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
38                void *scls,
39                const char *option,
40                const char *value)
41 {
42   const char *version = scls;
43
44   (void) option;
45   (void) value;
46   printf ("%s v%s\n",
47           ctx->binaryName,
48           version);
49   return GNUNET_NO;
50 }
51
52
53 /**
54  * Define the option to print the version of
55  * the application (-v option)
56  *
57  * @param version string with the version number
58  */
59 struct GNUNET_GETOPT_CommandLineOption
60 GNUNET_GETOPT_option_version (const char *version)
61 {
62   struct GNUNET_GETOPT_CommandLineOption clo = {
63     .shortName =  'v',
64     .name = "version",
65     .description = gettext_noop("print the version number"),
66     .processor = &print_version,
67     .scls = (void *) version
68   };
69   return clo;
70 }
71
72
73 /**
74  * At what offset does the help text start?
75  */
76 #define BORDER 29
77
78 /**
79  * Print out details on command line options (implements --help).
80  *
81  * @param ctx command line processing context
82  * @param scls additional closure (points to about text)
83  * @param option name of the option
84  * @param value not used (NULL)
85  * @return #GNUNET_NO (do not continue, not an error)
86  */
87 static int
88 format_help (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
89              void *scls,
90              const char *option,
91              const char *value)
92 {
93   const char *about = scls;
94   size_t slen;
95   unsigned int i;
96   int j;
97   size_t ml;
98   size_t p;
99   char *scp;
100   const char *trans;
101   const struct GNUNET_GETOPT_CommandLineOption *opt;
102   const struct GNUNET_OS_ProjectData *pd;
103
104   (void) option;
105   (void) value;
106   if (NULL != about)
107   {
108     printf ("%s\n%s\n", ctx->binaryOptions, gettext (about));
109     printf (_
110             ("Arguments mandatory for long options are also mandatory for short options.\n"));
111   }
112   i = 0;
113   opt = ctx->allOptions;
114   while (NULL != opt[i].description)
115   {
116     if (opt[i].shortName == '\0')
117       printf ("      ");
118     else
119       printf ("  -%c, ", opt[i].shortName);
120     printf ("--%s", opt[i].name);
121     slen = 8 + strlen (opt[i].name);
122     if (NULL != opt[i].argumentHelp)
123     {
124       printf ("=%s", opt[i].argumentHelp);
125       slen += 1 + strlen (opt[i].argumentHelp);
126     }
127     if (slen > BORDER)
128     {
129       printf ("\n%*s", BORDER, "");
130       slen = BORDER;
131     }
132     if (slen < BORDER)
133     {
134       printf ("%*s", (int) (BORDER - slen), "");
135       slen = BORDER;
136     }
137     if (0 < strlen (opt[i].description))
138       trans = gettext (opt[i].description);
139     else
140       trans = "";
141     ml = strlen (trans);
142     p = 0;
143 OUTER:
144     while (ml - p > 78 - slen)
145     {
146       for (j = p + 78 - slen; j > (int) p; j--)
147       {
148         if (isspace ((unsigned char) trans[j]))
149         {
150           scp = GNUNET_malloc (j - p + 1);
151           GNUNET_memcpy (scp, &trans[p], j - p);
152           scp[j - p] = '\0';
153           printf ("%s\n%*s", scp, BORDER + 2, "");
154           GNUNET_free (scp);
155           p = j + 1;
156           slen = BORDER + 2;
157           goto OUTER;
158         }
159       }
160       /* could not find space to break line */
161       scp = GNUNET_malloc (78 - slen + 1);
162       GNUNET_memcpy (scp, &trans[p], 78 - slen);
163       scp[78 - slen] = '\0';
164       printf ("%s\n%*s", scp, BORDER + 2, "");
165       GNUNET_free (scp);
166       slen = BORDER + 2;
167       p = p + 78 - slen;
168     }
169     /* print rest */
170     if (p < ml)
171       printf ("%s\n", &trans[p]);
172     if (strlen (trans) == 0)
173       printf ("\n");
174     i++;
175   }
176   pd = GNUNET_OS_project_data_get ();
177   printf ("Report bugs to %s.\n"
178           "GNUnet home page: %s\n"
179           "General help using GNU software: http://www.gnu.org/gethelp/\n",
180           pd->bug_email,
181           pd->homepage);
182   return GNUNET_NO;
183 }
184
185
186 /**
187  * Defining the option to print the command line
188  * help text (-h option).
189  *
190  * @param about string with brief description of the application
191  */
192 struct GNUNET_GETOPT_CommandLineOption
193 GNUNET_GETOPT_option_help (const char *about)
194 {
195   struct GNUNET_GETOPT_CommandLineOption clo = {
196     .shortName = 'h',
197     .name = "help",
198     .description = gettext_noop("print this help"),
199     .processor = format_help,
200     .scls = (void *) about
201   };
202
203   return clo;
204 }
205
206
207 /**
208  * Set an option of type 'unsigned int' from the command line. Each
209  * time the option flag is given, the value is incremented by one.
210  * A pointer to this function should be passed as part of the
211  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
212  * of this type.  It should be followed by a pointer to a value of
213  * type 'int'.
214  *
215  * @param ctx command line processing context
216  * @param scls additional closure (will point to the 'unsigned int')
217  * @param option name of the option
218  * @param value not used (NULL)
219  * @return #GNUNET_OK
220  */
221 static int
222 increment_value (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
223                  void *scls,
224                  const char *option,
225                  const char *value)
226 {
227   unsigned int *val = scls;
228
229   (void) ctx;
230   (void) option;
231   (void) value;
232   (*val)++;
233   return GNUNET_OK;
234 }
235
236
237 /**
238  * Increment @a val each time the option flag is given by one.
239  *
240  * @param shortName short name of the option
241  * @param name long name of the option
242  * @param argumentHelp help text for the option argument
243  * @param description long help text for the option
244  * @param[out] val increment by 1 each time the option is present
245  */
246 struct GNUNET_GETOPT_CommandLineOption
247 GNUNET_GETOPT_option_increment_uint (char shortName,
248                                      const char *name,
249                                      const char *description,
250                                      unsigned int *val)
251 {
252   struct GNUNET_GETOPT_CommandLineOption clo = {
253     .shortName =  shortName,
254     .name = name,
255     .description = description,
256     .processor = &increment_value,
257     .scls = (void *) val
258   };
259
260   return clo;
261 }
262
263
264 /**
265  * Define the '-V' verbosity option.  Using the option more
266  * than once increments @a level each time.
267  *
268  * @param[out] level set to the verbosity level
269  */
270 struct GNUNET_GETOPT_CommandLineOption
271 GNUNET_GETOPT_option_verbose (unsigned int *level)
272 {
273   struct GNUNET_GETOPT_CommandLineOption clo = {
274     .shortName = 'V',
275     .name = "verbose",
276     .description = gettext_noop("be verbose"),
277     .processor = &increment_value,
278     .scls = (void *) level
279   };
280
281   return clo;
282 }
283
284
285 /**
286  * Set an option of type 'int' from the command line to 1 if the
287  * given option is present.
288  * A pointer to this function should be passed as part of the
289  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
290  * of this type.  It should be followed by a pointer to a value of
291  * type 'int'.
292  *
293  * @param ctx command line processing context
294  * @param scls additional closure (will point to the 'int')
295  * @param option name of the option
296  * @param value not used (NULL)
297  * @return #GNUNET_OK
298  */
299 static int
300 set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
301          void *scls,
302          const char *option,
303          const char *value)
304 {
305   int *val = scls;
306
307   (void) ctx;
308   (void) option;
309   (void) value;
310   *val = 1;
311   return GNUNET_OK;
312 }
313
314
315 /**
316  * Allow user to specify a flag (which internally means setting
317  * an integer to 1/#GNUNET_YES/#GNUNET_OK.
318  *
319  * @param shortName short name of the option
320  * @param name long name of the option
321  * @param argumentHelp help text for the option argument
322  * @param description long help text for the option
323  * @param[out] val set to 1 if the option is present
324  */
325 struct GNUNET_GETOPT_CommandLineOption
326 GNUNET_GETOPT_option_flag (char shortName,
327                            const char *name,
328                            const char *description,
329                            int *val)
330 {
331   struct GNUNET_GETOPT_CommandLineOption clo = {
332     .shortName =  shortName,
333     .name = name,
334     .description = description,
335     .processor = &set_one,
336     .scls = (void *) val
337   };
338
339   return clo;
340 }
341
342
343 /**
344  * Set an option of type 'char *' from the command line.
345  * A pointer to this function should be passed as part of the
346  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
347  * of this type.  It should be followed by a pointer to a value of
348  * type 'char *', which will be allocated with the requested string.
349  *
350  * @param ctx command line processing context
351  * @param scls additional closure (will point to the 'char *',
352  *             which will be allocated)
353  * @param option name of the option
354  * @param value actual value of the option (a string)
355  * @return #GNUNET_OK
356  */
357 static int
358 set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
359             void *scls,
360             const char *option,
361             const char *value)
362 {
363   char **val = scls;
364
365   (void) ctx;
366   (void) option;
367   GNUNET_assert (NULL != value);
368   GNUNET_free_non_null (*val);
369   *val = GNUNET_strdup (value);
370   return GNUNET_OK;
371 }
372
373
374 /**
375  * Allow user to specify a string.
376  *
377  * @param shortName short name of the option
378  * @param name long name of the option
379  * @param argumentHelp help text for the option argument
380  * @param description long help text for the option
381  * @param[out] str set to the string
382  */
383 struct GNUNET_GETOPT_CommandLineOption
384 GNUNET_GETOPT_option_string (char shortName,
385                              const char *name,
386                              const char *argumentHelp,
387                              const char *description,
388                              char **str)
389 {
390   struct GNUNET_GETOPT_CommandLineOption clo = {
391     .shortName =  shortName,
392     .name = name,
393     .argumentHelp = argumentHelp,
394     .description = description,
395     .require_argument = 1,
396     .processor = &set_string,
397     .scls = (void *) str
398   };
399
400   return clo;
401 }
402
403
404 /**
405  * Define the '-L' log level option.  Note that we do not check
406  * that the log level is valid here.
407  *
408  * @param[out] level set to the log level
409  */
410 struct GNUNET_GETOPT_CommandLineOption
411 GNUNET_GETOPT_option_loglevel (char **level)
412 {
413   struct GNUNET_GETOPT_CommandLineOption clo = {
414     .shortName = 'L',
415     .name = "log",
416     .argumentHelp = "LOGLEVEL",
417     .description = gettext_noop("configure logging to use LOGLEVEL"),
418     .require_argument = 1,
419     .processor = &set_string,
420     .scls = (void *) level
421   };
422
423   return clo;
424 }
425
426
427 /**
428  * Set an option of type 'char *' from the command line with
429  * filename expansion a la #GNUNET_STRINGS_filename_expand().
430  *
431  * @param ctx command line processing context
432  * @param scls additional closure (will point to the `char *`,
433  *             which will be allocated)
434  * @param option name of the option
435  * @param value actual value of the option (a string)
436  * @return #GNUNET_OK
437  */
438 static int
439 set_filename (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
440               void *scls,
441               const char *option,
442               const char *value)
443 {
444   char **val = scls;
445
446   (void) ctx;
447   (void) option;
448   GNUNET_assert (NULL != value);
449   GNUNET_free_non_null (*val);
450   *val = GNUNET_STRINGS_filename_expand (value);
451   return GNUNET_OK;
452 }
453
454
455 /**
456  * Allow user to specify a filename (automatically path expanded).
457  *
458  * @param shortName short name of the option
459  * @param name long name of the option
460  * @param argumentHelp help text for the option argument
461  * @param description long help text for the option
462  * @param[out] str set to the string
463  */
464 struct GNUNET_GETOPT_CommandLineOption
465 GNUNET_GETOPT_option_filename (char shortName,
466                                const char *name,
467                                const char *argumentHelp,
468                                const char *description,
469                                char **str)
470 {
471   struct GNUNET_GETOPT_CommandLineOption clo = {
472     .shortName =  shortName,
473     .name = name,
474     .argumentHelp = argumentHelp,
475     .description = description,
476     .require_argument = 1,
477     .processor = &set_filename,
478     .scls = (void *) str
479   };
480
481   return clo;
482 }
483
484
485 /**
486  * Allow user to specify log file name (-l option)
487  *
488  * @param[out] logfn set to the name of the logfile
489  */
490 struct GNUNET_GETOPT_CommandLineOption
491 GNUNET_GETOPT_option_logfile (char **logfn)
492 {
493   struct GNUNET_GETOPT_CommandLineOption clo = {
494     .shortName =  'l',
495     .name = "logfile",
496     .argumentHelp = "FILENAME",
497     .description = gettext_noop ("configure logging to write logs to FILENAME"),
498     .require_argument = 1,
499     .processor = &set_filename,
500     .scls = (void *) logfn
501   };
502
503   return clo;
504 }
505
506
507 /**
508  * Allow user to specify configuration file name (-c option)
509  *
510  * @param[out] fn set to the name of the configuration file
511  */
512 struct GNUNET_GETOPT_CommandLineOption
513 GNUNET_GETOPT_option_cfgfile (char **fn)
514 {
515   struct GNUNET_GETOPT_CommandLineOption clo = {
516     .shortName =  'c',
517     .name = "config",
518     .argumentHelp = "FILENAME",
519     .description = gettext_noop("use configuration file FILENAME"),
520     .require_argument = 1,
521     .processor = &set_filename,
522     .scls = (void *) fn
523   };
524
525   return clo;
526 }
527
528
529 /**
530  * Set an option of type 'unsigned long long' from the command line.
531  * A pointer to this function should be passed as part of the
532  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
533  * of this type.  It should be followed by a pointer to a value of
534  * type 'unsigned long long'.
535  *
536  * @param ctx command line processing context
537  * @param scls additional closure (will point to the 'unsigned long long')
538  * @param option name of the option
539  * @param value actual value of the option as a string.
540  * @return #GNUNET_OK if parsing the value worked
541  */
542 static int
543 set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
544            void *scls,
545            const char *option,
546            const char *value)
547 {
548   unsigned long long *val = scls;
549
550   (void) ctx;
551   if (1 != SSCANF (value,
552                    "%llu",
553                    val))
554   {
555     FPRINTF (stderr,
556              _("You must pass a number to the `%s' option.\n"),
557              option);
558     return GNUNET_SYSERR;
559   }
560   return GNUNET_OK;
561 }
562
563
564 /**
565  * Allow user to specify an `unsigned long long`
566  *
567  * @param shortName short name of the option
568  * @param name long name of the option
569  * @param argumentHelp help text for the option argument
570  * @param description long help text for the option
571  * @param[out] val set to the value specified at the command line
572  */
573 struct GNUNET_GETOPT_CommandLineOption
574 GNUNET_GETOPT_option_ulong (char shortName,
575                             const char *name,
576                             const char *argumentHelp,
577                             const char *description,
578                             unsigned long long *val)
579 {
580   struct GNUNET_GETOPT_CommandLineOption clo = {
581     .shortName =  shortName,
582     .name = name,
583     .argumentHelp = argumentHelp,
584     .description = description,
585     .require_argument = 1,
586     .processor = &set_ulong,
587     .scls = (void *) val
588   };
589
590   return clo;
591 }
592
593
594 /**
595  * Set an option of type 'struct GNUNET_TIME_Relative' from the command line.
596  * A pointer to this function should be passed as part of the
597  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
598  * of this type.  It should be followed by a pointer to a value of
599  * type 'struct GNUNET_TIME_Relative'.
600  *
601  * @param ctx command line processing context
602  * @param scls additional closure (will point to the 'struct GNUNET_TIME_Relative')
603  * @param option name of the option
604  * @param value actual value of the option as a string.
605  * @return #GNUNET_OK if parsing the value worked
606  */
607 static int
608 set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
609                    void *scls,
610                    const char *option,
611                    const char *value)
612 {
613   struct GNUNET_TIME_Relative *val = scls;
614   
615   (void) ctx;  
616   if (GNUNET_OK !=
617       GNUNET_STRINGS_fancy_time_to_relative (value,
618                                              val))
619   {
620     FPRINTF (stderr,
621              _("You must pass relative time to the `%s' option.\n"),
622              option);
623     return GNUNET_SYSERR;
624   }
625   return GNUNET_OK;
626 }
627
628
629 /**
630  * Allow user to specify a `struct GNUNET_TIME_Relative`
631  * (using human-readable "fancy" time).
632  *
633  * @param shortName short name of the option
634  * @param name long name of the option
635  * @param argumentHelp help text for the option argument
636  * @param description long help text for the option
637  * @param[out] val set to the time specified at the command line
638  */
639 struct GNUNET_GETOPT_CommandLineOption
640 GNUNET_GETOPT_option_relative_time (char shortName,
641                                     const char *name,
642                                     const char *argumentHelp,
643                                     const char *description,
644                                     struct GNUNET_TIME_Relative *val)
645 {
646   struct GNUNET_GETOPT_CommandLineOption clo = {
647     .shortName =  shortName,
648     .name = name,
649     .argumentHelp = argumentHelp,
650     .description = description,
651     .require_argument = 1,
652     .processor = &set_relative_time,
653     .scls = (void *) val
654   };
655
656   return clo;
657 }
658
659
660 /**
661  * Set an option of type 'struct GNUNET_TIME_Absolute' from the command line.
662  * A pointer to this function should be passed as part of the
663  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
664  * of this type.  It should be followed by a pointer to a value of
665  * type 'struct GNUNET_TIME_Absolute'.
666  *
667  * @param ctx command line processing context
668  * @param scls additional closure (will point to the `struct GNUNET_TIME_Absolute`)
669  * @param option name of the option
670  * @param value actual value of the option as a string.
671  * @return #GNUNET_OK if parsing the value worked
672  */
673 static int
674 set_absolute_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
675                    void *scls,
676                    const char *option,
677                    const char *value)
678 {
679   struct GNUNET_TIME_Absolute *val = scls;
680
681   (void) ctx;
682   if (GNUNET_OK !=
683       GNUNET_STRINGS_fancy_time_to_absolute (value,
684                                              val))
685   {
686     FPRINTF (stderr,
687              _("You must pass absolute time to the `%s' option.\n"),
688              option);
689     return GNUNET_SYSERR;
690   }
691   return GNUNET_OK;
692 }
693
694
695 /**
696  * Allow user to specify a `struct GNUNET_TIME_Absolute`
697  * (using human-readable "fancy" time).
698  *
699  * @param shortName short name of the option
700  * @param name long name of the option
701  * @param argumentHelp help text for the option argument
702  * @param description long help text for the option
703  * @param[out] val set to the time specified at the command line
704  */
705 struct GNUNET_GETOPT_CommandLineOption
706 GNUNET_GETOPT_option_absolute_time (char shortName,
707                                     const char *name,
708                                     const char *argumentHelp,
709                                     const char *description,
710                                     struct GNUNET_TIME_Absolute *val)
711 {
712   struct GNUNET_GETOPT_CommandLineOption clo = {
713     .shortName =  shortName,
714     .name = name,
715     .argumentHelp = argumentHelp,
716     .description = description,
717     .require_argument = 1,
718     .processor = &set_absolute_time,
719     .scls = (void *) val
720   };
721
722   return clo;
723 }
724
725
726 /**
727  * Set an option of type 'unsigned int' from the command line.
728  * A pointer to this function should be passed as part of the
729  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
730  * of this type.  It should be followed by a pointer to a value of
731  * type 'unsigned int'.
732  *
733  * @param ctx command line processing context
734  * @param scls additional closure (will point to the 'unsigned int')
735  * @param option name of the option
736  * @param value actual value of the option as a string.
737  * @return #GNUNET_OK if parsing the value worked
738  */
739 static int
740 set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
741           void *scls,
742           const char *option,
743           const char *value)
744 {
745   unsigned int *val = scls;
746
747   (void) ctx;
748   if (1 != SSCANF (value,
749                    "%u",
750                    val))
751   {
752     FPRINTF (stderr,
753              _("You must pass a number to the `%s' option.\n"),
754              option);
755     return GNUNET_SYSERR;
756   }
757   return GNUNET_OK;
758 }
759
760
761 /**
762  * Allow user to specify an unsigned integer.
763  *
764  * @param shortName short name of the option
765  * @param name long name of the option
766  * @param argumentHelp help text for the option argument
767  * @param description long help text for the option
768  * @param[out] val set to the value specified at the command line
769  */
770 struct GNUNET_GETOPT_CommandLineOption
771 GNUNET_GETOPT_option_uint (char shortName,
772                            const char *name,
773                            const char *argumentHelp,
774                            const char *description,
775                            unsigned int *val)
776 {
777   struct GNUNET_GETOPT_CommandLineOption clo = {
778     .shortName =  shortName,
779     .name = name,
780     .argumentHelp = argumentHelp,
781     .description = description,
782     .require_argument = 1,
783     .processor = &set_uint,
784     .scls = (void *) val
785   };
786
787   return clo;
788 }
789
790
791
792 /**
793  * Set an option of type 'uint16_t' from the command line.
794  * A pointer to this function should be passed as part of the
795  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
796  * of this type.  It should be followed by a pointer to a value of
797  * type 'uint16_t'.
798  *
799  * @param ctx command line processing context
800  * @param scls additional closure (will point to the 'unsigned int')
801  * @param option name of the option
802  * @param value actual value of the option as a string.
803  * @return #GNUNET_OK if parsing the value worked
804  */
805 static int
806 set_uint16 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
807             void *scls,
808             const char *option,
809             const char *value)
810 {
811   uint16_t *val = scls;
812   unsigned int v;
813   
814   (void) ctx;
815   if (1 != SSCANF (value,
816                    "%u",
817                    &v))
818   {
819     FPRINTF (stderr,
820              _("You must pass a number to the `%s' option.\n"),
821              option);
822     return GNUNET_SYSERR;
823   }
824   if (v > UINT16_MAX)
825   {
826     FPRINTF (stderr,
827              _("You must pass a number below %u to the `%s' option.\n"),
828              (unsigned int) UINT16_MAX,
829              option);
830     return GNUNET_SYSERR;
831   }
832   *val = (uint16_t) v;
833   return GNUNET_OK;
834 }
835
836
837 /**
838  * Allow user to specify an uint16_t.
839  *
840  * @param shortName short name of the option
841  * @param name long name of the option
842  * @param argumentHelp help text for the option argument
843  * @param description long help text for the option
844  * @param[out] val set to the value specified at the command line
845  */
846 struct GNUNET_GETOPT_CommandLineOption
847 GNUNET_GETOPT_option_uint16 (char shortName,
848                              const char *name,
849                              const char *argumentHelp,
850                              const char *description,
851                              uint16_t *val)
852 {
853   struct GNUNET_GETOPT_CommandLineOption clo = {
854     .shortName =  shortName,
855     .name = name,
856     .argumentHelp = argumentHelp,
857     .description = description,
858     .require_argument = 1,
859     .processor = &set_uint16,
860     .scls = (void *) val
861   };
862
863   return clo;
864 }
865
866
867 /**
868  * Closure for #set_base32().
869  */
870 struct Base32Context
871 {
872   /**
873    * Value to initialize (already allocated)
874    */
875   void *val;
876
877   /**
878    * Number of bytes expected for @e val.
879    */
880   size_t val_size;
881 };
882
883
884 /**
885  * Set an option of type 'unsigned int' from the command line.
886  * A pointer to this function should be passed as part of the
887  * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
888  * of this type.  It should be followed by a pointer to a value of
889  * type 'unsigned int'.
890  *
891  * @param ctx command line processing context
892  * @param scls additional closure (will point to the 'unsigned int')
893  * @param option name of the option
894  * @param value actual value of the option as a string.
895  * @return #GNUNET_OK if parsing the value worked
896  */
897 static int
898 set_base32 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
899             void *scls,
900             const char *option,
901             const char *value)
902 {
903   struct Base32Context *bc = scls;
904
905   (void) ctx;
906   if (GNUNET_OK !=
907       GNUNET_STRINGS_string_to_data (value,
908                                      strlen (value),
909                                      bc->val,
910                                      bc->val_size))
911   {
912     fprintf (stderr,
913              _("Argument `%s' malformed. Expected base32 (Crockford) encoded value.\n"),
914              option);
915     return GNUNET_SYSERR;
916   }
917   return GNUNET_OK;
918 }
919
920
921 /**
922  * Helper function to clean up after
923  * #GNUNET_GETOPT_option_base32_fixed_size.
924  *
925  * @param cls value to GNUNET_free()
926  */
927 static void
928 free_bc (void *cls)
929 {
930   GNUNET_free (cls);
931 }
932
933
934 /**
935  * Allow user to specify a binary value using Crockford
936  * Base32 encoding.
937  *
938  * @param shortName short name of the option
939  * @param name long name of the option
940  * @param argumentHelp help text for the option argument
941  * @param description long help text for the option
942  * @param[out] val binary value decoded from Crockford Base32-encoded argument
943  * @param val_size size of @a val in bytes
944  */
945 struct GNUNET_GETOPT_CommandLineOption
946 GNUNET_GETOPT_option_base32_fixed_size (char shortName,
947                                             const char *name,
948                                             const char *argumentHelp,
949                                             const char *description,
950                                             void *val,
951                                             size_t val_size)
952 {
953   struct Base32Context *bc = GNUNET_new (struct Base32Context);
954   struct GNUNET_GETOPT_CommandLineOption clo = {
955     .shortName =  shortName,
956     .name = name,
957     .argumentHelp = argumentHelp,
958     .description = description,
959     .require_argument = 1,
960     .processor = &set_base32,
961     .cleaner = &free_bc,
962     .scls = (void *) bc
963   };
964
965   bc->val = val;
966   bc->val_size = val_size;
967   return clo;
968 }
969
970
971 /**
972  * Make the given option mandatory.
973  *
974  * @param opt option to modify
975  * @return @a opt with the mandatory flag set.
976  */
977 struct GNUNET_GETOPT_CommandLineOption
978 GNUNET_GETOPT_option_mandatory (struct GNUNET_GETOPT_CommandLineOption opt)
979 {
980   opt.option_mandatory = 1;
981   return opt;
982 }
983
984
985 /* end of getopt_helpers.c */