14DEFINE_FLAG(
bool, print_flags,
false,
"Print flags as they are being parsed.");
16 ignore_unrecognized_flags,
18 "Ignore unrecognized flags.");
20#define PRODUCT_FLAG_MACRO(name, type, default_value, comment) \
22 Flags::Register_##type(&FLAG_##name, #name, default_value, comment);
25#define DEBUG_FLAG_MACRO(name, type, default_value, comment) \
27 Flags::Register_##type(&FLAG_##name, #name, default_value, comment);
29#define DEBUG_FLAG_MACRO(name, type, default_value, comment)
32#if defined(PRODUCT) && defined(DART_PRECOMPILED_RUNTIME)
34#define RELEASE_FLAG_MACRO(name, product_value, type, default_value, comment)
36#define PRECOMPILE_FLAG_MACRO(name, pre_value, product_value, type, \
37 default_value, comment)
41#define RELEASE_FLAG_MACRO(name, product_value, type, default_value, comment)
43#define PRECOMPILE_FLAG_MACRO(name, pre_value, product_value, type, \
44 default_value, comment)
46#elif defined(DART_PRECOMPILED_RUNTIME)
47#define RELEASE_FLAG_MACRO(name, product_value, type, default_value, comment) \
49 Flags::Register_##type(&FLAG_##name, #name, default_value, comment);
51#define PRECOMPILE_FLAG_MACRO(name, pre_value, product_value, type, \
52 default_value, comment)
55#define RELEASE_FLAG_MACRO(name, product_value, type, default_value, comment) \
57 Flags::Register_##type(&FLAG_##name, #name, default_value, comment);
58#define PRECOMPILE_FLAG_MACRO(name, pre_value, product_value, type, \
59 default_value, comment) \
61 Flags::Register_##type(&FLAG_##name, #name, default_value, comment);
70#undef PRODUCT_FLAG_MACRO
71#undef RELEASE_FLAG_MACRO
72#undef PRECOMPILE_FLAG_MACRO
73#undef DEBUG_FLAG_MACRO
75bool Flags::initialized_ =
false;
78Flag** Flags::flags_ =
nullptr;
79intptr_t Flags::capacity_ = 0;
80intptr_t Flags::num_flags_ = 0;
170 for (intptr_t i = 0; i < num_flags_; i++) {
172 if (strcmp(
flag->name_,
name) == 0) {
182 (
flag->bool_ptr_ !=
nullptr) && (*
flag->bool_ptr_ ==
true);
187 initialized_ =
false;
192 if (num_flags_ == capacity_) {
193 if (flags_ ==
nullptr) {
195 flags_ =
new Flag*[capacity_];
197 intptr_t new_capacity = capacity_ * 2;
198 Flag** new_flags =
new Flag*[new_capacity];
199 for (intptr_t i = 0; i < num_flags_; i++) {
200 new_flags[i] = flags_[i];
204 capacity_ = new_capacity;
207 flags_[num_flags_++] =
flag;
213 const char* comment) {
215 if (
flag !=
nullptr) {
217 return default_value;
221 return default_value;
227 const char* comment) {
233 return default_value;
238 uint64_t default_value,
239 const char* comment) {
245 return default_value;
250 const char* default_value,
251 const char* comment) {
255 return default_value;
260 const char* comment) {
269 const char* comment) {
277 intptr_t len = strlen(
s);
278 for (intptr_t i = 0; i < len; i++) {
285bool Flags::SetFlagFromString(Flag*
flag,
const char* argument) {
287 switch (
flag->type_) {
289 if (strcmp(argument,
"true") == 0) {
290 *
flag->bool_ptr_ =
true;
291 }
else if (strcmp(argument,
"false") == 0) {
292 *
flag->bool_ptr_ =
false;
299 flag->string_value_.reset(argument ==
nullptr ?
nullptr
300 : Utils::StrDup(argument));
301 *
flag->charp_ptr_ =
flag->string_value_.get();
305 char* endptr =
nullptr;
306 const intptr_t
len = strlen(argument);
308 if ((len > 2) && (argument[0] ==
'0') && (argument[1] ==
'x')) {
311 int val = strtol(argument, &endptr,
base);
312 if (endptr == argument + len) {
313 *
flag->int_ptr_ = val;
320 char* endptr =
nullptr;
321 const intptr_t
len = strlen(argument);
323 if ((len > 2) && (argument[0] ==
'0') && (argument[1] ==
'x')) {
326 int64_t val = strtoll(argument, &endptr,
base);
327 if (endptr == argument + len) {
328 *
flag->uint64_ptr_ =
static_cast<uint64_t
>(val);
335 if (strcmp(argument,
"true") == 0) {
336 (
flag->flag_handler_)(
true);
337 }
else if (strcmp(argument,
"false") == 0) {
338 (
flag->flag_handler_)(
false);
347 (
flag->option_handler_)(argument);
355 flag->changed_ =
true;
359void Flags::Parse(
const char* option) {
361 const char*
equals = option;
366 const char* argument =
nullptr;
372 const char*
const kNo1Prefix =
"no_";
373 const char*
const kNo2Prefix =
"no-";
374 const intptr_t kNo1PrefixLen = strlen(kNo1Prefix);
375 const intptr_t kNo2PrefixLen = strlen(kNo2Prefix);
376 if (strncmp(option, kNo1Prefix, kNo1PrefixLen) == 0) {
377 option += kNo1PrefixLen;
379 }
else if (strncmp(option, kNo2Prefix, kNo2PrefixLen) == 0) {
380 option += kNo2PrefixLen;
391 intptr_t name_len =
equals - option;
392 char*
name =
new char[name_len + 1];
393 strncpy(
name, option, name_len);
394 name[name_len] =
'\0';
398 if (
flag ==
nullptr) {
400 char* new_flag =
new char[name_len + 1];
401 strncpy(new_flag, option, name_len);
402 new_flag[name_len] =
'\0';
408 if (!
flag->IsUnrecognized()) {
409 if (!SetFlagFromString(
flag, argument)) {
410 OS::PrintErr(
"Ignoring flag: %s is an invalid value for flag %s\n",
421 intptr_t prefix_length) {
422 intptr_t name_length = strlen(
name);
423 return ((name_length > prefix_length) &&
424 (strncmp(
name, prefix, prefix_length) == 0));
427int Flags::CompareFlagNames(
const void*
left,
const void*
right) {
428 const Flag* left_flag = *
reinterpret_cast<const Flag* const*
>(
left);
429 const Flag* right_flag = *
reinterpret_cast<const Flag* const*
>(
right);
430 return strcmp(left_flag->name_, right_flag->name_);
434 const char** vm_flags) {
439 qsort(flags_, num_flags_,
sizeof flags_[0], CompareFlagNames);
441 const char*
const kPrefix =
"--";
442 const intptr_t kPrefixLen = strlen(kPrefix);
445 while ((i < number_of_vm_flags) &&
447 const char* option = vm_flags[i] + kPrefixLen;
452 if (!FLAG_ignore_unrecognized_flags) {
453 int unrecognized_count = 0;
455 for (intptr_t j = 0; j < num_flags_; j++) {
457 if (
flag->IsUnrecognized()) {
458 if (unrecognized_count == 0) {
459 error.Printf(
"Unrecognized flags: %s",
flag->name_);
463 unrecognized_count++;
466 if (unrecognized_count > 0) {
467 return error.Steal();
470 if (FLAG_print_flags) {
480 if (
flag ==
nullptr) {
481 *
error =
"Cannot set flag: flag not found";
485 *
error =
"Cannot set flag: invalid value";
491void Flags::PrintFlags() {
493 for (intptr_t i = 0; i < num_flags_; ++i) {
499void Flags::PrintFlagToJSONArray(JSONArray* jsarr,
const Flag*
flag) {
500 if (
flag->IsUnrecognized()) {
503 JSONObject jsflag(jsarr);
504 jsflag.AddProperty(
"name",
flag->name_);
505 jsflag.AddProperty(
"comment",
flag->comment_);
506 jsflag.AddProperty(
"modified",
flag->changed_);
507 switch (
flag->type_) {
509 jsflag.AddProperty(
"_flagType",
"Bool");
510 jsflag.AddProperty(
"valueAsString",
511 (*
flag->bool_ptr_ ?
"true" :
"false"));
515 jsflag.AddProperty(
"_flagType",
"Int");
516 jsflag.AddPropertyF(
"valueAsString",
"%d", *
flag->int_ptr_);
520 jsflag.AddProperty(
"_flagType",
"UInt64");
521 jsflag.AddPropertyF(
"valueAsString",
"%" Pu64, *
flag->uint64_ptr_);
525 jsflag.AddProperty(
"_flagType",
"String");
526 if (
flag->charp_ptr_ !=
nullptr) {
527 jsflag.AddPropertyF(
"valueAsString",
"%s", *
flag->charp_ptr_);
534 jsflag.AddProperty(
"_flagType",
"Bool");
535 const char*
value =
flag->string_value_.get();
536 jsflag.AddProperty(
"valueAsString", value ==
nullptr ?
"false" :
value);
540 jsflag.AddProperty(
"_flagType",
"String");
541 if (
flag->string_value_ !=
nullptr) {
542 jsflag.AddProperty(
"valueAsString",
flag->string_value_.get());
558 for (intptr_t i = 0; i < num_flags_; ++i) {
559 PrintFlagToJSONArray(&jsarr, flags_[i]);
static bool equals(T *a, T *b)
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
FlagHandler flag_handler_
Flag(const char *name, const char *comment, OptionHandler handler)
Flag(const char *name, const char *comment, void *addr, FlagType type)
OptionHandler option_handler_
bool IsUnrecognized() const
Flag(const char *name, const char *comment, FlagHandler handler)
Utils::CStringUniquePtr string_value_
static bool RegisterOptionHandler(OptionHandler handler, const char *name, const char *comment)
static bool RegisterFlagHandler(FlagHandler handler, const char *name, const char *comment)
static Flag * Lookup(const char *name)
static uint64_t Register_uint64_t(uint64_t *addr, const char *name, uint64_t default_value, const char *comment)
static int Register_int(int *addr, const char *name, int default_value, const char *comment)
static char * ProcessCommandLineFlags(int argc, const char **argv)
static bool Register_bool(bool *addr, const char *name, bool default_value, const char *comment)
static bool SetFlag(const char *name, const char *value, const char **error)
static const char * Register_charp(charp *addr, const char *name, const char *default_value, const char *comment)
static void PrintJSON(JSONStream *js)
static bool IsSet(const char *name)
void AddProperty(const char *name, bool b) const
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static void Print(const char *format,...) PRINTF_ATTRIBUTE(1
static char * StrDup(const char *s)
static CStringUniquePtr CreateCStringUniquePtr(char *str)
std::unique_ptr< char, decltype(std::free) * > CStringUniquePtr
FlutterSemanticsFlag flag
const uint8_t uint32_t uint32_t GError ** error
#define FLAG_LIST(P, R, C, D)
#define DEBUG_FLAG_MACRO(name, type, default_value, comment)
#define PRECOMPILE_FLAG_MACRO(name, pre_value, product_value, type, default_value, comment)
#define RELEASE_FLAG_MACRO(name, product_value, type, default_value, comment)
#define PRODUCT_FLAG_MACRO(name, type, default_value, comment)
#define DEFINE_FLAG(type, name, default_value, comment)
void(* FlagHandler)(bool value)
void(* OptionHandler)(const char *value)
static void Normalize(char *s)
static bool IsValidFlag(const char *name, const char *prefix, intptr_t prefix_length)