9 import "OldIDESettings"
13 enum DirTypes { includes, libraries, executables };
15 define defaultCompilerName = "Default";
17 define defaultObjDirExpression = "obj/$(CONFIG).$(PLATFORM)$(COMPILER_SUFFIX)$(DEBUG_SUFFIX)";
19 char * settingsDirectoryNames[DirTypes] =
26 enum GlobalSettingsChange { none, editorSettings, projectOptions, compilerSettings };
28 enum PathRelationship { unrelated, identical, siblings, subPath, parentPath, insuficientInput, pathEmpty, toEmpty, pathNull, toNull, bothEmpty, bothNull };
29 PathRelationship eString_PathRelated(char * path, char * to, char * pathDiff)
31 PathRelationship result;
32 if(pathDiff) *pathDiff = '\0';
33 if(path && *path && to && *to)
35 char toPart[MAX_FILENAME], toRest[MAX_LOCATION];
36 char pathPart[MAX_FILENAME], pathRest[MAX_LOCATION];
38 strcpy(pathRest, path);
39 for(; toRest[0] && pathRest[0];)
41 SplitDirectory(toRest, toPart, toRest);
42 SplitDirectory(pathRest, pathPart, pathRest);
43 if(!fstrcmp(pathPart, toPart)) result = siblings;
46 if(result == siblings)
48 if(!*toRest && !*pathRest) result = identical;
49 else if(!*pathRest) result = parentPath;
50 else result = subPath;
51 if(pathDiff && result != identical) strcpy(pathDiff, *pathRest == '\0' ? toRest : pathRest);
53 else result = unrelated;
59 if(!*path && !*to) result = bothEmpty;
60 else if(!*path) result = pathEmpty;
61 else result = toEmpty;
63 else if(!path && !to) result = bothNull;
64 else if(!path) result = pathNull;
70 char * CopyValidateMakefilePath(char * path)
72 const int map[] = { 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 7 };
73 const char * vars[] = { "$(MODULE)", "$(CONFIG)", "$(PLATFORM)", "$(COMPILER)", "$(TARGET)", "$(COMPILER_SUFFIX)", "$(DEBUG_SUFFIX)", "$(PROJECT)", "$(CONFIGURATION)", "$(TARGET_PLATFORM)",(char *)0 };
80 copy = CopyString(path);
86 Array<char *> parts { };
93 for(v=0; vars[v]; v++)
95 if(SearchString(&tmp[c], 0, vars[v], false, false) == &tmp[c])
99 parts.Add(vars[map[v]]);
100 c += strlen(vars[v]);
114 for(c=0; c<parts.count; c++) len += strlen(parts[c]);
115 copy = new char[++len];
117 for(c=0; c<parts.count; c++) strcat(copy, parts[c]);
128 CompilerConfig MakeDefaultCompiler(char * name, bool readOnly)
130 CompilerConfig defaultCompiler
135 GetRuntimePlatform(),
146 incref defaultCompiler;
147 return defaultCompiler;
150 class IDESettingsContainer : GlobalSettings
153 settingsName = "ecereIDESettingsTest";
155 settingsName = "ecereIDE";
158 virtual void OnLoad(GlobalSettingsData data);
160 char moduleLocation[MAX_LOCATION];
163 IDESettingsContainer()
165 char path[MAX_LOCATION];
167 LocateModule(null, moduleLocation);
168 strcpy(path, moduleLocation);
169 StripLastDirectory(moduleLocation, moduleLocation);
170 ChangeCh(moduleLocation, '\\', '/');
171 // PortableApps.com directory structure
172 if((start = strstr(path, "\\App\\EcereSDK\\bin\\ide.exe")))
174 char configFilePath[MAX_LOCATION];
175 char defaultConfigFilePath[MAX_LOCATION];
179 strcpy(configFilePath, path);
180 PathCat(configFilePath, "Data");
181 PathCat(configFilePath, "ecereIDE.ini");
183 strcpy(defaultConfigFilePath, path);
184 PathCat(defaultConfigFilePath, "App");
185 PathCat(defaultConfigFilePath, "DefaultData");
186 PathCat(defaultConfigFilePath, "ecereIDE.ini");
188 if(FileExists(defaultConfigFilePath))
190 if(!FileExists(configFilePath))
192 File f = FileOpen(defaultConfigFilePath, read);
193 f.CopyTo(configFilePath);
197 PathCat(path, "Data");
198 // the forced settings location will only be
199 // used if the running ide's path matches
200 // the PortableApps.com directory structure
201 // and the default ini file is found in
202 // the DefaultData directory
203 settingsLocation = path;
209 void OnAskReloadSettings()
211 /*if(MessageBox { type = YesNo, master = this,
212 text = "Global Settings Modified Externally",
213 contents = "The global settings were modified by another instance.\n"
214 "Would you like to reload them?" }.Modal() == Yes)*/
220 SettingsIOResult Load()
222 SettingsIOResult result = GlobalSettings::Load();
223 IDESettings data = (IDESettings)this.data;
224 CompilerConfig defaultCompiler = null;
227 this.data = IDESettings { };
229 *dataOwner = this.data;
231 if(result == fileNotCompatibleWithDriver)
234 OldIDESettings oldSettings { };
236 loaded = oldSettings.Load() == success;
240 data = (IDESettings)this.data;
242 for(c : oldSettings.compilerConfigs)
243 data.compilerConfigs.Add(c.Copy());
245 for(s : oldSettings.recentFiles) data.recentFiles.Add(CopyString(s));
246 for(s : oldSettings.recentProjects) data.recentProjects.Add(CopyString(s));
248 data.docDir = oldSettings.docDir;
249 data.ideFileDialogLocation = oldSettings.ideFileDialogLocation;
250 data.ideProjectFileDialogLocation = oldSettings.ideProjectFileDialogLocation;
251 data.useFreeCaret = oldSettings.useFreeCaret;
252 data.showLineNumbers = oldSettings.showLineNumbers;
253 data.caretFollowsScrolling = oldSettings.caretFollowsScrolling;
254 delete data.displayDriver; data.displayDriver = CopyString(oldSettings.displayDriver);
255 data.projectDefaultTargetDir = oldSettings.projectDefaultTargetDir;
256 data.projectDefaultIntermediateObjDir = oldSettings.projectDefaultIntermediateObjDir;
263 if(result == fileNotFound || !data)
265 data = (IDESettings)this.data;
266 data.useFreeCaret = true;
267 data.showLineNumbers = true;
268 data.caretFollowsScrolling = true;
271 // Ensure we have a default compiler
272 defaultCompiler = data.GetCompilerConfig(defaultCompilerName);
275 defaultCompiler = MakeDefaultCompiler(defaultCompilerName, true);
276 data.compilerConfigs.Add(defaultCompiler);
279 // We incref the compilers below, so reset refCount to 0
280 defaultCompiler._refCount = 0;
283 if(data.compilerConfigs)
285 for(c : data.compilerConfigs)
287 CompilerConfig compiler = c;
288 char * cxxCommand = compiler.cxxCommand;
289 if(!cxxCommand || !cxxCommand[0])
290 compiler.cxxCommand = cxxDefaultCommand;
294 if(portable && moduleLocation[0] && FileExists(moduleLocation).isDirectory)
295 data.ManagePortablePaths(moduleLocation, true);
296 data.ForcePathSeparatorStyle(true);
301 SettingsIOResult Save()
303 SettingsIOResult result;
305 IDESettings data = (IDESettings)this.data;
306 Platform runtimePlatform = GetRuntimePlatform();
307 if(portable && moduleLocation[0] && FileExists(moduleLocation).isDirectory)
308 data.ManagePortablePaths(moduleLocation, false);
309 data.ForcePathSeparatorStyle(true);
310 result = GlobalSettings::Save();
311 if(result != success)
312 PrintLn("Error saving IDE settings");
313 if(portable && moduleLocation[0] && FileExists(moduleLocation).isDirectory)
314 data.ManagePortablePaths(moduleLocation, true);
320 class IDESettings : GlobalSettingsData
323 List<CompilerConfig> compilerConfigs { };
324 Array<String> recentFiles { };
325 Array<String> recentProjects { };
326 property char * docDir
328 set { delete docDir; if(value && value[0]) docDir = CopyString(value); }
329 get { return docDir ? docDir : ""; }
330 isset { return docDir && docDir[0]; }
332 property char * ideFileDialogLocation
334 set { delete ideFileDialogLocation; if(value && value[0]) ideFileDialogLocation = CopyString(value); }
335 get { return ideFileDialogLocation ? ideFileDialogLocation : ""; }
336 isset { return ideFileDialogLocation && ideFileDialogLocation[0]; }
338 property char * ideProjectFileDialogLocation
340 set { delete ideProjectFileDialogLocation; if(value && value[0]) ideProjectFileDialogLocation = CopyString(value); }
341 get { return ideProjectFileDialogLocation ? ideProjectFileDialogLocation : ""; }
342 isset { return ideProjectFileDialogLocation && ideProjectFileDialogLocation[0]; }
345 bool showLineNumbers;
346 bool caretFollowsScrolling;
347 char * displayDriver;
349 // TODO: Classify settings
350 //EditorSettings editor { };
352 property char * projectDefaultTargetDir
354 set { delete projectDefaultTargetDir; if(value && value[0]) projectDefaultTargetDir = CopyValidateMakefilePath(value); }
355 get { return projectDefaultTargetDir ? projectDefaultTargetDir : ""; }
356 isset { return projectDefaultTargetDir && projectDefaultTargetDir[0]; }
358 property char * projectDefaultIntermediateObjDir
360 set { delete projectDefaultIntermediateObjDir; if(value && value[0]) projectDefaultIntermediateObjDir = CopyValidateMakefilePath(value); }
361 get { return projectDefaultIntermediateObjDir ? projectDefaultIntermediateObjDir : ""; }
362 isset { return projectDefaultIntermediateObjDir && projectDefaultIntermediateObjDir[0]; }
365 property char * compilerConfigsDir
367 set { delete compilerConfigsDir; if(value && value[0]) compilerConfigsDir = CopyString(value); }
368 get { return compilerConfigsDir ? compilerConfigsDir : ""; }
369 isset { return compilerConfigsDir && compilerConfigsDir[0]; }
372 property char * defaultCompiler
374 set { delete defaultCompiler; if(value && value[0]) defaultCompiler = CopyString(value); }
375 get { return defaultCompiler && defaultCompiler[0] ? defaultCompiler : defaultCompilerName; }
376 isset { return defaultCompiler && defaultCompiler[0]; }
381 char * ideFileDialogLocation;
382 char * ideProjectFileDialogLocation;
383 char * projectDefaultTargetDir;
384 char * projectDefaultIntermediateObjDir;
385 char * compilerConfigsDir;
386 char * defaultCompiler;
388 CompilerConfig GetCompilerConfig(String compilerName)
390 char * name = compilerName && compilerName[0] ? compilerName : defaultCompilerName;
391 CompilerConfig compilerConfig = null;
392 for(compiler : compilerConfigs)
394 if(!strcmp(compiler.name, name))
396 compilerConfig = compiler;
400 if(!compilerConfig && compilerConfigs.count)
401 compilerConfig = compilerConfigs.firstIterator.data;
403 incref compilerConfig;
404 return compilerConfig;
409 compilerConfigs.Free();
410 delete compilerConfigs;
413 recentProjects.Free();
414 delete recentProjects;
417 delete projectDefaultTargetDir;
418 delete projectDefaultIntermediateObjDir;
419 delete compilerConfigsDir;
420 delete defaultCompiler;
422 delete ideFileDialogLocation;
423 delete ideProjectFileDialogLocation;
424 delete displayDriver;
427 void ForcePathSeparatorStyle(bool unixStyle)
431 from = '\\', to = '/';
433 from = '/', to = '\\';
434 if(compilerConfigs && compilerConfigs.count)
437 for(config : compilerConfigs)
439 if(config.includeDirs && config.includeDirs.count)
441 for(i = 0; i < config.includeDirs.count; i++)
443 if(config.includeDirs[i] && config.includeDirs[i][0])
444 ChangeCh(config.includeDirs[i], from, to);
447 if(config.libraryDirs && config.libraryDirs.count)
449 for(i = 0; i < config.libraryDirs.count; i++)
451 if(config.libraryDirs[i] && config.libraryDirs[i][0])
452 ChangeCh(config.libraryDirs[i], from, to);
455 if(config.executableDirs && config.executableDirs.count)
457 for(i = 0; i < config.executableDirs.count; i++)
459 if(config.executableDirs[i] && config.executableDirs[i][0])
460 ChangeCh(config.executableDirs[i], from, to);
465 if(recentFiles && recentFiles.count)
468 for(c = 0; c < recentFiles.count; c++)
470 if(recentFiles[c] && recentFiles[c][0])
471 ChangeCh(recentFiles[c], from, to);
474 if(recentProjects && recentProjects.count)
477 for(c = 0; c < recentProjects.count; c++)
479 if(recentProjects[c] && recentProjects[c][0])
480 ChangeCh(recentProjects[c], from, to);
483 if(docDir && docDir[0])
484 ChangeCh(docDir, from, to);
485 if(ideFileDialogLocation && ideFileDialogLocation[0])
486 ChangeCh(ideFileDialogLocation, from, to);
487 if(ideProjectFileDialogLocation && ideProjectFileDialogLocation[0])
488 ChangeCh(ideProjectFileDialogLocation, from, to);
490 if(projectDefaultTargetDir && projectDefaultTargetDir[0])
491 ChangeCh(projectDefaultTargetDir, from, to);
492 if(projectDefaultIntermediateObjDir && projectDefaultIntermediateObjDir[0])
493 ChangeCh(projectDefaultIntermediateObjDir, from, to);
495 if(compilerConfigsDir && compilerConfigsDir[0])
496 ChangeCh(compilerConfigsDir, from, to);
499 void ManagePortablePaths(char * location, bool makeAbsolute)
502 if(compilerConfigs && compilerConfigs.count)
504 for(config : compilerConfigs)
507 for(t = 0; t < DirTypes::enumSize; t++)
509 Array<String> dirs = null;
510 if(t == executables) dirs = config.executableDirs;
511 else if(t == includes) dirs = config.includeDirs;
512 else if(t == libraries) dirs = config.libraryDirs;
513 if(dirs && dirs.count)
515 for(c = 0; c < dirs.count; c++)
517 if(dirs[c] && dirs[c][0])
518 dirs[c] = UpdatePortablePath(dirs[c], location, makeAbsolute);
524 if(recentFiles && recentFiles.count)
526 for(c = 0; c < recentFiles.count; c++)
528 if(recentFiles[c] && recentFiles[c][0])
529 recentFiles[c] = UpdatePortablePath(recentFiles[c], location, makeAbsolute);
532 if(recentProjects && recentProjects.count)
534 for(c = 0; c < recentProjects.count; c++)
536 if(recentProjects[c] && recentProjects[c][0])
537 recentProjects[c] = UpdatePortablePath(recentProjects[c], location, makeAbsolute);
540 if(docDir && docDir[0])
541 docDir = UpdatePortablePath(docDir, location, makeAbsolute);
542 if(ideFileDialogLocation && ideFileDialogLocation[0])
543 ideFileDialogLocation = UpdatePortablePath(ideFileDialogLocation, location, makeAbsolute);
544 if(ideProjectFileDialogLocation && ideProjectFileDialogLocation[0])
545 ideProjectFileDialogLocation = UpdatePortablePath(ideProjectFileDialogLocation, location, makeAbsolute);
547 if(projectDefaultTargetDir && projectDefaultTargetDir[0])
548 projectDefaultTargetDir = UpdatePortablePath(projectDefaultTargetDir, location, makeAbsolute);
549 if(projectDefaultIntermediateObjDir && projectDefaultIntermediateObjDir[0])
550 projectDefaultIntermediateObjDir = UpdatePortablePath(projectDefaultIntermediateObjDir, location, makeAbsolute);
552 if(compilerConfigsDir && compilerConfigsDir[0])
553 compilerConfigsDir = UpdatePortablePath(compilerConfigsDir, location, makeAbsolute);
556 char * UpdatePortablePath(char * path, char * location, bool makeAbsolute)
561 char p[MAX_LOCATION];
563 PathCatSlash(p, path);
565 output = CopyString(p);
569 PathRelationship rel = eString_PathRelated(path, location, null);
570 if(rel == subPath || rel == identical)
572 char p[MAX_LOCATION];
573 MakePathRelative(path, location, p);
574 if(!*p) strcpy(p, "./");
575 else ChangeCh(p, '\\', '/');
577 output = CopyString(p);
585 void AddRecentFile(char * fileName)
588 char * filePath = CopyString(fileName);
589 ChangeCh(filePath, '\\', '/');
590 for(c = 0; c<recentFiles.count; c++)
592 if(recentFiles[c] && !fstrcmp(recentFiles[c], filePath))
594 recentFiles.Delete((void *)&recentFiles[c]);
598 while(recentFiles.count >= MaxRecent)
599 recentFiles.Delete(recentFiles.GetLast());
600 recentFiles.Insert(null, filePath);
601 //UpdateRecentMenus(owner);
604 void AddRecentProject(char * projectName)
607 char * filePath = CopyString(projectName);
608 ChangeCh(filePath, '\\', '/');
609 for(c = 0; c<recentProjects.count; c++)
611 if(recentProjects[c] && !fstrcmp(recentProjects[c], filePath))
613 recentProjects.Delete((void *)&recentProjects[c]);
617 while(recentProjects.count >= MaxRecent)
618 recentProjects.Delete(recentProjects.GetLast());
619 recentProjects.Insert(null, filePath);
620 //UpdateRecentMenus(owner);
624 static const char * compilerTypeNames[CompilerType] = { "GCC", "TCC", "PCC", "VS8", "VS9", "VS10" };
625 static const char * compilerTypeVersionString[CompilerType] = { "", "", "", "8.00", "9.00", "10.00" };
626 static const char * compilerTypeSolutionFileVersionString[CompilerType] = { "", "", "", "9.00", "10.00", "11.00" };
627 static const char * compilerTypeYearString[CompilerType] = { "", "", "", "2005", "2008", "2010" };
628 static const char * compilerTypeProjectFileExtension[CompilerType] = { "", "", "", "vcproj", "vcproj", "vcxproj" };
629 // TODO: i18n with Array
630 static Array<String> compilerTypeLongNames
632 $"GNU Compiler Collection (GCC) / GNU Make",
633 $"Tiny C Compiler / GNU Make",
634 $"Portable C Compiler / GNU Make",
635 $"Microsoft Visual Studio 2005 (8.0) Compiler",
636 $"Microsoft Visual Studio 2008 (9.0) Compiler",
637 $"Microsoft Visual Studio 2010 (10.0) Compiler"
639 const CompilerType firstCompilerType = gcc;
640 const CompilerType lastCompilerType = vs10;
641 public enum CompilerType
643 gcc, tcc, pcc, vs8, vs9, vs10;
647 get { return this == vs8 || this == vs9 || this == vs10; }
652 get { return OnGetString(null, null, null); }
658 for(c = firstCompilerType; c <= lastCompilerType; c++)
659 if(!strcmpi(value, compilerTypeNames[c]))
666 property char * longName { get { return OnGetString(null, (void*)1, null); } };
667 property char * versionString { get { return OnGetString(null, (void*)2, null); } };
668 property char * yearString { get { return OnGetString(null, (void*)3, null); } };
669 property char * projectFileExtension { get { return OnGetString(null, (void*)4, null); } };
670 property char * solutionFileVersionString { get { return OnGetString(null, (void*)5, null); } };
672 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
674 if(this >= firstCompilerType && this <= lastCompilerType)
677 strcpy(tempString, compilerTypeNames[this]);
678 if(fieldData == null)
679 return compilerTypeNames[this];
680 else if(fieldData == (void*)1)
681 return compilerTypeLongNames[this];
682 else if(fieldData == (void*)2)
683 return compilerTypeVersionString[this];
684 else if(fieldData == (void*)3)
685 return compilerTypeYearString[this];
686 else if(fieldData == (void*)4)
687 return compilerTypeProjectFileExtension[this];
688 else if(fieldData == (void*)5)
689 return compilerTypeSolutionFileVersionString[this];
707 name = CopyString(value);
713 Platform targetPlatform;
715 property char * makeCommand
717 set { delete makeCommand; if(value && value[0]) makeCommand = CopyString(value); }
718 get { return makeCommand; }
719 isset { return makeCommand && makeCommand[0]; }
721 property char * ecpCommand
723 set { delete ecpCommand; if(value && value[0]) ecpCommand = CopyString(value); }
724 get { return ecpCommand; }
725 isset { return ecpCommand && ecpCommand[0]; }
727 property char * eccCommand
729 set { delete eccCommand; if(value && value[0]) eccCommand = CopyString(value); }
730 get { return eccCommand; }
731 isset { return eccCommand && eccCommand[0]; }
733 property char * ecsCommand
735 set { delete ecsCommand; if(value && value[0]) ecsCommand = CopyString(value); }
736 get { return ecsCommand; }
737 isset { return ecsCommand && ecsCommand[0]; }
739 property char * earCommand
741 set { delete earCommand; if(value && value[0]) earCommand = CopyString(value); }
742 get { return earCommand; }
743 isset { return earCommand && earCommand[0]; }
745 property char * cppCommand
747 set { delete cppCommand; if(value && value[0]) cppCommand = CopyString(value); }
748 get { return cppCommand; }
749 isset { return cppCommand && cppCommand[0]; }
751 property char * ccCommand
753 set { delete ccCommand; if(value && value[0]) ccCommand = CopyString(value); }
754 get { return ccCommand; }
755 isset { return ccCommand && ccCommand[0]; }
757 property char * cxxCommand
759 set { delete cxxCommand; if(value && value[0]) cxxCommand = CopyString(value); }
760 get { return cxxCommand; }
761 isset { return cxxCommand && cxxCommand[0]; }
763 property char * execPrefixCommand // <-- old name for json ide settings file compatibility
765 set { delete executableLauncher; if(value && value[0]) executableLauncher = CopyString(value); }
766 get { return executableLauncher; }
767 isset { return executableLauncher && executableLauncher[0]; }
769 // TODO: implement CompilerConfig::windresCommand
773 property bool supportsBitDepth { set { } get { return true; } isset { return false; } }
775 property char * distccHosts
777 set { delete distccHosts; if(value && value[0]) distccHosts = CopyString(value); }
778 get { return distccHosts; }
779 isset { return distccHosts && distccHosts[0]; }
781 property char * gccPrefix // <-- old name for json ide settings file compatibility
783 set { delete gnuToolchainPrefix; if(value && value[0]) gnuToolchainPrefix = CopyString(value); }
784 get { return gnuToolchainPrefix; }
785 isset { return gnuToolchainPrefix && gnuToolchainPrefix[0]; }
787 property char * sysroot
789 set { delete sysroot; if(value && value[0]) sysroot = CopyString(value); }
790 get { return sysroot; }
791 isset { return sysroot && sysroot[0]; }
793 property Array<String> includeDirs
804 get { return includeDirs; }
805 isset { return includeDirs.count != 0; }
807 property Array<String> libraryDirs
818 get { return libraryDirs; }
819 isset { return libraryDirs.count != 0; }
821 property Array<String> executableDirs
825 executableDirs.Free();
828 delete executableDirs;
829 executableDirs = value;
832 get { return executableDirs; }
833 isset { return executableDirs.count != 0; }
835 property Array<NamedString> environmentVars
839 environmentVars.Free();
842 delete environmentVars;
843 environmentVars = value;
846 get { return environmentVars; }
847 isset { return environmentVars.count != 0; }
849 property Array<String> prepDirectives
853 prepDirectives.Free();
856 delete prepDirectives;
857 prepDirectives = value;
860 get { return prepDirectives; }
861 isset { return prepDirectives.count != 0; }
863 property Array<String> excludeLibs
874 get { return excludeLibs; }
875 isset { return excludeLibs.count != 0; }
877 property Array<String> compilerFlags
881 compilerFlags.Free();
884 delete compilerFlags;
885 compilerFlags = value;
888 get { return compilerFlags; }
889 isset { return compilerFlags.count != 0; }
891 property Array<String> linkerFlags
902 get { return linkerFlags; }
903 isset { return linkerFlags.count != 0; }
906 Array<String> includeDirs { };
907 Array<String> libraryDirs { };
908 Array<String> executableDirs { };
909 // TODO: Can JSON parse and serialize maps?
910 //EnvironmentVariables { };
911 Array<NamedString> environmentVars { };
912 Array<String> prepDirectives { };
913 Array<String> excludeLibs { };
914 Array<String> compilerFlags { };
915 Array<String> linkerFlags { };
925 char * executableLauncher;
927 char * gnuToolchainPrefix;
931 struct { Array<String> includes, libraries, executables; };
932 Array<String> dirs[DirTypes];
946 delete executableLauncher;
948 delete gnuToolchainPrefix;
950 if(environmentVars) environmentVars.Free();
951 if(includeDirs) { includeDirs.Free(); }
952 if(libraryDirs) { libraryDirs.Free(); }
953 if(executableDirs) { executableDirs.Free(); }
954 if(prepDirectives) { prepDirectives.Free(); }
955 if(excludeLibs) { excludeLibs.Free(); }
956 if(compilerFlags) { compilerFlags.Free(); }
957 if(linkerFlags) { linkerFlags.Free(); }
959 CompilerConfig Copy()
984 for(s : includeDirs) copy.includeDirs.Add(CopyString(s));
985 for(s : libraryDirs) copy.libraryDirs.Add(CopyString(s));
986 for(s : executableDirs) copy.executableDirs.Add(CopyString(s));
987 for(ns : environmentVars) copy.environmentVars.Add(NamedString { name = ns.name, string = ns.string });
988 for(s : prepDirectives) copy.prepDirectives.Add(CopyString(s));
989 for(s : excludeLibs) copy.excludeLibs.Add(CopyString(s));
990 for(s : compilerFlags) copy.compilerFlags.Add(CopyString(s));
991 for(s : linkerFlags) copy.linkerFlags.Add(CopyString(s));