8
#include <wx/textfile.h>
10
#include <wx/xml/xml.h>
11
#ifdef __WXMSW__ // for wxRegKey
12
#include <wx/msw/registry.h>
15
#include "compilerXML.h"
17
CompilerXML::CompilerXML(const wxString& name, const wxString& ID, const wxString& file)
18
: Compiler(wxGetTranslation(name), ID), m_fileName(file)
20
wxXmlDocument compiler;
21
compiler.Load(m_fileName);
22
m_Weight = wxAtoi(compiler.GetRoot()->GetAttribute(wxT("weight"), wxT("100")));
23
m_MultiLineMessages = _T("0") != compiler.GetRoot()->GetAttribute(wxT("multilinemessages"), wxT("0"));
27
CompilerXML::~CompilerXML()
31
Compiler* CompilerXML::CreateCopy()
33
return (new CompilerXML(*this));
36
AutoDetectResult CompilerXML::AutoDetectInstallationDir()
38
wxXmlDocument compiler;
39
compiler.Load(m_fileName);
40
wxXmlNode* node = compiler.GetRoot()->GetChildren();
44
wxGetEnv(wxT("PATH"), &path);
45
wxString origPath = path;
46
if (!m_MasterPath.IsEmpty())
48
path += wxPATH_SEP + m_MasterPath;
49
wxSetEnv(wxT("PATH"), path);
54
if (node->GetName() == wxT("if") && node->GetChildren())
56
if (EvalXMLCondition(node))
58
node = node->GetChildren();
62
else if (node->GetNext() && node->GetNext()->GetName() == wxT("else") &&
63
node->GetNext()->GetChildren())
65
node = node->GetNext()->GetChildren();
70
else if (node->GetName() == wxT("Path") && node->GetChildren())
72
wxString value = node->GetAttribute(wxT("type"), wxEmptyString);
73
if (value == wxT("master"))
75
else if (value == wxT("extra"))
77
else if (value == wxT("include"))
79
else if (value == wxT("resource"))
81
else if (value == wxT("lib"))
83
if (sm != master || m_MasterPath.IsEmpty())
85
node = node->GetChildren();
92
else if (node->GetName() == wxT("Search") && sm != none)
95
if (node->GetAttribute(wxT("envVar"), &value))
98
wxGetEnv(value, &pathValues);
99
if (!pathValues.IsEmpty())
101
wxArrayString pathArray = GetArrayFromString(pathValues, wxPATH_SEP);
102
wxString targ = GetExecName(node->GetAttribute(wxT("for"), wxEmptyString));
103
for (size_t i = 0; i < pathArray.GetCount(); ++i)
105
if ((targ.IsEmpty() && wxDirExists(pathArray[i])) || wxFileExists(pathArray[i] + wxFILE_SEP_PATH + targ))
107
if (AddPath(pathArray[i], sm, wxAtoi(compiler.GetRoot()->GetAttribute(wxT("rmDirs"), wxT("0")))))
110
else if (sm == master && ( (targ.IsEmpty() && wxDirExists(value + wxFILE_SEP_PATH + wxT("bin")))
111
|| wxFileExists(pathArray[i] + wxFILE_SEP_PATH + wxT("bin") + wxFILE_SEP_PATH + targ)) )
113
if (AddPath(pathArray[i] + wxFILE_SEP_PATH + wxT("bin"), sm))
119
else if (node->GetAttribute(wxT("path"), &value))
121
wxString targ = GetExecName(node->GetAttribute(wxT("for"), wxEmptyString));
124
path = wxFindFirstFile(value, wxDIR);
125
if (!path.IsEmpty() &&
126
((targ.IsEmpty() && wxDirExists(path)) ||
127
wxFileExists(path + wxFILE_SEP_PATH + targ) ||
128
wxFileExists(path + wxFILE_SEP_PATH + wxT("bin") + wxFILE_SEP_PATH + targ)))
133
else if ((targ.IsEmpty() && wxDirExists(value)) || wxFileExists(value + wxFILE_SEP_PATH + targ))
135
else if (sm == master && ((targ.IsEmpty() && wxDirExists(value + wxFILE_SEP_PATH + wxT("bin"))) || wxFileExists(value + wxFILE_SEP_PATH + wxT("bin") + wxFILE_SEP_PATH + targ)))
136
AddPath(value + wxFILE_SEP_PATH + wxT("bin"), sm);
138
else if (node->GetAttribute(wxT("file"), &value))
140
wxString regexp = node->GetAttribute(wxT("regex"), wxEmptyString);
141
int idx = wxAtoi(node->GetAttribute(wxT("index"), wxT("0")));
143
if (wxFileExists(value) && re.Compile(regexp))
145
wxTextFile file(value);
146
for (size_t i = 0; i < file.GetLineCount(); ++i)
148
if (re.Matches(file.GetLine(i)))
150
AddPath(re.GetMatch(file.GetLine(i), idx), sm);
151
if (sm == master && !m_MasterPath.IsEmpty())
157
#ifdef __WXMSW__ // for wxRegKey
158
else if (node->GetAttribute(wxT("registry"), &value))
163
if (key.Exists() && key.Open(wxRegKey::Read))
165
key.QueryValue(node->GetAttribute(wxT("value"), wxEmptyString), dir);
166
if (!dir.IsEmpty() && wxDirExists(dir))
173
else if (node->GetName() == wxT("Add"))
176
if (node->GetAttribute(wxT("cFlag"), &value))
177
AddCompilerOption(value);
178
else if (node->GetAttribute(wxT("lFlag"), &value))
179
AddLinkerOption(value);
180
else if (node->GetAttribute(wxT("lib"), &value))
185
wxXmlNode* child = node->GetChildren();
188
if (child->GetType() == wxXML_TEXT_NODE || child->GetType() == wxXML_CDATA_SECTION_NODE)
189
path << child->GetContent();
190
else if (child->GetName() == wxT("master"))
191
path << m_MasterPath;
192
else if (child->GetName() == wxT("separator"))
193
path << wxFILE_SEP_PATH;
194
else if (child->GetName() == wxT("envVar"))
196
value = child->GetAttribute(wxT("default"), wxEmptyString);
197
wxGetEnv(child->GetAttribute(wxT("value"), wxEmptyString), &value);
200
child = child->GetNext();
202
AddPath(path.Trim().Trim(false), sm);
205
else if (node->GetName() == wxT("Fallback") && sm != none)
207
wxString value = node->GetAttribute(wxT("path"), wxEmptyString);
211
if (m_MasterPath.IsEmpty())
215
if (m_ExtraPaths.IsEmpty())
219
if (m_IncludeDirs.IsEmpty())
223
if (m_ResIncludeDirs.IsEmpty())
227
if (m_LibDirs.IsEmpty())
230
case none: // fall-through
235
while ( (!node->GetNext() || (sm == master && !m_MasterPath.IsEmpty())) &&
238
node = node->GetParent();
239
if(node->GetName() == wxT("Path"))
245
node = node->GetNext();
247
wxSetEnv(wxT("PATH"), origPath);
249
if ( wxFileExists(m_MasterPath + wxFILE_SEP_PATH + wxT("bin") + wxFILE_SEP_PATH + m_Programs.C)
250
|| wxFileExists(m_MasterPath + wxFILE_SEP_PATH + m_Programs.C)
251
|| (GetID() == wxT("null")) ) // Special case so "No Compiler" is valid
255
for (size_t i = 0; i < m_ExtraPaths.GetCount(); ++i)
257
if (wxFileExists(m_ExtraPaths[i] + wxFILE_SEP_PATH + m_Programs.C))
263
bool CompilerXML::AddPath(const wxString& pth, SearchMode sm, int rmDirs)
265
wxFileName fn(pth + wxFILE_SEP_PATH);
266
fn.Normalize(wxPATH_NORM_ENV_VARS|wxPATH_NORM_DOTS);
267
for (int i = rmDirs; i > 0; --i)
269
wxString path = fn.GetPath();
273
if (path.AfterLast(wxFILE_SEP_PATH) == wxT("bin"))
274
m_MasterPath = path.BeforeLast(wxFILE_SEP_PATH);
279
if (m_ExtraPaths.Index(path, !platform::windows) == wxNOT_FOUND)
280
m_ExtraPaths.Add(path);
286
AddResourceIncludeDir(path);
291
case none: // fall-through