1 // ============================================================================
7 // This program tests both the short and long option support in
8 // <ACE_Get_Opt>, and demonstrates how to use it.
11 // Don Hinton <dhinton@dresystems.com>
13 // ============================================================================
15 #include "test_config.h"
16 #include "ace/Get_Opt.h"
18 #include "ace/SString.h"
19 #include "ace/OS_NS_stdlib.h"
20 #include "test_config.h"
25 * This is the heart of the test. It sets up the optstring, instantiates
26 * ACE_Get_Opt, add long options, processes them in a loop, and prints out
27 * the results to the log.
29 * It returns 0 for success and 1 for error so we can keep track of the
33 static const ACE_TString
empty_string (ACE_TEXT (""));
36 parse_args (int test_number
,
38 const ACE_TCHAR
*test_args
,
40 int report_errors
= 1,
41 const ACE_TString
&opt_prefix
= empty_string
)
44 ACE_TString
optstring (opt_prefix
);
46 // Test the skip_argv for the first test only.
49 test
= ACE_TEXT ("Test_");
51 test
+= ACE_OS::itoa (test_number
, s
, 10);
52 test
+= ACE_TEXT (" ");
56 optstring
+= ACE_TEXT ("fr:o::sW;");
59 ACE_TEXT (" TEST %d *****************************************")
60 ACE_TEXT ("*******************\n"),
62 ACE_DEBUG ((LM_INFO
, " Command line: \"%s\"\n", test
.c_str ()));
64 ACE_ARGV
args (test
.c_str ());
66 ACE_Get_Opt
get_opt (args
.argc (),
73 // Now add the default long args.
74 if (get_opt
.long_option (ACE_TEXT ("flag"),
76 ACE_Get_Opt::NO_ARG
) != 0)
77 ACE_ERROR_RETURN ((LM_ERROR
,
78 ACE_TEXT (" Unable to add long option 'f'\n")), 1);
80 if (get_opt
.long_option (ACE_TEXT ("requires_arg"),
82 ACE_Get_Opt::ARG_REQUIRED
) != 0)
83 ACE_ERROR_RETURN ((LM_ERROR
,
84 ACE_TEXT (" Unable to add long option 'r'\n")), 1);
86 if (get_opt
.long_option (ACE_TEXT ("optional_arg"),
88 ACE_Get_Opt::ARG_OPTIONAL
) != 0)
89 ACE_ERROR_RETURN ((LM_ERROR
,
90 ACE_TEXT (" Unable to add long option 'o'\n")), 1);
92 if (get_opt
.long_option (ACE_TEXT ("long_option"),
94 ACE_Get_Opt::ARG_OPTIONAL
) != 0)
95 ACE_ERROR_RETURN ((LM_ERROR
,
96 ACE_TEXT (" Unable to add long option 'l'\n")), 1);
98 if (get_opt
.long_option (ACE_TEXT ("long_only"),
100 ACE_Get_Opt::ARG_REQUIRED
) != 0)
101 ACE_ERROR_RETURN ((LM_ERROR
,
102 ACE_TEXT (" Unable to add long option ")
103 ACE_TEXT ("\"long_only\"\n")), 1);
105 if (get_opt
.long_option (ACE_TEXT ("long_no_arg")) != 0)
106 ACE_ERROR_RETURN ((LM_ERROR
,
107 ACE_TEXT (" Unable to add long option ")
108 ACE_TEXT ("\"long_no_arg\"\n")), 1);
110 // This is the special case of providing a non-alpha numeric corresponding
111 // short option. This lets you use the corresponding short option in a
112 // switch statement, even thought a meaningful short options isn't available
113 // (afterall, there are only so many alpha numeric characters available).
114 if (get_opt
.long_option (ACE_TEXT ("non_alpha-num_short"),
116 ACE_Get_Opt::ARG_OPTIONAL
) != 0)
117 ACE_ERROR_RETURN ((LM_ERROR
,
118 ACE_TEXT (" Unable to add long option ")
119 ACE_TEXT ("\"non_alpha_short\"\n")), 1);
121 // We print out the optstring here because adding long_options that
122 // have corresponding short options that aren't yet present, are added.
124 ACE_TEXT (" optstring: \"%s\" skip_argv: %d\n"),
125 get_opt
.optstring (), skip_argv
));
127 // Now, let's parse it...
129 while ((c
= get_opt ()) != EOF
)
135 if (!get_opt
.long_option ())
136 ACE_ERROR_RETURN ((LM_ERROR
, " Long option doesn't exist.\n"), 1);
138 ACE_DEBUG ((LM_INFO
, " Found long option \"%s\" %s %s\n",
139 get_opt
.long_option (),
140 get_opt
.opt_arg () ? ACE_TEXT ("with argument:")
142 get_opt
.opt_arg () ? get_opt
.opt_arg ()
146 // This flag was added in both the optstring in the ctor and with
149 // This one is only short and has no long option.
150 ACE_DEBUG ((LM_INFO
, " Found option flag '%s'\n",
151 get_opt
.last_option ()));
154 // This one has a required argument, we wouldn't be here if the
155 // arg were missing. Note that we call get_opt.opt_arg () to return
156 // the argument, but we could have used get_opt.opt_arg () since
157 // opt_arg () is defined as "opt_arg ()".
159 " Found option '%s' with required argument \"%s\"\n",
160 get_opt
.last_option (), get_opt
.opt_arg ()));
163 // This one has an optional argument.
165 // This short options was set automatically added to optstring.
167 " Found option '%s' with optional argument \"%s\"\n",
168 get_opt
.last_option (),
169 get_opt
.opt_arg () ? get_opt
.opt_arg ()
170 : ACE_TEXT ("default")));
173 // Non-option when in RETURN_IN_ORDER mode.
175 " Found a non-option argument \"%s\" before finding "
176 "\"--\" (must be in RETURN_IN_ORDER mode).\n",
177 get_opt
.opt_arg ()));
180 // we found the short option that isn't alpha numeric.
182 " Found option '%s' with optional argument \"%s\"\n",
183 get_opt
.last_option (),
184 get_opt
.opt_arg () ? get_opt
.opt_arg ()
185 : ACE_TEXT ("default")));
188 // we found the short option that isn't alpha numeric.
190 " Found option '%s' with argument \"%s\"\n",
191 get_opt
.last_option (), get_opt
.opt_arg ()));
194 // This means an option requiring an argument didn't have one.
196 ACE_TEXT (" Option '%c' (%s) requires an argument ")
197 ACE_TEXT ("but none was supplied\n"),
198 get_opt
.opt_opt (), get_opt
.last_option ()));
201 // An unrecognized option.
203 // This is an error, perhaps you could handle them, but let's
204 // just log it and keep going
206 " Found an unknown option (%s) we couldn't handle.\n",
207 get_opt
.last_option ()));
211 // Print out the rest of the arguments left in the command line (if any).
213 for (index
= get_opt
.opt_ind (); index
< args
.argc (); index
++)
214 ACE_DEBUG ((LM_INFO
, " Found non-option argument \"%s\"\n",
215 args
.argv ()[index
]));
217 // Now print them all so we can examine the permuted cmd line.
218 for (index
= 0; index
< args
.argc (); index
++)
219 ACE_DEBUG ((LM_INFO
, " argv[%u] \"%s\"\n",
220 index
, args
.argv ()[index
]));
225 * Add new tests cases here. We increment the test number and pass the
226 * type of ordering we want so that each test can be tested with multiple
227 * ordering values in order to demostrate the difference.
229 * The return value is cumulative, and serves as a failure count that is
230 * returned at the end of all the tests.
233 run_test (int& test_number
, int ordering
)
238 " ########## Running Tests with ordering = %C ##########\n",
239 ordering
== 1 ? "REQUIRE_ORDER" :
240 ordering
== 2 ? "PERMUTE_ARGS" :
243 // Basic test, but don't use the program name and don't skip any args.
245 (test_number
++, ordering
,
246 ACE_TEXT ("-f -rreq-arg -oopt-arg -lopt-arg --long_only=lo_arg -s arg1 arg2"),
249 // Same, but combining short args that don't take args
251 (test_number
++, ordering
,
252 ACE_TEXT ("-fsrreq-arg -oopt-arg -lopt-arg --long_only=lo_arg arg1 arg2"));
254 // Now we use defaults for options with optional args.
256 (test_number
++, ordering
,
257 ACE_TEXT ("-fsrreq-arg -o -l --long_only=lo_arg arg1 arg2"));
259 // Let's mix up the options and non-options an see what happens.
261 (test_number
++, ordering
,
262 ACE_TEXT ("-fs arg1 -rreq-arg -o arg2 -l --long_only=lo_arg"));
264 // Now we turn off options parsing explicitely by passing "--" in the middle.
266 (test_number
++, ordering
,
267 ACE_TEXT ("-fs -rreq-arg -- arg1 -o arg2 -l --long_only=lo_arg"));
269 // Let's try the same thing but mix up the options and non-options.
271 (test_number
++, ordering
,
272 ACE_TEXT ("-fs arg1 arg2 -rreq-arg -- arg3 -o"));
274 // One more time but with "-W".
276 (test_number
++, ordering
,
277 ACE_TEXT ("-fs arg1 arg2 -rreq-arg -W long_option=opt-arg -- arg3 -o"));
279 // Let's pass some long options.
281 (test_number
++, ordering
,
282 ACE_TEXT ("--flag -s --requires_arg=req-arg --optional_arg --long_only lo_arg arg1 arg2"));
284 // And long options without the '='.
286 (test_number
++, ordering
,
287 ACE_TEXT ("--flag -s --requires_arg req-arg --optional_arg --long_only=lo_arg arg1 arg2"));
289 // Pass "-W" to cause the next argument to be read as a long option.
291 (test_number
++, ordering
,
292 ACE_TEXT ("-fso -W requires_arg=req-arg -Woptional_arg -l arg1 arg2"));
294 // This is the special case of a non-alpha numeric short option.
296 (test_number
++, ordering
,
297 ACE_TEXT ("-fso --non_alpha-num_short=xxx arg1 arg2"));
299 // Now, let's test some error conditions (we turn off report_errors since they are
300 // intentional, we don't want to break the test script)
301 int report_errors
= 0;
304 retval
+= parse_args (test_number
++, ordering
, ACE_TEXT ("-X"), 1, report_errors
);
306 // Short option with missing required arg.
307 ACE_TString
report_missing (ACE_TEXT (":"));
308 retval
+= parse_args (test_number
++, ordering
, ACE_TEXT ("-r"), 1, report_errors
, report_missing
);
310 // Short option with missing required arg with trailing "--".
311 // This reads "--" as the arg, but should it?
312 retval
+= parse_args (test_number
++, ordering
, ACE_TEXT ("-r --"), 1, report_errors
);
314 // Long option with missing required arg.
315 retval
+= parse_args (test_number
++, ordering
, ACE_TEXT ("--long_only"), 1, report_errors
);
317 // Long option that doesn't take an arg has one.
318 retval
+= parse_args (test_number
++, ordering
, ACE_TEXT ("--long_no_arg=bad_arg"), 1, report_errors
);
320 // Unknown long option.
321 retval
+= parse_args (test_number
++, ordering
, ACE_TEXT ("--unknown"), 1, report_errors
);
323 // Ambigous long option.
324 retval
+= parse_args (test_number
++, ordering
, ACE_TEXT ("--long"), 1, report_errors
);
330 run_main (int, ACE_TCHAR
*argv
[])
332 ACE_START_TEST (ACE_TEXT ("Get_Opt_Test"));
333 ACE_UNUSED_ARG (argv
);
337 // Run the tests for each type of ordering.
338 retval
= run_test (test_number
, ACE_Get_Opt::PERMUTE_ARGS
);
339 retval
+= run_test (test_number
, ACE_Get_Opt::REQUIRE_ORDER
);
340 retval
+= run_test (test_number
, ACE_Get_Opt::RETURN_IN_ORDER
);