Code::Blocks  SVN r11506
compilerfactory.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3
3  * http://www.gnu.org/licenses/lgpl-3.0.html
4  *
5  * $Revision: 9426 $
6  * $Id: compilerfactory.cpp 9426 2013-11-02 19:42:20Z alpha0010 $
7  * $HeadURL: https://svn.code.sf.net/p/codeblocks/code/trunk/src/sdk/compilerfactory.cpp $
8  */
9 
10 #include "sdk_precomp.h"
11 
12 #ifndef CB_PRECOMP
13  #include <wx/choicdlg.h> // wxSingleChoiceDialog
14  #include "compilerfactory.h"
15  #include "manager.h"
16  #include "logmanager.h"
17  #include "configmanager.h"
18  #include "compiler.h"
19 #endif
20 
21 #include "autodetectcompilers.h"
22 
23 // statics
24 CompilersArray CompilerFactory::Compilers;
25 Compiler* CompilerFactory::s_DefaultCompiler = nullptr;
26 
28 {
29  return Compilers.GetCount();
30 }
31 
33 {
34  // NOTE: The index can be -1 , if there is no compiler at all or less than number of compilers.
35  /* NOTE: Any negative value of index will be converted to a large unsigned integer.
36  Therefore it's safe to check if the index equals or exceeds the compiler count. */
37  if ((Compilers.GetCount() < 1) || (index >= Compilers.GetCount()))
38  return nullptr;
39  return Compilers[index];
40 }
41 
43 {
44  const wxString lid = id.Lower();
45  for (size_t i = 0; i < Compilers.GetCount(); ++i)
46  {
47  if (Compilers[i]->GetID().IsSameAs(lid))
48  return Compilers[i];
49  }
50  // try again using previous id format
51  for (size_t i = 0; i < Compilers.GetCount(); ++i)
52  {
53  wxString oldId = Compilers[i]->GetID();
54  oldId.Replace(wxT("-"), wxEmptyString);
55  if (oldId.IsSameAs(lid))
56  return Compilers[i];
57  }
58  return nullptr;
59 }
60 
62 {
63  for (size_t i = 0; i < Compilers.GetCount(); ++i)
64  {
65  if (Compilers[i]->GetName().IsSameAs(title))
66  return Compilers[i];
67  }
68  return nullptr;
69 }
70 
72 {
73  const wxString lid = id.Lower();
74  for (size_t i = 0; i < Compilers.GetCount(); ++i)
75  {
76  if (Compilers[i]->GetID().IsSameAs(lid))
77  return i;
78  }
79  // try again using previous id format
80  for (size_t i = 0; i < Compilers.GetCount(); ++i)
81  {
82  wxString oldId = Compilers[i]->GetID();
83  oldId.Replace(wxT("-"), wxEmptyString);
84  if (oldId.IsSameAs(lid))
85  return i;
86  }
87  return -1;
88 }
89 
91 {
92  for (size_t i = 0; i < Compilers.GetCount(); ++i)
93  {
94  if (Compilers[i] == compiler)
95  return i;
96  }
97  return -1;
98 }
99 
101 {
102  return CompilerInheritsFrom(GetCompiler(id), from_id);
103 }
104 
106 {
107  if (!compiler)
108  return false;
109 
110  wxString id = compiler->GetID();
111  if (id.Matches(from_id))
112  return true;
113 
114  while (compiler)
115  {
116  id = compiler->GetParentID();
117  if (id.Matches(from_id))
118  return true;
119 
120  // traverse up the chain
121  Compiler* newcompiler = GetCompiler(id);
122  if (compiler == newcompiler)
123  {
124  Manager::Get()->GetLogManager()->DebugLog(_T("Compiler circular dependency detected?!?!?"));
125  break;
126  }
127  compiler = newcompiler;
128  }
129  return false;
130 }
131 
133 {
134  size_t idx = CompilerFactory::Compilers.GetCount();
135  for (; idx > 0; --idx)
136  {
137  if (compiler->m_Weight >= Compilers[idx - 1]->m_Weight)
138  break;
139  }
140  CompilerFactory::Compilers.Insert(compiler, idx);
141  // if it's the first one, set it as default
142  if (!s_DefaultCompiler)
143  s_DefaultCompiler = compiler;
144 }
145 
147 {
148  ConfigManager* cfg = Manager::Get()->GetConfigManager(_T("compiler"));
149  wxArrayString paths = cfg->EnumerateSubPaths(_T("/user_sets"));
150  for (unsigned int i = 0; i < paths.GetCount(); ++i)
151  {
152  wxString base = _T("/user_sets/") + paths[i];
153  wxString parent = cfg->Read(base + _T("/parent"), wxEmptyString);
154  if (!parent.IsEmpty())
155  {
156  Compiler* compiler = GetCompiler(parent);
157  wxString name = cfg->Read(base + _T("/name"), wxEmptyString);
158  CreateCompilerCopy(compiler, name);
159  }
160  }
161 }
162 
164 {
165  if (!compiler)
166  return nullptr;
167 
168  // abort if an existing compiler with the same name exists
169  // this also avoids the possibility of throwing an exception
170  // in the compiler->CreateCopy() call below...
171  for (size_t i = 0; i < Compilers.GetCount(); ++i)
172  {
173  if (Compilers[i]->GetName() == newName)
174  return nullptr;
175  }
176 
177  Compiler* newC = compiler->CreateCopy();
178  if (!newName.IsEmpty())
179  {
181  newC->SetName(newName);
182  newC->m_ID = newName;
183  newC->MakeValidID();
184  }
185  newC->ReloadOptions();
186  RegisterCompiler(newC);
187  newC->LoadSettings(_T("/user_sets"));
188  Manager::Get()->GetLogManager()->DebugLog(F(_T("Added compiler \"%s\""), newC->GetName().wx_str()));
189  return newC; // return the index for the new compiler
190 }
191 
193 {
194  if (!compiler || compiler->m_ParentID.IsEmpty())
195  return;
196  Manager::Get()->GetConfigManager(_T("compiler"))->DeleteSubPath(_T("/user_sets/") + compiler->GetID());
197 
198  Compilers.Remove(compiler);
199  Manager::Get()->GetLogManager()->DebugLog(F(_T("Compiler \"%s\" removed"), compiler->GetName().wx_str()));
200 
201  Compiler::m_CompilerIDs.Remove(compiler->GetID());
202  delete compiler;
203 
204  SaveSettings();
205 }
206 
208 {
212 
213  s_DefaultCompiler = nullptr;
214 }
215 
217 {
218  if (s_DefaultCompiler)
219  return s_DefaultCompiler->GetID();
220 
221  static wxString empty = wxEmptyString;
222  return empty;
223 }
224 
226 {
227  return s_DefaultCompiler;
228 }
229 
231 {
232  if ((Compilers.GetCount() > 0) && (index < Compilers.GetCount()))
233  s_DefaultCompiler = Compilers[index];
234 }
235 
237 {
238  Compiler* compiler = GetCompiler(id.Lower());
239  SetDefaultCompiler(compiler);
240 }
241 
243 {
244  if (compiler)
245  s_DefaultCompiler = compiler;
246 }
247 
249 {
250  // clear old keys before saving
251  Manager::Get()->GetConfigManager(_T("compiler"))->DeleteSubPath(_T("/sets"));
252  Manager::Get()->GetConfigManager(_T("compiler"))->DeleteSubPath(_T("/user_sets"));
253 
254  for (size_t i = 0; i < Compilers.GetCount(); ++i)
255  {
256  wxString baseKey = Compilers[i]->GetParentID().IsEmpty() ? _T("/sets") : _T("/user_sets");
257  Compilers[i]->SaveSettings(baseKey);
258 
260  event.SetString(Compilers[i]->GetID());
261  event.SetInt(static_cast<int>(i));
262  event.SetClientData(static_cast<void*>(Compilers[i]));
263  Manager::Get()->ProcessEvent(event);
264  }
265 }
266 
268 {
269  bool needAutoDetection = false;
270  for (size_t i = 0; i < Compilers.GetCount(); ++i)
271  {
272  wxString baseKey = Compilers[i]->GetParentID().IsEmpty() ? _T("/sets") : _T("/user_sets");
273  Compilers[i]->LoadSettings(baseKey);
274 
276  event.SetString(Compilers[i]->GetID());
277  event.SetInt(static_cast<int>(i));
278  event.SetClientData(static_cast<void*>(Compilers[i]));
279  Manager::Get()->ProcessEvent(event);
280 
281  if (Compilers[i]->GetMasterPath().IsEmpty())
282  {
283  Manager::Get()->GetLogManager()->DebugLog(F(_T("Master path of compiler ID \"%s\" is empty -> triggers auto-detection."), Compilers[i]->GetID().wx_str()));
284  needAutoDetection = true;
285  }
286  }
287 
288  // auto-detect missing compilers
289  if (needAutoDetection)
290  {
291  AutoDetectCompilers adc(Manager::Get()->GetAppWindow());
292  PlaceWindow(&adc);
293  adc.ShowModal();
294  adc.Raise();
295  }
296 }
297 
298 Compiler* CompilerFactory::SelectCompilerUI(const wxString& message, const wxString& preselectedID)
299 {
300  int selected = -1;
301  const wxString lid = preselectedID.Lower();
302 
303  // first build a list of available compilers
304  wxString* comps = new wxString[Compilers.GetCount()];
305  for (size_t i = 0; i < Compilers.GetCount(); ++i)
306  {
307  comps[i] = Compilers[i]->GetName();
308  if (selected == -1)
309  {
310  if (lid.IsEmpty())
311  {
312  if (Compilers[i] == s_DefaultCompiler)
313  selected = i;
314  }
315  else
316  {
317  if (Compilers[i]->GetID().IsSameAs(lid))
318  selected = i;
319  }
320  }
321  }
322  // now display a choice dialog
323  wxSingleChoiceDialog dlg(nullptr,
324  message,
325  _("Compiler selection"),
326  CompilerFactory::Compilers.GetCount(),
327  comps);
328  dlg.SetSelection(selected);
329  PlaceWindow(&dlg);
330  if (dlg.ShowModal() == wxID_OK)
331  return Compilers[dlg.GetSelection()];
332  return nullptr;
333 }
334 
336 {
337  wxString Version;
338  if (const Compiler* pCompiler = GetCompiler(Id))
339  Version = pCompiler->GetVersionString();
340  return Version;
341 }
wxString F(const wxChar *msg,...)
sprintf-like function
Definition: logmanager.h:20
void Remove(const wxString &sz)
const wxString empty(_T(""))
virtual void SetName(const wxString &name)
Set the compiler&#39;s name.
Definition: compiler.h:319
static wxArrayString m_CompilerIDs
Definition: compiler.h:427
ConfigManager * GetConfigManager(const wxString &name_space) const
Definition: manager.cpp:474
static Manager * Get()
Use Manager::Get() to get a pointer to its instance Manager::Get() is guaranteed to never return an i...
Definition: manager.cpp:182
wxString Lower() const
int GetSelection() const
static Compiler * GetDefaultCompiler()
EVTIMPORT const wxEventType cbEVT_COMPILER_SETTINGS_CHANGED
Definition: sdk_events.cpp:153
static Compiler * GetCompiler(size_t index)
static int GetCompilerIndex(const wxString &id)
#define _T(string)
static const wxString & GetDefaultCompilerID()
#define WX_CLEAR_ARRAY(wxArray_arrayToBeCleared)
virtual void ReloadOptions()
Reload option flags (for copied compilers).
Definition: compiler.cpp:174
#define wxT(string)
static void UnregisterCompilers()
Unregister all compilers.
A generic Code::Blocks event.
Definition: sdk_events.h:20
static Compiler * CreateCompilerCopy(Compiler *compiler, const wxString &newName)
Create a copy of a compiler.
virtual void LoadSettings(const wxString &baseKey)
Load settings.
Definition: compiler.cpp:584
static void RemoveCompiler(Compiler *compiler)
Remove a compiler.
static Compiler * SelectCompilerUI(const wxString &message=_("Select compiler"), const wxString &preselectedID=wxEmptyString)
void SetSelection(int selection)
const wxString & GetID() const
Get this compiler&#39;s unique ID.
Definition: compiler.h:351
virtual Compiler * CreateCopy()=0
Implement this in new compilers, to return a new copy.
wxArrayString EnumerateSubPaths(const wxString &path)
static wxString GetCompilerVersionString(const wxString &Id)
get the version number as string for the compiler with the specified index
size_t Replace(const wxString &strOld, const wxString &strNew, bool replaceAll=true)
void MakeValidID()
Definition: compiler.cpp:261
bool IsSameAs(const wxString &s, bool caseSensitive=true) const
static void SetDefaultCompiler(size_t index)
static void RegisterCompiler(Compiler *compiler)
Register a supported (builtin) compiler.
LogManager * GetLogManager() const
Definition: manager.cpp:439
wxString Read(const wxString &key, const wxString &defaultVal=wxEmptyString)
static void RegisterUserCompilers()
Register all user-defined compiler copies.
static void SaveSettings()
const wxStringCharType * wx_str() const
virtual int ShowModal()
static void LoadSettings()
wxString wxEmptyString
const wxString & _(const wxString &string)
wxString m_ParentID
Definition: compiler.h:426
static bool CompilerInheritsFrom(const wxString &id, const wxString &from_id)
Abstract base class for compilers.
Definition: compiler.h:274
void DeleteSubPath(const wxString &strPath)
bool IsEmpty() const
DLLIMPORT void PlaceWindow(wxTopLevelWindow *w, cbPlaceDialogMode mode=pdlBest, bool enforce=false)
Definition: globals.cpp:1177
virtual const wxString & GetName() const
Get the compiler&#39;s name.
Definition: compiler.h:293
const wxString & GetParentID() const
Get this compiler&#39;s parent&#39;s unique ID.
Definition: compiler.h:353
static Compiler * s_DefaultCompiler
void DebugLog(const wxString &msg, Logger::level lv=Logger::info)
Definition: logmanager.h:146
bool ProcessEvent(CodeBlocksEvent &event)
Definition: manager.cpp:246
static CompilersArray Compilers
static size_t GetCompilersCount()
size_t GetCount() const
static Compiler * GetCompilerByName(const wxString &title)
int m_Weight
Definition: compiler.h:422
wxString m_ID
Definition: compiler.h:425