1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "tools/gn/value.h"
7 #include "base/strings/string_number_conversions.h"
8 #include "base/strings/string_util.h"
9 #include "tools/gn/scope.h"
13 boolean_value_(false),
18 Value::Value(const ParseNode* origin, Type t)
20 boolean_value_(false),
25 Value::Value(const ParseNode* origin, bool bool_val)
27 boolean_value_(bool_val),
32 Value::Value(const ParseNode* origin, int64 int_val)
34 boolean_value_(false),
39 Value::Value(const ParseNode* origin, std::string str_val)
42 boolean_value_(false),
45 string_value_.swap(str_val);
48 Value::Value(const ParseNode* origin, const char* str_val)
50 string_value_(str_val),
51 boolean_value_(false),
56 Value::Value(const ParseNode* origin, scoped_ptr<Scope> scope)
59 boolean_value_(false),
61 scope_value_(scope.Pass()),
65 Value::Value(const Value& other)
67 string_value_(other.string_value_),
68 boolean_value_(other.boolean_value_),
69 int_value_(other.int_value_),
70 list_value_(other.list_value_),
71 origin_(other.origin_) {
72 if (type() == SCOPE && other.scope_value_.get())
73 scope_value_ = other.scope_value_->MakeClosure();
79 Value& Value::operator=(const Value& other) {
81 string_value_ = other.string_value_;
82 boolean_value_ = other.boolean_value_;
83 int_value_ = other.int_value_;
84 list_value_ = other.list_value_;
85 if (type() == SCOPE && other.scope_value_.get())
86 scope_value_ = other.scope_value_->MakeClosure();
87 origin_ = other.origin_;
91 void Value::RecursivelySetOrigin(const ParseNode* origin) {
93 if (type_ == Value::LIST) {
94 for (size_t i = 0; i < list_value_.size(); i++)
95 list_value_[i].RecursivelySetOrigin(origin);
100 const char* Value::DescribeType(Type t) {
120 void Value::SetScopeValue(scoped_ptr<Scope> scope) {
121 DCHECK(type_ == SCOPE);
122 scope_value_ = scope.Pass();
125 std::string Value::ToString(bool quote_string) const {
130 return boolean_value_ ? "true" : "false";
132 return base::Int64ToString(int_value_);
135 std::string escaped = string_value_;
136 // First escape all special uses of a backslash.
137 ReplaceSubstringsAfterOffset(&escaped, 0, "\\$", "\\\\$");
138 ReplaceSubstringsAfterOffset(&escaped, 0, "\\\"", "\\\\\"");
140 // Now escape special chars.
141 ReplaceSubstringsAfterOffset(&escaped, 0, "$", "\\$");
142 ReplaceSubstringsAfterOffset(&escaped, 0, "\"", "\\\"");
143 return "\"" + escaped + "\"";
145 return string_value_;
147 std::string result = "[";
148 for (size_t i = 0; i < list_value_.size(); i++) {
151 result += list_value_[i].ToString(true);
153 result.push_back(']');
157 Scope::KeyValueMap scope_values;
158 scope_value_->GetCurrentScopeValues(&scope_values);
159 if (scope_values.empty())
160 return std::string("{ }");
162 std::string result = "{\n";
163 for (Scope::KeyValueMap::const_iterator i = scope_values.begin();
164 i != scope_values.end(); ++i) {
165 result += " " + i->first.as_string() + " = " +
166 i->second.ToString(true) + "\n";
173 return std::string();
176 bool Value::VerifyTypeIs(Type t, Err* err) const {
180 *err = Err(origin(), std::string("This is not a ") + DescribeType(t) + ".");
184 bool Value::operator==(const Value& other) const {
185 if (type_ != other.type_)
190 return boolean_value() == other.boolean_value();
192 return int_value() == other.int_value();
194 return string_value() == other.string_value();
196 if (list_value().size() != other.list_value().size())
198 for (size_t i = 0; i < list_value().size(); i++) {
199 if (list_value()[i] != other.list_value()[i])
204 // Scopes are always considered not equal because there's currently
205 // no use case for comparing them, and it requires a bunch of complex
213 bool Value::operator!=(const Value& other) const {
214 return !operator==(other);