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: 11887 $
6  * $Id: compileoptionsbase.cpp 11887 2019-10-26 09:12:28Z fuscated $
7  * $HeadURL: svn://svn.code.sf.net/p/codeblocks/code/branches/release-20.xx/src/sdk/compileoptionsbase.cpp $
8  */
9 
10 #include "sdk_precomp.h"
11 
12 #ifndef CB_PRECOMP
13     #include "compileoptionsbase.h"
14     #include "sdk_events.h"
15     #include "manager.h"
16     #include "macrosmanager.h"
17 #endif
18 
19 namespace { static const bool s_case_sensitive = platform::windows ? false : true; }
20 
CompileOptionsBase()21 CompileOptionsBase::CompileOptionsBase()
22     : m_Platform(spAll),
23     m_LinkerExecutable(LinkerExecutableOption::AutoDetect),
24     m_Modified(false),
25     m_AlwaysRunPostCmds(false)
26 {
27     //ctor
28 }
29 
~CompileOptionsBase()30 CompileOptionsBase::~CompileOptionsBase()
31 {
32     //dtor
33 }
34 
AddPlatform(int platform)35 void CompileOptionsBase::AddPlatform(int platform)
36 {
37     if (m_Platform & platform)
38         return;
39     m_Platform |= platform;
40     SetModified(true);
41 }
42 
RemovePlatform(int platform)43 void CompileOptionsBase::RemovePlatform(int platform)
44 {
45     if (!(m_Platform & platform))
46         return;
47     m_Platform &= ~platform;
48     SetModified(true);
49 }
50 
SetPlatforms(int platforms)51 void CompileOptionsBase::SetPlatforms(int platforms)
52 {
53     if (m_Platform == platforms)
54         return;
55     m_Platform = platforms;
56     SetModified(true);
57 }
58 
GetPlatforms() const59 int CompileOptionsBase::GetPlatforms() const
60 {
61     return m_Platform;
62 }
63 
SupportsCurrentPlatform() const64 bool CompileOptionsBase::SupportsCurrentPlatform() const
65 {
66     if(platform::windows)
67         return m_Platform & spWindows;
68     if(platform::Unix)
69         return m_Platform & spUnix;
70     if(platform::macosx)
71         return m_Platform & spMac;
72 
73     return false;
74 }
75 
SetLinkerOptions(const wxArrayString & linkerOpts)76 void CompileOptionsBase::SetLinkerOptions(const wxArrayString& linkerOpts)
77 {
78     if (m_LinkerOptions == linkerOpts)
79         return;
80     m_LinkerOptions = linkerOpts;
81     SetModified(true);
82 }
83 
GetLinkerOptions() const84 const wxArrayString& CompileOptionsBase::GetLinkerOptions() const
85 {
86     return m_LinkerOptions;
87 }
88 
SetLinkLibs(const wxArrayString & linkLibs)89 void CompileOptionsBase::SetLinkLibs(const wxArrayString& linkLibs)
90 {
91     if (m_LinkLibs == linkLibs)
92         return;
93     m_LinkLibs = linkLibs;
94     SetModified(true);
95 }
96 
GetLinkLibs() const97 const wxArrayString& CompileOptionsBase::GetLinkLibs() const
98 {
99     return m_LinkLibs;
100 }
101 
SetCompilerOptions(const wxArrayString & compilerOpts)102 void CompileOptionsBase::SetCompilerOptions(const wxArrayString& compilerOpts)
103 {
104     if (m_CompilerOptions == compilerOpts)
105         return;
106     m_CompilerOptions = compilerOpts;
107     SetModified(true);
108 }
109 
GetCompilerOptions() const110 const wxArrayString& CompileOptionsBase::GetCompilerOptions() const
111 {
112     return m_CompilerOptions;
113 }
114 
SetResourceCompilerOptions(const wxArrayString & resourceCompilerOpts)115 void CompileOptionsBase::SetResourceCompilerOptions(const wxArrayString& resourceCompilerOpts)
116 {
117     if (m_ResourceCompilerOptions == resourceCompilerOpts)
118         return;
119     m_ResourceCompilerOptions = resourceCompilerOpts;
120     SetModified(true);
121 }
122 
GetResourceCompilerOptions() const123 const wxArrayString& CompileOptionsBase::GetResourceCompilerOptions() const
124 {
125     return m_ResourceCompilerOptions;
126 }
127 
SetIncludeDirs(const wxArrayString & includeDirs)128 void CompileOptionsBase::SetIncludeDirs(const wxArrayString& includeDirs)
129 {
130     if (m_IncludeDirs == includeDirs)
131         return;
132 
133     // make sure we don't have duplicate entries
134     // that's why we don't assign the array but rather copy it entry by entry...
135 
136     m_IncludeDirs.Clear();
137     for (size_t i = 0; i < includeDirs.GetCount(); ++i)
138     {
139         wxString entry = UnixFilename(includeDirs[i]);
140         if (m_IncludeDirs.Index(entry, s_case_sensitive) == wxNOT_FOUND)
141             m_IncludeDirs.Add(entry);
142     }
143     SetModified(true);
144 }
145 
GetIncludeDirs() const146 const wxArrayString& CompileOptionsBase::GetIncludeDirs() const
147 {
148     return m_IncludeDirs;
149 }
150 
SetResourceIncludeDirs(const wxArrayString & resIncludeDirs)151 void CompileOptionsBase::SetResourceIncludeDirs(const wxArrayString& resIncludeDirs)
152 {
153     if (m_ResIncludeDirs == resIncludeDirs)
154         return;
155 
156     // make sure we don't have duplicate entries
157     // that's why we don't assign the array but rather copy it entry by entry...
158 
159     m_ResIncludeDirs.Clear();
160     for (size_t i = 0; i < resIncludeDirs.GetCount(); ++i)
161     {
162         wxString entry = UnixFilename(resIncludeDirs[i]);
163         if (m_ResIncludeDirs.Index(entry, s_case_sensitive) == wxNOT_FOUND)
164             m_ResIncludeDirs.Add(entry);
165     }
166     SetModified(true);
167 }
168 
GetResourceIncludeDirs() const169 const wxArrayString& CompileOptionsBase::GetResourceIncludeDirs() const
170 {
171     return m_ResIncludeDirs;
172 }
173 
SetLibDirs(const wxArrayString & libDirs)174 void CompileOptionsBase::SetLibDirs(const wxArrayString& libDirs)
175 {
176     if (m_LibDirs == libDirs)
177         return;
178 
179     // make sure we don't have duplicate entries
180     // that's why we don't assign the array but rather copy it entry by entry...
181 
182     m_LibDirs.Clear();
183     for (size_t i = 0; i < libDirs.GetCount(); ++i)
184     {
185         wxString entry = UnixFilename(libDirs[i]);
186         if (m_LibDirs.Index(entry, s_case_sensitive) == wxNOT_FOUND)
187             m_LibDirs.Add(entry);
188     }
189     SetModified(true);
190 }
191 
GetLibDirs() const192 const wxArrayString& CompileOptionsBase::GetLibDirs() const
193 {
194     return m_LibDirs;
195 }
196 
SetBuildScripts(const wxArrayString & scripts)197 void CompileOptionsBase::SetBuildScripts(const wxArrayString& scripts)
198 {
199     if (m_Scripts == scripts)
200         return;
201 
202     // make sure we don't have duplicate entries
203     // that's why we don't assign the array but rather copy it entry by entry...
204 
205     m_Scripts.Clear();
206     for (size_t i = 0; i < scripts.GetCount(); ++i)
207     {
208         wxString entry = UnixFilename(scripts[i]);
209         if (m_Scripts.Index(entry, s_case_sensitive) == wxNOT_FOUND)
210             m_Scripts.Add(entry);
211     }
212     SetModified(true);
213 }
214 
GetBuildScripts() const215 const wxArrayString& CompileOptionsBase::GetBuildScripts() const
216 {
217     return m_Scripts;
218 }
219 
SetCommandsBeforeBuild(const wxArrayString & commands)220 void CompileOptionsBase::SetCommandsBeforeBuild(const wxArrayString& commands)
221 {
222     if (m_CmdsBefore == commands)
223         return;
224     m_CmdsBefore = commands;
225     SetModified(true);
226 }
227 
GetCommandsBeforeBuild() const228 const wxArrayString& CompileOptionsBase::GetCommandsBeforeBuild() const
229 {
230     return m_CmdsBefore;
231 }
232 
SetCommandsAfterBuild(const wxArrayString & commands)233 void CompileOptionsBase::SetCommandsAfterBuild(const wxArrayString& commands)
234 {
235     if (m_CmdsAfter == commands)
236         return;
237     m_CmdsAfter = commands;
238     SetModified(true);
239 }
240 
GetCommandsAfterBuild() const241 const wxArrayString& CompileOptionsBase::GetCommandsAfterBuild() const
242 {
243     return m_CmdsAfter;
244 }
245 
GetAlwaysRunPostBuildSteps() const246 bool CompileOptionsBase::GetAlwaysRunPostBuildSteps() const
247 {
248     return m_AlwaysRunPostCmds;
249 }
250 
SetAlwaysRunPostBuildSteps(bool always)251 void CompileOptionsBase::SetAlwaysRunPostBuildSteps(bool always)
252 {
253     if (m_AlwaysRunPostCmds == always)
254         return;
255     m_AlwaysRunPostCmds = always;
256     SetModified(true);
257 }
258 
GetModified() const259 bool CompileOptionsBase::GetModified() const
260 {
261     return m_Modified;
262 }
263 
SetModified(bool modified)264 void CompileOptionsBase::SetModified(bool modified)
265 {
266     m_Modified = modified;
267 }
268 
AddLinkerOption(const wxString & option)269 void CompileOptionsBase::AddLinkerOption(const wxString& option)
270 {
271     if (m_LinkerOptions.Index(option, s_case_sensitive) == wxNOT_FOUND)
272     {
273         m_LinkerOptions.Add(option);
274         SetModified(true);
275     }
276 }
277 
AddLinkLib(const wxString & option)278 void CompileOptionsBase::AddLinkLib(const wxString& option)
279 {
280     if (m_LinkLibs.Index(option, s_case_sensitive) == wxNOT_FOUND)
281     {
282         m_LinkLibs.Add(option);
283         SetModified(true);
284     }
285 }
286 
AddCompilerOption(const wxString & option)287 void CompileOptionsBase::AddCompilerOption(const wxString& option)
288 {
289     if (m_CompilerOptions.Index(option, s_case_sensitive) == wxNOT_FOUND)
290     {
291         m_CompilerOptions.Add(option);
292         SetModified(true);
293     }
294 }
295 
AddResourceCompilerOption(const wxString & option)296 void CompileOptionsBase::AddResourceCompilerOption(const wxString& option)
297 {
298     if (m_ResourceCompilerOptions.Index(option, s_case_sensitive) == wxNOT_FOUND)
299     {
300         m_ResourceCompilerOptions.Add(option);
301         SetModified(true);
302     }
303 }
304 
AddIncludeDir(const wxString & option)305 void CompileOptionsBase::AddIncludeDir(const wxString& option)
306 {
307     wxString entry = UnixFilename(option);
308     if (m_IncludeDirs.Index(entry, s_case_sensitive) == wxNOT_FOUND)
309     {
310         m_IncludeDirs.Add(entry);
311         SetModified(true);
312     }
313 }
314 
AddResourceIncludeDir(const wxString & option)315 void CompileOptionsBase::AddResourceIncludeDir(const wxString& option)
316 {
317     wxString entry = UnixFilename(option);
318     if (m_ResIncludeDirs.Index(entry, s_case_sensitive) == wxNOT_FOUND)
319     {
320         m_ResIncludeDirs.Add(entry);
321         SetModified(true);
322     }
323 }
324 
AddLibDir(const wxString & option)325 void CompileOptionsBase::AddLibDir(const wxString& option)
326 {
327     wxString entry = UnixFilename(option);
328     if (m_LibDirs.Index(entry, s_case_sensitive) == wxNOT_FOUND)
329     {
330         m_LibDirs.Add(entry);
331         SetModified(true);
332     }
333 }
334 
AddCommandsBeforeBuild(const wxString & command)335 void CompileOptionsBase::AddCommandsBeforeBuild(const wxString& command)
336 {
337     m_CmdsBefore.Add(command);
338     SetModified(true);
339 }
340 
AddCommandsAfterBuild(const wxString & command)341 void CompileOptionsBase::AddCommandsAfterBuild(const wxString& command)
342 {
343     m_CmdsAfter.Add(command);
344     SetModified(true);
345 }
346 
AddBuildScript(const wxString & script)347 void CompileOptionsBase::AddBuildScript(const wxString& script)
348 {
349     wxString envopt = UnixFilename(script);
350     if (m_Scripts.Index(envopt, s_case_sensitive) == wxNOT_FOUND)
351     {
352         m_Scripts.Add(envopt);
353         SetModified(true);
354     }
355 }
356 
ReplaceLinkerOption(const wxString & option,const wxString & new_option)357 void CompileOptionsBase::ReplaceLinkerOption(const wxString& option, const wxString& new_option)
358 {
359     int idx = m_LinkerOptions.Index(option, s_case_sensitive);
360     if (idx != wxNOT_FOUND)
361     {
362         m_LinkerOptions.Item(idx) = new_option;
363         SetModified(true);
364     }
365 }
366 
ReplaceLinkLib(const wxString & option,const wxString & new_option)367 void CompileOptionsBase::ReplaceLinkLib(const wxString& option, const wxString& new_option)
368 {
369     int idx = m_LinkLibs.Index(option, s_case_sensitive);
370     if (idx != wxNOT_FOUND)
371     {
372         m_LinkLibs.Item(idx) = new_option;
373         SetModified(true);
374     }
375 }
376 
ReplaceCompilerOption(const wxString & option,const wxString & new_option)377 void CompileOptionsBase::ReplaceCompilerOption(const wxString& option, const wxString& new_option)
378 {
379     int idx = m_CompilerOptions.Index(option, s_case_sensitive);
380     if (idx != wxNOT_FOUND)
381     {
382         m_CompilerOptions.Item(idx) = new_option;
383         SetModified(true);
384     }
385 }
386 
ReplaceResourceCompilerOption(const wxString & option,const wxString & new_option)387 void CompileOptionsBase::ReplaceResourceCompilerOption(const wxString& option, const wxString& new_option)
388 {
389     int idx = m_ResourceCompilerOptions.Index(option, s_case_sensitive);
390     if (idx != wxNOT_FOUND)
391     {
392         m_ResourceCompilerOptions.Item(idx) = new_option;
393         SetModified(true);
394     }
395 }
396 
ReplaceIncludeDir(const wxString & option,const wxString & new_option)397 void CompileOptionsBase::ReplaceIncludeDir(const wxString& option, const wxString& new_option)
398 {
399     int idx = m_IncludeDirs.Index(option, s_case_sensitive);
400     if (idx != wxNOT_FOUND)
401     {
402         m_IncludeDirs.Item(idx) = new_option;
403         SetModified(true);
404     }
405 }
406 
ReplaceResourceIncludeDir(const wxString & option,const wxString & new_option)407 void CompileOptionsBase::ReplaceResourceIncludeDir(const wxString& option, const wxString& new_option)
408 {
409     int idx = m_ResIncludeDirs.Index(option, s_case_sensitive);
410     if (idx != wxNOT_FOUND)
411     {
412         m_ResIncludeDirs.Item(idx) = new_option;
413         SetModified(true);
414     }
415 }
416 
ReplaceLibDir(const wxString & option,const wxString & new_option)417 void CompileOptionsBase::ReplaceLibDir(const wxString& option, const wxString& new_option)
418 {
419     int idx = m_LibDirs.Index(option, s_case_sensitive);
420     if (idx != wxNOT_FOUND)
421     {
422         m_LibDirs.Item(idx) = new_option;
423         SetModified(true);
424     }
425 }
426 
RemoveLinkerOption(const wxString & option)427 void CompileOptionsBase::RemoveLinkerOption(const wxString& option)
428 {
429     int idx = m_LinkerOptions.Index(option, s_case_sensitive);
430     if (idx != wxNOT_FOUND)
431     {
432         m_LinkerOptions.RemoveAt(idx);
433         SetModified(true);
434     }
435 }
436 
RemoveLinkLib(const wxString & option)437 void CompileOptionsBase::RemoveLinkLib(const wxString& option)
438 {
439     int idx = m_LinkLibs.Index(option, s_case_sensitive);
440     if (idx != wxNOT_FOUND)
441     {
442         m_LinkLibs.RemoveAt(idx);
443         SetModified(true);
444     }
445 }
446 
RemoveCompilerOption(const wxString & option)447 void CompileOptionsBase::RemoveCompilerOption(const wxString& option)
448 {
449     int idx = m_CompilerOptions.Index(option, s_case_sensitive);
450     if (idx != wxNOT_FOUND)
451     {
452         m_CompilerOptions.RemoveAt(idx);
453         SetModified(true);
454     }
455 }
456 
RemoveResourceCompilerOption(const wxString & option)457 void CompileOptionsBase::RemoveResourceCompilerOption(const wxString& option)
458 {
459     int idx = m_ResourceCompilerOptions.Index(option, s_case_sensitive);
460     if (idx != wxNOT_FOUND)
461     {
462         m_ResourceCompilerOptions.RemoveAt(idx);
463         SetModified(true);
464     }
465 }
466 
RemoveIncludeDir(const wxString & option)467 void CompileOptionsBase::RemoveIncludeDir(const wxString& option)
468 {
469     wxString entry = UnixFilename(option);
470     int idx = m_IncludeDirs.Index(entry, s_case_sensitive);
471     if (idx != wxNOT_FOUND)
472     {
473         m_IncludeDirs.RemoveAt(idx);
474         SetModified(true);
475     }
476 }
477 
RemoveResourceIncludeDir(const wxString & option)478 void CompileOptionsBase::RemoveResourceIncludeDir(const wxString& option)
479 {
480     wxString entry = UnixFilename(option);
481     int idx = m_ResIncludeDirs.Index(entry, s_case_sensitive);
482     if (idx != wxNOT_FOUND)
483     {
484         m_ResIncludeDirs.RemoveAt(idx);
485         SetModified(true);
486     }
487 }
488 
RemoveLibDir(const wxString & option)489 void CompileOptionsBase::RemoveLibDir(const wxString& option)
490 {
491     wxString entry = UnixFilename(option);
492     int idx = m_LibDirs.Index(entry, s_case_sensitive);
493     if (idx != wxNOT_FOUND)
494     {
495         m_LibDirs.RemoveAt(idx);
496         SetModified(true);
497     }
498 }
499 
RemoveCommandsBeforeBuild(const wxString & command)500 void CompileOptionsBase::RemoveCommandsBeforeBuild(const wxString& command)
501 {
502     m_CmdsBefore.Remove(command);
503     SetModified(true);
504 }
505 
RemoveCommandsAfterBuild(const wxString & command)506 void CompileOptionsBase::RemoveCommandsAfterBuild(const wxString& command)
507 {
508     m_CmdsAfter.Remove(command);
509     SetModified(true);
510 }
511 
RemoveBuildScript(const wxString & script)512 void CompileOptionsBase::RemoveBuildScript(const wxString& script)
513 {
514     wxString envopt = UnixFilename(script);
515     int idx = m_Scripts.Index(envopt, s_case_sensitive);
516     if (idx != wxNOT_FOUND)
517     {
518         m_Scripts.RemoveAt(idx);
519         SetModified(true);
520     }
521 }
522 
SetVar(const wxString & key,const wxString & value,bool onlyIfExists)523 bool CompileOptionsBase::SetVar(const wxString& key, const wxString& value, bool onlyIfExists)
524 {
525     if (onlyIfExists)
526     {
527         StringHash::iterator it = m_Vars.find(key);
528         if (it == m_Vars.end())
529             return false;
530         it->second = value;
531         return true;
532     }
533 
534     m_Vars[key] = value;
535     SetModified(true);
536     return true;
537 }
538 
UnsetVar(const wxString & key)539 bool CompileOptionsBase::UnsetVar(const wxString& key)
540 {
541     StringHash::iterator it = m_Vars.find(key);
542     if (it != m_Vars.end())
543     {
544         m_Vars.erase(it);
545         SetModified(true);
546         return true;
547     }
548     return false;
549 }
550 
UnsetAllVars()551 void CompileOptionsBase::UnsetAllVars()
552 {
553     m_Vars.clear();
554 }
555 
HasVar(const wxString & key) const556 bool CompileOptionsBase::HasVar(const wxString& key) const
557 {
558     StringHash::const_iterator it = m_Vars.find(key);
559     if (it != m_Vars.end())
560         return true;
561 
562     return false;
563 }
564 
GetVar(const wxString & key) const565 const wxString& CompileOptionsBase::GetVar(const wxString& key) const
566 {
567     StringHash::const_iterator it = m_Vars.find(key);
568     if (it != m_Vars.end())
569         return it->second;
570 
571     static wxString emptystring = wxEmptyString;
572     return emptystring;
573 }
574 
GetAllVars() const575 const StringHash& CompileOptionsBase::GetAllVars() const
576 {
577     return m_Vars;
578 }
579 
SetLinkerExecutable(LinkerExecutableOption option)580 void CompileOptionsBase::SetLinkerExecutable(LinkerExecutableOption option)
581 {
582     if (m_LinkerExecutable == option)
583         return;
584 
585     // We need to do this range check because this function could be called from scripting and there
586     // is no range checking done by the compiler.
587     if (option>= LinkerExecutableOption::First && option <= LinkerExecutableOption::Last)
588     {
589         m_LinkerExecutable = option;
590         SetModified(true);
591     }
592     else if (m_LinkerExecutable != LinkerExecutableOption::AutoDetect)
593     {
594         m_LinkerExecutable = LinkerExecutableOption::AutoDetect;
595         SetModified(true);
596     }
597 }
598 
GetLinkerExecutable() const599 LinkerExecutableOption CompileOptionsBase::GetLinkerExecutable() const
600 {
601     return m_LinkerExecutable;
602 }
603