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;
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"
181 "GNUnet home page: %s\n"
182 "General help using GNU software: http://www.gnu.org/gethelp/\n",
190 * Defining the option to print the command line
191 * help text (-h option).
193 * @param about string with brief description of the application
195 struct GNUNET_GETOPT_CommandLineOption
196 GNUNET_GETOPT_option_help (const char *about)
198 struct GNUNET_GETOPT_CommandLineOption clo = {
201 .description = gettext_noop("print this help"),
202 .processor = format_help,
203 .scls = (void *) about
211 * Set an option of type 'unsigned int' from the command line. Each
212 * time the option flag is given, the value is incremented by one.
213 * A pointer to this function should be passed as part of the
214 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
215 * of this type. It should be followed by a pointer to a value of
218 * @param ctx command line processing context
219 * @param scls additional closure (will point to the 'unsigned int')
220 * @param option name of the option
221 * @param value not used (NULL)
225 increment_value (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
230 unsigned int *val = scls;
241 * Increment @a val each time the option flag is given by one.
243 * @param shortName short name of the option
244 * @param name long name of the option
245 * @param argumentHelp help text for the option argument
246 * @param description long help text for the option
247 * @param[out] val increment by 1 each time the option is present
249 struct GNUNET_GETOPT_CommandLineOption
250 GNUNET_GETOPT_option_increment_uint (char shortName,
252 const char *description,
255 struct GNUNET_GETOPT_CommandLineOption clo = {
256 .shortName = shortName,
258 .description = description,
259 .processor = &increment_value,
268 * Define the '-V' verbosity option. Using the option more
269 * than once increments @a level each time.
271 * @param[out] level set to the verbosity level
273 struct GNUNET_GETOPT_CommandLineOption
274 GNUNET_GETOPT_option_verbose (unsigned int *level)
276 struct GNUNET_GETOPT_CommandLineOption clo = {
279 .description = gettext_noop("be verbose"),
280 .processor = &increment_value,
281 .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 = {
335 .shortName = shortName,
337 .description = description,
338 .processor = &set_one,
347 * Set an option of type 'char *' from the command line.
348 * A pointer to this function should be passed as part of the
349 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
350 * of this type. It should be followed by a pointer to a value of
351 * type 'char *', which will be allocated with the requested string.
353 * @param ctx command line processing context
354 * @param scls additional closure (will point to the 'char *',
355 * which will be allocated)
356 * @param option name of the option
357 * @param value actual value of the option (a string)
361 set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
370 GNUNET_assert (NULL != value);
371 GNUNET_free_non_null (*val);
372 *val = GNUNET_strdup (value);
378 * Allow user to specify a string.
380 * @param shortName short name of the option
381 * @param name long name of the option
382 * @param argumentHelp help text for the option argument
383 * @param description long help text for the option
384 * @param[out] str set to the string
386 struct GNUNET_GETOPT_CommandLineOption
387 GNUNET_GETOPT_option_string (char shortName,
389 const char *argumentHelp,
390 const char *description,
393 struct GNUNET_GETOPT_CommandLineOption clo = {
394 .shortName = shortName,
396 .argumentHelp = argumentHelp,
397 .description = description,
398 .require_argument = 1,
399 .processor = &set_string,
408 * Define the '-L' log level option. Note that we do not check
409 * that the log level is valid here.
411 * @param[out] level set to the log level
413 struct GNUNET_GETOPT_CommandLineOption
414 GNUNET_GETOPT_option_loglevel (char **level)
416 struct GNUNET_GETOPT_CommandLineOption clo = {
419 .argumentHelp = "LOGLEVEL",
420 .description = gettext_noop("configure logging to use LOGLEVEL"),
421 .require_argument = 1,
422 .processor = &set_string,
423 .scls = (void *) level
431 * Set an option of type 'char *' from the command line with
432 * filename expansion a la #GNUNET_STRINGS_filename_expand().
434 * @param ctx command line processing context
435 * @param scls additional closure (will point to the `char *`,
436 * which will be allocated)
437 * @param option name of the option
438 * @param value actual value of the option (a string)
442 set_filename (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
451 GNUNET_assert (NULL != value);
452 GNUNET_free_non_null (*val);
453 *val = GNUNET_STRINGS_filename_expand (value);
459 * Allow user to specify a filename (automatically path expanded).
461 * @param shortName short name of the option
462 * @param name long name of the option
463 * @param argumentHelp help text for the option argument
464 * @param description long help text for the option
465 * @param[out] str set to the string
467 struct GNUNET_GETOPT_CommandLineOption
468 GNUNET_GETOPT_option_filename (char shortName,
470 const char *argumentHelp,
471 const char *description,
474 struct GNUNET_GETOPT_CommandLineOption clo = {
475 .shortName = shortName,
477 .argumentHelp = argumentHelp,
478 .description = description,
479 .require_argument = 1,
480 .processor = &set_filename,
489 * Allow user to specify log file name (-l option)
491 * @param[out] logfn set to the name of the logfile
493 struct GNUNET_GETOPT_CommandLineOption
494 GNUNET_GETOPT_option_logfile (char **logfn)
496 struct GNUNET_GETOPT_CommandLineOption clo = {
499 .argumentHelp = "FILENAME",
500 .description = gettext_noop ("configure logging to write logs to FILENAME"),
501 .require_argument = 1,
502 .processor = &set_filename,
503 .scls = (void *) logfn
511 * Allow user to specify configuration file name (-c option)
513 * @param[out] fn set to the name of the configuration file
515 struct GNUNET_GETOPT_CommandLineOption
516 GNUNET_GETOPT_option_cfgfile (char **fn)
518 struct GNUNET_GETOPT_CommandLineOption clo = {
521 .argumentHelp = "FILENAME",
522 .description = gettext_noop("use configuration file FILENAME"),
523 .require_argument = 1,
524 .processor = &set_filename,
533 * Set an option of type 'unsigned long long' from the command line.
534 * A pointer to this function should be passed as part of the
535 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
536 * of this type. It should be followed by a pointer to a value of
537 * type 'unsigned long long'.
539 * @param ctx command line processing context
540 * @param scls additional closure (will point to the 'unsigned long long')
541 * @param option name of the option
542 * @param value actual value of the option as a string.
543 * @return #GNUNET_OK if parsing the value worked
546 set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
551 unsigned long long *val = scls;
554 if (1 != SSCANF (value,
559 _("You must pass a number to the `%s' option.\n"),
561 return GNUNET_SYSERR;
568 * Allow user to specify an `unsigned long long`
570 * @param shortName short name of the option
571 * @param name long name of the option
572 * @param argumentHelp help text for the option argument
573 * @param description long help text for the option
574 * @param[out] val set to the value specified at the command line
576 struct GNUNET_GETOPT_CommandLineOption
577 GNUNET_GETOPT_option_ulong (char shortName,
579 const char *argumentHelp,
580 const char *description,
581 unsigned long long *val)
583 struct GNUNET_GETOPT_CommandLineOption clo = {
584 .shortName = shortName,
586 .argumentHelp = argumentHelp,
587 .description = description,
588 .require_argument = 1,
589 .processor = &set_ulong,
598 * Set an option of type 'struct GNUNET_TIME_Relative' from the command line.
599 * A pointer to this function should be passed as part of the
600 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
601 * of this type. It should be followed by a pointer to a value of
602 * type 'struct GNUNET_TIME_Relative'.
604 * @param ctx command line processing context
605 * @param scls additional closure (will point to the 'struct GNUNET_TIME_Relative')
606 * @param option name of the option
607 * @param value actual value of the option as a string.
608 * @return #GNUNET_OK if parsing the value worked
611 set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
616 struct GNUNET_TIME_Relative *val = scls;
620 GNUNET_STRINGS_fancy_time_to_relative (value,
624 _("You must pass relative time to the `%s' option.\n"),
626 return GNUNET_SYSERR;
633 * Allow user to specify a `struct GNUNET_TIME_Relative`
634 * (using human-readable "fancy" time).
636 * @param shortName short name of the option
637 * @param name long name of the option
638 * @param argumentHelp help text for the option argument
639 * @param description long help text for the option
640 * @param[out] val set to the time specified at the command line
642 struct GNUNET_GETOPT_CommandLineOption
643 GNUNET_GETOPT_option_relative_time (char shortName,
645 const char *argumentHelp,
646 const char *description,
647 struct GNUNET_TIME_Relative *val)
649 struct GNUNET_GETOPT_CommandLineOption clo = {
650 .shortName = shortName,
652 .argumentHelp = argumentHelp,
653 .description = description,
654 .require_argument = 1,
655 .processor = &set_relative_time,
664 * Set an option of type 'struct GNUNET_TIME_Absolute' from the command line.
665 * A pointer to this function should be passed as part of the
666 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
667 * of this type. It should be followed by a pointer to a value of
668 * type 'struct GNUNET_TIME_Absolute'.
670 * @param ctx command line processing context
671 * @param scls additional closure (will point to the `struct GNUNET_TIME_Absolute`)
672 * @param option name of the option
673 * @param value actual value of the option as a string.
674 * @return #GNUNET_OK if parsing the value worked
677 set_absolute_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
682 struct GNUNET_TIME_Absolute *val = scls;
686 GNUNET_STRINGS_fancy_time_to_absolute (value,
690 _("You must pass absolute time to the `%s' option.\n"),
692 return GNUNET_SYSERR;
699 * Allow user to specify a `struct GNUNET_TIME_Absolute`
700 * (using human-readable "fancy" time).
702 * @param shortName short name of the option
703 * @param name long name of the option
704 * @param argumentHelp help text for the option argument
705 * @param description long help text for the option
706 * @param[out] val set to the time specified at the command line
708 struct GNUNET_GETOPT_CommandLineOption
709 GNUNET_GETOPT_option_absolute_time (char shortName,
711 const char *argumentHelp,
712 const char *description,
713 struct GNUNET_TIME_Absolute *val)
715 struct GNUNET_GETOPT_CommandLineOption clo = {
716 .shortName = shortName,
718 .argumentHelp = argumentHelp,
719 .description = description,
720 .require_argument = 1,
721 .processor = &set_absolute_time,
730 * Set an option of type 'unsigned int' from the command line.
731 * A pointer to this function should be passed as part of the
732 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
733 * of this type. It should be followed by a pointer to a value of
734 * type 'unsigned int'.
736 * @param ctx command line processing context
737 * @param scls additional closure (will point to the 'unsigned int')
738 * @param option name of the option
739 * @param value actual value of the option as a string.
740 * @return #GNUNET_OK if parsing the value worked
743 set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
748 unsigned int *val = scls;
751 if (1 != SSCANF (value,
756 _("You must pass a number to the `%s' option.\n"),
758 return GNUNET_SYSERR;
765 * Allow user to specify an unsigned integer.
767 * @param shortName short name of the option
768 * @param name long name of the option
769 * @param argumentHelp help text for the option argument
770 * @param description long help text for the option
771 * @param[out] val set to the value specified at the command line
773 struct GNUNET_GETOPT_CommandLineOption
774 GNUNET_GETOPT_option_uint (char shortName,
776 const char *argumentHelp,
777 const char *description,
780 struct GNUNET_GETOPT_CommandLineOption clo = {
781 .shortName = shortName,
783 .argumentHelp = argumentHelp,
784 .description = description,
785 .require_argument = 1,
786 .processor = &set_uint,
796 * Set an option of type 'uint16_t' from the command line.
797 * A pointer to this function should be passed as part of the
798 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
799 * of this type. It should be followed by a pointer to a value of
802 * @param ctx command line processing context
803 * @param scls additional closure (will point to the 'unsigned int')
804 * @param option name of the option
805 * @param value actual value of the option as a string.
806 * @return #GNUNET_OK if parsing the value worked
809 set_uint16 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
814 uint16_t *val = scls;
818 if (1 != SSCANF (value,
823 _("You must pass a number to the `%s' option.\n"),
825 return GNUNET_SYSERR;
830 _("You must pass a number below %u to the `%s' option.\n"),
831 (unsigned int) UINT16_MAX,
833 return GNUNET_SYSERR;
841 * Allow user to specify an uint16_t.
843 * @param shortName short name of the option
844 * @param name long name of the option
845 * @param argumentHelp help text for the option argument
846 * @param description long help text for the option
847 * @param[out] val set to the value specified at the command line
849 struct GNUNET_GETOPT_CommandLineOption
850 GNUNET_GETOPT_option_uint16 (char shortName,
852 const char *argumentHelp,
853 const char *description,
856 struct GNUNET_GETOPT_CommandLineOption clo = {
857 .shortName = shortName,
859 .argumentHelp = argumentHelp,
860 .description = description,
861 .require_argument = 1,
862 .processor = &set_uint16,
871 * Closure for #set_base32().
876 * Value to initialize (already allocated)
881 * Number of bytes expected for @e val.
888 * Set an option of type 'unsigned int' from the command line.
889 * A pointer to this function should be passed as part of the
890 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
891 * of this type. It should be followed by a pointer to a value of
892 * type 'unsigned int'.
894 * @param ctx command line processing context
895 * @param scls additional closure (will point to the 'unsigned int')
896 * @param option name of the option
897 * @param value actual value of the option as a string.
898 * @return #GNUNET_OK if parsing the value worked
901 set_base32 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
906 struct Base32Context *bc = scls;
910 GNUNET_STRINGS_string_to_data (value,
916 _("Argument `%s' malformed. Expected base32 (Crockford) encoded value.\n"),
918 return GNUNET_SYSERR;
925 * Helper function to clean up after
926 * #GNUNET_GETOPT_option_base32_fixed_size.
928 * @param cls value to GNUNET_free()
938 * Allow user to specify a binary value using Crockford
941 * @param shortName short name of the option
942 * @param name long name of the option
943 * @param argumentHelp help text for the option argument
944 * @param description long help text for the option
945 * @param[out] val binary value decoded from Crockford Base32-encoded argument
946 * @param val_size size of @a val in bytes
948 struct GNUNET_GETOPT_CommandLineOption
949 GNUNET_GETOPT_option_base32_fixed_size (char shortName,
951 const char *argumentHelp,
952 const char *description,
956 struct Base32Context *bc = GNUNET_new (struct Base32Context);
957 struct GNUNET_GETOPT_CommandLineOption clo = {
958 .shortName = shortName,
960 .argumentHelp = argumentHelp,
961 .description = description,
962 .require_argument = 1,
963 .processor = &set_base32,
969 bc->val_size = val_size;
975 * Make the given option mandatory.
977 * @param opt option to modify
978 * @return @a opt with the mandatory flag set.
980 struct GNUNET_GETOPT_CommandLineOption
981 GNUNET_GETOPT_option_mandatory (struct GNUNET_GETOPT_CommandLineOption opt)
983 opt.option_mandatory = 1;
988 /* end of getopt_helpers.c */