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.
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/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
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;
51 printf ("%s v%s\n", ctx->binaryName, version);
57 * Define the option to print the version of
58 * the application (-v option)
60 * @param version string with the version number
62 struct GNUNET_GETOPT_CommandLineOption
63 GNUNET_GETOPT_option_version (const char *version)
65 struct GNUNET_GETOPT_CommandLineOption clo = {.shortName = 'v',
67 .description = gettext_noop (
68 "print the version number"),
69 .option_exclusive = 1,
70 .processor = &print_version,
71 .scls = (void *) version};
77 * At what offset does the help text start?
82 * Print out details on command line options (implements --help).
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)
91 format_help (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
96 const char *about = scls;
104 const struct GNUNET_GETOPT_CommandLineOption *opt;
105 const struct GNUNET_OS_ProjectData *pd;
111 printf ("%s\n%s\n", ctx->binaryOptions, gettext (about));
113 "Arguments mandatory for long options are also mandatory for short options.\n"));
116 opt = ctx->allOptions;
117 while (NULL != opt[i].description)
119 if (opt[i].shortName == '\0')
122 printf (" -%c, ", opt[i].shortName);
123 printf ("--%s", opt[i].name);
124 slen = 8 + strlen (opt[i].name);
125 if (NULL != opt[i].argumentHelp)
127 printf ("=%s", opt[i].argumentHelp);
128 slen += 1 + strlen (opt[i].argumentHelp);
132 printf ("\n%*s", BORDER, "");
137 printf ("%*s", (int) (BORDER - slen), "");
140 if (0 < strlen (opt[i].description))
141 trans = gettext (opt[i].description);
147 while (ml - p > 78 - slen)
149 for (j = p + 78 - slen; j > (int) p; j--)
151 if (isspace ((unsigned char) trans[j]))
153 scp = GNUNET_malloc (j - p + 1);
154 GNUNET_memcpy (scp, &trans[p], j - p);
156 printf ("%s\n%*s", scp, BORDER + 2, "");
163 /* could not find space to break line */
164 scp = GNUNET_malloc (78 - slen + 1);
165 GNUNET_memcpy (scp, &trans[p], 78 - slen);
166 scp[78 - slen] = '\0';
167 printf ("%s\n%*s", scp, BORDER + 2, "");
174 printf ("%s\n", &trans[p]);
175 if (strlen (trans) == 0)
179 pd = GNUNET_OS_project_data_get ();
180 printf ("Report bugs to %s.\n"
186 printf ("General help using GNU software: http://www.gnu.org/gethelp/\n");
193 * Defining the option to print the command line
194 * help text (-h option).
196 * @param about string with brief description of the application
198 struct GNUNET_GETOPT_CommandLineOption
199 GNUNET_GETOPT_option_help (const char *about)
201 struct GNUNET_GETOPT_CommandLineOption clo = {.shortName = 'h',
203 .description = gettext_noop (
205 .option_exclusive = 1,
206 .processor = format_help,
207 .scls = (void *) about};
214 * Set an option of type 'unsigned int' from the command line. Each
215 * time the option flag is given, the value is incremented by one.
216 * A pointer to this function should be passed as part of the
217 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
218 * of this type. It should be followed by a pointer to a value of
221 * @param ctx command line processing context
222 * @param scls additional closure (will point to the 'unsigned int')
223 * @param option name of the option
224 * @param value not used (NULL)
228 increment_value (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
233 unsigned int *val = scls;
244 * Increment @a val each time the option flag is given by one.
246 * @param shortName short name of the option
247 * @param name long name of the option
248 * @param argumentHelp help text for the option argument
249 * @param description long help text for the option
250 * @param[out] val increment by 1 each time the option is present
252 struct GNUNET_GETOPT_CommandLineOption
253 GNUNET_GETOPT_option_increment_uint (char shortName,
255 const char *description,
258 struct GNUNET_GETOPT_CommandLineOption clo = {.shortName = shortName,
260 .description = description,
261 .processor = &increment_value,
262 .scls = (void *) val};
269 * Define the '-V' verbosity option. Using the option more
270 * than once increments @a level each time.
272 * @param[out] level set to the verbosity level
274 struct GNUNET_GETOPT_CommandLineOption
275 GNUNET_GETOPT_option_verbose (unsigned int *level)
277 struct GNUNET_GETOPT_CommandLineOption clo = {.shortName = 'V',
280 gettext_noop ("be verbose"),
281 .processor = &increment_value,
282 .scls = (void *) level};
289 * Set an option of type 'int' from the command line to 1 if the
290 * given option is present.
291 * A pointer to this function should be passed as part of the
292 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
293 * of this type. It should be followed by a pointer to a value of
296 * @param ctx command line processing context
297 * @param scls additional closure (will point to the 'int')
298 * @param option name of the option
299 * @param value not used (NULL)
303 set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
319 * Allow user to specify a flag (which internally means setting
320 * an integer to 1/#GNUNET_YES/#GNUNET_OK.
322 * @param shortName short name of the option
323 * @param name long name of the option
324 * @param argumentHelp help text for the option argument
325 * @param description long help text for the option
326 * @param[out] val set to 1 if the option is present
328 struct GNUNET_GETOPT_CommandLineOption
329 GNUNET_GETOPT_option_flag (char shortName,
331 const char *description,
334 struct GNUNET_GETOPT_CommandLineOption clo = {.shortName = shortName,
336 .description = description,
337 .processor = &set_one,
338 .scls = (void *) val};
345 * Set an option of type 'char *' from the command line.
346 * A pointer to this function should be passed as part of the
347 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
348 * of this type. It should be followed by a pointer to a value of
349 * type 'char *', which will be allocated with the requested string.
351 * @param ctx command line processing context
352 * @param scls additional closure (will point to the 'char *',
353 * which will be allocated)
354 * @param option name of the option
355 * @param value actual value of the option (a string)
359 set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
368 GNUNET_assert (NULL != value);
369 GNUNET_free_non_null (*val);
370 *val = GNUNET_strdup (value);
376 * Allow user to specify a string.
378 * @param shortName short name of the option
379 * @param name long name of the option
380 * @param argumentHelp help text for the option argument
381 * @param description long help text for the option
382 * @param[out] str set to the string
384 struct GNUNET_GETOPT_CommandLineOption
385 GNUNET_GETOPT_option_string (char shortName,
387 const char *argumentHelp,
388 const char *description,
391 struct GNUNET_GETOPT_CommandLineOption clo = {.shortName = shortName,
393 .argumentHelp = argumentHelp,
394 .description = description,
395 .require_argument = 1,
396 .processor = &set_string,
397 .scls = (void *) str};
404 * Define the '-L' log level option. Note that we do not check
405 * that the log level is valid here.
407 * @param[out] level set to the log level
409 struct GNUNET_GETOPT_CommandLineOption
410 GNUNET_GETOPT_option_loglevel (char **level)
412 struct GNUNET_GETOPT_CommandLineOption clo =
415 .argumentHelp = "LOGLEVEL",
416 .description = gettext_noop ("configure logging to use LOGLEVEL"),
417 .require_argument = 1,
418 .processor = &set_string,
419 .scls = (void *) level};
426 * Set an option of type 'char *' from the command line with
427 * filename expansion a la #GNUNET_STRINGS_filename_expand().
429 * @param ctx command line processing context
430 * @param scls additional closure (will point to the `char *`,
431 * which will be allocated)
432 * @param option name of the option
433 * @param value actual value of the option (a string)
437 set_filename (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
446 GNUNET_assert (NULL != value);
447 GNUNET_free_non_null (*val);
448 *val = GNUNET_STRINGS_filename_expand (value);
454 * Allow user to specify a filename (automatically path expanded).
456 * @param shortName short name of the option
457 * @param name long name of the option
458 * @param argumentHelp help text for the option argument
459 * @param description long help text for the option
460 * @param[out] str set to the string
462 struct GNUNET_GETOPT_CommandLineOption
463 GNUNET_GETOPT_option_filename (char shortName,
465 const char *argumentHelp,
466 const char *description,
469 struct GNUNET_GETOPT_CommandLineOption clo = {.shortName = shortName,
471 .argumentHelp = argumentHelp,
472 .description = description,
473 .require_argument = 1,
474 .processor = &set_filename,
475 .scls = (void *) str};
482 * Allow user to specify log file name (-l option)
484 * @param[out] logfn set to the name of the logfile
486 struct GNUNET_GETOPT_CommandLineOption
487 GNUNET_GETOPT_option_logfile (char **logfn)
489 struct GNUNET_GETOPT_CommandLineOption clo =
492 .argumentHelp = "FILENAME",
494 gettext_noop ("configure logging to write logs to FILENAME"),
495 .require_argument = 1,
496 .processor = &set_filename,
497 .scls = (void *) logfn};
504 * Allow user to specify configuration file name (-c option)
506 * @param[out] fn set to the name of the configuration file
508 struct GNUNET_GETOPT_CommandLineOption
509 GNUNET_GETOPT_option_cfgfile (char **fn)
511 struct GNUNET_GETOPT_CommandLineOption clo =
514 .argumentHelp = "FILENAME",
515 .description = gettext_noop ("use configuration file FILENAME"),
516 .require_argument = 1,
517 .processor = &set_filename,
518 .scls = (void *) fn};
525 * Set an option of type 'unsigned long long' from the command line.
526 * A pointer to this function should be passed as part of the
527 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
528 * of this type. It should be followed by a pointer to a value of
529 * type 'unsigned long long'.
531 * @param ctx command line processing context
532 * @param scls additional closure (will point to the 'unsigned long long')
533 * @param option name of the option
534 * @param value actual value of the option as a string.
535 * @return #GNUNET_OK if parsing the value worked
538 set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
543 unsigned long long *val = scls;
547 if (1 != SSCANF (value, "%llu%1s", val, dummy))
550 _ ("You must pass a number to the `%s' option.\n"),
552 return GNUNET_SYSERR;
559 * Allow user to specify an `unsigned long long`
561 * @param shortName short name of the option
562 * @param name long name of the option
563 * @param argumentHelp help text for the option argument
564 * @param description long help text for the option
565 * @param[out] val set to the value specified at the command line
567 struct GNUNET_GETOPT_CommandLineOption
568 GNUNET_GETOPT_option_ulong (char shortName,
570 const char *argumentHelp,
571 const char *description,
572 unsigned long long *val)
574 struct GNUNET_GETOPT_CommandLineOption clo = {.shortName = shortName,
576 .argumentHelp = argumentHelp,
577 .description = description,
578 .require_argument = 1,
579 .processor = &set_ulong,
580 .scls = (void *) val};
587 * Set an option of type 'struct GNUNET_TIME_Relative' from the command line.
588 * A pointer to this function should be passed as part of the
589 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
590 * of this type. It should be followed by a pointer to a value of
591 * type 'struct GNUNET_TIME_Relative'.
593 * @param ctx command line processing context
594 * @param scls additional closure (will point to the 'struct GNUNET_TIME_Relative')
595 * @param option name of the option
596 * @param value actual value of the option as a string.
597 * @return #GNUNET_OK if parsing the value worked
600 set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
605 struct GNUNET_TIME_Relative *val = scls;
608 if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_relative (value, val))
611 _ ("You must pass relative time to the `%s' option.\n"),
613 return GNUNET_SYSERR;
620 * Allow user to specify a `struct GNUNET_TIME_Relative`
621 * (using human-readable "fancy" time).
623 * @param shortName short name of the option
624 * @param name long name of the option
625 * @param argumentHelp help text for the option argument
626 * @param description long help text for the option
627 * @param[out] val set to the time specified at the command line
629 struct GNUNET_GETOPT_CommandLineOption
630 GNUNET_GETOPT_option_relative_time (char shortName,
632 const char *argumentHelp,
633 const char *description,
634 struct GNUNET_TIME_Relative *val)
636 struct GNUNET_GETOPT_CommandLineOption clo = {.shortName = shortName,
638 .argumentHelp = argumentHelp,
639 .description = description,
640 .require_argument = 1,
641 .processor = &set_relative_time,
642 .scls = (void *) val};
649 * Set an option of type 'struct GNUNET_TIME_Absolute' from the command line.
650 * A pointer to this function should be passed as part of the
651 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
652 * of this type. It should be followed by a pointer to a value of
653 * type 'struct GNUNET_TIME_Absolute'.
655 * @param ctx command line processing context
656 * @param scls additional closure (will point to the `struct GNUNET_TIME_Absolute`)
657 * @param option name of the option
658 * @param value actual value of the option as a string.
659 * @return #GNUNET_OK if parsing the value worked
662 set_absolute_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
667 struct GNUNET_TIME_Absolute *val = scls;
670 if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_absolute (value, val))
673 _ ("You must pass absolute time to the `%s' option.\n"),
675 return GNUNET_SYSERR;
682 * Allow user to specify a `struct GNUNET_TIME_Absolute`
683 * (using human-readable "fancy" time).
685 * @param shortName short name of the option
686 * @param name long name of the option
687 * @param argumentHelp help text for the option argument
688 * @param description long help text for the option
689 * @param[out] val set to the time specified at the command line
691 struct GNUNET_GETOPT_CommandLineOption
692 GNUNET_GETOPT_option_absolute_time (char shortName,
694 const char *argumentHelp,
695 const char *description,
696 struct GNUNET_TIME_Absolute *val)
698 struct GNUNET_GETOPT_CommandLineOption clo = {.shortName = shortName,
700 .argumentHelp = argumentHelp,
701 .description = description,
702 .require_argument = 1,
703 .processor = &set_absolute_time,
704 .scls = (void *) val};
711 * Set an option of type 'unsigned int' from the command line.
712 * A pointer to this function should be passed as part of the
713 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
714 * of this type. It should be followed by a pointer to a value of
715 * type 'unsigned int'.
717 * @param ctx command line processing context
718 * @param scls additional closure (will point to the 'unsigned int')
719 * @param option name of the option
720 * @param value actual value of the option as a string.
721 * @return #GNUNET_OK if parsing the value worked
724 set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
729 unsigned int *val = scls;
737 "Your input for the '%s' option has to be a non negative number \n"),
739 return GNUNET_SYSERR;
741 if (1 != SSCANF (value, "%u%1s", val, dummy))
744 _ ("You must pass a number to the `%s' option.\n"),
746 return GNUNET_SYSERR;
753 * Allow user to specify an unsigned integer.
755 * @param shortName short name of the option
756 * @param name long name of the option
757 * @param argumentHelp help text for the option argument
758 * @param description long help text for the option
759 * @param[out] val set to the value specified at the command line
761 struct GNUNET_GETOPT_CommandLineOption
762 GNUNET_GETOPT_option_uint (char shortName,
764 const char *argumentHelp,
765 const char *description,
768 struct GNUNET_GETOPT_CommandLineOption clo = {.shortName = shortName,
770 .argumentHelp = argumentHelp,
771 .description = description,
772 .require_argument = 1,
773 .processor = &set_uint,
774 .scls = (void *) val};
781 * Set an option of type 'uint16_t' from the command line.
782 * A pointer to this function should be passed as part of the
783 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
784 * of this type. It should be followed by a pointer to a value of
787 * @param ctx command line processing context
788 * @param scls additional closure (will point to the 'unsigned int')
789 * @param option name of the option
790 * @param value actual value of the option as a string.
791 * @return #GNUNET_OK if parsing the value worked
794 set_uint16 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
799 uint16_t *val = scls;
804 if (1 != SSCANF (value, "%u%1s", &v, dummy))
807 _ ("You must pass a number to the `%s' option.\n"),
809 return GNUNET_SYSERR;
814 _ ("You must pass a number below %u to the `%s' option.\n"),
815 (unsigned int) UINT16_MAX,
817 return GNUNET_SYSERR;
825 * Allow user to specify an uint16_t.
827 * @param shortName short name of the option
828 * @param name long name of the option
829 * @param argumentHelp help text for the option argument
830 * @param description long help text for the option
831 * @param[out] val set to the value specified at the command line
833 struct GNUNET_GETOPT_CommandLineOption
834 GNUNET_GETOPT_option_uint16 (char shortName,
836 const char *argumentHelp,
837 const char *description,
840 struct GNUNET_GETOPT_CommandLineOption clo = {.shortName = shortName,
842 .argumentHelp = argumentHelp,
843 .description = description,
844 .require_argument = 1,
845 .processor = &set_uint16,
846 .scls = (void *) val};
853 * Closure for #set_base32().
858 * Value to initialize (already allocated)
863 * Number of bytes expected for @e val.
870 * Set an option of type 'unsigned int' from the command line.
871 * A pointer to this function should be passed as part of the
872 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
873 * of this type. It should be followed by a pointer to a value of
874 * type 'unsigned int'.
876 * @param ctx command line processing context
877 * @param scls additional closure (will point to the 'unsigned int')
878 * @param option name of the option
879 * @param value actual value of the option as a string.
880 * @return #GNUNET_OK if parsing the value worked
883 set_base32 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
888 struct Base32Context *bc = scls;
891 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (value,
899 "Argument `%s' malformed. Expected base32 (Crockford) encoded value.\n"),
901 return GNUNET_SYSERR;
908 * Helper function to clean up after
909 * #GNUNET_GETOPT_option_base32_fixed_size.
911 * @param cls value to GNUNET_free()
921 * Allow user to specify a binary value using Crockford
924 * @param shortName short name of the option
925 * @param name long name of the option
926 * @param argumentHelp help text for the option argument
927 * @param description long help text for the option
928 * @param[out] val binary value decoded from Crockford Base32-encoded argument
929 * @param val_size size of @a val in bytes
931 struct GNUNET_GETOPT_CommandLineOption
932 GNUNET_GETOPT_option_base32_fixed_size (char shortName,
934 const char *argumentHelp,
935 const char *description,
939 struct Base32Context *bc = GNUNET_new (struct Base32Context);
940 struct GNUNET_GETOPT_CommandLineOption clo = {.shortName = shortName,
942 .argumentHelp = argumentHelp,
943 .description = description,
944 .require_argument = 1,
945 .processor = &set_base32,
947 .scls = (void *) bc};
950 bc->val_size = val_size;
956 * Make the given option mandatory.
958 * @param opt option to modify
959 * @return @a opt with the mandatory flag set.
961 struct GNUNET_GETOPT_CommandLineOption
962 GNUNET_GETOPT_option_mandatory (struct GNUNET_GETOPT_CommandLineOption opt)
964 opt.option_mandatory = 1;
970 * Make the given option mutually exclusive with other options.
972 * @param opt option to modify
973 * @return @a opt with the exclusive flag set.
975 struct GNUNET_GETOPT_CommandLineOption
976 GNUNET_GETOPT_option_exclusive (struct GNUNET_GETOPT_CommandLineOption opt)
978 opt.option_exclusive = 1;
983 /* end of getopt_helpers.c */