#include "sdk_precomp.h"
#include "compiler.h"
#include "manager.h"
#include "messagemanager.h"
#include "configmanager.h"
#include "globals.h"
#include "customvars.h"
#include <wx/intl.h>
#include <wx/regex.h>
#include <wx/arrimpl.cpp>
WX_DEFINE_OBJARRAY(RegExArray);
wxString Compiler::CommandTypeDescriptions[COMPILER_COMMAND_TYPES_COUNT] =
{
// These are the strings that describe each CommandType enumerator...
// No need to say that it must have the same order as the enumerators!
_("Compile single file to object file"),
_("Generate dependencies for file"),
_("Compile Win32 resource file"),
_("Link object files to executable"),
_("Link object files to console executable"),
_("Link object files to dynamic library"),
_("Link object files to static library")
};
long Compiler::CompilerIDCounter = 0; // built-in compilers can have IDs from 1 to 255
long Compiler::UserCompilerIDCounter = 255; // user compilers have IDs over 255 (256+)
Compiler::Compiler(const wxString& name)
: m_Name(name),
m_ID(++CompilerIDCounter),
m_ParentID(-1)
{
//ctor
Manager::Get()->GetMessageManager()->DebugLog(_("Added compiler \"%s\""), m_Name.c_str());
}
Compiler::Compiler(const Compiler& other)
: CompileOptionsBase(other),
m_ID(++UserCompilerIDCounter),
m_ParentID(other.m_ID)
{
m_Name = _("Copy of ") + other.m_Name;
m_MasterPath = other.m_MasterPath;
m_Programs = other.m_Programs;
m_Switches = other.m_Switches;
m_Options = other.m_Options;
m_IncludeDirs = other.m_IncludeDirs;
m_LibDirs = other.m_LibDirs;
m_CompilerOptions = other.m_CompilerOptions;
m_LinkerOptions = other.m_LinkerOptions;
m_LinkLibs = other.m_LinkLibs;
m_CmdsBefore = other.m_CmdsBefore;
m_CmdsAfter = other.m_CmdsAfter;
m_RegExes = other.m_RegExes;
for (int i = 0; i < COMPILER_COMMAND_TYPES_COUNT; ++i)
{
m_Commands[i] = other.m_Commands[i];
}
}
Compiler::~Compiler()
{
//dtor
}
void Compiler::SaveSettings(const wxString& baseKey)
{
wxString tmp;
tmp.Printf(_T("%s/%3.3d"), baseKey.c_str(), (int)m_ID);
ConfigManager::Get()->Write(tmp + _T("/_name"), m_Name);
ConfigManager::Get()->Write(tmp + _T("/_parent"), m_ParentID);
wxString key = GetStringFromArray(m_CompilerOptions);
ConfigManager::Get()->Write(tmp + _T("/compiler_options"), key);
key = GetStringFromArray(m_LinkerOptions);
ConfigManager::Get()->Write(tmp + _T("/linker_options"), key);
key = GetStringFromArray(m_IncludeDirs);
ConfigManager::Get()->Write(tmp + _T("/include_dirs"), key);
key = GetStringFromArray(m_ResIncludeDirs);
ConfigManager::Get()->Write(tmp + _T("/res_include_dirs"), key);
key = GetStringFromArray(m_LibDirs);
ConfigManager::Get()->Write(tmp + _T("/library_dirs"), key);
key = GetStringFromArray(m_LinkLibs);
ConfigManager::Get()->Write(tmp + _T("/libraries"), key);
key = GetStringFromArray(m_CmdsBefore);
ConfigManager::Get()->Write(tmp + _T("/commands_before"), key);
key = GetStringFromArray(m_CmdsAfter);
ConfigManager::Get()->Write(tmp + _T("/commands_after"), key);
ConfigManager::Get()->Write(tmp + _T("/master_path"), m_MasterPath);
ConfigManager::Get()->Write(tmp + _T("/extra_paths"), GetStringFromArray(m_ExtraPaths, _T(";")));
ConfigManager::Get()->Write(tmp + _T("/c_compiler"), m_Programs.C);
ConfigManager::Get()->Write(tmp + _T("/cpp_compiler"), m_Programs.CPP);
ConfigManager::Get()->Write(tmp + _T("/linker"), m_Programs.LD);
ConfigManager::Get()->Write(tmp + _T("/lib_linker"), m_Programs.LIB);
ConfigManager::Get()->Write(tmp + _T("/res_compiler"), m_Programs.WINDRES);
ConfigManager::Get()->Write(tmp + _T("/make"), m_Programs.MAKE);
ConfigManager::Get()->Write(tmp + _T("/debugger"), m_Programs.DBG);
for (int i = 0; i < COMPILER_COMMAND_TYPES_COUNT; ++i)
{
ConfigManager::Get()->Write(tmp + _T("/macros/") + CommandTypeDescriptions[i], m_Commands[i]);
}
// switches
ConfigManager::Get()->Write(tmp + _T("/switches/includes"), m_Switches.includeDirs);
ConfigManager::Get()->Write(tmp + _T("/switches/libs"), m_Switches.libDirs);
ConfigManager::Get()->Write(tmp + _T("/switches/link"), m_Switches.linkLibs);
ConfigManager::Get()->Write(tmp + _T("/switches/define"), m_Switches.defines);
ConfigManager::Get()->Write(tmp + _T("/switches/generic"), m_Switches.genericSwitch);
ConfigManager::Get()->Write(tmp + _T("/switches/objectext"), m_Switches.objectExtension);
ConfigManager::Get()->Write(tmp + _T("/switches/deps"), m_Switches.needDependencies);
ConfigManager::Get()->Write(tmp + _T("/switches/forceCompilerQuotes"), m_Switches.forceCompilerUseQuotes);
ConfigManager::Get()->Write(tmp + _T("/switches/forceLinkerQuotes"), m_Switches.forceLinkerUseQuotes);
ConfigManager::Get()->Write(tmp + _T("/switches/logging"), m_Switches.logging);
ConfigManager::Get()->Write(tmp + _T("/switches/buildMethod"), m_Switches.buildMethod);
ConfigManager::Get()->Write(tmp + _T("/switches/libPrefix"), m_Switches.libPrefix);
ConfigManager::Get()->Write(tmp + _T("/switches/libExtension"), m_Switches.libExtension);
ConfigManager::Get()->Write(tmp + _T("/switches/linkerNeedsLibPrefix"), m_Switches.linkerNeedsLibPrefix);
ConfigManager::Get()->Write(tmp + _T("/switches/linkerNeedsLibExtension"), m_Switches.linkerNeedsLibExtension);
// regexes
ConfigManager::Get()->DeleteGroup(tmp + _T("/regex"));
wxString group;
for (size_t i = 0; i < m_RegExes.Count(); ++i)
{
group.Printf(_T("%s/regex/%3.3d"), tmp.c_str(), i + 1);
RegExStruct& rs = m_RegExes[i];
ConfigManager::Get()->Write(group + _T("/description"), rs.desc);
ConfigManager::Get()->Write(group + _T("/type"), rs.lt);
ConfigManager::Get()->Write(group + _T("/regex"), rs.regex);
ConfigManager::Get()->Write(group + _T("/msg1"), rs.msg[0]);
ConfigManager::Get()->Write(group + _T("/msg2"), rs.msg[1]);
ConfigManager::Get()->Write(group + _T("/msg3"), rs.msg[2]);
ConfigManager::Get()->Write(group + _T("/filename"), rs.filename);
ConfigManager::Get()->Write(group + _T("/line"), rs.line);
}
// custom vars
m_pCustomVars->Save(tmp + _T("/custom_variables"));
}
void Compiler::LoadSettings(const wxString& baseKey)
{
wxString tmp;
tmp.Printf(_T("%s/%3.3d"), baseKey.c_str(), (int)m_ID);
if (!ConfigManager::Get()->HasEntry(tmp) && !ConfigManager::Get()->HasGroup(tmp))
return;
wxString sep = wxFileName::GetPathSeparator();
m_Name = ConfigManager::Get()->Read(tmp + _T("/_name"), m_Name);
m_MasterPath = ConfigManager::Get()->Read(tmp + _T("/master_path"), m_MasterPath);
m_ExtraPaths = GetArrayFromString(ConfigManager::Get()->Read(tmp + _T("/extra_paths"), _T("")), _T(";"));
m_Programs.C = ConfigManager::Get()->Read(tmp + _T("/c_compiler"), m_Programs.C);
m_Programs.CPP = ConfigManager::Get()->Read(tmp + _T("/cpp_compiler"), m_Programs.CPP);
m_Programs.LD = ConfigManager::Get()->Read(tmp + _T("/linker"), m_Programs.LD);
m_Programs.LIB = ConfigManager::Get()->Read(tmp + _T("/lib_linker"), m_Programs.LIB);
m_Programs.WINDRES = ConfigManager::Get()->Read(tmp + _T("/res_compiler"), m_Programs.WINDRES);
m_Programs.MAKE = ConfigManager::Get()->Read(tmp + _T("/make"), m_Programs.MAKE);
m_Programs.DBG = ConfigManager::Get()->Read(tmp + _T("/debugger"), m_Programs.DBG);
SetCompilerOptions(GetArrayFromString(ConfigManager::Get()->Read(tmp + _T("/compiler_options"), wxEmptyString)));
SetLinkerOptions(GetArrayFromString(ConfigManager::Get()->Read(tmp + _T("/linker_options"), wxEmptyString)));
SetIncludeDirs(GetArrayFromString(ConfigManager::Get()->Read(tmp + _T("/include_dirs"), m_MasterPath + sep + _T("include"))));
SetResourceIncludeDirs(GetArrayFromString(ConfigManager::Get()->Read(tmp + _T("/res_include_dirs"), m_MasterPath + sep + _T("include"))));
SetLibDirs(GetArrayFromString(ConfigManager::Get()->Read(tmp + _T("/library_dirs"), m_MasterPath + sep + _T("lib"))));
SetLinkLibs(GetArrayFromString(ConfigManager::Get()->Read(tmp + _T("/libraries"), _T(""))));
SetCommandsBeforeBuild(GetArrayFromString(ConfigManager::Get()->Read(tmp + _T("/commands_before"), wxEmptyString)));
SetCommandsAfterBuild(GetArrayFromString(ConfigManager::Get()->Read(tmp + _T("/commands_after"), wxEmptyString)));
for (int i = 0; i < COMPILER_COMMAND_TYPES_COUNT; ++i)
{
m_Commands[i] = ConfigManager::Get()->Read(tmp + _T("/macros/") + CommandTypeDescriptions[i], m_Commands[i]);
}
// switches
m_Switches.includeDirs = ConfigManager::Get()->Read(tmp + _T("/switches/includes"), m_Switches.includeDirs);
m_Switches.libDirs = ConfigManager::Get()->Read(tmp + _T("/switches/libs"), m_Switches.libDirs);
m_Switches.linkLibs = ConfigManager::Get()->Read(tmp + _T("/switches/link"), m_Switches.linkLibs);
m_Switches.defines = ConfigManager::Get()->Read(tmp + _T("/switches/define"), m_Switches.defines);
m_Switches.genericSwitch = ConfigManager::Get()->Read(tmp + _T("/switches/generic"), m_Switches.genericSwitch);
m_Switches.objectExtension = ConfigManager::Get()->Read(tmp + _T("/switches/objectext"), m_Switches.objectExtension);
m_Switches.needDependencies = ConfigManager::Get()->Read(tmp + _T("/switches/deps"), m_Switches.needDependencies);
m_Switches.forceCompilerUseQuotes = ConfigManager::Get()->Read(tmp + _T("/switches/forceCompilerQuotes"), m_Switches.forceCompilerUseQuotes);
m_Switches.forceLinkerUseQuotes = ConfigManager::Get()->Read(tmp + _T("/switches/forceLinkerQuotes"), m_Switches.forceLinkerUseQuotes);
m_Switches.logging = (CompilerLoggingType)ConfigManager::Get()->Read(tmp + _T("/switches/logging"), m_Switches.logging);
m_Switches.buildMethod = (CompilerBuildMethod)ConfigManager::Get()->Read(tmp + _T("/switches/buildMethod"), m_Switches.buildMethod);
m_Switches.libPrefix = ConfigManager::Get()->Read(tmp + _T("/switches/libPrefix"), m_Switches.libPrefix);
m_Switches.libExtension = ConfigManager::Get()->Read(tmp + _T("/switches/libExtension"), m_Switches.libExtension);
m_Switches.linkerNeedsLibPrefix = ConfigManager::Get()->Read(tmp + _T("/switches/linkerNeedsLibPrefix"), m_Switches.linkerNeedsLibPrefix);
m_Switches.linkerNeedsLibExtension = ConfigManager::Get()->Read(tmp + _T("/switches/linkerNeedsLibExtension"), m_Switches.linkerNeedsLibExtension);
// regexes
wxString group;
int index = 1;
bool cleared = false;
while (true)
{
group.Printf(_T("%s/regex/%3.3d"), tmp.c_str(), index++);
if (!ConfigManager::Get()->HasGroup(group))
break;
else if (!cleared)
{
cleared = true;
m_RegExes.Clear();
}
RegExStruct rs;
rs.desc = ConfigManager::Get()->Read(group + _T("/description"));
rs.lt = (CompilerLineType)ConfigManager::Get()->Read(group + _T("/type"), 0L);
rs.regex = ConfigManager::Get()->Read(group + _T("/regex"));
rs.msg[0] = ConfigManager::Get()->Read(group + _T("/msg1"), 0L);
rs.msg[1] = ConfigManager::Get()->Read(group + _T("/msg2"), 0L);
rs.msg[2] = ConfigManager::Get()->Read(group + _T("/msg3"), 0L);
rs.filename = ConfigManager::Get()->Read(group + _T("/filename"), 0L);
rs.line = ConfigManager::Get()->Read(group + _T("/line"), 0L);
m_RegExes.Add(rs);
}
// custom vars
m_pCustomVars->Load(tmp + _T("/custom_variables"));
m_pCustomVars->SetModified(false);
}
CompilerLineType Compiler::CheckForWarningsAndErrors(const wxString& line)
{
m_ErrorFilename.Clear();
m_ErrorLine.Clear();
m_Error.Clear();
for (size_t i = 0; i < m_RegExes.Count(); ++i)
{
RegExStruct& rs = m_RegExes[i];
if (rs.regex.IsEmpty())
continue;
wxRegEx regex(rs.regex);
if (regex.Matches(line))
{
if (rs.filename > 0)
m_ErrorFilename = UnixFilename(regex.GetMatch(line, rs.filename));
if (rs.line > 0)
m_ErrorLine = regex.GetMatch(line, rs.line);
for (int x = 0; x < 3; ++x)
{
if (rs.msg[x] > 0)
{
if (!m_Error.IsEmpty())
m_Error << _T(" ");
m_Error << regex.GetMatch(line, rs.msg[x]);
}
}
return rs.lt;
}
}
return cltNormal; // default return value
}
syntax highlighted by Code2HTML, v. 0.9.1