 28e2075280
			
		
	
	28e2075280
	
	
	
		
			
			trunk/talk git-svn-id: http://webrtc.googlecode.com/svn/trunk@4318 4adac7df-926f-26a2-2b94-8c16560cd09d
		
			
				
	
	
		
			285 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			285 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * libjingle
 | |
|  * Copyright 2006, Google Inc.
 | |
|  *
 | |
|  * Redistribution and use in source and binary forms, with or without 
 | |
|  * modification, are permitted provided that the following conditions are met:
 | |
|  *
 | |
|  *  1. Redistributions of source code must retain the above copyright notice, 
 | |
|  *     this list of conditions and the following disclaimer.
 | |
|  *  2. Redistributions in binary form must reproduce the above copyright notice,
 | |
|  *     this list of conditions and the following disclaimer in the documentation
 | |
|  *     and/or other materials provided with the distribution.
 | |
|  *  3. The name of the author may not be used to endorse or promote products 
 | |
|  *     derived from this software without specific prior written permission.
 | |
|  *
 | |
|  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 | |
|  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
 | |
|  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 | |
|  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 | |
|  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | |
|  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 | |
|  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 | |
|  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 | |
|  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 | |
|  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
|  */
 | |
| 
 | |
| 
 | |
| // Originally comes from shared/commandlineflags/flags.h
 | |
| 
 | |
| // Flags are defined and declared using DEFINE_xxx and DECLARE_xxx macros,
 | |
| // where xxx is the flag type. Flags are referred to via FLAG_yyy,
 | |
| // where yyy is the flag name. For intialization and iteration of flags,
 | |
| // see the FlagList class. For full programmatic access to any
 | |
| // flag, see the Flag class.
 | |
| //
 | |
| // The implementation only relies and basic C++ functionality
 | |
| // and needs no special library or STL support.
 | |
| 
 | |
| #ifndef TALK_BASE_FLAGS_H__
 | |
| #define TALK_BASE_FLAGS_H__
 | |
| 
 | |
| #include <assert.h>
 | |
| 
 | |
| #include "talk/base/checks.h"
 | |
| #include "talk/base/common.h"
 | |
| 
 | |
| // Internal use only.
 | |
| union FlagValue {
 | |
|   // Note: Because in C++ non-bool values are silently converted into
 | |
|   // bool values ('bool b = "false";' results in b == true!), we pass
 | |
|   // and int argument to New_BOOL as this appears to be safer - sigh.
 | |
|   // In particular, it prevents the (not uncommon!) bug where a bool
 | |
|   // flag is defined via: DEFINE_bool(flag, "false", "some comment");.
 | |
|   static FlagValue New_BOOL(int b) {
 | |
|     FlagValue v;
 | |
|     v.b = (b != 0);
 | |
|     return v;
 | |
|   }
 | |
| 
 | |
|   static FlagValue New_INT(int i) {
 | |
|     FlagValue v;
 | |
|     v.i = i;
 | |
|     return v;
 | |
|   }
 | |
| 
 | |
|   static FlagValue New_FLOAT(float f) {
 | |
|     FlagValue v;
 | |
|     v.f = f;
 | |
|     return v;
 | |
|   }
 | |
| 
 | |
|   static FlagValue New_STRING(const char* s) {
 | |
|     FlagValue v;
 | |
|     v.s = s;
 | |
|     return v;
 | |
|   }
 | |
| 
 | |
|   bool b;
 | |
|   int i;
 | |
|   double f;
 | |
|   const char* s;
 | |
| };
 | |
| 
 | |
| 
 | |
| // Each flag can be accessed programmatically via a Flag object.
 | |
| class Flag {
 | |
|  public:
 | |
|   enum Type { BOOL, INT, FLOAT, STRING };
 | |
| 
 | |
|   // Internal use only.
 | |
|   Flag(const char* file, const char* name, const char* comment,
 | |
|        Type type, void* variable, FlagValue default_);
 | |
| 
 | |
|   // General flag information
 | |
|   const char* file() const  { return file_; }
 | |
|   const char* name() const  { return name_; }
 | |
|   const char* comment() const  { return comment_; }
 | |
| 
 | |
|   // Flag type
 | |
|   Type type() const  { return type_; }
 | |
| 
 | |
|   // Flag variables
 | |
|   bool* bool_variable() const {
 | |
|     assert(type_ == BOOL);
 | |
|     return &variable_->b;
 | |
|   }
 | |
|   
 | |
|   int* int_variable() const {
 | |
|     assert(type_ == INT);
 | |
|     return &variable_->i;
 | |
|   }
 | |
|   
 | |
|   double* float_variable() const {
 | |
|     assert(type_ == FLOAT);
 | |
|     return &variable_->f;
 | |
|   }
 | |
|   
 | |
|   const char** string_variable() const {
 | |
|     assert(type_ == STRING);
 | |
|     return &variable_->s;
 | |
|   }
 | |
| 
 | |
|   // Default values
 | |
|   bool bool_default() const {
 | |
|     assert(type_ == BOOL);
 | |
|     return default_.b;
 | |
|   }
 | |
|   
 | |
|   int int_default() const {
 | |
|     assert(type_ == INT);
 | |
|     return default_.i;
 | |
|   }
 | |
|   
 | |
|   double float_default() const {
 | |
|     assert(type_ == FLOAT);
 | |
|     return default_.f;
 | |
|   }
 | |
|   
 | |
|   const char* string_default() const {
 | |
|     assert(type_ == STRING);
 | |
|     return default_.s;
 | |
|   }
 | |
| 
 | |
|   // Resets a flag to its default value
 | |
|   void SetToDefault();
 | |
| 
 | |
|   // Iteration support
 | |
|   Flag* next() const  { return next_; }
 | |
| 
 | |
|   // Prints flag information. The current flag value is only printed
 | |
|   // if print_current_value is set.
 | |
|   void Print(bool print_current_value);
 | |
| 
 | |
|  private:
 | |
|   const char* file_;
 | |
|   const char* name_;
 | |
|   const char* comment_;
 | |
| 
 | |
|   Type type_;
 | |
|   FlagValue* variable_;
 | |
|   FlagValue default_;
 | |
| 
 | |
|   Flag* next_;
 | |
| 
 | |
|   friend class FlagList;  // accesses next_
 | |
| };
 | |
| 
 | |
| 
 | |
| // Internal use only.
 | |
| #define DEFINE_FLAG(type, c_type, name, default, comment) \
 | |
|   /* define and initialize the flag */                    \
 | |
|   c_type FLAG_##name = (default);                         \
 | |
|   /* register the flag */                                 \
 | |
|   static Flag Flag_##name(__FILE__, #name, (comment),   \
 | |
|                           Flag::type, &FLAG_##name,       \
 | |
|                           FlagValue::New_##type(default))
 | |
| 
 | |
| 
 | |
| // Internal use only.
 | |
| #define DECLARE_FLAG(c_type, name)              \
 | |
|   /* declare the external flag */               \
 | |
|   extern c_type FLAG_##name
 | |
| 
 | |
| 
 | |
| // Use the following macros to define a new flag:
 | |
| #define DEFINE_bool(name, default, comment) \
 | |
|   DEFINE_FLAG(BOOL, bool, name, default, comment)
 | |
| #define DEFINE_int(name, default, comment) \
 | |
|   DEFINE_FLAG(INT, int, name, default, comment)
 | |
| #define DEFINE_float(name, default, comment) \
 | |
|   DEFINE_FLAG(FLOAT, double, name, default, comment)
 | |
| #define DEFINE_string(name, default, comment) \
 | |
|   DEFINE_FLAG(STRING, const char*, name, default, comment)
 | |
| 
 | |
| 
 | |
| // Use the following macros to declare a flag defined elsewhere:
 | |
| #define DECLARE_bool(name)  DECLARE_FLAG(bool, name)
 | |
| #define DECLARE_int(name)  DECLARE_FLAG(int, name)
 | |
| #define DECLARE_float(name)  DECLARE_FLAG(double, name)
 | |
| #define DECLARE_string(name)  DECLARE_FLAG(const char*, name)
 | |
| 
 | |
| 
 | |
| // The global list of all flags.
 | |
| class FlagList {
 | |
|  public:
 | |
|   FlagList();
 | |
| 
 | |
|   // The NULL-terminated list of all flags. Traverse with Flag::next().
 | |
|   static Flag* list()  { return list_; }
 | |
| 
 | |
|   // If file != NULL, prints information for all flags defined in file;
 | |
|   // otherwise prints information for all flags in all files. The current
 | |
|   // flag value is only printed if print_current_value is set.
 | |
|   static void Print(const char* file, bool print_current_value);
 | |
| 
 | |
|   // Lookup a flag by name. Returns the matching flag or NULL.
 | |
|   static Flag* Lookup(const char* name);
 | |
| 
 | |
|   // Helper function to parse flags: Takes an argument arg and splits it into
 | |
|   // a flag name and flag value (or NULL if they are missing). is_bool is set
 | |
|   // if the arg started with "-no" or "--no". The buffer may be used to NUL-
 | |
|   // terminate the name, it must be large enough to hold any possible name.
 | |
|   static void SplitArgument(const char* arg,
 | |
|                             char* buffer, int buffer_size,
 | |
|                             const char** name, const char** value,
 | |
|                             bool* is_bool);
 | |
| 
 | |
|   // Set the flag values by parsing the command line. If remove_flags
 | |
|   // is set, the flags and associated values are removed from (argc,
 | |
|   // argv). Returns 0 if no error occurred. Otherwise, returns the
 | |
|   // argv index > 0 for the argument where an error occurred. In that
 | |
|   // case, (argc, argv) will remain unchanged indepdendent of the
 | |
|   // remove_flags value, and no assumptions about flag settings should
 | |
|   // be made.
 | |
|   //
 | |
|   // The following syntax for flags is accepted (both '-' and '--' are ok):
 | |
|   //
 | |
|   //   --flag        (bool flags only)
 | |
|   //   --noflag      (bool flags only)
 | |
|   //   --flag=value  (non-bool flags only, no spaces around '=')
 | |
|   //   --flag value  (non-bool flags only)
 | |
|   static int SetFlagsFromCommandLine(int* argc,
 | |
|                                      const char** argv,
 | |
|                                      bool remove_flags);
 | |
|   static inline int SetFlagsFromCommandLine(int* argc,
 | |
|                                             char** argv,
 | |
|                                             bool remove_flags) {
 | |
|     return SetFlagsFromCommandLine(argc, const_cast<const char**>(argv),
 | |
|                                    remove_flags);
 | |
|   }
 | |
| 
 | |
|   // Registers a new flag. Called during program initialization. Not
 | |
|   // thread-safe.
 | |
|   static void Register(Flag* flag);
 | |
| 
 | |
|  private:
 | |
|   static Flag* list_;
 | |
| };
 | |
| 
 | |
| #ifdef WIN32
 | |
| // A helper class to translate Windows command line arguments into UTF8,
 | |
| // which then allows us to just pass them to the flags system.
 | |
| // This encapsulates all the work of getting the command line and translating
 | |
| // it to an array of 8-bit strings; all you have to do is create one of these,
 | |
| // and then call argc() and argv().
 | |
| class WindowsCommandLineArguments {
 | |
|  public:
 | |
|   WindowsCommandLineArguments();
 | |
|   ~WindowsCommandLineArguments();
 | |
| 
 | |
|   int argc() { return argc_; }
 | |
|   char **argv() { return argv_; }
 | |
|  private:
 | |
|   int argc_;
 | |
|   char **argv_;
 | |
| 
 | |
|  private:
 | |
|   DISALLOW_EVIL_CONSTRUCTORS(WindowsCommandLineArguments);
 | |
| };
 | |
| #endif  // WIN32
 | |
| 
 | |
| 
 | |
| #endif  // SHARED_COMMANDLINEFLAGS_FLAGS_H__
 |