1 /* 2 * Copyright 2006 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 12 // Originally comes from shared/commandlineflags/flags.h 13 14 // Flags are defined and declared using DEFINE_xxx and DECLARE_xxx macros, 15 // where xxx is the flag type. Flags are referred to via FLAG_yyy, 16 // where yyy is the flag name. For intialization and iteration of flags, 17 // see the FlagList class. For full programmatic access to any 18 // flag, see the Flag class. 19 // 20 // The implementation only relies and basic C++ functionality 21 // and needs no special library or STL support. 22 23 #ifndef WEBRTC_BASE_FLAGS_H__ 24 #define WEBRTC_BASE_FLAGS_H__ 25 26 #include <assert.h> 27 28 #include "webrtc/base/checks.h" 29 #include "webrtc/base/common.h" 30 31 namespace rtc { 32 33 // Internal use only. 34 union FlagValue { 35 // Note: Because in C++ non-bool values are silently converted into 36 // bool values ('bool b = "false";' results in b == true!), we pass 37 // and int argument to New_BOOL as this appears to be safer - sigh. 38 // In particular, it prevents the (not uncommon!) bug where a bool 39 // flag is defined via: DEFINE_bool(flag, "false", "some comment");. New_BOOL(int b)40 static FlagValue New_BOOL(int b) { 41 FlagValue v; 42 v.b = (b != 0); 43 return v; 44 } 45 New_INT(int i)46 static FlagValue New_INT(int i) { 47 FlagValue v; 48 v.i = i; 49 return v; 50 } 51 New_FLOAT(float f)52 static FlagValue New_FLOAT(float f) { 53 FlagValue v; 54 v.f = f; 55 return v; 56 } 57 New_STRING(const char * s)58 static FlagValue New_STRING(const char* s) { 59 FlagValue v; 60 v.s = s; 61 return v; 62 } 63 64 bool b; 65 int i; 66 double f; 67 const char* s; 68 }; 69 70 71 // Each flag can be accessed programmatically via a Flag object. 72 class Flag { 73 public: 74 enum Type { BOOL, INT, FLOAT, STRING }; 75 76 // Internal use only. 77 Flag(const char* file, const char* name, const char* comment, 78 Type type, void* variable, FlagValue default_); 79 80 // General flag information file()81 const char* file() const { return file_; } name()82 const char* name() const { return name_; } comment()83 const char* comment() const { return comment_; } 84 85 // Flag type type()86 Type type() const { return type_; } 87 88 // Flag variables bool_variable()89 bool* bool_variable() const { 90 assert(type_ == BOOL); 91 return &variable_->b; 92 } 93 int_variable()94 int* int_variable() const { 95 assert(type_ == INT); 96 return &variable_->i; 97 } 98 float_variable()99 double* float_variable() const { 100 assert(type_ == FLOAT); 101 return &variable_->f; 102 } 103 string_variable()104 const char** string_variable() const { 105 assert(type_ == STRING); 106 return &variable_->s; 107 } 108 109 // Default values bool_default()110 bool bool_default() const { 111 assert(type_ == BOOL); 112 return default_.b; 113 } 114 int_default()115 int int_default() const { 116 assert(type_ == INT); 117 return default_.i; 118 } 119 float_default()120 double float_default() const { 121 assert(type_ == FLOAT); 122 return default_.f; 123 } 124 string_default()125 const char* string_default() const { 126 assert(type_ == STRING); 127 return default_.s; 128 } 129 130 // Resets a flag to its default value 131 void SetToDefault(); 132 133 // Iteration support next()134 Flag* next() const { return next_; } 135 136 // Prints flag information. The current flag value is only printed 137 // if print_current_value is set. 138 void Print(bool print_current_value); 139 140 private: 141 const char* file_; 142 const char* name_; 143 const char* comment_; 144 145 Type type_; 146 FlagValue* variable_; 147 FlagValue default_; 148 149 Flag* next_; 150 151 friend class FlagList; // accesses next_ 152 }; 153 154 155 // Internal use only. 156 #define DEFINE_FLAG(type, c_type, name, default, comment) \ 157 /* define and initialize the flag */ \ 158 c_type FLAG_##name = (default); \ 159 /* register the flag */ \ 160 static rtc::Flag Flag_##name(__FILE__, #name, (comment), \ 161 rtc::Flag::type, &FLAG_##name, \ 162 rtc::FlagValue::New_##type(default)) 163 164 165 // Internal use only. 166 #define DECLARE_FLAG(c_type, name) \ 167 /* declare the external flag */ \ 168 extern c_type FLAG_##name 169 170 171 // Use the following macros to define a new flag: 172 #define DEFINE_bool(name, default, comment) \ 173 DEFINE_FLAG(BOOL, bool, name, default, comment) 174 #define DEFINE_int(name, default, comment) \ 175 DEFINE_FLAG(INT, int, name, default, comment) 176 #define DEFINE_float(name, default, comment) \ 177 DEFINE_FLAG(FLOAT, double, name, default, comment) 178 #define DEFINE_string(name, default, comment) \ 179 DEFINE_FLAG(STRING, const char*, name, default, comment) 180 181 182 // Use the following macros to declare a flag defined elsewhere: 183 #define DECLARE_bool(name) DECLARE_FLAG(bool, name) 184 #define DECLARE_int(name) DECLARE_FLAG(int, name) 185 #define DECLARE_float(name) DECLARE_FLAG(double, name) 186 #define DECLARE_string(name) DECLARE_FLAG(const char*, name) 187 188 189 // The global list of all flags. 190 class FlagList { 191 public: 192 FlagList(); 193 194 // The NULL-terminated list of all flags. Traverse with Flag::next(). list()195 static Flag* list() { return list_; } 196 197 // If file != NULL, prints information for all flags defined in file; 198 // otherwise prints information for all flags in all files. The current 199 // flag value is only printed if print_current_value is set. 200 static void Print(const char* file, bool print_current_value); 201 202 // Lookup a flag by name. Returns the matching flag or NULL. 203 static Flag* Lookup(const char* name); 204 205 // Helper function to parse flags: Takes an argument arg and splits it into 206 // a flag name and flag value (or NULL if they are missing). is_bool is set 207 // if the arg started with "-no" or "--no". The buffer may be used to NUL- 208 // terminate the name, it must be large enough to hold any possible name. 209 static void SplitArgument(const char* arg, 210 char* buffer, int buffer_size, 211 const char** name, const char** value, 212 bool* is_bool); 213 214 // Set the flag values by parsing the command line. If remove_flags 215 // is set, the flags and associated values are removed from (argc, 216 // argv). Returns 0 if no error occurred. Otherwise, returns the 217 // argv index > 0 for the argument where an error occurred. In that 218 // case, (argc, argv) will remain unchanged indepdendent of the 219 // remove_flags value, and no assumptions about flag settings should 220 // be made. 221 // 222 // The following syntax for flags is accepted (both '-' and '--' are ok): 223 // 224 // --flag (bool flags only) 225 // --noflag (bool flags only) 226 // --flag=value (non-bool flags only, no spaces around '=') 227 // --flag value (non-bool flags only) 228 static int SetFlagsFromCommandLine(int* argc, 229 const char** argv, 230 bool remove_flags); SetFlagsFromCommandLine(int * argc,char ** argv,bool remove_flags)231 static inline int SetFlagsFromCommandLine(int* argc, 232 char** argv, 233 bool remove_flags) { 234 return SetFlagsFromCommandLine(argc, const_cast<const char**>(argv), 235 remove_flags); 236 } 237 238 // Registers a new flag. Called during program initialization. Not 239 // thread-safe. 240 static void Register(Flag* flag); 241 242 private: 243 static Flag* list_; 244 }; 245 246 #if defined(WEBRTC_WIN) 247 // A helper class to translate Windows command line arguments into UTF8, 248 // which then allows us to just pass them to the flags system. 249 // This encapsulates all the work of getting the command line and translating 250 // it to an array of 8-bit strings; all you have to do is create one of these, 251 // and then call argc() and argv(). 252 class WindowsCommandLineArguments { 253 public: 254 WindowsCommandLineArguments(); 255 ~WindowsCommandLineArguments(); 256 argc()257 int argc() { return argc_; } argv()258 char **argv() { return argv_; } 259 private: 260 int argc_; 261 char **argv_; 262 263 private: 264 DISALLOW_EVIL_CONSTRUCTORS(WindowsCommandLineArguments); 265 }; 266 #endif // WEBRTC_WIN 267 268 } // namespace rtc 269 270 #endif // SHARED_COMMANDLINEFLAGS_FLAGS_H__ 271