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