00001 //# Aipsrc.h: Class to read the aipsrc 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$ 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 00035 00036 namespace casa { //# NAMESPACE CASA - BEGIN 00037 00038 //# Forward declarations 00039 template <class T> class Vector; 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 aipsrc 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 aipsrc files 00068 // </etymology> 00069 // 00070 // <synopsis> 00071 // The static Aipsrc class can get information from the aipsrc 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. The resource files searched are (in the 00105 // given order): 00106 // <srcblock> 00107 // ~/.aipsrc 00108 // $AIPSROOT/.aipsrc 00109 // $AIPSHOST/aipsrc 00110 // $AIPSSITE/aipsrc 00111 // $AIPSARCH/aipsrc 00112 // </srcblock> 00113 // It is not an error for any of the aipsrc files to be absent or empty. 00114 // However, it is an error if either <em>HOME</em> or <em>AIPSPATH</em> has 00115 // not been set: an exception will occur. AIPSPATH will in general be 00116 // read from the global environment variables, but can, before any other 00117 // <src>Aipsrc</src> related call, be set with the 00118 // <src>setAipsPath()</src> call.<br> 00119 // The basic interaction with the class is with the static keyword match function 00120 // <srcblock>Bool Aipsrc::find(String &result, const String &keyword) 00121 // </srcblock> 00122 // A set of 00123 // <srcblock>Bool AipsrcValue::find(Type &result, const String &keyword, ...) 00124 // </srcblock> 00125 // are available to interpret the string value found. 00126 // (see <linkto class="AipsrcValue">AipsrcValue</linkto>).<br> 00127 // All the <src>find</src> 00128 // functions have the ability to set a default if there is no match, 00129 // while also unit conversion is possible.<br> 00130 // The Bool return indicates if the keyword was found, and, in the case of the 00131 // interpretative finds, if an 'important' format error was found (e.g. 00132 // '+12a' will be accepted as a Double, with a result of '12', since the 00133 // standard double conversion in <src>>></src> will produce this result.) 00134 // <note role=caution> The search keyword (unlike the file keyword) has no 00135 // wildcards. The real name should, of course, be looked for.</note> 00136 // To aid in other places, the following (static) methods are available 00137 // to get the requested information (derived from <src>HOME</src> and 00138 // <src>AIPSPATH</src>, computer system information and/or aipsrc keywords): 00139 // <ul> 00140 // <li> const String &Aipsrc::aipsRoot() 00141 // <li> const String &Aipsrc::aipsArch() 00142 // <li> const String &Aipsrc::aipsSite() 00143 // <li> const String &Aipsrc::aipsHost() 00144 // <li> const String &Aipsrc::aipsHome() -- <src>~/aips++</src> 00145 // </ul> 00146 // Other, numeric, system information can be found in 00147 // <linkto class=AipsrcValue>AipsrcValue</linkto>.<br> 00148 // 00149 // Given an AIPSPATH of 00150 // <srcblock>/epp/aips++ sun4sol_gnu epping norma</srcblock> 00151 // aipsSite will return 00152 // <srcblock>/epp/aips++/sun4sol_gnu/epping</srcblock>. 00153 // 00154 // The basic find above reacts with the aipsrc files available. If regular 00155 // access is necessary (e.g. a lot of routines have to check independently a 00156 // certain integration time limit), keywords can be <em>registered</em> to 00157 // enable: 00158 // <ul> 00159 // <li> fast access with integer code, rather than string 00160 // <li> ability to set values from programs if no aipsrc information given 00161 // (a dynamic default) 00162 // <li> update the <src>$HOME/.aipsrc</src> keyword/value list with save() 00163 // </ul> 00164 // <note role=tip> The registered value is never equal to zero, hence a zero 00165 // value can be used to check if registration is done. Also, registering the 00166 // same keyword twice is safe, and will produce the same value.</note> 00167 // When saving a keyword/value pair in <src>$HOME/.aipsrc</src>, the old 00168 // version is saved in <src>$HOME/.aipsrc.old</src>, before the keyword/value 00169 // pair is prepended to the file. A limited number of edits of the same keyword 00170 // is preserved only (default 5, changeable with the 00171 // <src>user.aipsrc.edit.keep</src> keyword. 00172 // </synopsis> 00173 // 00174 // <example> 00175 // <srcblock> 00176 // String printerPage; // result of keyword find 00177 // if(!Aipsrc::find(printerPage, "printer.ps.page")) { // look for keyword match 00178 // printerPage = "notSet"; 00179 // }; 00180 // </srcblock> 00181 // A more convenient way of accomplishing the same result is: 00182 // <srcblock> 00183 // Aipsrc::find(printerPage, "printer.ps.page", "notSet"); 00184 // </srcblock> 00185 // Here the final argument is the default to use if the keyword is not found 00186 // at all.<br> 00187 // If you often want to know, dynamically, the current 'printer.ps.page' 00188 // value, you could do something like: 00189 // <srcblock> 00190 // static uInt pp = Aipsrc::registerRC("printer.ps.page", "noSet"); 00191 // String printerPage = Aipsrc::get(pp); 00192 // // Processing, and maybe somewhere else: 00193 // Aipsrc::set(pp, "nowSet"); 00194 // // ... 00195 // printerPage = Aipsrc::get(pp); 00196 // // and save it to the <src>$HOME/.aipsrc</src> list 00197 // Aipsrc::save(pp); 00198 // </srcblock> 00199 // </example> 00200 // 00201 // <motivation> 00202 // Programs need a way to interact with the aipsrc files. 00203 // </motivation> 00204 // 00205 // <thrown> 00206 // <li>AipsError if the environment variables HOME and/or AIPSPATH not set. 00207 // </thrown> 00208 // 00209 // <todo asof="1997/08/07"> 00210 // </todo> 00211 00212 class Aipsrc { 00213 00214 public: 00215 //# Constructors 00216 00217 //# Destructor 00218 00219 //# Copy assignment 00220 00221 //# Member functions 00222 // <thrown> 00223 // <li> AipsError if HOME or AIPSPATH environment variable not set 00224 // </thrown> 00225 // The <src>find()</src> functions will, given a keyword, return the value 00226 // with a matched keyword found in the files. If no match found the 00227 // function will be False. The <src>findNoHome()</src> emulates the <src>-i</src> 00228 // switch of getrc by bypassing the <src>~/.aipsrc</src> file. 00229 // <group> 00230 static Bool find(String &value, const String &keyword); 00231 static Bool findNoHome(String &value, const String &keyword); 00232 // </group> 00233 00234 // These finds check a (possible) value of the keyword against a list 00235 // of coded values provided, and return an index into the list (N if not 00236 // found). Matching is minimax, case insensitive. Always better to use 00237 // the one with default. return is False if no keyword or no match. 00238 // <group> 00239 static Bool find(uInt &value, const String &keyword, 00240 Int Nname, const String tname[]); 00241 static Bool find(uInt &value, const String &keyword, 00242 const Vector<String> &tname); 00243 // </group> 00244 // This find usually saves you some lines of code, since you can supply the 00245 // default you want to use when no such keyword is defined. 00246 // If the return value is False, the keyword was not found and the default 00247 // was used. 00248 // <group> 00249 static Bool find(String &value, const String &keyword, 00250 const String &deflt); 00251 static Bool findNoHome(String &value, const String &keyword, 00252 const String &deflt); 00253 static Bool find(uInt &value, const String &keyword, 00254 Int Nname, const String tname[], const String &deflt); 00255 static Bool find(uInt &value, const String &keyword, 00256 const Vector<String> &tname, const String &deflt); 00257 // </group> 00258 00259 // Functions to register keywords for later use in get() and set(). The 00260 // returned value is the index for get() and set(). 00261 // <group> 00262 static uInt registerRC(const String &keyword, 00263 const String &deflt); 00264 static uInt registerRC(const String &keyword, 00265 Int Nname, const String tname[], const String &deflt); 00266 static uInt registerRC(const String &keyword, 00267 const Vector<String> &tname, const String &deflt); 00268 // </group> 00269 00270 // Gets are like find, but using registered integers rather than names. 00271 // <group> 00272 static const String &get(uInt keyword); 00273 // get for code 00274 static const uInt &get(uInt &code, uInt keyword); 00275 // </group> 00276 00277 // Sets allow registered values to be set 00278 // <group> 00279 static void set(uInt keyword, const String &deflt); 00280 static void set(uInt keyword, 00281 Int Nname, const String tname[], const String &deflt); 00282 static void set(uInt keyword, 00283 const Vector<String> &tname, const String &deflt); 00284 // </group> 00285 00286 // Save a registered keyword value to <src>$HOME/.aipsrc</src> 00287 // <group> 00288 static void save(uInt keyword); 00289 static void save(uInt keyword, const String tname[]); 00290 static void save(uInt keyword, const Vector<String> &tname); 00291 // </group> 00292 00293 // Set an AIPSPATH that should be used in stead of a global AIPSPATH. 00294 // This call should be made before any Aipsrc related call. The AIPSPATH 00295 // will have up to 4 fields (which can all be empty) giving the root, host, 00296 // site and arch directory that will be searched for possible 00297 // <src>[.]aipsrc</src> files. 00298 static void setAipsPath(const String &path = String()); 00299 00300 // Returns the appropriate AIPS++ or system variable values 00301 // <group> 00302 static const String &aipsRoot(); 00303 static const String &aipsArch(); 00304 static const String &aipsSite(); 00305 static const String &aipsHost(); 00306 // Returns: <src>~/aips++</src> 00307 static const String &aipsHome(); 00308 // </group> 00309 00310 // The <src>reRead()</src> function, will reinitialise the static maps and read the 00311 // aipsrc files again. It could be useful in some interactive or multi-processor 00312 // circumstances. <src>lastRead()</src> returns the time last reRead. 00313 // <group> 00314 static void reRead(); 00315 static Double lastRead(); 00316 // </group> 00317 00318 00319 // The following functions return the full lists of available data. They could 00320 // be useful for debugging purposes. 00321 // <group> 00322 static const Block<String> &values(); 00323 static const Block<String> &patterns(); 00324 // </group> 00325 00326 // The following <src>show()</src> function, useful for debugging, outputs 00327 // all keyword/value pairs found 00328 static void show(ostream &oStream); 00329 // Prints all info on cout 00330 static void show(); 00331 // The following set is a general set of functions 00332 // <group> 00333 // Read aipsrc type files (without wildcards), and return the unique names 00334 // and values in the Vector arguments. The return value is number of names. 00335 static uInt genRestore(Vector<String> &namlst, Vector<String> &vallst, 00336 const String &fileList); 00337 // Save the names/values in file 00338 static void genSave(Vector<String> &namlst, Vector<String> &vallst, 00339 const String &fnam); 00340 // Set (new or overwrite) keyword/value pair 00341 static void genSet(Vector<String> &namlst, Vector<String> &vallst, 00342 const String &nam, const String &val); 00343 // Remove a keyword from list (False if not in list) 00344 static Bool genUnSet(Vector<String> &namlst, Vector<String> &vallst, 00345 const String &nam); 00346 // Get the value of a keyword 00347 static Bool genGet(String &val, Vector<String> &namlst, Vector<String> &vallst, 00348 const String &nam); 00349 // </group> 00350 00351 protected: 00352 // Actual find function 00353 static Bool find(String &value, const String &keyword, 00354 uInt start); 00355 // The registration function 00356 static uInt registerRC(const String &keyword, Block<String> &nlst); 00357 // Actual saving 00358 static void save(const String keyword, const String val); 00359 00360 private: 00361 //# Data 00362 // Indicate files read 00363 static Bool doInit; 00364 // Last time data was (re)read 00365 static Double lastParse; 00366 // List of values belonging to keywords found 00367 static Block<String> keywordValue; 00368 // List of patterns deducted from names 00369 static Block<String> keywordPattern; 00370 // The start of the non-home values 00371 static uInt fileEnd; 00372 // The possibly set external AIPSPATH 00373 static String extAipsPath; 00374 // AIPSROOT 00375 static String root; 00376 // AIPSARCH 00377 static String arch; 00378 // AIPSSITE 00379 static String site; 00380 // AIPSHOST 00381 static String host; 00382 // AIPSHOME 00383 static String home; 00384 // HOME 00385 static String uhome; 00386 // Indicate above filled 00387 static Bool filled; 00388 // String register list 00389 // <group> 00390 static Block<String> strlst; 00391 static Block<String> nstrlst; 00392 static Block<uInt> codlst; 00393 static Block<String> ncodlst; 00394 // </group> 00395 00396 //# General member functions 00397 // Read in the aipsrc files, returning the number of lines found 00398 // <group> 00399 static uInt parse(); 00400 static uInt parse(String &fileList); 00401 // </group> 00402 00403 // The following parse function can be used for any list of files. It will 00404 // return the list of Patterns and values found, and the last keyword number 00405 // of first file in list. 00406 static uInt genParse(Block<String> &keywordPattern, 00407 Block<String> &keywordValue, 00408 uInt &fileEnd, const String &fileList); 00409 00410 // Locate the right keyword in the static maps 00411 static Bool matchKeyword(uInt &where, const String &keyword, 00412 uInt start); 00413 // Fill in root, arch, site, host and home, and return requested nam 00414 static const String &fillAips(const String &nam); 00415 }; 00416 00417 00418 } //# NAMESPACE CASA - END 00419 00420 #endif 00421 00422
1.5.1