option.h

00001 /*<std-header orig-src='shore' incl-file-exclusion='OPTION_H'>
00002 
00003  $Id: option.h,v 1.31 2010/05/26 01:20:12 nhall Exp $
00004 
00005 SHORE -- Scalable Heterogeneous Object REpository
00006 
00007 Copyright (c) 1994-99 Computer Sciences Department, University of
00008                       Wisconsin -- Madison
00009 All Rights Reserved.
00010 
00011 Permission to use, copy, modify and distribute this software and its
00012 documentation is hereby granted, provided that both the copyright
00013 notice and this permission notice appear in all copies of the
00014 software, derivative works or modified versions, and any portions
00015 thereof, and that both notices appear in supporting documentation.
00016 
00017 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY
00018 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS
00019 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND
00020 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
00021 
00022 This software was developed with support by the Advanced Research
00023 Project Agency, ARPA order number 018 (formerly 8230), monitored by
00024 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518.
00025 Further funding for this work was provided by DARPA through
00026 Rome Research Laboratory Contract No. F30602-97-2-0247.
00027 
00028 */
00029 
00030 #ifndef OPTION_H
00031 #define OPTION_H
00032 
00033 #include "w_defines.h"
00034 
00035 /*  -- do not edit anything above this line --   </std-header>*/
00036 
00037 #include <w_stream.h>
00038 
00039 #ifdef __GNUG__
00040 #pragma interface
00041 #endif
00042 
00043 /**\addtogroup OPTIONS 
00044  *
00045  * The storage manager has run-time options. Some of them must be set
00046  * (they do not have defaults), so we provide this run-time options-control
00047  * package that can be used by the server to set the values for options
00048  * (both with and without defaults).
00049  *
00050  * This package makes it easy for values to be set and read 
00051  * in one or more of these ways:
00052  * - on a command line
00053  * - in an input stream
00054  * - in a file with an X-resources-style syntax that includes wildcarding:
00055  *    \e Aclass.Bclass.programname.optionname \b : \e value
00056  * - explicitly in the server code
00057  * - with defaults in the server code.
00058  *
00059  * A server creates is options (required and optional) with
00060  * their default values, and the server then adds the storage
00061  * manager's options to the collected set of "known" options.  
00062  *
00063  * Subsequently, the configuration file(s) may be scanned and 
00064  * the command line by the options-package code to find values for
00065  * any of the known options.
00066  *
00067  * All this is must be done before a storage manager is started up,
00068  * so that the values are available to the storage manager.
00069  * Before starting up the storage manager, the server should also 
00070  * determine if all required options have values, and this package helps
00071  * in that regard as well.
00072  *
00073  * This is all achieved with the following three classes:
00074  * option_t,
00075  * option_group_t, and 
00076  * option_file_scan_t.  
00077  *
00078  * Objects of type option_t contain information about individual options.  
00079  * An option has a string name and an assigned value.  
00080  * It might also have a default value. It is either "required" or "optional".
00081  *
00082  * An option_group_t manages a related group of options.  
00083  * The group has its own "class name", which is a set of appended names.
00084  * This allows hierarchical grouping of options.  (The original SHORE code
00085  * had many more layers and libraries, including client and server components,
00086  * so this was useful. A full-blown RDBMS built on the storage manager might
00087  * also make use of this hierarchical grouping.)
00088  *
00089  * An option_file_scan_t is parses a file containing option name-value
00090  * assignments.
00091  *
00092  * An option_stream_scan_t does the same for an input stream.
00093  *
00094  * The example \ref startstop.cpp shows how 
00095  * options are used in a minimal way.
00096  *
00097  * The example consisting of 
00098  * \ref create_rec.cpp and 
00099  * \ref init_config_options.cpp
00100  * is more complete.
00101 */
00102 
00103 #ifndef __opt_error_def_gen_h__
00104 #include "opt_error_def_gen.h"
00105 #endif
00106 
00107 class option_group_t;
00108 
00109 /**\brief  A single run-time option (e.g., from a .rc file). See \ref OPTIONS.
00110  * \ingroup OPTIONS
00111  *
00112  *\details 
00113  *   Information about an option is stored in a option_t object.
00114  *   All options have:
00115  *   - a string name, 
00116  *   - a description of the purpose of this option,
00117  *   - a string of possible values to print when giving for usage messages,
00118  *   - a Boolean indicating if the user is required to give a value for this,
00119  *   - a Boolean indicating whether this option was given a non-default value
00120  *   - a default value, used if this is not a "required" option.
00121  */
00122 class option_t : public w_base_t {
00123 friend class option_group_t;
00124 public:
00125 
00126     /// Returns true if the option name matches matchName
00127     bool        match(const char* matchName, bool exact=false);
00128 
00129     /**\brief Set the value of an option if it is not already set or if overRide is true.
00130      *
00131      * Error messages will be "printed" to err_stream if 
00132      * the given pointer to err_stream is non-null.
00133      *
00134      * A value of NULL indicates "please un-set the value".
00135     */
00136     w_rc_t        set_value(const char* value, bool overRide, ostream* err_stream);
00137 
00138     /// Get current assigned value.
00139     const char*        value()         { return _value;}
00140     /// Has this option been given a non-default value?
00141     bool        is_set()        { return _set; }
00142     /// Is this option required to be given a non-default value?
00143     bool        is_required()        { return _required; }
00144     /// Return the string name of the option.
00145     const char*        name()                { return _name; }
00146     /// Return a string of the permissible values, for printing usage info.
00147     const char*        possible_values(){ return _possible_values; }        
00148     /// Return a string of the default value.
00149     const char*        default_value()        { return _default_value; }        
00150     /// Return a string describing the meaning of the option.
00151     const char*        description()        { return _description; }        
00152 
00153     w_rc_t        copyValue(const char* value);
00154     // Append to the value.
00155     w_rc_t        concatValue(const char* value);
00156 
00157 
00158     // Standard call back functions for basic types
00159     static w_rc_t set_value_bool(option_t* opt, const char* value, ostream* err_stream);
00160     static w_rc_t set_value_int4(option_t* opt, const char* value, ostream* err_stream);
00161     static w_rc_t set_value_int8(option_t* opt, const char* value, ostream* err_stream);
00162     static w_rc_t set_value_charstr(option_t* opt, const char* value, ostream* err_stream);
00163 
00164     /* Backwards compatability */
00165     static w_rc_t set_value_long(option_t* opt, const char* value, ostream* err_stream);
00166     static w_rc_t set_value_long_long(option_t* opt, const char* value, ostream* err_stream);
00167 
00168     // function to convert a string to a bool (similar to strtol()).
00169     // first character is checked for t,T,y,Y for true
00170     // and f,F,n,N for false.
00171     // bad_str is set to true if none of these match (and 
00172     // false will be returned)
00173     static bool        str_to_bool(const char* str, bool& bad_str);
00174 
00175 private:
00176     // Type for "call back" functions called when a value is set
00177     typedef w_rc_t (*OptionSetFunc)(option_t*, const char * value,
00178                         ostream* err_stream);
00179 
00180     // These functions are called by option_group_t::add_option().
00181     NORET        option_t();
00182     NORET        ~option_t();
00183                     // initialize an option_t object
00184     w_rc_t        init(const char* name, const char* newPoss,
00185                      const char* default_value, const char* description,
00186                      bool required, OptionSetFunc callBack,
00187                      ostream *err_stream);
00188 
00189     const char*        _name;                        // name of the option
00190     const char*        _possible_values;        // example possible values
00191     const char*        _default_value;                // default value
00192     const char*        _description;                // description string
00193     bool        _required;                // must option be set
00194     bool        _set;                        // option has been set
00195     char*        _value;                        // value for the option
00196     w_link_t        _link;                        // link list of options 
00197 
00198     /*
00199      *      call-back function to call when option value is set
00200      *
00201      *      Call back functions should return 0 on success or a on-zero
00202      *      error code on failure.  This error code should not confict
00203      *      with the option error codes above.
00204      */
00205     OptionSetFunc _setFunc;
00206 
00207 };
00208 
00209 /**\brief Group of option_t.  See \ref OPTIONS.
00210  *
00211  * \ingroup OPTIONS
00212  * \details
00213  *   Manages a set of options.  
00214  *
00215  *   An option group has  a classification hierarchy associated with it.  
00216  *   Each level  of the hierarchy is given a string name.  
00217  *   Levels are added with add_class_level().  
00218  *   The levels are used when looking up an option with lookup_by_class().  
00219  *   The level hierarchy is printed  in the form: 
00220  *       "level1.level2.level3."  
00221  *   A complete option name is specified by 
00222  *      "level1.level2.level3.optionName:".  
00223  *   A convention for level names is:
00224  *        programtype.programname
00225  *   where programtype is indicates the general type of the program
00226  *   and programname is the file name of the program.
00227  */
00228 class option_group_t : public w_base_t {
00229 public:
00230     NORET        option_group_t(int max_class_levels);
00231     NORET         ~option_group_t();
00232 
00233     // Add_class_level is used to add a level name.
00234     w_rc_t        add_class_level(const char* name);
00235 
00236     /**\brief Add an option to this group.
00237      *
00238      * @param[in] name   Name of option.
00239      * @param[in] possible_values   String for printing "help" information.
00240      * @param[in] default_value   Default value or NULL.
00241      * @param[in] description   Description of the options's purpose.
00242      * @param[in] required   User must provide a value if "true".
00243      * @param[in] set_func   Callback used during file- or command-line- 
00244      * scanning  to set the option value; this is needed because 
00245      * the options are typed.
00246      * Possible callback functions include several provided here, described below.
00247      * @param[out] new_opt   The option_t created by this method is returned here.
00248      * @param[in] err_stream   Errors encountered during processing will
00249      * cause messages to be sent here.
00250      *
00251      * \details
00252      * Creates an option_t and adds it to this group.
00253      * The set_func parameter indicates what callback function to call
00254      * when the option is set.  Write your own or use one of 
00255      * these functions from option_t: 
00256      * - set_value_bool()
00257      * - set_value_int4()
00258      * - set_value_int8()
00259      * - set_value_charstr()
00260      *
00261      */
00262     w_rc_t        add_option(const char* name, 
00263                        const char* possible_values,
00264                        const char* default_value,
00265                        const char* description, 
00266                        bool required,
00267                        option_t::OptionSetFunc set_func,
00268                        option_t*& new_opt,
00269                        ostream *err_stream = &cerr
00270                        );
00271 
00272     /**\brief Look up an option by name.  
00273      *
00274      * \details
00275      * @param[in] name   Name of option.
00276      * @param[in] exact  name is not an abbreviation.
00277      * @param[out] ret  Populate the given pointer if found.
00278      *
00279      * Abbreviations are allowed if they are sufficient to identify the option
00280      * and exact is false.
00281      */
00282     w_rc_t        lookup(const char* name, bool exact, option_t*&ret);
00283 
00284 
00285     /**\brief Look up option by class name and option name.
00286      * \details
00287      * @param[in] opt_class_name is a string of the form level1.level2.optionname.
00288      * A "?" can be used as a wild card for any single level name.
00289      * A "*" can be used as a wild card for any number of level names.
00290      * @param[out] ret Pass in an option_t* and it will be filled in if found.
00291      * @param[in] exact  opt_class_name is not an abbreviation.
00292      *
00293      * Abbreviations are allowed if they are sufficient to identify the option
00294      * and exact is false.
00295     */
00296     w_rc_t        lookup_by_class(const char* opt_class_name, option_t*&ret,
00297                             bool exact=false);
00298 
00299     /**\brief Set a value of an option identified by a class name and option name.
00300      * \details
00301      * Set the value of an option if it is not already set
00302      * or if overRide is true.
00303      *
00304      * @param[in] name is a string of the form level1.level2.optionname.
00305      * @param[in] exact  name is not an abbreviation.
00306      * @param[in] value is a string form of the value to give the option;
00307      *            a value of NULL indicates un-set.
00308      * @param[in] overRide allows the value to be overwritten.
00309      * @param[in] err_stream: error messages will be sent to err_stream if non-null.
00310      */
00311     w_rc_t        set_value(const char* name, bool exact,
00312                           const char* value, bool overRide,
00313                           ostream* err_stream);
00314 
00315     /// Print the descriptive information to the given stream.
00316     void        print_usage(bool longForm, ostream& err_stream);
00317     /// Print the descriptive information to the given stream.
00318     void        print_values(bool longForm, ostream& err_stream);
00319 
00320     /**\brief Check that all required options are set.
00321      *
00322      * \details
00323      * Return OPTERR_NotSet if any are not.
00324      * Print information about each unset option to err_stream
00325      */
00326     w_rc_t         check_required(ostream* err_stream);
00327 
00328     /**\brief Search the command line for options, set, remove from argv,argc.
00329      * \details
00330      * @param[in] argv The command line to search.
00331      * @param[in] argc Number of entries in argv[].
00332      * @param[in] min_len Don't process argv entries shorter than this.
00333      * @param[out] err_stream Send error message here if non-NULL.
00334      *
00335      * Search the command line (argv[]) for options in this group.
00336      * Command-line options must be preceded by "-" 
00337      * and are recognized only if they are min_len since
00338      * options may be abbreviated.  
00339      * Any options found are removed from argv, 
00340      * and argc is adjusted accordingly.
00341      */
00342     w_rc_t         parse_command_line(const char** argv, 
00343                     int& argc, 
00344                     size_t min_len, 
00345                     ostream* err_stream);
00346 
00347     /// Return a list of the options in the group.
00348     w_list_t<option_t,unsafe_list_dummy_lock_t>& option_list() {return _options;}
00349 
00350     /// Number of levels in the class names.
00351     int                num_class_levels(){ return _numLevels; }        
00352     /// The complete option class name.
00353     const char*        class_name()        { return _class_name; }        
00354 
00355 private:
00356     w_list_t<option_t,unsafe_list_dummy_lock_t>  _options;
00357     char*                _class_name;
00358     // array of offsets into _class_name
00359     char**                 _levelLocation;
00360     int                        _maxLevels;
00361     int                        _numLevels;
00362 
00363     static bool        _error_codes_added;
00364 
00365         // disable copy operator
00366         NORET option_group_t(option_group_t const &); 
00367 };
00368 
00369 /**\brief Enables scanning of options group. See \ref OPTIONS.
00370  *
00371  * \ingroup OPTIONS
00372  * \details
00373  *   
00374  * Given an instream, scan for options in a given option_troup_t
00375  * on that stream.
00376  * This is used by option_file_scan_t.
00377  */
00378 class option_stream_scan_t : public w_base_t {
00379         istream                &_input;
00380         option_group_t        *_optList;
00381         char                  *_line;
00382         const char            *_label;
00383         int                   _lineNum;
00384 
00385         enum { _maxLineLen = 2000 };
00386 
00387         static const char *default_label;
00388 
00389 public:
00390         option_stream_scan_t(istream &is, option_group_t *option_group);
00391         ~option_stream_scan_t();
00392 
00393         // Allow a label to be associated with the stream, e.g., file name.
00394         void        setLabel(const char *label);
00395 
00396         /**\brief Scan all options, report errors to err_stream.
00397          *
00398          * @param[in] over_ride If false, new values of options will be ignored.
00399          *                      If true, assignments to already-set options 
00400          *                      will be made.
00401          * @param[out] err_stream Send error message here if non-NULL.
00402          * @param[in] exact If true, misspellings or abbreviations of
00403          *                      option names in the instream will result
00404          *                      in errors. 
00405          * @param[in] mismatch_ok  If true, bad option names will be ignored
00406          *                      and will not cause failure of the entire scan.
00407          */
00408         w_rc_t         scan(bool over_ride, ostream& err_stream, 
00409                              bool exact=false, bool mismatch_ok=false);
00410 
00411 };
00412 
00413 /**\brief Scan a text file for options. See \ref OPTIONS.
00414  * \ingroup OPTIONS
00415  *
00416  * \details
00417  * 
00418  * Each line of the file is either a comment or an option value setting.
00419  * 
00420  * A comment line begins with "!" or "#".
00421  *
00422  * An option value setting line has the form:
00423  *     level1.level2.optionname: value of option
00424  *
00425  * level1.level2.optionname is anything acceptable to
00426  * option_group_t::lookup_by_class().  The value of the option
00427  * is the string beginning with the first non-white space character
00428  * after the ":" and ending with last non-white space character in
00429  * the line.
00430  */ 
00431 class option_file_scan_t : public w_base_t {
00432 public:
00433     NORET        option_file_scan_t(const char* opt_file_path, option_group_t* opt_group);
00434     NORET        ~option_file_scan_t();
00435 
00436         /**\brief Scan all options, report errors to err_stream.
00437          *
00438          * @param[in] over_ride If false, new values of options will be ignored.
00439          * If true, assignments to already-set options will be made.
00440          * @param[out] err_stream Send error message here if non-NULL.
00441          * @param[in] exact If true, misspellings or abbreviations of
00442          *                      option names in the instream will result
00443          *                      in errors. 
00444          * @param[in] mismatch_ok  If true, bad option names will be ignored
00445          *                      and will not cause failure of the entire scan.
00446          */
00447     w_rc_t         scan(bool over_ride, ostream& err_stream, 
00448         bool exact=false, bool mismatch_ok=false);
00449 
00450 protected:
00451     const char*           _fileName;
00452     option_group_t        *_optList;
00453 };
00454 
00455 /*<std-footer incl-file-exclusion='OPTION_H'>  -- do not edit anything below this line -- */
00456 
00457 #endif          /*</std-footer>*/

Generated on Wed Jul 7 17:22:32 2010 for Shore Storage Manager by  doxygen 1.4.7