Coverage Report

Created: 2026-10-28 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmCacheManager.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
#include "cmCacheManager.h"
4
5
#include <algorithm>
6
#include <cstdio>
7
#include <cstring>
8
#include <string>
9
10
#include "cmsys/FStream.hxx"
11
#include "cmsys/Glob.hxx"
12
13
#include "cmGeneratedFileStream.h"
14
#include "cmList.h"
15
#include "cmMessageType.h"
16
#include "cmMessenger.h"
17
#include "cmState.h"
18
#include "cmStringAlgorithms.h"
19
#include "cmSystemTools.h"
20
#include "cmVersion.h"
21
22
void cmCacheManager::CleanCMakeFiles(std::string const& path)
23
0
{
24
0
  std::string glob = cmStrCat(path, "/CMakeFiles/*.cmake");
25
0
  cmsys::Glob globIt;
26
0
  globIt.FindFiles(glob);
27
0
  std::vector<std::string> files = globIt.GetFiles();
28
0
  std::for_each(files.begin(), files.end(), cmSystemTools::RemoveFile);
29
0
}
30
31
bool cmCacheManager::LoadCache(std::string const& path, bool internal,
32
                               std::set<std::string>& excludes,
33
                               std::set<std::string>& includes)
34
0
{
35
0
  std::string cacheFile = cmStrCat(path, "/CMakeCache.txt");
36
  // clear the old cache, if we are reading in internal values
37
0
  if (internal) {
38
0
    this->Cache.clear();
39
0
  }
40
0
  if (!cmSystemTools::FileExists(cacheFile)) {
41
0
    this->CleanCMakeFiles(path);
42
0
    return false;
43
0
  }
44
45
0
  cmsys::ifstream fin(cacheFile.c_str());
46
0
  if (!fin) {
47
0
    return false;
48
0
  }
49
0
  char const* realbuffer;
50
0
  std::string buffer;
51
0
  std::string entryKey;
52
0
  unsigned int lineno = 0;
53
0
  while (fin) {
54
    // Format is key:type=value
55
0
    std::string helpString;
56
0
    CacheEntry e;
57
0
    cmSystemTools::GetLineFromStream(fin, buffer);
58
0
    lineno++;
59
0
    realbuffer = buffer.c_str();
60
0
    while (*realbuffer == ' ' || *realbuffer == '\t' || *realbuffer == '\r' ||
61
0
           *realbuffer == '\n') {
62
0
      if (*realbuffer == '\n') {
63
0
        lineno++;
64
0
      }
65
0
      realbuffer++;
66
0
    }
67
    // skip blank lines and comment lines
68
0
    if (realbuffer[0] == '#' || realbuffer[0] == 0) {
69
0
      continue;
70
0
    }
71
0
    while (realbuffer[0] == '/' && realbuffer[1] == '/') {
72
0
      if ((realbuffer[2] == '\\') && (realbuffer[3] == 'n')) {
73
0
        helpString = cmStrCat(std::move(helpString), '\n', &realbuffer[4]);
74
0
      } else {
75
0
        helpString = cmStrCat(std::move(helpString), &realbuffer[2]);
76
0
      }
77
0
      cmSystemTools::GetLineFromStream(fin, buffer);
78
0
      lineno++;
79
0
      realbuffer = buffer.c_str();
80
0
      if (!fin) {
81
0
        continue;
82
0
      }
83
0
    }
84
0
    e.SetProperty("HELPSTRING", helpString);
85
0
    if (cmState::ParseCacheEntry(realbuffer, entryKey, e.Value, e.Type)) {
86
0
      if (excludes.find(entryKey) == excludes.end()) {
87
        // Load internal values if internal is set.
88
        // If the entry is not internal to the cache being loaded
89
        // or if it is in the list of internal entries to be
90
        // imported, load it.
91
0
        if (internal || (e.Type != cmStateEnums::INTERNAL) ||
92
0
            (includes.find(entryKey) != includes.end())) {
93
          // If we are loading the cache from another project,
94
          // make all loaded entries internal so that it is
95
          // not visible in the gui
96
0
          if (!internal) {
97
0
            e.Type = cmStateEnums::INTERNAL;
98
0
            helpString = cmStrCat("DO NOT EDIT, ", entryKey,
99
0
                                  " loaded from external file.  "
100
0
                                  "To change this value edit this file: ",
101
0
                                  path, "/CMakeCache.txt");
102
0
            e.SetProperty("HELPSTRING", helpString);
103
0
          }
104
0
          if (!this->ReadPropertyEntry(entryKey, e)) {
105
0
            e.Initialized = true;
106
0
            this->Cache[entryKey] = e;
107
0
          }
108
0
        }
109
0
      }
110
0
    } else {
111
0
      cmSystemTools::Error(cmStrCat("Parse error in cache file ", cacheFile,
112
0
                                    " on line ", lineno,
113
0
                                    ". Offending entry: ", realbuffer));
114
0
    }
115
0
  }
116
0
  this->CacheMajorVersion = 0;
117
0
  this->CacheMinorVersion = 0;
118
0
  if (cmValue cmajor =
119
0
        this->GetInitializedCacheValue("CMAKE_CACHE_MAJOR_VERSION")) {
120
0
    unsigned int v = 0;
121
0
    if (sscanf(cmajor->c_str(), "%u", &v) == 1) {
122
0
      this->CacheMajorVersion = v;
123
0
    }
124
0
    if (cmValue cminor =
125
0
          this->GetInitializedCacheValue("CMAKE_CACHE_MINOR_VERSION")) {
126
0
      if (sscanf(cminor->c_str(), "%u", &v) == 1) {
127
0
        this->CacheMinorVersion = v;
128
0
      }
129
0
    }
130
0
  } else {
131
    // CMake version not found in the list file.
132
    // Set as version 0.0
133
0
    this->AddCacheEntry("CMAKE_CACHE_MINOR_VERSION", "0",
134
0
                        "Minor version of cmake used to create the "
135
0
                        "current loaded cache",
136
0
                        cmStateEnums::INTERNAL);
137
0
    this->AddCacheEntry("CMAKE_CACHE_MAJOR_VERSION", "0",
138
0
                        "Major version of cmake used to create the "
139
0
                        "current loaded cache",
140
0
                        cmStateEnums::INTERNAL);
141
0
  }
142
  // check to make sure the cache directory has not
143
  // been moved
144
0
  cmValue oldDir = this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR");
145
0
  if (internal && oldDir) {
146
0
    std::string currentcwd = path;
147
0
    std::string oldcwd = *oldDir;
148
0
    cmSystemTools::ConvertToUnixSlashes(currentcwd);
149
0
    currentcwd = cmStrCat(std::move(currentcwd), "/CMakeCache.txt");
150
0
    oldcwd = cmStrCat(std::move(oldcwd), "/CMakeCache.txt");
151
0
    if (!cmSystemTools::SameFile(oldcwd, currentcwd)) {
152
0
      cmValue dir = this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR");
153
0
      std::string message =
154
0
        cmStrCat("The current CMakeCache.txt directory ", currentcwd,
155
0
                 " is different than the directory ", (dir ? *dir : ""),
156
0
                 " where CMakeCache.txt was created. This may result "
157
0
                 "in binaries being created in the wrong place. If you "
158
0
                 "are not sure, reedit the CMakeCache.txt");
159
0
      cmSystemTools::Error(message);
160
0
    }
161
0
  }
162
0
  this->CacheLoaded = true;
163
0
  return true;
164
0
}
165
166
char const* cmCacheManager::PersistentProperties[] = { "ADVANCED", "MODIFIED",
167
                                                       "STRINGS" };
168
169
bool cmCacheManager::ReadPropertyEntry(std::string const& entryKey,
170
                                       CacheEntry const& e)
171
0
{
172
  // All property entries are internal.
173
0
  if (e.Type != cmStateEnums::INTERNAL) {
174
0
    return false;
175
0
  }
176
177
0
  char const* end = entryKey.c_str() + entryKey.size();
178
0
  for (char const* p : cmCacheManager::PersistentProperties) {
179
0
    std::string::size_type plen = strlen(p) + 1;
180
0
    if (entryKey.size() > plen && *(end - plen) == '-' &&
181
0
        strcmp(end - plen + 1, p) == 0) {
182
0
      std::string key = entryKey.substr(0, entryKey.size() - plen);
183
0
      if (auto* entry = this->GetCacheEntry(key)) {
184
        // Store this property on its entry.
185
0
        entry->SetProperty(p, e.Value);
186
0
      } else {
187
        // Create an entry and store the property.
188
0
        CacheEntry& ne = this->Cache[key];
189
0
        ne.SetProperty(p, e.Value);
190
0
      }
191
0
      return true;
192
0
    }
193
0
  }
194
0
  return false;
195
0
}
196
197
void cmCacheManager::WritePropertyEntries(std::ostream& os,
198
                                          std::string const& entryKey,
199
                                          CacheEntry const& e,
200
                                          cmMessenger* messenger) const
201
0
{
202
0
  for (char const* p : cmCacheManager::PersistentProperties) {
203
0
    if (cmValue value = e.GetProperty(p)) {
204
0
      std::string helpstring =
205
0
        cmStrCat(p, " property for variable: ", entryKey);
206
0
      cmCacheManager::OutputHelpString(os, helpstring);
207
208
0
      std::string key = cmStrCat(entryKey, '-', p);
209
0
      cmCacheManager::OutputKey(os, key);
210
0
      os << ":INTERNAL=";
211
0
      cmCacheManager::OutputValue(os, *value);
212
0
      os << '\n';
213
0
      cmCacheManager::OutputNewlineTruncationWarning(os, key, *value,
214
0
                                                     messenger);
215
0
    }
216
0
  }
217
0
}
218
219
bool cmCacheManager::SaveCache(std::string const& path, cmMessenger* messenger)
220
0
{
221
0
  std::string cacheFile = cmStrCat(path, "/CMakeCache.txt");
222
0
  cmGeneratedFileStream fout(cacheFile);
223
0
  fout.SetCopyIfDifferent(true);
224
0
  if (!fout) {
225
0
    cmSystemTools::Error(
226
0
      cmStrCat("Unable to open cache file for save. ", std::move(cacheFile)));
227
0
    cmSystemTools::ReportLastSystemError("");
228
0
    return false;
229
0
  }
230
  // before writing the cache, update the version numbers
231
  // to the
232
0
  this->AddCacheEntry("CMAKE_CACHE_MAJOR_VERSION",
233
0
                      std::to_string(cmVersion::GetMajorVersion()),
234
0
                      "Major version of cmake used to create the "
235
0
                      "current loaded cache",
236
0
                      cmStateEnums::INTERNAL);
237
0
  this->AddCacheEntry("CMAKE_CACHE_MINOR_VERSION",
238
0
                      std::to_string(cmVersion::GetMinorVersion()),
239
0
                      "Minor version of cmake used to create the "
240
0
                      "current loaded cache",
241
0
                      cmStateEnums::INTERNAL);
242
0
  this->AddCacheEntry("CMAKE_CACHE_PATCH_VERSION",
243
0
                      std::to_string(cmVersion::GetPatchVersion()),
244
0
                      "Patch version of cmake used to create the "
245
0
                      "current loaded cache",
246
0
                      cmStateEnums::INTERNAL);
247
248
  // Let us store the current working directory so that if somebody
249
  // Copies it, he will not be surprised
250
0
  std::string currentcwd = path;
251
0
  if (currentcwd[0] >= 'A' && currentcwd[0] <= 'Z' && currentcwd[1] == ':') {
252
    // Cast added to avoid compiler warning. Cast is ok because
253
    // value is guaranteed to fit in char by the above if...
254
0
    currentcwd[0] = static_cast<char>(currentcwd[0] - 'A' + 'a');
255
0
  }
256
0
  cmSystemTools::ConvertToUnixSlashes(currentcwd);
257
0
  this->AddCacheEntry("CMAKE_CACHEFILE_DIR", currentcwd,
258
0
                      "This is the directory where this CMakeCache.txt"
259
0
                      " was created",
260
0
                      cmStateEnums::INTERNAL);
261
262
  /* clang-format off */
263
0
  fout << "# This is the CMakeCache file.\n"
264
0
          "# For build in directory: " << currentcwd << "\n"
265
0
          "# It was generated by CMake: "
266
0
       << cmSystemTools::GetCMakeCommand()
267
0
       << "\n"
268
0
          "# You can edit this file to change values found and used by cmake."
269
0
          "\n"
270
0
          "# If you do not want to change any of the values, simply exit the "
271
0
          "editor.\n"
272
0
          "# If you do want to change a value, simply edit, save, and exit "
273
0
          "the editor.\n"
274
0
          "# The syntax for the file is as follows:\n"
275
0
          "# KEY:TYPE=VALUE\n"
276
0
          "# KEY is the name of a variable in the cache.\n"
277
0
          "# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!."
278
0
          "\n"
279
0
          "# VALUE is the current value for the KEY.\n"
280
0
          "\n"
281
0
          "########################\n"
282
0
          "# EXTERNAL cache entries\n"
283
0
          "########################\n"
284
0
          "\n";
285
  /* clang-format on */
286
287
0
  for (auto const& i : this->Cache) {
288
0
    CacheEntry const& ce = i.second;
289
0
    cmStateEnums::CacheEntryType t = ce.Type;
290
0
    if (!ce.Initialized) {
291
      /*
292
        // This should be added in, but is not for now.
293
      cmSystemTools::Error(cmStrCat("Cache entry \"", i.first, "\" is
294
      uninitialized"));
295
      */
296
0
    } else if (t != cmStateEnums::INTERNAL) {
297
      // Format is key:type=value
298
0
      if (cmValue help = ce.GetProperty("HELPSTRING")) {
299
0
        cmCacheManager::OutputHelpString(fout, *help);
300
0
      } else {
301
0
        cmCacheManager::OutputHelpString(fout, "Missing description");
302
0
      }
303
0
      cmCacheManager::OutputKey(fout, i.first);
304
0
      fout << ':' << cmState::CacheEntryTypeToString(t) << '=';
305
0
      cmCacheManager::OutputValue(fout, ce.Value);
306
0
      fout << '\n';
307
0
      cmCacheManager::OutputNewlineTruncationWarning(fout, i.first, ce.Value,
308
0
                                                     messenger);
309
0
      fout << '\n';
310
0
    }
311
0
  }
312
313
0
  fout << "\n"
314
0
          "########################\n"
315
0
          "# INTERNAL cache entries\n"
316
0
          "########################\n"
317
0
          "\n";
318
319
0
  for (auto const& i : this->Cache) {
320
0
    if (!i.second.Initialized) {
321
0
      continue;
322
0
    }
323
324
0
    cmStateEnums::CacheEntryType t = i.second.GetType();
325
0
    this->WritePropertyEntries(fout, i.first, i.second, messenger);
326
0
    if (t == cmStateEnums::INTERNAL) {
327
      // Format is key:type=value
328
0
      if (cmValue help = i.second.GetProperty("HELPSTRING")) {
329
0
        cmCacheManager::OutputHelpString(fout, *help);
330
0
      }
331
0
      cmCacheManager::OutputKey(fout, i.first);
332
0
      fout << ':' << cmState::CacheEntryTypeToString(t) << '=';
333
0
      cmCacheManager::OutputValue(fout, i.second.GetValue());
334
0
      fout << '\n';
335
0
      cmCacheManager::OutputNewlineTruncationWarning(
336
0
        fout, i.first, i.second.GetValue(), messenger);
337
0
    }
338
0
  }
339
0
  fout << '\n';
340
0
  fout.Close();
341
0
  std::string checkCacheFile = cmStrCat(path, "/CMakeFiles");
342
0
  cmSystemTools::MakeDirectory(checkCacheFile);
343
0
  checkCacheFile = cmStrCat(std::move(checkCacheFile), "/cmake.check_cache");
344
0
  cmsys::ofstream checkCache(checkCacheFile.c_str());
345
0
  if (!checkCache) {
346
0
    cmSystemTools::Error(
347
0
      cmStrCat("Unable to open check cache file for write. ",
348
0
               std::move(checkCacheFile)));
349
0
    return false;
350
0
  }
351
0
  checkCache << "# This file is generated by cmake for dependency checking "
352
0
                "of the CMakeCache.txt file\n";
353
0
  return true;
354
0
}
355
356
bool cmCacheManager::DeleteCache(std::string const& path)
357
0
{
358
0
  std::string cacheFile = path;
359
0
  cmSystemTools::ConvertToUnixSlashes(cacheFile);
360
0
  std::string cmakeFiles = cacheFile;
361
0
  cacheFile += "/CMakeCache.txt";
362
0
  if (cmSystemTools::FileExists(cacheFile)) {
363
0
    cmSystemTools::RemoveFile(cacheFile);
364
    // now remove the files in the CMakeFiles directory
365
    // this cleans up language cache files
366
0
    cmakeFiles += "/CMakeFiles";
367
0
    if (cmSystemTools::FileIsDirectory(cmakeFiles)) {
368
0
      cmSystemTools::RemoveADirectory(cmakeFiles);
369
0
    }
370
0
  }
371
0
  return true;
372
0
}
373
374
void cmCacheManager::OutputKey(std::ostream& fout, std::string const& key)
375
0
{
376
  // support : in key name by double quoting
377
0
  char const* q =
378
0
    (key.find(':') != std::string::npos || cmHasLiteralPrefix(key, "//"))
379
0
    ? "\""
380
0
    : "";
381
0
  fout << q << key << q;
382
0
}
383
384
void cmCacheManager::OutputValue(std::ostream& fout, std::string const& value)
385
0
{
386
  // look for and truncate newlines
387
0
  std::string::size_type newline = value.find('\n');
388
0
  if (newline != std::string::npos) {
389
0
    std::string truncated = value.substr(0, newline);
390
0
    OutputValueNoNewlines(fout, truncated);
391
0
  } else {
392
0
    OutputValueNoNewlines(fout, value);
393
0
  }
394
0
}
395
396
void cmCacheManager::OutputValueNoNewlines(std::ostream& fout,
397
                                           std::string const& value)
398
0
{
399
  // if value has trailing space or tab, enclose it in single quotes
400
0
  if (!value.empty() && (value.back() == ' ' || value.back() == '\t')) {
401
0
    fout << '\'' << value << '\'';
402
0
  } else {
403
0
    fout << value;
404
0
  }
405
0
}
406
407
void cmCacheManager::OutputHelpString(std::ostream& fout,
408
                                      std::string const& helpString)
409
0
{
410
0
  std::string::size_type end = helpString.size();
411
0
  std::string oneLine;
412
0
  std::string::size_type pos = 0;
413
0
  for (std::string::size_type i = 1; i <= end; i++) {
414
0
    if ((i == end) || (helpString[i] == '\n') ||
415
0
        ((i - pos >= 60) && (helpString[i] == ' '))) {
416
0
      fout << "//";
417
0
      if (helpString[pos] == '\n') {
418
0
        pos++;
419
0
        fout << "\\n";
420
0
      }
421
0
      oneLine = helpString.substr(pos, i - pos);
422
0
      fout << oneLine << '\n';
423
0
      pos = i;
424
0
    }
425
0
  }
426
0
}
427
428
void cmCacheManager::OutputWarningComment(std::ostream& fout,
429
                                          std::string const& message,
430
                                          bool wrapSpaces)
431
0
{
432
0
  std::string::size_type end = message.size();
433
0
  std::string oneLine;
434
0
  std::string::size_type pos = 0;
435
0
  for (std::string::size_type i = 1; i <= end; i++) {
436
0
    if ((i == end) || (message[i] == '\n') ||
437
0
        ((i - pos >= 60) && (message[i] == ' ') && wrapSpaces)) {
438
0
      fout << "# ";
439
0
      if (message[pos] == '\n') {
440
0
        pos++;
441
0
        fout << "\\n";
442
0
      }
443
0
      oneLine = message.substr(pos, i - pos);
444
0
      fout << oneLine << '\n';
445
0
      pos = i;
446
0
    }
447
0
  }
448
0
}
449
450
void cmCacheManager::OutputNewlineTruncationWarning(std::ostream& fout,
451
                                                    std::string const& key,
452
                                                    std::string const& value,
453
                                                    cmMessenger* messenger)
454
0
{
455
0
  if (value.find('\n') != std::string::npos) {
456
0
    if (messenger) {
457
0
      std::string message =
458
0
        cmStrCat("Value of ", key, " contained a newline; truncating");
459
0
      messenger->IssueMessage(MessageType::WARNING, message);
460
0
    }
461
462
0
    std::string comment =
463
0
      cmStrCat("WARNING: Value of ", key,
464
0
               " contained a newline and was truncated. Original value:");
465
466
0
    OutputWarningComment(fout, comment, true);
467
0
    OutputWarningComment(fout, value, false);
468
0
  }
469
0
}
470
471
void cmCacheManager::RemoveCacheEntry(std::string const& key)
472
23.7k
{
473
23.7k
  this->Cache.erase(key);
474
23.7k
}
475
476
cmCacheManager::CacheEntry* cmCacheManager::GetCacheEntry(
477
  std::string const& key)
478
0
{
479
0
  auto i = this->Cache.find(key);
480
0
  if (i != this->Cache.end()) {
481
0
    return &i->second;
482
0
  }
483
0
  return nullptr;
484
0
}
485
486
cmCacheManager::CacheEntry const* cmCacheManager::GetCacheEntry(
487
  std::string const& key) const
488
6.16M
{
489
6.16M
  auto i = this->Cache.find(key);
490
6.16M
  if (i != this->Cache.end()) {
491
0
    return &i->second;
492
0
  }
493
6.16M
  return nullptr;
494
6.16M
}
495
496
cmValue cmCacheManager::GetInitializedCacheValue(std::string const& key) const
497
5.95M
{
498
5.95M
  if (auto const* entry = this->GetCacheEntry(key)) {
499
0
    if (entry->Initialized) {
500
0
      return cmValue(entry->GetValue());
501
0
    }
502
0
  }
503
5.95M
  return nullptr;
504
5.95M
}
505
506
void cmCacheManager::PrintCache(std::ostream& out) const
507
0
{
508
0
  out << "=================================================\n"
509
0
         "CMakeCache Contents:\n";
510
0
  for (auto const& i : this->Cache) {
511
0
    if (i.second.Type != cmStateEnums::INTERNAL) {
512
0
      out << i.first << " = " << i.second.Value << '\n';
513
0
    }
514
0
  }
515
0
  out << "\n\n"
516
0
         "To change values in the CMakeCache, \n"
517
0
         "edit CMakeCache.txt in your output directory.\n"
518
0
         "=================================================\n";
519
0
}
520
521
void cmCacheManager::AddCacheEntry(std::string const& key, cmValue value,
522
                                   cmValue helpString,
523
                                   cmStateEnums::CacheEntryType type)
524
3
{
525
3
  CacheEntry& e = this->Cache[key];
526
3
  e.SetValue(value);
527
3
  e.Type = type;
528
  // make sure we only use unix style paths
529
3
  if (type == cmStateEnums::FILEPATH || type == cmStateEnums::PATH) {
530
0
    if (e.Value.find(';') != std::string::npos) {
531
0
      cmList paths{ e.Value };
532
0
      for (std::string& i : paths) {
533
0
        cmSystemTools::ConvertToUnixSlashes(i);
534
0
      }
535
0
      e.Value = paths.to_string();
536
0
    } else {
537
0
      cmSystemTools::ConvertToUnixSlashes(e.Value);
538
0
    }
539
0
  }
540
3
  e.SetProperty(
541
3
    "HELPSTRING",
542
3
    helpString ? *helpString
543
3
               : std::string{
544
0
                   "(This variable does not exist and should not be used)" });
545
3
}
546
547
void cmCacheManager::CacheEntry::SetValue(cmValue value)
548
3
{
549
3
  if (value) {
550
3
    this->Value = *value;
551
3
    this->Initialized = true;
552
3
  } else {
553
0
    this->Value.clear();
554
0
  }
555
3
}
556
557
std::vector<std::string> cmCacheManager::CacheEntry::GetPropertyList() const
558
0
{
559
0
  return this->Properties.GetKeys();
560
0
}
561
562
cmValue cmCacheManager::CacheEntry::GetProperty(std::string const& prop) const
563
0
{
564
0
  if (prop == "TYPE") {
565
0
    return cmValue(cmState::CacheEntryTypeToString(this->Type));
566
0
  }
567
0
  if (prop == "VALUE") {
568
0
    return cmValue(this->Value);
569
0
  }
570
0
  return this->Properties.GetPropertyValue(prop);
571
0
}
572
573
bool cmCacheManager::CacheEntry::GetPropertyAsBool(
574
  std::string const& prop) const
575
0
{
576
0
  return this->GetProperty(prop).IsOn();
577
0
}
578
579
void cmCacheManager::CacheEntry::SetProperty(std::string const& prop,
580
                                             std::string const& value)
581
3
{
582
3
  if (prop == "TYPE") {
583
0
    this->Type = cmState::StringToCacheEntryType(value);
584
3
  } else if (prop == "VALUE") {
585
0
    this->Value = value;
586
3
  } else {
587
3
    this->Properties.SetProperty(prop, value);
588
3
  }
589
3
}
590
591
void cmCacheManager::CacheEntry::SetProperty(std::string const& p, bool v)
592
0
{
593
0
  this->SetProperty(p, v ? std::string{ "ON" } : std::string{ "OFF" });
594
0
}
595
596
void cmCacheManager::CacheEntry::RemoveProperty(std::string const& prop)
597
0
{
598
0
  if (prop == "TYPE") {
599
0
    this->Type = cmState::StringToCacheEntryType("STRING");
600
0
  } else if (prop == "VALUE") {
601
0
    this->Value.clear();
602
0
  } else {
603
0
    this->Properties.RemoveProperty(prop);
604
0
  }
605
0
}
606
607
void cmCacheManager::CacheEntry::AppendProperty(std::string const& prop,
608
                                                std::string const& value,
609
                                                bool asString)
610
0
{
611
0
  if (prop == "TYPE") {
612
0
    this->Type =
613
0
      cmState::StringToCacheEntryType(!value.empty() ? value : "STRING");
614
0
  } else if (prop == "VALUE") {
615
0
    if (!value.empty()) {
616
0
      if (!this->Value.empty() && !asString) {
617
0
        this->Value += ";";
618
0
      }
619
0
      this->Value += value;
620
0
    }
621
0
  } else {
622
0
    this->Properties.AppendProperty(prop, value, asString);
623
0
  }
624
0
}