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