Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / ACE / tests / Get_Opt_Test.cpp
blob6395c0a1f2ef89a3f98639698d6388b90a5e6801
1 // ============================================================================
2 //
3 // = LIBRARY
4 // tests
5 //
6 // = DESCRIPTION
7 // This program tests both the short and long option support in
8 // <ACE_Get_Opt>, and demonstrates how to use it.
9 //
10 // = AUTHOR
11 // Don Hinton <dhinton@dresystems.com>
13 // ============================================================================
15 #include "test_config.h"
16 #include "ace/Get_Opt.h"
17 #include "ace/ARGV.h"
18 #include "ace/SString.h"
19 #include "ace/OS_NS_stdlib.h"
20 #include "test_config.h"
24 * This is the heart of the test. It sets up the optstring, instantiates
25 * ACE_Get_Opt, add long options, processes them in a loop, and prints out
26 * the results to the log.
28 * It returns 0 for success and 1 for error so we can keep track of the
29 * total error count.
32 static const ACE_TString empty_string (ACE_TEXT (""));
34 static int
35 parse_args (int test_number,
36 int ordering,
37 const ACE_TCHAR *test_args,
38 int skip_argv = 1,
39 int report_errors = 1,
40 const ACE_TString &opt_prefix = empty_string)
42 ACE_TString test;
43 ACE_TString optstring (opt_prefix);
45 // Test the skip_argv for the first test only.
46 if (skip_argv > 0)
48 test = ACE_TEXT ("Test_");
49 ACE_TCHAR s[20];
50 test += ACE_OS::itoa (test_number, s, 10);
51 test += ACE_TEXT (" ");
54 test += test_args;
55 optstring += ACE_TEXT ("fr:o::sW;");
57 ACE_DEBUG ((LM_INFO,
58 ACE_TEXT (" TEST %d *****************************************")
59 ACE_TEXT ("*******************\n"),
60 test_number));
61 ACE_DEBUG ((LM_INFO, " Command line: \"%s\"\n", test.c_str ()));
63 ACE_ARGV args (test.c_str ());
65 ACE_Get_Opt get_opt (args.argc (),
66 args.argv (),
67 optstring.c_str (),
68 skip_argv,
69 report_errors,
70 ordering);
72 // Now add the default long args.
73 if (get_opt.long_option (ACE_TEXT ("flag"),
74 'f',
75 ACE_Get_Opt::NO_ARG) != 0)
76 ACE_ERROR_RETURN ((LM_ERROR,
77 ACE_TEXT (" Unable to add long option 'f'\n")), 1);
79 if (get_opt.long_option (ACE_TEXT ("requires_arg"),
80 'r',
81 ACE_Get_Opt::ARG_REQUIRED) != 0)
82 ACE_ERROR_RETURN ((LM_ERROR,
83 ACE_TEXT (" Unable to add long option 'r'\n")), 1);
85 if (get_opt.long_option (ACE_TEXT ("optional_arg"),
86 'o',
87 ACE_Get_Opt::ARG_OPTIONAL) != 0)
88 ACE_ERROR_RETURN ((LM_ERROR,
89 ACE_TEXT (" Unable to add long option 'o'\n")), 1);
91 if (get_opt.long_option (ACE_TEXT ("long_option"),
92 'l',
93 ACE_Get_Opt::ARG_OPTIONAL) != 0)
94 ACE_ERROR_RETURN ((LM_ERROR,
95 ACE_TEXT (" Unable to add long option 'l'\n")), 1);
97 if (get_opt.long_option (ACE_TEXT ("long_only"),
98 -11,
99 ACE_Get_Opt::ARG_REQUIRED) != 0)
100 ACE_ERROR_RETURN ((LM_ERROR,
101 ACE_TEXT (" Unable to add long option ")
102 ACE_TEXT ("\"long_only\"\n")), 1);
104 if (get_opt.long_option (ACE_TEXT ("long_no_arg")) != 0)
105 ACE_ERROR_RETURN ((LM_ERROR,
106 ACE_TEXT (" Unable to add long option ")
107 ACE_TEXT ("\"long_no_arg\"\n")), 1);
109 // This is the special case of providing a non-alpha numeric corresponding
110 // short option. This lets you use the corresponding short option in a
111 // switch statement, even thought a meaningful short options isn't available
112 // (afterall, there are only so many alpha numeric characters available).
113 if (get_opt.long_option (ACE_TEXT ("non_alpha-num_short"),
114 -10,
115 ACE_Get_Opt::ARG_OPTIONAL) != 0)
116 ACE_ERROR_RETURN ((LM_ERROR,
117 ACE_TEXT (" Unable to add long option ")
118 ACE_TEXT ("\"non_alpha_short\"\n")), 1);
120 // We print out the optstring here because adding long_options that
121 // have corresponding short options that aren't yet present, are added.
122 ACE_DEBUG ((LM_INFO,
123 ACE_TEXT (" optstring: \"%s\" skip_argv: %d\n"),
124 get_opt.optstring (), skip_argv));
126 // Now, let's parse it...
127 int c = 0;
128 while ((c = get_opt ()) != EOF)
130 switch (c)
132 case 0:
133 // Long Option.
134 if (!get_opt.long_option ())
135 ACE_ERROR_RETURN ((LM_ERROR, " Long option doesn't exist.\n"), 1);
137 ACE_DEBUG ((LM_INFO, " Found long option \"%s\" %s %s\n",
138 get_opt.long_option (),
139 get_opt.opt_arg () ? ACE_TEXT ("with argument:")
140 : ACE_TEXT (""),
141 get_opt.opt_arg () ? get_opt.opt_arg ()
142 : ACE_TEXT ("")));
143 break;
144 case 'f':
145 // This flag was added in both the optstring in the ctor and with
146 // long_option().
147 case 's':
148 // This one is only short and has no long option.
149 ACE_DEBUG ((LM_INFO, " Found option flag '%s'\n",
150 get_opt.last_option ()));
151 break;
152 case 'r':
153 // This one has a required argument, we wouldn't be here if the
154 // arg were missing. Note that we call get_opt.opt_arg () to return
155 // the argument, but we could have used get_opt.opt_arg () since
156 // opt_arg () is defined as "opt_arg ()".
157 ACE_DEBUG ((LM_INFO,
158 " Found option '%s' with required argument \"%s\"\n",
159 get_opt.last_option (), get_opt.opt_arg ()));
160 break;
161 case 'o':
162 // This one has an optional argument.
163 case 'l':
164 // This short options was set automatically added to optstring.
165 ACE_DEBUG ((LM_INFO,
166 " Found option '%s' with optional argument \"%s\"\n",
167 get_opt.last_option (),
168 get_opt.opt_arg () ? get_opt.opt_arg ()
169 : ACE_TEXT ("default")));
170 break;
171 case 1:
172 // Non-option when in RETURN_IN_ORDER mode.
173 ACE_DEBUG ((LM_INFO,
174 " Found a non-option argument \"%s\" before finding "
175 "\"--\" (must be in RETURN_IN_ORDER mode).\n",
176 get_opt.opt_arg ()));
177 break;
178 case -10:
179 // we found the short option that isn't alpha numeric.
180 ACE_DEBUG ((LM_INFO,
181 " Found option '%s' with optional argument \"%s\"\n",
182 get_opt.last_option (),
183 get_opt.opt_arg () ? get_opt.opt_arg ()
184 : ACE_TEXT ("default")));
185 break;
186 case -11:
187 // we found the short option that isn't alpha numeric.
188 ACE_DEBUG ((LM_INFO,
189 " Found option '%s' with argument \"%s\"\n",
190 get_opt.last_option (), get_opt.opt_arg ()));
191 break;
192 case ':':
193 // This means an option requiring an argument didn't have one.
194 ACE_DEBUG ((LM_INFO,
195 ACE_TEXT (" Option '%c' (%s) requires an argument ")
196 ACE_TEXT ("but none was supplied\n"),
197 get_opt.opt_opt (), get_opt.last_option ()));
198 break;
199 case '?':
200 // An unrecognized option.
201 default:
202 // This is an error, perhaps you could handle them, but let's
203 // just log it and keep going
204 ACE_DEBUG ((LM_INFO,
205 " Found an unknown option (%s) we couldn't handle.\n",
206 get_opt.last_option ()));
210 // Print out the rest of the arguments left in the command line (if any).
211 int index = 0;
212 for (index = get_opt.opt_ind (); index < args.argc (); index++)
213 ACE_DEBUG ((LM_INFO, " Found non-option argument \"%s\"\n",
214 args.argv ()[index]));
216 // Now print them all so we can examine the permuted cmd line.
217 for (index = 0; index < args.argc (); index++)
218 ACE_DEBUG ((LM_INFO, " argv[%u] \"%s\"\n",
219 index, args.argv ()[index]));
220 return 0;
224 * Add new tests cases here. We increment the test number and pass the
225 * type of ordering we want so that each test can be tested with multiple
226 * ordering values in order to demostrate the difference.
228 * The return value is cumulative, and serves as a failure count that is
229 * returned at the end of all the tests.
231 static int
232 run_test (int& test_number, int ordering)
234 int retval = 0;
236 ACE_DEBUG ((LM_INFO,
237 " ########## Running Tests with ordering = %C ##########\n",
238 ordering == 1 ? "REQUIRE_ORDER" :
239 ordering == 2 ? "PERMUTE_ARGS" :
240 "RETURN_IN_ORDER"));
242 // Basic test, but don't use the program name and don't skip any args.
243 retval += parse_args
244 (test_number++, ordering,
245 ACE_TEXT ("-f -rreq-arg -oopt-arg -lopt-arg --long_only=lo_arg -s arg1 arg2"),
248 // Same, but combining short args that don't take args
249 retval += parse_args
250 (test_number++, ordering,
251 ACE_TEXT ("-fsrreq-arg -oopt-arg -lopt-arg --long_only=lo_arg arg1 arg2"));
253 // Now we use defaults for options with optional args.
254 retval += parse_args
255 (test_number++, ordering,
256 ACE_TEXT ("-fsrreq-arg -o -l --long_only=lo_arg arg1 arg2"));
258 // Let's mix up the options and non-options an see what happens.
259 retval += parse_args
260 (test_number++, ordering,
261 ACE_TEXT ("-fs arg1 -rreq-arg -o arg2 -l --long_only=lo_arg"));
263 // Now we turn off options parsing explicitely by passing "--" in the middle.
264 retval += parse_args
265 (test_number++, ordering,
266 ACE_TEXT ("-fs -rreq-arg -- arg1 -o arg2 -l --long_only=lo_arg"));
268 // Let's try the same thing but mix up the options and non-options.
269 retval += parse_args
270 (test_number++, ordering,
271 ACE_TEXT ("-fs arg1 arg2 -rreq-arg -- arg3 -o"));
273 // One more time but with "-W".
274 retval += parse_args
275 (test_number++, ordering,
276 ACE_TEXT ("-fs arg1 arg2 -rreq-arg -W long_option=opt-arg -- arg3 -o"));
278 // Let's pass some long options.
279 retval += parse_args
280 (test_number++, ordering,
281 ACE_TEXT ("--flag -s --requires_arg=req-arg --optional_arg --long_only lo_arg arg1 arg2"));
283 // And long options without the '='.
284 retval += parse_args
285 (test_number++, ordering,
286 ACE_TEXT ("--flag -s --requires_arg req-arg --optional_arg --long_only=lo_arg arg1 arg2"));
288 // Pass "-W" to cause the next argument to be read as a long option.
289 retval += parse_args
290 (test_number++, ordering,
291 ACE_TEXT ("-fso -W requires_arg=req-arg -Woptional_arg -l arg1 arg2"));
293 // This is the special case of a non-alpha numeric short option.
294 retval += parse_args
295 (test_number++, ordering,
296 ACE_TEXT ("-fso --non_alpha-num_short=xxx arg1 arg2"));
298 // Now, let's test some error conditions (we turn off report_errors since they are
299 // intentional, we don't want to break the test script)
300 int report_errors = 0;
302 // Bad short option.
303 retval += parse_args (test_number++, ordering, ACE_TEXT ("-X"), 1, report_errors);
305 // Short option with missing required arg.
306 ACE_TString report_missing (ACE_TEXT (":"));
307 retval += parse_args (test_number++, ordering, ACE_TEXT ("-r"), 1, report_errors, report_missing);
309 // Short option with missing required arg with trailing "--".
310 // This reads "--" as the arg, but should it?
311 retval += parse_args (test_number++, ordering, ACE_TEXT ("-r --"), 1, report_errors);
313 // Long option with missing required arg.
314 retval += parse_args (test_number++, ordering, ACE_TEXT ("--long_only"), 1, report_errors);
316 // Long option that doesn't take an arg has one.
317 retval += parse_args (test_number++, ordering, ACE_TEXT ("--long_no_arg=bad_arg"), 1, report_errors);
319 // Unknown long option.
320 retval += parse_args (test_number++, ordering, ACE_TEXT ("--unknown"), 1, report_errors);
322 // Ambigous long option.
323 retval += parse_args (test_number++, ordering, ACE_TEXT ("--long"), 1, report_errors);
325 return retval;
329 run_main (int, ACE_TCHAR *argv[])
331 ACE_START_TEST (ACE_TEXT ("Get_Opt_Test"));
332 ACE_UNUSED_ARG (argv);
333 int retval = 0;
334 int test_number = 0;
336 // Run the tests for each type of ordering.
337 retval = run_test (test_number, ACE_Get_Opt::PERMUTE_ARGS);
338 retval += run_test (test_number, ACE_Get_Opt::REQUIRE_ORDER);
339 retval += run_test (test_number, ACE_Get_Opt::RETURN_IN_ORDER);
341 ACE_END_TEST;
342 return retval;