add way to mark options as mandatory, get tests to pass again
authorChristian Grothoff <christian@grothoff.org>
Wed, 15 Mar 2017 10:14:36 +0000 (11:14 +0100)
committerChristian Grothoff <christian@grothoff.org>
Wed, 15 Mar 2017 10:14:59 +0000 (11:14 +0100)
src/include/gnunet_getopt_lib.h
src/util/getopt.c
src/util/getopt_helpers.c
src/util/test_getopt.c
src/util/test_program.c

index bc2e079da1ca5be3b58bca483bf890363a1a95c0..c2bd72340db00d2b2e7bf1ad20ca36ff2cf0d497 100644 (file)
@@ -130,6 +130,11 @@ struct GNUNET_GETOPT_CommandLineOption
    */
   int require_argument;
 
+  /**
+   * Is the presence of this option mandatory?
+   */
+  int option_mandatory;
+
   /**
    * Handler for the option.
    */
@@ -388,11 +393,21 @@ struct GNUNET_GETOPT_CommandLineOption
 GNUNET_GETOPT_OPTION_CFG_FILE (char **fn);
 
 
+/**
+ * Make the given option mandatory.
+ *
+ * @param opt option to modify
+ * @return @a opt with the mandatory flag set.
+ */
+struct GNUNET_GETOPT_CommandLineOption
+GNUNET_GETOPT_OPTION_MANDATORY (struct GNUNET_GETOPT_CommandLineOption opt);
+
+
 /**
  * Marker for the end of the list of options.
  */
 #define GNUNET_GETOPT_OPTION_END \
-  { '\0', NULL, NULL, NULL, 0, NULL, NULL, NULL }
+  { '\0', NULL, NULL, NULL, 0, 0, NULL, NULL, NULL }
 
 
 /**
index 85f67500c85bd0317778287f3ea33934cd873edc..036e0f4be598d55f3d86d6ce76d2b6eb1a77dcb6 100644 (file)
@@ -881,6 +881,7 @@ GNUNET_GETOPT_run (const char *binaryOptions,
   int spos;
   int cont;
   int c;
+  uint8_t *seen;
 
   GNUNET_assert (argc > 0);
   GNoptind = 0;
@@ -893,6 +894,8 @@ GNUNET_GETOPT_run (const char *binaryOptions,
 
   long_options = GNUNET_new_array (count + 1,
                                    struct GNoption);
+  seen = GNUNET_new_array (count,
+                           uint8_t);
   shorts = GNUNET_malloc (count * 2 + 1);
   spos = 0;
   for (unsigned i = 0; i < count; i++)
@@ -934,6 +937,7 @@ GNUNET_GETOPT_run (const char *binaryOptions,
                                         allOptions[i].scls,
                                         allOptions[i].name,
                                         GNoptarg);
+        seen[i] = 1;
         break;
       }
     }
@@ -948,6 +952,20 @@ GNUNET_GETOPT_run (const char *binaryOptions,
   GNUNET_free (shorts);
   GNUNET_free (long_options);
 
+  if (GNUNET_YES == cont)
+  {
+    for (count = 0; NULL != allOptions[count].name; count++)
+      if ( (0 == seen[count]) &&
+           (allOptions[count].option_mandatory) )
+      {
+        FPRINTF (stderr,
+                 _("Missing mandatory option `%s'.\n"),
+                 allOptions[count].name);
+        cont = GNUNET_SYSERR;
+      }
+  }
+  GNUNET_free (seen);
+
   /* call cleaners, if available */
   for (count = 0; NULL != allOptions[count].name; count++)
     if (NULL != allOptions[count].cleaner)
index a94847a47fd44a07976061f7918aec74c402a6b2..76342a6c9c4384834780d6bd373038b668a3c94a 100644 (file)
@@ -357,7 +357,7 @@ set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
 {
   char **val = scls;
 
-  GNUNET_assert (value != NULL);
+  GNUNET_assert (NULL != value);
   GNUNET_free_non_null (*val);
   *val = GNUNET_strdup (value);
   return GNUNET_OK;
@@ -878,4 +878,18 @@ GNUNET_GETOPT_OPTION_SET_BASE32_FIXED_SIZE (char shortName,
 }
 
 
+/**
+ * Make the given option mandatory.
+ *
+ * @param opt option to modify
+ * @return @a opt with the mandatory flag set.
+ */
+struct GNUNET_GETOPT_CommandLineOption
+GNUNET_GETOPT_OPTION_MANDATORY (struct GNUNET_GETOPT_CommandLineOption opt)
+{
+  opt.option_mandatory = 1;
+  return opt;
+}
+
+
 /* end of getopt_helpers.c */
index faa6a07a19c75abbc7146ce2fd402314baa068ae..13cedd7f51786793c523ce7ad008fa71410c7b90 100644 (file)
@@ -136,13 +136,16 @@ testLogOpts ()
     GNUNET_GETOPT_OPTION_END
   };
 
-  if (5 != GNUNET_GETOPT_run ("test_getopt", logoptionlist, 5, myargv))
+  if (5 != GNUNET_GETOPT_run ("test_getopt",
+                              logoptionlist,
+                              5, myargv))
   {
     GNUNET_break (0);
     return 1;
   }
-  GNUNET_assert (fn != NULL);
-  if ((0 != strcmp (level, "WARNING")) || (0 != strcmp (fn, "filename")))
+  GNUNET_assert (NULL != fn);
+  if ( (0 != strcmp (level, "WARNING")) ||
+       (NULL == strstr (fn, "/filename")) )
   {
     GNUNET_break (0);
     GNUNET_free (level);
@@ -212,7 +215,9 @@ main (int argc, char *argv[])
 {
   int errCnt = 0;
 
-  GNUNET_log_setup ("test_getopt", "WARNING", NULL);
+  GNUNET_log_setup ("test_getopt",
+                    "WARNING",
+                    NULL);
   /* suppress output from -h, -v options */
 #ifndef MINGW
   GNUNET_break (0 == CLOSE (1));
index 669cee7bdc1ea4670c0f123f81bd4b3732051a9d..d206952af9ab1fb8a38b6926e3f1e8991a401f3a 100644 (file)
 #include "platform.h"
 #include "gnunet_util_lib.h"
 
-static int setme1, setme2;
-
-static struct GNUNET_GETOPT_CommandLineOption options1[] = {
-  {'n', "name", NULL, "description", 0, &GNUNET_GETOPT_set_one, &setme1},
-  GNUNET_GETOPT_OPTION_END
-};
-
-static struct GNUNET_GETOPT_CommandLineOption options2[] = {
-  {'n', "name", NULL, "description", 0, &GNUNET_GETOPT_set_one, &setme1},
-  {'N', "number", NULL, "description", 0, &GNUNET_GETOPT_set_one, &setme2},
-  GNUNET_GETOPT_OPTION_END
-};
-
-static struct GNUNET_GETOPT_CommandLineOption options3[] = {
-  {'N', "number", NULL, "description", 0, &GNUNET_GETOPT_set_one, &setme1},
-  {'n', "name", NULL, "description", 0, &GNUNET_GETOPT_set_one, &setme2},
-  GNUNET_GETOPT_OPTION_END
-};
-
-static struct GNUNET_GETOPT_CommandLineOption options4[] = {
-  {'n', "name", NULL, "description", 0, &GNUNET_GETOPT_set_one, &setme1},
-  {'n', "number", NULL, "description", 0, &GNUNET_GETOPT_set_one, &setme2},
-  GNUNET_GETOPT_OPTION_END
-};
+
+static int setme1;
+
+static int setme2;
+
 
 /**
  * Main function that will be run.
  */
-
 static void
-runner (void *cls, char *const *args, const char *cfgfile,
+runner (void *cls,
+        char *const *args,
+        const char *cfgfile,
         const struct GNUNET_CONFIGURATION_Handle *cfg)
 {
   int *ok = cls;
@@ -62,21 +44,16 @@ runner (void *cls, char *const *args, const char *cfgfile,
   GNUNET_assert (setme1 == 1);
   GNUNET_assert (0 == strcmp (args[0], "extra"));
   GNUNET_assert (args[1] == NULL);
-  GNUNET_assert (0 == strcmp (cfgfile, "test_program_data.conf"));
-
+  GNUNET_assert (NULL != strstr (cfgfile, "/test_program_data.conf"));
   *ok = 0;
 }
 
-/**
- * Main method, starts scheduler with task1,
- * checks that "ok" is correct at the end.
- */
-static int
-check ()
+
+int
+main (int argc, char *argv[])
 {
   int ok = 1;
-
-  char *const argv[] = {
+  char *const argvx[] = {
     "test_program",
     "-c",
     "test_program_data.conf",
@@ -86,33 +63,75 @@ check ()
     "extra",
     NULL
   };
+  struct GNUNET_GETOPT_CommandLineOption options1[] = {
+    GNUNET_GETOPT_OPTION_SET_ONE ('n',
+                                  "name",
+                                  "description",
+                                  &setme1),
+    GNUNET_GETOPT_OPTION_END
+  };
+  struct GNUNET_GETOPT_CommandLineOption options2[] = {
+    GNUNET_GETOPT_OPTION_SET_ONE ('n',
+                                  "name",
+                                  "description",
+                                  &setme1),
+    GNUNET_GETOPT_OPTION_SET_ONE ('N',
+                                  "number",
+                                  "description",
+                                  &setme2),
+    GNUNET_GETOPT_OPTION_END
+  };
+  struct GNUNET_GETOPT_CommandLineOption options3[] = {
+    GNUNET_GETOPT_OPTION_SET_ONE ('N',
+                                  "number",
+                                  "description",
+                                  &setme1),
+    GNUNET_GETOPT_OPTION_SET_ONE ('n',
+                                  "name",
+                                  "description",
+                                  &setme2),
+    GNUNET_GETOPT_OPTION_END
+  };
+  struct GNUNET_GETOPT_CommandLineOption options4[] = {
+    GNUNET_GETOPT_OPTION_SET_ONE ('n',
+                                  "name",
+                                  "description",
+                                  &setme1),
+    GNUNET_GETOPT_OPTION_SET_ONE ('n',
+                                  "name",
+                                  "description",
+                                  &setme2),
+    GNUNET_GETOPT_OPTION_END
+  };
 
+
+  GNUNET_log_setup ("test_program",
+                    "WARNING",
+                    NULL);
   GNUNET_assert (GNUNET_OK ==
-                 GNUNET_PROGRAM_run (7, argv, "test_program", "A test",
-                                     options1, &runner, &ok));
+                 GNUNET_PROGRAM_run (7, argvx,
+                                     "test_program",
+                                     "A test",
+                                     options1,
+                                     &runner, &ok));
 
   GNUNET_assert (GNUNET_OK ==
-                 GNUNET_PROGRAM_run (7, argv, "test_program", "A test",
-                                     options2, &runner, &ok));
+                 GNUNET_PROGRAM_run (7, argvx,
+                                     "test_program", "A test",
+                                     options2,
+                                     &runner, &ok));
   GNUNET_assert (GNUNET_OK ==
-                 GNUNET_PROGRAM_run (7, argv, "test_program", "A test",
-                                     options3, &runner, &ok));
+                 GNUNET_PROGRAM_run (7, argvx,
+                                     "test_program", "A test",
+                                     options3,
+                                     &runner, &ok));
   GNUNET_assert (GNUNET_OK ==
-                 GNUNET_PROGRAM_run (7, argv, "test_program", "A test",
-                                     options4, &runner, &ok));
+                 GNUNET_PROGRAM_run (7, argvx,
+                                     "test_program", "A test",
+                                     options4,
+                                     &runner, &ok));
 
   return ok;
 }
 
-int
-main (int argc, char *argv[])
-{
-  int ret = 0;
-
-  GNUNET_log_setup ("test_program", "WARNING", NULL);
-  ret += check ();
-
-  return ret;
-}
-
 /* end of test_program.c */