/src/CMake/Source/cmPkgConfigParser.cxx
Line | Count | Source |
1 | | /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
2 | | file LICENSE.rst or https://cmake.org/licensing for details. */ |
3 | | |
4 | | #include "cmPkgConfigParser.h" |
5 | | |
6 | | #include <algorithm> |
7 | | #include <cstddef> |
8 | | #include <set> |
9 | | #include <string> |
10 | | #include <unordered_map> |
11 | | #include <utility> |
12 | | #include <vector> |
13 | | |
14 | | #include <cmllpkgc/llpkgc.h> |
15 | | |
16 | | cmPkgConfigValueItem::cmPkgConfigValueItem(std::string text, |
17 | | bool isSubstitution) |
18 | 526k | : Text{ std::move(text) } |
19 | 526k | , IsSubstitution{ isSubstitution } |
20 | 526k | { |
21 | 526k | } |
22 | | |
23 | | cmPkgConfigEntry::cmPkgConfigEntry(std::vector<cmPkgConfigValueItem> value, |
24 | | std::string ident, |
25 | | cmPkgConfigEntryKind kind) |
26 | 550k | : Value{ std::move(value) } |
27 | 550k | , Ident{ std::move(ident) } |
28 | 550k | , Kind{ kind } |
29 | 550k | { |
30 | 550k | } |
31 | | |
32 | | cmPkgConfigFileParser::cmPkgConfigFileParser() |
33 | 59.7k | { |
34 | 59.7k | llpkgc_file_init(static_cast<llpkgc_file_t*>(this), &Settings_); |
35 | 59.7k | } |
36 | | |
37 | | cmPkgConfigFileParser::cmPkgConfigFileParser( |
38 | | cmPkgConfigFileParser const& other) |
39 | 13.7k | : cmPkgConfigFileParser() |
40 | 13.7k | { |
41 | 13.7k | *this = other; |
42 | 13.7k | } |
43 | | |
44 | | cmPkgConfigFileParser::cmPkgConfigFileParser( |
45 | | cmPkgConfigFileParser&& other) noexcept |
46 | 37.8k | : cmPkgConfigFileParser() |
47 | 37.8k | { |
48 | 37.8k | *this = std::move(other); |
49 | 37.8k | } |
50 | | |
51 | | cmPkgConfigFileParser& cmPkgConfigFileParser::operator=( |
52 | | cmPkgConfigFileParser const& other) |
53 | 13.7k | { |
54 | 13.7k | if (this != &other) { |
55 | 13.7k | this->ResetCallbacks(); |
56 | 13.7k | llpkgc_file_init(static_cast<llpkgc_file_t*>(this), &Settings_); |
57 | 13.7k | CurrentValue_.clear(); |
58 | 13.7k | Ident_ = other.Ident_; |
59 | 13.7k | Data_ = other.Data_; |
60 | 13.7k | } |
61 | 13.7k | return *this; |
62 | 13.7k | } |
63 | | |
64 | | cmPkgConfigFileParser& cmPkgConfigFileParser::operator=( |
65 | | cmPkgConfigFileParser&& other) noexcept |
66 | 37.8k | { |
67 | 37.8k | if (this != &other) { |
68 | 37.8k | this->ResetCallbacks(); |
69 | 37.8k | llpkgc_file_init(static_cast<llpkgc_file_t*>(this), &Settings_); |
70 | 37.8k | CurrentValue_.clear(); |
71 | 37.8k | Ident_ = std::move(other.Ident_); |
72 | 37.8k | Data_ = std::move(other.Data_); |
73 | 37.8k | } |
74 | 37.8k | return *this; |
75 | 37.8k | } |
76 | | |
77 | | void cmPkgConfigFileParser::ResetCallbacks() |
78 | 51.6k | { |
79 | 51.6k | Settings_.on_ident = OnIdentTr; |
80 | 51.6k | Settings_.on_value_literal = OnValueLiteralTr; |
81 | 51.6k | Settings_.on_value_substitution = OnValueSubstitutionTr; |
82 | 51.6k | Settings_.on_property_complete = OnPropertyCompleteTr; |
83 | 51.6k | Settings_.on_variable_complete = OnVariableCompleteTr; |
84 | 51.6k | Settings_.on_barewords_complete = OnBarewordsCompleteTr; |
85 | 51.6k | Settings_.on_value_literal_complete = OnValueLiteralCompleteTr; |
86 | 51.6k | Settings_.on_value_substitution_complete = OnValueSubstitutionCompleteTr; |
87 | 51.6k | Settings_.on_value_complete = OnValueCompleteTr; |
88 | 51.6k | Settings_.on_pkgc_complete = nullptr; |
89 | 51.6k | } |
90 | | |
91 | | llpkgc_file_errno_t cmPkgConfigFileParser::Parse(char const* input, |
92 | | std::size_t len) |
93 | 8.10k | { |
94 | 8.10k | return llpkgc_file_execute(static_cast<llpkgc_file_t*>(this), input, len); |
95 | 8.10k | } |
96 | | |
97 | | llpkgc_file_errno_t cmPkgConfigFileParser::Finish() |
98 | 8.10k | { |
99 | 8.10k | return llpkgc_file_finish(static_cast<llpkgc_file_t*>(this)); |
100 | 8.10k | } |
101 | | |
102 | | llpkgc_file_errno_t cmPkgConfigFileParser::GetErrno() const |
103 | 0 | { |
104 | 0 | return llpkgc_file_get_errno(static_cast<llpkgc_file_t const*>(this)); |
105 | 0 | } |
106 | | |
107 | | char const* cmPkgConfigFileParser::ErrorReason() const |
108 | 0 | { |
109 | 0 | return llpkgc_file_get_error_reason(static_cast<llpkgc_file_t const*>(this)); |
110 | 0 | } |
111 | | |
112 | | std::ptrdiff_t cmPkgConfigFileParser::ErrorOffset(char const* base) const |
113 | 0 | { |
114 | 0 | char const* pos = |
115 | 0 | llpkgc_file_get_error_pos(static_cast<llpkgc_file_t const*>(this)); |
116 | 0 | if (pos == nullptr) { |
117 | 0 | return -1; |
118 | 0 | } |
119 | 0 | return pos - base; |
120 | 0 | } |
121 | | |
122 | | int cmPkgConfigFileParser::OnIdentNext(char const* at, std::size_t len) |
123 | 28.2k | { |
124 | 28.2k | Ident_.append(at, len); |
125 | 28.2k | return 0; |
126 | 28.2k | } |
127 | | |
128 | | int cmPkgConfigFileParser::OnIdentNextTr(llpkgc_file_t* parser, char const* at, |
129 | | std::size_t len) |
130 | 28.2k | { |
131 | 28.2k | return static_cast<cmPkgConfigFileParser*>(parser)->OnIdentNext(at, len); |
132 | 28.2k | } |
133 | | |
134 | | void cmPkgConfigFileParser::AppendValue(std::string text, bool isSubstitution) |
135 | 939k | { |
136 | 939k | if (!isSubstitution && !Data_.empty() && !Data_.back().Value.empty() && |
137 | 652k | !Data_.back().Value.back().IsSubstitution) { |
138 | 454k | Data_.back().Value.back().Text += text; |
139 | 454k | return; |
140 | 454k | } |
141 | | |
142 | 485k | Data_.back().Value.emplace_back(std::move(text), isSubstitution); |
143 | 485k | } |
144 | | |
145 | | int cmPkgConfigFileParser::OnSpanNext(char const* at, std::size_t len) |
146 | 0 | { |
147 | 0 | CurrentValue_.append(at, len); |
148 | 0 | return 0; |
149 | 0 | } |
150 | | |
151 | | int cmPkgConfigFileParser::OnSpanNextTr(llpkgc_file_t* parser, char const* at, |
152 | | std::size_t len) |
153 | 0 | { |
154 | 0 | return static_cast<cmPkgConfigFileParser*>(parser)->OnSpanNext(at, len); |
155 | 0 | } |
156 | | |
157 | | int cmPkgConfigFileParser::OnIdent(char const* at, std::size_t len) |
158 | 550k | { |
159 | 550k | Ident_.assign(at, len); |
160 | 550k | Settings_.on_ident = OnIdentNextTr; |
161 | 550k | return 0; |
162 | 550k | } |
163 | | |
164 | | int cmPkgConfigFileParser::OnIdentTr(llpkgc_file_t* parser, char const* at, |
165 | | std::size_t len) |
166 | 550k | { |
167 | 550k | return static_cast<cmPkgConfigFileParser*>(parser)->OnIdent(at, len); |
168 | 550k | } |
169 | | |
170 | | int cmPkgConfigFileParser::OnPropertyComplete() |
171 | 188k | { |
172 | 188k | Data_.emplace_back(std::vector<cmPkgConfigValueItem>{}, Ident_, |
173 | 188k | cmPkgConfigEntryKind::Property); |
174 | 188k | Settings_.on_ident = OnIdentTr; |
175 | 188k | return 0; |
176 | 188k | } |
177 | | |
178 | | int cmPkgConfigFileParser::OnPropertyCompleteTr(llpkgc_file_t* parser) |
179 | 188k | { |
180 | 188k | return static_cast<cmPkgConfigFileParser*>(parser)->OnPropertyComplete(); |
181 | 188k | } |
182 | | |
183 | | int cmPkgConfigFileParser::OnVariableComplete() |
184 | 163k | { |
185 | 163k | Data_.emplace_back(std::vector<cmPkgConfigValueItem>{}, Ident_, |
186 | 163k | cmPkgConfigEntryKind::Variable); |
187 | 163k | Settings_.on_ident = OnIdentTr; |
188 | 163k | return 0; |
189 | 163k | } |
190 | | |
191 | | int cmPkgConfigFileParser::OnVariableCompleteTr(llpkgc_file_t* parser) |
192 | 163k | { |
193 | 163k | return static_cast<cmPkgConfigFileParser*>(parser)->OnVariableComplete(); |
194 | 163k | } |
195 | | |
196 | | int cmPkgConfigFileParser::OnBarewordsComplete() |
197 | 198k | { |
198 | 198k | Data_.emplace_back(std::vector<cmPkgConfigValueItem>{}, Ident_, |
199 | 198k | cmPkgConfigEntryKind::Barewords); |
200 | 198k | Settings_.on_ident = OnIdentTr; |
201 | 198k | return 0; |
202 | 198k | } |
203 | | |
204 | | int cmPkgConfigFileParser::OnBarewordsCompleteTr(llpkgc_file_t* parser) |
205 | 198k | { |
206 | 198k | return static_cast<cmPkgConfigFileParser*>(parser)->OnBarewordsComplete(); |
207 | 198k | } |
208 | | |
209 | | int cmPkgConfigFileParser::OnValueLiteral(char const* at, std::size_t len) |
210 | 720k | { |
211 | 720k | CurrentValue_.assign(at, len); |
212 | 720k | Settings_.on_value_literal = OnSpanNextTr; |
213 | 720k | return 0; |
214 | 720k | } |
215 | | |
216 | | int cmPkgConfigFileParser::OnValueLiteralTr(llpkgc_file_t* parser, |
217 | | char const* at, std::size_t len) |
218 | 720k | { |
219 | 720k | return static_cast<cmPkgConfigFileParser*>(parser)->OnValueLiteral(at, len); |
220 | 720k | } |
221 | | |
222 | | int cmPkgConfigFileParser::OnValueLiteralComplete() |
223 | 720k | { |
224 | 720k | Settings_.on_value_literal = OnValueLiteralTr; |
225 | 720k | AppendValue(std::move(CurrentValue_), false); |
226 | 720k | return 0; |
227 | 720k | } |
228 | | |
229 | | int cmPkgConfigFileParser::OnValueLiteralCompleteTr(llpkgc_file_t* parser) |
230 | 720k | { |
231 | 720k | return static_cast<cmPkgConfigFileParser*>(parser)->OnValueLiteralComplete(); |
232 | 720k | } |
233 | | |
234 | | int cmPkgConfigFileParser::OnValueSubstitution(char const* at, std::size_t len) |
235 | 219k | { |
236 | 219k | CurrentValue_.assign(at, len); |
237 | 219k | Settings_.on_value_substitution = OnSpanNextTr; |
238 | 219k | return 0; |
239 | 219k | } |
240 | | |
241 | | int cmPkgConfigFileParser::OnValueSubstitutionTr(llpkgc_file_t* parser, |
242 | | char const* at, |
243 | | std::size_t len) |
244 | 219k | { |
245 | 219k | return static_cast<cmPkgConfigFileParser*>(parser)->OnValueSubstitution(at, |
246 | 219k | len); |
247 | 219k | } |
248 | | |
249 | | int cmPkgConfigFileParser::OnValueSubstitutionComplete() |
250 | 219k | { |
251 | 219k | Settings_.on_value_substitution = OnValueSubstitutionTr; |
252 | 219k | AppendValue(std::move(CurrentValue_), true); |
253 | 219k | return 0; |
254 | 219k | } |
255 | | |
256 | | int cmPkgConfigFileParser::OnValueSubstitutionCompleteTr(llpkgc_file_t* parser) |
257 | 219k | { |
258 | 219k | return static_cast<cmPkgConfigFileParser*>(parser) |
259 | 219k | ->OnValueSubstitutionComplete(); |
260 | 219k | } |
261 | | |
262 | | int cmPkgConfigFileParser::OnValueComplete() |
263 | 549k | { |
264 | 549k | return 0; |
265 | 549k | } |
266 | | |
267 | | int cmPkgConfigFileParser::OnValueCompleteTr(llpkgc_file_t* parser) |
268 | 549k | { |
269 | 549k | return static_cast<cmPkgConfigFileParser*>(parser)->OnValueComplete(); |
270 | 549k | } |
271 | | |
272 | | cmPkgConfigFragmentParser::cmPkgConfigFragmentParser() |
273 | 3.89k | { |
274 | 3.89k | llpkgc_frag_init(static_cast<llpkgc_frag_t*>(this), &Settings_); |
275 | 3.89k | } |
276 | | |
277 | | llpkgc_frag_errno_t cmPkgConfigFragmentParser::Parse(char const* input, |
278 | | std::size_t len) |
279 | 3.89k | { |
280 | 3.89k | return llpkgc_frag_execute(static_cast<llpkgc_frag_t*>(this), input, len); |
281 | 3.89k | } |
282 | | |
283 | | llpkgc_frag_errno_t cmPkgConfigFragmentParser::Finish() |
284 | 3.89k | { |
285 | 3.89k | return llpkgc_frag_finish(static_cast<llpkgc_frag_t*>(this)); |
286 | 3.89k | } |
287 | | |
288 | | llpkgc_frag_errno_t cmPkgConfigFragmentParser::GetErrno() const |
289 | 0 | { |
290 | 0 | return llpkgc_frag_get_errno(static_cast<llpkgc_frag_t const*>(this)); |
291 | 0 | } |
292 | | |
293 | | char const* cmPkgConfigFragmentParser::ErrorReason() const |
294 | 0 | { |
295 | 0 | return llpkgc_frag_get_error_reason(static_cast<llpkgc_frag_t const*>(this)); |
296 | 0 | } |
297 | | |
298 | | int cmPkgConfigFragmentParser::OnFragmentText(char const* at, std::size_t len) |
299 | 48.3M | { |
300 | 48.3M | CurrentFragment_.append(at, len); |
301 | 48.3M | return 0; |
302 | 48.3M | } |
303 | | |
304 | | int cmPkgConfigFragmentParser::OnFragmentTextTr(llpkgc_frag_t* parser, |
305 | | char const* at, |
306 | | std::size_t len) |
307 | 48.3M | { |
308 | 48.3M | return static_cast<cmPkgConfigFragmentParser*>(parser)->OnFragmentText(at, |
309 | 48.3M | len); |
310 | 48.3M | } |
311 | | |
312 | | int cmPkgConfigFragmentParser::OnFragmentComplete() |
313 | 44.9M | { |
314 | 44.9M | Fragments_.push_back(std::move(CurrentFragment_)); |
315 | 44.9M | CurrentFragment_.clear(); |
316 | 44.9M | return 0; |
317 | 44.9M | } |
318 | | |
319 | | int cmPkgConfigFragmentParser::OnFragmentCompleteTr(llpkgc_frag_t* parser) |
320 | 44.9M | { |
321 | 44.9M | return static_cast<cmPkgConfigFragmentParser*>(parser)->OnFragmentComplete(); |
322 | 44.9M | } |
323 | | |
324 | | cmPkgConfigDependencyParser::cmPkgConfigDependencyParser() |
325 | 2.94k | { |
326 | 2.94k | llpkgc_dep_init(static_cast<llpkgc_dep_t*>(this), &Settings_); |
327 | 2.94k | } |
328 | | |
329 | | llpkgc_dep_errno_t cmPkgConfigDependencyParser::Parse(char const* input, |
330 | | std::size_t len) |
331 | 2.94k | { |
332 | 2.94k | return llpkgc_dep_execute(static_cast<llpkgc_dep_t*>(this), input, len); |
333 | 2.94k | } |
334 | | |
335 | | llpkgc_dep_errno_t cmPkgConfigDependencyParser::Finish() |
336 | 2.94k | { |
337 | 2.94k | return llpkgc_dep_finish(static_cast<llpkgc_dep_t*>(this)); |
338 | 2.94k | } |
339 | | |
340 | | llpkgc_dep_errno_t cmPkgConfigDependencyParser::GetErrno() const |
341 | 0 | { |
342 | 0 | return llpkgc_dep_get_errno(static_cast<llpkgc_dep_t const*>(this)); |
343 | 0 | } |
344 | | |
345 | | char const* cmPkgConfigDependencyParser::ErrorReason() const |
346 | 0 | { |
347 | 0 | return llpkgc_dep_get_error_reason(static_cast<llpkgc_dep_t const*>(this)); |
348 | 0 | } |
349 | | |
350 | | int cmPkgConfigDependencyParser::OnDependencyName(char const* at, |
351 | | std::size_t len) |
352 | 34.6M | { |
353 | 34.6M | Current_.Name.append(at, len); |
354 | 34.6M | return 0; |
355 | 34.6M | } |
356 | | |
357 | | int cmPkgConfigDependencyParser::OnDependencyNameTr(llpkgc_dep_t* parser, |
358 | | char const* at, |
359 | | std::size_t len) |
360 | 34.6M | { |
361 | 34.6M | return static_cast<cmPkgConfigDependencyParser*>(parser)->OnDependencyName( |
362 | 34.6M | at, len); |
363 | 34.6M | } |
364 | | |
365 | | int cmPkgConfigDependencyParser::OnDependencyVersion(char const* at, |
366 | | std::size_t len) |
367 | 9.65M | { |
368 | 9.65M | Current_.Version.append(at, len); |
369 | 9.65M | return 0; |
370 | 9.65M | } |
371 | | |
372 | | int cmPkgConfigDependencyParser::OnDependencyVersionTr(llpkgc_dep_t* parser, |
373 | | char const* at, |
374 | | std::size_t len) |
375 | 9.65M | { |
376 | 9.65M | return static_cast<cmPkgConfigDependencyParser*>(parser) |
377 | 9.65M | ->OnDependencyVersion(at, len); |
378 | 9.65M | } |
379 | | |
380 | | int cmPkgConfigDependencyParser::OnDependencyComplete() |
381 | 34.6M | { |
382 | 34.6M | Current_.Operation = static_cast<cmPkgConfigDependencyOperation>( |
383 | 34.6M | llpkgc_dep_get_comparator(static_cast<llpkgc_dep_t*>(this))); |
384 | 34.6M | Dependencies_.push_back(std::move(Current_)); |
385 | 34.6M | Current_ = cmPkgConfigDependencySpec{}; |
386 | 34.6M | return 0; |
387 | 34.6M | } |
388 | | |
389 | | int cmPkgConfigDependencyParser::OnDependencyCompleteTr(llpkgc_dep_t* parser) |
390 | 34.6M | { |
391 | 34.6M | return static_cast<cmPkgConfigDependencyParser*>(parser) |
392 | 34.6M | ->OnDependencyComplete(); |
393 | 34.6M | } |
394 | | |
395 | | llpkgc_file_errno_t cmPkgConfigParser::Parse(char const* input, |
396 | | std::size_t len) |
397 | 8.10k | { |
398 | 8.10k | return File_.Parse(input, len); |
399 | 8.10k | } |
400 | | |
401 | | llpkgc_file_errno_t cmPkgConfigParser::Finish() |
402 | 8.10k | { |
403 | 8.10k | return File_.Finish(); |
404 | 8.10k | } |
405 | | |
406 | | llpkgc_file_errno_t cmPkgConfigParser::Finish(char const* input, |
407 | | std::size_t len) |
408 | 0 | { |
409 | 0 | auto err = Parse(input, len); |
410 | 0 | if (err != PFCE_OK && err != PFCE_NEED_MORE) { |
411 | 0 | return err; |
412 | 0 | } |
413 | 0 | return Finish(); |
414 | 0 | } |
415 | | |
416 | | llpkgc_file_errno_t cmPkgConfigParser::GetErrno() const |
417 | 0 | { |
418 | 0 | return File_.GetErrno(); |
419 | 0 | } |
420 | | |
421 | | char const* cmPkgConfigParser::ErrorReason() const |
422 | 0 | { |
423 | 0 | return File_.ErrorReason(); |
424 | 0 | } |
425 | | |
426 | | std::ptrdiff_t cmPkgConfigParser::ErrorOffset(char const* base) const |
427 | 0 | { |
428 | 0 | return File_.ErrorOffset(base); |
429 | 0 | } |
430 | | |
431 | | void cmPkgConfigParser::SetVariable(std::string name, std::string value) |
432 | 41.3k | { |
433 | 41.3k | ValueItems variable; |
434 | 41.3k | variable.emplace_back(std::move(value), false); |
435 | 41.3k | StoredVariables_[std::move(name)] = std::move(variable); |
436 | 41.3k | Cache_.clear(); |
437 | 41.3k | } |
438 | | |
439 | | std::string cmPkgConfigParser::GetVariable(std::string const& name) |
440 | 0 | { |
441 | 0 | return ResolveValue(StoredVariables_[name]); |
442 | 0 | } |
443 | | |
444 | | bool cmPkgConfigParser::HasProperty(std::string const& name) const |
445 | 13.0k | { |
446 | 13.0k | return std::any_of(StoredProperties_.begin(), StoredProperties_.end(), |
447 | 254k | [&name](cmPkgConfigEntry const& entry) -> bool { |
448 | 254k | return entry.Ident == name; |
449 | 254k | }); |
450 | 13.0k | } |
451 | | |
452 | | std::vector<std::string> cmPkgConfigParser::GetFragments( |
453 | | std::string const& name) |
454 | 54.8k | { |
455 | 54.8k | auto it = Cache_.find(name); |
456 | 54.8k | if (it != Cache_.end()) { |
457 | 0 | return it->second.Fragments; |
458 | 0 | } |
459 | | |
460 | 54.8k | cmPkgConfigResolvedValue cache; |
461 | 54.8k | if (!ResolveAndParse(name, cache)) { |
462 | 50.9k | return {}; |
463 | 50.9k | } |
464 | 3.89k | return cache.Fragments; |
465 | 54.8k | } |
466 | | |
467 | | std::vector<cmPkgConfigDependencySpec> cmPkgConfigParser::GetDependencies( |
468 | | std::string const& name) |
469 | 36.5k | { |
470 | 36.5k | auto it = Cache_.find(name); |
471 | 36.5k | if (it != Cache_.end()) { |
472 | 0 | return it->second.Dependencies; |
473 | 0 | } |
474 | | |
475 | 36.5k | cmPkgConfigResolvedValue cache; |
476 | 36.5k | if (!ResolveAndParse(name, cache)) { |
477 | 33.5k | return {}; |
478 | 33.5k | } |
479 | 2.94k | return cache.Dependencies; |
480 | 36.5k | } |
481 | | |
482 | | std::string cmPkgConfigParser::GetLiteral(std::string const& name) |
483 | 27.4k | { |
484 | 27.4k | auto it = Cache_.find(name); |
485 | 27.4k | if (it != Cache_.end()) { |
486 | 0 | return it->second.Literal; |
487 | 0 | } |
488 | | |
489 | 27.4k | cmPkgConfigResolvedValue cache; |
490 | 27.4k | if (!ResolveAndParse(name, cache)) { |
491 | 22.0k | return {}; |
492 | 22.0k | } |
493 | 5.37k | return cache.Literal; |
494 | 27.4k | } |
495 | | |
496 | | void cmPkgConfigParser::ParseComplete() |
497 | 21.9k | { |
498 | 21.9k | StoredVariables_.clear(); |
499 | 21.9k | StoredProperties_.clear(); |
500 | 21.9k | Cache_.clear(); |
501 | | |
502 | 1.64M | for (auto const& entry : File_.Data_) { |
503 | 1.64M | switch (entry.Kind) { |
504 | 419k | case cmPkgConfigEntryKind::Variable: |
505 | 419k | StoredVariables_[entry.Ident] = entry.Value; |
506 | 419k | break; |
507 | 546k | case cmPkgConfigEntryKind::Property: |
508 | 546k | StoredProperties_.push_back(entry); |
509 | 546k | break; |
510 | 676k | default: |
511 | 676k | break; |
512 | 1.64M | } |
513 | 1.64M | } |
514 | 21.9k | } |
515 | | |
516 | | std::string cmPkgConfigParser::ResolveValue(ValueItems const& items) |
517 | 12.2k | { |
518 | 12.2k | return ResolveValueImpl(items, {}); |
519 | 12.2k | } |
520 | | |
521 | | std::string cmPkgConfigParser::ResolveValueImpl( |
522 | | ValueItems const& items, std::set<std::string> resolving) |
523 | 2.23M | { |
524 | 2.23M | std::string result; |
525 | 2.23M | if (items.empty()) { |
526 | 87.3k | return result; |
527 | 87.3k | } |
528 | | |
529 | 143M | for (auto const& item : items) { |
530 | 143M | if (item.IsSubstitution) { |
531 | 72.1M | if (resolving.count(item.Text)) { |
532 | 68.1M | result += "${"; |
533 | 68.1M | result += item.Text; |
534 | 68.1M | result += "}"; |
535 | 68.1M | continue; |
536 | 68.1M | } |
537 | 4.05M | auto it = StoredVariables_.find(item.Text); |
538 | 4.05M | if (it != StoredVariables_.end()) { |
539 | 2.22M | resolving.insert(item.Text); |
540 | 2.22M | result += ResolveValueImpl(it->second, resolving); |
541 | 2.22M | resolving.erase(item.Text); |
542 | 2.22M | } |
543 | 71.3M | } else { |
544 | 71.3M | result += item.Text; |
545 | 71.3M | } |
546 | 143M | } |
547 | | |
548 | 2.15M | return result; |
549 | 2.23M | } |
550 | | |
551 | | bool cmPkgConfigParser::ResolveAndParse(std::string const& name, |
552 | | cmPkgConfigResolvedValue& cache) |
553 | 118k | { |
554 | 118k | cmPkgConfigEntry const* entry = nullptr; |
555 | 2.71M | for (auto const& candidate : StoredProperties_) { |
556 | 2.71M | if (candidate.Ident == name) { |
557 | 12.2k | entry = &candidate; |
558 | 12.2k | break; |
559 | 12.2k | } |
560 | 2.71M | } |
561 | 118k | if (entry == nullptr) { |
562 | 106k | return false; |
563 | 106k | } |
564 | | |
565 | 12.2k | std::string resolved = ResolveValue(entry->Value); |
566 | 12.2k | cache.Literal = resolved; |
567 | | |
568 | 12.2k | auto kind = llpkgc_classify_field(name.data(), name.size()); |
569 | 12.2k | if (kind == LLPKGC_VALUE_FRAGMENTS) { |
570 | 3.89k | cmPkgConfigFragmentParser fragmentParser; |
571 | 3.89k | auto err = fragmentParser.Parse(resolved.data(), resolved.size()); |
572 | 3.89k | if (err == PFFE_OK && fragmentParser.Finish() == PFFE_OK) { |
573 | 3.33k | cache.Fragments = fragmentParser.Fragments(); |
574 | 3.33k | } |
575 | 8.31k | } else if (kind == LLPKGC_VALUE_DEPENDENCIES) { |
576 | 2.94k | cmPkgConfigDependencyParser dependencyParser; |
577 | 2.94k | auto err = dependencyParser.Parse(resolved.data(), resolved.size()); |
578 | 2.94k | if (err == PDEP_OK && dependencyParser.Finish() == PDEP_OK) { |
579 | 2.94k | cache.Dependencies = dependencyParser.Dependencies(); |
580 | 2.94k | } |
581 | 2.94k | } |
582 | | |
583 | 12.2k | Cache_[name] = cache; |
584 | 12.2k | return true; |
585 | 118k | } |