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>*/