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