#ifdef ECERE_STATIC
-import static "ecere"
+public import static "ecere"
#else
-import "ecere"
+public import "ecere"
#endif
import "StringsBox"
define defaultCompilerName = "Default";
-define defaultObjDirExpression = "obj/$(CONFIG).$(PLATFORM)";
+define defaultObjDirExpression = "obj/$(CONFIG).$(PLATFORM)$(COMPILER_SUFFIX)$(DEBUG_SUFFIX)";
-char * settingsDirectoryNames[DirTypes] =
+char * settingsDirectoryNames[DirTypes] =
{
"Include Files",
"Library Files",
"Executable Files"
};
+// This function cannot accept same pointer for source and output
+// todo: rename ReplaceSpaces to EscapeSpaceAndSpecialChars or something
+void ReplaceSpaces(char * output, char * source)
+{
+ int c, dc;
+ char ch, pch = 0;
+
+ for(c = 0, dc = 0; (ch = source[c]); c++, dc++)
+ {
+ if(ch == ' ') output[dc++] = '\\';
+ if(ch == '\"') output[dc++] = '\\';
+ if(ch == '&') output[dc++] = '\\';
+ if(pch != '$')
+ {
+ if(ch == '(' || ch == ')') output[dc++] = '\\';
+ pch = ch;
+ }
+ else if(ch == ')')
+ pch = 0;
+ output[dc] = ch;
+ }
+ output[dc] = '\0';
+}
+
+
enum GlobalSettingsChange { none, editorSettings, projectOptions, compilerSettings };
+enum PathRelationship { unrelated, identical, siblings, subPath, parentPath, insuficientInput, pathEmpty, toEmpty, pathNull, toNull, bothEmpty, bothNull };
+PathRelationship eString_PathRelated(char * path, char * to, char * pathDiff)
+{
+ PathRelationship result;
+ if(pathDiff) *pathDiff = '\0';
+ if(path && *path && to && *to)
+ {
+ char toPart[MAX_FILENAME], toRest[MAX_LOCATION];
+ char pathPart[MAX_FILENAME], pathRest[MAX_LOCATION];
+ strcpy(toRest, to);
+ strcpy(pathRest, path);
+ for(; toRest[0] && pathRest[0];)
+ {
+ SplitDirectory(toRest, toPart, toRest);
+ SplitDirectory(pathRest, pathPart, pathRest);
+ if(!fstrcmp(pathPart, toPart)) result = siblings;
+ else break;
+ }
+ if(result == siblings)
+ {
+ if(!*toRest && !*pathRest) result = identical;
+ else if(!*pathRest) result = parentPath;
+ else result = subPath;
+ if(pathDiff && result != identical) strcpy(pathDiff, *pathRest == '\0' ? toRest : pathRest);
+ }
+ else result = unrelated;
+ }
+ else
+ {
+ if(path && to)
+ {
+ if(!*path && !*to) result = bothEmpty;
+ else if(!*path) result = pathEmpty;
+ else result = toEmpty;
+ }
+ else if(!path && !to) result = bothNull;
+ else if(!path) result = pathNull;
+ else result = toNull;
+ }
+ return result;
+}
+
char * CopyValidateMakefilePath(char * path)
{
- const int map[] = { 0, 1, 2, 3, 4, 0, 1, 7 };
- const char * vars[] = { "$(MODULE)", "$(CONFIG)", "$(PLATFORM)", "$(COMPILER)", "$(TARGET)", "$(PROJECT)", "$(CONFIGURATION)", (char *)0 };
+ const int map[] = { 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 7 };
+ const char * vars[] = { "$(MODULE)", "$(CONFIG)", "$(PLATFORM)", "$(COMPILER)", "$(TARGET)", "$(COMPILER_SUFFIX)", "$(DEBUG_SUFFIX)", "$(PROJECT)", "$(CONFIGURATION)", "$(TARGET_PLATFORM)",(char *)0 };
char * copy = null;
if(path)
char * tmp = copy;
char * start = tmp;
Array<char *> parts { };
-
+
for(c=0; c<len; c++)
{
if(tmp[c] == '$')
return copy;
}
+void ValidPathBufCopy(char *output, char *input)
+{
+#ifdef __WIN32__
+ bool volumePath = false;
+#endif
+ strcpy(output, input);
+ TrimLSpaces(output, output);
+ TrimRSpaces(output, output);
+ MakeSystemPath(output);
+#ifdef __WIN32__
+ if(output[0] && output[1] == ':')
+ {
+ output[1] = '_';
+ volumePath = true;
+ }
+#endif
+ {
+ char * chars = "*|:\",<>?";
+ char ch, * s = output, * o = output;
+ while((ch = *s++)) { if(!strchr(chars, ch)) *o++ = ch; }
+ *o = '\0';
+ }
+#ifdef __WIN32__
+ if(volumePath && output[0])
+ output[1] = ':';
+#endif
+}
+
+void RemoveTrailingPathSeparator(char *path)
+{
+ int len;
+ len = strlen(path);
+ if(len>1 && path[len-1] == DIR_SEP)
+ path[--len] = '\0';
+}
+
+void BasicValidatePathBoxPath(PathBox pathBox)
+{
+ char path[MAX_LOCATION];
+ ValidPathBufCopy(path, pathBox.path);
+ RemoveTrailingPathSeparator(path);
+ pathBox.path = path;
+}
+
CompilerConfig MakeDefaultCompiler(char * name, bool readOnly)
{
CompilerConfig defaultCompiler
ecsDefaultCommand,
earDefaultCommand,
cppDefaultCommand,
- ccDefaultCommand
+ ccDefaultCommand,
+ cxxDefaultCommand
};
incref defaultCompiler;
return defaultCompiler;
virtual void OnLoad(GlobalSettingsData data);
+ char moduleLocation[MAX_LOCATION];
+
private:
+ FileSize settingsFileSize;
+
IDESettingsContainer()
{
char path[MAX_LOCATION];
char * start;
- LocateModule(null, path);
+ LocateModule(null, moduleLocation);
+ strcpy(path, moduleLocation);
+ StripLastDirectory(moduleLocation, moduleLocation);
+ ChangeCh(moduleLocation, '\\', '/');
// PortableApps.com directory structure
if((start = strstr(path, "\\App\\EcereSDK\\bin\\ide.exe")))
{
PathCat(defaultConfigFilePath, "App");
PathCat(defaultConfigFilePath, "DefaultData");
PathCat(defaultConfigFilePath, "ecereIDE.ini");
-
+
if(FileExists(defaultConfigFilePath))
{
if(!FileExists(configFilePath))
}
PathCat(path, "Data");
// the forced settings location will only be
- // used if the running ide's path matches
+ // used if the running ide's path matches
// the PortableApps.com directory structure
- // and the default ini file is found in
+ // and the default ini file is found in
// the DefaultData directory
settingsLocation = path;
portable = true;
void OnAskReloadSettings()
{
- /*if(MessageBox { type = YesNo, master = this,
- text = "Global Settings Modified Externally",
+ /*if(MessageBox { type = YesNo, master = this,
+ text = "Global Settings Modified Externally",
contents = "The global settings were modified by another instance.\n"
"Would you like to reload them?" }.Modal() == Yes)*/
{
- Load();
+ double o, n;
+ FileSize newSettingsFileSize;
+ FileGetSize(settingsFilePath, &newSettingsFileSize);
+ o = settingsFileSize;
+ n = newSettingsFileSize;
+ if(o - n < 2048)
+ Load();
+ else
+ {
+ GuiApplication app = ((GuiApplication)__thisModule.application);
+ Window w;
+ for(w = app.desktop.firstChild; w && (!w.created || !w.visible); w = w.next);
+ MessageBox { master = w, type = ok,
+ text = "Global Settings Modified Externally",
+ contents = "The global settings were modified by another process and a drastic shrinking of the settings file was detected.\n"
+ "The new settings will not be loaded to prevent loss of your ide settings.\n"
+ "Please check your settings file and make sure to save this IDE's global settings if your settings file has been compromised."
+ }.Create();
+ //Save();
+ }
}
}
- void Load()
+ SettingsIOResult Load()
{
SettingsIOResult result = GlobalSettings::Load();
IDESettings data = (IDESettings)this.data;
- //if(result == success)
+ CompilerConfig defaultCompiler = null;
if(!data)
{
this.data = IDESettings { };
bool loaded;
OldIDESettings oldSettings { };
Close();
- loaded = oldSettings.Load();
+ loaded = oldSettings.Load() == success;
oldSettings.Close();
if(loaded)
{
data.useFreeCaret = oldSettings.useFreeCaret;
data.showLineNumbers = oldSettings.showLineNumbers;
data.caretFollowsScrolling = oldSettings.caretFollowsScrolling;
- delete data.displayDriver;
- data.displayDriver = oldSettings.displayDriver;
+ delete data.displayDriver; data.displayDriver = CopyString(oldSettings.displayDriver);
data.projectDefaultTargetDir = oldSettings.projectDefaultTargetDir;
data.projectDefaultIntermediateObjDir = oldSettings.projectDefaultIntermediateObjDir;
-
+
Save();
result = success;
}
}
if(result == fileNotFound || !data)
{
- CompilerConfig defaultCompiler = MakeDefaultCompiler(defaultCompilerName, true);
- // We incref the compilers below, so reset refCount to 0
- defaultCompiler._refCount = 0;
data = (IDESettings)this.data;
-
- data.compilerConfigs.Add(defaultCompiler);
- data.useFreeCaret = true;
+ data.useFreeCaret = false; //true;
data.showLineNumbers = true;
- data.caretFollowsScrolling = true;
+ data.caretFollowsScrolling = false; //true;
}
}
+ // Ensure we have a default compiler
+ defaultCompiler = data.GetCompilerConfig(defaultCompilerName);
+ if(!defaultCompiler)
+ {
+ defaultCompiler = MakeDefaultCompiler(defaultCompilerName, true);
+ data.compilerConfigs.Add(defaultCompiler);
+ }
+
+ // We incref the compilers below, so reset refCount to 0
+ defaultCompiler._refCount = 0;
+
CloseAndMonitor();
+ FileGetSize(settingsFilePath, &settingsFileSize);
if(data.compilerConfigs)
{
for(c : data.compilerConfigs)
{
CompilerConfig compiler = c;
+ char * cxxCommand = compiler.cxxCommand;
+ if(!cxxCommand || !cxxCommand[0])
+ compiler.cxxCommand = cxxDefaultCommand;
incref compiler;
}
}
- if(portable)
- {
- char location[MAX_LOCATION];
- LocateModule(null, location);
- StripLastDirectory(location, location);
- if(location[0] && FileExists(location).isDirectory)
- {
- if(data.portableLocation && data.portableLocation[0] && strcmp(data.portableLocation, location))
- {
- data.UpdatePortablePaths(data.portableLocation, location);
- data.portableLocation = location;
- Save();
- }
- }
- }
+ if(portable && moduleLocation[0] && FileExists(moduleLocation).isDirectory)
+ data.ManagePortablePaths(moduleLocation, true);
data.ForcePathSeparatorStyle(true);
OnLoad(data);
+ return result;
}
- void Save()
+ SettingsIOResult Save()
{
+ SettingsIOResult result;
+
IDESettings data = (IDESettings)this.data;
Platform runtimePlatform = GetRuntimePlatform();
- data.ForcePathSeparatorStyle(runtimePlatform != win32);
- if(!GlobalSettings::Save())
+ if(portable && moduleLocation[0] && FileExists(moduleLocation).isDirectory)
+ data.ManagePortablePaths(moduleLocation, false);
+ data.ForcePathSeparatorStyle(true);
+ result = GlobalSettings::Save();
+ if(result != success)
PrintLn("Error saving IDE settings");
- if(runtimePlatform == win32)
- data.ForcePathSeparatorStyle(true);
+ if(portable && moduleLocation[0] && FileExists(moduleLocation).isDirectory)
+ data.ManagePortablePaths(moduleLocation, true);
CloseAndMonitor();
+ FileGetSize(settingsFilePath, &settingsFileSize);
+ return result;
}
}
bool showLineNumbers;
bool caretFollowsScrolling;
char * displayDriver;
-
+
// TODO: Classify settings
//EditorSettings editor { };
isset { return projectDefaultIntermediateObjDir && projectDefaultIntermediateObjDir[0]; }
}
- property char * portableLocation
+ property char * compilerConfigsDir
{
- set { delete portableLocation; if(value && value[0]) portableLocation = CopyString(value); }
- get { return portableLocation ? portableLocation : ""; }
- isset { return portableLocation && portableLocation[0]; }
+ set { delete compilerConfigsDir; if(value && value[0]) compilerConfigsDir = CopyString(value); }
+ get { return compilerConfigsDir ? compilerConfigsDir : ""; }
+ isset { return compilerConfigsDir && compilerConfigsDir[0]; }
}
property char * defaultCompiler
isset { return defaultCompiler && defaultCompiler[0]; }
}
+ property String language
+ {
+ set
+ {
+ delete language;
+ language = CopyString(value);
+ }
+ get { return language; }
+ isset { return language != null; }
+ }
+
private:
char * docDir;
char * ideFileDialogLocation;
char * ideProjectFileDialogLocation;
char * projectDefaultTargetDir;
char * projectDefaultIntermediateObjDir;
- char * portableLocation;
+ char * compilerConfigsDir;
char * defaultCompiler;
+ String language;
CompilerConfig GetCompilerConfig(String compilerName)
{
recentProjects.Free();
delete recentProjects;
delete docDir;
-
+
delete projectDefaultTargetDir;
delete projectDefaultIntermediateObjDir;
- delete portableLocation;
+ delete compilerConfigsDir;
delete defaultCompiler;
delete ideFileDialogLocation;
if(projectDefaultIntermediateObjDir && projectDefaultIntermediateObjDir[0])
ChangeCh(projectDefaultIntermediateObjDir, from, to);
- if(portableLocation && portableLocation[0])
- ChangeCh(portableLocation, from, to);
+ if(compilerConfigsDir && compilerConfigsDir[0])
+ ChangeCh(compilerConfigsDir, from, to);
}
- bool UpdatePortablePaths(char * oldPath, char * newPath)
+ void ManagePortablePaths(char * location, bool makeAbsolute)
{
- int oldLen = strlen(oldPath);
- int newLen = strlen(newPath);
+ int c;
if(compilerConfigs && compilerConfigs.count)
{
for(config : compilerConfigs)
{
- DirTypes c;
- for(c = 0; c < DirTypes::enumSize; c++)
+ DirTypes t;
+ for(t = 0; t < DirTypes::enumSize; t++)
{
- Array<String> dirs;
- if(c == executables) dirs = config.executableDirs;
- else if(c == includes) dirs = config.includeDirs;
- else if(c == libraries) dirs = config.libraryDirs;
+ Array<String> dirs = null;
+ if(t == executables) dirs = config.executableDirs;
+ else if(t == includes) dirs = config.includeDirs;
+ else if(t == libraries) dirs = config.libraryDirs;
if(dirs && dirs.count)
{
- int i;
- for(i = 0; i < dirs.count; i++)
+ for(c = 0; c < dirs.count; c++)
{
- if(dirs[i] && dirs[i][0])
- dirs[i] = ReplaceInCopyString(dirs[i], oldPath, oldLen, newPath, newLen);
+ if(dirs[c] && dirs[c][0])
+ dirs[c] = UpdatePortablePath(dirs[c], location, makeAbsolute);
}
}
}
}
if(recentFiles && recentFiles.count)
{
- int c;
for(c = 0; c < recentFiles.count; c++)
{
if(recentFiles[c] && recentFiles[c][0])
- recentFiles[c] = ReplaceInCopyString(recentFiles[c], oldPath, oldLen, newPath, newLen);
+ recentFiles[c] = UpdatePortablePath(recentFiles[c], location, makeAbsolute);
}
}
if(recentProjects && recentProjects.count)
{
- int c;
for(c = 0; c < recentProjects.count; c++)
{
if(recentProjects[c] && recentProjects[c][0])
- recentProjects[c] = ReplaceInCopyString(recentProjects[c], oldPath, oldLen, newPath, newLen);
+ recentProjects[c] = UpdatePortablePath(recentProjects[c], location, makeAbsolute);
}
}
if(docDir && docDir[0])
- docDir = ReplaceInCopyString(docDir, oldPath, oldLen, newPath, newLen);
+ docDir = UpdatePortablePath(docDir, location, makeAbsolute);
if(ideFileDialogLocation && ideFileDialogLocation[0])
- ideFileDialogLocation = ReplaceInCopyString(ideFileDialogLocation, oldPath, oldLen, newPath, newLen);
+ ideFileDialogLocation = UpdatePortablePath(ideFileDialogLocation, location, makeAbsolute);
if(ideProjectFileDialogLocation && ideProjectFileDialogLocation[0])
- ideProjectFileDialogLocation = ReplaceInCopyString(ideProjectFileDialogLocation, oldPath, oldLen, newPath, newLen);
+ ideProjectFileDialogLocation = UpdatePortablePath(ideProjectFileDialogLocation, location, makeAbsolute);
if(projectDefaultTargetDir && projectDefaultTargetDir[0])
- projectDefaultTargetDir = ReplaceInCopyString(projectDefaultTargetDir, oldPath, oldLen, newPath, newLen);
+ projectDefaultTargetDir = UpdatePortablePath(projectDefaultTargetDir, location, makeAbsolute);
if(projectDefaultIntermediateObjDir && projectDefaultIntermediateObjDir[0])
- projectDefaultIntermediateObjDir = ReplaceInCopyString(projectDefaultIntermediateObjDir, oldPath, oldLen, newPath, newLen);
+ projectDefaultIntermediateObjDir = UpdatePortablePath(projectDefaultIntermediateObjDir, location, makeAbsolute);
+
+ if(compilerConfigsDir && compilerConfigsDir[0])
+ compilerConfigsDir = UpdatePortablePath(compilerConfigsDir, location, makeAbsolute);
}
- char * ReplaceInCopyString(char * string, char * find, int lenFind, char * replace, int lenReplace)
+ char * UpdatePortablePath(char * path, char * location, bool makeAbsolute)
{
- char * output = string;
- char * start;
- if(/*string && string[0] && */(start = strstr(string, find)))
+ char * output;
+ if(makeAbsolute)
{
- if(lenFind == lenReplace)
- strncpy(start, replace, lenReplace);
- else
+ char p[MAX_LOCATION];
+ strcpy(p, location);
+ PathCatSlash(p, path);
+ delete path;
+ output = CopyString(p);
+ }
+ else
+ {
+ PathRelationship rel = eString_PathRelated(path, location, null);
+ if(rel == subPath || rel == identical)
{
- int newLen = strlen(string) + lenReplace - lenFind + 1;
- char * newString = new char[newLen];
- start[0] = '\0';
- strcpy(newString, string);
- start += lenFind;
- strcat(newString, replace);
- strcat(newString, start);
- delete string;
- return newString;
+ char p[MAX_LOCATION];
+ MakePathRelative(path, location, p);
+ if(!*p) strcpy(p, "./");
+ else ChangeCh(p, '\\', '/');
+ delete path;
+ output = CopyString(p);
}
+ else
+ output = path;
}
return output;
}
static const char * compilerTypeYearString[CompilerType] = { "", "", "", "2005", "2008", "2010" };
static const char * compilerTypeProjectFileExtension[CompilerType] = { "", "", "", "vcproj", "vcproj", "vcxproj" };
// TODO: i18n with Array
-static const char * compilerTypeLongNames[CompilerType] =
-{
- "GNU Compiler Collection (GCC) / GNU Make",
- "Tiny C Compiler / GNU Make",
- "Portable C Compiler / GNU Make",
- "Microsoft Visual Studio 2005 (8.0) Compiler",
- "Microsoft Visual Studio 2008 (9.0) Compiler",
- "Microsoft Visual Studio 2010 (10.0) Compiler"
-};
+static Array<String> compilerTypeLongNames
+{ [
+ $"GNU Compiler Collection (GCC) / GNU Make",
+ $"Tiny C Compiler / GNU Make",
+ $"Portable C Compiler / GNU Make",
+ $"Microsoft Visual Studio 2005 (8.0) Compiler",
+ $"Microsoft Visual Studio 2008 (9.0) Compiler",
+ $"Microsoft Visual Studio 2010 (10.0) Compiler"
+] };
const CompilerType firstCompilerType = gcc;
const CompilerType lastCompilerType = vs10;
public enum CompilerType
{
get { return OnGetString(null, null, null); }
set
- {
+ {
if(value)
{
Platform c;
get { return ccCommand; }
isset { return ccCommand && ccCommand[0]; }
}
- property char * execPrefixCommand
+ property char * cxxCommand
{
- set { delete execPrefixCommand; if(value && value[0]) execPrefixCommand = CopyString(value); }
- get { return execPrefixCommand; }
- isset { return execPrefixCommand && execPrefixCommand[0]; }
+ set { delete cxxCommand; if(value && value[0]) cxxCommand = CopyString(value); }
+ get { return cxxCommand; }
+ isset { return cxxCommand && cxxCommand[0]; }
}
+ property char * execPrefixCommand // <-- old name for json ide settings file compatibility
+ {
+ set { delete executableLauncher; if(value && value[0]) executableLauncher = CopyString(value); }
+ get { return executableLauncher; }
+ isset { return executableLauncher && executableLauncher[0]; }
+ }
+ // TODO: implement CompilerConfig::windresCommand
bool ccacheEnabled;
bool distccEnabled;
+ // deprecated
+ property bool supportsBitDepth { set { } get { return true; } isset { return false; } }
+
property char * distccHosts
{
set { delete distccHosts; if(value && value[0]) distccHosts = CopyString(value); }
get { return distccHosts; }
isset { return distccHosts && distccHosts[0]; }
}
+ property char * gccPrefix // <-- old name for json ide settings file compatibility
+ {
+ set { delete gnuToolchainPrefix; if(value && value[0]) gnuToolchainPrefix = CopyString(value); }
+ get { return gnuToolchainPrefix; }
+ isset { return gnuToolchainPrefix && gnuToolchainPrefix[0]; }
+ }
+ property char * sysroot
+ {
+ set { delete sysroot; if(value && value[0]) sysroot = CopyString(value); }
+ get { return sysroot; }
+ isset { return sysroot && sysroot[0]; }
+ }
property Array<String> includeDirs
{
set
get { return environmentVars; }
isset { return environmentVars.count != 0; }
}
+ property Array<String> prepDirectives
+ {
+ set
+ {
+ prepDirectives.Free();
+ if(value)
+ {
+ delete prepDirectives;
+ prepDirectives = value;
+ }
+ }
+ get { return prepDirectives; }
+ isset { return prepDirectives.count != 0; }
+ }
+ property Array<String> excludeLibs
+ {
+ set
+ {
+ excludeLibs.Free();
+ if(value)
+ {
+ delete excludeLibs;
+ excludeLibs = value;
+ }
+ }
+ get { return excludeLibs; }
+ isset { return excludeLibs.count != 0; }
+ }
+ property Array<String> eCcompilerFlags
+ {
+ set
+ {
+ eCcompilerFlags.Free();
+ if(value)
+ {
+ delete eCcompilerFlags;
+ eCcompilerFlags = value;
+ }
+ }
+ get { return eCcompilerFlags; }
+ isset { return eCcompilerFlags.count != 0; }
+ }
+ property Array<String> compilerFlags
+ {
+ set
+ {
+ compilerFlags.Free();
+ if(value)
+ {
+ delete compilerFlags;
+ compilerFlags = value;
+ }
+ }
+ get { return compilerFlags; }
+ isset { return compilerFlags.count != 0; }
+ }
+ property Array<String> linkerFlags
+ {
+ set
+ {
+ linkerFlags.Free();
+ if(value)
+ {
+ delete linkerFlags;
+ linkerFlags = value;
+ }
+ }
+ get { return linkerFlags; }
+ isset { return linkerFlags.count != 0; }
+ }
private:
Array<String> includeDirs { };
Array<String> libraryDirs { };
// TODO: Can JSON parse and serialize maps?
//EnvironmentVariables { };
Array<NamedString> environmentVars { };
+ Array<String> prepDirectives { };
+ Array<String> excludeLibs { };
+ Array<String> eCcompilerFlags { };
+ Array<String> compilerFlags { };
+ Array<String> linkerFlags { };
char * name;
char * makeCommand;
char * ecpCommand;
char * earCommand;
char * cppCommand;
char * ccCommand;
- char * execPrefixCommand;
+ char * cxxCommand;
+ char * executableLauncher;
char * distccHosts;
+ char * gnuToolchainPrefix;
+ char * sysroot;
/*union
{
struct { Array<String> includes, libraries, executables; };
delete earCommand;
delete cppCommand;
delete ccCommand;
+ delete cxxCommand;
delete makeCommand;
- delete execPrefixCommand;
+ delete executableLauncher;
delete distccHosts;
+ delete gnuToolchainPrefix;
+ delete sysroot;
if(environmentVars) environmentVars.Free();
if(includeDirs) { includeDirs.Free(); }
if(libraryDirs) { libraryDirs.Free(); }
if(executableDirs) { executableDirs.Free(); }
+ if(prepDirectives) { prepDirectives.Free(); }
+ if(excludeLibs) { excludeLibs.Free(); }
+ if(compilerFlags) { compilerFlags.Free(); }
+ if(eCcompilerFlags) { eCcompilerFlags.Free(); }
+ if(linkerFlags) { linkerFlags.Free(); }
}
CompilerConfig Copy()
{
earCommand,
cppCommand,
ccCommand,
- execPrefixCommand,
+ cxxCommand,
+ executableLauncher,
ccacheEnabled,
distccEnabled,
- distccHosts
+ false,
+ distccHosts,
+ gnuToolchainPrefix,
+ sysroot
};
for(s : includeDirs) copy.includeDirs.Add(CopyString(s));
for(s : libraryDirs) copy.libraryDirs.Add(CopyString(s));
for(s : executableDirs) copy.executableDirs.Add(CopyString(s));
for(ns : environmentVars) copy.environmentVars.Add(NamedString { name = ns.name, string = ns.string });
+ for(s : prepDirectives) copy.prepDirectives.Add(CopyString(s));
+ for(s : excludeLibs) copy.excludeLibs.Add(CopyString(s));
+ for(s : compilerFlags) copy.compilerFlags.Add(CopyString(s));
+ for(s : eCcompilerFlags) copy.eCcompilerFlags.Add(CopyString(s));
+ for(s : linkerFlags) copy.linkerFlags.Add(CopyString(s));
incref copy;
return copy;
}
}
+
+struct LanguageOption
+{
+ String name;
+ String bitmap;
+ String code;
+ BitmapResource res;
+
+ char * OnGetString(char * tempString, void * fieldData, bool * needClass)
+ {
+ return name;
+ }
+
+ void OnDisplay(Surface surface, int x, int y, int width, void * data, Alignment alignment, DataDisplayFlags flags)
+ {
+ Bitmap icon = res ? res.bitmap : null;
+ int w = 8 + 16;
+ if(icon)
+ surface.Blit(icon, x + (16 - icon.width) / 2,y+2,0,0, icon.width, icon.height);
+ class::OnDisplay(surface, x + w, y, width - w, null, alignment, flags);
+ }
+};
+
+Array<LanguageOption> languages
+{ [
+ { "English", ":countryCode/gb.png", "" },
+ { "汉语", ":countryCode/cn.png", "zh_CN" },
+ { "Español", ":countryCode/es.png", "es" },
+ { "Русский (43%)", ":countryCode/ru.png", "ru" },
+ { "Português (28%)", ":countryCode/pt.png", "pt_BR" },
+ { "Nederlandse (13%)", ":countryCode/nl.png", "nl" },
+ { "Tiếng Việt (12%)", ":countryCode/vn.png", "vi" },
+ { "मराठी (10%)", ":countryCode/in.png", "mr" },
+ { "Hebrew (8%)", ":countryCode/il.png", "he" },
+ { "Magyar (8%)", ":countryCode/hu.png", "hu" }
+] };
+
+String GetLanguageString()
+{
+ String language = getenv("LANGUAGE");
+ if(!language) language = getenv("LC_ALL");
+ if(!language) language = getenv("LC_MESSAGES");
+ if(!language) language = getenv("LANG");
+ if(!language) language = "";
+ return language;
+}
+
+bool LanguageRestart(char * code, Application app, IDESettings settings, IDESettingsContainer settingsContainer, Window ide, Window projectView, bool wait)
+{
+ bool restart = true;
+ String command = null;
+ int arg0Len = strlen(app.argv[0]);
+ int len = arg0Len;
+ int j;
+ char ch;
+
+ if(ide)
+ {
+ Window w;
+
+ if(projectView)
+ {
+ Window w;
+ for(w = ide.firstChild; w; w = w.next)
+ {
+ if(w.isActiveClient && w.isDocument)
+ {
+ if(!w.CloseConfirmation(true))
+ {
+ restart = false;
+ break;
+ }
+ }
+ }
+ if(restart)
+ {
+ if(!projectView.CloseConfirmation(true))
+ restart = false;
+ if(projectView.fileName)
+ {
+ char * name = projectView.fileName;
+ if(name)
+ {
+ for(j = 0; (ch = name[j]); j++)
+ len += (ch == ' ' || ch == '\"' || ch == '&' || ch == '$' || ch == '(' || ch == ')') ? 2 : 1;
+ }
+ }
+
+ command = new char[len + 1];
+
+ strcpy(command, app.argv[0]);
+ len = arg0Len;
+ if(projectView.fileName)
+ {
+ strcat(command, " ");
+ len++;
+ ReplaceSpaces(command + len, projectView.fileName);
+ }
+ }
+ if(restart)
+ {
+ for(w = ide.firstChild; w; w = w.next)
+ if(w.isActiveClient && w.isDocument)
+ w.modifiedDocument = false;
+ projectView.modifiedDocument = false;
+ }
+ }
+ else
+ {
+ for(w = ide.firstChild; w; w = w.next)
+ {
+ if(w.isActiveClient && w.isDocument)
+ {
+ if(!w.CloseConfirmation(true))
+ {
+ restart = false;
+ break;
+ }
+ if(w.fileName)
+ {
+ char * name = w.fileName;
+ len++;
+ for(j = 0; (ch = name[j]); j++)
+ len += (ch == ' ' || ch == '\"' || ch == '&' || ch == '$' || ch == '(' || ch == ')') ? 2 : 1;
+ }
+ }
+ }
+
+ if(restart)
+ {
+ command = new char[len + 1];
+ strcpy(command, app.argv[0]);
+ len = arg0Len;
+
+ for(w = ide.firstChild; w; w = w.next)
+ {
+ if(w.isActiveClient && w.isDocument)
+ {
+ char * name = w.fileName;
+ if(name)
+ {
+ strcat(command, " ");
+ len++;
+ ReplaceSpaces(command + len, name);
+ len = strlen(command);
+ }
+ }
+ }
+ }
+ if(restart)
+ {
+ for(w = ide.firstChild; w; w = w.next)
+ if(w.isActiveClient && w.isDocument)
+ w.modifiedDocument = false;
+ }
+ }
+ if(restart)
+ {
+ settings.language = code;
+ settingsContainer.Save();
+ if(eClass_IsDerived(app._class, class(GuiApplication)))
+ {
+ GuiApplication guiApp = (GuiApplication)app;
+ guiApp.desktop.Destroy(0);
+ }
+ }
+ }
+ else
+ {
+ int i;
+ for(i = 1; i < app.argc; i++)
+ {
+ char * arg = app.argv[i];
+ len++;
+ for(j = 0; (ch = arg[j]); j++)
+ len += (ch == ' ' || ch == '\"' || ch == '&' || ch == '$' || ch == '(' || ch == ')') ? 2 : 1;
+ }
+
+ command = new char[len + 1];
+ strcpy(command, app.argv[0]);
+ len = arg0Len;
+ for(i = 1; i < app.argc; i++)
+ {
+ strcat(command, " ");
+ len++;
+ ReplaceSpaces(command + len, app.argv[i]);
+ len = strlen(command);
+ }
+ }
+
+ if(restart)
+ {
+ SetEnvironment("LANGUAGE", code);
+ if(wait)
+ ExecuteWait(command);
+ else
+ Execute(command);
+ }
+ delete command;
+ return restart;
+}