Index: src/flags.cc |
diff --git a/src/flags.cc b/src/flags.cc |
index f7ae004ac26e2bf7e80583b0c4e87b19fdddb5ca..07a31c38fe35c05ed1b5d0b7977002f709d1abae 100644 |
--- a/src/flags.cc |
+++ b/src/flags.cc |
@@ -33,8 +33,15 @@ namespace { |
// to the actual flag, default value, comment, etc. This is designed to be POD |
// initialized as to avoid requiring static constructors. |
struct Flag { |
- enum FlagType { TYPE_BOOL, TYPE_MAYBE_BOOL, TYPE_INT, TYPE_FLOAT, |
- TYPE_STRING, TYPE_ARGS }; |
+ enum FlagType { |
+ TYPE_BOOL, |
+ TYPE_MAYBE_BOOL, |
+ TYPE_INT, |
+ TYPE_UINT, |
+ TYPE_FLOAT, |
+ TYPE_STRING, |
+ TYPE_ARGS |
+ }; |
FlagType type_; // What type of flag, bool, int, or string. |
const char* name_; // Name of the flag, ex "my_flag". |
@@ -64,6 +71,11 @@ struct Flag { |
return reinterpret_cast<int*>(valptr_); |
} |
+ unsigned int* uint_variable() const { |
+ DCHECK(type_ == TYPE_UINT); |
+ return reinterpret_cast<unsigned int*>(valptr_); |
+ } |
+ |
double* float_variable() const { |
DCHECK(type_ == TYPE_FLOAT); |
return reinterpret_cast<double*>(valptr_); |
@@ -97,6 +109,11 @@ struct Flag { |
return *reinterpret_cast<const int*>(defptr_); |
} |
+ unsigned int uint_default() const { |
+ DCHECK(type_ == TYPE_UINT); |
+ return *reinterpret_cast<const unsigned int*>(defptr_); |
+ } |
+ |
double float_default() const { |
DCHECK(type_ == TYPE_FLOAT); |
return *reinterpret_cast<const double*>(defptr_); |
@@ -121,6 +138,8 @@ struct Flag { |
return maybe_bool_variable()->has_value == false; |
case TYPE_INT: |
return *int_variable() == int_default(); |
+ case TYPE_UINT: |
+ return *uint_variable() == uint_default(); |
case TYPE_FLOAT: |
return *float_variable() == float_default(); |
case TYPE_STRING: { |
@@ -149,6 +168,9 @@ struct Flag { |
case TYPE_INT: |
*int_variable() = int_default(); |
break; |
+ case TYPE_UINT: |
+ *uint_variable() = uint_default(); |
+ break; |
case TYPE_FLOAT: |
*float_variable() = float_default(); |
break; |
@@ -177,6 +199,8 @@ static const char* Type2String(Flag::FlagType type) { |
case Flag::TYPE_BOOL: return "bool"; |
case Flag::TYPE_MAYBE_BOOL: return "maybe_bool"; |
case Flag::TYPE_INT: return "int"; |
+ case Flag::TYPE_UINT: |
+ return "uint"; |
case Flag::TYPE_FLOAT: return "float"; |
case Flag::TYPE_STRING: return "string"; |
case Flag::TYPE_ARGS: return "arguments"; |
@@ -199,6 +223,9 @@ std::ostream& operator<<(std::ostream& os, const Flag& flag) { // NOLINT |
case Flag::TYPE_INT: |
os << *flag.int_variable(); |
break; |
+ case Flag::TYPE_UINT: |
+ os << *flag.uint_variable(); |
+ break; |
case Flag::TYPE_FLOAT: |
os << *flag.float_variable(); |
break; |
@@ -399,6 +426,24 @@ int FlagList::SetFlagsFromCommandLine(int* argc, |
case Flag::TYPE_INT: |
*flag->int_variable() = static_cast<int>(strtol(value, &endp, 10)); |
break; |
+ case Flag::TYPE_UINT: { |
+ // We do not use strtoul because it accepts negative numbers. |
+ int64_t val = static_cast<int64_t>(strtoll(value, &endp, 10)); |
+ if (val < 0 || val > std::numeric_limits<unsigned int>::max()) { |
+ PrintF(stderr, |
+ "Error: Value for flag %s of type %s is out of bounds " |
+ "[0-%" PRIu64 |
+ "]\n" |
+ "Try --help for options\n", |
+ arg, Type2String(flag->type()), |
+ static_cast<uint64_t>( |
+ std::numeric_limits<unsigned int>::max())); |
+ return_code = j; |
+ break; |
+ } |
+ *flag->uint_variable() = static_cast<unsigned int>(val); |
+ break; |
+ } |
case Flag::TYPE_FLOAT: |
*flag->float_variable() = strtod(value, &endp); |
break; |