casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Input.h
Go to the documentation of this file.
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