- Implement simple case of RtlInsertUnicodePrefix where a new node entry needs to...
[reactos.git] / reactos / tools / rbuild / backend / devcpp / devcpp.cpp
1 /*
2 * Copyright (C) 2005 Trevor McCort
3 * Copyright (C) 2005 Casper S. Hornstrup
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 #ifdef _MSC_VER
20 #pragma warning ( disable : 4786 )
21 #endif//_MSC_VER
22
23 #include <iostream>
24 #include <fstream>
25 #include <string>
26
27 #include "devcpp.h"
28
29 using namespace std;
30
31 static class DevCppFactory : public Backend::Factory
32 {
33 public:
34
35 DevCppFactory() : Factory("devcpp") {}
36 Backend *operator() (Project &project,
37 Configuration& configuration)
38 {
39 return new DevCppBackend(project, configuration);
40 }
41
42 } factory;
43
44
45 DevCppBackend::DevCppBackend(Project &project,
46 Configuration& configuration) : Backend(project, configuration)
47 {
48 m_unitCount = 0;
49 }
50
51 void DevCppBackend::Process()
52 {
53 string filename = ProjectNode.name + ".dev";
54
55 cout << "Creating Dev-C++ project: " << filename << endl;
56
57 ProcessModules();
58
59 m_devFile.open(filename.c_str());
60
61 if(!m_devFile.is_open())
62 {
63 cout << "Could not open file." << endl;
64 return;
65 }
66
67 m_devFile << "[Project]" << endl;
68
69 m_devFile << "FileName=" << filename << endl
70 << "Name=" << ProjectNode.name << endl
71 << "UnitCount=" << m_unitCount << endl
72 << "Type=1" << endl
73 << "Ver=1" << endl
74 << "ObjFiles=" << endl
75 << "Includes=" << endl
76 << "Libs=" << endl
77 << "PrivateResource=" << endl
78 << "ResourceIncludes=" << endl
79 << "MakeIncludes=" << endl
80 << "Compiler=" << endl
81 << "CppCompiler=" << endl
82 << "Linker=" << endl
83 << "IsCpp=1" << endl
84 << "Icon=" << endl
85 << "ExeOutput=" << endl
86 << "ObjectOutput=" << endl
87 << "OverrideOutput=0" << endl
88 << "OverrideOutputName=" << endl
89 << "HostApplication=" << endl
90 << "CommandLine=" << endl
91 << "UseCustomMakefile=1" << endl
92 << "CustomMakefile=" << ProjectNode.makefile << endl
93 << "IncludeVersionInto=0" << endl
94 << "SupportXPThemes=0" << endl
95 << "CompilerSet=0" << endl
96
97 << "CompilerSettings=0000000000000000000000" << endl;
98
99 OutputFolders();
100
101 m_devFile << endl << endl;
102
103 OutputFileUnits();
104
105 m_devFile.close();
106
107 // Dev-C++ needs a makefile, so use the MinGW backend to create one.
108
109 cout << "Creating Makefile: " << ProjectNode.makefile << endl;
110
111 Backend *backend = Backend::Factory::Create("mingw",
112 ProjectNode,
113 configuration );
114 backend->Process();
115 delete backend;
116
117 cout << "Done." << endl << endl;
118
119 cout << "You may want to disable Class browsing (see below) before you open this project in Dev-C++, as the "
120 << "parsing required for large projects can take quite awhile."
121 << endl << endl
122 << "(Tools->Editor Options->Class browsing->Enable class browsing check box)"
123 << endl << endl;
124 }
125
126 void DevCppBackend::ProcessModules()
127 {
128 for(size_t i = 0; i < ProjectNode.modules.size(); i++)
129 {
130 Module &module = *ProjectNode.modules[i];
131
132 for(size_t k = 0; k < module.non_if_data.files.size(); k++)
133 {
134 File &file = *module.non_if_data.files[k];
135
136 ProcessFile(file.name);
137 }
138 }
139 }
140
141 bool FileExists(string &filename)
142 {
143 ifstream file(filename.c_str());
144
145 if(!file.is_open())
146 return false;
147
148 file.close();
149 return true;
150 }
151
152 void DevCppBackend::ProcessFile(string &filepath)
153 {
154 // Remove the .\ at the start of the filenames
155 if ((filepath[0] == '.') && (filepath[1] == '\\')) filepath.erase(0, 2);
156
157 if(!FileExists(filepath))
158 return;
159
160 // Change the \ to /
161 for(size_t i = 0; i < filepath.length(); i++)
162 {
163 if(filepath[i] == '\\')
164 filepath[i] = '/';
165 }
166
167 // Remove the filename from the path
168 string folder = "";
169
170 size_t pos = filepath.rfind(string("/"), filepath.length() - 1);
171
172 if(pos != string::npos)
173 {
174 folder = filepath;
175 folder.erase(pos, folder.length() - pos);
176 }
177
178 FileUnit fileUnit;
179 fileUnit.filename = filepath;
180 fileUnit.folder = folder;
181
182 m_fileUnits.push_back(fileUnit);
183
184 if(folder != "")
185 AddFolders(folder);
186
187 m_unitCount++;
188 }
189
190 bool DevCppBackend::CheckFolderAdded(string &folder)
191 {
192 for(size_t i = 0; i < m_folders.size(); i++)
193 {
194 if(m_folders[i] == folder)
195 return true;
196 }
197
198 return false;
199 }
200
201 void DevCppBackend::AddFolders(string &folder)
202 {
203 // Check if this folder was already added. true if it was, false otherwise.
204 if(CheckFolderAdded(folder))
205 return;
206
207 m_folders.push_back(folder);
208
209 size_t pos = folder.rfind(string("/"), folder.length() - 1);
210
211 if(pos == string::npos)
212 return;
213
214 folder.erase(pos, folder.length() - pos);
215 AddFolders(folder);
216 }
217
218 void DevCppBackend::OutputFolders()
219 {
220 m_devFile << "Folders=";
221
222 for(size_t i = 0; i < m_folders.size(); i++)
223 {
224 if(i > 0)
225 m_devFile << ",";
226
227 m_devFile << m_folders[i];
228 }
229 }
230
231 void DevCppBackend::OutputFileUnits()
232 {
233 for(size_t i = 0; i < m_fileUnits.size(); i++)
234 {
235 m_devFile << "[Unit" << i + 1 << "]" << endl;
236
237
238 m_devFile << "FileName=" << m_fileUnits[i].filename << endl;
239 m_devFile << "CompileCpp=1" << endl;
240 m_devFile << "Folder=" << m_fileUnits[i].folder << endl;
241 m_devFile << "Compile=1" << endl;
242 m_devFile << "Link=1" << endl;
243 m_devFile << "Priority=1000" << endl;
244 m_devFile << "OverrideBuildCmd=0" << endl;
245 m_devFile << "BuildCmd=" << endl << endl;;
246 }
247 }