1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmLoadCacheCommand.cxx,v $
6 Date: $Date: 2008-01-23 15:27:59 $
7 Version: $Revision: 1.19 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "cmLoadCacheCommand.h"
19 #include <cmsys/RegularExpression.hxx>
22 bool cmLoadCacheCommand
23 ::InitialPass(std::vector
<std::string
> const& args
, cmExecutionStatus
&)
27 this->SetError("called with wrong number of arguments.");
30 if(args
.size() >= 2 && args
[1] == "READ_WITH_PREFIX")
32 return this->ReadWithPrefix(args
);
35 // Cache entries to be excluded from the import list.
36 // If this set is empty, all cache entries are brought in
37 // and they can not be overridden.
38 bool excludeFiles
=false;
40 std::set
<cmStdString
> excludes
;
42 for(i
=0; i
<args
.size(); i
++)
46 excludes
.insert(args
[i
]);
48 if (args
[i
] == "EXCLUDE")
52 if (excludeFiles
&& (args
[i
] == "INCLUDE_INTERNALS"))
58 // Internal cache entries to be imported.
59 // If this set is empty, no internal cache entries are
61 bool includeFiles
=false;
62 std::set
<cmStdString
> includes
;
64 for(i
=0; i
<args
.size(); i
++)
68 includes
.insert(args
[i
]);
70 if (args
[i
] == "INCLUDE_INTERNALS")
74 if (includeFiles
&& (args
[i
] == "EXCLUDE"))
80 // Loop over each build directory listed in the arguments. Each
81 // directory has a cache file.
82 for(i
=0; i
<args
.size(); i
++)
84 if ((args
[i
] == "EXCLUDE") || (args
[i
] == "INCLUDE_INTERNALS"))
88 this->Makefile
->GetCacheManager()->LoadCache(args
[i
].c_str(), false,
96 //----------------------------------------------------------------------------
97 bool cmLoadCacheCommand::ReadWithPrefix(std::vector
<std::string
> const& args
)
99 // Make sure we have a prefix.
102 this->SetError("READ_WITH_PREFIX form must specify a prefix.");
106 // Make sure the cache file exists.
107 std::string cacheFile
= args
[0]+"/CMakeCache.txt";
108 if(!cmSystemTools::FileExists(cacheFile
.c_str()))
110 std::string e
= "Cannot load cache file from " + cacheFile
;
111 this->SetError(e
.c_str());
115 // Prepare the table of variables to read.
116 this->Prefix
= args
[2];
117 for(unsigned int i
=3; i
< args
.size(); ++i
)
119 this->VariablesToRead
.insert(args
[i
]);
122 // Read the cache file.
123 std::ifstream
fin(cacheFile
.c_str());
125 // This is a big hack read loop to overcome a buggy ifstream
126 // implementation on HP-UX. This should work on all platforms even
127 // for small buffer sizes.
128 const int bufferSize
= 4096;
129 char buffer
[bufferSize
];
133 // Read a block of the file.
134 fin
.read(buffer
, bufferSize
);
137 // Parse for newlines directly.
138 const char* i
= buffer
;
139 const char* end
= buffer
+fin
.gcount();
142 const char* begin
= i
;
143 while(i
!= end
&& *i
!= '\n') { ++i
; }
144 if(i
== begin
|| *(i
-1) != '\r')
146 // Include this portion of the line.
147 line
+= std::string(begin
, i
-begin
);
151 // Include this portion of the line.
152 // Don't include the \r in a \r\n pair.
153 line
+= std::string(begin
, i
-1-begin
);
158 this->CheckLine(line
.c_str());
161 // Skip the newline character.
169 // Partial last line.
170 this->CheckLine(line
.c_str());
176 //----------------------------------------------------------------------------
177 void cmLoadCacheCommand::CheckLine(const char* line
)
179 // Check one line of the cache file.
182 if(this->ParseEntry(line
, var
, value
))
184 // Found a real entry. See if this one was requested.
185 if(this->VariablesToRead
.find(var
) != this->VariablesToRead
.end())
187 // This was requested. Set this variable locally with the given
189 var
= this->Prefix
+ var
;
192 this->Makefile
->AddDefinition(var
.c_str(), value
.c_str());
196 this->Makefile
->RemoveDefinition(var
.c_str());
202 //----------------------------------------------------------------------------
203 bool cmLoadCacheCommand::ParseEntry(const char* entry
, std::string
& var
,
206 // input line is: key:type=value
207 cmsys::RegularExpression
reg("^([^:]*):([^=]*)=(.*[^\t ]|[\t ]*)[\t ]*$");
208 // input line is: "key":type=value
209 cmsys::RegularExpression
210 regQuoted("^\"([^\"]*)\":([^=]*)=(.*[^\t ]|[\t ]*)[\t ]*$");
212 if(regQuoted
.find(entry
))
214 var
= regQuoted
.match(1);
215 value
= regQuoted
.match(3);
218 else if (reg
.find(entry
))
221 value
= reg
.match(3);
225 // if value is enclosed in single quotes ('foo') then remove them
226 // it is used to enclose trailing space or tab
230 value
[value
.size() - 1] == '\'')
232 value
= value
.substr(1, value
.size() - 2);