Resync
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / cmOutputRequiredFilesCommand.cxx
blob4a93e3a7754bfe4ca5c0dee39916fbc1070307f2
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmOutputRequiredFilesCommand.cxx,v $
5 Language: C++
6 <<<<<<< cmOutputRequiredFilesCommand.cxx
7 Date: $Date: 2008/01/23 15:27:59 $
8 Version: $Revision: 1.16 $
9 =======
10 Date: $Date: 2008-10-10 14:48:10 $
11 Version: $Revision: 1.17 $
12 >>>>>>> 1.17
14 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
15 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
17 This software is distributed WITHOUT ANY WARRANTY; without even
18 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
19 PURPOSE. See the above copyright notices for more information.
21 =========================================================================*/
22 #include "cmOutputRequiredFilesCommand.h"
23 #include "cmMakeDepend.h"
25 class cmLBDepend : public cmMakeDepend
27 /**
28 * Compute the depend information for this class.
30 virtual void DependWalk(cmDependInformation* info);
33 void cmLBDepend::DependWalk(cmDependInformation* info)
35 std::ifstream fin(info->FullPath.c_str());
36 if(!fin)
38 cmSystemTools::Error("error can not open ", info->FullPath.c_str());
39 return;
42 std::string line;
43 while(cmSystemTools::GetLineFromStream(fin, line))
45 if(!strncmp(line.c_str(), "#include", 8))
47 // if it is an include line then create a string class
48 std::string currentline = line;
49 size_t qstart = currentline.find('\"', 8);
50 size_t qend;
51 // if a quote is not found look for a <
52 if(qstart == std::string::npos)
54 qstart = currentline.find('<', 8);
55 // if a < is not found then move on
56 if(qstart == std::string::npos)
58 cmSystemTools::Error("unknown include directive ",
59 currentline.c_str() );
60 continue;
62 else
64 qend = currentline.find('>', qstart+1);
67 else
69 qend = currentline.find('\"', qstart+1);
71 // extract the file being included
72 std::string includeFile = currentline.substr(qstart+1, qend - qstart-1);
73 // see if the include matches the regular expression
74 if(!this->IncludeFileRegularExpression.find(includeFile))
76 if(this->Verbose)
78 std::string message = "Skipping ";
79 message += includeFile;
80 message += " for file ";
81 message += info->FullPath.c_str();
82 cmSystemTools::Error(message.c_str(), 0);
84 continue;
87 // Add this file and all its dependencies.
88 this->AddDependency(info, includeFile.c_str());
89 /// add the cxx file if it exists
90 std::string cxxFile = includeFile;
91 std::string::size_type pos = cxxFile.rfind('.');
92 if(pos != std::string::npos)
94 std::string root = cxxFile.substr(0, pos);
95 cxxFile = root + ".cxx";
96 bool found = false;
97 // try jumping to .cxx .cpp and .c in order
98 if(cmSystemTools::FileExists(cxxFile.c_str()))
100 found = true;
102 for(std::vector<std::string>::iterator i =
103 this->IncludeDirectories.begin();
104 i != this->IncludeDirectories.end(); ++i)
106 std::string path = *i;
107 path = path + "/";
108 path = path + cxxFile;
109 if(cmSystemTools::FileExists(path.c_str()))
111 found = true;
114 if (!found)
116 cxxFile = root + ".cpp";
117 if(cmSystemTools::FileExists(cxxFile.c_str()))
119 found = true;
121 for(std::vector<std::string>::iterator i =
122 this->IncludeDirectories.begin();
123 i != this->IncludeDirectories.end(); ++i)
125 std::string path = *i;
126 path = path + "/";
127 path = path + cxxFile;
128 if(cmSystemTools::FileExists(path.c_str()))
130 found = true;
134 if (!found)
136 cxxFile = root + ".c";
137 if(cmSystemTools::FileExists(cxxFile.c_str()))
139 found = true;
141 for(std::vector<std::string>::iterator i =
142 this->IncludeDirectories.begin();
143 i != this->IncludeDirectories.end(); ++i)
145 std::string path = *i;
146 path = path + "/";
147 path = path + cxxFile;
148 if(cmSystemTools::FileExists(path.c_str()))
150 found = true;
154 if (!found)
156 cxxFile = root + ".txx";
157 if(cmSystemTools::FileExists(cxxFile.c_str()))
159 found = true;
161 for(std::vector<std::string>::iterator i =
162 this->IncludeDirectories.begin();
163 i != this->IncludeDirectories.end(); ++i)
165 std::string path = *i;
166 path = path + "/";
167 path = path + cxxFile;
168 if(cmSystemTools::FileExists(path.c_str()))
170 found = true;
174 if (found)
176 this->AddDependency(info, cxxFile.c_str());
183 // cmOutputRequiredFilesCommand
184 bool cmOutputRequiredFilesCommand
185 ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
187 if(args.size() != 2 )
189 this->SetError("called with incorrect number of arguments");
190 return false;
193 // store the arg for final pass
194 this->File = args[0];
195 this->OutputFile = args[1];
197 // compute the list of files
198 cmLBDepend md;
199 md.SetMakefile(this->Makefile);
200 md.AddSearchPath(this->Makefile->GetStartDirectory());
201 // find the depends for a file
202 const cmDependInformation *info = md.FindDependencies(this->File.c_str());
203 if (info)
205 // write them out
206 FILE *fout = fopen(this->OutputFile.c_str(),"w");
207 if(!fout)
209 std::string err = "Can not open output file: ";
210 err += this->OutputFile;
211 this->SetError(err.c_str());
212 return false;
214 std::set<cmDependInformation const*> visited;
215 this->ListDependencies(info,fout, &visited);
216 fclose(fout);
219 return true;
222 void cmOutputRequiredFilesCommand::
223 ListDependencies(cmDependInformation const *info,
224 FILE *fout,
225 std::set<cmDependInformation const*> *visited)
227 // add info to the visited set
228 visited->insert(info);
229 // now recurse with info's dependencies
230 for(cmDependInformation::DependencySetType::const_iterator d =
231 info->DependencySet.begin();
232 d != info->DependencySet.end(); ++d)
234 if (visited->find(*d) == visited->end())
236 if(info->FullPath != "")
238 std::string tmp = (*d)->FullPath;
239 std::string::size_type pos = tmp.rfind('.');
240 if(pos != std::string::npos && (tmp.substr(pos) != ".h"))
242 tmp = tmp.substr(0, pos);
243 fprintf(fout,"%s\n",(*d)->FullPath.c_str());
246 this->ListDependencies(*d,fout,visited);