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