//# Aipsrc.h: Class to read the casa general resource files //# Copyright (C) 1995,1996,1997,1998,1999,2002,2004,2016 //# Associated Universities, Inc. Washington DC, USA. //# //# This library is free software; you can redistribute it and/or modify it //# under the terms of the GNU Library General Public License as published by //# the Free Software Foundation; either version 2 of the License, or (at your //# option) any later version. //# //# This library is distributed in the hope that it will be useful, but WITHOUT //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public //# License for more details. //# //# You should have received a copy of the GNU Library General Public License //# along with this library; if not, write to the Free Software Foundation, //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. //# //# Correspondence concerning AIPS++ should be addressed as follows: //# Internet email: aips2-request@nrao.edu. //# Postal address: AIPS++ Project Office //# National Radio Astronomy Observatory //# 520 Edgemont Road //# Charlottesville, VA 22903-2475 USA //# //# $Id$ #ifndef CASA_AIPSRC_H #define CASA_AIPSRC_H #include #include #include #include #include namespace casacore { //# NAMESPACE CASACORE - BEGIN //# Forward declarations template class AipsrcValue; template class AipsrcVector; class Aipsrc; //# Typedefs typedef AipsrcValue AipsrcDouble; typedef AipsrcValue AipsrcInt; typedef AipsrcValue AipsrcBool; typedef Aipsrc AipsrcString; typedef AipsrcVector AipsrcVDouble; typedef AipsrcVector AipsrcVInt; typedef AipsrcVector AipsrcVBool; typedef AipsrcVector AipsrcVString; // Class to read the casa general resource files // // // // //
  • None // // // // A class for getting values from the casa resource files // // // // The static Aipsrc class can get information from the casa resource files. // It has the same functionality as getrc (c program used for Casacore // installation scripts).
    // In addition it acts as a central clearing house between system and // software by providing functionality to obtain Casacore system parameters // (like AIPSPATH elements), and the possibility of storing system wide // information provided by a class for reference by other classes.
    // The format of a line in a resource file is: // // # Line starting with an # in column 1 is a comment (as is an empty line) // keyword: value // keyword: value // // The keyword (starting at first non-blank) // consists in general of keyword fields separated by periods: // // printer.ps.page // measures.precession.d_interval // measures.nutation.d_interval // // and, by preference, in lower case (but // search is case sensitive) with an _ as word-parts separator.
    // The keyword and value are separated by a :. The value is the string // from the first non-whitespace character after the separator to the end of // the line. Interpretation of the string is in general the program's // responsibility, but special find() calls (see below) exist to // aid.
    // Any part of the keyword string can be replaced by a wildcard * // to indicate all values with that structure (e.g. // *.d_interval would indicate in the example above both the // precession and the nutation d_interval.
    // A match between a keyword to be found and a keyword in the resource files // will be the first match (taking wildcards into account) encountered in the // search through the resource files. // The resource files to be looked at can be defined in the environment // variable CASARCFILES. If undefined, the resource files searched are (in the // given order): // // ~/.casarc // ~/.casa/rc // ~/.aipsrc // $AIPSROOT/.aipsrc // $AIPSHOST/aipsrc // $AIPSSITE/aipsrc // $AIPSARCH/aipsrc // // It is not an error for any of the aipsrc files to be absent or empty. // However, it is an error if HOME has not been set: // an exception will occur. AIPSPATH will in general be // read from the global environment variables, but can, before any other // Aipsrc related call, be set with the // setAipsPath() call.
    // If AIPSPATH is not set in either way, it is set to the home directory. //

    // The basic interaction with the class is with the static keyword match function // Bool Aipsrc::find(String &result, const String &keyword) // // A set of // Bool AipsrcValue::find(Type &result, const String &keyword, ...) // // are available to interpret the string value found. // (see AipsrcValue).
    // All the find // functions have the ability to set a default if there is no match, // while also unit conversion is possible.
    // The Bool return indicates if the keyword was found, and, in the case of the // interpretative finds, if an 'important' format error was found (e.g. // '+12a' will be accepted as a Double, with a result of '12', since the // standard double conversion in >> will produce this result.) // The search keyword (unlike the file keyword) has no // wildcards. The real name should, of course, be looked for. // To aid in other places, the following (static) methods are available // to get the requested information (derived from HOME and // AIPSPATH, computer system information and/or aipsrc keywords): //

      //
    • const String &Aipsrc::aipsRoot() //
    • const String &Aipsrc::aipsArch() //
    • const String &Aipsrc::aipsSite() //
    • const String &Aipsrc::aipsHost() //
    • const String &Aipsrc::aipsHome() //
    // Other, numeric, system information can be found in // AipsrcValue.
    // // Given an AIPSPATH of // /epp/aips++ sun4sol_gnu epping norma // aipsSite will return // /epp/aips++/sun4sol_gnu/epping. // // The basic find above reacts with the aipsrc files available. If regular // access is necessary (e.g. a lot of routines have to check independently a // certain integration time limit), keywords can be registered to // enable: //
      //
    • fast access with integer code, rather than string //
    • ability to set values from programs if no aipsrc information given // (a dynamic default) //
    • update the $HOME/.aipsrc keyword/value list with save() //
    // The registered value is never equal to zero, hence a zero // value can be used to check if registration is done. Also, registering the // same keyword twice is safe, and will produce the same value. // When saving a keyword/value pair in $HOME/.aipsrc, the old // version is saved in $HOME/.aipsrc.old, before the keyword/value // pair is prepended to the file. A limited number of edits of the same keyword // is preserved only (default 5, changeable with the // user.aipsrc.edit.keep keyword. //
    // // // // String printerPage; // result of keyword find // if(!Aipsrc::find(printerPage, "printer.ps.page")) { // look for keyword match // printerPage = "notSet"; // }; // // A more convenient way of accomplishing the same result is: // // Aipsrc::find(printerPage, "printer.ps.page", "notSet"); // // Here the final argument is the default to use if the keyword is not found // at all.
    // If you often want to know, dynamically, the current 'printer.ps.page' // value, you could do something like: // // static uInt pp = Aipsrc::registerRC("printer.ps.page", "noSet"); // String printerPage = Aipsrc::get(pp); // // Processing, and maybe somewhere else: // Aipsrc::set(pp, "nowSet"); // // ... // printerPage = Aipsrc::get(pp); // // and save it to the $HOME/.aipsrc list // Aipsrc::save(pp); // //
    // // // Programs need a way to interact with the aipsrc files. // // // //
  • AipsError if the environment variables HOME and/or AIPSPATH not set. // // // // class Aipsrc { public: //# Constructors //# Destructor //# Copy assignment //# Member functions // //
  • AipsError if HOME environment variable not set // // The find() functions will, given a keyword, return the value // with a matched keyword found in the files. If no match found the // function will be False. The findNoHome() emulates the -i // switch of getrc by bypassing the ~/.aipsrc file. // static Bool find(String &value, const String &keyword); static Bool findNoHome(String &value, const String &keyword); // // These finds check a (possible) value of the keyword against a list // of coded values provided, and return an index into the list (N if not // found). Matching is minimax, case insensitive. Always better to use // the one with default. return is False if no keyword or no match. // static Bool find(uInt &value, const String &keyword, Int Nname, const String tname[]); static Bool find(uInt &value, const String &keyword, const Vector &tname); // // This find usually saves you some lines of code, since you can supply the // default you want to use when no such keyword is defined. // If the return value is False, the keyword was not found and the default // was used. // static Bool find(String &value, const String &keyword, const String &deflt); static Bool findNoHome(String &value, const String &keyword, const String &deflt); static Bool find(uInt &value, const String &keyword, Int Nname, const String tname[], const String &deflt); static Bool find(uInt &value, const String &keyword, const Vector &tname, const String &deflt); // // Sets foundDir to the first /firstPart/lastPart path that it finds // present on the system, where /firstPart comes from, in order, // this list: // contents of prepends // + useStd ? (., aipsHome(), aipsRoot()) : () // + contents of appends static Bool findDir(String& foundDir, const String& lastPart="", const Vector& prepends=Vector(), const Vector& appends=Vector(), Bool useStds=True); // Functions to register keywords for later use in get() and set(). The // returned value is the index for get() and set(). // static uInt registerRC(const String &keyword, const String &deflt); static uInt registerRC(const String &keyword, Int Nname, const String tname[], const String &deflt); static uInt registerRC(const String &keyword, const Vector &tname, const String &deflt); // // Gets are like find, but using registered integers rather than names. // static const String &get(uInt keyword); // get for code static const uInt &get(uInt &code, uInt keyword); // // Sets allow registered values to be set // static void set(uInt keyword, const String &deflt); static void set(uInt keyword, Int Nname, const String tname[], const String &deflt); static void set(uInt keyword, const Vector &tname, const String &deflt); // // Save a registered keyword value to $HOME/.aipsrc // static void save(uInt keyword); static void save(uInt keyword, const String tname[]); static void save(uInt keyword, const Vector &tname); // // Set an AIPSPATH that should be used in stead of a global AIPSPATH. // This call should be made before any Aipsrc related call. The AIPSPATH // will have up to 4 fields (which can all be empty) giving the root, host, // site and arch directory that will be searched for possible // [.]aipsrc files. static void setAipsPath(const String &path = String()); // Returns the appropriate Casacore or system variable values // static const String &aipsRoot(); static const String &aipsArch(); static const String &aipsSite(); static const String &aipsHost(); // Returns: ~/aips++ static const String &aipsHome(); // // The reRead() function will reinitialise the static maps and read // the aipsrc files again. It could be useful in some interactive circumstances. // Note: Calling reRead() while using the static maps is not (thread-)safe. // (Getting it right is a lot of work, but why apply settings while processing?) // Note: casa_measures MeasTable.cc reads its iau2000_reg and // iau2000a_reg upon first uses. Those cached values are not re-read, // but only influence what useIAU2000() and useIAU2000A() return. // // lastRead() returns the time last reRead. // static void reRead(); static Double lastRead(); // // The following functions return the full lists of available data. They could // be useful for debugging purposes. // static const Block &values(); static const Block &patterns(); // // The following show() function, useful for debugging, outputs // all keyword/value pairs found static void show(ostream &oStream); // Prints all info on cout static void show(); // The following set is a general set of functions // // Read aipsrc type files (without wildcards), and return the unique names // and values in the Vector arguments. The return value is number of names. static uInt genRestore(Vector &namlst, Vector &vallst, const String &fileList); // Save the names/values in file static void genSave(Vector &namlst, Vector &vallst, const String &fnam); // Set (new or overwrite) keyword/value pair static void genSet(Vector &namlst, Vector &vallst, const String &nam, const String &val); // Remove a keyword from list (False if not in list) static Bool genUnSet(Vector &namlst, Vector &vallst, const String &nam); // Get the value of a keyword static Bool genGet(String &val, Vector &namlst, Vector &vallst, const String &nam); // protected: // Actual find function static Bool find(String &value, const String &keyword, uInt start); // Actual find function to use during parse() without recursing into parse() static Bool findNoParse(String &value, const String &keyword, uInt start); // The registration function static uInt registerRC(const String &keyword, Block &nlst); // Actual saving static void save(const String keyword, const String val); private: //# Data // Object to ensure safe multi-threaded lazy single initialization static std::once_flag theirCallOnceFlag; // Last time data was (re)read static Double lastParse; // List of values belonging to keywords found static Block keywordValue; // List of patterns deducted from names static Block keywordPattern; // The start of the non-home values static uInt fileEnd; // The possibly set external AIPSPATH static String extAipsPath; // AIPSROOT static String root; // AIPSARCH static String arch; // AIPSSITE static String site; // AIPSHOST static String host; // AIPSHOME static String home; // HOME static String uhome; // Indicate above filled static Bool filled; // String register list // static Block strlst; static Block nstrlst; static Block codlst; static Block ncodlst; // //# General member functions // Read in the aipsrc files. Always called using theirCallOnce (except for reRead()). // static void parse(); static void doParse(String &fileList); // // The following parse function can be used for any list of files. It will // return the list of Patterns and values found, and the last keyword number // of first file in list. static uInt genParse(Block &keywordPattern, Block &keywordValue, uInt &fileEnd, const String &fileList); // Locate the right keyword in the static maps static Bool matchKeyword(uInt &where, const String &keyword, uInt start); // Fill in root, arch, site, host and home static void fillAips(); }; } //# NAMESPACE CASACORE - END #endif