3 * Copyright 2006, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 // Originally comes from shared/commandlineflags/flags.h
31 // Flags are defined and declared using DEFINE_xxx and DECLARE_xxx macros,
32 // where xxx is the flag type. Flags are referred to via FLAG_yyy,
33 // where yyy is the flag name. For intialization and iteration of flags,
34 // see the FlagList class. For full programmatic access to any
35 // flag, see the Flag class.
37 // The implementation only relies and basic C++ functionality
38 // and needs no special library or STL support.
40 #ifndef TALK_BASE_FLAGS_H__
41 #define TALK_BASE_FLAGS_H__
45 #include "talk/base/checks.h"
46 #include "talk/base/common.h"
50 // Note: Because in C++ non-bool values are silently converted into
51 // bool values ('bool b = "false";' results in b == true!), we pass
52 // and int argument to New_BOOL as this appears to be safer - sigh.
53 // In particular, it prevents the (not uncommon!) bug where a bool
54 // flag is defined via: DEFINE_bool(flag, "false", "some comment");.
55 static FlagValue New_BOOL(int b) {
61 static FlagValue New_INT(int i) {
67 static FlagValue New_FLOAT(float f) {
73 static FlagValue New_STRING(const char* s) {
86 // Each flag can be accessed programmatically via a Flag object.
89 enum Type { BOOL, INT, FLOAT, STRING };
92 Flag(const char* file, const char* name, const char* comment,
93 Type type, void* variable, FlagValue default_);
95 // General flag information
96 const char* file() const { return file_; }
97 const char* name() const { return name_; }
98 const char* comment() const { return comment_; }
101 Type type() const { return type_; }
104 bool* bool_variable() const {
105 assert(type_ == BOOL);
106 return &variable_->b;
109 int* int_variable() const {
110 assert(type_ == INT);
111 return &variable_->i;
114 double* float_variable() const {
115 assert(type_ == FLOAT);
116 return &variable_->f;
119 const char** string_variable() const {
120 assert(type_ == STRING);
121 return &variable_->s;
125 bool bool_default() const {
126 assert(type_ == BOOL);
130 int int_default() const {
131 assert(type_ == INT);
135 double float_default() const {
136 assert(type_ == FLOAT);
140 const char* string_default() const {
141 assert(type_ == STRING);
145 // Resets a flag to its default value
149 Flag* next() const { return next_; }
151 // Prints flag information. The current flag value is only printed
152 // if print_current_value is set.
153 void Print(bool print_current_value);
158 const char* comment_;
161 FlagValue* variable_;
166 friend class FlagList; // accesses next_
170 // Internal use only.
171 #define DEFINE_FLAG(type, c_type, name, default, comment) \
172 /* define and initialize the flag */ \
173 c_type FLAG_##name = (default); \
174 /* register the flag */ \
175 static Flag Flag_##name(__FILE__, #name, (comment), \
176 Flag::type, &FLAG_##name, \
177 FlagValue::New_##type(default))
180 // Internal use only.
181 #define DECLARE_FLAG(c_type, name) \
182 /* declare the external flag */ \
183 extern c_type FLAG_##name
186 // Use the following macros to define a new flag:
187 #define DEFINE_bool(name, default, comment) \
188 DEFINE_FLAG(BOOL, bool, name, default, comment)
189 #define DEFINE_int(name, default, comment) \
190 DEFINE_FLAG(INT, int, name, default, comment)
191 #define DEFINE_float(name, default, comment) \
192 DEFINE_FLAG(FLOAT, double, name, default, comment)
193 #define DEFINE_string(name, default, comment) \
194 DEFINE_FLAG(STRING, const char*, name, default, comment)
197 // Use the following macros to declare a flag defined elsewhere:
198 #define DECLARE_bool(name) DECLARE_FLAG(bool, name)
199 #define DECLARE_int(name) DECLARE_FLAG(int, name)
200 #define DECLARE_float(name) DECLARE_FLAG(double, name)
201 #define DECLARE_string(name) DECLARE_FLAG(const char*, name)
204 // The global list of all flags.
209 // The NULL-terminated list of all flags. Traverse with Flag::next().
210 static Flag* list() { return list_; }
212 // If file != NULL, prints information for all flags defined in file;
213 // otherwise prints information for all flags in all files. The current
214 // flag value is only printed if print_current_value is set.
215 static void Print(const char* file, bool print_current_value);
217 // Lookup a flag by name. Returns the matching flag or NULL.
218 static Flag* Lookup(const char* name);
220 // Helper function to parse flags: Takes an argument arg and splits it into
221 // a flag name and flag value (or NULL if they are missing). is_bool is set
222 // if the arg started with "-no" or "--no". The buffer may be used to NUL-
223 // terminate the name, it must be large enough to hold any possible name.
224 static void SplitArgument(const char* arg,
225 char* buffer, int buffer_size,
226 const char** name, const char** value,
229 // Set the flag values by parsing the command line. If remove_flags
230 // is set, the flags and associated values are removed from (argc,
231 // argv). Returns 0 if no error occurred. Otherwise, returns the
232 // argv index > 0 for the argument where an error occurred. In that
233 // case, (argc, argv) will remain unchanged indepdendent of the
234 // remove_flags value, and no assumptions about flag settings should
237 // The following syntax for flags is accepted (both '-' and '--' are ok):
239 // --flag (bool flags only)
240 // --noflag (bool flags only)
241 // --flag=value (non-bool flags only, no spaces around '=')
242 // --flag value (non-bool flags only)
243 static int SetFlagsFromCommandLine(int* argc,
246 static inline int SetFlagsFromCommandLine(int* argc,
249 return SetFlagsFromCommandLine(argc, const_cast<const char**>(argv),
253 // Registers a new flag. Called during program initialization. Not
255 static void Register(Flag* flag);
262 // A helper class to translate Windows command line arguments into UTF8,
263 // which then allows us to just pass them to the flags system.
264 // This encapsulates all the work of getting the command line and translating
265 // it to an array of 8-bit strings; all you have to do is create one of these,
266 // and then call argc() and argv().
267 class WindowsCommandLineArguments {
269 WindowsCommandLineArguments();
270 ~WindowsCommandLineArguments();
272 int argc() { return argc_; }
273 char **argv() { return argv_; }
279 DISALLOW_EVIL_CONSTRUCTORS(WindowsCommandLineArguments);
284 #endif // SHARED_COMMANDLINEFLAGS_FLAGS_H__