summaryrefslogtreecommitdiff
path: root/ACE/tests/Get_Opt_Test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/tests/Get_Opt_Test.cpp')
-rw-r--r--ACE/tests/Get_Opt_Test.cpp346
1 files changed, 346 insertions, 0 deletions
diff --git a/ACE/tests/Get_Opt_Test.cpp b/ACE/tests/Get_Opt_Test.cpp
new file mode 100644
index 00000000000..f9d4442344b
--- /dev/null
+++ b/ACE/tests/Get_Opt_Test.cpp
@@ -0,0 +1,346 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = DESCRIPTION
+// This program tests both the short and long option support in
+// <ACE_Get_Opt>, and demonstrates how to use it.
+//
+// = AUTHOR
+// Don Hinton <dhinton@dresystems.com>
+//
+// ============================================================================
+
+#include "tests/test_config.h"
+#include "ace/Get_Opt.h"
+#include "ace/ARGV.h"
+#include "ace/SString.h"
+#include "ace/OS_NS_stdlib.h"
+#include "tests/test_config.h"
+
+ACE_RCSID(tests, Get_Opt_Test, "$Id$")
+
+/*
+ * This is the heart of the test. It sets up the optstring, instantiates
+ * ACE_Get_Opt, add long options, processes them in a loop, and prints out
+ * the results to the log.
+ *
+ * It returns 0 for success and 1 for error so we can keep track of the
+ * total error count.
+ */
+
+static const ACE_TString empty (ACE_TEXT (""));
+
+static int
+parse_args (int test_number,
+ int ordering,
+ const ACE_TCHAR *test_args,
+ int skip_argv = 1,
+ int report_errors = 1,
+ const ACE_TString &opt_prefix = empty)
+{
+ ACE_TString test;
+ ACE_TString optstring (opt_prefix);
+
+ // Test the skip_argv for the first test only.
+ if (skip_argv > 0)
+ {
+ test = ACE_TEXT ("Test_");
+ ACE_TCHAR s[20];
+ test += ACE_OS::itoa (test_number, s, 10);
+ test += ACE_TEXT (" ");
+ }
+
+ test += test_args;
+ optstring += ACE_TEXT ("fr:o::sW;");
+
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT (" TEST %d *****************************************")
+ ACE_TEXT ("*******************\n"),
+ test_number));
+ ACE_DEBUG ((LM_INFO, " Command line: \"%s\"\n", test.c_str ()));
+
+ ACE_ARGV args (test.c_str ());
+
+ ACE_Get_Opt get_opt (args.argc (),
+ args.argv (),
+ optstring.c_str (),
+ skip_argv,
+ report_errors,
+ ordering);
+
+ // Now add the default long args.
+ if (get_opt.long_option (ACE_TEXT ("flag"),
+ 'f',
+ ACE_Get_Opt::NO_ARG) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT (" Unable to add long option 'f' \n")), 1);
+
+ if (get_opt.long_option (ACE_TEXT ("requires_arg"),
+ 'r',
+ ACE_Get_Opt::ARG_REQUIRED) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT (" Unable to add long option 'r' \n")), 1);
+
+ if (get_opt.long_option (ACE_TEXT ("optional_arg"),
+ 'o',
+ ACE_Get_Opt::ARG_OPTIONAL) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT (" Unable to add long option 'o' \n")), 1);
+
+ if (get_opt.long_option (ACE_TEXT ("long_option"),
+ 'l',
+ ACE_Get_Opt::ARG_OPTIONAL) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT (" Unable to add long option 'l' \n")), 1);
+
+ if (get_opt.long_option (ACE_TEXT ("long_only"),
+ -11,
+ ACE_Get_Opt::ARG_REQUIRED) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT (" Unable to add long option ")
+ ACE_TEXT ("\"long_only\" \n")), 1);
+
+ if (get_opt.long_option (ACE_TEXT ("long_no_arg")) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT (" Unable to add long option ")
+ ACE_TEXT ("\"long_no_arg\" \n")), 1);
+
+ // This is the special case of providing a non-alpha numeric corresponding
+ // short option. This lets you use the corresponding short option in a
+ // switch statement, even thought a meaningful short options isn't available
+ // (afterall, there are only so many alpha numeric characters available).
+ if (get_opt.long_option (ACE_TEXT ("non_alpha-num_short"),
+ -10,
+ ACE_Get_Opt::ARG_OPTIONAL) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT (" Unable to add long option ")
+ ACE_TEXT ("\"non_alpha_short\" \n")), 1);
+
+ // We print out the optstring here because adding long_options that
+ // have corresponding short options that aren't yet present, are added.
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT (" optstring: \"%s\" skip_argv: %d\n"),
+ get_opt.optstring (), skip_argv));
+
+ // Now, let's parse it...
+ int c = 0;
+ while ((c = get_opt ()) != EOF)
+ {
+ switch (c)
+ {
+ case 0:
+ // Long Option.
+ if (!get_opt.long_option ())
+ ACE_ERROR_RETURN ((LM_ERROR, " Long option doesn't exist.\n"), 1);
+
+ ACE_DEBUG ((LM_INFO, " Found long option \"%s\" %s %s\n",
+ get_opt.long_option (),
+ get_opt.opt_arg () ? ACE_TEXT ("with argument:")
+ : ACE_TEXT (""),
+ get_opt.opt_arg () ? get_opt.opt_arg ()
+ : ACE_TEXT ("")));
+ break;
+ case 'f':
+ // This flag was added in both the optstring in the ctor and with
+ // long_option().
+ case 's':
+ // This one is only short and has no long option.
+ ACE_DEBUG ((LM_INFO, " Found option flag '%s'\n",
+ get_opt.last_option ()));
+ break;
+ case 'r':
+ // This one has a required argument, we wouldn't be here if the
+ // arg were missing. Note that we call get_opt.opt_arg () to return
+ // the argument, but we could have used get_opt.opt_arg () since
+ // opt_arg () is defined as "opt_arg ()".
+ ACE_DEBUG ((LM_INFO,
+ " Found option '%s' with required argument \"%s\"\n",
+ get_opt.last_option (), get_opt.opt_arg ()));
+ break;
+ case 'o':
+ // This one has an optional argument.
+ case 'l':
+ // This short options was set automatically added to optstring.
+ ACE_DEBUG ((LM_INFO,
+ " Found option '%s' with optional argument \"%s\"\n",
+ get_opt.last_option (),
+ get_opt.opt_arg () ? get_opt.opt_arg ()
+ : ACE_TEXT ("default")));
+ break;
+ case 1:
+ // Non-option when in RETURN_IN_ORDER mode.
+ ACE_DEBUG ((LM_INFO,
+ " Found a non-option argument \"%s\" before finding "
+ "\"--\" (must be in RETURN_IN_ORDER mode).\n",
+ get_opt.opt_arg ()));
+ break;
+ case -10:
+ // we found the short option that isn't alpha numeric.
+ ACE_DEBUG ((LM_INFO,
+ " Found option '%s' with optional argument \"%s\"\n",
+ get_opt.last_option (),
+ get_opt.opt_arg () ? get_opt.opt_arg ()
+ : ACE_TEXT ("default")));
+ break;
+ case -11:
+ // we found the short option that isn't alpha numeric.
+ ACE_DEBUG ((LM_INFO,
+ " Found option '%s' with argument \"%s\"\n",
+ get_opt.last_option (), get_opt.opt_arg ()));
+ break;
+ case ':':
+ // This means an option requiring an argument didn't have one.
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT (" Option '%c' (%s) requires an argument ")
+ ACE_TEXT ("but none was supplied\n"),
+ get_opt.opt_opt (), get_opt.last_option ()));
+ break;
+ case '?':
+ // An unrecognized option.
+ default:
+ // This is an error, perhaps you could handle them, but let's
+ // just log it and keep going
+ ACE_DEBUG ((LM_INFO,
+ " Found an unknown option (%s) we couldn't handle.\n",
+ get_opt.last_option ()));
+ }
+ }
+
+ // Print out the rest of the arguments left in the command line (if any).
+ int index = 0;
+ for (index = get_opt.opt_ind (); index < args.argc (); index++)
+ ACE_DEBUG ((LM_INFO, " Found non-option argument \"%s\"\n",
+ args.argv ()[index]));
+
+ // Now print them all so we can examine the permuted cmd line.
+ for (index = 0; index < args.argc (); index++)
+ ACE_DEBUG ((LM_INFO, " argv[%u] \"%s\"\n",
+ index, args.argv ()[index]));
+ return 0;
+}
+
+/*
+ * Add new tests cases here. We increment the test number and pass the
+ * type of ordering we want so that each test can be tested with multiple
+ * ordering values in order to demostrate the difference.
+ *
+ * The return value is cumulative, and serves as a failure count that is
+ * returned at the end of all the tests.
+ */
+static int
+run_test (int& test_number, int ordering)
+{
+ int retval = 0;
+
+ ACE_DEBUG ((LM_INFO,
+ " ########## Running Tests with ordering = %C ##########\n",
+ ordering == 1 ? "REQUIRE_ORDER" :
+ ordering == 2 ? "PERMUTE_ARGS" :
+ "RETURN_IN_ORDER"));
+
+ // Basic test, but don't use the program name and don't skip any args.
+ retval += parse_args
+ (test_number++, ordering,
+ ACE_TEXT ("-f -rreq-arg -oopt-arg -lopt-arg --long_only=lo_arg -s arg1 arg2"),
+ 0);
+
+ // Same, but combining short args that don't take args
+ retval += parse_args
+ (test_number++, ordering,
+ ACE_TEXT ("-fsrreq-arg -oopt-arg -lopt-arg --long_only=lo_arg arg1 arg2"));
+
+ // Now we use defaults for options with optional args.
+ retval += parse_args
+ (test_number++, ordering,
+ ACE_TEXT ("-fsrreq-arg -o -l --long_only=lo_arg arg1 arg2"));
+
+ // Let's mix up the options and non-options an see what happens.
+ retval += parse_args
+ (test_number++, ordering,
+ ACE_TEXT ("-fs arg1 -rreq-arg -o arg2 -l --long_only=lo_arg"));
+
+ // Now we turn off options parsing explicitely by passing "--" in the middle.
+ retval += parse_args
+ (test_number++, ordering,
+ ACE_TEXT ("-fs -rreq-arg -- arg1 -o arg2 -l --long_only=lo_arg"));
+
+ // Let's try the same thing but mix up the options and non-options.
+ retval += parse_args
+ (test_number++, ordering,
+ ACE_TEXT ("-fs arg1 arg2 -rreq-arg -- arg3 -o"));
+
+ // One more time but with "-W".
+ retval += parse_args
+ (test_number++, ordering,
+ ACE_TEXT ("-fs arg1 arg2 -rreq-arg -W long_option=opt-arg -- arg3 -o"));
+
+ // Let's pass some long options.
+ retval += parse_args
+ (test_number++, ordering,
+ ACE_TEXT ("--flag -s --requires_arg=req-arg --optional_arg --long_only lo_arg arg1 arg2"));
+
+ // And long options without the '='.
+ retval += parse_args
+ (test_number++, ordering,
+ ACE_TEXT ("--flag -s --requires_arg req-arg --optional_arg --long_only=lo_arg arg1 arg2"));
+
+ // Pass "-W" to cause the next argument to be read as a long option.
+ retval += parse_args
+ (test_number++, ordering,
+ ACE_TEXT ("-fso -W requires_arg=req-arg -Woptional_arg -l arg1 arg2"));
+
+ // This is the special case of a non-alpha numeric short option.
+ retval += parse_args
+ (test_number++, ordering,
+ ACE_TEXT ("-fso --non_alpha-num_short=xxx arg1 arg2"));
+
+ // Now, let's test some error conditions (we turn off report_errors since they are
+ // intentional, we don't want to break the test script)
+ int report_errors = 0;
+
+ // Bad short option.
+ retval += parse_args (test_number++, ordering, ACE_TEXT ("-X"), 1, report_errors);
+
+ // Short option with missing required arg.
+ ACE_TString report_missing (ACE_TEXT (":"));
+ retval += parse_args (test_number++, ordering, ACE_TEXT ("-r"), 1, report_errors, report_missing);
+
+ // Short option with missing required arg with trailing "--".
+ // This reads "--" as the arg, but should it?
+ retval += parse_args (test_number++, ordering, ACE_TEXT ("-r --"), 1, report_errors);
+
+ // Long option with missing required arg.
+ retval += parse_args (test_number++, ordering, ACE_TEXT ("--long_only"), 1, report_errors);
+
+ // Long option that doesn't take an arg has one.
+ retval += parse_args (test_number++, ordering, ACE_TEXT ("--long_no_arg=bad_arg"), 1, report_errors);
+
+ // Unknown long option.
+ retval += parse_args (test_number++, ordering, ACE_TEXT ("--unknown"), 1, report_errors);
+
+ // Ambigous long option.
+ retval += parse_args (test_number++, ordering, ACE_TEXT ("--long"), 1, report_errors);
+
+ return retval;
+}
+
+int
+run_main (int, ACE_TCHAR *argv[])
+{
+ ACE_START_TEST (ACE_TEXT ("Get_Opt_Test"));
+ ACE_UNUSED_ARG (argv);
+ int retval = 0;
+ int test_number = 0;
+
+ // Run the tests for each type of ordering.
+ retval = run_test (test_number, ACE_Get_Opt::PERMUTE_ARGS);
+ retval += run_test (test_number, ACE_Get_Opt::REQUIRE_ORDER);
+ retval += run_test (test_number, ACE_Get_Opt::RETURN_IN_ORDER);
+
+ ACE_END_TEST;
+ return retval;
+}