summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/webrtc/rtc_base/flags.h
blob: 5a07b1a73740fa8232ac599ee867c0490fffb499 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
/*
 *  Copyright 2006 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */


// Originally comes from shared/commandlineflags/flags.h

// Flags are defined and declared using DEFINE_xxx and DECLARE_xxx macros,
// where xxx is the flag type. Flags are referred to via FLAG_yyy,
// where yyy is the flag name. For intialization and iteration of flags,
// see the FlagList class. For full programmatic access to any
// flag, see the Flag class.
//
// The implementation only relies and basic C++ functionality
// and needs no special library or STL support.

#ifndef RTC_BASE_FLAGS_H_
#define RTC_BASE_FLAGS_H_

#include "rtc_base/checks.h"
#include "rtc_base/constructormagic.h"

namespace rtc {

// Internal use only.
union FlagValue {
  // Note: Because in C++ non-bool values are silently converted into
  // bool values ('bool b = "false";' results in b == true!), we pass
  // and int argument to New_BOOL as this appears to be safer - sigh.
  // In particular, it prevents the (not uncommon!) bug where a bool
  // flag is defined via: DEFINE_bool(flag, "false", "some comment");.
  static FlagValue New_BOOL(int b) {
    FlagValue v;
    v.b = (b != 0);
    return v;
  }

  static FlagValue New_INT(int i) {
    FlagValue v;
    v.i = i;
    return v;
  }

  static FlagValue New_FLOAT(float f) {
    FlagValue v;
    v.f = f;
    return v;
  }

  static FlagValue New_STRING(const char* s) {
    FlagValue v;
    v.s = s;
    return v;
  }

  bool b;
  int i;
  double f;
  const char* s;
};


// Each flag can be accessed programmatically via a Flag object.
class Flag {
 public:
  enum Type { BOOL, INT, FLOAT, STRING };

  // Internal use only.
  Flag(const char* file, const char* name, const char* comment,
       Type type, void* variable, FlagValue default_);

  // General flag information
  const char* file() const  { return file_; }
  const char* name() const  { return name_; }
  const char* comment() const  { return comment_; }

  // Flag type
  Type type() const  { return type_; }

  // Flag variables
  bool* bool_variable() const {
    RTC_DCHECK_EQ(BOOL, type_);
    return &variable_->b;
  }

  int* int_variable() const {
    RTC_DCHECK_EQ(INT, type_);
    return &variable_->i;
  }

  double* float_variable() const {
    RTC_DCHECK_EQ(FLOAT, type_);
    return &variable_->f;
  }

  const char** string_variable() const {
    RTC_DCHECK_EQ(STRING, type_);
    return &variable_->s;
  }

  // Default values
  bool bool_default() const {
    RTC_DCHECK_EQ(BOOL, type_);
    return default_.b;
  }

  int int_default() const {
    RTC_DCHECK_EQ(INT, type_);
    return default_.i;
  }

  double float_default() const {
    RTC_DCHECK_EQ(FLOAT, type_);
    return default_.f;
  }

  const char* string_default() const {
    RTC_DCHECK_EQ(STRING, type_);
    return default_.s;
  }

  // Resets a flag to its default value
  void SetToDefault();

  // Iteration support
  Flag* next() const  { return next_; }

  // Prints flag information. The current flag value is only printed
  // if print_current_value is set.
  void Print(bool print_current_value);

 private:
  const char* file_;
  const char* name_;
  const char* comment_;

  Type type_;
  FlagValue* variable_;
  FlagValue default_;

  Flag* next_;

  friend class FlagList;  // accesses next_
};


// Internal use only.
#define DEFINE_FLAG(type, c_type, name, default, comment) \
  /* define and initialize the flag */                    \
  c_type FLAG_##name = (default);                         \
  /* register the flag */                                 \
  static rtc::Flag Flag_##name(__FILE__, #name, (comment),      \
                               rtc::Flag::type, &FLAG_##name,   \
                               rtc::FlagValue::New_##type(default))


// Internal use only.
#define DECLARE_FLAG(c_type, name)              \
  /* declare the external flag */               \
  extern c_type FLAG_##name


// Use the following macros to define a new flag:
#define DEFINE_bool(name, default, comment) \
  DEFINE_FLAG(BOOL, bool, name, default, comment)
#define DEFINE_int(name, default, comment) \
  DEFINE_FLAG(INT, int, name, default, comment)
#define DEFINE_float(name, default, comment) \
  DEFINE_FLAG(FLOAT, double, name, default, comment)
#define DEFINE_string(name, default, comment) \
  DEFINE_FLAG(STRING, const char*, name, default, comment)


// Use the following macros to declare a flag defined elsewhere:
#define DECLARE_bool(name)  DECLARE_FLAG(bool, name)
#define DECLARE_int(name)  DECLARE_FLAG(int, name)
#define DECLARE_float(name)  DECLARE_FLAG(double, name)
#define DECLARE_string(name)  DECLARE_FLAG(const char*, name)


// The global list of all flags.
class FlagList {
 public:
  FlagList();

  // The null-terminated list of all flags. Traverse with Flag::next().
  static Flag* list()  { return list_; }

  // If file != nullptr, prints information for all flags defined in file;
  // otherwise prints information for all flags in all files. The current flag
  // value is only printed if print_current_value is set.
  static void Print(const char* file, bool print_current_value);

  // Lookup a flag by name. Returns the matching flag or null.
  static Flag* Lookup(const char* name);

  // Helper function to parse flags: Takes an argument arg and splits it into
  // a flag name and flag value (or null if they are missing). is_bool is set
  // if the arg started with "-no" or "--no". The buffer may be used to NUL-
  // terminate the name, it must be large enough to hold any possible name.
  static void SplitArgument(const char* arg,
                            char* buffer, int buffer_size,
                            const char** name, const char** value,
                            bool* is_bool);

  // Set the flag values by parsing the command line. If remove_flags
  // is set, the flags and associated values are removed from (argc,
  // argv). Returns 0 if no error occurred. Otherwise, returns the
  // argv index > 0 for the argument where an error occurred. In that
  // case, (argc, argv) will remain unchanged indepdendent of the
  // remove_flags value, and no assumptions about flag settings should
  // be made.
  //
  // The following syntax for flags is accepted (both '-' and '--' are ok):
  //
  //   --flag        (bool flags only)
  //   --noflag      (bool flags only)
  //   --flag=value  (non-bool flags only, no spaces around '=')
  //   --flag value  (non-bool flags only)
  static int SetFlagsFromCommandLine(int* argc,
                                     const char** argv,
                                     bool remove_flags);
  static inline int SetFlagsFromCommandLine(int* argc,
                                            char** argv,
                                            bool remove_flags) {
    return SetFlagsFromCommandLine(argc, const_cast<const char**>(argv),
                                   remove_flags);
  }

  // Registers a new flag. Called during program initialization. Not
  // thread-safe.
  static void Register(Flag* flag);

 private:
  static Flag* list_;
};

#if defined(WEBRTC_WIN)
// A helper class to translate Windows command line arguments into UTF8,
// which then allows us to just pass them to the flags system.
// This encapsulates all the work of getting the command line and translating
// it to an array of 8-bit strings; all you have to do is create one of these,
// and then call argc() and argv().
class WindowsCommandLineArguments {
 public:
  WindowsCommandLineArguments();
  ~WindowsCommandLineArguments();

  int argc() { return argc_; }
  char **argv() { return argv_; }
 private:
  int argc_;
  char **argv_;

 private:
  RTC_DISALLOW_COPY_AND_ASSIGN(WindowsCommandLineArguments);
};
#endif  // WEBRTC_WIN

}  // namespace rtc

#endif  // SHARED_COMMANDLINEFLAGS_FLAGS_H_