- add third_party src.
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / base / flags.h
1 /*
2  * libjingle
3  * Copyright 2006, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without 
6  * modification, are permitted provided that the following conditions are met:
7  *
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.
15  *
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.
26  */
27
28
29 // Originally comes from shared/commandlineflags/flags.h
30
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.
36 //
37 // The implementation only relies and basic C++ functionality
38 // and needs no special library or STL support.
39
40 #ifndef TALK_BASE_FLAGS_H__
41 #define TALK_BASE_FLAGS_H__
42
43 #include <assert.h>
44
45 #include "talk/base/checks.h"
46 #include "talk/base/common.h"
47
48 // Internal use only.
49 union FlagValue {
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) {
56     FlagValue v;
57     v.b = (b != 0);
58     return v;
59   }
60
61   static FlagValue New_INT(int i) {
62     FlagValue v;
63     v.i = i;
64     return v;
65   }
66
67   static FlagValue New_FLOAT(float f) {
68     FlagValue v;
69     v.f = f;
70     return v;
71   }
72
73   static FlagValue New_STRING(const char* s) {
74     FlagValue v;
75     v.s = s;
76     return v;
77   }
78
79   bool b;
80   int i;
81   double f;
82   const char* s;
83 };
84
85
86 // Each flag can be accessed programmatically via a Flag object.
87 class Flag {
88  public:
89   enum Type { BOOL, INT, FLOAT, STRING };
90
91   // Internal use only.
92   Flag(const char* file, const char* name, const char* comment,
93        Type type, void* variable, FlagValue default_);
94
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_; }
99
100   // Flag type
101   Type type() const  { return type_; }
102
103   // Flag variables
104   bool* bool_variable() const {
105     assert(type_ == BOOL);
106     return &variable_->b;
107   }
108   
109   int* int_variable() const {
110     assert(type_ == INT);
111     return &variable_->i;
112   }
113   
114   double* float_variable() const {
115     assert(type_ == FLOAT);
116     return &variable_->f;
117   }
118   
119   const char** string_variable() const {
120     assert(type_ == STRING);
121     return &variable_->s;
122   }
123
124   // Default values
125   bool bool_default() const {
126     assert(type_ == BOOL);
127     return default_.b;
128   }
129   
130   int int_default() const {
131     assert(type_ == INT);
132     return default_.i;
133   }
134   
135   double float_default() const {
136     assert(type_ == FLOAT);
137     return default_.f;
138   }
139   
140   const char* string_default() const {
141     assert(type_ == STRING);
142     return default_.s;
143   }
144
145   // Resets a flag to its default value
146   void SetToDefault();
147
148   // Iteration support
149   Flag* next() const  { return next_; }
150
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);
154
155  private:
156   const char* file_;
157   const char* name_;
158   const char* comment_;
159
160   Type type_;
161   FlagValue* variable_;
162   FlagValue default_;
163
164   Flag* next_;
165
166   friend class FlagList;  // accesses next_
167 };
168
169
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))
178
179
180 // Internal use only.
181 #define DECLARE_FLAG(c_type, name)              \
182   /* declare the external flag */               \
183   extern c_type FLAG_##name
184
185
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)
195
196
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)
202
203
204 // The global list of all flags.
205 class FlagList {
206  public:
207   FlagList();
208
209   // The NULL-terminated list of all flags. Traverse with Flag::next().
210   static Flag* list()  { return list_; }
211
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);
216
217   // Lookup a flag by name. Returns the matching flag or NULL.
218   static Flag* Lookup(const char* name);
219
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,
227                             bool* is_bool);
228
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
235   // be made.
236   //
237   // The following syntax for flags is accepted (both '-' and '--' are ok):
238   //
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,
244                                      const char** argv,
245                                      bool remove_flags);
246   static inline int SetFlagsFromCommandLine(int* argc,
247                                             char** argv,
248                                             bool remove_flags) {
249     return SetFlagsFromCommandLine(argc, const_cast<const char**>(argv),
250                                    remove_flags);
251   }
252
253   // Registers a new flag. Called during program initialization. Not
254   // thread-safe.
255   static void Register(Flag* flag);
256
257  private:
258   static Flag* list_;
259 };
260
261 #ifdef WIN32
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 {
268  public:
269   WindowsCommandLineArguments();
270   ~WindowsCommandLineArguments();
271
272   int argc() { return argc_; }
273   char **argv() { return argv_; }
274  private:
275   int argc_;
276   char **argv_;
277
278  private:
279   DISALLOW_EVIL_CONSTRUCTORS(WindowsCommandLineArguments);
280 };
281 #endif  // WIN32
282
283
284 #endif  // SHARED_COMMANDLINEFLAGS_FLAGS_H__