packaging: Initial packaging
[platform/upstream/cmake.git] / Source / cmUseMangledMesaCommand.cxx
1 /*============================================================================
2   CMake - Cross Platform Makefile Generator
3   Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
4
5   Distributed under the OSI-approved BSD License (the "License");
6   see accompanying file Copyright.txt for details.
7
8   This software is distributed WITHOUT ANY WARRANTY; without even the
9   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10   See the License for more information.
11 ============================================================================*/
12 #include "cmUseMangledMesaCommand.h"
13 #include "cmSystemTools.h"
14
15 #include <cmsys/RegularExpression.hxx>
16
17 // cmUseMangledMesaCommand
18 bool cmUseMangledMesaCommand
19 ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
20 {
21   // expected two arguments:
22   // arguement one: the full path to gl_mangle.h
23   // arguement two : directory for output of edited headers
24   if(args.size() != 2)
25     {
26     this->SetError("called with incorrect number of arguments");
27     return false;
28     }
29   const char* inputDir = args[0].c_str();
30   std::string glh = inputDir;
31   glh += "/";
32   glh += "gl.h";
33   if(!cmSystemTools::FileExists(glh.c_str()))
34     {
35     std::string e = "Bad path to Mesa, could not find: ";
36     e += glh;
37     e += " ";
38     this->SetError(e.c_str());
39     return false;
40     }
41   const char* destDir = args[1].c_str();
42   std::vector<std::string> files;
43   cmSystemTools::Glob(inputDir, "\\.h$", files);
44   if(files.size() == 0)
45     {
46     cmSystemTools::Error("Could not open Mesa Directory ", inputDir);
47     return false;
48     }
49   cmSystemTools::MakeDirectory(destDir);
50   for(std::vector<std::string>::iterator i = files.begin();
51       i != files.end(); ++i)
52     {
53     std::string path = inputDir;
54     path += "/";
55     path += *i;
56     this->CopyAndFullPathMesaHeader(path.c_str(), destDir);
57     }
58
59   return true;
60 }
61
62 void
63 cmUseMangledMesaCommand::
64 CopyAndFullPathMesaHeader(const char* source,
65                           const char* outdir)
66 {
67   std::string dir, file;
68   cmSystemTools::SplitProgramPath(source, dir, file);
69   std::string outFile = outdir;
70   outFile += "/";
71   outFile += file;
72   std::string tempOutputFile = outFile;
73   tempOutputFile += ".tmp";
74   std::ofstream fout(tempOutputFile.c_str());
75   if(!fout)
76     {
77     cmSystemTools::Error("Could not open file for write in copy operation: ",
78                          tempOutputFile.c_str(), outdir);
79     cmSystemTools::ReportLastSystemError("");
80     return;
81     }
82   std::ifstream fin(source);
83   if(!fin)
84     {
85     cmSystemTools::Error("Could not open file for read in copy operation",
86                          source);
87     return;
88     }
89   // now copy input to output and expand variables in the
90   // input file at the same time
91   std::string inLine;
92   // regular expression for any #include line
93   cmsys::RegularExpression includeLine(
94     "^[ \t]*#[ \t]*include[ \t]*[<\"]([^\">]+)[\">]");
95   // regular expression for gl/ or GL/ in a file (match(1) of above)
96   cmsys::RegularExpression glDirLine("(gl|GL)(/|\\\\)([^<\"]+)");
97   // regular expression for gl GL or xmesa in a file (match(1) of above)
98   cmsys::RegularExpression glLine("(gl|GL|xmesa)");
99   while(cmSystemTools::GetLineFromStream(fin,inLine))
100     {
101     if(includeLine.find(inLine.c_str()))
102       {
103       std::string includeFile = includeLine.match(1);
104       if(glDirLine.find(includeFile.c_str()))
105         {
106         std::string gfile = glDirLine.match(3);
107         fout << "#include \"" << outdir << "/" << gfile.c_str() << "\"\n";
108         }
109       else if(glLine.find(includeFile.c_str()))
110         {
111         fout << "#include \"" << outdir << "/" <<
112           includeLine.match(1).c_str() << "\"\n";
113         }
114       else
115         {
116         fout << inLine << "\n";
117         }
118       }
119     else
120       {
121       fout << inLine << "\n";
122       }
123     }
124   // close the files before attempting to copy
125   fin.close();
126   fout.close();
127   cmSystemTools::CopyFileIfDifferent(tempOutputFile.c_str(),
128                                      outFile.c_str());
129   cmSystemTools::RemoveFile(tempOutputFile.c_str());
130 }
131