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;
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;
116 printf (_("Arguments mandatory for long options are also mandatory for short options.\n"));
119 opt = ctx->allOptions;
120 while (NULL != opt[i].description)
122 if (opt[i].shortName == '\0')
125 printf (" -%c, ", opt[i].shortName);
126 printf ("--%s", opt[i].name);
127 slen = 8 + strlen (opt[i].name);
128 if (NULL != opt[i].argumentHelp)
130 printf ("=%s", opt[i].argumentHelp);
131 slen += 1 + strlen (opt[i].argumentHelp);
135 printf ("\n%*s", BORDER, "");
140 printf ("%*s", (int) (BORDER - slen), "");
143 if (0 < strlen (opt[i].description))
144 trans = gettext (opt[i].description);
150 while (ml - p > 78 - slen)
152 for (j = p + 78 - slen; j > (int) p; j--)
154 if (isspace ((unsigned char) trans[j]))
156 scp = GNUNET_malloc (j - p + 1);
157 GNUNET_memcpy (scp, &trans[p], j - p);
159 printf ("%s\n%*s", scp, BORDER + 2, "");
166 /* could not find space to break line */
167 scp = GNUNET_malloc (78 - slen + 1);
168 GNUNET_memcpy (scp, &trans[p], 78 - slen);
169 scp[78 - slen] = '\0';
170 printf ("%s\n%*s", scp, BORDER + 2, "");
177 printf ("%s\n", &trans[p]);
178 if (strlen (trans) == 0)
182 pd = GNUNET_OS_project_data_get ();
183 printf ("Report bugs to %s.\n"
184 "GNUnet home page: %s\n"
185 "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 = {
204 .description = gettext_noop("print this help"),
205 .processor = format_help,
206 .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 = {
259 .shortName = shortName,
261 .description = description,
262 .processor = &increment_value,
271 * Define the '-V' verbosity option. Using the option more
272 * than once increments @a level each time.
274 * @param[out] level set to the verbosity level
276 struct GNUNET_GETOPT_CommandLineOption
277 GNUNET_GETOPT_option_verbose (unsigned int *level)
279 struct GNUNET_GETOPT_CommandLineOption clo = {
282 .description = gettext_noop("be verbose"),
283 .processor = &increment_value,
284 .scls = (void *) level
292 * Set an option of type 'int' from the command line to 1 if the
293 * given option is present.
294 * A pointer to this function should be passed as part of the
295 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
296 * of this type. It should be followed by a pointer to a value of
299 * @param ctx command line processing context
300 * @param scls additional closure (will point to the 'int')
301 * @param option name of the option
302 * @param value not used (NULL)
306 set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
322 * Allow user to specify a flag (which internally means setting
323 * an integer to 1/#GNUNET_YES/#GNUNET_OK.
325 * @param shortName short name of the option
326 * @param name long name of the option
327 * @param argumentHelp help text for the option argument
328 * @param description long help text for the option
329 * @param[out] val set to 1 if the option is present
331 struct GNUNET_GETOPT_CommandLineOption
332 GNUNET_GETOPT_option_flag (char shortName,
334 const char *description,
337 struct GNUNET_GETOPT_CommandLineOption clo = {
338 .shortName = shortName,
340 .description = description,
341 .processor = &set_one,
350 * Set an option of type 'char *' from the command line.
351 * A pointer to this function should be passed as part of the
352 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
353 * of this type. It should be followed by a pointer to a value of
354 * type 'char *', which will be allocated with the requested string.
356 * @param ctx command line processing context
357 * @param scls additional closure (will point to the 'char *',
358 * which will be allocated)
359 * @param option name of the option
360 * @param value actual value of the option (a string)
364 set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
373 GNUNET_assert (NULL != value);
374 GNUNET_free_non_null (*val);
375 *val = GNUNET_strdup (value);
381 * Allow user to specify a string.
383 * @param shortName short name of the option
384 * @param name long name of the option
385 * @param argumentHelp help text for the option argument
386 * @param description long help text for the option
387 * @param[out] str set to the string
389 struct GNUNET_GETOPT_CommandLineOption
390 GNUNET_GETOPT_option_string (char shortName,
392 const char *argumentHelp,
393 const char *description,
396 struct GNUNET_GETOPT_CommandLineOption clo = {
397 .shortName = shortName,
399 .argumentHelp = argumentHelp,
400 .description = description,
401 .require_argument = 1,
402 .processor = &set_string,
411 * Define the '-L' log level option. Note that we do not check
412 * that the log level is valid here.
414 * @param[out] level set to the log level
416 struct GNUNET_GETOPT_CommandLineOption
417 GNUNET_GETOPT_option_loglevel (char **level)
419 struct GNUNET_GETOPT_CommandLineOption clo = {
422 .argumentHelp = "LOGLEVEL",
423 .description = gettext_noop("configure logging to use LOGLEVEL"),
424 .require_argument = 1,
425 .processor = &set_string,
426 .scls = (void *) level
434 * Set an option of type 'char *' from the command line with
435 * filename expansion a la #GNUNET_STRINGS_filename_expand().
437 * @param ctx command line processing context
438 * @param scls additional closure (will point to the `char *`,
439 * which will be allocated)
440 * @param option name of the option
441 * @param value actual value of the option (a string)
445 set_filename (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
454 GNUNET_assert (NULL != value);
455 GNUNET_free_non_null (*val);
456 *val = GNUNET_STRINGS_filename_expand (value);
462 * Allow user to specify a filename (automatically path expanded).
464 * @param shortName short name of the option
465 * @param name long name of the option
466 * @param argumentHelp help text for the option argument
467 * @param description long help text for the option
468 * @param[out] str set to the string
470 struct GNUNET_GETOPT_CommandLineOption
471 GNUNET_GETOPT_option_filename (char shortName,
473 const char *argumentHelp,
474 const char *description,
477 struct GNUNET_GETOPT_CommandLineOption clo = {
478 .shortName = shortName,
480 .argumentHelp = argumentHelp,
481 .description = description,
482 .require_argument = 1,
483 .processor = &set_filename,
492 * Allow user to specify log file name (-l option)
494 * @param[out] logfn set to the name of the logfile
496 struct GNUNET_GETOPT_CommandLineOption
497 GNUNET_GETOPT_option_logfile (char **logfn)
499 struct GNUNET_GETOPT_CommandLineOption clo = {
502 .argumentHelp = "FILENAME",
503 .description = gettext_noop ("configure logging to write logs to FILENAME"),
504 .require_argument = 1,
505 .processor = &set_filename,
506 .scls = (void *) logfn
514 * Allow user to specify configuration file name (-c option)
516 * @param[out] fn set to the name of the configuration file
518 struct GNUNET_GETOPT_CommandLineOption
519 GNUNET_GETOPT_option_cfgfile (char **fn)
521 struct GNUNET_GETOPT_CommandLineOption clo = {
524 .argumentHelp = "FILENAME",
525 .description = gettext_noop("use configuration file FILENAME"),
526 .require_argument = 1,
527 .processor = &set_filename,
536 * Set an option of type 'unsigned long long' from the command line.
537 * A pointer to this function should be passed as part of the
538 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
539 * of this type. It should be followed by a pointer to a value of
540 * type 'unsigned long long'.
542 * @param ctx command line processing context
543 * @param scls additional closure (will point to the 'unsigned long long')
544 * @param option name of the option
545 * @param value actual value of the option as a string.
546 * @return #GNUNET_OK if parsing the value worked
549 set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
554 unsigned long long *val = scls;
558 if (1 != SSCANF (value,
564 _("You must pass a number to the `%s' option.\n"),
566 return GNUNET_SYSERR;
573 * Allow user to specify an `unsigned long long`
575 * @param shortName short name of the option
576 * @param name long name of the option
577 * @param argumentHelp help text for the option argument
578 * @param description long help text for the option
579 * @param[out] val set to the value specified at the command line
581 struct GNUNET_GETOPT_CommandLineOption
582 GNUNET_GETOPT_option_ulong (char shortName,
584 const char *argumentHelp,
585 const char *description,
586 unsigned long long *val)
588 struct GNUNET_GETOPT_CommandLineOption clo = {
589 .shortName = shortName,
591 .argumentHelp = argumentHelp,
592 .description = description,
593 .require_argument = 1,
594 .processor = &set_ulong,
603 * Set an option of type 'struct GNUNET_TIME_Relative' from the command line.
604 * A pointer to this function should be passed as part of the
605 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
606 * of this type. It should be followed by a pointer to a value of
607 * type 'struct GNUNET_TIME_Relative'.
609 * @param ctx command line processing context
610 * @param scls additional closure (will point to the 'struct GNUNET_TIME_Relative')
611 * @param option name of the option
612 * @param value actual value of the option as a string.
613 * @return #GNUNET_OK if parsing the value worked
616 set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
621 struct GNUNET_TIME_Relative *val = scls;
625 GNUNET_STRINGS_fancy_time_to_relative (value,
629 _("You must pass relative time to the `%s' option.\n"),
631 return GNUNET_SYSERR;
638 * Allow user to specify a `struct GNUNET_TIME_Relative`
639 * (using human-readable "fancy" time).
641 * @param shortName short name of the option
642 * @param name long name of the option
643 * @param argumentHelp help text for the option argument
644 * @param description long help text for the option
645 * @param[out] val set to the time specified at the command line
647 struct GNUNET_GETOPT_CommandLineOption
648 GNUNET_GETOPT_option_relative_time (char shortName,
650 const char *argumentHelp,
651 const char *description,
652 struct GNUNET_TIME_Relative *val)
654 struct GNUNET_GETOPT_CommandLineOption clo = {
655 .shortName = shortName,
657 .argumentHelp = argumentHelp,
658 .description = description,
659 .require_argument = 1,
660 .processor = &set_relative_time,
669 * Set an option of type 'struct GNUNET_TIME_Absolute' from the command line.
670 * A pointer to this function should be passed as part of the
671 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
672 * of this type. It should be followed by a pointer to a value of
673 * type 'struct GNUNET_TIME_Absolute'.
675 * @param ctx command line processing context
676 * @param scls additional closure (will point to the `struct GNUNET_TIME_Absolute`)
677 * @param option name of the option
678 * @param value actual value of the option as a string.
679 * @return #GNUNET_OK if parsing the value worked
682 set_absolute_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
687 struct GNUNET_TIME_Absolute *val = scls;
691 GNUNET_STRINGS_fancy_time_to_absolute (value,
695 _("You must pass absolute time to the `%s' option.\n"),
697 return GNUNET_SYSERR;
704 * Allow user to specify a `struct GNUNET_TIME_Absolute`
705 * (using human-readable "fancy" time).
707 * @param shortName short name of the option
708 * @param name long name of the option
709 * @param argumentHelp help text for the option argument
710 * @param description long help text for the option
711 * @param[out] val set to the time specified at the command line
713 struct GNUNET_GETOPT_CommandLineOption
714 GNUNET_GETOPT_option_absolute_time (char shortName,
716 const char *argumentHelp,
717 const char *description,
718 struct GNUNET_TIME_Absolute *val)
720 struct GNUNET_GETOPT_CommandLineOption clo = {
721 .shortName = shortName,
723 .argumentHelp = argumentHelp,
724 .description = description,
725 .require_argument = 1,
726 .processor = &set_absolute_time,
735 * Set an option of type 'unsigned int' from the command line.
736 * A pointer to this function should be passed as part of the
737 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
738 * of this type. It should be followed by a pointer to a value of
739 * type 'unsigned int'.
741 * @param ctx command line processing context
742 * @param scls additional closure (will point to the 'unsigned int')
743 * @param option name of the option
744 * @param value actual value of the option as a string.
745 * @return #GNUNET_OK if parsing the value worked
748 set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
753 unsigned int *val = scls;
760 _("Your input for the '%s' option has to be a non negative number \n"),
762 return GNUNET_SYSERR;
764 if (1 != SSCANF (value,
770 _("You must pass a number to the `%s' option.\n"),
772 return GNUNET_SYSERR;
779 * Allow user to specify an unsigned integer.
781 * @param shortName short name of the option
782 * @param name long name of the option
783 * @param argumentHelp help text for the option argument
784 * @param description long help text for the option
785 * @param[out] val set to the value specified at the command line
787 struct GNUNET_GETOPT_CommandLineOption
788 GNUNET_GETOPT_option_uint (char shortName,
790 const char *argumentHelp,
791 const char *description,
794 struct GNUNET_GETOPT_CommandLineOption clo = {
795 .shortName = shortName,
797 .argumentHelp = argumentHelp,
798 .description = description,
799 .require_argument = 1,
800 .processor = &set_uint,
810 * Set an option of type 'uint16_t' from the command line.
811 * A pointer to this function should be passed as part of the
812 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
813 * of this type. It should be followed by a pointer to a value of
816 * @param ctx command line processing context
817 * @param scls additional closure (will point to the 'unsigned int')
818 * @param option name of the option
819 * @param value actual value of the option as a string.
820 * @return #GNUNET_OK if parsing the value worked
823 set_uint16 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
828 uint16_t *val = scls;
833 if (1 != SSCANF (value,
839 _("You must pass a number to the `%s' option.\n"),
841 return GNUNET_SYSERR;
846 _("You must pass a number below %u to the `%s' option.\n"),
847 (unsigned int) UINT16_MAX,
849 return GNUNET_SYSERR;
857 * Allow user to specify an uint16_t.
859 * @param shortName short name of the option
860 * @param name long name of the option
861 * @param argumentHelp help text for the option argument
862 * @param description long help text for the option
863 * @param[out] val set to the value specified at the command line
865 struct GNUNET_GETOPT_CommandLineOption
866 GNUNET_GETOPT_option_uint16 (char shortName,
868 const char *argumentHelp,
869 const char *description,
872 struct GNUNET_GETOPT_CommandLineOption clo = {
873 .shortName = shortName,
875 .argumentHelp = argumentHelp,
876 .description = description,
877 .require_argument = 1,
878 .processor = &set_uint16,
887 * Closure for #set_base32().
892 * Value to initialize (already allocated)
897 * Number of bytes expected for @e val.
904 * Set an option of type 'unsigned int' from the command line.
905 * A pointer to this function should be passed as part of the
906 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
907 * of this type. It should be followed by a pointer to a value of
908 * type 'unsigned int'.
910 * @param ctx command line processing context
911 * @param scls additional closure (will point to the 'unsigned int')
912 * @param option name of the option
913 * @param value actual value of the option as a string.
914 * @return #GNUNET_OK if parsing the value worked
917 set_base32 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
922 struct Base32Context *bc = scls;
926 GNUNET_STRINGS_string_to_data (value,
932 _("Argument `%s' malformed. Expected base32 (Crockford) encoded value.\n"),
934 return GNUNET_SYSERR;
941 * Helper function to clean up after
942 * #GNUNET_GETOPT_option_base32_fixed_size.
944 * @param cls value to GNUNET_free()
954 * Allow user to specify a binary value using Crockford
957 * @param shortName short name of the option
958 * @param name long name of the option
959 * @param argumentHelp help text for the option argument
960 * @param description long help text for the option
961 * @param[out] val binary value decoded from Crockford Base32-encoded argument
962 * @param val_size size of @a val in bytes
964 struct GNUNET_GETOPT_CommandLineOption
965 GNUNET_GETOPT_option_base32_fixed_size (char shortName,
967 const char *argumentHelp,
968 const char *description,
972 struct Base32Context *bc = GNUNET_new (struct Base32Context);
973 struct GNUNET_GETOPT_CommandLineOption clo = {
974 .shortName = shortName,
976 .argumentHelp = argumentHelp,
977 .description = description,
978 .require_argument = 1,
979 .processor = &set_base32,
985 bc->val_size = val_size;
991 * Make the given option mandatory.
993 * @param opt option to modify
994 * @return @a opt with the mandatory flag set.
996 struct GNUNET_GETOPT_CommandLineOption
997 GNUNET_GETOPT_option_mandatory (struct GNUNET_GETOPT_CommandLineOption opt)
999 opt.option_mandatory = 1;
1004 /* end of getopt_helpers.c */