flags.cc revision d0582a6c46733687d045e4188a1bcd0123c758a1
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2008 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include <ctype.h>
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include <stdlib.h>
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h"
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "platform.h"
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "smart-pointer.h"
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "string-stream.h"
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Define all of our flags.
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define FLAG_MODE_DEFINE
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "flag-definitions.h"
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Define all of our flags default values.
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define FLAG_MODE_DEFINE_DEFAULTS
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "flag-definitions.h"
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace {
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This structure represents a single entry in the flag system, with a pointer
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// to the actual flag, default value, comment, etc.  This is designed to be POD
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// initialized as to avoid requiring static constructors.
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct Flag {
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enum FlagType { TYPE_BOOL, TYPE_INT, TYPE_FLOAT, TYPE_STRING, TYPE_ARGS };
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FlagType type_;           // What type of flag, bool, int, or string.
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const char* name_;        // Name of the flag, ex "my_flag".
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void* valptr_;            // Pointer to the global flag variable.
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const void* defptr_;      // Pointer to the default value.
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const char* cmt_;         // A comment about the flags purpose.
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool owns_ptr_;           // Does the flag own its string value?
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FlagType type() const { return type_; }
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const char* name() const { return name_; }
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const char* comment() const { return cmt_; }
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool* bool_variable() const {
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(type_ == TYPE_BOOL);
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return reinterpret_cast<bool*>(valptr_);
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int* int_variable() const {
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(type_ == TYPE_INT);
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return reinterpret_cast<int*>(valptr_);
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  double* float_variable() const {
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(type_ == TYPE_FLOAT);
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return reinterpret_cast<double*>(valptr_);
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const char* string_value() const {
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(type_ == TYPE_STRING);
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return *reinterpret_cast<const char**>(valptr_);
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void set_string_value(const char* value, bool owns_ptr) {
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(type_ == TYPE_STRING);
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    const char** ptr = reinterpret_cast<const char**>(valptr_);
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (owns_ptr_ && *ptr != NULL) DeleteArray(*ptr);
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    *ptr = value;
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    owns_ptr_ = owns_ptr;
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JSArguments* args_variable() const {
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(type_ == TYPE_ARGS);
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return reinterpret_cast<JSArguments*>(valptr_);
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool bool_default() const {
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(type_ == TYPE_BOOL);
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return *reinterpret_cast<const bool*>(defptr_);
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int int_default() const {
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(type_ == TYPE_INT);
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return *reinterpret_cast<const int*>(defptr_);
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  double float_default() const {
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(type_ == TYPE_FLOAT);
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return *reinterpret_cast<const double*>(defptr_);
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const char* string_default() const {
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(type_ == TYPE_STRING);
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return *reinterpret_cast<const char* const *>(defptr_);
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JSArguments args_default() const {
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(type_ == TYPE_ARGS);
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return *reinterpret_cast<const JSArguments*>(defptr_);
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compare this flag's current value against the default.
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool IsDefault() const {
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    switch (type_) {
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      case TYPE_BOOL:
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        return *bool_variable() == bool_default();
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      case TYPE_INT:
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        return *int_variable() == int_default();
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      case TYPE_FLOAT:
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        return *float_variable() == float_default();
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      case TYPE_STRING: {
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        const char* str1 = string_value();
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        const char* str2 = string_default();
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        if (str2 == NULL) return str1 == NULL;
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        if (str1 == NULL) return str2 == NULL;
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        return strcmp(str1, str2) == 0;
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      case TYPE_ARGS:
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        return args_variable()->argc() == 0;
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    UNREACHABLE();
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return true;
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set a flag back to it's default value.
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Reset() {
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    switch (type_) {
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      case TYPE_BOOL:
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        *bool_variable() = bool_default();
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      case TYPE_INT:
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        *int_variable() = int_default();
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      case TYPE_FLOAT:
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        *float_variable() = float_default();
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      case TYPE_STRING:
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        set_string_value(string_default(), false);
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      case TYPE_ARGS:
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        *args_variable() = args_default();
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockFlag flags[] = {
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define FLAG_MODE_META
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "flag-definitions.h"
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst size_t num_flags = sizeof(flags) / sizeof(*flags);
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}  // namespace
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const char* Type2String(Flag::FlagType type) {
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  switch (type) {
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Flag::TYPE_BOOL: return "bool";
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Flag::TYPE_INT: return "int";
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Flag::TYPE_FLOAT: return "float";
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Flag::TYPE_STRING: return "string";
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Flag::TYPE_ARGS: return "arguments";
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic SmartPointer<const char> ToString(Flag* flag) {
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HeapStringAllocator string_allocator;
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StringStream buffer(&string_allocator);
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  switch (flag->type()) {
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Flag::TYPE_BOOL:
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      buffer.Add("%s", (*flag->bool_variable() ? "true" : "false"));
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Flag::TYPE_INT:
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      buffer.Add("%d", *flag->int_variable());
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Flag::TYPE_FLOAT:
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      buffer.Add("%f", FmtElm(*flag->float_variable()));
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Flag::TYPE_STRING: {
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      const char* str = flag->string_value();
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      buffer.Add("%s", str ? str : "NULL");
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Flag::TYPE_ARGS: {
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      JSArguments args = *flag->args_variable();
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (args.argc() > 0) {
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        buffer.Add("%s",  args[0]);
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        for (int i = 1; i < args.argc(); i++) {
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          buffer.Add(" %s", args[i]);
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        }
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return buffer.ToCString();
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// static
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockList<const char*>* FlagList::argv() {
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  List<const char*>* args = new List<const char*>(8);
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Flag* args_flag = NULL;
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (size_t i = 0; i < num_flags; ++i) {
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Flag* f = &flags[i];
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!f->IsDefault()) {
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (f->type() == Flag::TYPE_ARGS) {
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        ASSERT(args_flag == NULL);
238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        args_flag = f;  // Must be last in arguments.
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        continue;
240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      HeapStringAllocator string_allocator;
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      StringStream buffer(&string_allocator);
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (f->type() != Flag::TYPE_BOOL || *(f->bool_variable())) {
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        buffer.Add("--%s", f->name());
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      } else {
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        buffer.Add("--no%s", f->name());
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      args->Add(buffer.ToCString().Detach());
249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (f->type() != Flag::TYPE_BOOL) {
250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        args->Add(ToString(f).Detach());
251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (args_flag != NULL) {
255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    HeapStringAllocator string_allocator;
256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    StringStream buffer(&string_allocator);
257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    buffer.Add("--%s", args_flag->name());
258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    args->Add(buffer.ToCString().Detach());
259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    JSArguments jsargs = *args_flag->args_variable();
260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (int j = 0; j < jsargs.argc(); j++) {
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      args->Add(StrDup(jsargs[j]));
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return args;
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper function to parse flags: Takes an argument arg and splits it into
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// a flag name and flag value (or NULL if they are missing). is_bool is set
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// if the arg started with "-no" or "--no". The buffer may be used to NUL-
271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// terminate the name, it must be large enough to hold any possible name.
272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void SplitArgument(const char* arg,
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          char* buffer,
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          int buffer_size,
275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          const char** name,
276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          const char** value,
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          bool* is_bool) {
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  *name = NULL;
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  *value = NULL;
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  *is_bool = false;
281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (*arg == '-') {
283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // find the begin of the flag name
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    arg++;  // remove 1st '-'
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (*arg == '-') {
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      arg++;  // remove 2nd '-'
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (arg[0] == '\0') {
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        const char* kJSArgumentsFlagName = "js_arguments";
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        *name = kJSArgumentsFlagName;
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        return;
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (arg[0] == 'n' && arg[1] == 'o') {
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      arg += 2;  // remove "no"
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      *is_bool = true;
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    *name = arg;
298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // find the end of the flag name
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    while (*arg != '\0' && *arg != '=')
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      arg++;
302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // get the value if any
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (*arg == '=') {
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // make a copy so we can NUL-terminate flag name
306d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      size_t n = arg - *name;
307d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      CHECK(n < static_cast<size_t>(buffer_size));  // buffer is too small
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      memcpy(buffer, *name, n);
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      buffer[n] = '\0';
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      *name = buffer;
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // get the value
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      *value = arg + 1;
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockinline char NormalizeChar(char ch) {
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return ch == '_' ? '-' : ch;
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic bool EqualNames(const char* a, const char* b) {
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; NormalizeChar(a[i]) == NormalizeChar(b[i]); i++) {
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (a[i] == '\0') {
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return true;
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return false;
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic Flag* FindFlag(const char* name) {
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (size_t i = 0; i < num_flags; ++i) {
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (EqualNames(name, flags[i].name()))
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return &flags[i];
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// static
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint FlagList::SetFlagsFromCommandLine(int* argc,
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                      char** argv,
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                      bool remove_flags) {
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // parse arguments
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 1; i < *argc;) {
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int j = i;  // j > 0
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    const char* arg = argv[i++];
350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // split arg into flag components
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    char buffer[1*KB];
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    const char* name;
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    const char* value;
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool is_bool;
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    SplitArgument(arg, buffer, sizeof buffer, &name, &value, &is_bool);
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (name != NULL) {
359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // lookup the flag
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Flag* flag = FindFlag(name);
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (flag == NULL) {
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        if (remove_flags) {
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          // We don't recognize this flag but since we're removing
364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          // the flags we recognize we assume that the remaining flags
365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          // will be processed somewhere else so this flag might make
366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          // sense there.
367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          continue;
368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        } else {
369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          fprintf(stderr, "Error: unrecognized flag %s\n"
370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  "Try --help for options\n", arg);
371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          return j;
372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        }
373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // if we still need a flag value, use the next argument if available
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (flag->type() != Flag::TYPE_BOOL &&
377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          flag->type() != Flag::TYPE_ARGS &&
378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          value == NULL) {
379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        if (i < *argc) {
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          value = argv[i++];
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        } else {
382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          fprintf(stderr, "Error: missing value for flag %s of type %s\n"
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  "Try --help for options\n",
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  arg, Type2String(flag->type()));
385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          return j;
386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        }
387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // set the flag
390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      char* endp = const_cast<char*>("");  // *endp is only read
391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      switch (flag->type()) {
392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        case Flag::TYPE_BOOL:
393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          *flag->bool_variable() = !is_bool;
394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          break;
395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        case Flag::TYPE_INT:
396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          *flag->int_variable() = strtol(value, &endp, 10);  // NOLINT
397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          break;
398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        case Flag::TYPE_FLOAT:
399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          *flag->float_variable() = strtod(value, &endp);
400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          break;
401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        case Flag::TYPE_STRING:
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          flag->set_string_value(value ? StrDup(value) : NULL, true);
403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          break;
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        case Flag::TYPE_ARGS: {
405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          int start_pos = (value == NULL) ? i : i - 1;
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          int js_argc = *argc - start_pos;
407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          const char** js_argv = NewArray<const char*>(js_argc);
408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          if (value != NULL) {
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block            js_argv[0] = StrDup(value);
410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          }
411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          for (int k = i; k < *argc; k++) {
412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block            js_argv[k - start_pos] = StrDup(argv[k]);
413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          }
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          *flag->args_variable() = JSArguments(js_argc, js_argv);
415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          i = *argc;  // Consume all arguments
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          break;
417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        }
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // handle errors
421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if ((flag->type() == Flag::TYPE_BOOL && value != NULL) ||
422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          (flag->type() != Flag::TYPE_BOOL && is_bool) ||
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          *endp != '\0') {
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        fprintf(stderr, "Error: illegal value for flag %s of type %s\n"
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                "Try --help for options\n",
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                arg, Type2String(flag->type()));
427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        return j;
428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // remove the flag & value from the command
431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (remove_flags) {
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        while (j < i) {
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          argv[j++] = NULL;
434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        }
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // shrink the argument list
440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (remove_flags) {
441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int j = 1;
442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (int i = 1; i < *argc; i++) {
443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (argv[i] != NULL)
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        argv[j++] = argv[i];
445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    *argc = j;
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (FLAG_help) {
450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintHelp();
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    exit(0);
452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // parsed all flags successfully
454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return 0;
455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic char* SkipWhiteSpace(char* p) {
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  while (*p != '\0' && isspace(*p) != 0) p++;
460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return p;
461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic char* SkipBlackSpace(char* p) {
465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  while (*p != '\0' && isspace(*p) == 0) p++;
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return p;
467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// static
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint FlagList::SetFlagsFromString(const char* str, int len) {
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // make a 0-terminated copy of str
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  char* copy0 = NewArray<char>(len + 1);
474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  memcpy(copy0, str, len);
475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  copy0[len] = '\0';
476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // strip leading white space
478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  char* copy = SkipWhiteSpace(copy0);
479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // count the number of 'arguments'
481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int argc = 1;  // be compatible with SetFlagsFromCommandLine()
482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (char* p = copy; *p != '\0'; argc++) {
483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    p = SkipBlackSpace(p);
484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    p = SkipWhiteSpace(p);
485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // allocate argument array
488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  char** argv = NewArray<char*>(argc);
489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // split the flags string into arguments
491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  argc = 1;  // be compatible with SetFlagsFromCommandLine()
492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (char* p = copy; *p != '\0'; argc++) {
493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    argv[argc] = p;
494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    p = SkipBlackSpace(p);
495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (*p != '\0') *p++ = '\0';  // 0-terminate argument
496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    p = SkipWhiteSpace(p);
497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // set the flags
500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int result = SetFlagsFromCommandLine(&argc, argv, false);
501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // cleanup
503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DeleteArray(argv);
504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DeleteArray(copy0);
505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// static
511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid FlagList::ResetAllFlags() {
512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (size_t i = 0; i < num_flags; ++i) {
513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    flags[i].Reset();
514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// static
519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid FlagList::PrintHelp() {
520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  printf("Usage:\n");
521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  printf("  shell [options] -e string\n");
522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  printf("    execute string in V8\n");
523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  printf("  shell [options] file1 file2 ... filek\n");
524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  printf("    run JavaScript scripts in file1, file2, ..., filek\n");
525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  printf("  shell [options]\n");
526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  printf("  shell [options] --shell [file1 file2 ... filek]\n");
527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  printf("    run an interactive JavaScript shell\n");
528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  printf("  d8 [options] file1 file2 ... filek\n");
529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  printf("  d8 [options]\n");
530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  printf("  d8 [options] --shell [file1 file2 ... filek]\n");
531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  printf("    run the new debugging shell\n\n");
532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  printf("Options:\n");
533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (size_t i = 0; i < num_flags; ++i) {
534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Flag* f = &flags[i];
535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    SmartPointer<const char> value = ToString(f);
536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    printf("  --%s (%s)\n        type: %s  default: %s\n",
537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block           f->name(), f->comment(), Type2String(f->type()), *value);
538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockJSArguments::JSArguments()
542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    : argc_(0), argv_(NULL) {}
543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockJSArguments::JSArguments(int argc, const char** argv)
544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    : argc_(argc), argv_(argv) {}
545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint JSArguments::argc() const { return argc_; }
546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char** JSArguments::argv() { return argv_; }
547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char*& JSArguments::operator[](int idx) { return argv_[idx]; }
548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockJSArguments& JSArguments::operator=(JSArguments args) {
549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    argc_ = args.argc_;
550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    argv_ = args.argv_;
551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return *this;
552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
556