Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
core/test/CommandLineProcessor/cxx_main.cpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Teuchos: Common Tools Package
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
44 #include "Teuchos_Version.hpp"
45 
46 int main( int argc, char* argv[] )
47 {
48 
50 
51  bool verbose = true;
52  bool parse_successful = true;
53 
54  Teuchos::GlobalMPISession mpiSession(&argc, &argv);
55 
56  // First create tests for a command line processor that doesn't throw exceptions.
57  try {
58  // Read options from the commandline
59  CommandLineProcessor clp(false, false); // Don't throw exceptions
60 
61  double rel_proc_speed = 1e-5; // Should
62  clp.setOption( "rel-proc-speed", &rel_proc_speed, "Relative processor speed (try around 1.0 for timing)." );
63 
64  int size = 1;
65  clp.setOption( "size", &size, "Size of memory blocks created." );
66 
67  size_t sizetOption = 10;
68  clp.setOption( "sizeTOption", &sizetOption, "An option of type size_t.");
69 
70  long long longLongOption = 42;
71  clp.setOption( "longLongOption", &longLongOption, "An option of type long long." );
72 
73  // Parse the current input, which should return succesful.
74  CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
75  if (verbose)
76  std::cout << "Test 1: CommandLineProcessor - No exceptions - All extra options ignored: ";
77  if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL )
78  {
79  parse_successful = false;
80  if (verbose) std::cout << "FAILED" << std::endl;
81  }
82  else
83  if (verbose) std::cout << "PASSED" << std::endl;
84 
85  // Add a new option that is required
86  int num = 1;
87  clp.setOption( "num", &num, "Number of memory blocks created (required option).", true );
88 
89  // Now parse with this new option (which should not be passed in on the command line)
90  parse_return = clp.parse(argc,argv);
91  if (verbose)
92  std::cout << "Test 2: CommandLineProcessor - No exceptions - All extra options ignored - 1 required: ";
93  if( parse_return != CommandLineProcessor::PARSE_ERROR )
94  {
95  parse_successful = false;
96  if (verbose) std::cout << "FAILED" << std::endl;
97  }
98  else
99  if (verbose) std::cout << "PASSED" << std::endl;
100 
101  }
102  catch( ... ) {
103  if(verbose)
104  std::cerr << "*** Caught UNEXPECTED unknown exception\n";
105  parse_successful = false; // No exceptions should be thrown for this command line processor.
106  }
107 
108  // Next create tests for a command line processor that does throw exceptions.
109  // Read options from the commandline
110  try {
111  CommandLineProcessor clp2(true, false); // Throw exceptions
112 
113  clp2.setOption( "verbose", "quiet", &verbose, "Set if output is printed or not." );
114 
115  double rel_proc_speed = 1e-5; // Should
116  clp2.setOption( "rel-proc-speed", &rel_proc_speed, "Relative processor speed (try around 1.0 for timing)." );
117 
118  int size = 1;
119  clp2.setOption( "size", &size, "Size of memory blocks created." );
120 
121  // Add a new option that is required
122  int num = 1;
123  clp2.setOption( "num", &num, "Number of memory blocks created (required option).", true );
124 
125  // Parse the argument line and see if we get an exception thrown
126  clp2.parse(argc,argv);
127  }
128  catch( CommandLineProcessor::ParseError &excpt ) {
129  if(verbose)
130  std::cout << "*** Caught EXPECTED standard exception : " << excpt.what() << std::endl
131  << "Test 3: CommandLineProcessor - Throw exceptions - All extra options ignored - 1 required: PASSED" << std::endl;
132  }
133  catch( ... ) {
134  if(verbose)
135  std::cout << "*** Caught UNEXPECTED unknown exception" << std::endl
136  << "Test 3: CommandLineProcessor - Throw exceptions - All extra options ignored - 1 required: FAILED" << std::endl;
137  parse_successful = false; // No exceptions should be thrown for this command line processor.
138  }
139 
140  // Next create tests for a command line processor that doesn't throw exceptions, and doesn't recognize all options.
141  try {
142  CommandLineProcessor clp3(false, true); // Don't recognize all options
143 
144  // Parse the current input, which should not be successful because the test is run with "--verbose" argument.
145  CommandLineProcessor::EParseCommandLineReturn parse_return = clp3.parse(argc,argv);
146  if (verbose)
147  std::cout << "Test 4 : CommandLineProcessor - No exceptions - Extra options not recognized: ";
148  if( parse_return != CommandLineProcessor::PARSE_UNRECOGNIZED_OPTION )
149  {
150  parse_successful = false;
151  if (verbose) std::cout << "FAILED" << std::endl;
152  }
153  else
154  if (verbose) std::cout << "PASSED" << std::endl;
155 
156  // Now add the verbose option back in and add a required option.
157  clp3.setOption( "verbose", "quiet", &verbose, "Set if output is printed or not." );
158 
159  int num = 1;
160  clp3.setOption( "num", &num, "Number of memory blocks created (required option).", true );
161 
162  parse_return = clp3.parse(argc,argv);
163  if (verbose)
164  std::cout << "Test 5 : CommandLineProcessor - No exceptions - Extra options not recognized - 1 required: ";
165  if( parse_return != CommandLineProcessor::PARSE_ERROR )
166  {
167  parse_successful = false;
168  if (verbose) std::cout << "FAILED" << std::endl;
169  }
170  else
171  if (verbose) std::cout << "PASSED" << std::endl;
172  }
173  catch( ... ) {
174  if(verbose)
175  std::cerr << "*** Caught UNEXPECTED unknown exception" << std::endl;
176  parse_successful = false; // No exceptions should be thrown for this command line processor.
177  }
178 
179  // Next create tests for a command line processor that doesn't throw exceptions, and doesn't recognize all options.
180  try {
181  if (verbose)
182  std::cout << "Test 6 : CommandLineProcessor - Throw exceptions - Extra options not recognized: ";
183 
184  CommandLineProcessor clp4(true, true); // Don't recognize all options AND throw exceptions (default mode)
185 
186  // Parse the current input, which should not be successful because the test is run with "--verbose" argument.
187  clp4.parse(argc,argv);
188  }
189  catch( CommandLineProcessor::UnrecognizedOption &excpt ) {
190  if(verbose)
191  std::cout << "*** Caught EXPECTED standard exception : " << excpt.what() << std::endl
192  << "Test 6: CommandLineProcessor - Throw exceptions - Extra options not recognized: PASSED" << std::endl;
193  }
194  catch( ... ) {
195  if(verbose)
196  std::cout << "*** Caught UNEXPECTED unknown exception" << std::endl
197  << "Test 6: CommandLineProcessor - Throw exceptions - Extra options not recognized: FAILED" << std::endl;
198  parse_successful = false; // No exceptions should be thrown for this command line processor.
199  }
200 
201  // Next create tests for a command line processor that makes sure help output is the same independent of the arg position
202  try {
203  if (verbose)
204  std::cout << "Test 7 : CommandLineProcessor - Help position" << std::endl;
205 
206  CommandLineProcessor clp7(false, false); // Recognize all options AND do not throw exceptions
207 
208  int n = 10;
209  clp7.setOption("n", &n, "A parameter");
210 
211  char arg_c[] = "command";
212  char arg_n[] = "--n=20";
213  char arg_h[] = "--help";
214 
215  const int aux_argc = 3;
216  char *aux_argv[aux_argc];
217 
218  std::stringbuf buffer1, buffer2;;
219  std::streambuf* oldbuffer = NULL;
220 
221  // help before args
222  aux_argv[0] = &arg_c[0];
223  aux_argv[1] = &arg_h[0];
224  aux_argv[2] = &arg_n[0];
225 
226  oldbuffer = std::cerr.rdbuf(&buffer1); // redirect output
227  clp7.parse(aux_argc, aux_argv);
228  std::cerr.rdbuf(oldbuffer); // redirect output back
229 
230  // help after args
231  aux_argv[0] = &arg_c[0];
232  aux_argv[1] = &arg_n[0];
233  aux_argv[2] = &arg_h[0];
234 
235  oldbuffer = std::cerr.rdbuf(&buffer2); // redirect output
236  clp7.parse(aux_argc, aux_argv);
237  std::cerr.rdbuf(oldbuffer); // redirect output back
238 
239  if (verbose)
240  std::cout << "Test 7 : CommandLineProcessor - Help position: ";
241  if (buffer1.str() != buffer2.str())
242  {
243  parse_successful = false;
244  if (verbose) std::cout << "FAILED" << std::endl;
245  }
246  else
247  if (verbose) std::cout << "PASSED" << std::endl;
248  }
249  catch( CommandLineProcessor::UnrecognizedOption &excpt ) {
250  if(verbose)
251  std::cout << "*** Caught EXPECTED standard exception : " << excpt.what() << std::endl
252  << "Test 7: CommandLineProcessor - Help position: PASSED" << std::endl;
253  }
254  catch( ... ) {
255  if(verbose)
256  std::cout << "*** Caught UNEXPECTED unknown exception" << std::endl
257  << "Test 7: CommandLineProcessor - Help position: FAILED" << std::endl;
258  parse_successful = false; // No exceptions should be thrown for this command line processor.
259  }
260 
261  // Return whether the command line processor tests passed.
262  if (parse_successful) {
263  std::cout << "End Result: TEST PASSED" << std::endl;
264  return 0;
265  }
266  else {
267  std::cout << "End Result: TEST FAILED" << std::endl;
268  return 1;
269  }
270 }
Initialize, finalize, and query the global MPI session.
int size(const Comm< Ordinal > &comm)
Get the number of processes in the communicator.
int main(int argc, char *argv[])
A MPI utilities class, providing methods for initializing, finalizing, and querying the global MPI se...
Basic command line parser for input from (argc,argv[])
Class that helps parse command line input arguments from (argc,argv[]) and set options.