aboutsummaryrefslogtreecommitdiff
path: root/src/lib/util/getopt_helpers.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/util/getopt_helpers.c')
-rw-r--r--src/lib/util/getopt_helpers.c1017
1 files changed, 1017 insertions, 0 deletions
diff --git a/src/lib/util/getopt_helpers.c b/src/lib/util/getopt_helpers.c
new file mode 100644
index 000000000..31020f185
--- /dev/null
+++ b/src/lib/util/getopt_helpers.c
@@ -0,0 +1,1017 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2006, 2011, 2020 GNUnet e.V.
4
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.
9
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.
14
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/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file src/util/getopt_helpers.c
23 * @brief implements command line that sets option
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_util_lib.h"
29
30#define LOG(kind, ...) GNUNET_log_from (kind, "util-getopt", __VA_ARGS__)
31
32
33/**
34 * Print out program version (implements --version).
35 *
36 * @param ctx command line processing context
37 * @param scls additional closure (points to version string)
38 * @param option name of the option
39 * @param value not used (NULL)
40 * @return #GNUNET_NO (do not continue, not an error)
41 */
42static enum GNUNET_GenericReturnValue
43print_version (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
44 void *scls,
45 const char *option,
46 const char *value)
47{
48 const char *version = scls;
49
50 (void) option;
51 (void) value;
52 printf ("%s v%s\n", ctx->binaryName, version);
53 return GNUNET_NO;
54}
55
56
57struct GNUNET_GETOPT_CommandLineOption
58GNUNET_GETOPT_option_version (const char *version)
59{
60 struct GNUNET_GETOPT_CommandLineOption clo = {
61 .shortName = 'v',
62 .name = "version",
63 .description = gettext_noop (
64 "print the version number"),
65 .option_exclusive = 1,
66 .processor = &print_version,
67 .scls = (void *) version
68 };
69
70 return clo;
71}
72
73
74/**
75 * At what offset does the help text start?
76 */
77#define BORDER 29
78
79/**
80 * Print out details on command line options (implements --help).
81 *
82 * @param ctx command line processing context
83 * @param scls additional closure (points to about text)
84 * @param option name of the option
85 * @param value not used (NULL)
86 * @return #GNUNET_NO (do not continue, not an error)
87 */
88static enum GNUNET_GenericReturnValue
89format_help (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
90 void *scls,
91 const char *option,
92 const char *value)
93{
94 const char *about = scls;
95 size_t slen;
96 unsigned int i;
97 int j;
98 size_t ml;
99 size_t p;
100 char *scp;
101 const char *trans;
102 const struct GNUNET_GETOPT_CommandLineOption *opt;
103 const struct GNUNET_OS_ProjectData *pd;
104
105 (void) option;
106 (void) value;
107 if (NULL != about)
108 {
109 printf ("%s\n%s\n", ctx->binaryOptions, gettext (about));
110 printf (_ (
111 "Arguments mandatory for long options are also mandatory for short options.\n"));
112 }
113 i = 0;
114 opt = ctx->allOptions;
115 while (NULL != opt[i].description)
116 {
117 if (opt[i].shortName == '\0')
118 printf (" ");
119 else
120 printf (" -%c, ", opt[i].shortName);
121 printf ("--%s", opt[i].name);
122 slen = 8 + strlen (opt[i].name);
123 if (NULL != opt[i].argumentHelp)
124 {
125 printf ("=%s", opt[i].argumentHelp);
126 slen += 1 + strlen (opt[i].argumentHelp);
127 }
128 if (slen > BORDER)
129 {
130 printf ("\n%*s", BORDER, "");
131 slen = BORDER;
132 }
133 if (slen < BORDER)
134 {
135 printf ("%*s", (int) (BORDER - slen), "");
136 slen = BORDER;
137 }
138 if (0 < strlen (opt[i].description))
139 trans = gettext (opt[i].description);
140 else
141 trans = "";
142 ml = strlen (trans);
143 p = 0;
144OUTER:
145 while (ml - p > 78 - slen)
146 {
147 for (j = p + 78 - slen; j > (int) p; j--)
148 {
149 if (isspace ((unsigned char) trans[j]))
150 {
151 scp = GNUNET_malloc (j - p + 1);
152 GNUNET_memcpy (scp, &trans[p], j - p);
153 scp[j - p] = '\0';
154 printf ("%s\n%*s", scp, BORDER + 2, "");
155 GNUNET_free (scp);
156 p = j + 1;
157 slen = BORDER + 2;
158 goto OUTER;
159 }
160 }
161 /* could not find space to break line */
162 scp = GNUNET_malloc (78 - slen + 1);
163 GNUNET_memcpy (scp, &trans[p], 78 - slen);
164 scp[78 - slen] = '\0';
165 printf ("%s\n%*s", scp, BORDER + 2, "");
166 GNUNET_free (scp);
167 slen = BORDER + 2;
168 p = p + 78 - slen;
169 }
170 /* print rest */
171 if (p < ml)
172 printf ("%s\n", &trans[p]);
173 if (strlen (trans) == 0)
174 printf ("\n");
175 i++;
176 }
177 pd = GNUNET_OS_project_data_get ();
178 printf ("\n"
179 "Report bugs to %s.\n"
180 "Home page: %s\n",
181 pd->bug_email,
182 pd->homepage);
183
184 if (0 != pd->is_gnu)
185 printf ("General help using GNU software: http://www.gnu.org/gethelp/\n");
186
187 return GNUNET_NO;
188}
189
190
191struct GNUNET_GETOPT_CommandLineOption
192GNUNET_GETOPT_option_help (const char *about)
193{
194 struct GNUNET_GETOPT_CommandLineOption clo = {
195 .shortName = 'h',
196 .name = "help",
197 .description = gettext_noop (
198 "print this help"),
199 .option_exclusive = 1,
200 .processor = format_help,
201 .scls = (void *) about
202 };
203
204 return clo;
205}
206
207
208/**
209 * Set an option of type 'unsigned int' from the command line. Each
210 * time the option flag is given, the value is incremented by one.
211 * A pointer to this function should be passed as part of the
212 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
213 * of this type. It should be followed by a pointer to a value of
214 * type 'int'.
215 *
216 * @param ctx command line processing context
217 * @param scls additional closure (will point to the 'unsigned int')
218 * @param option name of the option
219 * @param value not used (NULL)
220 * @return #GNUNET_OK
221 */
222static enum GNUNET_GenericReturnValue
223increment_value (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
224 void *scls,
225 const char *option,
226 const char *value)
227{
228 unsigned int *val = scls;
229
230 (void) ctx;
231 (void) option;
232 (void) value;
233 (*val)++;
234 return GNUNET_OK;
235}
236
237
238struct GNUNET_GETOPT_CommandLineOption
239GNUNET_GETOPT_option_increment_uint (char shortName,
240 const char *name,
241 const char *description,
242 unsigned int *val)
243{
244 struct GNUNET_GETOPT_CommandLineOption clo = {
245 .shortName = shortName,
246 .name = name,
247 .description = description,
248 .processor = &increment_value,
249 .scls = (void *) val
250 };
251
252 return clo;
253}
254
255
256struct GNUNET_GETOPT_CommandLineOption
257GNUNET_GETOPT_option_verbose (unsigned int *level)
258{
259 struct GNUNET_GETOPT_CommandLineOption clo = {
260 .shortName = 'V',
261 .name = "verbose",
262 .description =
263 gettext_noop ("be verbose"),
264 .processor = &increment_value,
265 .scls = (void *) level
266 };
267
268 return clo;
269}
270
271
272/**
273 * Set an option of type 'int' from the command line to 1 if the
274 * given option is present.
275 * A pointer to this function should be passed as part of the
276 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
277 * of this type. It should be followed by a pointer to a value of
278 * type 'int'.
279 *
280 * @param ctx command line processing context
281 * @param scls additional closure (will point to the 'int')
282 * @param option name of the option
283 * @param value not used (NULL)
284 * @return #GNUNET_OK
285 */
286static enum GNUNET_GenericReturnValue
287set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
288 void *scls,
289 const char *option,
290 const char *value)
291{
292 int *val = scls;
293
294 (void) ctx;
295 (void) option;
296 (void) value;
297 *val = 1;
298 return GNUNET_OK;
299}
300
301
302struct GNUNET_GETOPT_CommandLineOption
303GNUNET_GETOPT_option_flag (char shortName,
304 const char *name,
305 const char *description,
306 int *val)
307{
308 struct GNUNET_GETOPT_CommandLineOption clo = {
309 .shortName = shortName,
310 .name = name,
311 .description = description,
312 .processor = &set_one,
313 .scls = (void *) val
314 };
315
316 return clo;
317}
318
319
320/**
321 * Set an option of type 'char *' from the command line.
322 * A pointer to this function should be passed as part of the
323 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
324 * of this type. It should be followed by a pointer to a value of
325 * type 'char *', which will be allocated with the requested string.
326 *
327 * @param ctx command line processing context
328 * @param scls additional closure (will point to the 'char *',
329 * which will be allocated)
330 * @param option name of the option
331 * @param value actual value of the option (a string)
332 * @return #GNUNET_OK
333 */
334static enum GNUNET_GenericReturnValue
335set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
336 void *scls,
337 const char *option,
338 const char *value)
339{
340 char **val = scls;
341
342 (void) ctx;
343 (void) option;
344 GNUNET_assert (NULL != value);
345 GNUNET_free (*val);
346 *val = GNUNET_strdup (value);
347 return GNUNET_OK;
348}
349
350
351struct GNUNET_GETOPT_CommandLineOption
352GNUNET_GETOPT_option_string (char shortName,
353 const char *name,
354 const char *argumentHelp,
355 const char *description,
356 char **str)
357{
358 struct GNUNET_GETOPT_CommandLineOption clo = {
359 .shortName = shortName,
360 .name = name,
361 .argumentHelp = argumentHelp,
362 .description = description,
363 .require_argument = 1,
364 .processor = &set_string,
365 .scls = (void *) str
366 };
367
368 return clo;
369}
370
371
372struct GNUNET_GETOPT_CommandLineOption
373GNUNET_GETOPT_option_loglevel (char **level)
374{
375 struct GNUNET_GETOPT_CommandLineOption clo = {
376 .shortName = 'L',
377 .name = "log",
378 .argumentHelp = "LOGLEVEL",
379 .description = gettext_noop ("configure logging to use LOGLEVEL"),
380 .require_argument = 1,
381 .processor = &set_string,
382 .scls = (void *) level
383 };
384
385 return clo;
386}
387
388
389/**
390 * Set an option of type 'char *' from the command line with
391 * filename expansion a la #GNUNET_STRINGS_filename_expand().
392 *
393 * @param ctx command line processing context
394 * @param scls additional closure (will point to the `char *`,
395 * which will be allocated)
396 * @param option name of the option
397 * @param value actual value of the option (a string)
398 * @return #GNUNET_OK
399 */
400static enum GNUNET_GenericReturnValue
401set_filename (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
402 void *scls,
403 const char *option,
404 const char *value)
405{
406 char **val = scls;
407
408 (void) ctx;
409 (void) option;
410 GNUNET_assert (NULL != value);
411 GNUNET_free (*val);
412 *val = GNUNET_STRINGS_filename_expand (value);
413 return GNUNET_OK;
414}
415
416
417struct GNUNET_GETOPT_CommandLineOption
418GNUNET_GETOPT_option_filename (char shortName,
419 const char *name,
420 const char *argumentHelp,
421 const char *description,
422 char **str)
423{
424 struct GNUNET_GETOPT_CommandLineOption clo = {
425 .shortName = shortName,
426 .name = name,
427 .argumentHelp = argumentHelp,
428 .description = description,
429 .require_argument = 1,
430 .processor = &set_filename,
431 .scls = (void *) str
432 };
433
434 return clo;
435}
436
437
438struct GNUNET_GETOPT_CommandLineOption
439GNUNET_GETOPT_option_logfile (char **logfn)
440{
441 struct GNUNET_GETOPT_CommandLineOption clo = {
442 .shortName = 'l',
443 .name = "logfile",
444 .argumentHelp = "FILENAME",
445 .description =
446 gettext_noop ("configure logging to write logs to FILENAME"),
447 .require_argument = 1,
448 .processor = &set_filename,
449 .scls = (void *) logfn
450 };
451
452 return clo;
453}
454
455
456struct GNUNET_GETOPT_CommandLineOption
457GNUNET_GETOPT_option_cfgfile (char **fn)
458{
459 struct GNUNET_GETOPT_CommandLineOption clo = {
460 .shortName = 'c',
461 .name = "config",
462 .argumentHelp = "FILENAME",
463 .description = gettext_noop ("use configuration file FILENAME"),
464 .require_argument = 1,
465 .processor = &set_filename,
466 .scls = (void *) fn
467 };
468
469 return clo;
470}
471
472
473/**
474 * Set an option of type 'unsigned long long' from the command line.
475 * A pointer to this function should be passed as part of the
476 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
477 * of this type. It should be followed by a pointer to a value of
478 * type 'unsigned long long'.
479 *
480 * @param ctx command line processing context
481 * @param scls additional closure (will point to the 'unsigned long long')
482 * @param option name of the option
483 * @param value actual value of the option as a string.
484 * @return #GNUNET_OK if parsing the value worked
485 */
486static enum GNUNET_GenericReturnValue
487set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
488 void *scls,
489 const char *option,
490 const char *value)
491{
492 unsigned long long *val = scls;
493 char dummy[2];
494
495 (void) ctx;
496 if (1 != sscanf (value, "%llu%1s", val, dummy))
497 {
498 fprintf (stderr,
499 _ ("You must pass a number to the `%s' option.\n"),
500 option);
501 return GNUNET_SYSERR;
502 }
503 return GNUNET_OK;
504}
505
506
507struct GNUNET_GETOPT_CommandLineOption
508GNUNET_GETOPT_option_ulong (char shortName,
509 const char *name,
510 const char *argumentHelp,
511 const char *description,
512 unsigned long long *val)
513{
514 struct GNUNET_GETOPT_CommandLineOption clo = {
515 .shortName = shortName,
516 .name = name,
517 .argumentHelp = argumentHelp,
518 .description = description,
519 .require_argument = 1,
520 .processor = &set_ulong,
521 .scls = (void *) val
522 };
523
524 return clo;
525}
526
527
528/**
529 * Set an option of type 'struct GNUNET_TIME_Relative' from the command line.
530 * A pointer to this function should be passed as part of the
531 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
532 * of this type. It should be followed by a pointer to a value of
533 * type 'struct GNUNET_TIME_Relative'.
534 *
535 * @param ctx command line processing context
536 * @param scls additional closure (will point to the 'struct GNUNET_TIME_Relative')
537 * @param option name of the option
538 * @param value actual value of the option as a string.
539 * @return #GNUNET_OK if parsing the value worked
540 */
541static enum GNUNET_GenericReturnValue
542set_timetravel_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
543 void *scls,
544 const char *option,
545 const char *value)
546{
547 long long delta;
548 long long minus;
549 struct GNUNET_TIME_Relative rt;
550
551 (void) scls;
552 (void) ctx;
553 while (isspace (value[0]))
554 value++;
555 minus = 1;
556 if (value[0] == '-')
557 {
558 minus = -1;
559 value++;
560 }
561 else if (value[0] == '+')
562 {
563 value++;
564 }
565 if (GNUNET_OK !=
566 GNUNET_STRINGS_fancy_time_to_relative (value,
567 &rt))
568 {
569 fprintf (stderr,
570 _ (
571 "You must pass a relative time (optionally with sign) to the `%s' option.\n"),
572 option);
573 return GNUNET_SYSERR;
574 }
575 if (rt.rel_value_us > LLONG_MAX)
576 {
577 fprintf (stderr,
578 _ ("Value given for time travel `%s' option is too big.\n"),
579 option);
580 return GNUNET_SYSERR;
581 }
582 delta = (long long) rt.rel_value_us;
583 delta *= minus;
584 GNUNET_TIME_set_offset (delta);
585 return GNUNET_OK;
586}
587
588
589struct GNUNET_GETOPT_CommandLineOption
590GNUNET_GETOPT_option_timetravel (char shortName,
591 const char *name)
592{
593 struct GNUNET_GETOPT_CommandLineOption clo = {
594 .shortName = shortName,
595 .name = name,
596 .argumentHelp = _ ("[+/-]MICROSECONDS"),
597 .description = _ (
598 "modify system time by given offset (for debugging/testing only)"),
599 .require_argument = 1,
600 .processor = &set_timetravel_time
601 };
602
603 return clo;
604}
605
606
607/**
608 * Set an option of type 'struct GNUNET_TIME_Relative' from the command line.
609 * A pointer to this function should be passed as part of the
610 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
611 * of this type. It should be followed by a pointer to a value of
612 * type 'struct GNUNET_TIME_Relative'.
613 *
614 * @param ctx command line processing context
615 * @param scls additional closure (will point to the 'struct GNUNET_TIME_Relative')
616 * @param option name of the option
617 * @param value actual value of the option as a string.
618 * @return #GNUNET_OK if parsing the value worked
619 */
620static enum GNUNET_GenericReturnValue
621set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
622 void *scls,
623 const char *option,
624 const char *value)
625{
626 struct GNUNET_TIME_Relative *val = scls;
627
628 (void) ctx;
629 if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_relative (value, val))
630 {
631 fprintf (stderr,
632 _ ("You must pass relative time to the `%s' option.\n"),
633 option);
634 return GNUNET_SYSERR;
635 }
636 return GNUNET_OK;
637}
638
639
640struct GNUNET_GETOPT_CommandLineOption
641GNUNET_GETOPT_option_relative_time (char shortName,
642 const char *name,
643 const char *argumentHelp,
644 const char *description,
645 struct GNUNET_TIME_Relative *val)
646{
647 struct GNUNET_GETOPT_CommandLineOption clo = {
648 .shortName = shortName,
649 .name = name,
650 .argumentHelp = argumentHelp,
651 .description = description,
652 .require_argument = 1,
653 .processor = &set_relative_time,
654 .scls = (void *) val
655 };
656
657 return clo;
658}
659
660
661/**
662 * Set an option of type 'struct GNUNET_TIME_Absolute' from the command line.
663 * A pointer to this function should be passed as part of the
664 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
665 * of this type. It should be followed by a pointer to a value of
666 * type 'struct GNUNET_TIME_Absolute'.
667 *
668 * @param ctx command line processing context
669 * @param scls additional closure (will point to the `struct GNUNET_TIME_Absolute`)
670 * @param option name of the option
671 * @param value actual value of the option as a string.
672 * @return #GNUNET_OK if parsing the value worked
673 */
674static enum GNUNET_GenericReturnValue
675set_absolute_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
676 void *scls,
677 const char *option,
678 const char *value)
679{
680 struct GNUNET_TIME_Absolute *val = scls;
681
682 (void) ctx;
683 if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_absolute (value, val))
684 {
685 fprintf (stderr,
686 _ ("You must pass absolute time to the `%s' option.\n"),
687 option);
688 return GNUNET_SYSERR;
689 }
690 return GNUNET_OK;
691}
692
693
694struct GNUNET_GETOPT_CommandLineOption
695GNUNET_GETOPT_option_absolute_time (char shortName,
696 const char *name,
697 const char *argumentHelp,
698 const char *description,
699 struct GNUNET_TIME_Absolute *val)
700{
701 struct GNUNET_GETOPT_CommandLineOption clo = {
702 .shortName = shortName,
703 .name = name,
704 .argumentHelp = argumentHelp,
705 .description = description,
706 .require_argument = 1,
707 .processor = &set_absolute_time,
708 .scls = (void *) val
709 };
710
711 return clo;
712}
713
714
715/**
716 * Set an option of type 'struct GNUNET_TIME_Timestamp' from the command line.
717 * A pointer to this function should be passed as part of the
718 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
719 * of this type. It should be followed by a pointer to a value of
720 * type 'struct GNUNET_TIME_Absolute'.
721 *
722 * @param ctx command line processing context
723 * @param scls additional closure (will point to the `struct GNUNET_TIME_Absolute`)
724 * @param option name of the option
725 * @param value actual value of the option as a string.
726 * @return #GNUNET_OK if parsing the value worked
727 */
728static enum GNUNET_GenericReturnValue
729set_timestamp (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
730 void *scls,
731 const char *option,
732 const char *value)
733{
734 struct GNUNET_TIME_Timestamp *t = scls;
735 struct GNUNET_TIME_Absolute abs;
736
737 (void) ctx;
738 if (GNUNET_OK !=
739 GNUNET_STRINGS_fancy_time_to_absolute (value,
740 &abs))
741 {
742 fprintf (stderr,
743 _ ("You must pass a timestamp to the `%s' option.\n"),
744 option);
745 return GNUNET_SYSERR;
746 }
747 if (0 != abs.abs_value_us % GNUNET_TIME_UNIT_SECONDS.rel_value_us)
748 {
749 fprintf (stderr,
750 _ ("The maximum precision allowed for timestamps is seconds.\n"));
751 return GNUNET_SYSERR;
752 }
753 t->abs_time = abs;
754 return GNUNET_OK;
755}
756
757
758struct GNUNET_GETOPT_CommandLineOption
759GNUNET_GETOPT_option_timestamp (char shortName,
760 const char *name,
761 const char *argumentHelp,
762 const char *description,
763 struct GNUNET_TIME_Timestamp *val)
764{
765 struct GNUNET_GETOPT_CommandLineOption clo = {
766 .shortName = shortName,
767 .name = name,
768 .argumentHelp = argumentHelp,
769 .description = description,
770 .require_argument = 1,
771 .processor = &set_timestamp,
772 .scls = (void *) val
773 };
774
775 return clo;
776}
777
778
779/**
780 * Set an option of type 'unsigned int' from the command line.
781 * A pointer to this function should be passed as part of the
782 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
783 * of this type. It should be followed by a pointer to a value of
784 * type 'unsigned int'.
785 *
786 * @param ctx command line processing context
787 * @param scls additional closure (will point to the 'unsigned int')
788 * @param option name of the option
789 * @param value actual value of the option as a string.
790 * @return #GNUNET_OK if parsing the value worked
791 */
792static enum GNUNET_GenericReturnValue
793set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
794 void *scls,
795 const char *option,
796 const char *value)
797{
798 unsigned int *val = scls;
799 char dummy[2];
800
801 (void) ctx;
802 if ('-' == *value)
803 {
804 fprintf (stderr,
805 _ (
806 "Your input for the '%s' option has to be a non negative number\n"),
807 option);
808 return GNUNET_SYSERR;
809 }
810 if (1 != sscanf (value, "%u%1s", val, dummy))
811 {
812 fprintf (stderr,
813 _ ("You must pass a number to the `%s' option.\n"),
814 option);
815 return GNUNET_SYSERR;
816 }
817 return GNUNET_OK;
818}
819
820
821struct GNUNET_GETOPT_CommandLineOption
822GNUNET_GETOPT_option_uint (char shortName,
823 const char *name,
824 const char *argumentHelp,
825 const char *description,
826 unsigned int *val)
827{
828 struct GNUNET_GETOPT_CommandLineOption clo = {
829 .shortName = shortName,
830 .name = name,
831 .argumentHelp = argumentHelp,
832 .description = description,
833 .require_argument = 1,
834 .processor = &set_uint,
835 .scls = (void *) val
836 };
837
838 return clo;
839}
840
841
842/**
843 * Set an option of type 'uint16_t' from the command line.
844 * A pointer to this function should be passed as part of the
845 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
846 * of this type. It should be followed by a pointer to a value of
847 * type 'uint16_t'.
848 *
849 * @param ctx command line processing context
850 * @param scls additional closure (will point to the 'unsigned int')
851 * @param option name of the option
852 * @param value actual value of the option as a string.
853 * @return #GNUNET_OK if parsing the value worked
854 */
855static enum GNUNET_GenericReturnValue
856set_uint16 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
857 void *scls,
858 const char *option,
859 const char *value)
860{
861 uint16_t *val = scls;
862 unsigned int v;
863 char dummy[2];
864
865 (void) ctx;
866 if (1 != sscanf (value, "%u%1s", &v, dummy))
867 {
868 fprintf (stderr,
869 _ ("You must pass a number to the `%s' option.\n"),
870 option);
871 return GNUNET_SYSERR;
872 }
873 if (v > UINT16_MAX)
874 {
875 fprintf (stderr,
876 _ ("You must pass a number below %u to the `%s' option.\n"),
877 (unsigned int) UINT16_MAX,
878 option);
879 return GNUNET_SYSERR;
880 }
881 *val = (uint16_t) v;
882 return GNUNET_OK;
883}
884
885
886struct GNUNET_GETOPT_CommandLineOption
887GNUNET_GETOPT_option_uint16 (char shortName,
888 const char *name,
889 const char *argumentHelp,
890 const char *description,
891 uint16_t *val)
892{
893 struct GNUNET_GETOPT_CommandLineOption clo = {
894 .shortName = shortName,
895 .name = name,
896 .argumentHelp = argumentHelp,
897 .description = description,
898 .require_argument = 1,
899 .processor = &set_uint16,
900 .scls = (void *) val
901 };
902
903 return clo;
904}
905
906
907/**
908 * Closure for #set_base32().
909 */
910struct Base32Context
911{
912 /**
913 * Value to initialize (already allocated)
914 */
915 void *val;
916
917 /**
918 * Number of bytes expected for @e val.
919 */
920 size_t val_size;
921};
922
923
924/**
925 * Set an option of type 'unsigned int' from the command line.
926 * A pointer to this function should be passed as part of the
927 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
928 * of this type. It should be followed by a pointer to a value of
929 * type 'unsigned int'.
930 *
931 * @param ctx command line processing context
932 * @param scls additional closure (will point to the 'unsigned int')
933 * @param option name of the option
934 * @param value actual value of the option as a string.
935 * @return #GNUNET_OK if parsing the value worked
936 */
937static enum GNUNET_GenericReturnValue
938set_base32 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
939 void *scls,
940 const char *option,
941 const char *value)
942{
943 struct Base32Context *bc = scls;
944
945 (void) ctx;
946 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (value,
947 strlen (value),
948 bc->val,
949 bc->val_size))
950 {
951 fprintf (
952 stderr,
953 _ (
954 "Argument `%s' malformed. Expected base32 (Crockford) encoded value.\n"),
955 option);
956 return GNUNET_SYSERR;
957 }
958 return GNUNET_OK;
959}
960
961
962/**
963 * Helper function to clean up after
964 * #GNUNET_GETOPT_option_base32_fixed_size.
965 *
966 * @param cls value to GNUNET_free()
967 */
968static void
969free_bc (void *cls)
970{
971 GNUNET_free (cls);
972}
973
974
975struct GNUNET_GETOPT_CommandLineOption
976GNUNET_GETOPT_option_base32_fixed_size (char shortName,
977 const char *name,
978 const char *argumentHelp,
979 const char *description,
980 void *val,
981 size_t val_size)
982{
983 struct Base32Context *bc = GNUNET_new (struct Base32Context);
984 struct GNUNET_GETOPT_CommandLineOption clo = {
985 .shortName = shortName,
986 .name = name,
987 .argumentHelp = argumentHelp,
988 .description = description,
989 .require_argument = 1,
990 .processor = &set_base32,
991 .cleaner = &free_bc,
992 .scls = (void *) bc
993 };
994
995 bc->val = val;
996 bc->val_size = val_size;
997 return clo;
998}
999
1000
1001struct GNUNET_GETOPT_CommandLineOption
1002GNUNET_GETOPT_option_mandatory (struct GNUNET_GETOPT_CommandLineOption opt)
1003{
1004 opt.option_mandatory = 1;
1005 return opt;
1006}
1007
1008
1009struct GNUNET_GETOPT_CommandLineOption
1010GNUNET_GETOPT_option_exclusive (struct GNUNET_GETOPT_CommandLineOption opt)
1011{
1012 opt.option_exclusive = 1;
1013 return opt;
1014}
1015
1016
1017/* end of getopt_helpers.c */