view gen/cl_helpers.cpp @ 1317:4099548c80e0

Allocate objects on the stack if they (a) don't have a destructor, and (b) don't override the delete operator (on top of the regular conditions for stack allocation that also apply to arrays, structs, etc.). The "no destructor" clause is not strictly necessary, but calling them at the right time would be tricky to say the least; it would involve, among other things, "manually" inserting a try-finally block around anything that might throw exceptions not caught in the current function. Note: objects with custom new operators are automatically ignored because they don't use the regular allocation runtime call, so there's no need to pay special attention to them.
author Frits van Bommel <fvbommel wxs.nl>
date Sat, 09 May 2009 00:50:15 +0200
parents b30fe7e1dbb9
children 40bd4a0d4870
line wrap: on
line source

#include "gen/cl_helpers.h"

#include "root.h"
#include "rmem.h"

#include <cctype>       // isupper, tolower
#include <algorithm>
#include <utility>
#include <stdarg.h>

namespace opts {

// Helper function
static char toLower(char c) {
    if (isupper(c))
        return tolower(c);
    return c;
}

bool FlagParser::parse(cl::Option &O, const char *ArgName, const std::string &Arg, bool &Val) {
    // Make a std::string out of it to make comparisons easier
    // (and avoid repeated conversion)
    std::string argname = ArgName;
    
    typedef std::vector<std::pair<std::string, bool> >::iterator It;
    for (It I = switches.begin(), E = switches.end(); I != E; ++I) {
        std::string name = I->first;
        if (name == argname
                || (name.length() < argname.length()
                    && argname.substr(0, name.length()) == name
                    && argname[name.length()] == '=')) {
            
            if (!cl::parser<bool>::parse(O, ArgName, Arg, Val)) {
                Val = (Val == I->second);
                return false;
            }
            // Invalid option value
            break;
        }
    }
    return true;
}

void FlagParser::getExtraOptionNames(std::vector<const char*> &Names) {
    typedef std::vector<std::pair<std::string, bool> >::iterator It;
    for (It I = switches.begin() + 1, E = switches.end(); I != E; ++I) {
        Names.push_back(I->first.c_str());
    }
}


MultiSetter::MultiSetter(bool invert, bool* p, ...) {
    this->invert = invert;
    if (p) {
        locations.push_back(p);
        va_list va;
        va_start(va, p);
        while (p = va_arg(va, bool*)) {
            locations.push_back(p);
        }
    }
}
        
void MultiSetter::operator=(bool val) {
    typedef std::vector<bool*>::iterator It;
    for (It I = locations.begin(), E = locations.end(); I != E; ++I) {
        **I = (val != invert);
    }
}


void ArrayAdapter::push_back(const char* cstr) {
    if (!cstr || !*cstr)
        error("Expected argument to '-%s'", name);
    
    if (!*arrp)
        *arrp = new Array;
    (*arrp)->push(mem.strdup(cstr));
}

} // namespace opts