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_
;
92 const char* Value::DescribeType(Type t
) {
112 void Value::SetScopeValue(scoped_ptr
<Scope
> scope
) {
113 DCHECK(type_
== SCOPE
);
114 scope_value_
= scope
.Pass();
117 std::string
Value::ToString(bool quote_string
) const {
122 return boolean_value_
? "true" : "false";
124 return base::Int64ToString(int_value_
);
127 std::string escaped
= string_value_
;
128 // First escape all special uses of a backslash.
129 ReplaceSubstringsAfterOffset(&escaped
, 0, "\\$", "\\\\$");
130 ReplaceSubstringsAfterOffset(&escaped
, 0, "\\\"", "\\\\\"");
132 // Now escape special chars.
133 ReplaceSubstringsAfterOffset(&escaped
, 0, "$", "\\$");
134 ReplaceSubstringsAfterOffset(&escaped
, 0, "\"", "\\\"");
135 return "\"" + escaped
+ "\"";
137 return string_value_
;
139 std::string result
= "[";
140 for (size_t i
= 0; i
< list_value_
.size(); i
++) {
143 result
+= list_value_
[i
].ToString(true);
145 result
.push_back(']');
149 Scope::KeyValueMap scope_values
;
150 scope_value_
->GetCurrentScopeValues(&scope_values
);
151 if (scope_values
.empty())
152 return std::string("{ }");
154 std::string result
= "{\n";
155 for (const auto& pair
: scope_values
) {
156 result
+= " " + pair
.first
.as_string() + " = " +
157 pair
.second
.ToString(true) + "\n";
164 return std::string();
167 bool Value::VerifyTypeIs(Type t
, Err
* err
) const {
172 std::string("This is not a ") + DescribeType(t
) + ".",
173 std::string("Instead I see a ") + DescribeType(type_
) + " = " +
178 bool Value::operator==(const Value
& other
) const {
179 if (type_
!= other
.type_
)
184 return boolean_value() == other
.boolean_value();
186 return int_value() == other
.int_value();
188 return string_value() == other
.string_value();
190 if (list_value().size() != other
.list_value().size())
192 for (size_t i
= 0; i
< list_value().size(); i
++) {
193 if (list_value()[i
] != other
.list_value()[i
])
198 // Scopes are always considered not equal because there's currently
199 // no use case for comparing them, and it requires a bunch of complex
207 bool Value::operator!=(const Value
& other
) const {
208 return !operator==(other
);