aboutsummaryrefslogtreecommitdiff
path: root/src/util/getopt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/getopt.c')
-rw-r--r--src/util/getopt.c72
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
28This code was heavily modified for GNUnet. 28This code was heavily modified for GNUnet.
29Copyright Copyright (C) 2006 Christian Grothoff 29Copyright 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
848static int 849static int
849GNgetopt_long (int argc, char *const *argv, const char *options, 850GNgetopt_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,
867int 871int
868GNUNET_GETOPT_run (const char *binaryOptions, 872GNUNET_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