Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(338)

Side by Side Diff: tools/gn/file_template.cc

Issue 21114002: Add initial prototype for the GN meta-buildsystem. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add owners and readme Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/gn/file_template.h ('k') | tools/gn/file_template_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
5 #include "tools/gn/file_template.h"
6
7 #include "tools/gn/filesystem_utils.h"
8
9 const char FileTemplate::kSource[] = "{{source}}";
10 const char FileTemplate::kSourceNamePart[] = "{{source_name_part}}";
11
12 FileTemplate::FileTemplate(const Value& t, Err* err) {
13 ParseInput(t, err);
14 }
15
16 FileTemplate::FileTemplate(const std::vector<std::string>& t) {
17 for (size_t i = 0; i < t.size(); i++)
18 ParseOneTemplateString(t[i]);
19 }
20
21 FileTemplate::~FileTemplate() {
22 }
23
24 void FileTemplate::Apply(const Value& sources,
25 const ParseNode* origin,
26 std::vector<Value>* dest,
27 Err* err) const {
28 if (!sources.VerifyTypeIs(Value::LIST, err))
29 return;
30 dest->reserve(sources.list_value().size() * templates_.container().size());
31
32 // Temporary holding place, allocate outside to re-use- buffer.
33 std::vector<std::string> string_output;
34
35 const std::vector<Value>& sources_list = sources.list_value();
36 for (size_t i = 0; i < sources_list.size(); i++) {
37 if (!sources_list[i].VerifyTypeIs(Value::STRING, err))
38 return;
39
40 ApplyString(sources_list[i].string_value(), &string_output);
41 for (size_t out_i = 0; out_i < string_output.size(); out_i++)
42 dest->push_back(Value(origin, string_output[i]));
43 }
44 }
45
46 void FileTemplate::ApplyString(const std::string& str,
47 std::vector<std::string>* output) const {
48 // Compute all substitutions needed so we can just do substitutions below.
49 // We skip the LITERAL one since that varies each time.
50 std::string subst[Subrange::NUM_TYPES];
51 if (types_required_[Subrange::SOURCE])
52 subst[Subrange::SOURCE] = str;
53 if (types_required_[Subrange::NAME_PART])
54 subst[Subrange::NAME_PART] = FindFilenameNoExtension(&str).as_string();
55
56 output->resize(templates_.container().size());
57 for (size_t template_i = 0;
58 template_i < templates_.container().size(); template_i++) {
59 const Template& t = templates_[template_i];
60 (*output)[template_i].clear();
61 for (size_t subrange_i = 0; subrange_i < t.container().size();
62 subrange_i++) {
63 if (t[subrange_i].type == Subrange::LITERAL)
64 (*output)[template_i].append(t[subrange_i].literal);
65 else
66 (*output)[template_i].append(subst[t[subrange_i].type]);
67 }
68 }
69 }
70
71 void FileTemplate::ParseInput(const Value& value, Err* err) {
72 switch (value.type()) {
73 case Value::STRING:
74 ParseOneTemplateString(value.string_value());
75 break;
76 case Value::LIST:
77 for (size_t i = 0; i < value.list_value().size(); i++) {
78 if (!value.list_value()[i].VerifyTypeIs(Value::STRING, err))
79 return;
80 ParseOneTemplateString(value.list_value()[i].string_value());
81 }
82 break;
83 default:
84 *err = Err(value, "File template must be a string or list.",
85 "A sarcastic comment about your skills goes here.");
86 }
87 }
88
89 void FileTemplate::ParseOneTemplateString(const std::string& str) {
90 templates_.container().resize(templates_.container().size() + 1);
91 Template& t = templates_[templates_.container().size() - 1];
92
93 size_t cur = 0;
94 while (true) {
95 size_t next = str.find("{{", cur);
96
97 // Pick up everything from the previous spot to here as a literal.
98 if (next == std::string::npos) {
99 if (cur != str.size())
100 t.container().push_back(Subrange(Subrange::LITERAL, str.substr(cur)));
101 break;
102 } else if (next > cur) {
103 t.container().push_back(
104 Subrange(Subrange::LITERAL, str.substr(cur, next - cur)));
105 }
106
107 // Decode the template param.
108 if (str.compare(next, arraysize(kSource) - 1, kSource) == 0) {
109 t.container().push_back(Subrange(Subrange::SOURCE));
110 types_required_[Subrange::SOURCE] = true;
111 cur = next + arraysize(kSource) - 1;
112 } else if (str.compare(next, arraysize(kSourceNamePart) - 1,
113 kSourceNamePart) == 0) {
114 t.container().push_back(Subrange(Subrange::NAME_PART));
115 types_required_[Subrange::NAME_PART] = true;
116 cur = next + arraysize(kSourceNamePart) - 1;
117 } else {
118 // If it's not a match, treat it like a one-char literal (this will be
119 // rare, so it's not worth the bother to add to the previous literal) so
120 // we can keep going.
121 t.container().push_back(Subrange(Subrange::LITERAL, "{"));
122 cur = next + 1;
123 }
124 }
125 }
OLDNEW
« no previous file with comments | « tools/gn/file_template.h ('k') | tools/gn/file_template_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698