1f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch/*
2f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * libjingle
3f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Copyright 2006, Google Inc.
4f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
5f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Redistribution and use in source and binary forms, with or without
6f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * modification, are permitted provided that the following conditions are met:
7f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
8f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  1. Redistributions of source code must retain the above copyright notice,
9f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     this list of conditions and the following disclaimer.
10f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  2. Redistributions in binary form must reproduce the above copyright notice,
11f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     this list of conditions and the following disclaimer in the documentation
12f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     and/or other materials provided with the distribution.
13f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  3. The name of the author may not be used to endorse or promote products
14f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     derived from this software without specific prior written permission.
15f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
16f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch */
27f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
28f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Flags are defined and declared using DEFINE_xxx and DECLARE_xxx macros,
29f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// where xxx is the flag type. Flags are referred to via FLAG_yyy,
30f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// where yyy is the flag name. For intialization and iteration of flags,
31f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// see the FlagList class. For full programmatic access to any
32f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// flag, see the Flag class.
33f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch//
34f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// The implementation only relies and basic C++ functionality
35f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// and needs no special library or STL support.
36f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
37f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifndef TALK_BASE_FLAGS_H__
38f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define TALK_BASE_FLAGS_H__
39f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
40f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <assert.h>
41f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
42f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/checks.h"
43f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/common.h"
44f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
45f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Internal use only.
46f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochunion FlagValue {
47f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Note: Because in C++ non-bool values are silently converted into
48f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // bool values ('bool b = "false";' results in b == true!), we pass
49f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // and int argument to New_BOOL as this appears to be safer - sigh.
50f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // In particular, it prevents the (not uncommon!) bug where a bool
51f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // flag is defined via: DEFINE_bool(flag, "false", "some comment");.
52f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static FlagValue New_BOOL(int b) {
53f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    FlagValue v;
54f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    v.b = (b != 0);
55f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return v;
56f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
57f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
58f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static FlagValue New_INT(int i) {
59f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    FlagValue v;
60f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    v.i = i;
61f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return v;
62f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
63f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
64f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static FlagValue New_FLOAT(float f) {
65f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    FlagValue v;
66f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    v.f = f;
67f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return v;
68f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
69f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
70f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static FlagValue New_STRING(const char* s) {
71f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    FlagValue v;
72f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    v.s = s;
73f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return v;
74f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
75f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
76f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool b;
77f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  int i;
78f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  double f;
79f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  const char* s;
80f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
81f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
82f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
83f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Each flag can be accessed programmatically via a Flag object.
84f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass Flag {
85f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch public:
86f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  enum Type { BOOL, INT, FLOAT, STRING };
87f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
88f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Internal use only.
89f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  Flag(const char* file, const char* name, const char* comment,
90f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch       Type type, void* variable, FlagValue default_);
91f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
92f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // General flag information
93f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  const char* file() const  { return file_; }
94f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  const char* name() const  { return name_; }
95f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  const char* comment() const  { return comment_; }
96f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
97f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Flag type
98f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  Type type() const  { return type_; }
99f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
100f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Flag variables
101f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool* bool_variable() const {
102f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    assert(type_ == BOOL);
103f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return &variable_->b;
104f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
105f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
106f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  int* int_variable() const {
107f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    assert(type_ == INT);
108f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return &variable_->i;
109f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
110f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
111f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  double* float_variable() const {
112f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    assert(type_ == FLOAT);
113f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return &variable_->f;
114f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
115f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
116f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  const char** string_variable() const {
117f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    assert(type_ == STRING);
118f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return &variable_->s;
119f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
120f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
121f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Default values
122f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool bool_default() const {
123f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    assert(type_ == BOOL);
124f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return default_.b;
125f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
126f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
127f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  int int_default() const {
128f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    assert(type_ == INT);
129f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return default_.i;
130f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
131f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
132f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  double float_default() const {
133f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    assert(type_ == FLOAT);
134f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return default_.f;
135f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
136f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
137f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  const char* string_default() const {
138f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    assert(type_ == STRING);
139f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return default_.s;
140f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
141f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
142f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Resets a flag to its default value
143f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  void SetToDefault();
144f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
145f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Iteration support
146f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  Flag* next() const  { return next_; }
147f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
148f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Prints flag information. The current flag value is only printed
149f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // if print_current_value is set.
150f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  void Print(bool print_current_value);
151f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
152f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch private:
153f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  const char* file_;
154f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  const char* name_;
155f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  const char* comment_;
156f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
157f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  Type type_;
158f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  FlagValue* variable_;
159f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  FlagValue default_;
160f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
161f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  Flag* next_;
162f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
163f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  friend class FlagList;  // accesses next_
164f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
165f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
166f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
167f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Internal use only.
168f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define DEFINE_FLAG(type, c_type, name, default, comment) \
169f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  /* define and initialize the flag */                    \
170f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  c_type FLAG_##name = (default);                         \
171f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  /* register the flag */                                 \
172f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static Flag Flag_##name(__FILE__, #name, (comment),   \
173f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                          Flag::type, &FLAG_##name,       \
174f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                          FlagValue::New_##type(default))
175f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
176f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
177f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Internal use only.
178f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define DECLARE_FLAG(c_type, name)              \
179f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  /* declare the external flag */               \
180f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  extern c_type FLAG_##name
181f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
182f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
183f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Use the following macros to define a new flag:
184f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define DEFINE_bool(name, default, comment) \
185f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DEFINE_FLAG(BOOL, bool, name, default, comment)
186f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define DEFINE_int(name, default, comment) \
187f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DEFINE_FLAG(INT, int, name, default, comment)
188f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define DEFINE_float(name, default, comment) \
189f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DEFINE_FLAG(FLOAT, double, name, default, comment)
190f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define DEFINE_string(name, default, comment) \
191f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DEFINE_FLAG(STRING, const char*, name, default, comment)
192f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
193f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
194f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Use the following macros to declare a flag defined elsewhere:
195f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define DECLARE_bool(name)  DECLARE_FLAG(bool, name)
196f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define DECLARE_int(name)  DECLARE_FLAG(int, name)
197f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define DECLARE_float(name)  DECLARE_FLAG(double, name)
198f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#define DECLARE_string(name)  DECLARE_FLAG(const char*, name)
199f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
200f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
201f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// The global list of all flags.
202f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass FlagList {
203f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch public:
204f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  FlagList();
205f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
206f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // The NULL-terminated list of all flags. Traverse with Flag::next().
207f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static Flag* list()  { return list_; }
208f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
209f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // If file != NULL, prints information for all flags defined in file;
210f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // otherwise prints information for all flags in all files. The current
211f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // flag value is only printed if print_current_value is set.
212f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static void Print(const char* file, bool print_current_value);
213f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
214f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Lookup a flag by name. Returns the matching flag or NULL.
215f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static Flag* Lookup(const char* name);
216f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
217f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Helper function to parse flags: Takes an argument arg and splits it into
218f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // a flag name and flag value (or NULL if they are missing). is_bool is set
219f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // if the arg started with "-no" or "--no". The buffer may be used to NUL-
220f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // terminate the name, it must be large enough to hold any possible name.
221f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static void SplitArgument(const char* arg,
222f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                            char* buffer, int buffer_size,
223f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                            const char** name, const char** value,
224f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                            bool* is_bool);
225f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
226f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Set the flag values by parsing the command line. If remove_flags
227f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // is set, the flags and associated values are removed from (argc,
228f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // argv). Returns 0 if no error occurred. Otherwise, returns the
229f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // argv index > 0 for the argument where an error occurred. In that
230f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // case, (argc, argv) will remain unchanged indepdendent of the
231f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // remove_flags value, and no assumptions about flag settings should
232f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // be made.
233f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //
234f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // The following syntax for flags is accepted (both '-' and '--' are ok):
235f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //
236f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //   --flag        (bool flags only)
237f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //   --noflag      (bool flags only)
238f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //   --flag=value  (non-bool flags only, no spaces around '=')
239f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  //   --flag value  (non-bool flags only)
240f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static int SetFlagsFromCommandLine(int* argc,
241f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                                     const char** argv,
242f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                                     bool remove_flags);
243f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static inline int SetFlagsFromCommandLine(int* argc,
244f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                                            char** argv,
245f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                                            bool remove_flags) {
246f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return SetFlagsFromCommandLine(argc, const_cast<const char**>(argv),
247f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                                   remove_flags);
248f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
249f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
250f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Registers a new flag. Called during program initialization. Not
251f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // thread-safe.
252f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static void Register(Flag* flag);
253f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
254f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch private:
255f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static Flag* list_;
256f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
257f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
258f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef WIN32
259f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// A helper class to translate Windows command line arguments into UTF8,
260f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// which then allows us to just pass them to the flags system.
261f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// This encapsulates all the work of getting the command line and translating
262f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// it to an array of 8-bit strings; all you have to do is create one of these,
263f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// and then call argc() and argv().
264f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass WindowsCommandLineArguments {
265f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch public:
266f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  WindowsCommandLineArguments();
267f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ~WindowsCommandLineArguments();
268f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
269f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  int argc() { return argc_; }
270f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  char **argv() { return argv_; }
271f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch private:
272f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  int argc_;
273f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  char **argv_;
274f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
275f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch private:
276f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DISALLOW_EVIL_CONSTRUCTORS(WindowsCommandLineArguments);
277f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
278f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif  // WIN32
279f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
280f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
281f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif  // SHARED_COMMANDLINEFLAGS_FLAGS_H__
282