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 result
= "\"";
128 bool hanging_backslash
= false;
129 for (char ch
: string_value_
) {
130 // If the last character was a literal backslash and the next
131 // character could form a valid escape sequence, we need to insert
132 // an extra backslash to prevent that.
133 if (hanging_backslash
&& (ch
== '$' || ch
== '"' || ch
== '\\'))
135 // If the next character is a dollar sign or double quote, it needs
136 // to be escaped; otherwise it can be printed as is.
137 if (ch
== '$' || ch
== '"')
140 hanging_backslash
= (ch
== '\\');
142 // Again, we need to prevent the closing double quotes from becoming
143 // an escape sequence.
144 if (hanging_backslash
)
149 return string_value_
;
151 std::string result
= "[";
152 for (size_t i
= 0; i
< list_value_
.size(); i
++) {
155 result
+= list_value_
[i
].ToString(true);
157 result
.push_back(']');
161 Scope::KeyValueMap scope_values
;
162 scope_value_
->GetCurrentScopeValues(&scope_values
);
163 if (scope_values
.empty())
164 return std::string("{ }");
166 std::string result
= "{\n";
167 for (const auto& pair
: scope_values
) {
168 result
+= " " + pair
.first
.as_string() + " = " +
169 pair
.second
.ToString(true) + "\n";
176 return std::string();
179 bool Value::VerifyTypeIs(Type t
, Err
* err
) const {
184 std::string("This is not a ") + DescribeType(t
) + ".",
185 std::string("Instead I see a ") + DescribeType(type_
) + " = " +
190 bool Value::operator==(const Value
& other
) const {
191 if (type_
!= other
.type_
)
196 return boolean_value() == other
.boolean_value();
198 return int_value() == other
.int_value();
200 return string_value() == other
.string_value();
202 if (list_value().size() != other
.list_value().size())
204 for (size_t i
= 0; i
< list_value().size(); i
++) {
205 if (list_value()[i
] != other
.list_value()[i
])
210 // Scopes are always considered not equal because there's currently
211 // no use case for comparing them, and it requires a bunch of complex
219 bool Value::operator!=(const Value
& other
) const {
220 return !operator==(other
);