diff options
Diffstat (limited to 'src/util/getopt.c')
-rw-r--r-- | src/util/getopt.c | 72 |
1 files changed, 52 insertions, 20 deletions
diff --git a/src/util/getopt.c b/src/util/getopt.c index ff62dba9b..036e0f4be 100644 --- a/src/util/getopt.c +++ b/src/util/getopt.c | |||
@@ -26,7 +26,7 @@ USA. | |||
26 | 26 | ||
27 | 27 | ||
28 | This code was heavily modified for GNUnet. | 28 | This code was heavily modified for GNUnet. |
29 | Copyright Copyright (C) 2006 Christian Grothoff | 29 | Copyright Copyright (C) 2006, 2017 Christian Grothoff |
30 | */ | 30 | */ |
31 | 31 | ||
32 | /** | 32 | /** |
@@ -845,9 +845,13 @@ GN_getopt_internal (int argc, char *const *argv, const char *optstring, | |||
845 | } | 845 | } |
846 | } | 846 | } |
847 | 847 | ||
848 | |||
848 | static int | 849 | static int |
849 | GNgetopt_long (int argc, char *const *argv, const char *options, | 850 | GNgetopt_long (int argc, |
850 | const struct GNoption *long_options, int *opt_index) | 851 | char *const *argv, |
852 | const char *options, | ||
853 | const struct GNoption *long_options, | ||
854 | int *opt_index) | ||
851 | { | 855 | { |
852 | return GN_getopt_internal (argc, argv, options, long_options, opt_index, 0); | 856 | return GN_getopt_internal (argc, argv, options, long_options, opt_index, 0); |
853 | } | 857 | } |
@@ -867,16 +871,17 @@ GNgetopt_long (int argc, char *const *argv, const char *options, | |||
867 | int | 871 | int |
868 | GNUNET_GETOPT_run (const char *binaryOptions, | 872 | GNUNET_GETOPT_run (const char *binaryOptions, |
869 | const struct GNUNET_GETOPT_CommandLineOption *allOptions, | 873 | const struct GNUNET_GETOPT_CommandLineOption *allOptions, |
870 | unsigned int argc, char *const *argv) | 874 | unsigned int argc, |
875 | char *const *argv) | ||
871 | { | 876 | { |
872 | struct GNoption *long_options; | 877 | struct GNoption *long_options; |
873 | struct GNUNET_GETOPT_CommandLineProcessorContext clpc; | 878 | struct GNUNET_GETOPT_CommandLineProcessorContext clpc; |
874 | int count; | 879 | int count; |
875 | int i; | ||
876 | char *shorts; | 880 | char *shorts; |
877 | int spos; | 881 | int spos; |
878 | int cont; | 882 | int cont; |
879 | int c; | 883 | int c; |
884 | uint8_t *seen; | ||
880 | 885 | ||
881 | GNUNET_assert (argc > 0); | 886 | GNUNET_assert (argc > 0); |
882 | GNoptind = 0; | 887 | GNoptind = 0; |
@@ -885,13 +890,15 @@ GNUNET_GETOPT_run (const char *binaryOptions, | |||
885 | clpc.allOptions = allOptions; | 890 | clpc.allOptions = allOptions; |
886 | clpc.argv = argv; | 891 | clpc.argv = argv; |
887 | clpc.argc = argc; | 892 | clpc.argc = argc; |
888 | count = 0; | 893 | for (count = 0; NULL != allOptions[count].name; count++) ; |
889 | while (allOptions[count].name != NULL) | 894 | |
890 | count++; | 895 | long_options = GNUNET_new_array (count + 1, |
891 | long_options = GNUNET_malloc (sizeof (struct GNoption) * (count + 1)); | 896 | struct GNoption); |
897 | seen = GNUNET_new_array (count, | ||
898 | uint8_t); | ||
892 | shorts = GNUNET_malloc (count * 2 + 1); | 899 | shorts = GNUNET_malloc (count * 2 + 1); |
893 | spos = 0; | 900 | spos = 0; |
894 | for (i = 0; i < count; i++) | 901 | for (unsigned i = 0; i < count; i++) |
895 | { | 902 | { |
896 | long_options[i].name = allOptions[i].name; | 903 | long_options[i].name = allOptions[i].name; |
897 | long_options[i].has_arg = allOptions[i].require_argument; | 904 | long_options[i].has_arg = allOptions[i].require_argument; |
@@ -907,13 +914,17 @@ GNUNET_GETOPT_run (const char *binaryOptions, | |||
907 | long_options[count].val = '\0'; | 914 | long_options[count].val = '\0'; |
908 | shorts[spos] = '\0'; | 915 | shorts[spos] = '\0'; |
909 | cont = GNUNET_OK; | 916 | cont = GNUNET_OK; |
917 | |||
910 | /* main getopt loop */ | 918 | /* main getopt loop */ |
911 | while (cont == GNUNET_OK) | 919 | while (GNUNET_OK == cont) |
912 | { | 920 | { |
913 | int option_index = 0; | 921 | int option_index = 0; |
922 | unsigned int i; | ||
914 | 923 | ||
915 | c = GNgetopt_long (argc, argv, shorts, long_options, &option_index); | 924 | c = GNgetopt_long (argc, argv, |
916 | 925 | shorts, | |
926 | long_options, | ||
927 | &option_index); | ||
917 | if (c == GNUNET_SYSERR) | 928 | if (c == GNUNET_SYSERR) |
918 | break; /* No more flags to process */ | 929 | break; /* No more flags to process */ |
919 | 930 | ||
@@ -922,25 +933,46 @@ GNUNET_GETOPT_run (const char *binaryOptions, | |||
922 | clpc.currentArgument = GNoptind - 1; | 933 | clpc.currentArgument = GNoptind - 1; |
923 | if ((char) c == allOptions[i].shortName) | 934 | if ((char) c == allOptions[i].shortName) |
924 | { | 935 | { |
925 | cont = | 936 | cont = allOptions[i].processor (&clpc, |
926 | allOptions[i].processor (&clpc, allOptions[i].scls, | 937 | allOptions[i].scls, |
927 | allOptions[i].name, GNoptarg); | 938 | allOptions[i].name, |
939 | GNoptarg); | ||
940 | seen[i] = 1; | ||
928 | break; | 941 | break; |
929 | } | 942 | } |
930 | } | 943 | } |
931 | if (i == count) | 944 | if (i == count) |
932 | { | 945 | { |
933 | FPRINTF (stderr, _("Use %s to get a list of options.\n"), "--help"); | 946 | FPRINTF (stderr, |
947 | _("Use %s to get a list of options.\n"), | ||
948 | "--help"); | ||
934 | cont = GNUNET_SYSERR; | 949 | cont = GNUNET_SYSERR; |
935 | } | 950 | } |
936 | } | 951 | } |
937 | |||
938 | GNUNET_free (shorts); | 952 | GNUNET_free (shorts); |
939 | GNUNET_free (long_options); | 953 | GNUNET_free (long_options); |
940 | if (cont != GNUNET_OK) | 954 | |
955 | if (GNUNET_YES == cont) | ||
941 | { | 956 | { |
942 | return cont; | 957 | for (count = 0; NULL != allOptions[count].name; count++) |
958 | if ( (0 == seen[count]) && | ||
959 | (allOptions[count].option_mandatory) ) | ||
960 | { | ||
961 | FPRINTF (stderr, | ||
962 | _("Missing mandatory option `%s'.\n"), | ||
963 | allOptions[count].name); | ||
964 | cont = GNUNET_SYSERR; | ||
965 | } | ||
943 | } | 966 | } |
967 | GNUNET_free (seen); | ||
968 | |||
969 | /* call cleaners, if available */ | ||
970 | for (count = 0; NULL != allOptions[count].name; count++) | ||
971 | if (NULL != allOptions[count].cleaner) | ||
972 | allOptions[count].cleaner (allOptions[count].scls); | ||
973 | |||
974 | if (GNUNET_OK != cont) | ||
975 | return cont; | ||
944 | return GNoptind; | 976 | return GNoptind; |
945 | } | 977 | } |
946 | 978 | ||