blob: 5a07b1a73740fa8232ac599ee867c0490fffb499 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#ifndef RTC_BASE_FLAGS_H_
24#define RTC_BASE_FLAGS_H_
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020025
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "rtc_base/checks.h"
27#include "rtc_base/constructormagic.h"
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020028
29namespace rtc {
30
31// Internal use only.
32union 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};
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000067
68
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020069// Each flag can be accessed programmatically via a Flag object.
70class Flag {
71 public:
72 enum Type { BOOL, INT, FLOAT, STRING };
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000073
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020074 // 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 const char* file() const { return file_; }
80 const char* name() const { return name_; }
81 const char* comment() const { return comment_; }
82
83 // Flag type
84 Type type() const { return type_; }
85
86 // Flag variables
87 bool* bool_variable() const {
88 RTC_DCHECK_EQ(BOOL, type_);
89 return &variable_->b;
90 }
91
92 int* int_variable() const {
93 RTC_DCHECK_EQ(INT, type_);
94 return &variable_->i;
95 }
96
97 double* float_variable() const {
98 RTC_DCHECK_EQ(FLOAT, type_);
99 return &variable_->f;
100 }
101
102 const char** string_variable() const {
103 RTC_DCHECK_EQ(STRING, type_);
104 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 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.
188class 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 != nullptr, prints information for all flags defined in file;
196 // otherwise prints information for all flags in all files. The current flag
197 // 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().
250class 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
Henrik Kjellanderc0362762017-06-29 08:03:04 +0200268#endif // SHARED_COMMANDLINEFLAGS_FLAGS_H_