| /* | 
 |  *  Copyright 2006 The WebRTC Project Authors. All rights reserved. | 
 |  * | 
 |  *  Use of this source code is governed by a BSD-style license | 
 |  *  that can be found in the LICENSE file in the root of the source | 
 |  *  tree. An additional intellectual property rights grant can be found | 
 |  *  in the file PATENTS.  All contributing project authors may | 
 |  *  be found in the AUTHORS file in the root of the source tree. | 
 |  */ | 
 |  | 
 |  | 
 | // 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 RTC_BASE_FLAGS_H_ | 
 | #define RTC_BASE_FLAGS_H_ | 
 |  | 
 | #include "rtc_base/checks.h" | 
 | #include "rtc_base/constructormagic.h" | 
 |  | 
 | namespace rtc { | 
 |  | 
 | // 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 { | 
 |     RTC_DCHECK_EQ(BOOL, type_); | 
 |     return &variable_->b; | 
 |   } | 
 |  | 
 |   int* int_variable() const { | 
 |     RTC_DCHECK_EQ(INT, type_); | 
 |     return &variable_->i; | 
 |   } | 
 |  | 
 |   double* float_variable() const { | 
 |     RTC_DCHECK_EQ(FLOAT, type_); | 
 |     return &variable_->f; | 
 |   } | 
 |  | 
 |   const char** string_variable() const { | 
 |     RTC_DCHECK_EQ(STRING, type_); | 
 |     return &variable_->s; | 
 |   } | 
 |  | 
 |   // Default values | 
 |   bool bool_default() const { | 
 |     RTC_DCHECK_EQ(BOOL, type_); | 
 |     return default_.b; | 
 |   } | 
 |  | 
 |   int int_default() const { | 
 |     RTC_DCHECK_EQ(INT, type_); | 
 |     return default_.i; | 
 |   } | 
 |  | 
 |   double float_default() const { | 
 |     RTC_DCHECK_EQ(FLOAT, type_); | 
 |     return default_.f; | 
 |   } | 
 |  | 
 |   const char* string_default() const { | 
 |     RTC_DCHECK_EQ(STRING, type_); | 
 |     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 rtc::Flag Flag_##name(__FILE__, #name, (comment),      \ | 
 |                                rtc::Flag::type, &FLAG_##name,   \ | 
 |                                rtc::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 != nullptr, 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_; | 
 | }; | 
 |  | 
 | #if defined(WEBRTC_WIN) | 
 | // 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: | 
 |   RTC_DISALLOW_COPY_AND_ASSIGN(WindowsCommandLineArguments); | 
 | }; | 
 | #endif  // WEBRTC_WIN | 
 |  | 
 | }  // namespace rtc | 
 |  | 
 | #endif  // SHARED_COMMANDLINEFLAGS_FLAGS_H_ |