Coverage Report

Created: 2026-10-28 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}