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