OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 // Define all of our flags default values. | 48 // Define all of our flags default values. |
49 #define FLAG_MODE_DEFINE_DEFAULTS | 49 #define FLAG_MODE_DEFINE_DEFAULTS |
50 #include "flag-definitions.h" | 50 #include "flag-definitions.h" |
51 | 51 |
52 namespace { | 52 namespace { |
53 | 53 |
54 // This structure represents a single entry in the flag system, with a pointer | 54 // This structure represents a single entry in the flag system, with a pointer |
55 // to the actual flag, default value, comment, etc. This is designed to be POD | 55 // to the actual flag, default value, comment, etc. This is designed to be POD |
56 // initialized as to avoid requiring static constructors. | 56 // initialized as to avoid requiring static constructors. |
57 struct Flag { | 57 struct Flag { |
58 enum FlagType { TYPE_BOOL, TYPE_INT, TYPE_FLOAT, TYPE_STRING, TYPE_ARGS }; | 58 enum FlagType { TYPE_BOOL, TYPE_MAYBE_BOOL, TYPE_INT, TYPE_FLOAT, |
| 59 TYPE_STRING, TYPE_ARGS }; |
59 | 60 |
60 FlagType type_; // What type of flag, bool, int, or string. | 61 FlagType type_; // What type of flag, bool, int, or string. |
61 const char* name_; // Name of the flag, ex "my_flag". | 62 const char* name_; // Name of the flag, ex "my_flag". |
62 void* valptr_; // Pointer to the global flag variable. | 63 void* valptr_; // Pointer to the global flag variable. |
63 const void* defptr_; // Pointer to the default value. | 64 const void* defptr_; // Pointer to the default value. |
64 const char* cmt_; // A comment about the flags purpose. | 65 const char* cmt_; // A comment about the flags purpose. |
65 bool owns_ptr_; // Does the flag own its string value? | 66 bool owns_ptr_; // Does the flag own its string value? |
66 | 67 |
67 FlagType type() const { return type_; } | 68 FlagType type() const { return type_; } |
68 | 69 |
69 const char* name() const { return name_; } | 70 const char* name() const { return name_; } |
70 | 71 |
71 const char* comment() const { return cmt_; } | 72 const char* comment() const { return cmt_; } |
72 | 73 |
73 bool* bool_variable() const { | 74 bool* bool_variable() const { |
74 ASSERT(type_ == TYPE_BOOL); | 75 ASSERT(type_ == TYPE_BOOL); |
75 return reinterpret_cast<bool*>(valptr_); | 76 return reinterpret_cast<bool*>(valptr_); |
76 } | 77 } |
77 | 78 |
| 79 MaybeBoolFlag* maybe_bool_variable() const { |
| 80 ASSERT(type_ == TYPE_MAYBE_BOOL); |
| 81 return reinterpret_cast<MaybeBoolFlag*>(valptr_); |
| 82 } |
| 83 |
78 int* int_variable() const { | 84 int* int_variable() const { |
79 ASSERT(type_ == TYPE_INT); | 85 ASSERT(type_ == TYPE_INT); |
80 return reinterpret_cast<int*>(valptr_); | 86 return reinterpret_cast<int*>(valptr_); |
81 } | 87 } |
82 | 88 |
83 double* float_variable() const { | 89 double* float_variable() const { |
84 ASSERT(type_ == TYPE_FLOAT); | 90 ASSERT(type_ == TYPE_FLOAT); |
85 return reinterpret_cast<double*>(valptr_); | 91 return reinterpret_cast<double*>(valptr_); |
86 } | 92 } |
87 | 93 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 JSArguments args_default() const { | 132 JSArguments args_default() const { |
127 ASSERT(type_ == TYPE_ARGS); | 133 ASSERT(type_ == TYPE_ARGS); |
128 return *reinterpret_cast<const JSArguments*>(defptr_); | 134 return *reinterpret_cast<const JSArguments*>(defptr_); |
129 } | 135 } |
130 | 136 |
131 // Compare this flag's current value against the default. | 137 // Compare this flag's current value against the default. |
132 bool IsDefault() const { | 138 bool IsDefault() const { |
133 switch (type_) { | 139 switch (type_) { |
134 case TYPE_BOOL: | 140 case TYPE_BOOL: |
135 return *bool_variable() == bool_default(); | 141 return *bool_variable() == bool_default(); |
| 142 case TYPE_MAYBE_BOOL: |
| 143 return maybe_bool_variable()->has_value == false; |
136 case TYPE_INT: | 144 case TYPE_INT: |
137 return *int_variable() == int_default(); | 145 return *int_variable() == int_default(); |
138 case TYPE_FLOAT: | 146 case TYPE_FLOAT: |
139 return *float_variable() == float_default(); | 147 return *float_variable() == float_default(); |
140 case TYPE_STRING: { | 148 case TYPE_STRING: { |
141 const char* str1 = string_value(); | 149 const char* str1 = string_value(); |
142 const char* str2 = string_default(); | 150 const char* str2 = string_default(); |
143 if (str2 == NULL) return str1 == NULL; | 151 if (str2 == NULL) return str1 == NULL; |
144 if (str1 == NULL) return str2 == NULL; | 152 if (str1 == NULL) return str2 == NULL; |
145 return strcmp(str1, str2) == 0; | 153 return strcmp(str1, str2) == 0; |
146 } | 154 } |
147 case TYPE_ARGS: | 155 case TYPE_ARGS: |
148 return args_variable()->argc() == 0; | 156 return args_variable()->argc == 0; |
149 } | 157 } |
150 UNREACHABLE(); | 158 UNREACHABLE(); |
151 return true; | 159 return true; |
152 } | 160 } |
153 | 161 |
154 // Set a flag back to it's default value. | 162 // Set a flag back to it's default value. |
155 void Reset() { | 163 void Reset() { |
156 switch (type_) { | 164 switch (type_) { |
157 case TYPE_BOOL: | 165 case TYPE_BOOL: |
158 *bool_variable() = bool_default(); | 166 *bool_variable() = bool_default(); |
159 break; | 167 break; |
| 168 case TYPE_MAYBE_BOOL: |
| 169 *maybe_bool_variable() = MaybeBoolFlag::Create(false, false); |
| 170 break; |
160 case TYPE_INT: | 171 case TYPE_INT: |
161 *int_variable() = int_default(); | 172 *int_variable() = int_default(); |
162 break; | 173 break; |
163 case TYPE_FLOAT: | 174 case TYPE_FLOAT: |
164 *float_variable() = float_default(); | 175 *float_variable() = float_default(); |
165 break; | 176 break; |
166 case TYPE_STRING: | 177 case TYPE_STRING: |
167 set_string_value(string_default(), false); | 178 set_string_value(string_default(), false); |
168 break; | 179 break; |
169 case TYPE_ARGS: | 180 case TYPE_ARGS: |
170 *args_variable() = args_default(); | 181 *args_variable() = args_default(); |
171 break; | 182 break; |
172 } | 183 } |
173 } | 184 } |
174 }; | 185 }; |
175 | 186 |
176 Flag flags[] = { | 187 Flag flags[] = { |
177 #define FLAG_MODE_META | 188 #define FLAG_MODE_META |
178 #include "flag-definitions.h" | 189 #include "flag-definitions.h" |
179 }; | 190 }; |
180 | 191 |
181 const size_t num_flags = sizeof(flags) / sizeof(*flags); | 192 const size_t num_flags = sizeof(flags) / sizeof(*flags); |
182 | 193 |
183 } // namespace | 194 } // namespace |
184 | 195 |
185 | 196 |
186 static const char* Type2String(Flag::FlagType type) { | 197 static const char* Type2String(Flag::FlagType type) { |
187 switch (type) { | 198 switch (type) { |
188 case Flag::TYPE_BOOL: return "bool"; | 199 case Flag::TYPE_BOOL: return "bool"; |
| 200 case Flag::TYPE_MAYBE_BOOL: return "maybe_bool"; |
189 case Flag::TYPE_INT: return "int"; | 201 case Flag::TYPE_INT: return "int"; |
190 case Flag::TYPE_FLOAT: return "float"; | 202 case Flag::TYPE_FLOAT: return "float"; |
191 case Flag::TYPE_STRING: return "string"; | 203 case Flag::TYPE_STRING: return "string"; |
192 case Flag::TYPE_ARGS: return "arguments"; | 204 case Flag::TYPE_ARGS: return "arguments"; |
193 } | 205 } |
194 UNREACHABLE(); | 206 UNREACHABLE(); |
195 return NULL; | 207 return NULL; |
196 } | 208 } |
197 | 209 |
198 | 210 |
199 static SmartArrayPointer<const char> ToString(Flag* flag) { | 211 static SmartArrayPointer<const char> ToString(Flag* flag) { |
200 HeapStringAllocator string_allocator; | 212 HeapStringAllocator string_allocator; |
201 StringStream buffer(&string_allocator); | 213 StringStream buffer(&string_allocator); |
202 switch (flag->type()) { | 214 switch (flag->type()) { |
203 case Flag::TYPE_BOOL: | 215 case Flag::TYPE_BOOL: |
204 buffer.Add("%s", (*flag->bool_variable() ? "true" : "false")); | 216 buffer.Add("%s", (*flag->bool_variable() ? "true" : "false")); |
205 break; | 217 break; |
| 218 case Flag::TYPE_MAYBE_BOOL: |
| 219 buffer.Add("%s", flag->maybe_bool_variable()->has_value |
| 220 ? (flag->maybe_bool_variable()->value ? "true" : "false") |
| 221 : "unset"); |
| 222 break; |
206 case Flag::TYPE_INT: | 223 case Flag::TYPE_INT: |
207 buffer.Add("%d", *flag->int_variable()); | 224 buffer.Add("%d", *flag->int_variable()); |
208 break; | 225 break; |
209 case Flag::TYPE_FLOAT: | 226 case Flag::TYPE_FLOAT: |
210 buffer.Add("%f", FmtElm(*flag->float_variable())); | 227 buffer.Add("%f", FmtElm(*flag->float_variable())); |
211 break; | 228 break; |
212 case Flag::TYPE_STRING: { | 229 case Flag::TYPE_STRING: { |
213 const char* str = flag->string_value(); | 230 const char* str = flag->string_value(); |
214 buffer.Add("%s", str ? str : "NULL"); | 231 buffer.Add("%s", str ? str : "NULL"); |
215 break; | 232 break; |
216 } | 233 } |
217 case Flag::TYPE_ARGS: { | 234 case Flag::TYPE_ARGS: { |
218 JSArguments args = *flag->args_variable(); | 235 JSArguments args = *flag->args_variable(); |
219 if (args.argc() > 0) { | 236 if (args.argc > 0) { |
220 buffer.Add("%s", args[0]); | 237 buffer.Add("%s", args[0]); |
221 for (int i = 1; i < args.argc(); i++) { | 238 for (int i = 1; i < args.argc; i++) { |
222 buffer.Add(" %s", args[i]); | 239 buffer.Add(" %s", args[i]); |
223 } | 240 } |
224 } | 241 } |
225 break; | 242 break; |
226 } | 243 } |
227 } | 244 } |
228 return buffer.ToCString(); | 245 return buffer.ToCString(); |
229 } | 246 } |
230 | 247 |
231 | 248 |
(...skipping 21 matching lines...) Expand all Loading... |
253 args->Add(ToString(f).Detach()); | 270 args->Add(ToString(f).Detach()); |
254 } | 271 } |
255 } | 272 } |
256 } | 273 } |
257 if (args_flag != NULL) { | 274 if (args_flag != NULL) { |
258 HeapStringAllocator string_allocator; | 275 HeapStringAllocator string_allocator; |
259 StringStream buffer(&string_allocator); | 276 StringStream buffer(&string_allocator); |
260 buffer.Add("--%s", args_flag->name()); | 277 buffer.Add("--%s", args_flag->name()); |
261 args->Add(buffer.ToCString().Detach()); | 278 args->Add(buffer.ToCString().Detach()); |
262 JSArguments jsargs = *args_flag->args_variable(); | 279 JSArguments jsargs = *args_flag->args_variable(); |
263 for (int j = 0; j < jsargs.argc(); j++) { | 280 for (int j = 0; j < jsargs.argc; j++) { |
264 args->Add(StrDup(jsargs[j])); | 281 args->Add(StrDup(jsargs[j])); |
265 } | 282 } |
266 } | 283 } |
267 return args; | 284 return args; |
268 } | 285 } |
269 | 286 |
270 | 287 |
271 inline char NormalizeChar(char ch) { | 288 inline char NormalizeChar(char ch) { |
272 return ch == '_' ? '-' : ch; | 289 return ch == '_' ? '-' : ch; |
273 } | 290 } |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 } else { | 390 } else { |
374 PrintF(stderr, "Error: unrecognized flag %s\n" | 391 PrintF(stderr, "Error: unrecognized flag %s\n" |
375 "Try --help for options\n", arg); | 392 "Try --help for options\n", arg); |
376 return_code = j; | 393 return_code = j; |
377 break; | 394 break; |
378 } | 395 } |
379 } | 396 } |
380 | 397 |
381 // if we still need a flag value, use the next argument if available | 398 // if we still need a flag value, use the next argument if available |
382 if (flag->type() != Flag::TYPE_BOOL && | 399 if (flag->type() != Flag::TYPE_BOOL && |
| 400 flag->type() != Flag::TYPE_MAYBE_BOOL && |
383 flag->type() != Flag::TYPE_ARGS && | 401 flag->type() != Flag::TYPE_ARGS && |
384 value == NULL) { | 402 value == NULL) { |
385 if (i < *argc) { | 403 if (i < *argc) { |
386 value = argv[i++]; | 404 value = argv[i++]; |
387 } else { | 405 } else { |
388 PrintF(stderr, "Error: missing value for flag %s of type %s\n" | 406 PrintF(stderr, "Error: missing value for flag %s of type %s\n" |
389 "Try --help for options\n", | 407 "Try --help for options\n", |
390 arg, Type2String(flag->type())); | 408 arg, Type2String(flag->type())); |
391 return_code = j; | 409 return_code = j; |
392 break; | 410 break; |
393 } | 411 } |
394 } | 412 } |
395 | 413 |
396 // set the flag | 414 // set the flag |
397 char* endp = const_cast<char*>(""); // *endp is only read | 415 char* endp = const_cast<char*>(""); // *endp is only read |
398 switch (flag->type()) { | 416 switch (flag->type()) { |
399 case Flag::TYPE_BOOL: | 417 case Flag::TYPE_BOOL: |
400 *flag->bool_variable() = !is_bool; | 418 *flag->bool_variable() = !is_bool; |
401 break; | 419 break; |
| 420 case Flag::TYPE_MAYBE_BOOL: |
| 421 *flag->maybe_bool_variable() = MaybeBoolFlag::Create(true, !is_bool); |
| 422 break; |
402 case Flag::TYPE_INT: | 423 case Flag::TYPE_INT: |
403 *flag->int_variable() = strtol(value, &endp, 10); // NOLINT | 424 *flag->int_variable() = strtol(value, &endp, 10); // NOLINT |
404 break; | 425 break; |
405 case Flag::TYPE_FLOAT: | 426 case Flag::TYPE_FLOAT: |
406 *flag->float_variable() = strtod(value, &endp); | 427 *flag->float_variable() = strtod(value, &endp); |
407 break; | 428 break; |
408 case Flag::TYPE_STRING: | 429 case Flag::TYPE_STRING: |
409 flag->set_string_value(value ? StrDup(value) : NULL, true); | 430 flag->set_string_value(value ? StrDup(value) : NULL, true); |
410 break; | 431 break; |
411 case Flag::TYPE_ARGS: { | 432 case Flag::TYPE_ARGS: { |
412 int start_pos = (value == NULL) ? i : i - 1; | 433 int start_pos = (value == NULL) ? i : i - 1; |
413 int js_argc = *argc - start_pos; | 434 int js_argc = *argc - start_pos; |
414 const char** js_argv = NewArray<const char*>(js_argc); | 435 const char** js_argv = NewArray<const char*>(js_argc); |
415 if (value != NULL) { | 436 if (value != NULL) { |
416 js_argv[0] = StrDup(value); | 437 js_argv[0] = StrDup(value); |
417 } | 438 } |
418 for (int k = i; k < *argc; k++) { | 439 for (int k = i; k < *argc; k++) { |
419 js_argv[k - start_pos] = StrDup(argv[k]); | 440 js_argv[k - start_pos] = StrDup(argv[k]); |
420 } | 441 } |
421 *flag->args_variable() = JSArguments::Create(js_argc, js_argv); | 442 *flag->args_variable() = JSArguments::Create(js_argc, js_argv); |
422 i = *argc; // Consume all arguments | 443 i = *argc; // Consume all arguments |
423 break; | 444 break; |
424 } | 445 } |
425 } | 446 } |
426 | 447 |
427 // handle errors | 448 // handle errors |
428 if ((flag->type() == Flag::TYPE_BOOL && value != NULL) || | 449 bool is_bool_type = flag->type() == Flag::TYPE_BOOL || |
429 (flag->type() != Flag::TYPE_BOOL && is_bool) || | 450 flag->type() == Flag::TYPE_MAYBE_BOOL; |
| 451 if ((is_bool_type && value != NULL) || (!is_bool_type && is_bool) || |
430 *endp != '\0') { | 452 *endp != '\0') { |
431 PrintF(stderr, "Error: illegal value for flag %s of type %s\n" | 453 PrintF(stderr, "Error: illegal value for flag %s of type %s\n" |
432 "Try --help for options\n", | 454 "Try --help for options\n", |
433 arg, Type2String(flag->type())); | 455 arg, Type2String(flag->type())); |
434 return_code = j; | 456 return_code = j; |
435 break; | 457 break; |
436 } | 458 } |
437 | 459 |
438 // remove the flag & value from the command | 460 // remove the flag & value from the command |
439 if (remove_flags) { | 461 if (remove_flags) { |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 printf("Options:\n"); | 564 printf("Options:\n"); |
543 for (size_t i = 0; i < num_flags; ++i) { | 565 for (size_t i = 0; i < num_flags; ++i) { |
544 Flag* f = &flags[i]; | 566 Flag* f = &flags[i]; |
545 SmartArrayPointer<const char> value = ToString(f); | 567 SmartArrayPointer<const char> value = ToString(f); |
546 printf(" --%s (%s)\n type: %s default: %s\n", | 568 printf(" --%s (%s)\n type: %s default: %s\n", |
547 f->name(), f->comment(), Type2String(f->type()), *value); | 569 f->name(), f->comment(), Type2String(f->type()), *value); |
548 } | 570 } |
549 } | 571 } |
550 | 572 |
551 | 573 |
| 574 // static |
552 void FlagList::EnforceFlagImplications() { | 575 void FlagList::EnforceFlagImplications() { |
553 #define FLAG_MODE_DEFINE_IMPLICATIONS | 576 #define FLAG_MODE_DEFINE_IMPLICATIONS |
554 #include "flag-definitions.h" | 577 #include "flag-definitions.h" |
555 #undef FLAG_MODE_DEFINE_IMPLICATIONS | 578 #undef FLAG_MODE_DEFINE_IMPLICATIONS |
556 } | 579 } |
557 | 580 |
558 } } // namespace v8::internal | 581 } } // namespace v8::internal |
OLD | NEW |