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/>.
20 * @file src/util/getopt_helpers.c
21 * @brief implements command line that sets option
22 * @author Christian Grothoff
25 #include "gnunet_util_lib.h"
27 #define LOG(kind,...) GNUNET_log_from (kind, "util-getopt", __VA_ARGS__)
31 * Print out program version (implements --version).
33 * @param ctx command line processing context
34 * @param scls additional closure (points to version string)
35 * @param option name of the option
36 * @param value not used (NULL)
37 * @return #GNUNET_NO (do not continue, not an error)
40 print_version (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
45 const char *version = scls;
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 = {
68 .description = gettext_noop("print the version number"),
69 .processor = &print_version,
70 .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;
114 printf (_("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"
182 "GNUnet home page: %s\n"
183 "General help using GNU software: http://www.gnu.org/gethelp/\n",
191 * Defining the option to print the command line
192 * help text (-h option).
194 * @param about string with brief description of the application
196 struct GNUNET_GETOPT_CommandLineOption
197 GNUNET_GETOPT_option_help (const char *about)
199 struct GNUNET_GETOPT_CommandLineOption clo = {
202 .description = gettext_noop("print this help"),
203 .processor = format_help,
204 .scls = (void *) about
212 * Set an option of type 'unsigned int' from the command line. Each
213 * time the option flag is given, the value is incremented by one.
214 * A pointer to this function should be passed as part of the
215 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
216 * of this type. It should be followed by a pointer to a value of
219 * @param ctx command line processing context
220 * @param scls additional closure (will point to the 'unsigned int')
221 * @param option name of the option
222 * @param value not used (NULL)
226 increment_value (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
231 unsigned int *val = scls;
242 * Increment @a val each time the option flag is given by one.
244 * @param shortName short name of the option
245 * @param name long name of the option
246 * @param argumentHelp help text for the option argument
247 * @param description long help text for the option
248 * @param[out] val increment by 1 each time the option is present
250 struct GNUNET_GETOPT_CommandLineOption
251 GNUNET_GETOPT_option_increment_uint (char shortName,
253 const char *description,
256 struct GNUNET_GETOPT_CommandLineOption clo = {
257 .shortName = shortName,
259 .description = description,
260 .processor = &increment_value,
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 = {
280 .description = gettext_noop("be verbose"),
281 .processor = &increment_value,
282 .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 = {
336 .shortName = shortName,
338 .description = description,
339 .processor = &set_one,
348 * Set an option of type 'char *' from the command line.
349 * A pointer to this function should be passed as part of the
350 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
351 * of this type. It should be followed by a pointer to a value of
352 * type 'char *', which will be allocated with the requested string.
354 * @param ctx command line processing context
355 * @param scls additional closure (will point to the 'char *',
356 * which will be allocated)
357 * @param option name of the option
358 * @param value actual value of the option (a string)
362 set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
371 GNUNET_assert (NULL != value);
372 GNUNET_free_non_null (*val);
373 *val = GNUNET_strdup (value);
379 * Allow user to specify a string.
381 * @param shortName short name of the option
382 * @param name long name of the option
383 * @param argumentHelp help text for the option argument
384 * @param description long help text for the option
385 * @param[out] str set to the string
387 struct GNUNET_GETOPT_CommandLineOption
388 GNUNET_GETOPT_option_string (char shortName,
390 const char *argumentHelp,
391 const char *description,
394 struct GNUNET_GETOPT_CommandLineOption clo = {
395 .shortName = shortName,
397 .argumentHelp = argumentHelp,
398 .description = description,
399 .require_argument = 1,
400 .processor = &set_string,
409 * Define the '-L' log level option. Note that we do not check
410 * that the log level is valid here.
412 * @param[out] level set to the log level
414 struct GNUNET_GETOPT_CommandLineOption
415 GNUNET_GETOPT_option_loglevel (char **level)
417 struct GNUNET_GETOPT_CommandLineOption clo = {
420 .argumentHelp = "LOGLEVEL",
421 .description = gettext_noop("configure logging to use LOGLEVEL"),
422 .require_argument = 1,
423 .processor = &set_string,
424 .scls = (void *) level
432 * Set an option of type 'char *' from the command line with
433 * filename expansion a la #GNUNET_STRINGS_filename_expand().
435 * @param ctx command line processing context
436 * @param scls additional closure (will point to the `char *`,
437 * which will be allocated)
438 * @param option name of the option
439 * @param value actual value of the option (a string)
443 set_filename (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
452 GNUNET_assert (NULL != value);
453 GNUNET_free_non_null (*val);
454 *val = GNUNET_STRINGS_filename_expand (value);
460 * Allow user to specify a filename (automatically path expanded).
462 * @param shortName short name of the option
463 * @param name long name of the option
464 * @param argumentHelp help text for the option argument
465 * @param description long help text for the option
466 * @param[out] str set to the string
468 struct GNUNET_GETOPT_CommandLineOption
469 GNUNET_GETOPT_option_filename (char shortName,
471 const char *argumentHelp,
472 const char *description,
475 struct GNUNET_GETOPT_CommandLineOption clo = {
476 .shortName = shortName,
478 .argumentHelp = argumentHelp,
479 .description = description,
480 .require_argument = 1,
481 .processor = &set_filename,
490 * Allow user to specify log file name (-l option)
492 * @param[out] logfn set to the name of the logfile
494 struct GNUNET_GETOPT_CommandLineOption
495 GNUNET_GETOPT_option_logfile (char **logfn)
497 struct GNUNET_GETOPT_CommandLineOption clo = {
500 .argumentHelp = "FILENAME",
501 .description = gettext_noop ("configure logging to write logs to FILENAME"),
502 .require_argument = 1,
503 .processor = &set_filename,
504 .scls = (void *) logfn
512 * Allow user to specify configuration file name (-c option)
514 * @param[out] fn set to the name of the configuration file
516 struct GNUNET_GETOPT_CommandLineOption
517 GNUNET_GETOPT_option_cfgfile (char **fn)
519 struct GNUNET_GETOPT_CommandLineOption clo = {
522 .argumentHelp = "FILENAME",
523 .description = gettext_noop("use configuration file FILENAME"),
524 .require_argument = 1,
525 .processor = &set_filename,
534 * Set an option of type 'unsigned long long' from the command line.
535 * A pointer to this function should be passed as part of the
536 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
537 * of this type. It should be followed by a pointer to a value of
538 * type 'unsigned long long'.
540 * @param ctx command line processing context
541 * @param scls additional closure (will point to the 'unsigned long long')
542 * @param option name of the option
543 * @param value actual value of the option as a string.
544 * @return #GNUNET_OK if parsing the value worked
547 set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
552 unsigned long long *val = scls;
556 if (1 != SSCANF (value,
562 _("You must pass a number to the `%s' option.\n"),
564 return GNUNET_SYSERR;
571 * Allow user to specify an `unsigned long long`
573 * @param shortName short name of the option
574 * @param name long name of the option
575 * @param argumentHelp help text for the option argument
576 * @param description long help text for the option
577 * @param[out] val set to the value specified at the command line
579 struct GNUNET_GETOPT_CommandLineOption
580 GNUNET_GETOPT_option_ulong (char shortName,
582 const char *argumentHelp,
583 const char *description,
584 unsigned long long *val)
586 struct GNUNET_GETOPT_CommandLineOption clo = {
587 .shortName = shortName,
589 .argumentHelp = argumentHelp,
590 .description = description,
591 .require_argument = 1,
592 .processor = &set_ulong,
601 * Set an option of type 'struct GNUNET_TIME_Relative' from the command line.
602 * A pointer to this function should be passed as part of the
603 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
604 * of this type. It should be followed by a pointer to a value of
605 * type 'struct GNUNET_TIME_Relative'.
607 * @param ctx command line processing context
608 * @param scls additional closure (will point to the 'struct GNUNET_TIME_Relative')
609 * @param option name of the option
610 * @param value actual value of the option as a string.
611 * @return #GNUNET_OK if parsing the value worked
614 set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
619 struct GNUNET_TIME_Relative *val = scls;
623 GNUNET_STRINGS_fancy_time_to_relative (value,
627 _("You must pass relative time to the `%s' option.\n"),
629 return GNUNET_SYSERR;
636 * Allow user to specify a `struct GNUNET_TIME_Relative`
637 * (using human-readable "fancy" time).
639 * @param shortName short name of the option
640 * @param name long name of the option
641 * @param argumentHelp help text for the option argument
642 * @param description long help text for the option
643 * @param[out] val set to the time specified at the command line
645 struct GNUNET_GETOPT_CommandLineOption
646 GNUNET_GETOPT_option_relative_time (char shortName,
648 const char *argumentHelp,
649 const char *description,
650 struct GNUNET_TIME_Relative *val)
652 struct GNUNET_GETOPT_CommandLineOption clo = {
653 .shortName = shortName,
655 .argumentHelp = argumentHelp,
656 .description = description,
657 .require_argument = 1,
658 .processor = &set_relative_time,
667 * Set an option of type 'struct GNUNET_TIME_Absolute' from the command line.
668 * A pointer to this function should be passed as part of the
669 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
670 * of this type. It should be followed by a pointer to a value of
671 * type 'struct GNUNET_TIME_Absolute'.
673 * @param ctx command line processing context
674 * @param scls additional closure (will point to the `struct GNUNET_TIME_Absolute`)
675 * @param option name of the option
676 * @param value actual value of the option as a string.
677 * @return #GNUNET_OK if parsing the value worked
680 set_absolute_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
685 struct GNUNET_TIME_Absolute *val = scls;
689 GNUNET_STRINGS_fancy_time_to_absolute (value,
693 _("You must pass absolute time to the `%s' option.\n"),
695 return GNUNET_SYSERR;
702 * Allow user to specify a `struct GNUNET_TIME_Absolute`
703 * (using human-readable "fancy" time).
705 * @param shortName short name of the option
706 * @param name long name of the option
707 * @param argumentHelp help text for the option argument
708 * @param description long help text for the option
709 * @param[out] val set to the time specified at the command line
711 struct GNUNET_GETOPT_CommandLineOption
712 GNUNET_GETOPT_option_absolute_time (char shortName,
714 const char *argumentHelp,
715 const char *description,
716 struct GNUNET_TIME_Absolute *val)
718 struct GNUNET_GETOPT_CommandLineOption clo = {
719 .shortName = shortName,
721 .argumentHelp = argumentHelp,
722 .description = description,
723 .require_argument = 1,
724 .processor = &set_absolute_time,
733 * Set an option of type 'unsigned int' from the command line.
734 * A pointer to this function should be passed as part of the
735 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
736 * of this type. It should be followed by a pointer to a value of
737 * type 'unsigned int'.
739 * @param ctx command line processing context
740 * @param scls additional closure (will point to the 'unsigned int')
741 * @param option name of the option
742 * @param value actual value of the option as a string.
743 * @return #GNUNET_OK if parsing the value worked
746 set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
751 unsigned int *val = scls;
758 _("Your input for the '%s' option has to be a non negative number \n"),
760 return GNUNET_SYSERR;
762 if (1 != SSCANF (value,
768 _("You must pass a number to the `%s' option.\n"),
770 return GNUNET_SYSERR;
777 * Allow user to specify an unsigned integer.
779 * @param shortName short name of the option
780 * @param name long name of the option
781 * @param argumentHelp help text for the option argument
782 * @param description long help text for the option
783 * @param[out] val set to the value specified at the command line
785 struct GNUNET_GETOPT_CommandLineOption
786 GNUNET_GETOPT_option_uint (char shortName,
788 const char *argumentHelp,
789 const char *description,
792 struct GNUNET_GETOPT_CommandLineOption clo = {
793 .shortName = shortName,
795 .argumentHelp = argumentHelp,
796 .description = description,
797 .require_argument = 1,
798 .processor = &set_uint,
808 * Set an option of type 'uint16_t' from the command line.
809 * A pointer to this function should be passed as part of the
810 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
811 * of this type. It should be followed by a pointer to a value of
814 * @param ctx command line processing context
815 * @param scls additional closure (will point to the 'unsigned int')
816 * @param option name of the option
817 * @param value actual value of the option as a string.
818 * @return #GNUNET_OK if parsing the value worked
821 set_uint16 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
826 uint16_t *val = scls;
831 if (1 != SSCANF (value,
837 _("You must pass a number to the `%s' option.\n"),
839 return GNUNET_SYSERR;
844 _("You must pass a number below %u to the `%s' option.\n"),
845 (unsigned int) UINT16_MAX,
847 return GNUNET_SYSERR;
855 * Allow user to specify an uint16_t.
857 * @param shortName short name of the option
858 * @param name long name of the option
859 * @param argumentHelp help text for the option argument
860 * @param description long help text for the option
861 * @param[out] val set to the value specified at the command line
863 struct GNUNET_GETOPT_CommandLineOption
864 GNUNET_GETOPT_option_uint16 (char shortName,
866 const char *argumentHelp,
867 const char *description,
870 struct GNUNET_GETOPT_CommandLineOption clo = {
871 .shortName = shortName,
873 .argumentHelp = argumentHelp,
874 .description = description,
875 .require_argument = 1,
876 .processor = &set_uint16,
885 * Closure for #set_base32().
890 * Value to initialize (already allocated)
895 * Number of bytes expected for @e val.
902 * Set an option of type 'unsigned int' from the command line.
903 * A pointer to this function should be passed as part of the
904 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
905 * of this type. It should be followed by a pointer to a value of
906 * type 'unsigned int'.
908 * @param ctx command line processing context
909 * @param scls additional closure (will point to the 'unsigned int')
910 * @param option name of the option
911 * @param value actual value of the option as a string.
912 * @return #GNUNET_OK if parsing the value worked
915 set_base32 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
920 struct Base32Context *bc = scls;
924 GNUNET_STRINGS_string_to_data (value,
930 _("Argument `%s' malformed. Expected base32 (Crockford) encoded value.\n"),
932 return GNUNET_SYSERR;
939 * Helper function to clean up after
940 * #GNUNET_GETOPT_option_base32_fixed_size.
942 * @param cls value to GNUNET_free()
952 * Allow user to specify a binary value using Crockford
955 * @param shortName short name of the option
956 * @param name long name of the option
957 * @param argumentHelp help text for the option argument
958 * @param description long help text for the option
959 * @param[out] val binary value decoded from Crockford Base32-encoded argument
960 * @param val_size size of @a val in bytes
962 struct GNUNET_GETOPT_CommandLineOption
963 GNUNET_GETOPT_option_base32_fixed_size (char shortName,
965 const char *argumentHelp,
966 const char *description,
970 struct Base32Context *bc = GNUNET_new (struct Base32Context);
971 struct GNUNET_GETOPT_CommandLineOption clo = {
972 .shortName = shortName,
974 .argumentHelp = argumentHelp,
975 .description = description,
976 .require_argument = 1,
977 .processor = &set_base32,
983 bc->val_size = val_size;
989 * Make the given option mandatory.
991 * @param opt option to modify
992 * @return @a opt with the mandatory flag set.
994 struct GNUNET_GETOPT_CommandLineOption
995 GNUNET_GETOPT_option_mandatory (struct GNUNET_GETOPT_CommandLineOption opt)
997 opt.option_mandatory = 1;
1002 /* end of getopt_helpers.c */