Mercurial > projects > ldc
view gen/configfile.cpp @ 1479:4f7d50c744ed
Rewrite `StructLiteralExp::toElem` to store individual fields instead of
generating a constant to fill the entire struct with a single `store`.
This is much more efficient at compile time (fixing #320) and vastly reduces
the size of the emitted code. Since LLVM no longer needs to keep the data for
all fields in "registers" until the store happens, it should also be more
efficient at run time in cases where the fields aren't assigned with constants.
There's also some code clean-up by removing duplicated logic.
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Sat, 06 Jun 2009 20:16:13 +0200 |
parents | 6023f65a3aee |
children | 7d3b47852a7a |
line wrap: on
line source
#include <iostream> #include <string> #include <cassert> #include <cstring> #include "llvm/System/Path.h" #include "libconfig.h++" #include "gen/configfile.h" #include "mars.h" #if _WIN32 #include <windows.h> #undef GetCurrentDirectory #endif namespace sys = llvm::sys; ConfigFile::ConfigFile() { cfg = new libconfig::Config; } ConfigFile::~ConfigFile() { delete cfg; } #if _WIN32 sys::Path ConfigGetExePath(sys::Path p) { char buf[MAX_PATH]; GetModuleFileName(NULL, buf, MAX_PATH); p = buf; p.eraseComponent(); return p; } #endif bool ConfigFile::read(const char* argv0, void* mainAddr, const char* filename) { #if _WIN32 std::string exeDirectoryName; #endif // try to find the config file // 1) try the current working dir sys::Path p = sys::Path::GetCurrentDirectory(); p.appendComponent(filename); if (!p.exists()) { // 2) try the user home dir p = sys::Path::GetUserHomeDirectory(); p.appendComponent(filename); if (!p.exists()) { // 3) try the install-prefix/etc p = sys::Path(LDC_INSTALL_PREFIX); #if !_WIN32 // Does Window need something similar? p.appendComponent("etc"); #endif p.appendComponent(filename); if (!p.exists()) { #if _WIN32 p = ConfigGetExePath(p); exeDirectoryName = p.toString(); #else // 4) try next to the executable p = sys::Path::GetMainExecutable(argv0, mainAddr); p.eraseComponent(); #endif p.appendComponent(filename); if (!p.exists()) { // 5) fail load cfg, users still have the DFLAGS environment var std::cerr << "Error failed to locate the configuration file: " << filename << std::endl; return false; } } } } try { // read the cfg cfg->readFile(p.c_str()); // make sure there's a default group if (!cfg->exists("default")) { std::cerr << "no default settings in configuration file" << std::endl; return false; } libconfig::Setting& root = cfg->lookup("default"); if (!root.isGroup()) { std::cerr << "default is not a group" << std::endl; return false; } // handle switches if (root.exists("switches")) { std::string binpathkey = "%%ldcbinarypath%%"; #if _WIN32 std::string binpath; //This will happen if ldc.conf is found somewhere other than //beside the ldc executable if (exeDirectoryName == "") { sys::Path p; p = ConfigGetExePath(p); exeDirectoryName = p.toString(); } binpath = exeDirectoryName; #else std::string binpath = sys::Path::GetMainExecutable(argv0, mainAddr).getDirname(); #endif libconfig::Setting& arr = cfg->lookup("default.switches"); int len = arr.getLength(); for (int i=0; i<len; i++) { std::string v = arr[i]; // replace binpathkey with binpath size_t p; while (std::string::npos != (p = v.find(binpathkey))) v.replace(p, binpathkey.size(), binpath); switches.push_back(strdup(v.c_str())); } } } catch(libconfig::FileIOException& fioe) { std::cerr << "Error reading configuration file: " << filename << std::endl; return false; } catch(libconfig::ParseException& pe) { std::cerr << "Error parsing configuration file: " << filename << "(" << pe.getLine() << "): " << pe.getError() << std::endl; return false; } catch(...) { std::cerr << "Unknown exception caught!" << std::endl; return false; } return true; }