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 };
78 * At what offset does the help text start?
83 * Print out details on command line options (implements --help).
85 * @param ctx command line processing context
86 * @param scls additional closure (points to about text)
87 * @param option name of the option
88 * @param value not used (NULL)
89 * @return #GNUNET_NO (do not continue, not an error)
92 format_help(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
97 const char *about = scls;
105 const struct GNUNET_GETOPT_CommandLineOption *opt;
106 const struct GNUNET_OS_ProjectData *pd;
112 printf("%s\n%s\n", ctx->binaryOptions, gettext(about));
114 "Arguments mandatory for long options are also mandatory for short options.\n"));
117 opt = ctx->allOptions;
118 while (NULL != opt[i].description)
120 if (opt[i].shortName == '\0')
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)
128 printf("=%s", opt[i].argumentHelp);
129 slen += 1 + strlen(opt[i].argumentHelp);
133 printf("\n%*s", BORDER, "");
138 printf("%*s", (int)(BORDER - slen), "");
141 if (0 < strlen(opt[i].description))
142 trans = gettext(opt[i].description);
148 while (ml - p > 78 - slen)
150 for (j = p + 78 - slen; j > (int)p; j--)
152 if (isspace((unsigned char)trans[j]))
154 scp = GNUNET_malloc(j - p + 1);
155 GNUNET_memcpy(scp, &trans[p], j - p);
157 printf("%s\n%*s", scp, BORDER + 2, "");
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, "");
175 printf("%s\n", &trans[p]);
176 if (strlen(trans) == 0)
180 pd = GNUNET_OS_project_data_get();
181 printf("Report bugs to %s.\n"
187 printf("General help using GNU software: http://www.gnu.org/gethelp/\n");
194 * Defining the option to print the command line
195 * help text (-h option).
197 * @param about string with brief description of the application
199 struct GNUNET_GETOPT_CommandLineOption
200 GNUNET_GETOPT_option_help(const char *about)
202 struct GNUNET_GETOPT_CommandLineOption clo = { .shortName = 'h',
204 .description = gettext_noop(
206 .option_exclusive = 1,
207 .processor = format_help,
208 .scls = (void *)about };
215 * Set an option of type 'unsigned int' from the command line. Each
216 * time the option flag is given, the value is incremented by one.
217 * A pointer to this function should be passed as part of the
218 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
219 * of this type. It should be followed by a pointer to a value of
222 * @param ctx command line processing context
223 * @param scls additional closure (will point to the 'unsigned int')
224 * @param option name of the option
225 * @param value not used (NULL)
229 increment_value(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
234 unsigned int *val = scls;
245 * Increment @a val each time the option flag is given by one.
247 * @param shortName short name of the option
248 * @param name long name of the option
249 * @param argumentHelp help text for the option argument
250 * @param description long help text for the option
251 * @param[out] val increment by 1 each time the option is present
253 struct GNUNET_GETOPT_CommandLineOption
254 GNUNET_GETOPT_option_increment_uint(char shortName,
256 const char *description,
259 struct GNUNET_GETOPT_CommandLineOption clo = { .shortName = shortName,
261 .description = description,
262 .processor = &increment_value,
263 .scls = (void *)val };
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 = { .shortName = 'V',
281 gettext_noop("be verbose"),
282 .processor = &increment_value,
283 .scls = (void *)level };
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
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)
304 set_one(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
320 * Allow user to specify a flag (which internally means setting
321 * an integer to 1/#GNUNET_YES/#GNUNET_OK.
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
329 struct GNUNET_GETOPT_CommandLineOption
330 GNUNET_GETOPT_option_flag(char shortName,
332 const char *description,
335 struct GNUNET_GETOPT_CommandLineOption clo = { .shortName = shortName,
337 .description = description,
338 .processor = &set_one,
339 .scls = (void *)val };
346 * Set an option of type 'char *' from the command line.
347 * A pointer to this function should be passed as part of the
348 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
349 * of this type. It should be followed by a pointer to a value of
350 * type 'char *', which will be allocated with the requested string.
352 * @param ctx command line processing context
353 * @param scls additional closure (will point to the 'char *',
354 * which will be allocated)
355 * @param option name of the option
356 * @param value actual value of the option (a string)
360 set_string(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
369 GNUNET_assert(NULL != value);
370 GNUNET_free_non_null(*val);
371 *val = GNUNET_strdup(value);
377 * Allow user to specify a string.
379 * @param shortName short name of the option
380 * @param name long name of the option
381 * @param argumentHelp help text for the option argument
382 * @param description long help text for the option
383 * @param[out] str set to the string
385 struct GNUNET_GETOPT_CommandLineOption
386 GNUNET_GETOPT_option_string(char shortName,
388 const char *argumentHelp,
389 const char *description,
392 struct GNUNET_GETOPT_CommandLineOption clo = { .shortName = shortName,
394 .argumentHelp = argumentHelp,
395 .description = description,
396 .require_argument = 1,
397 .processor = &set_string,
398 .scls = (void *)str };
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 };
427 * Set an option of type 'char *' from the command line with
428 * filename expansion a la #GNUNET_STRINGS_filename_expand().
430 * @param ctx command line processing context
431 * @param scls additional closure (will point to the `char *`,
432 * which will be allocated)
433 * @param option name of the option
434 * @param value actual value of the option (a string)
438 set_filename(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
447 GNUNET_assert(NULL != value);
448 GNUNET_free_non_null(*val);
449 *val = GNUNET_STRINGS_filename_expand(value);
455 * Allow user to specify a filename (automatically path expanded).
457 * @param shortName short name of the option
458 * @param name long name of the option
459 * @param argumentHelp help text for the option argument
460 * @param description long help text for the option
461 * @param[out] str set to the string
463 struct GNUNET_GETOPT_CommandLineOption
464 GNUNET_GETOPT_option_filename(char shortName,
466 const char *argumentHelp,
467 const char *description,
470 struct GNUNET_GETOPT_CommandLineOption clo = { .shortName = shortName,
472 .argumentHelp = argumentHelp,
473 .description = description,
474 .require_argument = 1,
475 .processor = &set_filename,
476 .scls = (void *)str };
483 * Allow user to specify log file name (-l option)
485 * @param[out] logfn set to the name of the logfile
487 struct GNUNET_GETOPT_CommandLineOption
488 GNUNET_GETOPT_option_logfile(char **logfn)
490 struct GNUNET_GETOPT_CommandLineOption clo =
493 .argumentHelp = "FILENAME",
495 gettext_noop("configure logging to write logs to FILENAME"),
496 .require_argument = 1,
497 .processor = &set_filename,
498 .scls = (void *)logfn };
505 * Allow user to specify configuration file name (-c option)
507 * @param[out] fn set to the name of the configuration file
509 struct GNUNET_GETOPT_CommandLineOption
510 GNUNET_GETOPT_option_cfgfile(char **fn)
512 struct GNUNET_GETOPT_CommandLineOption clo =
515 .argumentHelp = "FILENAME",
516 .description = gettext_noop("use configuration file FILENAME"),
517 .require_argument = 1,
518 .processor = &set_filename,
519 .scls = (void *)fn };
526 * Set an option of type 'unsigned long long' from the command line.
527 * A pointer to this function should be passed as part of the
528 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
529 * of this type. It should be followed by a pointer to a value of
530 * type 'unsigned long long'.
532 * @param ctx command line processing context
533 * @param scls additional closure (will point to the 'unsigned long long')
534 * @param option name of the option
535 * @param value actual value of the option as a string.
536 * @return #GNUNET_OK if parsing the value worked
539 set_ulong(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
544 unsigned long long *val = scls;
548 if (1 != sscanf(value, "%llu%1s", val, dummy))
551 _("You must pass a number to the `%s' option.\n"),
553 return GNUNET_SYSERR;
560 * Allow user to specify an `unsigned long long`
562 * @param shortName short name of the option
563 * @param name long name of the option
564 * @param argumentHelp help text for the option argument
565 * @param description long help text for the option
566 * @param[out] val set to the value specified at the command line
568 struct GNUNET_GETOPT_CommandLineOption
569 GNUNET_GETOPT_option_ulong(char shortName,
571 const char *argumentHelp,
572 const char *description,
573 unsigned long long *val)
575 struct GNUNET_GETOPT_CommandLineOption clo = { .shortName = shortName,
577 .argumentHelp = argumentHelp,
578 .description = description,
579 .require_argument = 1,
580 .processor = &set_ulong,
581 .scls = (void *)val };
588 * Set an option of type 'struct GNUNET_TIME_Relative' from the command line.
589 * A pointer to this function should be passed as part of the
590 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
591 * of this type. It should be followed by a pointer to a value of
592 * type 'struct GNUNET_TIME_Relative'.
594 * @param ctx command line processing context
595 * @param scls additional closure (will point to the 'struct GNUNET_TIME_Relative')
596 * @param option name of the option
597 * @param value actual value of the option as a string.
598 * @return #GNUNET_OK if parsing the value worked
601 set_relative_time(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
606 struct GNUNET_TIME_Relative *val = scls;
609 if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_relative(value, val))
612 _("You must pass relative time to the `%s' option.\n"),
614 return GNUNET_SYSERR;
621 * Allow user to specify a `struct GNUNET_TIME_Relative`
622 * (using human-readable "fancy" time).
624 * @param shortName short name of the option
625 * @param name long name of the option
626 * @param argumentHelp help text for the option argument
627 * @param description long help text for the option
628 * @param[out] val set to the time specified at the command line
630 struct GNUNET_GETOPT_CommandLineOption
631 GNUNET_GETOPT_option_relative_time(char shortName,
633 const char *argumentHelp,
634 const char *description,
635 struct GNUNET_TIME_Relative *val)
637 struct GNUNET_GETOPT_CommandLineOption clo = { .shortName = shortName,
639 .argumentHelp = argumentHelp,
640 .description = description,
641 .require_argument = 1,
642 .processor = &set_relative_time,
643 .scls = (void *)val };
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'.
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
663 set_absolute_time(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
668 struct GNUNET_TIME_Absolute *val = scls;
671 if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_absolute(value, val))
674 _("You must pass absolute time to the `%s' option.\n"),
676 return GNUNET_SYSERR;
683 * Allow user to specify a `struct GNUNET_TIME_Absolute`
684 * (using human-readable "fancy" time).
686 * @param shortName short name of the option
687 * @param name long name of the option
688 * @param argumentHelp help text for the option argument
689 * @param description long help text for the option
690 * @param[out] val set to the time specified at the command line
692 struct GNUNET_GETOPT_CommandLineOption
693 GNUNET_GETOPT_option_absolute_time(char shortName,
695 const char *argumentHelp,
696 const char *description,
697 struct GNUNET_TIME_Absolute *val)
699 struct GNUNET_GETOPT_CommandLineOption clo = { .shortName = shortName,
701 .argumentHelp = argumentHelp,
702 .description = description,
703 .require_argument = 1,
704 .processor = &set_absolute_time,
705 .scls = (void *)val };
712 * Set an option of type 'unsigned int' from the command line.
713 * A pointer to this function should be passed as part of the
714 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
715 * of this type. It should be followed by a pointer to a value of
716 * type 'unsigned int'.
718 * @param ctx command line processing context
719 * @param scls additional closure (will point to the 'unsigned int')
720 * @param option name of the option
721 * @param value actual value of the option as a string.
722 * @return #GNUNET_OK if parsing the value worked
725 set_uint(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
730 unsigned int *val = scls;
738 "Your input for the '%s' option has to be a non negative number \n"),
740 return GNUNET_SYSERR;
742 if (1 != sscanf(value, "%u%1s", val, dummy))
745 _("You must pass a number to the `%s' option.\n"),
747 return GNUNET_SYSERR;
754 * Allow user to specify an unsigned integer.
756 * @param shortName short name of the option
757 * @param name long name of the option
758 * @param argumentHelp help text for the option argument
759 * @param description long help text for the option
760 * @param[out] val set to the value specified at the command line
762 struct GNUNET_GETOPT_CommandLineOption
763 GNUNET_GETOPT_option_uint(char shortName,
765 const char *argumentHelp,
766 const char *description,
769 struct GNUNET_GETOPT_CommandLineOption clo = { .shortName = shortName,
771 .argumentHelp = argumentHelp,
772 .description = description,
773 .require_argument = 1,
774 .processor = &set_uint,
775 .scls = (void *)val };
782 * Set an option of type 'uint16_t' from the command line.
783 * A pointer to this function should be passed as part of the
784 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
785 * of this type. It should be followed by a pointer to a value of
788 * @param ctx command line processing context
789 * @param scls additional closure (will point to the 'unsigned int')
790 * @param option name of the option
791 * @param value actual value of the option as a string.
792 * @return #GNUNET_OK if parsing the value worked
795 set_uint16(struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
800 uint16_t *val = scls;
805 if (1 != sscanf(value, "%u%1s", &v, dummy))
808 _("You must pass a number to the `%s' option.\n"),
810 return GNUNET_SYSERR;
815 _("You must pass a number below %u to the `%s' option.\n"),
816 (unsigned int)UINT16_MAX,
818 return GNUNET_SYSERR;
826 * Allow user to specify an uint16_t.
828 * @param shortName short name of the option
829 * @param name long name of the option
830 * @param argumentHelp help text for the option argument
831 * @param description long help text for the option
832 * @param[out] val set to the value specified at the command line
834 struct GNUNET_GETOPT_CommandLineOption
835 GNUNET_GETOPT_option_uint16(char shortName,
837 const char *argumentHelp,
838 const char *description,
841 struct GNUNET_GETOPT_CommandLineOption clo = { .shortName = shortName,
843 .argumentHelp = argumentHelp,
844 .description = description,
845 .require_argument = 1,
846 .processor = &set_uint16,
847 .scls = (void *)val };
854 * Closure for #set_base32().
856 struct Base32Context {
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 */