cmState.cxx 27.5 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 "cmGlobVerificationManager.h"
17
#include "cmListFileCache.h"
18
19
#include "cmStatePrivate.h"
#include "cmStateSnapshot.h"
20
#include "cmSystemTools.h"
21
#include "cmUnexpectedCommand.h"
22
#include "cmake.h"
23

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

38
39
cmState::~cmState()
{
40
  delete this->CacheManager;
41
  delete this->GlobVerificationManager;
42
43
  cmDeleteAll(this->BuiltinCommands);
  cmDeleteAll(this->ScriptedCommands);
44
45
}

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

72
73
const char* cmCacheEntryTypes[] = { "BOOL",          "PATH",     "FILEPATH",
                                    "STRING",        "INTERNAL", "STATIC",
Daniel Pfeifer's avatar
Daniel Pfeifer committed
74
                                    "UNINITIALIZED", nullptr };
75

76
const char* cmState::CacheEntryTypeToString(cmStateEnums::CacheEntryType type)
Stephen Kelly's avatar
Stephen Kelly committed
77
{
78
  if (type > 6) {
79
    return cmCacheEntryTypes[6];
80
  }
81
  return cmCacheEntryTypes[type];
Stephen Kelly's avatar
Stephen Kelly committed
82
83
}

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

bool cmState::IsCacheEntryType(std::string const& key)
{
98
  for (int i = 0; cmCacheEntryTypes[i]; ++i) {
99
    if (key == cmCacheEntryTypes[i]) {
100
101
      return true;
    }
102
  }
103
  return false;
Stephen Kelly's avatar
Stephen Kelly committed
104
105
}

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

113
bool cmState::SaveCache(const std::string& path, cmMessenger* messenger)
114
{
115
  return this->CacheManager->SaveCache(path, messenger);
116
117
118
119
}

bool cmState::DeleteCache(const std::string& path)
{
120
  return this->CacheManager->DeleteCache(path);
121
122
}

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

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

143
const char* cmState::GetInitializedCacheValue(std::string const& key) const
Stephen Kelly's avatar
Stephen Kelly committed
144
{
145
146
  const std::string* p = this->CacheManager->GetInitializedCacheValue(key);
  return p ? p->c_str() : nullptr;
Stephen Kelly's avatar
Stephen Kelly committed
147
148
}

149
cmStateEnums::CacheEntryType cmState::GetCacheEntryType(
150
  std::string const& key) const
Stephen Kelly's avatar
Stephen Kelly committed
151
152
{
  cmCacheManager::CacheIterator it =
153
    this->CacheManager->GetCacheIterator(key.c_str());
Stephen Kelly's avatar
Stephen Kelly committed
154
155
156
157
  return it.GetType();
}

void cmState::SetCacheEntryValue(std::string const& key,
158
                                 std::string const& value)
Stephen Kelly's avatar
Stephen Kelly committed
159
{
160
  this->CacheManager->SetCacheEntryValue(key, value);
Stephen Kelly's avatar
Stephen Kelly committed
161
162
163
}

void cmState::SetCacheEntryProperty(std::string const& key,
164
165
                                    std::string const& propertyName,
                                    std::string const& value)
Stephen Kelly's avatar
Stephen Kelly committed
166
167
{
  cmCacheManager::CacheIterator it =
168
    this->CacheManager->GetCacheIterator(key.c_str());
Stephen Kelly's avatar
Stephen Kelly committed
169
170
171
172
  it.SetProperty(propertyName, value.c_str());
}

void cmState::SetCacheEntryBoolProperty(std::string const& key,
173
174
                                        std::string const& propertyName,
                                        bool value)
Stephen Kelly's avatar
Stephen Kelly committed
175
176
{
  cmCacheManager::CacheIterator it =
177
    this->CacheManager->GetCacheIterator(key.c_str());
Stephen Kelly's avatar
Stephen Kelly committed
178
179
180
  it.SetProperty(propertyName, value);
}

181
182
183
184
185
186
187
188
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
189
const char* cmState::GetCacheEntryProperty(std::string const& key,
190
                                           std::string const& propertyName)
Stephen Kelly's avatar
Stephen Kelly committed
191
{
192
193
194
  cmCacheManager::CacheIterator it =
    this->CacheManager->GetCacheIterator(key.c_str());
  if (!it.PropertyExists(propertyName)) {
Daniel Pfeifer's avatar
Daniel Pfeifer committed
195
    return nullptr;
196
  }
Stephen Kelly's avatar
Stephen Kelly committed
197
198
199
200
  return it.GetProperty(propertyName);
}

bool cmState::GetCacheEntryPropertyAsBool(std::string const& key,
201
                                          std::string const& propertyName)
Stephen Kelly's avatar
Stephen Kelly committed
202
{
203
204
  return this->CacheManager->GetCacheIterator(key.c_str())
    .GetPropertyAsBool(propertyName);
Stephen Kelly's avatar
Stephen Kelly committed
205
206
207
}

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

214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
bool cmState::DoWriteGlobVerifyTarget() const
{
  return this->GlobVerificationManager->DoWriteVerifyTarget();
}

std::string const& cmState::GetGlobVerifyScript() const
{
  return this->GlobVerificationManager->GetVerifyScript();
}

std::string const& cmState::GetGlobVerifyStamp() const
{
  return this->GlobVerificationManager->GetVerifyStamp();
}

bool cmState::SaveVerificationScript(const std::string& path)
{
  return this->GlobVerificationManager->SaveVerificationScript(path);
}

void cmState::AddGlobCacheEntry(bool recurse, bool listDirectories,
                                bool followSymlinks,
                                const std::string& relative,
                                const std::string& expression,
                                const std::vector<std::string>& files,
                                const std::string& variable,
                                cmListFileBacktrace const& backtrace)
{
  this->GlobVerificationManager->AddCacheEntry(
    recurse, listDirectories, followSymlinks, relative, expression, files,
    variable, backtrace);
}

Stephen Kelly's avatar
Stephen Kelly committed
247
248
void cmState::RemoveCacheEntry(std::string const& key)
{
249
  this->CacheManager->RemoveCacheEntry(key);
Stephen Kelly's avatar
Stephen Kelly committed
250
251
252
}

void cmState::AppendCacheEntryProperty(const std::string& key,
253
254
                                       const std::string& property,
                                       const std::string& value, bool asString)
Stephen Kelly's avatar
Stephen Kelly committed
255
{
256
257
  this->CacheManager->GetCacheIterator(key.c_str())
    .AppendProperty(property, value.c_str(), asString);
Stephen Kelly's avatar
Stephen Kelly committed
258
259
260
}

void cmState::RemoveCacheEntryProperty(std::string const& key,
261
                                       std::string const& propertyName)
Stephen Kelly's avatar
Stephen Kelly committed
262
{
263
  this->CacheManager->GetCacheIterator(key.c_str())
Daniel Pfeifer's avatar
Daniel Pfeifer committed
264
    .SetProperty(propertyName, nullptr);
Stephen Kelly's avatar
Stephen Kelly committed
265
}
266

267
cmStateSnapshot cmState::Reset()
268
{
269
  this->GlobalProperties.clear();
270
  this->PropertyDefinitions.clear();
271
  this->GlobVerificationManager->Reset();
272

273
  cmStateDetail::PositionType pos = this->SnapshotData.Truncate();
274
275
  this->ExecutionListFiles.Truncate();

276
  {
277
    cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator it =
278
      this->BuildsystemDirectory.Truncate();
279
280
281
282
283
284
    it->IncludeDirectories.clear();
    it->IncludeDirectoryBacktraces.clear();
    it->CompileDefinitions.clear();
    it->CompileDefinitionsBacktraces.clear();
    it->CompileOptions.clear();
    it->CompileOptionsBacktraces.clear();
285
286
    it->LinkOptions.clear();
    it->LinkOptionsBacktraces.clear();
287
    it->DirectoryEnd = pos;
288
    it->NormalTargetNames.clear();
289
290
    it->Properties.clear();
    it->Children.clear();
291
  }
292

293
294
295
296
297
298
  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());
299
300

  {
301
    std::string srcDir =
302
      *cmDefinitions::Get("CMAKE_SOURCE_DIR", pos->Vars, pos->Root);
303
    std::string binDir =
304
      *cmDefinitions::Get("CMAKE_BINARY_DIR", pos->Vars, pos->Root);
305
306
307
308
    this->VarTree.Clear();
    pos->Vars = this->VarTree.Push(this->VarTree.Root());
    pos->Parent = this->VarTree.Root();
    pos->Root = this->VarTree.Root();
309

310
311
    pos->Vars->Set("CMAKE_SOURCE_DIR", srcDir.c_str());
    pos->Vars->Set("CMAKE_BINARY_DIR", binDir.c_str());
312
313
  }

314
315
316
317
318
319
320
321
322
323
324
  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);
325

326
  return cmStateSnapshot(this, pos);
327
328
329
}

void cmState::DefineProperty(const std::string& name,
330
331
332
                             cmProperty::ScopeType scope,
                             const char* ShortDescription,
                             const char* FullDescription, bool chained)
333
{
334
335
  this->PropertyDefinitions[scope].DefineProperty(
    name, scope, ShortDescription, FullDescription, chained);
336
337
}

338
339
cmPropertyDefinition const* cmState::GetPropertyDefinition(
  const std::string& name, cmProperty::ScopeType scope) const
340
{
341
  if (this->IsPropertyDefined(name, scope)) {
342
    cmPropertyDefinitionMap const& defs =
343
      this->PropertyDefinitions.find(scope)->second;
344
    return &defs.find(name)->second;
345
  }
Daniel Pfeifer's avatar
Daniel Pfeifer committed
346
  return nullptr;
347
348
349
}

bool cmState::IsPropertyDefined(const std::string& name,
350
                                cmProperty::ScopeType scope) const
351
{
352
353
354
  std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it =
    this->PropertyDefinitions.find(scope);
  if (it == this->PropertyDefinitions.end()) {
355
    return false;
356
  }
357
  return it->second.IsPropertyDefined(name);
358
359
360
}

bool cmState::IsPropertyChained(const std::string& name,
361
                                cmProperty::ScopeType scope) const
362
{
363
364
365
  std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it =
    this->PropertyDefinitions.find(scope);
  if (it == this->PropertyDefinitions.end()) {
366
    return false;
367
  }
368
  return it->second.IsPropertyChained(name);
369
}
370
371
372

void cmState::SetLanguageEnabled(std::string const& l)
{
373
374
375
  std::vector<std::string>::iterator it = std::lower_bound(
    this->EnabledLanguages.begin(), this->EnabledLanguages.end(), l);
  if (it == this->EnabledLanguages.end() || *it != l) {
376
    this->EnabledLanguages.insert(it, l);
377
  }
378
379
380
381
382
383
384
385
386
387
388
389
390
}

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;
}

391
392
393
394
395
void cmState::SetEnabledLanguages(std::vector<std::string> const& langs)
{
  this->EnabledLanguages = langs;
}

396
397
398
399
void cmState::ClearEnabledLanguages()
{
  this->EnabledLanguages.clear();
}
400
401
402
403
404
405
406
407
408
409

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

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

411
412
413
414
415
416
417
418
419
420
bool cmState::GetIsGeneratorMultiConfig() const
{
  return this->IsGeneratorMultiConfig;
}

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

421
422
423
void cmState::AddBuiltinCommand(std::string const& name, cmCommand* command)
{
  assert(name == cmSystemTools::LowerCase(name));
424
425
  assert(this->BuiltinCommands.find(name) == this->BuiltinCommands.end());
  this->BuiltinCommands.insert(std::make_pair(name, command));
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
}

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));
}

441
442
void cmState::AddScriptedCommand(std::string const& name, cmCommand* command)
{
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
  std::string sName = cmSystemTools::LowerCase(name);

  // if the command already exists, give a new name to the old command.
  if (cmCommand* oldCmd = this->GetCommand(sName)) {
    std::string const newName = "_" + sName;
    std::map<std::string, cmCommand*>::iterator pos =
      this->ScriptedCommands.find(newName);
    if (pos != this->ScriptedCommands.end()) {
      delete pos->second;
      this->ScriptedCommands.erase(pos);
    }
    this->ScriptedCommands.insert(std::make_pair(newName, oldCmd->Clone()));
  }

  // if the command already exists, free the old one
  std::map<std::string, cmCommand*>::iterator pos =
    this->ScriptedCommands.find(sName);
  if (pos != this->ScriptedCommands.end()) {
    delete pos->second;
    this->ScriptedCommands.erase(pos);
  }
  this->ScriptedCommands.insert(std::make_pair(sName, command));
465
466
}

467
468
cmCommand* cmState::GetCommand(std::string const& name) const
{
469
470
471
472
473
  return GetCommandByExactName(cmSystemTools::LowerCase(name));
}

cmCommand* cmState::GetCommandByExactName(std::string const& name) const
{
474
  std::map<std::string, cmCommand*>::const_iterator pos;
475
  pos = this->ScriptedCommands.find(name);
476
477
  if (pos != this->ScriptedCommands.end()) {
    return pos->second;
478
  }
479
  pos = this->BuiltinCommands.find(name);
480
481
482
  if (pos != this->BuiltinCommands.end()) {
    return pos->second;
  }
Daniel Pfeifer's avatar
Daniel Pfeifer committed
483
  return nullptr;
484
485
486
487
488
}

std::vector<std::string> cmState::GetCommandNames() const
{
  std::vector<std::string> commandNames;
489
490
  commandNames.reserve(this->BuiltinCommands.size() +
                       this->ScriptedCommands.size());
491
492
  for (auto const& bc : this->BuiltinCommands) {
    commandNames.push_back(bc.first);
493
  }
494
495
  for (auto const& sc : this->ScriptedCommands) {
    commandNames.push_back(sc.first);
496
  }
497
498
499
  std::sort(commandNames.begin(), commandNames.end());
  commandNames.erase(std::unique(commandNames.begin(), commandNames.end()),
                     commandNames.end());
500
501
502
503
504
  return commandNames;
}

void cmState::RemoveUserDefinedCommands()
{
505
506
  cmDeleteAll(this->ScriptedCommands);
  this->ScriptedCommands.clear();
507
}
508
509
510

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

514
515
void cmState::AppendGlobalProperty(const std::string& prop, const char* value,
                                   bool asString)
516
{
517
  this->GlobalProperties.AppendProperty(prop, value, asString);
518
519
}

520
const char* cmState::GetGlobalProperty(const std::string& prop)
521
{
522
  if (prop == "CACHE_VARIABLES") {
523
524
    std::vector<std::string> cacheKeys = this->GetCacheEntryKeys();
    this->SetGlobalProperty("CACHE_VARIABLES", cmJoin(cacheKeys, ";").c_str());
525
  } else if (prop == "COMMANDS") {
526
527
    std::vector<std::string> commands = this->GetCommandNames();
    this->SetGlobalProperty("COMMANDS", cmJoin(commands, ";").c_str());
528
  } else if (prop == "IN_TRY_COMPILE") {
529
    this->SetGlobalProperty("IN_TRY_COMPILE",
530
                            this->IsInTryCompile ? "1" : "0");
531
532
533
  } else if (prop == "GENERATOR_IS_MULTI_CONFIG") {
    this->SetGlobalProperty("GENERATOR_IS_MULTI_CONFIG",
                            this->IsGeneratorMultiConfig ? "1" : "0");
534
  } else if (prop == "ENABLED_LANGUAGES") {
535
536
537
    std::string langs;
    langs = cmJoin(this->EnabledLanguages, ";");
    this->SetGlobalProperty("ENABLED_LANGUAGES", langs.c_str());
538
  }
539
#define STRING_LIST_ELEMENT(F) ";" #F
540
  if (prop == "CMAKE_C_KNOWN_FEATURES") {
541
    return FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT) + 1;
542
543
  }
  if (prop == "CMAKE_CXX_KNOWN_FEATURES") {
544
    return FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT) + 1;
545
  }
546
#undef STRING_LIST_ELEMENT
547
  return this->GlobalProperties.GetPropertyValue(prop);
548
549
550
551
552
553
}

bool cmState::GetGlobalPropertyAsBool(const std::string& prop)
{
  return cmSystemTools::IsOn(this->GetGlobalProperty(prop));
}
554
555
556
557
558
559
560

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

561
std::string const& cmState::GetSourceDirectory() const
562
{
563
  return this->SourceDirectory;
564
565
566
567
568
569
570
571
}

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

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
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
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;
}

632
633
unsigned int cmState::GetCacheMajorVersion() const
{
634
  return this->CacheManager->GetCacheMajorVersion();
635
636
637
638
}

unsigned int cmState::GetCacheMinorVersion() const
{
639
  return this->CacheManager->GetCacheMinorVersion();
640
641
}

642
std::string const& cmState::GetBinaryDirectory() const
643
{
644
  return this->BinaryDirectory;
645
}
Stephen Kelly's avatar
Stephen Kelly committed
646

647
cmStateSnapshot cmState::CreateBaseSnapshot()
648
{
649
650
  cmStateDetail::PositionType pos =
    this->SnapshotData.Push(this->SnapshotData.Root());
651
  pos->DirectoryParent = this->SnapshotData.Root();
652
  pos->ScopeParent = this->SnapshotData.Root();
653
  pos->SnapshotType = cmStateEnums::BaseType;
654
  pos->Keep = true;
655
  pos->BuildSystemDirectory =
656
    this->BuildsystemDirectory.Push(this->BuildsystemDirectory.Root());
657
  pos->ExecutionListFile =
658
    this->ExecutionListFiles.Push(this->ExecutionListFiles.Root());
659
660
661
  pos->IncludeDirectoryPosition = 0;
  pos->CompileDefinitionsPosition = 0;
  pos->CompileOptionsPosition = 0;
662
  pos->BuildSystemDirectory->DirectoryEnd = pos;
663
664
665
666
667
  pos->Policies = this->PolicyStack.Root();
  pos->PolicyRoot = this->PolicyStack.Root();
  pos->PolicyScope = this->PolicyStack.Root();
  assert(pos->Policies.IsValid());
  assert(pos->PolicyRoot.IsValid());
668
  pos->Vars = this->VarTree.Push(this->VarTree.Root());
669
670
671
  assert(pos->Vars.IsValid());
  pos->Parent = this->VarTree.Root();
  pos->Root = this->VarTree.Root();
672
  return cmStateSnapshot(this, pos);
673
674
}

675
cmStateSnapshot cmState::CreateBuildsystemDirectorySnapshot(
676
  cmStateSnapshot const& originSnapshot)
Stephen Kelly's avatar
Stephen Kelly committed
677
{
678
  assert(originSnapshot.IsValid());
679
680
  cmStateDetail::PositionType pos =
    this->SnapshotData.Push(originSnapshot.Position);
681
  pos->DirectoryParent = originSnapshot.Position;
682
  pos->ScopeParent = originSnapshot.Position;
683
  pos->SnapshotType = cmStateEnums::BuildsystemDirectoryType;
684
  pos->Keep = true;
685
686
  pos->BuildSystemDirectory = this->BuildsystemDirectory.Push(
    originSnapshot.Position->BuildSystemDirectory);
687
  pos->ExecutionListFile =
688
    this->ExecutionListFiles.Push(originSnapshot.Position->ExecutionListFile);
689
  pos->BuildSystemDirectory->DirectoryEnd = pos;
690
691
692
693
694
  pos->Policies = originSnapshot.Position->Policies;
  pos->PolicyRoot = originSnapshot.Position->Policies;
  pos->PolicyScope = originSnapshot.Position->Policies;
  assert(pos->Policies.IsValid());
  assert(pos->PolicyRoot.IsValid());
695

696
  cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
697
698
  pos->Parent = origin;
  pos->Root = origin;
699
  pos->Vars = this->VarTree.Push(origin);
700

701
  cmStateSnapshot snapshot = cmStateSnapshot(this, pos);
702
  originSnapshot.Position->BuildSystemDirectory->Children.push_back(snapshot);
703
  snapshot.SetDefaultDefinitions();
704
  snapshot.InitializeFromParent();
705
  snapshot.SetDirectoryDefinitions();
706
  return snapshot;
Stephen Kelly's avatar
Stephen Kelly committed
707
708
}

709
cmStateSnapshot cmState::CreateFunctionCallSnapshot(
710
  cmStateSnapshot const& originSnapshot, std::string const& fileName)
711
{
712
  cmStateDetail::PositionType pos =
713
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
714
  pos->ScopeParent = originSnapshot.Position;
715
  pos->SnapshotType = cmStateEnums::FunctionCallType;
716
  pos->Keep = false;
717
  pos->ExecutionListFile = this->ExecutionListFiles.Push(
718
    originSnapshot.Position->ExecutionListFile, fileName);
719
  pos->BuildSystemDirectory->DirectoryEnd = pos;
720
  pos->PolicyScope = originSnapshot.Position->Policies;
721
  assert(originSnapshot.Position->Vars.IsValid());
722
  cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
723
  pos->Parent = origin;
724
  pos->Vars = this->VarTree.Push(origin);
725
  return cmStateSnapshot(this, pos);
726
727
}

728
cmStateSnapshot cmState::CreateMacroCallSnapshot(
729
  cmStateSnapshot const& originSnapshot, std::string const& fileName)
730
{
731
  cmStateDetail::PositionType pos =
732
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
733
  pos->SnapshotType = cmStateEnums::MacroCallType;
734
  pos->Keep = false;
735
  pos->ExecutionListFile = this->ExecutionListFiles.Push(
736
    originSnapshot.Position->ExecutionListFile, fileName);
737
  assert(originSnapshot.Position->Vars.IsValid());
738
  pos->BuildSystemDirectory->DirectoryEnd = pos;
739
  pos->PolicyScope = originSnapshot.Position->Policies;
740
  return cmStateSnapshot(this, pos);
741
742
}

743
cmStateSnapshot cmState::CreateIncludeFileSnapshot(
744
  cmStateSnapshot const& originSnapshot, std::string const& fileName)
745
{
746
  cmStateDetail::PositionType pos =
747
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
748
  pos->SnapshotType = cmStateEnums::IncludeFileType;
749
  pos->Keep = true;
750
  pos->ExecutionListFile = this->ExecutionListFiles.Push(
751
    originSnapshot.Position->ExecutionListFile, fileName);
752
  assert(originSnapshot.Position->Vars.IsValid());
753
  pos->BuildSystemDirectory->DirectoryEnd = pos;
754
  pos->PolicyScope = originSnapshot.Position->Policies;
755
  return cmStateSnapshot(this, pos);
756
757
}

758
cmStateSnapshot cmState::CreateVariableScopeSnapshot(
759
  cmStateSnapshot const& originSnapshot)
760
{
761
  cmStateDetail::PositionType pos =
762
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
763
  pos->ScopeParent = originSnapshot.Position;
764
  pos->SnapshotType = cmStateEnums::VariableScopeType;
765
  pos->Keep = false;
766
  pos->PolicyScope = originSnapshot.Position->Policies;
767
  assert(originSnapshot.Position->Vars.IsValid());
768

769
  cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
770
  pos->Parent = origin;
771
  pos->Vars = this->VarTree.Push(origin);
772
  assert(pos->Vars.IsValid());
773
  return cmStateSnapshot(this, pos);
774
775
}

776
cmStateSnapshot cmState::CreateInlineListFileSnapshot(
777
  cmStateSnapshot const& originSnapshot, std::string const& fileName)
778
{
779
  cmStateDetail::PositionType pos =
780
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
781
  pos->SnapshotType = cmStateEnums::InlineListFileType;
782
  pos->Keep = true;
783
  pos->ExecutionListFile = this->ExecutionListFiles.Push(
784
    originSnapshot.Position->ExecutionListFile, fileName);
785
  pos->BuildSystemDirectory->DirectoryEnd = pos;
786
  pos->PolicyScope = originSnapshot.Position->Policies;
787
  return cmStateSnapshot(this, pos);
788
789
}

790
cmStateSnapshot cmState::CreatePolicyScopeSnapshot(
791
  cmStateSnapshot const& originSnapshot)
792
{
793
  cmStateDetail::PositionType pos =
794
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
795
  pos->SnapshotType = cmStateEnums::PolicyScopeType;
796
  pos->Keep = false;
797
  pos->BuildSystemDirectory->DirectoryEnd = pos;
798
  pos->PolicyScope = originSnapshot.Position->Policies;
799
  return cmStateSnapshot(this, pos);
800
801
}

802
cmStateSnapshot cmState::Pop(cmStateSnapshot const& originSnapshot)
803
{
804
805
  cmStateDetail::PositionType pos = originSnapshot.Position;
  cmStateDetail::PositionType prevPos = pos;
806
  ++prevPos;
807
  prevPos->IncludeDirectoryPosition =
808
    prevPos->BuildSystemDirectory->IncludeDirectories.size();
809
  prevPos->CompileDefinitionsPosition =
810
    prevPos->BuildSystemDirectory->CompileDefinitions.size();
811
  prevPos->CompileOptionsPosition =
812
    prevPos->BuildSystemDirectory->CompileOptions.size();
813
  prevPos->BuildSystemDirectory->DirectoryEnd = prevPos;
814

815
816
  if (!pos->Keep && this->SnapshotData.IsLast(pos)) {
    if (pos->Vars != prevPos->Vars) {
817
818
      assert(this->VarTree.IsLast(pos->Vars));
      this->VarTree.Pop(pos->Vars);
819
820
    }
    if (pos->ExecutionListFile != prevPos->ExecutionListFile) {
821
822
823
      assert(this->ExecutionListFiles.IsLast(pos->ExecutionListFile));
      this->ExecutionListFiles.Pop(pos->ExecutionListFile);
    }
824
825
    this->SnapshotData.Pop(pos);
  }
826

827
  return cmStateSnapshot(this, prevPos);
828
829
}

830
static bool ParseEntryWithoutType(const std::string& entry, std::string& var,
831
832
833
834
835
836
837
838
839
                                  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;
840
  if (regQuoted.find(entry)) {
841
842
843
    var = regQuoted.match(1);
    value = regQuoted.match(2);
    flag = true;
844
  } else if (reg.find(entry)) {
845
846
847
    var = reg.match(1);
    value = reg.match(2);
    flag = true;
848
  }
849
850
851

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

  return flag;
}

860
bool cmState::ParseCacheEntry(const std::string& entry, std::string& var,
861
862
                              std::string& value,
                              cmStateEnums::CacheEntryType& type)
863
864
865
866
867
868
869
870
{
  // 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;
871
  if (regQuoted.find(entry)) {
872
873
874
875
    var = regQuoted.match(1);
    type = cmState::StringToCacheEntryType(regQuoted.match(2).c_str());
    value = regQuoted.match(3);
    flag = true;
876
  } else if (reg.find(entry)) {
877
878
879
880
    var = reg.match(1);
    type = cmState::StringToCacheEntryType(reg.match(2).c_str());
    value = reg.match(3);
    flag = true;
881
  }
882