casa
$Rev:20696$
|
00001 //# Aipsrc.h: Class to read the casa general resource files 00002 //# Copyright (C) 1995,1996,1997,1998,1999,2002,2004 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: Aipsrc.h 21067 2011-05-06 13:58:12Z gervandiepen $ 00027 00028 #ifndef CASA_AIPSRC_H 00029 #define CASA_AIPSRC_H 00030 00031 #include <casa/aips.h> 00032 #include <casa/BasicSL/String.h> 00033 #include <casa/Containers/Block.h> 00034 #include <casa/Arrays/Vector.h> 00035 #include <casa/OS/Mutex.h> 00036 00037 namespace casa { //# NAMESPACE CASA - BEGIN 00038 00039 //# Forward declarations 00040 template <class T> class AipsrcValue; 00041 template <class T> class AipsrcVector; 00042 class Aipsrc; 00043 00044 //# Typedefs 00045 typedef AipsrcValue<Double> AipsrcDouble; 00046 typedef AipsrcValue<Int> AipsrcInt; 00047 typedef AipsrcValue<Bool> AipsrcBool; 00048 typedef Aipsrc AipsrcString; 00049 typedef AipsrcVector<Double> AipsrcVDouble; 00050 typedef AipsrcVector<Int> AipsrcVInt; 00051 typedef AipsrcVector<Bool> AipsrcVBool; 00052 typedef AipsrcVector<String> AipsrcVString; 00053 00054 00055 // <summary> Class to read the casa general resource files </summary> 00056 00057 // <use visibility=export> 00058 00059 // <reviewed reviewer="wyoung" date="1996/11/25" tests="tAipsrc" demos=""> 00060 // </reviewed> 00061 00062 // <prerequisite> 00063 // <li> None 00064 // </prerequisite> 00065 // 00066 // <etymology> 00067 // A class for getting values from the casa resource files 00068 // </etymology> 00069 // 00070 // <synopsis> 00071 // The static Aipsrc class can get information from the casa resource files. 00072 // It has the same functionality as getrc (c program used for aips++ 00073 // installation scripts).<br> 00074 // In addition it acts as a central clearing house between system and 00075 // software by providing functionality to obtain aips++ system parameters (like 00076 // AIPSPATH elements), and the possibility of storing system wide information 00077 // provided by a class for reference by other classes. <br> 00078 // The format of a line in a resource file is: 00079 // <srcblock> 00080 // # Line starting with an # in column 1 is a comment (as is an empty line) 00081 // keyword: value 00082 // keyword: value 00083 // </srcblock> 00084 // The keyword (starting at first non-blank) 00085 // consists in general of keyword fields separated by periods: 00086 //<srcblock> 00087 // printer.ps.page 00088 // measures.precession.d_interval 00089 // measures.nutation.d_interval 00090 // </srcblock> 00091 // and, by preference, in lower case (but 00092 // search is case sensitive) with an <src>_</src> as word-parts separator. <br> 00093 // The keyword and value are separated by a <src>:</src>. The value is the string 00094 // from the first non-whitespace character after the separator to the end of 00095 // the line. Interpretation of the string is in general the program's 00096 // responsibility, but special <src>find()</src> calls (see below) exist to 00097 // aid.<br> 00098 // Any part of the keyword string can be replaced by a wildcard <src>*</src> 00099 // to indicate all values with that structure (e.g. 00100 // <src>*.d_interval</src> would indicate in the example above both the 00101 // precession and the nutation <src>d_interval</src>.<br> 00102 // A match between a keyword to be found and a keyword in the resource files 00103 // will be the first match (taking wildcards into account) encountered in the 00104 // search through the resource files. 00105 // The resource files to be looked at can be defined in the environment 00106 // variable CASARCFILES. If undefined, the resource files searched are (in the 00107 // given order): 00108 // <srcblock> 00109 // ~/.casarc 00110 // ~/.casa/rc 00111 // ~/.aipsrc 00112 // $AIPSROOT/.aipsrc 00113 // $AIPSHOST/aipsrc 00114 // $AIPSSITE/aipsrc 00115 // $AIPSARCH/aipsrc 00116 // </srcblock> 00117 // It is not an error for any of the aipsrc files to be absent or empty. 00118 // However, it is an error if <em>HOME</em> has not been set: 00119 // an exception will occur. AIPSPATH will in general be 00120 // read from the global environment variables, but can, before any other 00121 // <src>Aipsrc</src> related call, be set with the 00122 // <src>setAipsPath()</src> call.<br> 00123 // If AIPSPATH is not set in either way, it is set to the home directory. 00124 // <p> 00125 // The basic interaction with the class is with the static keyword match function 00126 // <srcblock>Bool Aipsrc::find(String &result, const String &keyword) 00127 // </srcblock> 00128 // A set of 00129 // <srcblock>Bool AipsrcValue::find(Type &result, const String &keyword, ...) 00130 // </srcblock> 00131 // are available to interpret the string value found. 00132 // (see <linkto class="AipsrcValue">AipsrcValue</linkto>).<br> 00133 // All the <src>find</src> 00134 // functions have the ability to set a default if there is no match, 00135 // while also unit conversion is possible.<br> 00136 // The Bool return indicates if the keyword was found, and, in the case of the 00137 // interpretative finds, if an 'important' format error was found (e.g. 00138 // '+12a' will be accepted as a Double, with a result of '12', since the 00139 // standard double conversion in <src>>></src> will produce this result.) 00140 // <note role=caution> The search keyword (unlike the file keyword) has no 00141 // wildcards. The real name should, of course, be looked for.</note> 00142 // To aid in other places, the following (static) methods are available 00143 // to get the requested information (derived from <src>HOME</src> and 00144 // <src>AIPSPATH</src>, computer system information and/or aipsrc keywords): 00145 // <ul> 00146 // <li> const String &Aipsrc::aipsRoot() 00147 // <li> const String &Aipsrc::aipsArch() 00148 // <li> const String &Aipsrc::aipsSite() 00149 // <li> const String &Aipsrc::aipsHost() 00150 // <li> const String &Aipsrc::aipsHome() -- <src>~/aips++</src> 00151 // </ul> 00152 // Other, numeric, system information can be found in 00153 // <linkto class=AipsrcValue>AipsrcValue</linkto>.<br> 00154 // 00155 // Given an AIPSPATH of 00156 // <srcblock>/epp/aips++ sun4sol_gnu epping norma</srcblock> 00157 // aipsSite will return 00158 // <srcblock>/epp/aips++/sun4sol_gnu/epping</srcblock>. 00159 // 00160 // The basic find above reacts with the aipsrc files available. If regular 00161 // access is necessary (e.g. a lot of routines have to check independently a 00162 // certain integration time limit), keywords can be <em>registered</em> to 00163 // enable: 00164 // <ul> 00165 // <li> fast access with integer code, rather than string 00166 // <li> ability to set values from programs if no aipsrc information given 00167 // (a dynamic default) 00168 // <li> update the <src>$HOME/.aipsrc</src> keyword/value list with save() 00169 // </ul> 00170 // <note role=tip> The registered value is never equal to zero, hence a zero 00171 // value can be used to check if registration is done. Also, registering the 00172 // same keyword twice is safe, and will produce the same value.</note> 00173 // When saving a keyword/value pair in <src>$HOME/.aipsrc</src>, the old 00174 // version is saved in <src>$HOME/.aipsrc.old</src>, before the keyword/value 00175 // pair is prepended to the file. A limited number of edits of the same keyword 00176 // is preserved only (default 5, changeable with the 00177 // <src>user.aipsrc.edit.keep</src> keyword. 00178 // </synopsis> 00179 // 00180 // <example> 00181 // <srcblock> 00182 // String printerPage; // result of keyword find 00183 // if(!Aipsrc::find(printerPage, "printer.ps.page")) { // look for keyword match 00184 // printerPage = "notSet"; 00185 // }; 00186 // </srcblock> 00187 // A more convenient way of accomplishing the same result is: 00188 // <srcblock> 00189 // Aipsrc::find(printerPage, "printer.ps.page", "notSet"); 00190 // </srcblock> 00191 // Here the final argument is the default to use if the keyword is not found 00192 // at all.<br> 00193 // If you often want to know, dynamically, the current 'printer.ps.page' 00194 // value, you could do something like: 00195 // <srcblock> 00196 // static uInt pp = Aipsrc::registerRC("printer.ps.page", "noSet"); 00197 // String printerPage = Aipsrc::get(pp); 00198 // // Processing, and maybe somewhere else: 00199 // Aipsrc::set(pp, "nowSet"); 00200 // // ... 00201 // printerPage = Aipsrc::get(pp); 00202 // // and save it to the <src>$HOME/.aipsrc</src> list 00203 // Aipsrc::save(pp); 00204 // </srcblock> 00205 // </example> 00206 // 00207 // <motivation> 00208 // Programs need a way to interact with the aipsrc files. 00209 // </motivation> 00210 // 00211 // <thrown> 00212 // <li>AipsError if the environment variables HOME and/or AIPSPATH not set. 00213 // </thrown> 00214 // 00215 // <todo asof="1997/08/07"> 00216 // </todo> 00217 00218 class Aipsrc { 00219 00220 public: 00221 //# Constructors 00222 00223 //# Destructor 00224 00225 //# Copy assignment 00226 00227 //# Member functions 00228 // <thrown> 00229 // <li> AipsError if HOME environment variable not set 00230 // </thrown> 00231 // The <src>find()</src> functions will, given a keyword, return the value 00232 // with a matched keyword found in the files. If no match found the 00233 // function will be False. The <src>findNoHome()</src> emulates the <src>-i</src> 00234 // switch of getrc by bypassing the <src>~/.aipsrc</src> file. 00235 // <group> 00236 static Bool find(String &value, const String &keyword); 00237 static Bool findNoHome(String &value, const String &keyword); 00238 // </group> 00239 00240 // These finds check a (possible) value of the keyword against a list 00241 // of coded values provided, and return an index into the list (N if not 00242 // found). Matching is minimax, case insensitive. Always better to use 00243 // the one with default. return is False if no keyword or no match. 00244 // <group> 00245 static Bool find(uInt &value, const String &keyword, 00246 Int Nname, const String tname[]); 00247 static Bool find(uInt &value, const String &keyword, 00248 const Vector<String> &tname); 00249 // </group> 00250 // This find usually saves you some lines of code, since you can supply the 00251 // default you want to use when no such keyword is defined. 00252 // If the return value is False, the keyword was not found and the default 00253 // was used. 00254 // <group> 00255 static Bool find(String &value, const String &keyword, 00256 const String &deflt); 00257 static Bool findNoHome(String &value, const String &keyword, 00258 const String &deflt); 00259 static Bool find(uInt &value, const String &keyword, 00260 Int Nname, const String tname[], const String &deflt); 00261 static Bool find(uInt &value, const String &keyword, 00262 const Vector<String> &tname, const String &deflt); 00263 // </group> 00264 00265 // Sets foundDir to the first /firstPart/lastPart path that it finds 00266 // present on the system, where /firstPart comes from, in order, 00267 // this list: 00268 // contents of prepends 00269 // + useStd ? (., aipsHome(), aipsRoot()) : () 00270 // + contents of appends 00271 static Bool findDir(String& foundDir, const String& lastPart="", 00272 const Vector<String>& prepends=Vector<String>(), 00273 const Vector<String>& appends=Vector<String>(), 00274 Bool useStds=True); 00275 00276 // Functions to register keywords for later use in get() and set(). The 00277 // returned value is the index for get() and set(). 00278 // <group> 00279 static uInt registerRC(const String &keyword, 00280 const String &deflt); 00281 static uInt registerRC(const String &keyword, 00282 Int Nname, const String tname[], const String &deflt); 00283 static uInt registerRC(const String &keyword, 00284 const Vector<String> &tname, const String &deflt); 00285 // </group> 00286 00287 // Gets are like find, but using registered integers rather than names. 00288 // <group> 00289 static const String &get(uInt keyword); 00290 // get for code 00291 static const uInt &get(uInt &code, uInt keyword); 00292 // </group> 00293 00294 // Sets allow registered values to be set 00295 // <group> 00296 static void set(uInt keyword, const String &deflt); 00297 static void set(uInt keyword, 00298 Int Nname, const String tname[], const String &deflt); 00299 static void set(uInt keyword, 00300 const Vector<String> &tname, const String &deflt); 00301 // </group> 00302 00303 // Save a registered keyword value to <src>$HOME/.aipsrc</src> 00304 // <group> 00305 static void save(uInt keyword); 00306 static void save(uInt keyword, const String tname[]); 00307 static void save(uInt keyword, const Vector<String> &tname); 00308 // </group> 00309 00310 // Set an AIPSPATH that should be used in stead of a global AIPSPATH. 00311 // This call should be made before any Aipsrc related call. The AIPSPATH 00312 // will have up to 4 fields (which can all be empty) giving the root, host, 00313 // site and arch directory that will be searched for possible 00314 // <src>[.]aipsrc</src> files. 00315 static void setAipsPath(const String &path = String()); 00316 00317 // Returns the appropriate AIPS++ or system variable values 00318 // <group> 00319 static const String &aipsRoot(); 00320 static const String &aipsArch(); 00321 static const String &aipsSite(); 00322 static const String &aipsHost(); 00323 // Returns: <src>~/aips++</src> 00324 static const String &aipsHome(); 00325 // </group> 00326 00327 // The <src>reRead()</src> function, will reinitialise the static maps and read the 00328 // aipsrc files again. It could be useful in some interactive or multi-processor 00329 // circumstances. <src>lastRead()</src> returns the time last reRead. 00330 // <group> 00331 static void reRead(); 00332 static Double lastRead(); 00333 // </group> 00334 00335 00336 // The following functions return the full lists of available data. They could 00337 // be useful for debugging purposes. 00338 // <group> 00339 static const Block<String> &values(); 00340 static const Block<String> &patterns(); 00341 // </group> 00342 00343 // The following <src>show()</src> function, useful for debugging, outputs 00344 // all keyword/value pairs found 00345 static void show(ostream &oStream); 00346 // Prints all info on cout 00347 static void show(); 00348 // The following set is a general set of functions 00349 // <group> 00350 // Read aipsrc type files (without wildcards), and return the unique names 00351 // and values in the Vector arguments. The return value is number of names. 00352 static uInt genRestore(Vector<String> &namlst, Vector<String> &vallst, 00353 const String &fileList); 00354 // Save the names/values in file 00355 static void genSave(Vector<String> &namlst, Vector<String> &vallst, 00356 const String &fnam); 00357 // Set (new or overwrite) keyword/value pair 00358 static void genSet(Vector<String> &namlst, Vector<String> &vallst, 00359 const String &nam, const String &val); 00360 // Remove a keyword from list (False if not in list) 00361 static Bool genUnSet(Vector<String> &namlst, Vector<String> &vallst, 00362 const String &nam); 00363 // Get the value of a keyword 00364 static Bool genGet(String &val, Vector<String> &namlst, Vector<String> &vallst, 00365 const String &nam); 00366 // </group> 00367 00368 protected: 00369 // Actual find function 00370 static Bool find(String &value, const String &keyword, 00371 uInt start); 00372 // The registration function 00373 static uInt registerRC(const String &keyword, Block<String> &nlst); 00374 // Actual saving 00375 static void save(const String keyword, const String val); 00376 00377 private: 00378 //# Data 00379 static Mutex theirMutex; 00380 // Indicate files read 00381 static volatile Bool doInit; 00382 // Last time data was (re)read 00383 static Double lastParse; 00384 // List of values belonging to keywords found 00385 static Block<String> keywordValue; 00386 // List of patterns deducted from names 00387 static Block<String> keywordPattern; 00388 // The start of the non-home values 00389 static uInt fileEnd; 00390 // The possibly set external AIPSPATH 00391 static String extAipsPath; 00392 // AIPSROOT 00393 static String root; 00394 // AIPSARCH 00395 static String arch; 00396 // AIPSSITE 00397 static String site; 00398 // AIPSHOST 00399 static String host; 00400 // AIPSHOME 00401 static String home; 00402 // HOME 00403 static String uhome; 00404 // Indicate above filled 00405 static Bool filled; 00406 // String register list 00407 // <group> 00408 static Block<String> strlst; 00409 static Block<String> nstrlst; 00410 static Block<uInt> codlst; 00411 static Block<String> ncodlst; 00412 // </group> 00413 00414 //# General member functions 00415 // Read in the aipsrc files, returning the number of lines found 00416 // <group> 00417 static void parse(Bool force=False); 00418 static void doParse(String &fileList); 00419 // </group> 00420 00421 // The following parse function can be used for any list of files. It will 00422 // return the list of Patterns and values found, and the last keyword number 00423 // of first file in list. 00424 static uInt genParse(Block<String> &keywordPattern, 00425 Block<String> &keywordValue, 00426 uInt &fileEnd, const String &fileList); 00427 00428 // Locate the right keyword in the static maps 00429 static Bool matchKeyword(uInt &where, const String &keyword, 00430 uInt start); 00431 // Fill in root, arch, site, host and home, and return requested nam 00432 static const String &fillAips(const String &nam); 00433 }; 00434 00435 00436 } //# NAMESPACE CASA - END 00437 00438 #endif 00439 00440