Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

VestaConfig.H

Go to the documentation of this file.
00001 // Copyright (C) 2001, Compaq Computer Corporation
00002 // 
00003 // This file is part of Vesta.
00004 // 
00005 // Vesta is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 // 
00010 // Vesta is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with Vesta; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 // Last modified on Mon Jan  3 14:03:38 EST 2005 by ken@xorian.net 
00020 //      modified on Tue Dec 12 13:25:25 PST 2000 by mann 
00021 //      modified on Tue Dec  5 13:45:30 PST 1995 by levin
00022 
00023 // The VestaConfig class provides an interface to the central configuration
00024 // file for a Vesta installation.  The configuration file is stored at
00025 // an installation-specific location; see the comments on the get() method.
00026 //
00027 // The configuration file itself is a text file with the following syntax
00028 //
00029 // config file = line*
00030 // line = ws ( sect | option | comment ) ws new-line
00031 // sect = '[' ws name ws ']' | '[' "include" name ']'
00032 // option = name ws '=' ws value
00033 // comment = ( ';' | "//" ) non-new-line* | <empty>
00034 // name = ( letter | digit | special )+
00035 // value = non-new-line*
00036 // new-line = <ASCII CR> | <ASCII LF>
00037 // non-new-line = <any ASCII character except those for new-line>
00038 // ws = <space> | <tab>
00039 //
00040 // This syntax is slightly ambiguous, but the intent should be clear.
00041 // The file is a sequence of lines, each of which is either a section name
00042 // in square brackets, a <name,value> pair separated by an equal sign, or
00043 // a comment.  Leading and trailing white space is ignored, as are blank
00044 // lines and comment lines.  A comment line has a semicolon or two slashes
00045 // as its first non-whitespace characters.
00046 //
00047 // The configuration file defines a two-level naming structure, with
00048 // sections as the upper level and the names of <name, value> pairs as the
00049 // lower level.  Once the file has been parsed, the basic operation is
00050 // to lookup a <section, name> pair, obtaining the associated value.
00051 //
00052 // There is a limited facility for one configuration file to refer to
00053 // another one.  Notice the second alternative for the 'sect' nonterminal
00054 // in the grammar above.  When this form is used, it doesn't introduce
00055 // a section name; instead, the specified file is read and processed instead.
00056 // That is, if the file contains a line of the form:
00057 //     [include /proj/vesta/pkg/config-file/vesta.cfg]
00058 // then the line will effectively be replaced by the contents of the file
00059 // /proj/vesta/pkg/config-file/vesta.cfg
00060 //
00061 // This mechanism is chiefly intended for overriding a set of shared
00062 // defaults.  A configuration file containing standard definitions is
00063 // stored in a public location (e.g., /etc/vesta.cfg; or at SRC,
00064 // /udir/vestasrv/misc/vesta.cfg).  A second configuration file is stored
00065 // in the user's home directory or at the location specified by the
00066 // environment variable VESTACONFIG.  This second file begins with an
00067 // "include" line that mentions the first file, then continues with
00068 // additional sections that either add to or override the standard
00069 // definitions.  Thus, it is not an error for a <section, name> pair to
00070 // appear more than once in the course of configuration file processing
00071 // (which may involve reading multiple files).  The last-encountered value
00072 // wins.
00073 
00074 #ifndef _VestaConfig_H
00075 #define _VestaConfig_H
00076 
00077 #include <Basics.H>
00078 #include <Generics.H>
00079 
00080 namespace VestaConfig {
00081 
00082   struct failure {
00083     Text msg;
00084     inline failure(const Text &msg) { this->msg = msg; };
00085     inline failure(const failure &f) { this->msg = f.msg; };
00086     inline failure& operator=(const failure &f) {
00087       this->msg = f.msg; return *this; };
00088   };
00089 
00090   //  *********************************
00091   //  *  Configuration file location  *
00092   //  *********************************
00093 
00094   void set_location(const Text &file_name);
00095   // 'file_name' specifies the location of the configuration file.  This
00096   // file's contents are used by subsequent calls of 'get' (see below).
00097 
00098   Text get_location() throw(failure);
00099   // Returns the location of the configuration file.  The location is
00100   // is determined as described under 'get', below.
00101 
00102 
00103   //  ********************************************
00104   //  *  Reading fields from configuration file  *
00105   //  ********************************************
00106 
00107   bool get(const Text &section, const Text &name, Text &value)
00108     throw(failure);
00109   // The configuration file is examined for a section whose name is 'section'.
00110   // If such a section is found and it contains a <name, value> pair whose
00111   // name matches the 'name' argument, then the value is stored in the
00112   // 'value' argument and this function returns true.  If no matching
00113   // section and name can be found, the function leaves 'value' unchanged
00114   // and returns false.  If the configuration file cannot be
00115   // successfully read and parsed, 'failure' is thrown.
00116   //
00117   // The location of the configuration file is determined as follows:
00118   //    1.  If 'set_location' was previously called, the path it
00119   //        specified is used.  If the specified file can't be read,
00120   //        'failure' is thrown.
00121   //    2.  If 'set_location' was not previously invoked, the value of
00122   //        the environment variable VESTACONFIG is used.  If the
00123   //        specified file can't be found, 'failure' is thrown.
00124   //    3.  If VESTACONFIG isn't defined, the environment variable
00125   //        HOME is used to define a directory from which 'vesta.cfg'
00126   //        is read.  If it exists, it is read and used for all
00127   //        subsequent calls of 'get', unless 'set_location' is
00128   //        subsequently called.
00129   //    4.  If 'vesta.cfg' is not found in $HOME, /etc/vesta.cfg is
00130   //        tried next.  If it exists, it is read and used for all
00131   //        subsequent calls of 'get', unless 'set_location' is
00132   //        subsequently called.  If it does not exist, 'failure' is
00133   //        thrown. 
00134 
00135   bool is_set(const Text &section, const Text &name)
00136     throw(failure);
00137   // This function is semantically equivalent to:
00138   //    Text value;
00139   //    return get(section, name, value);
00140   // It avoids the need for declaring a dummy variable to call get to
00141   // determine whether a variable is set.
00142 
00143   Text get_Text(const Text &section, const Text &name)
00144     throw(failure);
00145   // This function is semantically equivalent to:
00146   //    Text value;
00147   //    if (get(section, name, value)) return value;
00148   //    throw(failure(<suitable message about [section]name not found>));
00149 
00150   int get_int(const Text &section, const Text &name)
00151     throw(failure);
00152   // This function is semantically equivalent to:
00153   //    istrstream ss(get_Text(section, name).chars());
00154   //    int value;
00155   //    if (ss >> value) return value;
00156   //    throw(failure(<message about [section]name not an integer>));
00157 
00158   bool get_bool(const Text &section, const Text &name)
00159     throw(failure);
00160   // This function inteprets the setting of a configuration variable
00161   // as a boolean.  If it is equal (witout regard to case) to "yes",
00162   // "on", or "true", or can be parsed as an integer that is non-zero,
00163   // it's interpreted as a true value.  If it is equal (witout regard
00164   // to case) to "no", "off", or "false", or can be parsed as an
00165   // integer that is zero, it's interpreted as a false value.
00166   // Otherwise an expetion is thrown.  (Exceptions can also be thrown
00167   // if the value isn't set or if there are parsing errors.)
00168 
00169   float get_float(const Text &section, const Text &name)
00170     throw(failure);
00171   // This function is semantically equivalent to:
00172   //    istrstream ss(get_Text(section, name).chars());
00173   //    float value;
00174   //    if (ss >> value) return value;
00175   //    throw(failure(<message about [section]name not an integer>));
00176 
00177   TextSeq sections()
00178     throw(failure);
00179   // Returns all the sections in the configuration file.  If the
00180   // configuration file cannot be successfully read and parsed,
00181   // 'failure' is thrown.
00182 
00183   TextSeq section_vars(const Text &section)
00184     throw(failure);
00185   // Returns all the names in the given section in the configuration
00186   // file.  If the specified section doesn't exist, the empty sequence
00187   // is returned.  If the configuration file cannot be successfully
00188   // read and parsed, 'failure' is thrown.
00189 
00190 }
00191 
00192 #endif  /* _VestaConfig_H */

Generated on Mon May 8 00:48:37 2006 for Vesta by  doxygen 1.4.2