1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmListFileCache.cxx,v $
6 Date: $Date: 2008-03-07 20:30:33 $
7 Version: $Revision: 1.38 $
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 "cmListFileCache.h"
19 #include "cmListFileLexer.h"
20 #include "cmSystemTools.h"
21 #include "cmMakefile.h"
23 #include <cmsys/RegularExpression.hxx>
26 # pragma warn -8060 /* possibly incorrect assignment */
29 bool cmListFileCacheParseFunction(cmListFileLexer
* lexer
,
30 cmListFileFunction
& function
,
31 const char* filename
);
33 bool cmListFile::ParseFile(const char* filename
,
37 if(!cmSystemTools::FileExists(filename
))
42 // Create the scanner.
43 cmListFileLexer
* lexer
= cmListFileLexer_New();
46 cmSystemTools::Error("cmListFileCache: error allocating lexer ");
51 if(!cmListFileLexer_SetFileName(lexer
, filename
))
53 cmListFileLexer_Delete(lexer
);
54 cmSystemTools::Error("cmListFileCache: error can not open file ",
59 // Use a simple recursive-descent parser to process the token
61 this->ModifiedTime
= cmSystemTools::ModifiedTime(filename
);
62 bool parseError
= false;
63 bool haveNewline
= true;
64 cmListFileLexer_Token
* token
;
65 while(!parseError
&& (token
= cmListFileLexer_Scan(lexer
)))
67 if(token
->type
== cmListFileLexer_Token_Newline
)
71 else if(token
->type
== cmListFileLexer_Token_Identifier
)
76 cmListFileFunction inFunction
;
77 inFunction
.Name
= token
->text
;
78 inFunction
.FilePath
= filename
;
79 inFunction
.Line
= token
->line
;
80 if(cmListFileCacheParseFunction(lexer
, inFunction
, filename
))
82 this->Functions
.push_back(inFunction
);
91 cmOStringStream error
;
92 error
<< "Error in cmake code at\n"
93 << filename
<< ":" << token
->line
<< ":\n"
94 << "Parse error. Expected a newline, got "
95 << cmListFileLexer_GetTypeAsString(lexer
, token
->type
)
96 << " with text \"" << token
->text
<< "\".";
97 cmSystemTools::Error(error
.str().c_str());
103 cmOStringStream error
;
104 error
<< "Error in cmake code at\n"
105 << filename
<< ":" << token
->line
<< ":\n"
106 << "Parse error. Expected a command name, got "
107 << cmListFileLexer_GetTypeAsString(lexer
, token
->type
)
109 << token
->text
<< "\".";
110 cmSystemTools::Error(error
.str().c_str());
116 this->ModifiedTime
= 0;
119 cmListFileLexer_Delete(lexer
);
121 // do we need a cmake_policy(VERSION call?
124 bool hasPolicy
= false;
125 // search for the right policy command
126 for(std::vector
<cmListFileFunction
>::iterator i
127 = this->Functions
.begin();
128 i
!= this->Functions
.end(); ++i
)
130 if (cmSystemTools::LowerCase(i
->Name
) == "cmake_policy" &&
131 i
->Arguments
.size() &&
132 cmSystemTools::LowerCase(i
->Arguments
[0].Value
) == "version")
137 if (cmSystemTools::LowerCase(i
->Name
) == "cmake_minimum_required")
143 // if no policy command is found this is an error
146 switch (mf
->GetPolicyStatus(cmPolicies::CMP_0000
))
148 case cmPolicies::WARN
:
150 mf
->GetPolicies()->GetPolicyWarning(cmPolicies::CMP_0000
)
153 // Implicitly set the version for the user.
154 mf
->SetPolicyVersion("2.4");
155 case cmPolicies::OLD
:
159 mf
->GetPolicies()->GetRequiredPolicyError(cmPolicies::CMP_0000
)
168 bool hasProject
= false;
169 // search for a project command
170 for(std::vector
<cmListFileFunction
>::iterator i
171 = this->Functions
.begin();
172 i
!= this->Functions
.end(); ++i
)
174 if(cmSystemTools::LowerCase(i
->Name
) == "project")
180 // if no project command is found, add one
183 cmListFileFunction project
;
184 project
.Name
= "PROJECT";
185 cmListFileArgument
prj("Project", false, filename
, 0);
186 project
.Arguments
.push_back(prj
);
187 this->Functions
.insert(this->Functions
.begin(),project
);
197 bool cmListFileCacheParseFunction(cmListFileLexer
* lexer
,
198 cmListFileFunction
& function
,
199 const char* filename
)
201 // Command name has already been parsed. Read the left paren.
202 cmListFileLexer_Token
* token
;
203 if(!(token
= cmListFileLexer_Scan(lexer
)))
205 cmOStringStream error
;
206 error
<< "Error in cmake code at\n"
207 << filename
<< ":" << cmListFileLexer_GetCurrentLine(lexer
) << ":\n"
208 << "Parse error. Function missing opening \"(\".";
209 cmSystemTools::Error(error
.str().c_str());
212 if(token
->type
!= cmListFileLexer_Token_ParenLeft
)
214 cmOStringStream error
;
215 error
<< "Error in cmake code at\n"
216 << filename
<< ":" << cmListFileLexer_GetCurrentLine(lexer
) << ":\n"
217 << "Parse error. Expected \"(\", got "
218 << cmListFileLexer_GetTypeAsString(lexer
, token
->type
)
219 << " with text \"" << token
->text
<< "\".";
220 cmSystemTools::Error(error
.str().c_str());
225 unsigned long lastLine
= cmListFileLexer_GetCurrentLine(lexer
);
226 while((token
= cmListFileLexer_Scan(lexer
)))
228 if(token
->type
== cmListFileLexer_Token_ParenRight
)
232 else if(token
->type
== cmListFileLexer_Token_Identifier
||
233 token
->type
== cmListFileLexer_Token_ArgumentUnquoted
)
235 cmListFileArgument
a(token
->text
,
236 false, filename
, token
->line
);
237 function
.Arguments
.push_back(a
);
239 else if(token
->type
== cmListFileLexer_Token_ArgumentQuoted
)
241 cmListFileArgument
a(token
->text
,
242 true, filename
, token
->line
);
243 function
.Arguments
.push_back(a
);
245 else if(token
->type
!= cmListFileLexer_Token_Newline
)
248 cmOStringStream error
;
249 error
<< "Error in cmake code at\n"
250 << filename
<< ":" << cmListFileLexer_GetCurrentLine(lexer
)
252 << "Parse error. Function missing ending \")\". "
254 << cmListFileLexer_GetTypeAsString(lexer
, token
->type
)
255 << " with text \"" << token
->text
<< "\".";
256 cmSystemTools::Error(error
.str().c_str());
259 lastLine
= cmListFileLexer_GetCurrentLine(lexer
);
262 cmOStringStream error
;
263 error
<< "Error in cmake code at\n"
264 << filename
<< ":" << lastLine
<< ":\n"
265 << "Parse error. Function missing ending \")\". "
266 << "End of file reached.";
267 cmSystemTools::Error(error
.str().c_str());