OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "tools/gn/string_utils.h" | 5 #include "tools/gn/string_utils.h" |
6 | 6 |
7 #include "tools/gn/err.h" | 7 #include "tools/gn/err.h" |
8 #include "tools/gn/input_file.h" | 8 #include "tools/gn/input_file.h" |
9 #include "tools/gn/parser.h" | 9 #include "tools/gn/parser.h" |
10 #include "tools/gn/scope.h" | 10 #include "tools/gn/scope.h" |
11 #include "tools/gn/token.h" | 11 #include "tools/gn/token.h" |
12 #include "tools/gn/tokenizer.h" | 12 #include "tools/gn/tokenizer.h" |
13 #include "tools/gn/value.h" | 13 #include "tools/gn/value.h" |
14 | 14 |
15 namespace { | 15 namespace { |
16 | 16 |
17 // Constructs an Err indicating a range inside a string. We assume that the | 17 // Constructs an Err indicating a range inside a string. We assume that the |
18 // token has quotes around it that are not counted by the offset. | 18 // token has quotes around it that are not counted by the offset. |
19 Err ErrInsideStringToken(const Token& token, size_t offset, size_t size, | 19 Err ErrInsideStringToken(const Token& token, size_t offset, size_t size, |
20 const std::string& msg, | 20 const std::string& msg, |
21 const std::string& help = std::string()) { | 21 const std::string& help = std::string()) { |
22 // The "+1" is skipping over the " at the beginning of the token. | 22 // The "+1" is skipping over the " at the beginning of the token. |
23 int int_offset = static_cast<int>(offset); | 23 int int_offset = static_cast<int>(offset); |
24 Location begin_loc(token.location().file(), | 24 Location begin_loc(token.location().file(), |
25 token.location().line_number(), | 25 token.location().line_number(), |
26 token.location().char_offset() + int_offset + 1, | 26 token.location().column_number() + int_offset + 1, |
27 token.location().byte() + int_offset + 1); | 27 token.location().byte() + int_offset + 1); |
28 Location end_loc( | 28 Location end_loc( |
29 token.location().file(), | 29 token.location().file(), |
30 token.location().line_number(), | 30 token.location().line_number(), |
31 token.location().char_offset() + int_offset + 1 + static_cast<int>(size), | 31 token.location().column_number() + int_offset + 1 + |
| 32 static_cast<int>(size), |
32 token.location().byte() + int_offset + 1 + static_cast<int>(size)); | 33 token.location().byte() + int_offset + 1 + static_cast<int>(size)); |
33 return Err(LocationRange(begin_loc, end_loc), msg, help); | 34 return Err(LocationRange(begin_loc, end_loc), msg, help); |
34 } | 35 } |
35 | 36 |
36 // Notes about expression interpolation. This is based loosly on Dart but is | 37 // Notes about expression interpolation. This is based loosly on Dart but is |
37 // slightly less flexible. In Dart, seeing the ${ in a string is something | 38 // slightly less flexible. In Dart, seeing the ${ in a string is something |
38 // the toplevel parser knows about, and it will recurse into the block | 39 // the toplevel parser knows about, and it will recurse into the block |
39 // treating it as a first-class {...} block. So even things like this work: | 40 // treating it as a first-class {...} block. So even things like this work: |
40 // "hello ${"foo}"*2+"bar"}" => "hello foo}foo}bar" | 41 // "hello ${"foo}"*2+"bar"}" => "hello foo}foo}bar" |
41 // (you can see it did not get confused by the nested strings or the nested "}" | 42 // (you can see it did not get confused by the nested strings or the nested "}" |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 } else if (input[i] == '$') { | 236 } else if (input[i] == '$') { |
236 if (!AppendStringInterpolation(scope, literal, input, size, &i, | 237 if (!AppendStringInterpolation(scope, literal, input, size, &i, |
237 &output, err)) | 238 &output, err)) |
238 return false; | 239 return false; |
239 } else { | 240 } else { |
240 output.push_back(input[i]); | 241 output.push_back(input[i]); |
241 } | 242 } |
242 } | 243 } |
243 return true; | 244 return true; |
244 } | 245 } |
OLD | NEW |