casa
$Rev:20696$
|
00001 //# Input.h: A simple command-line argument method for applications. 00002 //# Copyright (C) 1993,1994,1995,1999,2000,2001 00003 //# Associated Universities, Inc. Washington DC, USA. 00004 //# 00005 //# This library is free software; you can redistribute it and/or modify it 00006 //# under the terms of the GNU Library General Public License as published by 00007 //# the Free Software Foundation; either version 2 of the License, or (at your 00008 //# option) any later version. 00009 //# 00010 //# This library is distributed in the hope that it will be useful, but WITHOUT 00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 //# License for more details. 00014 //# 00015 //# You should have received a copy of the GNU Library General Public License 00016 //# along with this library; if not, write to the Free Software Foundation, 00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00018 //# 00019 //# Correspondence concerning AIPS++ should be addressed as follows: 00020 //# Internet email: aips2-request@nrao.edu. 00021 //# Postal address: AIPS++ Project Office 00022 //# National Radio Astronomy Observatory 00023 //# 520 Edgemont Road 00024 //# Charlottesville, VA 22903-2475 USA 00025 //# 00026 //# $Id: Input.h 20551 2009-03-25 00:11:33Z Malte.Marquarding $ 00027 00028 #ifndef CASA_INPUT_H 00029 #define CASA_INPUT_H 00030 00031 00032 #include <casa/aips.h> 00033 #include <casa/Inputs/Param.h> 00034 #include <casa/Containers/List.h> 00035 00036 namespace casa { //# NAMESPACE CASA - BEGIN 00037 00038 template<class T> class Vector; 00039 00040 // <summary> 00041 // Input.h: A simple command-line argument method for applications. 00042 // </summary> 00043 00044 // <use visibility=export> 00045 00046 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tInput.cc" demos=""> 00047 //</reviewed> 00048 00049 // <prerequisite> 00050 // <li> none noted 00051 // </prerequisite> 00052 // 00053 // <etymology> 00054 // The Input class name is a reflection of it's role as the early command 00055 // line user interface for AIPS++ applications. This class provides "inputs" 00056 // in the form "key=value" or "-key value." 00057 // </etymology> 00058 // 00059 // <synopsis> 00060 // The Input class is a holder of parameters, either automatically assigned 00061 // values or altered at the execution of the program which utilizes them. The 00062 // parameters are associations of String "keys" to "values". The parameters 00063 // may be used as internal values during the program's run. The shell command 00064 // <srcblock> 00065 // shell% myexecutable limits=1000 happy=True 00066 // </srcblock> 00067 // would run "myexecutable" and set the internal parameter "limits" to a value 00068 // of 1000 and "happy" to True. 00069 // 00070 // The Input class is instantiated by a constructor with a single Int argument 00071 // which, when non-zero, switches on the filling of the keys "debug" and 00072 // "help" from environment variables. These two keys always exist in an 00073 // instance of Input. No argument to the Input constructor defaults to "debug" 00074 // and "help" being set to zero. 00075 // 00076 // The default existance of the help parameter allows the user to specify 00077 // predefined modes for the "help" key. The argument "help=prompt" turns 00078 // on prompting for parameter values not specified on the command-line. In 00079 // such an instance, the optional String arguments to Input::create become 00080 // important. The argument "help=keys" will print to standard output a list 00081 // of all the parameters. Finally, "help=pane" prints to standard output a 00082 // pane file usable as a graphic user interface within Khoros Cantata. 00083 // 00084 // The default existance of the debug parameter allows the user to specify 00085 // levels of debugging, where 0 implies none and higher integers means more. 00086 // The usage would be as follows: 00087 // <srcblock> 00088 // Input inp; 00089 // // this will execute the block only for values higher than 5 00090 // if(inp.debug(5)) 00091 // { 00092 // // do debugging stuff here 00093 // } 00094 // </srcblock> 00095 // 00096 // Additional parameters must be created inside the main block (or deeper) 00097 // of your application. The member function create() is overloaded to accept 00098 // from one to six String arguments. All but the first are optional. However, 00099 // should the user decide to call any of the get() functions which return a 00100 // String, that String will be empty. In this case it is assumed that all 00101 // values will be filled from the command line. 00102 // Some examples: 00103 // <srcblock> 00104 // int main(int argc,const char* argv[]) 00105 // { 00106 // Input inp; 00107 // // Create a parameter called "foo" which defaults to True. 00108 // inp.create("foo", "True"); 00109 // // Create a parameter called "iterbound" which defaults to 2000 and 00110 // // has a help String used in cases of prompting. 00111 // inp.create("iterbound", "2000", "The upper boundary of the iterator"); 00112 // // Create a normalising value with a range, type, and unit. 00113 // inp.create("dividend", "10000", The normalization factor of the chutspah", 00114 // "0-100000", "Double", "clean steps"); 00115 // </srcblock> 00116 // The parameters are "filled" from the command line arguments by the member 00117 // function ReadArguments(int argc, const char* argv[]). If an argument is not defined 00118 // within the main block but specified at the command line, an exception is 00119 // thrown. 00120 // <srcblock> 00121 // inp.readArguments(argc, argv); 00122 // </srcblock> 00123 // 00124 // Finally, the values of the various parameter's are utilized by calling the 00125 // Input::getWhatever(key) member functions. They return either a String or 00126 // are converted to the data type chosen by the "whatever" in the name of the 00127 // function. The value associated with the passed key is returned. 00128 // <srcblock> 00129 // // get a boolean 00130 // if(inp.getBool("foo") 00131 // // get an iteration boundary 00132 // for(Int i=0; i<inp.getInt("iterbound"); i++) { 00133 // // get a double 00134 // chutspah /= inp.getDouble("dividend"); 00135 // } 00136 // </srcblock> 00137 // 00138 // Optional items include: 00139 // <ol> <li> specifying a version <src> inp.version("$ID:");</src> 00140 // will print at run time the version of the program being run. 00141 // <li> run time checking of ranges 00142 // <src> inp.makeMaskFromRanges(const String &ranges, uInt length, 00143 // Bool oneRelative=False); </src> 00144 // </ol> 00145 // </synopsis> 00146 // 00147 // <example> 00148 // <srcblock> 00149 // #include <casa/Inputs/Input.h> 00150 // int main(int argc, const char* argv[]) 00151 // { 00152 // // instantiate an Input. The integer argument of 1 to the ctor builds 00153 // // the system parameters "debug" and "help" and sets their values to the 00154 // // shell environment variables DEBUG and HELP. 00155 // Input inp(1); 00156 // // set the version to be automatically expanded by the RCS. This will 00157 // // print the version at run time. 00158 // inp.version("$ID:$"); 00159 // // We will now create some parameters. 00160 // // Create a parameter with no default value i.e. it must be set by a 00161 // // command line argument. 00162 // inp.create("test"); 00163 // // Create a parameter with a default value. 00164 // inp.create("file", "$AIPSROOT/data.txt"); 00165 // // Create a parameter with a help String which will be displayed when in 00166 // // the prompted entry mode. 00167 // inp.create("ubound", "1000", "The number of iterations to clean."); 00168 // // Create a parameter with a type. This is utilized to create the correct 00169 // // labels on a Khoros pane. You could do type checking yourself, as well. 00170 // inp.create("baseline", "451", "The number of baselines.", "Int"); 00171 // // Create a parameter with a range of acceptable values. Note: checking 00172 // // must be done by the user as this isn't coded in. 00173 // inp.create("gainstride", "0.5", "The factor by which the Clean strides.", 00174 // "Double", "0-1.0"); 00175 // // Create a parameter with a unit String. Note: checking must be done 00176 // // by the user as this test isn't coded in. 00177 // String help("The velocity of the Earth in the direction of the object."); 00178 // inp.create("velocity", "2.89e+05", help, "Double", "0-3.0e+06", "m/s"); 00179 // // Now we close parameter creation and get the values from the command line 00180 // // arguments. 00181 // inp.readArguments(argc, argv); 00182 // // Now we may utilize the values from the paramters we have created. 00183 // // Here we are getting a boolean from the parameter with the key "test". 00184 // if(inp.getBool("test") { 00185 // // Here we get a String from the parameter with the key "file". 00186 // Image myImage(inp.getString("file")); 00187 // // Here we set the boundary of the loop. 00188 // for(Int i=0;i<inp.getInt("ubound"), i++) { 00189 // // Here we set a value to the number of baselines. 00190 // Int baseline = inp.getInt("baseline"); 00191 // // Here we set the gain stride. 00192 // Cleaner.gain(inp.getDouble("gainstride")); 00193 // // lets add a debugging block 00194 // if(inp.debug(5)) cout << "the chutspah is " << chutspah << endl; 00195 // } 00196 // } 00197 // </srcblock> 00198 // </example> 00199 // 00200 // <motivation> 00201 // In the earliest days of the AIPS++ project, the desire to start coding 00202 // right away led to the need for a user interface. The preexistant C language 00203 // method of argc/argv was enclosed in an object for easier use. This also 00204 // provided a means to output a pane file. Pane files are used by the 00205 // Cantata desktop within the Khoros system to build quick graphic user 00206 // interfaces. The AIPS++ code has moved on to greater heights and left the 00207 // Input class mostly unchanged. 00208 // </motivation> 00209 // 00210 // <todo asof="Thu 1995/04/06 21:26:43 GMT"> 00211 // <li> major cleanup needed - this is the oldest code in AIPS++. 00212 // <li> replace List<Param> with keywords 00213 // </todo> 00214 00215 00216 class Input { 00217 public: 00218 00219 // The default constructor enables the creation of parameters. 00220 // If the optional Int argument is non-zero, the parameters "help" and 00221 // "debug" are created from their shell environment values. 00222 // This puts the program in no-prompt mode unless environment variable HELP 00223 // is defined with value "prompt". The output debug level is set according 00224 // to the value of the environment variable DEBUG. 00225 Input (Int createEnv=0); 00226 00227 // Destructor. 00228 ~Input(); 00229 00230 // Create a new parameter, either from scratch or looking it 00231 // up from an internal list of templates. 00232 // The function also checks whether parameters can still be created, 00233 // and whether key is unique for the program. 00234 // The value, help and remaining arguments are all optional. 00235 // <note> The multiple definitions are to allow default values</note> 00236 // <group> 00237 void create (const String& key); 00238 void create (const String& key, const String& value); 00239 void create (const String& key, const String& value, const String& help); 00240 void create (const String& key, const String& value, const String& help, 00241 const String& type); 00242 void create (const String& key, const String& value, const String& help, 00243 const String& type, const String& range); 00244 void create (const String& key, const String& value, const String& help, 00245 const String& type, const String& range, const String& unit); 00246 // </group> 00247 00248 // Disable the creation of parameters. Highly recommended, but 00249 // not required. readArguments calls it when filling the values from argv[]. 00250 void close(); 00251 00252 // fill the parameter list from argc, argv command line args 00253 void readArguments (int argc, char const* const* argv); 00254 00255 // Get the double value of the parameter (or 0.0 if unknown key). 00256 // If the program is in prompt mode, ask the user for the value. 00257 Double getDouble (const String& key); 00258 00259 // Get the Block<double> value of the parameter (or default Block if unknown 00260 // key). 00261 // If the program is in prompt mode, ask the user for the value. 00262 Block<Double> getDoubleArray (const String& key); 00263 00264 // Get the int value of the parameter (or 0 if unknown key). 00265 // If the program is in prompt mode, ask the user for the value. 00266 Int getInt (const String& key); 00267 00268 // Get the Block<int> value of parameter (or default Block if unknown key) 00269 // If the program is in prompt mode, ask the user for the value. 00270 Block<Int> getIntArray (const String& key); 00271 00272 // Get the String value of the parameter (or "" if unknown key). 00273 // If the program is in prompt mode, ask the user for the value. 00274 String getString (const String& key); 00275 00276 // Get the boolean value of the parameter (or FALSE if unknown key). 00277 // If the program is in prompt mode, ask the user for the value. 00278 Bool getBool (const String& key); 00279 00280 // Get the total number of parameters of this program 00281 Int count() const; 00282 00283 // See if the current debug level is thresholded 00284 Bool debug (Int l) const 00285 { return (debug_level >= l) ? True : False; } 00286 00287 // Set a new value for an existing named parameter 00288 // Returns FALSE if key is an unknown parameter name. 00289 // <group> 00290 Bool put (const String& key, const String& value); 00291 00292 // The single argument is of the form `key=value', where key is a valid 00293 // parameter name. 00294 Bool put (const String& keyval); 00295 // </group> 00296 00297 // Set version string for announcements 00298 void version (const String&); 00299 00300 // Announce program and version. 00301 void announce(); 00302 00303 // Turn a string in the form "5,7,9-11,13,2-4" into a Vector<Bool>, where 00304 // each specified position or range, is set to True and every other position 00305 // is set to False. While the returned vector always has a zero origin, if 00306 // oneRelative is True, all the numbers in the supplied string are 00307 // decremented before use. Spaces in ranges are ignored, but otherwise 00308 // ill-formed strings, or numbers that would fill in beyond the length 00309 // of the Vector<Bool> results in an exception being thrown. 00310 static Vector<Bool> makeMaskFromRanges(const String& ranges, uInt length, 00311 Bool oneRelative=False); 00312 00313 00314 private: 00315 // Get the index of the named parameter (0 if unknown key). 00316 // Anywhere from 1.. if a key is found. 00317 Int getParam (const String& key) const; 00318 00319 // Prompt the user for a value for the parameter. 00320 // If he gives a non-empty answer, set that value. 00321 void prompt (Param& parameter) const; 00322 00323 // Bind an environment variable to a parameter 00324 void envCreate (const Char *env, const String& key, const String& def); 00325 00326 // The actual creation of a new (system/program) parameter 00327 void createPar (Int, const String&, const String&, const String&, 00328 const String&, const String&, const String&); 00329 00330 // output to stdout a Khoros Cantata pane. 00331 void pane(); 00332 00333 // output to stdout a listing of all "key=value" pairs. 00334 void keys(); 00335 00336 00337 // linked list container of parameters 00338 List<Param> parList_p; 00339 00340 // version id 00341 String version_id; 00342 00343 // parameter creation allowed? 00344 Bool is_closed; 00345 00346 // ask user for parameter value? 00347 Bool do_prompt; 00348 00349 // threshold value for debug output 00350 Int debug_level; 00351 00352 // "prompt", "keys", or "pane" indicates the various types of help. 00353 String help_mode; 00354 00355 // count of program parameters 00356 Int p_count; 00357 }; 00358 00359 00360 } //# NAMESPACE CASA - END 00361 00362 #endif 00363 00364