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