Resync
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / cmListFileCache.cxx
blobf0a8c920dde72930beaa5ff4c1da524d6cf1bb4d
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmListFileCache.cxx,v $
5 Language: C++
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>
25 #ifdef __BORLANDC__
26 # pragma warn -8060 /* possibly incorrect assignment */
27 #endif
29 bool cmListFileCacheParseFunction(cmListFileLexer* lexer,
30 cmListFileFunction& function,
31 const char* filename);
33 bool cmListFile::ParseFile(const char* filename,
34 bool topLevel,
35 cmMakefile *mf)
37 if(!cmSystemTools::FileExists(filename))
39 return false;
42 // Create the scanner.
43 cmListFileLexer* lexer = cmListFileLexer_New();
44 if(!lexer)
46 cmSystemTools::Error("cmListFileCache: error allocating lexer ");
47 return false;
50 // Open the file.
51 if(!cmListFileLexer_SetFileName(lexer, filename))
53 cmListFileLexer_Delete(lexer);
54 cmSystemTools::Error("cmListFileCache: error can not open file ",
55 filename);
56 return false;
59 // Use a simple recursive-descent parser to process the token
60 // stream.
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)
69 haveNewline = true;
71 else if(token->type == cmListFileLexer_Token_Identifier)
73 if(haveNewline)
75 haveNewline = false;
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);
84 else
86 parseError = true;
89 else
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());
98 parseError = true;
101 else
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)
108 << " with text \""
109 << token->text << "\".";
110 cmSystemTools::Error(error.str().c_str());
111 parseError = true;
114 if (parseError)
116 this->ModifiedTime = 0;
119 cmListFileLexer_Delete(lexer);
121 // do we need a cmake_policy(VERSION call?
122 if(topLevel)
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")
134 hasPolicy = true;
135 break;
137 if (cmSystemTools::LowerCase(i->Name) == "cmake_minimum_required")
139 hasPolicy = true;
140 break;
143 // if no policy command is found this is an error
144 if(!hasPolicy)
146 switch (mf->GetPolicyStatus(cmPolicies::CMP_0000))
148 case cmPolicies::WARN:
149 mf->IssueWarning(
150 mf->GetPolicies()->GetPolicyWarning(cmPolicies::CMP_0000)
153 // Implicitly set the version for the user.
154 mf->SetPolicyVersion("2.4");
155 case cmPolicies::OLD:
156 break;
157 default:
158 mf->IssueError(
159 mf->GetPolicies()->GetRequiredPolicyError(cmPolicies::CMP_0000)
161 return false;
166 if(topLevel)
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")
176 hasProject = true;
177 break;
180 // if no project command is found, add one
181 if(!hasProject)
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);
190 if(parseError)
192 return false;
194 return true;
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());
210 return false;
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());
221 return false;
224 // Arguments.
225 unsigned long lastLine = cmListFileLexer_GetCurrentLine(lexer);
226 while((token = cmListFileLexer_Scan(lexer)))
228 if(token->type == cmListFileLexer_Token_ParenRight)
230 return true;
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)
247 // Error.
248 cmOStringStream error;
249 error << "Error in cmake code at\n"
250 << filename << ":" << cmListFileLexer_GetCurrentLine(lexer)
251 << ":\n"
252 << "Parse error. Function missing ending \")\". "
253 << "Instead found "
254 << cmListFileLexer_GetTypeAsString(lexer, token->type)
255 << " with text \"" << token->text << "\".";
256 cmSystemTools::Error(error.str().c_str());
257 return false;
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());
269 return false;