2 This file is part of GNUnet
3 Copyright (C) 2006, 2011 GNUnet e.V.
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.
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.
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.
22 * @file src/util/getopt_helpers.c
23 * @brief implements command line that sets option
24 * @author Christian Grothoff
27 #include "gnunet_util_lib.h"
29 #define LOG(kind,...) GNUNET_log_from (kind, "util-getopt", __VA_ARGS__)
33 * Print out program version (implements --version).
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)
42 print_version (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
47 const char *version = scls;
59 * Define the option to print the version of
60 * the application (-v option)
62 * @param version string with the version number
64 struct GNUNET_GETOPT_CommandLineOption
65 GNUNET_GETOPT_option_version (const char *version)
67 struct GNUNET_GETOPT_CommandLineOption clo = {
70 .description = gettext_noop("print the version number"),
71 .processor = &print_version,
72 .scls = (void *) version
79 * At what offset does the help text start?
84 * Print out details on command line options (implements --help).
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)
93 format_help (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
98 const char *about = scls;
106 const struct GNUNET_GETOPT_CommandLineOption *opt;
107 const struct GNUNET_OS_ProjectData *pd;
113 printf ("%s\n%s\n", ctx->binaryOptions, gettext (about));
115 ("Arguments mandatory for long options are also mandatory for short options.\n"));
118 opt = ctx->allOptions;
119 while (NULL != opt[i].description)
121 if (opt[i].shortName == '\0')
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)
129 printf ("=%s", opt[i].argumentHelp);
130 slen += 1 + strlen (opt[i].argumentHelp);
134 printf ("\n%*s", BORDER, "");
139 printf ("%*s", (int) (BORDER - slen), "");
142 if (0 < strlen (opt[i].description))
143 trans = gettext (opt[i].description);
149 while (ml - p > 78 - slen)
151 for (j = p + 78 - slen; j > (int) p; j--)
153 if (isspace ((unsigned char) trans[j]))
155 scp = GNUNET_malloc (j - p + 1);
156 GNUNET_memcpy (scp, &trans[p], j - p);
158 printf ("%s\n%*s", scp, BORDER + 2, "");
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, "");
176 printf ("%s\n", &trans[p]);
177 if (strlen (trans) == 0)
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",
192 * Defining the option to print the command line
193 * help text (-h option).
195 * @param about string with brief description of the application
197 struct GNUNET_GETOPT_CommandLineOption
198 GNUNET_GETOPT_option_help (const char *about)
200 struct GNUNET_GETOPT_CommandLineOption clo = {
203 .description = gettext_noop("print this help"),
204 .processor = format_help,
205 .scls = (void *) about
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
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)
227 increment_value (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
232 unsigned int *val = scls;
243 * Increment @a val each time the option flag is given by one.
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
251 struct GNUNET_GETOPT_CommandLineOption
252 GNUNET_GETOPT_option_increment_uint (char shortName,
254 const char *description,
257 struct GNUNET_GETOPT_CommandLineOption clo = {
258 .shortName = shortName,
260 .description = description,
261 .processor = &increment_value,
270 * Define the '-V' verbosity option. Using the option more
271 * than once increments @a level each time.
273 * @param[out] level set to the verbosity level
275 struct GNUNET_GETOPT_CommandLineOption
276 GNUNET_GETOPT_option_verbose (unsigned int *level)
278 struct GNUNET_GETOPT_CommandLineOption clo = {
281 .description = gettext_noop("be verbose"),
282 .processor = &increment_value,
283 .scls = (void *) level
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
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)
305 set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
321 * Allow user to specify a flag (which internally means setting
322 * an integer to 1/#GNUNET_YES/#GNUNET_OK.
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
330 struct GNUNET_GETOPT_CommandLineOption
331 GNUNET_GETOPT_option_flag (char shortName,
333 const char *description,
336 struct GNUNET_GETOPT_CommandLineOption clo = {
337 .shortName = shortName,
339 .description = description,
340 .processor = &set_one,
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.
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)
363 set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
372 GNUNET_assert (NULL != value);
373 GNUNET_free_non_null (*val);
374 *val = GNUNET_strdup (value);
380 * Allow user to specify a string.
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
388 struct GNUNET_GETOPT_CommandLineOption
389 GNUNET_GETOPT_option_string (char shortName,
391 const char *argumentHelp,
392 const char *description,
395 struct GNUNET_GETOPT_CommandLineOption clo = {
396 .shortName = shortName,
398 .argumentHelp = argumentHelp,
399 .description = description,
400 .require_argument = 1,
401 .processor = &set_string,
410 * Define the '-L' log level option. Note that we do not check
411 * that the log level is valid here.
413 * @param[out] level set to the log level
415 struct GNUNET_GETOPT_CommandLineOption
416 GNUNET_GETOPT_option_loglevel (char **level)
418 struct GNUNET_GETOPT_CommandLineOption clo = {
421 .argumentHelp = "LOGLEVEL",
422 .description = gettext_noop("configure logging to use LOGLEVEL"),
423 .require_argument = 1,
424 .processor = &set_string,
425 .scls = (void *) level
433 * Set an option of type 'char *' from the command line with
434 * filename expansion a la #GNUNET_STRINGS_filename_expand().
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)
444 set_filename (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
453 GNUNET_assert (NULL != value);
454 GNUNET_free_non_null (*val);
455 *val = GNUNET_STRINGS_filename_expand (value);
461 * Allow user to specify a filename (automatically path expanded).
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
469 struct GNUNET_GETOPT_CommandLineOption
470 GNUNET_GETOPT_option_filename (char shortName,
472 const char *argumentHelp,
473 const char *description,
476 struct GNUNET_GETOPT_CommandLineOption clo = {
477 .shortName = shortName,
479 .argumentHelp = argumentHelp,
480 .description = description,
481 .require_argument = 1,
482 .processor = &set_filename,
491 * Allow user to specify log file name (-l option)
493 * @param[out] logfn set to the name of the logfile
495 struct GNUNET_GETOPT_CommandLineOption
496 GNUNET_GETOPT_option_logfile (char **logfn)
498 struct GNUNET_GETOPT_CommandLineOption clo = {
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
513 * Allow user to specify configuration file name (-c option)
515 * @param[out] fn set to the name of the configuration file
517 struct GNUNET_GETOPT_CommandLineOption
518 GNUNET_GETOPT_option_cfgfile (char **fn)
520 struct GNUNET_GETOPT_CommandLineOption clo = {
523 .argumentHelp = "FILENAME",
524 .description = gettext_noop("use configuration file FILENAME"),
525 .require_argument = 1,
526 .processor = &set_filename,
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'.
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
548 set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
553 unsigned long long *val = scls;
556 if (1 != SSCANF (value,
561 _("You must pass a number to the `%s' option.\n"),
563 return GNUNET_SYSERR;
570 * Allow user to specify an `unsigned long long`
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
578 struct GNUNET_GETOPT_CommandLineOption
579 GNUNET_GETOPT_option_ulong (char shortName,
581 const char *argumentHelp,
582 const char *description,
583 unsigned long long *val)
585 struct GNUNET_GETOPT_CommandLineOption clo = {
586 .shortName = shortName,
588 .argumentHelp = argumentHelp,
589 .description = description,
590 .require_argument = 1,
591 .processor = &set_ulong,
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'.
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
613 set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
618 struct GNUNET_TIME_Relative *val = scls;
622 GNUNET_STRINGS_fancy_time_to_relative (value,
626 _("You must pass relative time to the `%s' option.\n"),
628 return GNUNET_SYSERR;
635 * Allow user to specify a `struct GNUNET_TIME_Relative`
636 * (using human-readable "fancy" time).
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
644 struct GNUNET_GETOPT_CommandLineOption
645 GNUNET_GETOPT_option_relative_time (char shortName,
647 const char *argumentHelp,
648 const char *description,
649 struct GNUNET_TIME_Relative *val)
651 struct GNUNET_GETOPT_CommandLineOption clo = {
652 .shortName = shortName,
654 .argumentHelp = argumentHelp,
655 .description = description,
656 .require_argument = 1,
657 .processor = &set_relative_time,
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'.
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
679 set_absolute_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
684 struct GNUNET_TIME_Absolute *val = scls;
688 GNUNET_STRINGS_fancy_time_to_absolute (value,
692 _("You must pass absolute time to the `%s' option.\n"),
694 return GNUNET_SYSERR;
701 * Allow user to specify a `struct GNUNET_TIME_Absolute`
702 * (using human-readable "fancy" time).
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
710 struct GNUNET_GETOPT_CommandLineOption
711 GNUNET_GETOPT_option_absolute_time (char shortName,
713 const char *argumentHelp,
714 const char *description,
715 struct GNUNET_TIME_Absolute *val)
717 struct GNUNET_GETOPT_CommandLineOption clo = {
718 .shortName = shortName,
720 .argumentHelp = argumentHelp,
721 .description = description,
722 .require_argument = 1,
723 .processor = &set_absolute_time,
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'.
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
745 set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
750 unsigned int *val = scls;
753 if (1 != SSCANF (value,
758 _("You must pass a number to the `%s' option.\n"),
760 return GNUNET_SYSERR;
767 * Allow user to specify an unsigned integer.
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
775 struct GNUNET_GETOPT_CommandLineOption
776 GNUNET_GETOPT_option_uint (char shortName,
778 const char *argumentHelp,
779 const char *description,
782 struct GNUNET_GETOPT_CommandLineOption clo = {
783 .shortName = shortName,
785 .argumentHelp = argumentHelp,
786 .description = description,
787 .require_argument = 1,
788 .processor = &set_uint,
797 * Closure for #set_base32().
802 * Value to initialize (already allocated)
807 * Number of bytes expected for @e val.
814 * Set an option of type 'unsigned int' from the command line.
815 * A pointer to this function should be passed as part of the
816 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
817 * of this type. It should be followed by a pointer to a value of
818 * type 'unsigned int'.
820 * @param ctx command line processing context
821 * @param scls additional closure (will point to the 'unsigned int')
822 * @param option name of the option
823 * @param value actual value of the option as a string.
824 * @return #GNUNET_OK if parsing the value worked
827 set_base32 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
832 struct Base32Context *bc = scls;
836 GNUNET_STRINGS_string_to_data (value,
842 _("Argument `%s' malformed. Expected base32 (Crockford) encoded value.\n"),
844 return GNUNET_SYSERR;
851 * Helper function to clean up after
852 * #GNUNET_GETOPT_option_base32_fixed_size.
854 * @param cls value to GNUNET_free()
864 * Allow user to specify a binary value using Crockford
867 * @param shortName short name of the option
868 * @param name long name of the option
869 * @param argumentHelp help text for the option argument
870 * @param description long help text for the option
871 * @param[out] val binary value decoded from Crockford Base32-encoded argument
872 * @param val_size size of @a val in bytes
874 struct GNUNET_GETOPT_CommandLineOption
875 GNUNET_GETOPT_option_base32_fixed_size (char shortName,
877 const char *argumentHelp,
878 const char *description,
882 struct Base32Context *bc = GNUNET_new (struct Base32Context);
883 struct GNUNET_GETOPT_CommandLineOption clo = {
884 .shortName = shortName,
886 .argumentHelp = argumentHelp,
887 .description = description,
888 .require_argument = 1,
889 .processor = &set_base32,
895 bc->val_size = val_size;
901 * Make the given option mandatory.
903 * @param opt option to modify
904 * @return @a opt with the mandatory flag set.
906 struct GNUNET_GETOPT_CommandLineOption
907 GNUNET_GETOPT_option_mandatory (struct GNUNET_GETOPT_CommandLineOption opt)
909 opt.option_mandatory = 1;
914 /* end of getopt_helpers.c */