• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   RTC_DISALLOW_COPY_AND_ASSIGN(WindowsCommandLineArguments);
265 };
266 #endif  // WEBRTC_WIN
267 
268 }  // namespace rtc
269 
270 #endif  // SHARED_COMMANDLINEFLAGS_FLAGS_H__
271