Imported Upstream version 2.8.12.2
[platform/upstream/cmake.git] / Source / cmGeneratorExpressionEvaluationFile.cxx
1 /*============================================================================
2   CMake - Cross Platform Makefile Generator
3   Copyright 2013 Stephen Kelly <steveire@gmail.com>
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
13 #include "cmGeneratorExpressionEvaluationFile.h"
14
15 #include "cmMakefile.h"
16
17 #include <assert.h>
18
19 //----------------------------------------------------------------------------
20 cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile(
21         const std::string &input,
22         cmsys::auto_ptr<cmCompiledGeneratorExpression> outputFileExpr,
23         cmMakefile *makefile,
24         cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
25         bool inputIsContent)
26   : Input(input),
27     OutputFileExpr(outputFileExpr),
28     Makefile(makefile),
29     Condition(condition),
30     InputIsContent(inputIsContent)
31 {
32 }
33
34 //----------------------------------------------------------------------------
35 void cmGeneratorExpressionEvaluationFile::Generate(const char *config,
36               cmCompiledGeneratorExpression* inputExpression,
37               std::map<std::string, std::string> &outputFiles)
38 {
39   std::string rawCondition = this->Condition->GetInput();
40   if (!rawCondition.empty())
41     {
42     std::string condResult = this->Condition->Evaluate(this->Makefile, config);
43     if (condResult == "0")
44       {
45       return;
46       }
47     if (condResult != "1")
48       {
49       cmOStringStream e;
50       e << "Evaluation file condition \"" << rawCondition << "\" did "
51           "not evaluate to valid content. Got \"" << condResult << "\".";
52       this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
53       return;
54       }
55     }
56
57   const std::string outputFileName
58                     = this->OutputFileExpr->Evaluate(this->Makefile, config);
59   const std::string outputContent
60                           = inputExpression->Evaluate(this->Makefile, config);
61
62   std::map<std::string, std::string>::iterator it
63                                           = outputFiles.find(outputFileName);
64
65   if(it != outputFiles.end())
66     {
67     if (it->second == outputContent)
68       {
69       return;
70       }
71     cmOStringStream e;
72     e << "Evaluation file to be written multiple times for different "
73          "configurations with different content:\n  " << outputFileName;
74     this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
75     return;
76     }
77
78   this->Files.push_back(outputFileName);
79   outputFiles[outputFileName] = outputContent;
80
81   std::ofstream fout(outputFileName.c_str());
82
83   if(!fout)
84     {
85     cmOStringStream e;
86     e << "Evaluation file \"" << outputFileName << "\" cannot be written.";
87     this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
88     return;
89     }
90
91   fout << outputContent;
92
93   fout.close();
94 }
95
96 //----------------------------------------------------------------------------
97 void cmGeneratorExpressionEvaluationFile::Generate()
98 {
99   std::string inputContent;
100   if (this->InputIsContent)
101     {
102     inputContent = this->Input;
103     }
104   else
105     {
106     std::ifstream fin(this->Input.c_str());
107     if(!fin)
108       {
109       cmOStringStream e;
110       e << "Evaluation file \"" << this->Input << "\" cannot be read.";
111       this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
112       return;
113       }
114
115     std::string line;
116     std::string sep;
117     while(cmSystemTools::GetLineFromStream(fin, line))
118       {
119       inputContent += sep + line;
120       sep = "\n";
121       }
122     inputContent += sep;
123     }
124
125   cmListFileBacktrace lfbt = this->OutputFileExpr->GetBacktrace();
126   cmGeneratorExpression contentGE(lfbt);
127   cmsys::auto_ptr<cmCompiledGeneratorExpression> inputExpression
128                                               = contentGE.Parse(inputContent);
129
130   std::map<std::string, std::string> outputFiles;
131
132   std::vector<std::string> allConfigs;
133   this->Makefile->GetConfigurations(allConfigs);
134
135   if (allConfigs.empty())
136     {
137     this->Generate(0, inputExpression.get(), outputFiles);
138     }
139   else
140     {
141     for(std::vector<std::string>::const_iterator li = allConfigs.begin();
142         li != allConfigs.end(); ++li)
143       {
144       this->Generate(li->c_str(), inputExpression.get(), outputFiles);
145       if(cmSystemTools::GetFatalErrorOccured())
146         {
147         return;
148         }
149       }
150     }
151 }