Code::Blocks  SVN r11506
compilerXML.cpp
Go to the documentation of this file.
1 #include <sdk.h>
2 
3 #ifndef CB_PRECOMP
4  #include <wx/arrstr.h>
5 #endif // CB_PRECOMP
6 
7 #include <wx/filefn.h>
8 #include <wx/textfile.h>
9 #include <wx/regex.h>
10 #include <wx/xml/xml.h>
11 #ifdef __WXMSW__ // for wxRegKey
12  #include <wx/msw/registry.h>
13 #endif // __WXMSW__
14 
15 #include "compilerXML.h"
16 
17 CompilerXML::CompilerXML(const wxString& name, const wxString& ID, const wxString& file)
18  : Compiler(wxGetTranslation(name), ID), m_fileName(file)
19 {
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"));
24  Reset();
25 }
26 
28 {
29 }
30 
32 {
33  return (new CompilerXML(*this));
34 }
35 
37 {
38  wxXmlDocument compiler;
39  compiler.Load(m_fileName);
40  wxXmlNode* node = compiler.GetRoot()->GetChildren();
41  int depth = 0;
42  SearchMode sm = none;
43  wxString path;
44  wxGetEnv(wxT("PATH"), &path);
45  wxString origPath = path;
46  if (!m_MasterPath.IsEmpty())
47  {
48  path += wxPATH_SEP + m_MasterPath;
49  wxSetEnv(wxT("PATH"), path);
50  m_MasterPath.Clear();
51  }
52  while (node)
53  {
54  if (node->GetName() == wxT("if") && node->GetChildren())
55  {
56  if (EvalXMLCondition(node))
57  {
58  node = node->GetChildren();
59  ++depth;
60  continue;
61  }
62  else if (node->GetNext() && node->GetNext()->GetName() == wxT("else") &&
63  node->GetNext()->GetChildren())
64  {
65  node = node->GetNext()->GetChildren();
66  ++depth;
67  continue;
68  }
69  }
70  else if (node->GetName() == wxT("Path") && node->GetChildren())
71  {
72  wxString value = node->GetAttribute(wxT("type"), wxEmptyString);
73  if (value == wxT("master"))
74  sm = master;
75  else if (value == wxT("extra"))
76  sm = extra;
77  else if (value == wxT("include"))
78  sm = include;
79  else if (value == wxT("resource"))
80  sm = resource;
81  else if (value == wxT("lib"))
82  sm = lib;
83  if (sm != master || m_MasterPath.IsEmpty())
84  {
85  node = node->GetChildren();
86  ++depth;
87  continue;
88  }
89  else
90  sm = none;
91  }
92  else if (node->GetName() == wxT("Search") && sm != none)
93  {
94  wxString value;
95  if (node->GetAttribute(wxT("envVar"), &value))
96  {
97  wxString pathValues;
98  wxGetEnv(value, &pathValues);
99  if (!pathValues.IsEmpty())
100  {
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)
104  {
105  if ((targ.IsEmpty() && wxDirExists(pathArray[i])) || wxFileExists(pathArray[i] + wxFILE_SEP_PATH + targ))
106  {
107  if (AddPath(pathArray[i], sm, wxAtoi(compiler.GetRoot()->GetAttribute(wxT("rmDirs"), wxT("0")))))
108  break;
109  }
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)) )
112  {
113  if (AddPath(pathArray[i] + wxFILE_SEP_PATH + wxT("bin"), sm))
114  break;
115  }
116  }
117  }
118  }
119  else if (node->GetAttribute(wxT("path"), &value))
120  {
121  wxString targ = GetExecName(node->GetAttribute(wxT("for"), wxEmptyString));
122  if (wxIsWild(value))
123  {
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)))
129  {
130  AddPath(path, sm);
131  }
132  }
133  else if ((targ.IsEmpty() && wxDirExists(value)) || wxFileExists(value + wxFILE_SEP_PATH + targ))
134  AddPath(value, sm);
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);
137  }
138  else if (node->GetAttribute(wxT("file"), &value))
139  {
140  wxString regexp = node->GetAttribute(wxT("regex"), wxEmptyString);
141  int idx = wxAtoi(node->GetAttribute(wxT("index"), wxT("0")));
142  wxRegEx re;
143  if (wxFileExists(value) && re.Compile(regexp))
144  {
145  wxTextFile file(value);
146  for (size_t i = 0; i < file.GetLineCount(); ++i)
147  {
148  if (re.Matches(file.GetLine(i)))
149  {
150  AddPath(re.GetMatch(file.GetLine(i), idx), sm);
151  if (sm == master && !m_MasterPath.IsEmpty())
152  break;
153  }
154  }
155  }
156  }
157 #ifdef __WXMSW__ // for wxRegKey
158  else if (node->GetAttribute(wxT("registry"), &value))
159  {
160  wxRegKey key;
161  wxString dir;
162  key.SetName(value);
163  if (key.Exists() && key.Open(wxRegKey::Read))
164  {
165  key.QueryValue(node->GetAttribute(wxT("value"), wxEmptyString), dir);
166  if (!dir.IsEmpty() && wxDirExists(dir))
167  AddPath(dir, sm);
168  key.Close();
169  }
170  }
171 #endif // __WXMSW__
172  }
173  else if (node->GetName() == wxT("Add"))
174  {
175  wxString value;
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))
181  AddLinkLib(value);
182  else if (sm != none)
183  {
184  path.Clear();
185  wxXmlNode* child = node->GetChildren();
186  while (child)
187  {
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"))
195  {
196  value = child->GetAttribute(wxT("default"), wxEmptyString);
197  wxGetEnv(child->GetAttribute(wxT("value"), wxEmptyString), &value);
198  path << value;
199  }
200  child = child->GetNext();
201  }
202  AddPath(path.Trim().Trim(false), sm);
203  }
204  }
205  else if (node->GetName() == wxT("Fallback") && sm != none)
206  {
207  wxString value = node->GetAttribute(wxT("path"), wxEmptyString);
208  switch (sm)
209  {
210  case master:
211  if (m_MasterPath.IsEmpty())
212  AddPath(value, sm);
213  break;
214  case extra:
215  if (m_ExtraPaths.IsEmpty())
216  AddPath(value, sm);
217  break;
218  case include:
219  if (m_IncludeDirs.IsEmpty())
220  AddPath(value, sm);
221  break;
222  case resource:
224  AddPath(value, sm);
225  break;
226  case lib:
227  if (m_LibDirs.IsEmpty())
228  AddPath(value, sm);
229  break;
230  case none: // fall-through
231  default:
232  break;
233  }
234  }
235  while ( (!node->GetNext() || (sm == master && !m_MasterPath.IsEmpty())) &&
236  depth > 0 )
237  {
238  node = node->GetParent();
239  if(node->GetName() == wxT("Path"))
240  {
241  sm = none;
242  }
243  --depth;
244  }
245  node = node->GetNext();
246  }
247  wxSetEnv(wxT("PATH"), origPath);
248 
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
252  {
253  return adrDetected;
254  }
255  for (size_t i = 0; i < m_ExtraPaths.GetCount(); ++i)
256  {
257  if (wxFileExists(m_ExtraPaths[i] + wxFILE_SEP_PATH + m_Programs.C))
258  return adrDetected;
259  }
260  return adrGuessed;
261 }
262 
263 bool CompilerXML::AddPath(const wxString& pth, SearchMode sm, int rmDirs)
264 {
265  wxFileName fn(pth + wxFILE_SEP_PATH);
267  for (int i = rmDirs; i > 0; --i)
268  fn.RemoveLastDir();
269  wxString path = fn.GetPath();
270  switch (sm)
271  {
272  case master:
273  if (path.AfterLast(wxFILE_SEP_PATH) == wxT("bin"))
274  m_MasterPath = path.BeforeLast(wxFILE_SEP_PATH);
275  else
276  m_MasterPath = path;
277  return true;
278  case extra:
279  if (m_ExtraPaths.Index(path, !platform::windows) == wxNOT_FOUND)
280  m_ExtraPaths.Add(path);
281  break;
282  case include:
283  AddIncludeDir(path);
284  break;
285  case resource:
286  AddResourceIncludeDir(path);
287  break;
288  case lib:
289  AddLibDir(path);
290  break;
291  case none: // fall-through
292  default:
293  break;
294  }
295  return false;
296 }
bool AddPath(const wxString &pth, SearchMode sm, int rmDirs=0)
wxString AfterLast(wxUniChar ch) const
DLLIMPORT wxArrayString GetArrayFromString(const wxString &text, const wxString &separator=DEFAULT_ARRAY_SEP, bool trimSpaces=true)
Definition: globals.cpp:134
bool EvalXMLCondition(const wxXmlNode *node)
Definition: compiler.cpp:1179
bool wxGetEnv(const wxString &var, wxString *value)
wxXmlNode * GetRoot() const
bool GetAttribute(const wxString &attrName, wxString *value) const
bool wxFileExists(const wxString &filename)
bool m_MultiLineMessages
Definition: compiler.h:423
int Index(const wxString &sz, bool bCase=true, bool bFromEnd=false) const
wxArrayString m_ResIncludeDirs
bool wxDirExists(const wxString &dirname)
virtual void Reset()
Reset settings to defaults.
Definition: compiler.cpp:157
#define _T(string)
virtual void AddIncludeDir(const wxString &option)
size_t GetLineCount() const
wxString BeforeLast(wxUniChar ch, wxString *rest=NULL) const
bool QueryValue(const wxString &szValue, wxString &strValue, bool raw) const
wxXmlNode * GetParent() const
virtual Compiler * CreateCopy()
Implement this in new compilers, to return a new copy.
Definition: compilerXML.cpp:31
CompilerPrograms m_Programs
Definition: compiler.h:412
void Close()
const wxString & GetName() const
#define wxT(string)
#define wxNOT_FOUND
AutoDetectResult
Definition: compiler.h:190
const wxString & GetContent() const
wxXmlNode * GetNext() const
const wxString & GetID() const
Get this compiler&#39;s unique ID.
Definition: compiler.h:351
virtual void AddResourceIncludeDir(const wxString &option)
wxXmlNodeType GetType() const
void RemoveLastDir()
const wxString & wxGetTranslation(const wxString &string, const wxString &domain=wxEmptyString)
virtual void AddLinkLib(const wxString &option)
virtual void AddCompilerOption(const wxString &option)
virtual void AddLibDir(const wxString &option)
bool wxIsWild(const wxString &pattern)
wxXmlNode * GetChildren() const
wxArrayString m_ExtraPaths
Definition: compiler.h:410
bool IsEmpty() const
wxString GetExecName(const wxString &name)
Definition: compiler.cpp:1270
wxString wxEmptyString
wxString & Trim(bool fromRight=true)
int wxAtoi(const wxString &str)
Definition: id.h:15
Abstract base class for compilers.
Definition: compiler.h:274
bool IsEmpty() const
wxString wxFindFirstFile(const wxString &spec, int flags=0)
void Clear()
wxString GetPath(int flags=wxPATH_GET_VOLUME, wxPathFormat format=wxPATH_NATIVE) const
wxString C
Definition: compiler.h:199
wxString m_MasterPath
Definition: compiler.h:409
wxString & GetLine(size_t n)
virtual AutoDetectResult AutoDetectInstallationDir()
Try to auto-detect the compiler&#39;s installation directory.
Definition: compilerXML.cpp:36
bool Exists() const
size_t Add(const wxString &str, size_t copies=1)
CompilerXML(const wxString &name, const wxString &ID, const wxString &file)
Definition: compilerXML.cpp:17
virtual ~CompilerXML()
Definition: compilerXML.cpp:27
bool Normalize(int flags=wxPATH_NORM_ALL, const wxString &cwd=wxEmptyString, wxPathFormat format=wxPATH_NATIVE)
bool Open(AccessMode mode=Write)
size_t GetCount() const
virtual bool Load(const wxString &filename, const wxString &encoding="UTF-8", int flags=wxXMLDOC_NONE)
wxString m_fileName
Definition: compilerXML.h:33
virtual void AddLinkerOption(const wxString &option)
int m_Weight
Definition: compiler.h:422
bool wxSetEnv(const wxString &var, const wxString &value)
void SetName(const wxString &strKey)
wxArrayString m_IncludeDirs