summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/gn/args.cc18
-rw-r--r--tools/gn/function_toolchain.cc6
-rw-r--r--tools/gn/functions.cc10
-rw-r--r--tools/gn/operators.cc49
-rw-r--r--tools/gn/parse_tree.cc14
-rw-r--r--tools/gn/parser.cc2
-rw-r--r--tools/gn/secondary/build/config/BUILDCONFIG.gn18
-rw-r--r--tools/gn/secondary/build/toolchain/nacl/BUILD.gn14
-rw-r--r--tools/gn/string_utils_unittest.cc3
-rw-r--r--tools/gn/token.h2
-rw-r--r--tools/gn/tokenizer.cc6
-rw-r--r--tools/gn/value.cc40
-rw-r--r--tools/gn/value.h20
13 files changed, 127 insertions, 75 deletions
diff --git a/tools/gn/args.cc b/tools/gn/args.cc
index d60f1e7..d340713 100644
--- a/tools/gn/args.cc
+++ b/tools/gn/args.cc
@@ -25,7 +25,7 @@ const char kBuildArgs_Help[] =
" applied. These can override the system default ones, and add new ones.\n"
" These are whitespace-separated. For example:\n"
"\n"
- " gn --args=\"teleportation_level=3 is_win=1 is_evil=0\"\n"
+ " gn --args=\"is_win=true enable_doom_melon=false\"\n"
"\n"
" Third, toolchain overrides are applied. These are specified in the\n"
" toolchain_args section of a toolchain definition. The use-case for\n"
@@ -145,11 +145,11 @@ bool Args::VerifyAllOverridesUsed(Err* err) const {
void Args::SetSystemVars(Scope* dest) const {
#if defined(OS_WIN)
- Value is_win(NULL, 1);
- Value is_posix(NULL, 0);
+ Value is_win(NULL, true);
+ Value is_posix(NULL, false);
#else
- Value is_win(NULL, 0);
- Value is_posix(NULL, 1);
+ Value is_win(NULL, false);
+ Value is_posix(NULL, true);
#endif
dest->SetValue(variables::kIsWin, is_win, NULL);
dest->SetValue(variables::kIsPosix, is_posix, NULL);
@@ -157,17 +157,17 @@ void Args::SetSystemVars(Scope* dest) const {
declared_arguments_[variables::kIsPosix] = is_posix;
#if defined(OS_MACOSX)
- Value is_mac(NULL, 1);
+ Value is_mac(NULL, true);
#else
- Value is_mac(NULL, 0);
+ Value is_mac(NULL, false);
#endif
dest->SetValue(variables::kIsMac, is_mac, NULL);
declared_arguments_[variables::kIsMac] = is_mac;
#if defined(OS_LINUX)
- Value is_linux(NULL, 1);
+ Value is_linux(NULL, true);
#else
- Value is_linux(NULL, 0);
+ Value is_linux(NULL, false);
#endif
dest->SetValue(variables::kIsLinux, is_linux, NULL);
declared_arguments_[variables::kIsLinux] = is_linux;
diff --git a/tools/gn/function_toolchain.cc b/tools/gn/function_toolchain.cc
index 8bb3065..63aa3c2 100644
--- a/tools/gn/function_toolchain.cc
+++ b/tools/gn/function_toolchain.cc
@@ -166,11 +166,11 @@ extern const char kToolchainArgs_Help[] =
" ...\n"
" toolchain_args() {\n"
" # Override the system values for a generic Posix system.\n"
- " is_win = 0\n"
- " is_posix = 1\n"
+ " is_win = false\n"
+ " is_posix = true\n"
"\n"
" # Pass this new value for specific setup for my toolchain.\n"
- " is_my_weird_system = 1\n"
+ " is_my_weird_system = true\n"
" }\n"
" }\n";
diff --git a/tools/gn/functions.cc b/tools/gn/functions.cc
index 2da5ef5..11608ef 100644
--- a/tools/gn/functions.cc
+++ b/tools/gn/functions.cc
@@ -166,7 +166,9 @@ Value RunAssert(Scope* scope,
*err = Err(function->function(), "Wrong number of arguments.",
"assert() takes one argument, "
"were you expecting somethig else?");
- } else if (args[0].InterpretAsInt() == 0) {
+ } else if (args[0].type() != Value::BOOLEAN) {
+ *err = Err(function->function(), "Assertion value not a bool.");
+ } else if (!args[0].boolean_value()) {
*err = Err(function->function(), "Assertion failed.");
if (args[0].origin()) {
// If you do "assert(foo)" we'd ideally like to show you where foo was
@@ -248,12 +250,12 @@ const char kDeclareArgs_Help[] =
"\n"
"Example:\n"
" declare_args() {\n"
- " enable_teleporter = 1\n"
- " enable_doom_melon = 0\n"
+ " enable_teleporter = true\n"
+ " enable_doom_melon = false\n"
" }\n"
"\n"
" If you want to override the (default disabled) Doom Melon:\n"
- " gn --args=\"enable_doom_melon=1 enable-teleporter=1\"\n"
+ " gn --args=\"enable_doom_melon=true enable_teleporter=false\"\n"
" This also sets the teleporter, but it's already defaulted to on so\n"
" it will have no effect.\n";
diff --git a/tools/gn/operators.cc b/tools/gn/operators.cc
index 9cc0de3..0e91f6b 100644
--- a/tools/gn/operators.cc
+++ b/tools/gn/operators.cc
@@ -56,6 +56,7 @@ void RemoveMatchesFromList(const BinaryOpNode* op_node,
Err* err) {
std::vector<Value>& v = list->list_value();
switch (to_remove.type()) {
+ case Value::BOOLEAN:
case Value::INTEGER: // Filter out the individual int/string.
case Value::STRING: {
bool found_match = false;
@@ -342,8 +343,8 @@ Value ExecuteEqualsEquals(Scope* scope,
const Value& right,
Err* err) {
if (left == right)
- return Value(op_node, 1);
- return Value(op_node, 0);
+ return Value(op_node, true);
+ return Value(op_node, false);
}
Value ExecuteNotEquals(Scope* scope,
@@ -357,10 +358,10 @@ Value ExecuteNotEquals(Scope* scope,
return result;
}
-Value FillNeedsToIntegersError(const BinaryOpNode* op_node,
- const Value& left,
- const Value& right,
- Err* err) {
+Value FillNeedsTwoIntegersError(const BinaryOpNode* op_node,
+ const Value& left,
+ const Value& right,
+ Err* err) {
*err = Err(op_node, "Comparison requires two integers.",
"This operator can only compare two integers.");
err->AppendRange(left.origin()->GetRange());
@@ -374,7 +375,7 @@ Value ExecuteLessEquals(Scope* scope,
const Value& right,
Err* err) {
if (left.type() != Value::INTEGER || right.type() != Value::INTEGER)
- return FillNeedsToIntegersError(op_node, left, right, err);
+ return FillNeedsTwoIntegersError(op_node, left, right, err);
return Value(op_node, left.int_value() <= right.int_value());
}
@@ -384,7 +385,7 @@ Value ExecuteGreaterEquals(Scope* scope,
const Value& right,
Err* err) {
if (left.type() != Value::INTEGER || right.type() != Value::INTEGER)
- return FillNeedsToIntegersError(op_node, left, right, err);
+ return FillNeedsTwoIntegersError(op_node, left, right, err);
return Value(op_node, left.int_value() >= right.int_value());
}
@@ -394,7 +395,7 @@ Value ExecuteGreater(Scope* scope,
const Value& right,
Err* err) {
if (left.type() != Value::INTEGER || right.type() != Value::INTEGER)
- return FillNeedsToIntegersError(op_node, left, right, err);
+ return FillNeedsTwoIntegersError(op_node, left, right, err);
return Value(op_node, left.int_value() > right.int_value());
}
@@ -404,7 +405,7 @@ Value ExecuteLess(Scope* scope,
const Value& right,
Err* err) {
if (left.type() != Value::INTEGER || right.type() != Value::INTEGER)
- return FillNeedsToIntegersError(op_node, left, right, err);
+ return FillNeedsTwoIntegersError(op_node, left, right, err);
return Value(op_node, left.int_value() < right.int_value());
}
@@ -415,8 +416,14 @@ Value ExecuteOr(Scope* scope,
const Value& left,
const Value& right,
Err* err) {
- return Value(op_node,
- static_cast<int64>(left.InterpretAsInt() || right.InterpretAsInt()));
+ if (left.type() != Value::BOOLEAN) {
+ *err = Err(left, "Left side of || operator is not a boolean.");
+ err->AppendRange(op_node->GetRange());
+ } else if (right.type() != Value::BOOLEAN) {
+ *err = Err(right, "Right side of || operator is not a boolean.");
+ err->AppendRange(op_node->GetRange());
+ }
+ return Value(op_node, left.boolean_value() || right.boolean_value());
}
Value ExecuteAnd(Scope* scope,
@@ -424,8 +431,14 @@ Value ExecuteAnd(Scope* scope,
const Value& left,
const Value& right,
Err* err) {
- return Value(op_node,
- static_cast<int64>(left.InterpretAsInt() && right.InterpretAsInt()));
+ if (left.type() != Value::BOOLEAN) {
+ *err = Err(left, "Left side of && operator is not a boolean.");
+ err->AppendRange(op_node->GetRange());
+ } else if (right.type() != Value::BOOLEAN) {
+ *err = Err(right, "Right side of && operator is not a boolean.");
+ err->AppendRange(op_node->GetRange());
+ }
+ return Value(op_node, left.boolean_value() && right.boolean_value());
}
} // namespace
@@ -473,8 +486,14 @@ Value ExecuteUnaryOperator(Scope* scope,
const Value& expr,
Err* err) {
DCHECK(op_node->op().type() == Token::BANG);
+
+ if (expr.type() != Value::BOOLEAN) {
+ *err = Err(expr, "Operand of ! operator is not a boolean.");
+ err->AppendRange(op_node->GetRange());
+ return Value();
+ }
// TODO(scottmg): Why no unary minus?
- return Value(op_node, !expr.InterpretAsInt());
+ return Value(op_node, !expr.boolean_value());
}
Value ExecuteBinaryOperator(Scope* scope,
diff --git a/tools/gn/parse_tree.cc b/tools/gn/parse_tree.cc
index 613c797..24c477d 100644
--- a/tools/gn/parse_tree.cc
+++ b/tools/gn/parse_tree.cc
@@ -218,15 +218,17 @@ Value ConditionNode::Execute(Scope* scope, Err* err) const {
Value condition_result = condition_->Execute(scope, err);
if (err->has_error())
return Value();
- if (condition_result.type() == Value::NONE) {
+ if (condition_result.type() != Value::BOOLEAN) {
*err = condition_->MakeErrorDescribing(
- "This does not evaluate to a value.",
- "Please give me something to work with for the if statement.");
+ "Condition does not evaluate to a boolean value.",
+ std::string("This is a value of type \"") +
+ Value::DescribeType(condition_result.type()) +
+ "\" instead.");
err->AppendRange(if_token_.range());
return Value();
}
- if (condition_result.InterpretAsInt()) {
+ if (condition_result.boolean_value()) {
if_true_->ExecuteBlockInScope(scope, err);
} else if (if_false_) {
// The else block is optional. It's either another condition (for an
@@ -402,6 +404,10 @@ const LiteralNode* LiteralNode::AsLiteral() const {
Value LiteralNode::Execute(Scope* scope, Err* err) const {
switch (value_.type()) {
+ case Token::TRUE_TOKEN:
+ return Value(this, true);
+ case Token::FALSE_TOKEN:
+ return Value(this, false);
case Token::INTEGER: {
int64 result_int;
if (!base::StringToInt64(value_.value(), &result_int)) {
diff --git a/tools/gn/parser.cc b/tools/gn/parser.cc
index 567d846..e507dfb 100644
--- a/tools/gn/parser.cc
+++ b/tools/gn/parser.cc
@@ -57,6 +57,8 @@ ParserHelper Parser::expressions_[] = {
{NULL, NULL, -1}, // INVALID
{&Parser::Literal, NULL, -1}, // INTEGER
{&Parser::Literal, NULL, -1}, // STRING
+ {&Parser::Literal, NULL, -1}, // TRUE_TOKEN
+ {&Parser::Literal, NULL, -1}, // FALSE_TOKEN
{NULL, &Parser::Assignment, PRECEDENCE_ASSIGNMENT}, // EQUAL
{NULL, &Parser::BinaryOperator, PRECEDENCE_SUM}, // PLUS
{NULL, &Parser::BinaryOperator, PRECEDENCE_SUM}, // MINUS
diff --git a/tools/gn/secondary/build/config/BUILDCONFIG.gn b/tools/gn/secondary/build/config/BUILDCONFIG.gn
index 2bca156..78df4e7 100644
--- a/tools/gn/secondary/build/config/BUILDCONFIG.gn
+++ b/tools/gn/secondary/build/config/BUILDCONFIG.gn
@@ -18,29 +18,29 @@
# "use_*" names for optional features libraries, and configurations.
declare_args() {
# Set to build the Android version.
- is_android = 0
+ is_android = false
# Component build.
- is_component_build = 1
+ is_component_build = true
# ChromeOS build.
- is_chromeos = 0
+ is_chromeos = false
# Debug build.
- is_debug = 1
+ is_debug = true
# Hello, world
# IOS build.
- is_ios = 0
+ is_ios = false
# Set when building with the "untrusted" Native Client toolchain.
#
# Do not set directly, this will be set automatically when compiling targets
# with a NaCl toolchain.
- is_nacl = 0
+ is_nacl = false
# ASH is enabled.
- use_ash = 0
+ use_ash = false
# Aura is enabled.
- use_aura = 0
+ use_aura = false
# Ozone is enabled.
- use_ozone = 0
+ use_ozone = false
}
# =============================================================================
diff --git a/tools/gn/secondary/build/toolchain/nacl/BUILD.gn b/tools/gn/secondary/build/toolchain/nacl/BUILD.gn
index 75c132b..2e2fc7f 100644
--- a/tools/gn/secondary/build/toolchain/nacl/BUILD.gn
+++ b/tools/gn/secondary/build/toolchain/nacl/BUILD.gn
@@ -39,17 +39,17 @@ toolchain("x86_newlib") {
}
toolchain_args() {
- is_nacl = 1
+ is_nacl = true
# Component build not supported in NaCl, since it does not support shared
# libraries.
- is_component_build = 0
+ is_component_build = false
# Override the default OS detection.
- is_android = 0
- is_mac = 0
- is_posix = 1
- is_linux = 0
- is_win = 0
+ is_android = false
+ is_mac = false
+ is_posix = true
+ is_linux = false
+ is_win = false
}
}
diff --git a/tools/gn/string_utils_unittest.cc b/tools/gn/string_utils_unittest.cc
index 81181d2..9e69d40 100644
--- a/tools/gn/string_utils_unittest.cc
+++ b/tools/gn/string_utils_unittest.cc
@@ -14,7 +14,8 @@ namespace {
bool CheckExpansionCase(const char* input, const char* expected, bool success) {
Scope scope(static_cast<const Settings*>(NULL));
- scope.SetValue("one", Value(NULL, 1), NULL);
+ int64 one = 1;
+ scope.SetValue("one", Value(NULL, one), NULL);
scope.SetValue("onestring", Value(NULL, "one"), NULL);
// Construct the string token, which includes the quotes.
diff --git a/tools/gn/token.h b/tools/gn/token.h
index 4af7e62..25f176b 100644
--- a/tools/gn/token.h
+++ b/tools/gn/token.h
@@ -14,6 +14,8 @@ class Token {
INVALID,
INTEGER, // 123
STRING, // "blah"
+ TRUE_TOKEN, // Not "TRUE" to avoid collisions with #define in windows.h.
+ FALSE_TOKEN,
// Various operators.
EQUAL,
diff --git a/tools/gn/tokenizer.cc b/tools/gn/tokenizer.cc
index 6051e1b..6771927 100644
--- a/tools/gn/tokenizer.cc
+++ b/tools/gn/tokenizer.cc
@@ -115,8 +115,12 @@ std::vector<Token> Tokenizer::Run() {
if (type == Token::IDENTIFIER) {
if (token_value == "if")
type = Token::IF;
- if (token_value == "else")
+ else if (token_value == "else")
type = Token::ELSE;
+ else if (token_value == "true")
+ type = Token::TRUE_TOKEN;
+ else if (token_value == "false")
+ type = Token::FALSE_TOKEN;
}
// TODO(brettw) This just strips comments from the token stream. This
diff --git a/tools/gn/value.cc b/tools/gn/value.cc
index 5a595d0..a8abee4 100644
--- a/tools/gn/value.cc
+++ b/tools/gn/value.cc
@@ -18,15 +18,31 @@ Value::Value(const ParseNode* origin, Type t)
origin_(origin) {
}
+Value::Value(const ParseNode* origin, bool bool_val)
+ : type_(BOOLEAN),
+ boolean_value_(bool_val),
+ int_value_(0),
+ origin_(origin) {
+}
+
Value::Value(const ParseNode* origin, int64 int_val)
: type_(INTEGER),
+ boolean_value_(false),
int_value_(int_val),
origin_(origin) {
}
-Value::Value(const ParseNode* origin, const base::StringPiece& str_val)
+Value::Value(const ParseNode* origin, std::string str_val)
+ : type_(STRING),
+ string_value_(),
+ int_value_(0),
+ origin_(origin) {
+ string_value_.swap(str_val);
+}
+
+Value::Value(const ParseNode* origin, const char* str_val)
: type_(STRING),
- string_value_(str_val.as_string()),
+ string_value_(str_val),
int_value_(0),
origin_(origin) {
}
@@ -39,6 +55,8 @@ const char* Value::DescribeType(Type t) {
switch (t) {
case NONE:
return "none";
+ case BOOLEAN:
+ return "boolean";
case INTEGER:
return "integer";
case STRING:
@@ -51,24 +69,12 @@ const char* Value::DescribeType(Type t) {
}
}
-int64 Value::InterpretAsInt() const {
- switch (type_) {
- case NONE:
- return 0;
- case INTEGER:
- return int_value_;
- case STRING:
- return string_value_.empty() ? 0 : 1;
- case LIST:
- return list_value_.empty() ? 0 : 1;
- }
- return 0;
-}
-
std::string Value::ToString(bool quote_string) const {
switch (type_) {
case NONE:
return "<void>";
+ case BOOLEAN:
+ return boolean_value_ ? "true" : "false";
case INTEGER:
return base::Int64ToString(int_value_);
case STRING:
@@ -102,6 +108,8 @@ bool Value::operator==(const Value& other) const {
return false;
switch (type_) {
+ case Value::BOOLEAN:
+ return boolean_value() == other.boolean_value();
case Value::INTEGER:
return int_value() == other.int_value();
case Value::STRING:
diff --git a/tools/gn/value.h b/tools/gn/value.h
index c987b6c..952f52a 100644
--- a/tools/gn/value.h
+++ b/tools/gn/value.h
@@ -17,6 +17,7 @@ class Value {
public:
enum Type {
NONE = 0,
+ BOOLEAN,
INTEGER,
STRING,
LIST
@@ -24,8 +25,10 @@ class Value {
Value();
Value(const ParseNode* origin, Type t);
+ Value(const ParseNode* origin, bool bool_val);
Value(const ParseNode* origin, int64 int_val);
- Value(const ParseNode* origin, const base::StringPiece& str_val);
+ Value(const ParseNode* origin, std::string str_val);
+ Value(const ParseNode* origin, const char* str_val);
~Value();
Type type() const { return type_; }
@@ -37,6 +40,15 @@ class Value {
const ParseNode* origin() const { return origin_; }
void set_origin(const ParseNode* o) { origin_ = o; }
+ bool& boolean_value() {
+ DCHECK(type_ == BOOLEAN);
+ return boolean_value_;
+ }
+ const bool& boolean_value() const {
+ DCHECK(type_ == BOOLEAN);
+ return boolean_value_;
+ }
+
int64& int_value() {
DCHECK(type_ == INTEGER);
return int_value_;
@@ -64,11 +76,6 @@ class Value {
return list_value_;
}
- // Returns the current value converted to an int, normally used for
- // boolean operations. Undefined variables, empty lists, and empty strings
- // are all interpreted as 0, otherwise 1.
- int64 InterpretAsInt() const;
-
// Converts the given value to a string. Returns true if strings should be
// quoted or the ToString of a string should be the string itself.
std::string ToString(bool quote_strings) const;
@@ -84,6 +91,7 @@ class Value {
private:
Type type_;
std::string string_value_;
+ bool boolean_value_;
int64 int_value_;
std::vector<Value> list_value_;
const ParseNode* origin_;