view gen/configfile.cpp @ 1605:1d5721f9ae18

[WIP] Merge DMD r251: bugzilla 111 (appending a dchar to a char[]) This patch needs some work in the code generation, because of the runtime changes (functions "_d_arrayappendcd" and "_d_arrayappendwd" are added). This doesn't affect existing code though, it just makes with patch a little useless, because something like this: char [] s; s ~= '\u6211'; That failed to compile with a nice error message previously to this change, now fails with and ugly error message (a failed assertion). Apparently there is a regression introduced by this patch too, when compiling Dil I get this assertion message: ldc: /home/luca/tesis/ldc/gen/statements.cpp:132: virtual void ReturnStatement::toIR(IRState*): Assertion `p->topfunc()->getReturnType() == llvm::Type::getVoidTy(gIR->context())' failed. 0 ldc 0x08a91628 Thank god we have bisecting capabilities in VCSs now ;) --- dmd/expression.c | 47 +++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 41 insertions(+), 6 deletions(-)
author Leandro Lucarella <llucax@gmail.com>
date Wed, 06 Jan 2010 15:18:19 -0300
parents ee6b20e7aedb
children 40bd4a0d4870
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"

namespace sys = llvm::sys;

ConfigFile::ConfigFile()
{
    cfg = new libconfig::Config;
}

ConfigFile::~ConfigFile()
{
    delete cfg;
}


bool ConfigFile::locate(sys::Path& p, const char* argv0, void* mainAddr, const char* filename)
{
    // temporary configuration

    // try the current working dir
    p = sys::Path::GetCurrentDirectory();
    p.appendComponent(filename);
    if (p.exists())
        return true;

    // user configuration

    // try ~/.ldc
    p = sys::Path::GetUserHomeDirectory();
    p.appendComponent(".ldc");
    p.appendComponent(filename);
    if (p.exists())
        return true;

#if _WIN32
    // try home dir
    p = sys::Path::GetUserHomeDirectory();
    p.appendComponent(filename);
    if (p.exists())
        return true;
#endif

    // system configuration

#if _WIN32
    // try the install-prefix
    p = sys::Path(LDC_INSTALL_PREFIX);
    p.appendComponent(filename);
    if (p.exists())
        return true;
#else
    // try the install-prefix/etc
    p = sys::Path(LDC_INSTALL_PREFIX);
    p.appendComponent("etc");
    p.appendComponent(filename);
    if (p.exists())
        return true;

    // try the install-prefix/etc/ldc
    p = sys::Path(LDC_INSTALL_PREFIX);
    p.appendComponent("etc");
    p.appendComponent("ldc");
    p.appendComponent(filename);
    if (p.exists())
        return true;

    // try /etc (absolute path)
    p = sys::Path("/etc");
    p.appendComponent(filename);
    if (p.exists())
        return true;

    // try /etc/ldc (absolute path)
    p = sys::Path("/etc/ldc");
    p.appendComponent(filename);
    if (p.exists())
        return true;
#endif

    // try next to the executable
    p = sys::Path::GetMainExecutable(argv0, mainAddr);
    p.eraseComponent();
    p.appendComponent(filename);
    if (p.exists())
        return true;
        
    return false;
}

bool ConfigFile::read(const char* argv0, void* mainAddr, const char* filename)
{
    sys::Path p;
    if (!locate(p, argv0, mainAddr, filename))
    {        
        // failed to find cfg, users still have the DFLAGS environment var
        std::cerr << "Error failed to locate the configuration file: " << filename << std::endl;
        return false;
    }

    // save config file path for -v output
    pathstr = p.toString();

    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%%";

            std::string binpath = sys::Path::GetMainExecutable(argv0, mainAddr).getDirname();

            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;
}