cmState.cxx 26.4 KB
Newer Older
1
2
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
Stephen Kelly's avatar
Stephen Kelly committed
3
4
#include "cmState.h"

5
#include "cmsys/RegularExpression.hxx"
6
7
8
9
#include <algorithm>
#include <assert.h>
#include <string.h>
#include <utility>
10

11
#include "cmAlgorithms.h"
12
#include "cmCacheManager.h"
13
#include "cmCommand.h"
14
#include "cmDefinitions.h"
15
#include "cmDisallowedCommand.h"
16
#include "cmListFileCache.h"
17
18
#include "cmStatePrivate.h"
#include "cmStateSnapshot.h"
19
#include "cmSystemTools.h"
20
#include "cmUnexpectedCommand.h"
21
#include "cmake.h"
22

23
cmState::cmState()
24
  : IsInTryCompile(false)
25
  , IsGeneratorMultiConfig(false)
26
27
28
29
30
31
  , WindowsShell(false)
  , WindowsVSIDE(false)
  , WatcomWMake(false)
  , MinGWMake(false)
  , NMake(false)
  , MSYSShell(false)
Stephen Kelly's avatar
Stephen Kelly committed
32
{
33
  this->CacheManager = new cmCacheManager;
Stephen Kelly's avatar
Stephen Kelly committed
34
}
35

36
37
cmState::~cmState()
{
38
  delete this->CacheManager;
39
40
41
  cmDeleteAll(this->Commands);
}

42
const char* cmState::GetTargetTypeName(cmStateEnums::TargetType targetType)
43
{
44
  switch (targetType) {
45
    case cmStateEnums::STATIC_LIBRARY:
46
      return "STATIC_LIBRARY";
47
    case cmStateEnums::MODULE_LIBRARY:
48
      return "MODULE_LIBRARY";
49
    case cmStateEnums::SHARED_LIBRARY:
50
      return "SHARED_LIBRARY";
51
    case cmStateEnums::OBJECT_LIBRARY:
52
      return "OBJECT_LIBRARY";
53
    case cmStateEnums::EXECUTABLE:
54
      return "EXECUTABLE";
55
    case cmStateEnums::UTILITY:
56
      return "UTILITY";
57
    case cmStateEnums::GLOBAL_TARGET:
58
      return "GLOBAL_TARGET";
59
    case cmStateEnums::INTERFACE_LIBRARY:
60
      return "INTERFACE_LIBRARY";
61
    case cmStateEnums::UNKNOWN_LIBRARY:
62
63
      return "UNKNOWN_LIBRARY";
  }
64
  assert(false && "Unexpected target type");
Daniel Pfeifer's avatar
Daniel Pfeifer committed
65
  return CM_NULLPTR;
66
67
}

68
69
const char* cmCacheEntryTypes[] = { "BOOL",          "PATH",     "FILEPATH",
                                    "STRING",        "INTERNAL", "STATIC",
Daniel Pfeifer's avatar
Daniel Pfeifer committed
70
                                    "UNINITIALIZED", CM_NULLPTR };
71

72
const char* cmState::CacheEntryTypeToString(cmStateEnums::CacheEntryType type)
Stephen Kelly's avatar
Stephen Kelly committed
73
{
74
  if (type > 6) {
75
    return cmCacheEntryTypes[6];
76
  }
77
  return cmCacheEntryTypes[type];
Stephen Kelly's avatar
Stephen Kelly committed
78
79
}

80
cmStateEnums::CacheEntryType cmState::StringToCacheEntryType(const char* s)
Stephen Kelly's avatar
Stephen Kelly committed
81
{
82
  int i = 0;
83
84
  while (cmCacheEntryTypes[i]) {
    if (strcmp(s, cmCacheEntryTypes[i]) == 0) {
85
      return static_cast<cmStateEnums::CacheEntryType>(i);
86
    }
87
88
    ++i;
  }
89
  return cmStateEnums::STRING;
Stephen Kelly's avatar
Stephen Kelly committed
90
91
92
93
}

bool cmState::IsCacheEntryType(std::string const& key)
{
94
95
  for (int i = 0; cmCacheEntryTypes[i]; ++i) {
    if (strcmp(key.c_str(), cmCacheEntryTypes[i]) == 0) {
96
97
      return true;
    }
98
  }
99
  return false;
Stephen Kelly's avatar
Stephen Kelly committed
100
101
}

102
103
104
105
bool cmState::LoadCache(const std::string& path, bool internal,
                        std::set<std::string>& excludes,
                        std::set<std::string>& includes)
{
106
  return this->CacheManager->LoadCache(path, internal, excludes, includes);
107
108
109
110
}

bool cmState::SaveCache(const std::string& path)
{
111
  return this->CacheManager->SaveCache(path);
112
113
114
115
}

bool cmState::DeleteCache(const std::string& path)
{
116
  return this->CacheManager->DeleteCache(path);
117
118
}

Stephen Kelly's avatar
Stephen Kelly committed
119
120
121
std::vector<std::string> cmState::GetCacheEntryKeys() const
{
  std::vector<std::string> definitions;
122
  definitions.reserve(this->CacheManager->GetSize());
123
124
  cmCacheManager::CacheIterator cit = this->CacheManager->GetCacheIterator();
  for (cit.Begin(); !cit.IsAtEnd(); cit.Next()) {
Stephen Kelly's avatar
Stephen Kelly committed
125
    definitions.push_back(cit.GetName());
126
  }
Stephen Kelly's avatar
Stephen Kelly committed
127
128
129
130
131
  return definitions;
}

const char* cmState::GetCacheEntryValue(std::string const& key) const
{
132
133
  cmCacheManager::CacheEntry* e = this->CacheManager->GetCacheEntry(key);
  if (!e) {
Daniel Pfeifer's avatar
Daniel Pfeifer committed
134
    return CM_NULLPTR;
135
  }
Stephen Kelly's avatar
Stephen Kelly committed
136
137
138
  return e->Value.c_str();
}

139
const char* cmState::GetInitializedCacheValue(std::string const& key) const
Stephen Kelly's avatar
Stephen Kelly committed
140
{
141
  return this->CacheManager->GetInitializedCacheValue(key);
Stephen Kelly's avatar
Stephen Kelly committed
142
143
}

144
cmStateEnums::CacheEntryType cmState::GetCacheEntryType(
145
  std::string const& key) const
Stephen Kelly's avatar
Stephen Kelly committed
146
147
{
  cmCacheManager::CacheIterator it =
148
    this->CacheManager->GetCacheIterator(key.c_str());
Stephen Kelly's avatar
Stephen Kelly committed
149
150
151
152
  return it.GetType();
}

void cmState::SetCacheEntryValue(std::string const& key,
153
                                 std::string const& value)
Stephen Kelly's avatar
Stephen Kelly committed
154
{
155
  this->CacheManager->SetCacheEntryValue(key, value);
Stephen Kelly's avatar
Stephen Kelly committed
156
157
158
}

void cmState::SetCacheEntryProperty(std::string const& key,
159
160
                                    std::string const& propertyName,
                                    std::string const& value)
Stephen Kelly's avatar
Stephen Kelly committed
161
162
{
  cmCacheManager::CacheIterator it =
163
    this->CacheManager->GetCacheIterator(key.c_str());
Stephen Kelly's avatar
Stephen Kelly committed
164
165
166
167
  it.SetProperty(propertyName, value.c_str());
}

void cmState::SetCacheEntryBoolProperty(std::string const& key,
168
169
                                        std::string const& propertyName,
                                        bool value)
Stephen Kelly's avatar
Stephen Kelly committed
170
171
{
  cmCacheManager::CacheIterator it =
172
    this->CacheManager->GetCacheIterator(key.c_str());
Stephen Kelly's avatar
Stephen Kelly committed
173
174
175
  it.SetProperty(propertyName, value);
}

176
177
178
179
180
181
182
183
std::vector<std::string> cmState::GetCacheEntryPropertyList(
  const std::string& key)
{
  cmCacheManager::CacheIterator it =
    this->CacheManager->GetCacheIterator(key.c_str());
  return it.GetPropertyList();
}

Stephen Kelly's avatar
Stephen Kelly committed
184
const char* cmState::GetCacheEntryProperty(std::string const& key,
185
                                           std::string const& propertyName)
Stephen Kelly's avatar
Stephen Kelly committed
186
{
187
188
189
  cmCacheManager::CacheIterator it =
    this->CacheManager->GetCacheIterator(key.c_str());
  if (!it.PropertyExists(propertyName)) {
Daniel Pfeifer's avatar
Daniel Pfeifer committed
190
    return CM_NULLPTR;
191
  }
Stephen Kelly's avatar
Stephen Kelly committed
192
193
194
195
  return it.GetProperty(propertyName);
}

bool cmState::GetCacheEntryPropertyAsBool(std::string const& key,
196
                                          std::string const& propertyName)
Stephen Kelly's avatar
Stephen Kelly committed
197
{
198
199
  return this->CacheManager->GetCacheIterator(key.c_str())
    .GetPropertyAsBool(propertyName);
Stephen Kelly's avatar
Stephen Kelly committed
200
201
202
}

void cmState::AddCacheEntry(const std::string& key, const char* value,
203
                            const char* helpString,
204
                            cmStateEnums::CacheEntryType type)
Stephen Kelly's avatar
Stephen Kelly committed
205
{
206
  this->CacheManager->AddCacheEntry(key, value, helpString, type);
Stephen Kelly's avatar
Stephen Kelly committed
207
208
209
210
}

void cmState::RemoveCacheEntry(std::string const& key)
{
211
  this->CacheManager->RemoveCacheEntry(key);
Stephen Kelly's avatar
Stephen Kelly committed
212
213
214
}

void cmState::AppendCacheEntryProperty(const std::string& key,
215
216
                                       const std::string& property,
                                       const std::string& value, bool asString)
Stephen Kelly's avatar
Stephen Kelly committed
217
{
218
219
  this->CacheManager->GetCacheIterator(key.c_str())
    .AppendProperty(property, value.c_str(), asString);
Stephen Kelly's avatar
Stephen Kelly committed
220
221
222
}

void cmState::RemoveCacheEntryProperty(std::string const& key,
223
                                       std::string const& propertyName)
Stephen Kelly's avatar
Stephen Kelly committed
224
{
225
  this->CacheManager->GetCacheIterator(key.c_str())
Daniel Pfeifer's avatar
Daniel Pfeifer committed
226
    .SetProperty(propertyName, (void*)CM_NULLPTR);
Stephen Kelly's avatar
Stephen Kelly committed
227
}
228

229
cmStateSnapshot cmState::Reset()
230
{
231
  this->GlobalProperties.clear();
232
  this->PropertyDefinitions.clear();
233

234
  cmStateDetail::PositionType pos = this->SnapshotData.Truncate();
235
236
  this->ExecutionListFiles.Truncate();

237
  {
238
    cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator it =
239
      this->BuildsystemDirectory.Truncate();
240
241
242
243
244
245
246
    it->IncludeDirectories.clear();
    it->IncludeDirectoryBacktraces.clear();
    it->CompileDefinitions.clear();
    it->CompileDefinitionsBacktraces.clear();
    it->CompileOptions.clear();
    it->CompileOptionsBacktraces.clear();
    it->DirectoryEnd = pos;
247
    it->NormalTargetNames.clear();
248
249
    it->Properties.clear();
    it->Children.clear();
250
  }
251

252
253
254
255
256
257
  this->PolicyStack.Clear();
  pos->Policies = this->PolicyStack.Root();
  pos->PolicyRoot = this->PolicyStack.Root();
  pos->PolicyScope = this->PolicyStack.Root();
  assert(pos->Policies.IsValid());
  assert(pos->PolicyRoot.IsValid());
258
259

  {
260
    std::string srcDir =
261
      cmDefinitions::Get("CMAKE_SOURCE_DIR", pos->Vars, pos->Root);
262
    std::string binDir =
263
      cmDefinitions::Get("CMAKE_BINARY_DIR", pos->Vars, pos->Root);
264
265
266
267
    this->VarTree.Clear();
    pos->Vars = this->VarTree.Push(this->VarTree.Root());
    pos->Parent = this->VarTree.Root();
    pos->Root = this->VarTree.Root();
268

269
270
    pos->Vars->Set("CMAKE_SOURCE_DIR", srcDir.c_str());
    pos->Vars->Set("CMAKE_BINARY_DIR", binDir.c_str());
271
272
  }

273
274
275
276
277
278
279
280
281
282
283
  this->DefineProperty("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY, "", "",
                       true);
  this->DefineProperty("RULE_LAUNCH_LINK", cmProperty::DIRECTORY, "", "",
                       true);
  this->DefineProperty("RULE_LAUNCH_CUSTOM", cmProperty::DIRECTORY, "", "",
                       true);

  this->DefineProperty("RULE_LAUNCH_COMPILE", cmProperty::TARGET, "", "",
                       true);
  this->DefineProperty("RULE_LAUNCH_LINK", cmProperty::TARGET, "", "", true);
  this->DefineProperty("RULE_LAUNCH_CUSTOM", cmProperty::TARGET, "", "", true);
284

285
  return cmStateSnapshot(this, pos);
286
287
288
}

void cmState::DefineProperty(const std::string& name,
289
290
291
                             cmProperty::ScopeType scope,
                             const char* ShortDescription,
                             const char* FullDescription, bool chained)
292
{
293
294
  this->PropertyDefinitions[scope].DefineProperty(
    name, scope, ShortDescription, FullDescription, chained);
295
296
}

297
298
cmPropertyDefinition const* cmState::GetPropertyDefinition(
  const std::string& name, cmProperty::ScopeType scope) const
299
{
300
  if (this->IsPropertyDefined(name, scope)) {
301
    cmPropertyDefinitionMap const& defs =
302
      this->PropertyDefinitions.find(scope)->second;
303
    return &defs.find(name)->second;
304
  }
Daniel Pfeifer's avatar
Daniel Pfeifer committed
305
  return CM_NULLPTR;
306
307
308
}

bool cmState::IsPropertyDefined(const std::string& name,
309
                                cmProperty::ScopeType scope) const
310
{
311
312
313
  std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it =
    this->PropertyDefinitions.find(scope);
  if (it == this->PropertyDefinitions.end()) {
314
    return false;
315
  }
316
  return it->second.IsPropertyDefined(name);
317
318
319
}

bool cmState::IsPropertyChained(const std::string& name,
320
                                cmProperty::ScopeType scope) const
321
{
322
323
324
  std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it =
    this->PropertyDefinitions.find(scope);
  if (it == this->PropertyDefinitions.end()) {
325
    return false;
326
  }
327
  return it->second.IsPropertyChained(name);
328
}
329
330
331

void cmState::SetLanguageEnabled(std::string const& l)
{
332
333
334
  std::vector<std::string>::iterator it = std::lower_bound(
    this->EnabledLanguages.begin(), this->EnabledLanguages.end(), l);
  if (it == this->EnabledLanguages.end() || *it != l) {
335
    this->EnabledLanguages.insert(it, l);
336
  }
337
338
339
340
341
342
343
344
345
346
347
348
349
}

bool cmState::GetLanguageEnabled(std::string const& l) const
{
  return std::binary_search(this->EnabledLanguages.begin(),
                            this->EnabledLanguages.end(), l);
}

std::vector<std::string> cmState::GetEnabledLanguages() const
{
  return this->EnabledLanguages;
}

350
351
352
353
354
void cmState::SetEnabledLanguages(std::vector<std::string> const& langs)
{
  this->EnabledLanguages = langs;
}

355
356
357
358
void cmState::ClearEnabledLanguages()
{
  this->EnabledLanguages.clear();
}
359
360
361
362
363
364
365
366
367
368

bool cmState::GetIsInTryCompile() const
{
  return this->IsInTryCompile;
}

void cmState::SetIsInTryCompile(bool b)
{
  this->IsInTryCompile = b;
}
369

370
371
372
373
374
375
376
377
378
379
bool cmState::GetIsGeneratorMultiConfig() const
{
  return this->IsGeneratorMultiConfig;
}

void cmState::SetIsGeneratorMultiConfig(bool b)
{
  this->IsGeneratorMultiConfig = b;
}

380
381
382
383
384
385
386
void cmState::RenameCommand(std::string const& oldName,
                            std::string const& newName)
{
  // if the command already exists, free the old one
  std::string sOldName = cmSystemTools::LowerCase(oldName);
  std::string sNewName = cmSystemTools::LowerCase(newName);
  std::map<std::string, cmCommand*>::iterator pos =
387
388
    this->Commands.find(sOldName);
  if (pos == this->Commands.end()) {
389
    return;
390
  }
391
392
393
  cmCommand* cmd = pos->second;

  pos = this->Commands.find(sNewName);
394
  if (pos != this->Commands.end()) {
395
396
    delete pos->second;
    this->Commands.erase(pos);
397
  }
398
399
400
401
402
403
404
405
406
407
  this->Commands.insert(std::make_pair(sNewName, cmd));
  pos = this->Commands.find(sOldName);
  this->Commands.erase(pos);
}

void cmState::AddCommand(cmCommand* command)
{
  std::string name = cmSystemTools::LowerCase(command->GetName());
  // if the command already exists, free the old one
  std::map<std::string, cmCommand*>::iterator pos = this->Commands.find(name);
408
  if (pos != this->Commands.end()) {
409
410
    delete pos->second;
    this->Commands.erase(pos);
411
  }
412
413
414
  this->Commands.insert(std::make_pair(name, command));
}

415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
void cmState::AddBuiltinCommand(std::string const& name, cmCommand* command)
{
  assert(name == cmSystemTools::LowerCase(name));
  assert(name == cmSystemTools::LowerCase(command->GetName()));
  assert(this->Commands.find(name) == this->Commands.end());
  this->Commands.insert(std::make_pair(name, command));
}

void cmState::AddDisallowedCommand(std::string const& name, cmCommand* command,
                                   cmPolicies::PolicyID policy,
                                   const char* message)
{
  this->AddBuiltinCommand(name,
                          new cmDisallowedCommand(command, policy, message));
}

void cmState::AddUnexpectedCommand(std::string const& name, const char* error)
{
  this->AddBuiltinCommand(name, new cmUnexpectedCommand(name, error));
}

436
437
cmCommand* cmState::GetCommand(std::string const& name) const
{
Daniel Pfeifer's avatar
Daniel Pfeifer committed
438
  cmCommand* command = CM_NULLPTR;
439
440
  std::string sName = cmSystemTools::LowerCase(name);
  std::map<std::string, cmCommand*>::const_iterator pos =
441
442
    this->Commands.find(sName);
  if (pos != this->Commands.end()) {
443
    command = (*pos).second;
444
  }
445
446
447
448
449
450
451
  return command;
}

std::vector<std::string> cmState::GetCommandNames() const
{
  std::vector<std::string> commandNames;
  commandNames.reserve(this->Commands.size());
452
453
454
  std::map<std::string, cmCommand*>::const_iterator cmds =
    this->Commands.begin();
  for (; cmds != this->Commands.end(); ++cmds) {
455
    commandNames.push_back(cmds->first);
456
  }
457
458
459
460
461
  return commandNames;
}

void cmState::RemoveUserDefinedCommands()
{
462
  std::vector<cmCommand*> renamedCommands;
463
464
  for (std::map<std::string, cmCommand*>::iterator j = this->Commands.begin();
       j != this->Commands.end();) {
465
    if (j->second->IsUserDefined()) {
466
467
      delete j->second;
      this->Commands.erase(j++);
468
    } else if (j->first != j->second->GetName()) {
469
470
      renamedCommands.push_back(j->second);
      this->Commands.erase(j++);
471
    } else {
472
473
      ++j;
    }
474
  }
475
  for (std::vector<cmCommand*>::const_iterator it = renamedCommands.begin();
476
       it != renamedCommands.end(); ++it) {
477
    this->Commands[cmSystemTools::LowerCase((*it)->GetName())] = *it;
478
  }
479
}
480
481
482

void cmState::SetGlobalProperty(const std::string& prop, const char* value)
{
483
  this->GlobalProperties.SetProperty(prop, value);
484
485
}

486
487
void cmState::AppendGlobalProperty(const std::string& prop, const char* value,
                                   bool asString)
488
{
489
  this->GlobalProperties.AppendProperty(prop, value, asString);
490
491
}

492
const char* cmState::GetGlobalProperty(const std::string& prop)
493
{
494
  if (prop == "CACHE_VARIABLES") {
495
496
    std::vector<std::string> cacheKeys = this->GetCacheEntryKeys();
    this->SetGlobalProperty("CACHE_VARIABLES", cmJoin(cacheKeys, ";").c_str());
497
  } else if (prop == "COMMANDS") {
498
499
    std::vector<std::string> commands = this->GetCommandNames();
    this->SetGlobalProperty("COMMANDS", cmJoin(commands, ";").c_str());
500
  } else if (prop == "IN_TRY_COMPILE") {
501
    this->SetGlobalProperty("IN_TRY_COMPILE",
502
                            this->IsInTryCompile ? "1" : "0");
503
504
505
  } else if (prop == "GENERATOR_IS_MULTI_CONFIG") {
    this->SetGlobalProperty("GENERATOR_IS_MULTI_CONFIG",
                            this->IsGeneratorMultiConfig ? "1" : "0");
506
  } else if (prop == "ENABLED_LANGUAGES") {
507
508
509
    std::string langs;
    langs = cmJoin(this->EnabledLanguages, ";");
    this->SetGlobalProperty("ENABLED_LANGUAGES", langs.c_str());
510
  }
511
#define STRING_LIST_ELEMENT(F) ";" #F
512
  if (prop == "CMAKE_C_KNOWN_FEATURES") {
513
    return FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT) + 1;
514
515
  }
  if (prop == "CMAKE_CXX_KNOWN_FEATURES") {
516
    return FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT) + 1;
517
  }
518
#undef STRING_LIST_ELEMENT
519
  return this->GlobalProperties.GetPropertyValue(prop);
520
521
522
523
524
525
}

bool cmState::GetGlobalPropertyAsBool(const std::string& prop)
{
  return cmSystemTools::IsOn(this->GetGlobalProperty(prop));
}
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543

void cmState::SetSourceDirectory(std::string const& sourceDirectory)
{
  this->SourceDirectory = sourceDirectory;
  cmSystemTools::ConvertToUnixSlashes(this->SourceDirectory);
}

const char* cmState::GetSourceDirectory() const
{
  return this->SourceDirectory.c_str();
}

void cmState::SetBinaryDirectory(std::string const& binaryDirectory)
{
  this->BinaryDirectory = binaryDirectory;
  cmSystemTools::ConvertToUnixSlashes(this->BinaryDirectory);
}

544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
void cmState::SetWindowsShell(bool windowsShell)
{
  this->WindowsShell = windowsShell;
}

bool cmState::UseWindowsShell() const
{
  return this->WindowsShell;
}

void cmState::SetWindowsVSIDE(bool windowsVSIDE)
{
  this->WindowsVSIDE = windowsVSIDE;
}

bool cmState::UseWindowsVSIDE() const
{
  return this->WindowsVSIDE;
}

void cmState::SetWatcomWMake(bool watcomWMake)
{
  this->WatcomWMake = watcomWMake;
}

bool cmState::UseWatcomWMake() const
{
  return this->WatcomWMake;
}

void cmState::SetMinGWMake(bool minGWMake)
{
  this->MinGWMake = minGWMake;
}

bool cmState::UseMinGWMake() const
{
  return this->MinGWMake;
}

void cmState::SetNMake(bool nMake)
{
  this->NMake = nMake;
}

bool cmState::UseNMake() const
{
  return this->NMake;
}

void cmState::SetMSYSShell(bool mSYSShell)
{
  this->MSYSShell = mSYSShell;
}

bool cmState::UseMSYSShell() const
{
  return this->MSYSShell;
}

604
605
unsigned int cmState::GetCacheMajorVersion() const
{
606
  return this->CacheManager->GetCacheMajorVersion();
607
608
609
610
}

unsigned int cmState::GetCacheMinorVersion() const
{
611
  return this->CacheManager->GetCacheMinorVersion();
612
613
}

614
615
616
617
const char* cmState::GetBinaryDirectory() const
{
  return this->BinaryDirectory.c_str();
}
Stephen Kelly's avatar
Stephen Kelly committed
618

619
cmStateSnapshot cmState::CreateBaseSnapshot()
620
{
621
622
  cmStateDetail::PositionType pos =
    this->SnapshotData.Push(this->SnapshotData.Root());
623
  pos->DirectoryParent = this->SnapshotData.Root();
624
  pos->ScopeParent = this->SnapshotData.Root();
625
  pos->SnapshotType = cmStateEnums::BaseType;
626
  pos->Keep = true;
627
  pos->BuildSystemDirectory =
628
    this->BuildsystemDirectory.Push(this->BuildsystemDirectory.Root());
629
  pos->ExecutionListFile =
630
    this->ExecutionListFiles.Push(this->ExecutionListFiles.Root());
631
632
633
  pos->IncludeDirectoryPosition = 0;
  pos->CompileDefinitionsPosition = 0;
  pos->CompileOptionsPosition = 0;
634
  pos->BuildSystemDirectory->DirectoryEnd = pos;
635
636
637
638
639
  pos->Policies = this->PolicyStack.Root();
  pos->PolicyRoot = this->PolicyStack.Root();
  pos->PolicyScope = this->PolicyStack.Root();
  assert(pos->Policies.IsValid());
  assert(pos->PolicyRoot.IsValid());
640
  pos->Vars = this->VarTree.Push(this->VarTree.Root());
641
642
643
  assert(pos->Vars.IsValid());
  pos->Parent = this->VarTree.Root();
  pos->Root = this->VarTree.Root();
644
  return cmStateSnapshot(this, pos);
645
646
}

647
648
cmStateSnapshot cmState::CreateBuildsystemDirectorySnapshot(
  cmStateSnapshot originSnapshot)
Stephen Kelly's avatar
Stephen Kelly committed
649
{
650
  assert(originSnapshot.IsValid());
651
652
  cmStateDetail::PositionType pos =
    this->SnapshotData.Push(originSnapshot.Position);
653
  pos->DirectoryParent = originSnapshot.Position;
654
  pos->ScopeParent = originSnapshot.Position;
655
  pos->SnapshotType = cmStateEnums::BuildsystemDirectoryType;
656
  pos->Keep = true;
657
658
  pos->BuildSystemDirectory = this->BuildsystemDirectory.Push(
    originSnapshot.Position->BuildSystemDirectory);
659
  pos->ExecutionListFile =
660
    this->ExecutionListFiles.Push(originSnapshot.Position->ExecutionListFile);
661
  pos->BuildSystemDirectory->DirectoryEnd = pos;
662
663
664
665
666
  pos->Policies = originSnapshot.Position->Policies;
  pos->PolicyRoot = originSnapshot.Position->Policies;
  pos->PolicyScope = originSnapshot.Position->Policies;
  assert(pos->Policies.IsValid());
  assert(pos->PolicyRoot.IsValid());
667

668
  cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
669
670
  pos->Parent = origin;
  pos->Root = origin;
671
  pos->Vars = this->VarTree.Push(origin);
672

673
  cmStateSnapshot snapshot = cmStateSnapshot(this, pos);
674
  originSnapshot.Position->BuildSystemDirectory->Children.push_back(snapshot);
675
  snapshot.SetDefaultDefinitions();
676
  snapshot.InitializeFromParent();
677
  snapshot.SetDirectoryDefinitions();
678
  return snapshot;
Stephen Kelly's avatar
Stephen Kelly committed
679
680
}

681
682
cmStateSnapshot cmState::CreateFunctionCallSnapshot(
  cmStateSnapshot originSnapshot, std::string const& fileName)
683
{
684
  cmStateDetail::PositionType pos =
685
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
686
  pos->ScopeParent = originSnapshot.Position;
687
  pos->SnapshotType = cmStateEnums::FunctionCallType;
688
  pos->Keep = false;
689
  pos->ExecutionListFile = this->ExecutionListFiles.Push(
690
    originSnapshot.Position->ExecutionListFile, fileName);
691
  pos->BuildSystemDirectory->DirectoryEnd = pos;
692
  pos->PolicyScope = originSnapshot.Position->Policies;
693
  assert(originSnapshot.Position->Vars.IsValid());
694
  cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
695
  pos->Parent = origin;
696
  pos->Vars = this->VarTree.Push(origin);
697
  return cmStateSnapshot(this, pos);
698
699
}

700
701
cmStateSnapshot cmState::CreateMacroCallSnapshot(
  cmStateSnapshot originSnapshot, std::string const& fileName)
702
{
703
  cmStateDetail::PositionType pos =
704
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
705
  pos->SnapshotType = cmStateEnums::MacroCallType;
706
  pos->Keep = false;
707
  pos->ExecutionListFile = this->ExecutionListFiles.Push(
708
    originSnapshot.Position->ExecutionListFile, fileName);
709
  assert(originSnapshot.Position->Vars.IsValid());
710
  pos->BuildSystemDirectory->DirectoryEnd = pos;
711
  pos->PolicyScope = originSnapshot.Position->Policies;
712
  return cmStateSnapshot(this, pos);
713
714
}

715
716
cmStateSnapshot cmState::CreateIncludeFileSnapshot(
  cmStateSnapshot originSnapshot, const std::string& fileName)
717
{
718
  cmStateDetail::PositionType pos =
719
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
720
  pos->SnapshotType = cmStateEnums::IncludeFileType;
721
  pos->Keep = true;
722
  pos->ExecutionListFile = this->ExecutionListFiles.Push(
723
    originSnapshot.Position->ExecutionListFile, fileName);
724
  assert(originSnapshot.Position->Vars.IsValid());
725
  pos->BuildSystemDirectory->DirectoryEnd = pos;
726
  pos->PolicyScope = originSnapshot.Position->Policies;
727
  return cmStateSnapshot(this, pos);
728
729
}

730
731
cmStateSnapshot cmState::CreateVariableScopeSnapshot(
  cmStateSnapshot originSnapshot)
732
{
733
  cmStateDetail::PositionType pos =
734
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
735
  pos->ScopeParent = originSnapshot.Position;
736
  pos->SnapshotType = cmStateEnums::VariableScopeType;
737
  pos->Keep = false;
738
  pos->PolicyScope = originSnapshot.Position->Policies;
739
  assert(originSnapshot.Position->Vars.IsValid());
740

741
  cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
742
  pos->Parent = origin;
743
  pos->Vars = this->VarTree.Push(origin);
744
  assert(pos->Vars.IsValid());
745
  return cmStateSnapshot(this, pos);
746
747
}

748
749
cmStateSnapshot cmState::CreateInlineListFileSnapshot(
  cmStateSnapshot originSnapshot, const std::string& fileName)
750
{
751
  cmStateDetail::PositionType pos =
752
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
753
  pos->SnapshotType = cmStateEnums::InlineListFileType;
754
  pos->Keep = true;
755
  pos->ExecutionListFile = this->ExecutionListFiles.Push(
756
    originSnapshot.Position->ExecutionListFile, fileName);
757
  pos->BuildSystemDirectory->DirectoryEnd = pos;
758
  pos->PolicyScope = originSnapshot.Position->Policies;
759
  return cmStateSnapshot(this, pos);
760
761
}

762
763
cmStateSnapshot cmState::CreatePolicyScopeSnapshot(
  cmStateSnapshot originSnapshot)
764
{
765
  cmStateDetail::PositionType pos =
766
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
767
  pos->SnapshotType = cmStateEnums::PolicyScopeType;
768
  pos->Keep = false;
769
  pos->BuildSystemDirectory->DirectoryEnd = pos;
770
  pos->PolicyScope = originSnapshot.Position->Policies;
771
  return cmStateSnapshot(this, pos);
772
773
}

774
cmStateSnapshot cmState::Pop(cmStateSnapshot originSnapshot)
775
{
776
777
  cmStateDetail::PositionType pos = originSnapshot.Position;
  cmStateDetail::PositionType prevPos = pos;
778
  ++prevPos;
779
  prevPos->IncludeDirectoryPosition =
780
    prevPos->BuildSystemDirectory->IncludeDirectories.size();
781
  prevPos->CompileDefinitionsPosition =
782
    prevPos->BuildSystemDirectory->CompileDefinitions.size();
783
  prevPos->CompileOptionsPosition =
784
    prevPos->BuildSystemDirectory->CompileOptions.size();
785
  prevPos->BuildSystemDirectory->DirectoryEnd = prevPos;
786

787
788
  if (!pos->Keep && this->SnapshotData.IsLast(pos)) {
    if (pos->Vars != prevPos->Vars) {
789
790
      assert(this->VarTree.IsLast(pos->Vars));
      this->VarTree.Pop(pos->Vars);
791
792
    }
    if (pos->ExecutionListFile != prevPos->ExecutionListFile) {
793
794
795
      assert(this->ExecutionListFiles.IsLast(pos->ExecutionListFile));
      this->ExecutionListFiles.Pop(pos->ExecutionListFile);
    }
796
797
    this->SnapshotData.Pop(pos);
  }
798

799
  return cmStateSnapshot(this, prevPos);
800
801
}

802
static bool ParseEntryWithoutType(const std::string& entry, std::string& var,
803
804
805
806
807
808
809
810
811
                                  std::string& value)
{
  // input line is:         key=value
  static cmsys::RegularExpression reg(
    "^([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
  // input line is:         "key"=value
  static cmsys::RegularExpression regQuoted(
    "^\"([^\"]*)\"=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
  bool flag = false;
812
  if (regQuoted.find(entry)) {
813
814
815
    var = regQuoted.match(1);
    value = regQuoted.match(2);
    flag = true;
816
  } else if (reg.find(entry)) {
817
818
819
    var = reg.match(1);
    value = reg.match(2);
    flag = true;
820
  }
821
822
823

  // if value is enclosed in single quotes ('foo') then remove them
  // it is used to enclose trailing space or tab
824
825
826
827
  if (flag && value.size() >= 2 && value[0] == '\'' &&
      value[value.size() - 1] == '\'') {
    value = value.substr(1, value.size() - 2);
  }
828
829
830
831

  return flag;
}

832
bool cmState::ParseCacheEntry(const std::string& entry, std::string& var,
833
834
                              std::string& value,
                              cmStateEnums::CacheEntryType& type)
835
836
837
838
839
840
841
842
{
  // input line is:         key:type=value
  static cmsys::RegularExpression reg(
    "^([^=:]*):([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
  // input line is:         "key":type=value
  static cmsys::RegularExpression regQuoted(
    "^\"([^\"]*)\":([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
  bool flag = false;
843
  if (regQuoted.find(entry)) {
844
845
846
847
    var = regQuoted.match(1);
    type = cmState::StringToCacheEntryType(regQuoted.match(2).c_str());
    value = regQuoted.match(3);
    flag = true;
848
  } else if (reg.find(entry)) {
849
850
851
852
    var = reg.match(1);
    type = cmState::StringToCacheEntryType(reg.match(2).c_str());
    value = reg.match(3);
    flag = true;
853
  }
854
855
856

  // if value is enclosed in single quotes ('foo') then remove them
  // it is used to enclose trailing space or tab
857
858
859
860
  if (flag && value.size() >= 2 && value[0] == '\'' &&
      value[value.size() - 1] == '\'') {
    value = value.substr(1, value.size() - 2);
  }
861

862
  if (!flag) {
863
    return ParseEntryWithoutType(entry, var, value);
864
  }
865
866
867

  return flag;
}