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 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.
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.
17 * @file src/util/getopt_helpers.c
18 * @brief implements command line that sets option
19 * @author Christian Grothoff
22 #include "gnunet_util_lib.h"
24 #define LOG(kind,...) GNUNET_log_from (kind, "util-getopt", __VA_ARGS__)
28 * Print out program version (implements --version).
30 * @param ctx command line processing context
31 * @param scls additional closure (points to version string)
32 * @param option name of the option
33 * @param value not used (NULL)
34 * @return #GNUNET_NO (do not continue, not an error)
37 print_version (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
42 const char *version = scls;
54 * Define the option to print the version of
55 * the application (-v option)
57 * @param version string with the version number
59 struct GNUNET_GETOPT_CommandLineOption
60 GNUNET_GETOPT_option_version (const char *version)
62 struct GNUNET_GETOPT_CommandLineOption clo = {
65 .description = gettext_noop("print the version number"),
66 .processor = &print_version,
67 .scls = (void *) version
74 * At what offset does the help text start?
79 * Print out details on command line options (implements --help).
81 * @param ctx command line processing context
82 * @param scls additional closure (points to about text)
83 * @param option name of the option
84 * @param value not used (NULL)
85 * @return #GNUNET_NO (do not continue, not an error)
88 format_help (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
93 const char *about = scls;
101 const struct GNUNET_GETOPT_CommandLineOption *opt;
102 const struct GNUNET_OS_ProjectData *pd;
108 printf ("%s\n%s\n", ctx->binaryOptions, gettext (about));
110 ("Arguments mandatory for long options are also mandatory for short options.\n"));
113 opt = ctx->allOptions;
114 while (NULL != opt[i].description)
116 if (opt[i].shortName == '\0')
119 printf (" -%c, ", opt[i].shortName);
120 printf ("--%s", opt[i].name);
121 slen = 8 + strlen (opt[i].name);
122 if (NULL != opt[i].argumentHelp)
124 printf ("=%s", opt[i].argumentHelp);
125 slen += 1 + strlen (opt[i].argumentHelp);
129 printf ("\n%*s", BORDER, "");
134 printf ("%*s", (int) (BORDER - slen), "");
137 if (0 < strlen (opt[i].description))
138 trans = gettext (opt[i].description);
144 while (ml - p > 78 - slen)
146 for (j = p + 78 - slen; j > (int) p; j--)
148 if (isspace ((unsigned char) trans[j]))
150 scp = GNUNET_malloc (j - p + 1);
151 GNUNET_memcpy (scp, &trans[p], j - p);
153 printf ("%s\n%*s", scp, BORDER + 2, "");
160 /* could not find space to break line */
161 scp = GNUNET_malloc (78 - slen + 1);
162 GNUNET_memcpy (scp, &trans[p], 78 - slen);
163 scp[78 - slen] = '\0';
164 printf ("%s\n%*s", scp, BORDER + 2, "");
171 printf ("%s\n", &trans[p]);
172 if (strlen (trans) == 0)
176 pd = GNUNET_OS_project_data_get ();
177 printf ("Report bugs to %s.\n"
178 "GNUnet home page: %s\n"
179 "General help using GNU software: http://www.gnu.org/gethelp/\n",
187 * Defining the option to print the command line
188 * help text (-h option).
190 * @param about string with brief description of the application
192 struct GNUNET_GETOPT_CommandLineOption
193 GNUNET_GETOPT_option_help (const char *about)
195 struct GNUNET_GETOPT_CommandLineOption clo = {
198 .description = gettext_noop("print this help"),
199 .processor = format_help,
200 .scls = (void *) about
208 * Set an option of type 'unsigned int' from the command line. Each
209 * time the option flag is given, the value is incremented by one.
210 * A pointer to this function should be passed as part of the
211 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
212 * of this type. It should be followed by a pointer to a value of
215 * @param ctx command line processing context
216 * @param scls additional closure (will point to the 'unsigned int')
217 * @param option name of the option
218 * @param value not used (NULL)
222 increment_value (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
227 unsigned int *val = scls;
238 * Increment @a val each time the option flag is given by one.
240 * @param shortName short name of the option
241 * @param name long name of the option
242 * @param argumentHelp help text for the option argument
243 * @param description long help text for the option
244 * @param[out] val increment by 1 each time the option is present
246 struct GNUNET_GETOPT_CommandLineOption
247 GNUNET_GETOPT_option_increment_uint (char shortName,
249 const char *description,
252 struct GNUNET_GETOPT_CommandLineOption clo = {
253 .shortName = shortName,
255 .description = description,
256 .processor = &increment_value,
265 * Define the '-V' verbosity option. Using the option more
266 * than once increments @a level each time.
268 * @param[out] level set to the verbosity level
270 struct GNUNET_GETOPT_CommandLineOption
271 GNUNET_GETOPT_option_verbose (unsigned int *level)
273 struct GNUNET_GETOPT_CommandLineOption clo = {
276 .description = gettext_noop("be verbose"),
277 .processor = &increment_value,
278 .scls = (void *) level
286 * Set an option of type 'int' from the command line to 1 if the
287 * given option is present.
288 * A pointer to this function should be passed as part of the
289 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
290 * of this type. It should be followed by a pointer to a value of
293 * @param ctx command line processing context
294 * @param scls additional closure (will point to the 'int')
295 * @param option name of the option
296 * @param value not used (NULL)
300 set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
316 * Allow user to specify a flag (which internally means setting
317 * an integer to 1/#GNUNET_YES/#GNUNET_OK.
319 * @param shortName short name of the option
320 * @param name long name of the option
321 * @param argumentHelp help text for the option argument
322 * @param description long help text for the option
323 * @param[out] val set to 1 if the option is present
325 struct GNUNET_GETOPT_CommandLineOption
326 GNUNET_GETOPT_option_flag (char shortName,
328 const char *description,
331 struct GNUNET_GETOPT_CommandLineOption clo = {
332 .shortName = shortName,
334 .description = description,
335 .processor = &set_one,
344 * Set an option of type 'char *' from the command line.
345 * A pointer to this function should be passed as part of the
346 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
347 * of this type. It should be followed by a pointer to a value of
348 * type 'char *', which will be allocated with the requested string.
350 * @param ctx command line processing context
351 * @param scls additional closure (will point to the 'char *',
352 * which will be allocated)
353 * @param option name of the option
354 * @param value actual value of the option (a string)
358 set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
367 GNUNET_assert (NULL != value);
368 GNUNET_free_non_null (*val);
369 *val = GNUNET_strdup (value);
375 * Allow user to specify a string.
377 * @param shortName short name of the option
378 * @param name long name of the option
379 * @param argumentHelp help text for the option argument
380 * @param description long help text for the option
381 * @param[out] str set to the string
383 struct GNUNET_GETOPT_CommandLineOption
384 GNUNET_GETOPT_option_string (char shortName,
386 const char *argumentHelp,
387 const char *description,
390 struct GNUNET_GETOPT_CommandLineOption clo = {
391 .shortName = shortName,
393 .argumentHelp = argumentHelp,
394 .description = description,
395 .require_argument = 1,
396 .processor = &set_string,
405 * Define the '-L' log level option. Note that we do not check
406 * that the log level is valid here.
408 * @param[out] level set to the log level
410 struct GNUNET_GETOPT_CommandLineOption
411 GNUNET_GETOPT_option_loglevel (char **level)
413 struct GNUNET_GETOPT_CommandLineOption clo = {
416 .argumentHelp = "LOGLEVEL",
417 .description = gettext_noop("configure logging to use LOGLEVEL"),
418 .require_argument = 1,
419 .processor = &set_string,
420 .scls = (void *) level
428 * Set an option of type 'char *' from the command line with
429 * filename expansion a la #GNUNET_STRINGS_filename_expand().
431 * @param ctx command line processing context
432 * @param scls additional closure (will point to the `char *`,
433 * which will be allocated)
434 * @param option name of the option
435 * @param value actual value of the option (a string)
439 set_filename (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
448 GNUNET_assert (NULL != value);
449 GNUNET_free_non_null (*val);
450 *val = GNUNET_STRINGS_filename_expand (value);
456 * Allow user to specify a filename (automatically path expanded).
458 * @param shortName short name of the option
459 * @param name long name of the option
460 * @param argumentHelp help text for the option argument
461 * @param description long help text for the option
462 * @param[out] str set to the string
464 struct GNUNET_GETOPT_CommandLineOption
465 GNUNET_GETOPT_option_filename (char shortName,
467 const char *argumentHelp,
468 const char *description,
471 struct GNUNET_GETOPT_CommandLineOption clo = {
472 .shortName = shortName,
474 .argumentHelp = argumentHelp,
475 .description = description,
476 .require_argument = 1,
477 .processor = &set_filename,
486 * Allow user to specify log file name (-l option)
488 * @param[out] logfn set to the name of the logfile
490 struct GNUNET_GETOPT_CommandLineOption
491 GNUNET_GETOPT_option_logfile (char **logfn)
493 struct GNUNET_GETOPT_CommandLineOption clo = {
496 .argumentHelp = "FILENAME",
497 .description = gettext_noop ("configure logging to write logs to FILENAME"),
498 .require_argument = 1,
499 .processor = &set_filename,
500 .scls = (void *) logfn
508 * Allow user to specify configuration file name (-c option)
510 * @param[out] fn set to the name of the configuration file
512 struct GNUNET_GETOPT_CommandLineOption
513 GNUNET_GETOPT_option_cfgfile (char **fn)
515 struct GNUNET_GETOPT_CommandLineOption clo = {
518 .argumentHelp = "FILENAME",
519 .description = gettext_noop("use configuration file FILENAME"),
520 .require_argument = 1,
521 .processor = &set_filename,
530 * Set an option of type 'unsigned long long' from the command line.
531 * A pointer to this function should be passed as part of the
532 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
533 * of this type. It should be followed by a pointer to a value of
534 * type 'unsigned long long'.
536 * @param ctx command line processing context
537 * @param scls additional closure (will point to the 'unsigned long long')
538 * @param option name of the option
539 * @param value actual value of the option as a string.
540 * @return #GNUNET_OK if parsing the value worked
543 set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
548 unsigned long long *val = scls;
551 if (1 != SSCANF (value,
556 _("You must pass a number to the `%s' option.\n"),
558 return GNUNET_SYSERR;
565 * Allow user to specify an `unsigned long long`
567 * @param shortName short name of the option
568 * @param name long name of the option
569 * @param argumentHelp help text for the option argument
570 * @param description long help text for the option
571 * @param[out] val set to the value specified at the command line
573 struct GNUNET_GETOPT_CommandLineOption
574 GNUNET_GETOPT_option_ulong (char shortName,
576 const char *argumentHelp,
577 const char *description,
578 unsigned long long *val)
580 struct GNUNET_GETOPT_CommandLineOption clo = {
581 .shortName = shortName,
583 .argumentHelp = argumentHelp,
584 .description = description,
585 .require_argument = 1,
586 .processor = &set_ulong,
595 * Set an option of type 'struct GNUNET_TIME_Relative' from the command line.
596 * A pointer to this function should be passed as part of the
597 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
598 * of this type. It should be followed by a pointer to a value of
599 * type 'struct GNUNET_TIME_Relative'.
601 * @param ctx command line processing context
602 * @param scls additional closure (will point to the 'struct GNUNET_TIME_Relative')
603 * @param option name of the option
604 * @param value actual value of the option as a string.
605 * @return #GNUNET_OK if parsing the value worked
608 set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
613 struct GNUNET_TIME_Relative *val = scls;
617 GNUNET_STRINGS_fancy_time_to_relative (value,
621 _("You must pass relative time to the `%s' option.\n"),
623 return GNUNET_SYSERR;
630 * Allow user to specify a `struct GNUNET_TIME_Relative`
631 * (using human-readable "fancy" time).
633 * @param shortName short name of the option
634 * @param name long name of the option
635 * @param argumentHelp help text for the option argument
636 * @param description long help text for the option
637 * @param[out] val set to the time specified at the command line
639 struct GNUNET_GETOPT_CommandLineOption
640 GNUNET_GETOPT_option_relative_time (char shortName,
642 const char *argumentHelp,
643 const char *description,
644 struct GNUNET_TIME_Relative *val)
646 struct GNUNET_GETOPT_CommandLineOption clo = {
647 .shortName = shortName,
649 .argumentHelp = argumentHelp,
650 .description = description,
651 .require_argument = 1,
652 .processor = &set_relative_time,
661 * Set an option of type 'struct GNUNET_TIME_Absolute' from the command line.
662 * A pointer to this function should be passed as part of the
663 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
664 * of this type. It should be followed by a pointer to a value of
665 * type 'struct GNUNET_TIME_Absolute'.
667 * @param ctx command line processing context
668 * @param scls additional closure (will point to the `struct GNUNET_TIME_Absolute`)
669 * @param option name of the option
670 * @param value actual value of the option as a string.
671 * @return #GNUNET_OK if parsing the value worked
674 set_absolute_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
679 struct GNUNET_TIME_Absolute *val = scls;
683 GNUNET_STRINGS_fancy_time_to_absolute (value,
687 _("You must pass absolute time to the `%s' option.\n"),
689 return GNUNET_SYSERR;
696 * Allow user to specify a `struct GNUNET_TIME_Absolute`
697 * (using human-readable "fancy" time).
699 * @param shortName short name of the option
700 * @param name long name of the option
701 * @param argumentHelp help text for the option argument
702 * @param description long help text for the option
703 * @param[out] val set to the time specified at the command line
705 struct GNUNET_GETOPT_CommandLineOption
706 GNUNET_GETOPT_option_absolute_time (char shortName,
708 const char *argumentHelp,
709 const char *description,
710 struct GNUNET_TIME_Absolute *val)
712 struct GNUNET_GETOPT_CommandLineOption clo = {
713 .shortName = shortName,
715 .argumentHelp = argumentHelp,
716 .description = description,
717 .require_argument = 1,
718 .processor = &set_absolute_time,
727 * Set an option of type 'unsigned int' from the command line.
728 * A pointer to this function should be passed as part of the
729 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
730 * of this type. It should be followed by a pointer to a value of
731 * type 'unsigned int'.
733 * @param ctx command line processing context
734 * @param scls additional closure (will point to the 'unsigned int')
735 * @param option name of the option
736 * @param value actual value of the option as a string.
737 * @return #GNUNET_OK if parsing the value worked
740 set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
745 unsigned int *val = scls;
748 if (1 != SSCANF (value,
753 _("You must pass a number to the `%s' option.\n"),
755 return GNUNET_SYSERR;
762 * Allow user to specify an unsigned integer.
764 * @param shortName short name of the option
765 * @param name long name of the option
766 * @param argumentHelp help text for the option argument
767 * @param description long help text for the option
768 * @param[out] val set to the value specified at the command line
770 struct GNUNET_GETOPT_CommandLineOption
771 GNUNET_GETOPT_option_uint (char shortName,
773 const char *argumentHelp,
774 const char *description,
777 struct GNUNET_GETOPT_CommandLineOption clo = {
778 .shortName = shortName,
780 .argumentHelp = argumentHelp,
781 .description = description,
782 .require_argument = 1,
783 .processor = &set_uint,
793 * Set an option of type 'uint16_t' from the command line.
794 * A pointer to this function should be passed as part of the
795 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
796 * of this type. It should be followed by a pointer to a value of
799 * @param ctx command line processing context
800 * @param scls additional closure (will point to the 'unsigned int')
801 * @param option name of the option
802 * @param value actual value of the option as a string.
803 * @return #GNUNET_OK if parsing the value worked
806 set_uint16 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
811 uint16_t *val = scls;
815 if (1 != SSCANF (value,
820 _("You must pass a number to the `%s' option.\n"),
822 return GNUNET_SYSERR;
827 _("You must pass a number below %u to the `%s' option.\n"),
828 (unsigned int) UINT16_MAX,
830 return GNUNET_SYSERR;
838 * Allow user to specify an uint16_t.
840 * @param shortName short name of the option
841 * @param name long name of the option
842 * @param argumentHelp help text for the option argument
843 * @param description long help text for the option
844 * @param[out] val set to the value specified at the command line
846 struct GNUNET_GETOPT_CommandLineOption
847 GNUNET_GETOPT_option_uint16 (char shortName,
849 const char *argumentHelp,
850 const char *description,
853 struct GNUNET_GETOPT_CommandLineOption clo = {
854 .shortName = shortName,
856 .argumentHelp = argumentHelp,
857 .description = description,
858 .require_argument = 1,
859 .processor = &set_uint16,
868 * Closure for #set_base32().
873 * Value to initialize (already allocated)
878 * Number of bytes expected for @e val.
885 * Set an option of type 'unsigned int' from the command line.
886 * A pointer to this function should be passed as part of the
887 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
888 * of this type. It should be followed by a pointer to a value of
889 * type 'unsigned int'.
891 * @param ctx command line processing context
892 * @param scls additional closure (will point to the 'unsigned int')
893 * @param option name of the option
894 * @param value actual value of the option as a string.
895 * @return #GNUNET_OK if parsing the value worked
898 set_base32 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
903 struct Base32Context *bc = scls;
907 GNUNET_STRINGS_string_to_data (value,
913 _("Argument `%s' malformed. Expected base32 (Crockford) encoded value.\n"),
915 return GNUNET_SYSERR;
922 * Helper function to clean up after
923 * #GNUNET_GETOPT_option_base32_fixed_size.
925 * @param cls value to GNUNET_free()
935 * Allow user to specify a binary value using Crockford
938 * @param shortName short name of the option
939 * @param name long name of the option
940 * @param argumentHelp help text for the option argument
941 * @param description long help text for the option
942 * @param[out] val binary value decoded from Crockford Base32-encoded argument
943 * @param val_size size of @a val in bytes
945 struct GNUNET_GETOPT_CommandLineOption
946 GNUNET_GETOPT_option_base32_fixed_size (char shortName,
948 const char *argumentHelp,
949 const char *description,
953 struct Base32Context *bc = GNUNET_new (struct Base32Context);
954 struct GNUNET_GETOPT_CommandLineOption clo = {
955 .shortName = shortName,
957 .argumentHelp = argumentHelp,
958 .description = description,
959 .require_argument = 1,
960 .processor = &set_base32,
966 bc->val_size = val_size;
972 * Make the given option mandatory.
974 * @param opt option to modify
975 * @return @a opt with the mandatory flag set.
977 struct GNUNET_GETOPT_CommandLineOption
978 GNUNET_GETOPT_option_mandatory (struct GNUNET_GETOPT_CommandLineOption opt)
980 opt.option_mandatory = 1;
985 /* end of getopt_helpers.c */