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