<commit_before>#include "include/SearchManager.h"

#define LOGGING_LEVEL_1
#include "log.h"

/**
 * @brief Constructs a SearchManager connecting it to the given ResultsPageWidget.
 * @param The ResultsPageWidget.
 */
SearchManager::SearchManager(ResultsPageWidget *resultsPageWidget)
    : mResultsPageWidget(resultsPageWidget)
{
    QObject::connect(resultsPageWidget, SIGNAL(startAlgorithm(Algorithm*)), this, SLOT(startSearch(Algorithm*)));
}

/**
 * @brief Runs the given Algorithm and sends the results to the ResultsPageWidget.
 * @param The Algorithm.
 */
void SearchManager::startSearch(Algorithm *algo)
{
    mThread = new AlgorithmThread(algo);
    connect(mThread, SIGNAL(resultsReady()), this, SLOT(submitResults()));
    connect(mThread, SIGNAL(finished()), this, SLOT(deleteLater()));
    mThread->start();
}

/**
 * @brief Terminates the search.
 */
void SearchManager::terminateSearch()
{
}

void SearchManager::submitResults()
{
    QList<DataPacket*> results = mThread->getResults();
    if(results.size() > 0){
        SearchResult* searchResult = dynamic_cast<SearchResult*>(results.at(0));
        if(searchResult){
            mResultsPageWidget->setResults(std::move(*searchResult));
        } else {
            LOG_ERR("could not handle packet of type other than SearchResult in SearchManager");
        }
    } else {
        LOG("algorithm did not return any results");
    }
    qDeleteAll(results);
}

void SearchManager::updateProgress(float progress, const QString& message)
{
    Q_UNUSED(progress);
    Q_UNUSED(message);
}

<commit_msg>Fixed segfault.<commit_after>#include "include/SearchManager.h"

#define LOGGING_LEVEL_1
#include "log.h"

/**
 * @brief Constructs a SearchManager connecting it to the given ResultsPageWidget.
 * @param The ResultsPageWidget.
 */
SearchManager::SearchManager(ResultsPageWidget *resultsPageWidget)
    : mResultsPageWidget(resultsPageWidget)
{
    QObject::connect(resultsPageWidget, SIGNAL(startAlgorithm(Algorithm*)), this, SLOT(startSearch(Algorithm*)));
}

/**
 * @brief Runs the given Algorithm and sends the results to the ResultsPageWidget.
 * @param The Algorithm.
 */
void SearchManager::startSearch(Algorithm *algo)
{
    mThread = new AlgorithmThread(algo);
    connect(mThread, SIGNAL(resultsReady()), this, SLOT(submitResults()));
    connect(mThread, SIGNAL(finished()), mThread, SLOT(deleteLater()));
    mThread->start();
}

/**
 * @brief Terminates the search.
 */
void SearchManager::terminateSearch()
{
}

void SearchManager::submitResults()
{
    QList<DataPacket*> results = mThread->getResults();
    if(results.size() > 0){
        SearchResult* searchResult = dynamic_cast<SearchResult*>(results.at(0));
        if(searchResult){
            mResultsPageWidget->setResults(std::move(*searchResult));
        } else {
            LOG_ERR("could not handle packet of type other than SearchResult in SearchManager");
        }
    } else {
        LOG("algorithm did not return any results");
    }
    qDeleteAll(results);
}

void SearchManager::updateProgress(float progress, const QString& message)
{
    Q_UNUSED(progress);
    Q_UNUSED(message);
}

<|endoftext|>


<commit_before>#include "filters.h"
#include "scene/styleContext.h"
#include "data/tileData.h"
#include "platform.h"

#include <cmath>

namespace Tangram {

void countTypes(const std::vector<Filter>& filters, int& global, int& function, int& property) {

}

void Filter::print(int _indent) const {

    switch (data.get_type_index()) {

    case Data::type<OperatorAny>::value: {
        logMsg("%*s any\n", _indent, "");
        for (const auto& filt : data.get<OperatorAny>().operands) {
            filt.print(_indent + 2);
        }
        break;
    }
    case Data::type<OperatorAll>::value: {
        logMsg("%*s all\n", _indent, "");
        for (const auto& filt : data.get<OperatorAll>().operands) {
            filt.print(_indent + 2);
        }
        break;
    }
    case Data::type<OperatorNone>::value: {
        logMsg("%*s none\n", _indent, "");
        for (const auto& filt : data.get<OperatorNone>().operands) {
            filt.print(_indent + 2);
        }
        break;
    }
    case Data::type<Existence>::value: {
        auto& f = data.get<Existence>();
        logMsg("%*s existence - key:%s\n", _indent, "", f.key.c_str());
        break;
    }
    case Data::type<EqualitySet>::value: {
        auto& f = data.get<EqualitySet>();
        if (f.values[0].is<std::string>()) {
            logMsg("%*s equality set - global:%d key:%s val:%s\n", _indent, "",
                   f.global != FilterGlobal::undefined,
                   f.key.c_str(),
                   f.values[0].get<std::string>().c_str());
        }
        if (f.values[0].is<double>()) {
            logMsg("%*s equality - global:%d key:%s val:%f\n", _indent, "",
                   f.global != FilterGlobal::undefined,
                   f.key.c_str(),
                   f.values[0].get<double>());
        }
        break;
    }
    case Data::type<Equality>::value: {
        auto& f = data.get<Equality>();
        if (f.value.is<std::string>()) {
            logMsg("%*s equality - global:%d key:%s val:%s\n", _indent, "",
                   f.global != FilterGlobal::undefined,
                   f.key.c_str(),
                   f.value.get<std::string>().c_str());
        }
        if (f.value.is<double>()) {
            logMsg("%*s equality - global:%d key:%s val:%f\n", _indent, "",
                   f.global != FilterGlobal::undefined,
                   f.key.c_str(),
                   f.value.get<double>());
        }
        break;
    }
    case Data::type<Range>::value: {
        auto& f = data.get<Range>();
        logMsg("%*s range - global:%d key:%s min:%f max:%f\n", _indent, "",
               f.global != FilterGlobal::undefined,
               f.key.c_str(), f.min, f.max);
        return;
    }
    case Data::type<Function>::value: {
        logMsg("%*s function\n", _indent, "");
        break;
    }
    default:
        break;
    }

}

int Filter::filterCost() const {
    // Add some extra penalty for set vs simple filters
    int sum = 100;

    switch (data.get_type_index()) {
    case Data::type<OperatorAny>::value:
        for (auto& f : operands()) { sum += f.filterCost(); }
        return sum;

    case Data::type<OperatorAll>::value:
        for (auto& f : operands()) { sum += f.filterCost(); }
        return sum;

    case Data::type<OperatorNone>::value:
        for (auto& f : operands()) { sum += f.filterCost(); }
        return sum;

    case Data::type<Existence>::value:
        // Equality and Range are more specific for increasing
        // the chance to fail early check them before Existence
        return 20;

    case Data::type<EqualitySet>::value:
        return data.get<EqualitySet>().global == FilterGlobal::undefined ? 10 : 1;

    case Data::type<Equality>::value:
        return data.get<Equality>().global == FilterGlobal::undefined ? 10 : 1;

    case Data::type<Filter::Range>::value:
        return data.get<Range>().global == FilterGlobal::undefined ? 10 : 1;

    case Data::type<Function>::value:
        // Most expensive filter should be checked last
        return 1000;
    }
    assert(false);
    return 0;
}

const std::string& Filter::key() const {
    static const std::string empty = "";

    switch (data.get_type_index()) {

    case Data::type<Existence>::value:
        return data.get<Existence>().key;

    case Data::type<EqualitySet>::value:
        return data.get<EqualitySet>().key;

    case Data::type<Equality>::value:
        return data.get<Equality>().key;

    case Data::type<Filter::Range>::value:
        return data.get<Range>().key;

    default:
        break;
    }
    return empty;
}

const std::vector<Filter>& Filter::operands() const {
    static const std::vector<Filter> empty;

    switch (data.get_type_index()) {
    case Data::type<OperatorAny>::value:
        return data.get<OperatorAny>().operands;

    case Data::type<OperatorAll>::value:
        return data.get<OperatorAll>().operands;

    case Data::type<OperatorNone>::value:
        return data.get<OperatorNone>().operands;

    default:
        break;
    }
    return empty;
}

const bool Filter::isOperator() const {

    switch (data.get_type_index()) {
    case Data::type<OperatorAny>::value:
        return true;

    case Data::type<OperatorAll>::value:
        return true;

    case Data::type<OperatorNone>::value:
        return true;

    default:
        break;
    }
    return false;
}

int compareSetFilter(const Filter& a, const Filter& b) {
    auto& oa = a.operands();
    auto& ob = b.operands();

    if (oa.size() != ob.size()) { return oa.size() < ob.size(); }

    if (oa[0].data.is<Filter::Range>() &&
        ob[0].data.is<Filter::Range>() &&
        oa[0].key() == ob[0].key()) {
        // take the one with more restrictive range
        auto ra = oa[0].data.get<Filter::Range>();
        auto rb = ob[0].data.get<Filter::Range>();

        if (std::isinf(ra.max) && std::isinf(rb.max)) {
            return rb.min - ra.min;
        }
    }

    return 0;
}

std::vector<Filter> Filter::sort(const std::vector<Filter>& _filters) {
    std::vector<Filter> filters = _filters;
    std::sort(filters.begin(), filters.end(),
              [](auto& a, auto& b) {

                  // Sort simple filters by eval cost
                  int ma = a.filterCost();
                  int mb = b.filterCost();

                  if (!a.isOperator() && !b.isOperator()) {
                      int diff = ma - mb;
                      if (diff != 0) {
                          return diff < 0;
                      }

                      // just for consistent ordering
                      // (and using > to prefer $zoom over $geom)
                      return a.key() > b.key();
                  }

                  // When one is a simple Filter and the other is a operaor
                  // or both are operators prefer the one with the cheaper
                  // filter(s).
                  if (ma != mb) {
                      return ma < mb;
                  }

                  return compareSetFilter(a, b) < 0;
              });

    return filters;
}

#if 0

bool Filter::eval(const Feature& feat, StyleContext& ctx) const {

    switch (data.get_type_index()) {

    case Data::type<OperatorAny>::value: {
        for (const auto& filt : data.get<OperatorAny>().operands) {
            if (filt.eval(feat, ctx)) { return true; }
        }
        return false;
    }
    case Data::type<OperatorAll>::value: {
        for (const auto& filt : data.get<OperatorAll>().operands) {
            if (!filt.eval(feat, ctx)) { return false; }
        }
        return true;
    }
    case Data::type<OperatorNone>::value: {
        for (const auto& filt : data.get<OperatorNone>().operands) {
            if (filt.eval(feat, ctx)) { return false; }
        }
        return true;
    }
    case Data::type<Existence>::value: {
        auto& f = data.get<Existence>();
        return f.exists == feat.props.contains(f.key);
    }
    case Data::type<Equality>::value: {
        auto& f = data.get<Equality>();

        if (f.global == FilterGlobal::undefined) {
            auto& value = feat.props.get(f.key);
            for (const auto& v : f.values) {
                if (v == value) {
                    return true;
                } else if (value.is<double>() && v.is<double>()) {
                    auto& a = v.get<double>();
                    auto& b = value.get<double>();
                    if (std::fabs(a - b) <= std::numeric_limits<double>::epsilon()) { return true; }
                }
            }
        } else {
            auto& global = ctx.getGlobal(f.global);
            if (!global.is<none_type>()) {
                for (const auto& v : f.values) {
                    if (v == global) { return true; }
                }
                return false;
            }
        }

        return false;
    }
    case Data::type<Range>::value: {
        auto& f = data.get<Range>();

        if (f.global == FilterGlobal::undefined) {
            auto& value = feat.props.get(f.key);
            if (value.is<double>()) {
                double num =  value.get<double>();
                return num >= f.min && num < f.max;
            }
        } else {
            auto& global = ctx.getGlobal(f.global);
            if (!global.is<none_type>()) {
                // only check range for numbers
                if (global.is<double>()) {
                    double num = global.get<double>();
                    return num >= f.min && num < f.max;
                }
            }
        }
        return false;
    }
    case Data::type<Function>::value: {
        auto& f = data.get<Function>();
        return ctx.evalFilter(f.id);
    }
    default:
        return true;
    }

    // Cannot be reached
    //assert(false);
    return false;
}

#else

struct string_matcher {
    using result_type = bool;
    const std::string& str;

    template <typename T>
    bool operator()(T v) const { return false; }
    bool operator()(const std::string& v) const {
        return str == v;
    }
};

struct number_matcher {
    using result_type = bool;
    double num;

    template <typename T>
    bool operator()(T v) const { return false; }
    bool operator()(const double& v) const {
        if (num == v) { return true; }
        return std::fabs(num - v) <= std::numeric_limits<double>::epsilon();
    }
};

struct match_equal_set {
    using result_type = bool;
    const std::vector<Value>& values;

    template <typename T>
    bool operator()(T) const { return false; }

    bool operator()(const double& num) const {
        number_matcher m{num};
        for (const auto& v : values) {
            if (Value::visit(v, m)) {
                return true;
            }
        }
        return false;
    }
    bool operator()(const std::string& str) const {
        string_matcher m{str};

        for (const auto& v : values) {
            if (Value::visit(v, m)) {
                return true;
            }
        }
        return false;
    }
};

struct match_equal {
    using result_type = bool;
    const Value& value;

    template <typename T>
    bool operator()(T) const { return false; }

    bool operator()(const double& num) const {
        return Value::visit(value, number_matcher{num});
    }
    bool operator()(const std::string& str) const {
        return Value::visit(value, string_matcher{str});
    }
};

struct match_range {
    const Filter::Range& f;

    bool operator() (const double& num) const {
        return num >= f.min && num < f.max;
    }
    bool operator() (const std::string&) const { return false; }
    bool operator() (const none_type&) const { return false; }
};

struct matcher {
    using result_type = bool;

    matcher(const Feature& feat, StyleContext& ctx) :
        props(feat.props), ctx(ctx) {}

    const Properties& props;
    StyleContext& ctx;

    bool eval(const Filter::Data& data) const {
        return Filter::Data::visit(data, *this);
    }

    bool operator() (const Filter::OperatorAny& f) const {
        for (const auto& filt : f.operands) {
            if (eval(filt.data)) { return true; }
        }
        return false;
    }
    bool operator() (const Filter::OperatorAll& f) const {
        for (const auto& filt : f.operands) {
            if (!eval(filt.data)) { return false; }
        }
        return true;
    }
    bool operator() (const Filter::OperatorNone& f) const {
        for (const auto& filt : f.operands) {
            if (eval(filt.data)) { return false; }
        }
        return true;
    }
    bool operator() (const Filter::Existence& f) const {
        return f.exists == props.contains(f.key);
    }
    bool operator() (const Filter::EqualitySet& f) const {
        auto& value = (f.global == FilterGlobal::undefined)
            ? props.get(f.key)
            : ctx.getGlobal(f.global);

        return Value::visit(value, match_equal_set{f.values});
    }
    bool operator() (const Filter::Equality& f) const {
        auto& value = (f.global == FilterGlobal::undefined)
            ? props.get(f.key)
            : ctx.getGlobal(f.global);

        return Value::visit(value, match_equal{f.value});
    }
    bool operator() (const Filter::Range& f) const {
        auto& value = (f.global == FilterGlobal::undefined)
            ? props.get(f.key)
            : ctx.getGlobal(f.global);

        return Value::visit(value, match_range{f});
    }
    bool operator() (const Filter::Function& f) const {
        return ctx.evalFilter(f.id);
    }
    bool operator() (const none_type& f) const {
        return true;
    }
};

bool Filter::eval(const Feature& feat, StyleContext& ctx) const {
    return Data::visit(data, matcher(feat, ctx));
}

#endif

}
<commit_msg>cleanup<commit_after>#include "filters.h"
#include "scene/styleContext.h"
#include "data/tileData.h"
#include "platform.h"

#include <cmath>

namespace Tangram {

void Filter::print(int _indent) const {

    switch (data.get_type_index()) {

    case Data::type<OperatorAny>::value: {
        logMsg("%*s any\n", _indent, "");
        for (const auto& filt : data.get<OperatorAny>().operands) {
            filt.print(_indent + 2);
        }
        break;
    }
    case Data::type<OperatorAll>::value: {
        logMsg("%*s all\n", _indent, "");
        for (const auto& filt : data.get<OperatorAll>().operands) {
            filt.print(_indent + 2);
        }
        break;
    }
    case Data::type<OperatorNone>::value: {
        logMsg("%*s none\n", _indent, "");
        for (const auto& filt : data.get<OperatorNone>().operands) {
            filt.print(_indent + 2);
        }
        break;
    }
    case Data::type<Existence>::value: {
        auto& f = data.get<Existence>();
        logMsg("%*s existence - key:%s\n", _indent, "", f.key.c_str());
        break;
    }
    case Data::type<EqualitySet>::value: {
        auto& f = data.get<EqualitySet>();
        if (f.values[0].is<std::string>()) {
            logMsg("%*s equality set - global:%d key:%s val:%s\n", _indent, "",
                   f.global != FilterGlobal::undefined,
                   f.key.c_str(),
                   f.values[0].get<std::string>().c_str());
        }
        if (f.values[0].is<double>()) {
            logMsg("%*s equality - global:%d key:%s val:%f\n", _indent, "",
                   f.global != FilterGlobal::undefined,
                   f.key.c_str(),
                   f.values[0].get<double>());
        }
        break;
    }
    case Data::type<Equality>::value: {
        auto& f = data.get<Equality>();
        if (f.value.is<std::string>()) {
            logMsg("%*s equality - global:%d key:%s val:%s\n", _indent, "",
                   f.global != FilterGlobal::undefined,
                   f.key.c_str(),
                   f.value.get<std::string>().c_str());
        }
        if (f.value.is<double>()) {
            logMsg("%*s equality - global:%d key:%s val:%f\n", _indent, "",
                   f.global != FilterGlobal::undefined,
                   f.key.c_str(),
                   f.value.get<double>());
        }
        break;
    }
    case Data::type<Range>::value: {
        auto& f = data.get<Range>();
        logMsg("%*s range - global:%d key:%s min:%f max:%f\n", _indent, "",
               f.global != FilterGlobal::undefined,
               f.key.c_str(), f.min, f.max);
        return;
    }
    case Data::type<Function>::value: {
        logMsg("%*s function\n", _indent, "");
        break;
    }
    default:
        break;
    }

}

int Filter::filterCost() const {
    // Add some extra penalty for set vs simple filters
    int sum = 100;

    switch (data.get_type_index()) {
    case Data::type<OperatorAny>::value:
        for (auto& f : operands()) { sum += f.filterCost(); }
        return sum;

    case Data::type<OperatorAll>::value:
        for (auto& f : operands()) { sum += f.filterCost(); }
        return sum;

    case Data::type<OperatorNone>::value:
        for (auto& f : operands()) { sum += f.filterCost(); }
        return sum;

    case Data::type<Existence>::value:
        // Equality and Range are more specific for increasing
        // the chance to fail early check them before Existence
        return 20;

    case Data::type<EqualitySet>::value:
        return data.get<EqualitySet>().global == FilterGlobal::undefined ? 10 : 1;

    case Data::type<Equality>::value:
        return data.get<Equality>().global == FilterGlobal::undefined ? 10 : 1;

    case Data::type<Filter::Range>::value:
        return data.get<Range>().global == FilterGlobal::undefined ? 10 : 1;

    case Data::type<Function>::value:
        // Most expensive filter should be checked last
        return 1000;
    }
    assert(false);
    return 0;
}

const std::string& Filter::key() const {
    static const std::string empty = "";

    switch (data.get_type_index()) {

    case Data::type<Existence>::value:
        return data.get<Existence>().key;

    case Data::type<EqualitySet>::value:
        return data.get<EqualitySet>().key;

    case Data::type<Equality>::value:
        return data.get<Equality>().key;

    case Data::type<Filter::Range>::value:
        return data.get<Range>().key;

    default:
        break;
    }
    return empty;
}

const std::vector<Filter>& Filter::operands() const {
    static const std::vector<Filter> empty;

    switch (data.get_type_index()) {
    case Data::type<OperatorAny>::value:
        return data.get<OperatorAny>().operands;

    case Data::type<OperatorAll>::value:
        return data.get<OperatorAll>().operands;

    case Data::type<OperatorNone>::value:
        return data.get<OperatorNone>().operands;

    default:
        break;
    }
    return empty;
}

const bool Filter::isOperator() const {

    switch (data.get_type_index()) {
    case Data::type<OperatorAny>::value:
        return true;

    case Data::type<OperatorAll>::value:
        return true;

    case Data::type<OperatorNone>::value:
        return true;

    default:
        break;
    }
    return false;
}

int compareSetFilter(const Filter& a, const Filter& b) {
    auto& oa = a.operands();
    auto& ob = b.operands();

    if (oa.size() != ob.size()) { return oa.size() < ob.size(); }

    if (oa[0].data.is<Filter::Range>() &&
        ob[0].data.is<Filter::Range>() &&
        oa[0].key() == ob[0].key()) {
        // take the one with more restrictive range
        auto ra = oa[0].data.get<Filter::Range>();
        auto rb = ob[0].data.get<Filter::Range>();

        if (std::isinf(ra.max) && std::isinf(rb.max)) {
            return rb.min - ra.min;
        }
    }

    return 0;
}

std::vector<Filter> Filter::sort(const std::vector<Filter>& _filters) {
    std::vector<Filter> filters = _filters;
    std::sort(filters.begin(), filters.end(),
              [](auto& a, auto& b) {

                  // Sort simple filters by eval cost
                  int ma = a.filterCost();
                  int mb = b.filterCost();

                  if (!a.isOperator() && !b.isOperator()) {
                      int diff = ma - mb;
                      if (diff != 0) {
                          return diff < 0;
                      }

                      // just for consistent ordering
                      // (and using > to prefer $zoom over $geom)
                      return a.key() > b.key();
                  }

                  // When one is a simple Filter and the other is a operaor
                  // or both are operators prefer the one with the cheaper
                  // filter(s).
                  if (ma != mb) {
                      return ma < mb;
                  }

                  return compareSetFilter(a, b) < 0;
              });

    return filters;
}

struct string_matcher {
    using result_type = bool;
    const std::string& str;

    template <typename T>
    bool operator()(T v) const { return false; }
    bool operator()(const std::string& v) const {
        return str == v;
    }
};

struct number_matcher {
    using result_type = bool;
    double num;

    template <typename T>
    bool operator()(T v) const { return false; }
    bool operator()(const double& v) const {
        if (num == v) { return true; }
        return std::fabs(num - v) <= std::numeric_limits<double>::epsilon();
    }
};

struct match_equal_set {
    using result_type = bool;
    const std::vector<Value>& values;

    template <typename T>
    bool operator()(T) const { return false; }

    bool operator()(const double& num) const {
        number_matcher m{num};
        for (const auto& v : values) {
            if (Value::visit(v, m)) {
                return true;
            }
        }
        return false;
    }
    bool operator()(const std::string& str) const {
        string_matcher m{str};

        for (const auto& v : values) {
            if (Value::visit(v, m)) {
                return true;
            }
        }
        return false;
    }
};

struct match_equal {
    using result_type = bool;
    const Value& value;

    template <typename T>
    bool operator()(T) const { return false; }

    bool operator()(const double& num) const {
        return Value::visit(value, number_matcher{num});
    }
    bool operator()(const std::string& str) const {
        return Value::visit(value, string_matcher{str});
    }
};

struct match_range {
    const Filter::Range& f;

    bool operator() (const double& num) const {
        return num >= f.min && num < f.max;
    }
    bool operator() (const std::string&) const { return false; }
    bool operator() (const none_type&) const { return false; }
};

struct matcher {
    using result_type = bool;

    matcher(const Feature& feat, StyleContext& ctx) :
        props(feat.props), ctx(ctx) {}

    const Properties& props;
    StyleContext& ctx;

    bool eval(const Filter::Data& data) const {
        return Filter::Data::visit(data, *this);
    }

    bool operator() (const Filter::OperatorAny& f) const {
        for (const auto& filt : f.operands) {
            if (eval(filt.data)) { return true; }
        }
        return false;
    }
    bool operator() (const Filter::OperatorAll& f) const {
        for (const auto& filt : f.operands) {
            if (!eval(filt.data)) { return false; }
        }
        return true;
    }
    bool operator() (const Filter::OperatorNone& f) const {
        for (const auto& filt : f.operands) {
            if (eval(filt.data)) { return false; }
        }
        return true;
    }
    bool operator() (const Filter::Existence& f) const {
        return f.exists == props.contains(f.key);
    }
    bool operator() (const Filter::EqualitySet& f) const {
        auto& value = (f.global == FilterGlobal::undefined)
            ? props.get(f.key)
            : ctx.getGlobal(f.global);

        return Value::visit(value, match_equal_set{f.values});
    }
    bool operator() (const Filter::Equality& f) const {
        auto& value = (f.global == FilterGlobal::undefined)
            ? props.get(f.key)
            : ctx.getGlobal(f.global);

        return Value::visit(value, match_equal{f.value});
    }
    bool operator() (const Filter::Range& f) const {
        auto& value = (f.global == FilterGlobal::undefined)
            ? props.get(f.key)
            : ctx.getGlobal(f.global);

        return Value::visit(value, match_range{f});
    }
    bool operator() (const Filter::Function& f) const {
        return ctx.evalFilter(f.id);
    }
    bool operator() (const none_type& f) const {
        return true;
    }
};

bool Filter::eval(const Feature& feat, StyleContext& ctx) const {
    return Data::visit(data, matcher(feat, ctx));
}

}
<|endoftext|>


<commit_before>/*********************************************************************
 *
 * Copyright 2011 Intel Corporation
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 *********************************************************************/

#include <iostream>

#include "os_string.hpp"
#include "trace_tools.hpp"

namespace trace {

os::String
findFile(const char *relPath,
         const char *absPath,
         bool verbose)
{
    os::String complete;

    /* First look in the same directory from which this process is
     * running, (to support developers running a compiled program that
     * has not been installed. */
    os::String process_dir = os::getProcessName();
    process_dir.trimFilename();

    complete = process_dir;
    complete.join(relPath);

    if (complete.exists())
        return complete;

    /* Second, look in the directory for installed wrappers. */
    complete = absPath;
    if (complete.exists())
        return complete;

    if (verbose) {
        std::cerr << "error: cannot find " << relPath << " or " << absPath << "\n";
    }

    return "";
}

#define SCRIPTS_SUBDIR "lib/apitrace/scripts"

os::String
findScript(const char *name)
{
    os::String path;

#if defined(APITRACE_SOURCE_DIR)
    // Try the absolute source  path -- useful for development or quick
    // experiment.  Relative paths don't quite work here due to out of source
    // trees.
    path = APITRACE_SOURCE_DIR "/scripts";
    path.join(name);
    if (path.exists()) {
        return path;
    }
#endif

#if defined(_WIN32)
    // Windows has no standard installation path, so find it relatively to the
    // process name, which is assumed to be in a bin subdirectory.
    path = os::getProcessName();
    path.trimFilename();
    path.join("..\\lib\\apitrace\\scripts");
    path.join(name);
    if (path.exists()) {
        return path;
    }
#else
    // Assume a predefined installation path on Unices
    path = APITRACE_INSTALL_PREFIX "/lib/apitrace/scripts";
    path.join(name);
    if (path.exists()) {
        return path;
    }
#endif

    std::cerr << "error: cannot find " << name << " script\n";

    return "";
}

} /* namespace trace */
<commit_msg>Remove dead source line.<commit_after>/*********************************************************************
 *
 * Copyright 2011 Intel Corporation
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 *********************************************************************/

#include <iostream>

#include "os_string.hpp"
#include "trace_tools.hpp"

namespace trace {

os::String
findFile(const char *relPath,
         const char *absPath,
         bool verbose)
{
    os::String complete;

    /* First look in the same directory from which this process is
     * running, (to support developers running a compiled program that
     * has not been installed. */
    os::String process_dir = os::getProcessName();
    process_dir.trimFilename();

    complete = process_dir;
    complete.join(relPath);

    if (complete.exists())
        return complete;

    /* Second, look in the directory for installed wrappers. */
    complete = absPath;
    if (complete.exists())
        return complete;

    if (verbose) {
        std::cerr << "error: cannot find " << relPath << " or " << absPath << "\n";
    }

    return "";
}

os::String
findScript(const char *name)
{
    os::String path;

#if defined(APITRACE_SOURCE_DIR)
    // Try the absolute source  path -- useful for development or quick
    // experiment.  Relative paths don't quite work here due to out of source
    // trees.
    path = APITRACE_SOURCE_DIR "/scripts";
    path.join(name);
    if (path.exists()) {
        return path;
    }
#endif

#if defined(_WIN32)
    // Windows has no standard installation path, so find it relatively to the
    // process name, which is assumed to be in a bin subdirectory.
    path = os::getProcessName();
    path.trimFilename();
    path.join("..\\lib\\apitrace\\scripts");
    path.join(name);
    if (path.exists()) {
        return path;
    }
#else
    // Assume a predefined installation path on Unices
    path = APITRACE_INSTALL_PREFIX "/lib/apitrace/scripts";
    path.join(name);
    if (path.exists()) {
        return path;
    }
#endif

    std::cerr << "error: cannot find " << name << " script\n";

    return "";
}

} /* namespace trace */
<|endoftext|>


<commit_before>// @(#)root/utils:$Id$
// Author: Fons Rademakers   05/12/2003

/*************************************************************************
 * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

// This program generates a map between class name and shared library.
// Its output is in TEnv format.
// Usage: rlibmap [-f] [-o <mapfile>] -l <sofile> -d <depsofiles>
//                 -c <linkdeffiles>
// -f: output full library path name (not needed when ROOT library
//     search path is used)
// -o: write output to specified file, otherwise to stdout
// -r: replace existing entries in the specified file
// -l: library containing the classes in the specified linkdef files
// -d: libraries on which the -l library depends
// -c: linkdef files containing the list of classes defined in the -l library

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string>
#include <string.h>
#include <vector>
#ifndef WIN32
#   include <unistd.h>
#else
#   define ssize_t int
#   include <io.h>
#   include <sys/types.h>
#endif

#ifdef __APPLE__
#include <AvailabilityMacros.h>
#endif
#if (defined(__FreeBSD__) && (__FreeBSD__ < 4)) || defined(__OpenBSD__) || \
    (defined(__APPLE__) && (!defined(MAC_OS_X_VERSION_10_3) || \
     (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3)))
#include <sys/file.h>
#define lockf(fd, op, sz)   flock((fd), (op))
#ifndef F_LOCK
#define F_LOCK             (LOCK_EX | LOCK_NB)
#endif
#ifndef F_ULOCK
#define F_ULOCK             LOCK_UN
#endif
#endif

#if defined(__CYGWIN__) && defined(__GNUC__)
#define F_LOCK F_WRLCK
#define F_ULOCK F_UNLCK
static int fcntl_lockf(int fd, int op, off_t off)
{
   flock fl;
   fl.l_whence = SEEK_SET;
   fl.l_start  = off;
   fl.l_len    = 0;       // whole file
   fl.l_pid    = getpid();
   fl.l_type   = op;
   return fcntl(fd, F_SETLK, &fl);
}
#define lockf fcntl_lockf
#endif

const char *usage = "Usage: %s [-f] [<-r|-o> <mapfile>] -l <sofile> -d <depsofiles> -c <linkdeffiles>\n";

namespace std {}
using namespace std;

#ifdef WIN32
#include <windows.h>
#include <errno.h>

#define ftruncate(fd, size)  win32_ftruncate(fd, size)

//______________________________________________________________________________
int win32_ftruncate(int fd, ssize_t size)
{
   HANDLE hfile;
   int curpos;

   if (fd < 0) return -1;

   hfile = (HANDLE) _get_osfhandle(fd);
   curpos = ::SetFilePointer(hfile, 0, 0, FILE_CURRENT);
   if (curpos == 0xFFFFFFFF ||
       ::SetFilePointer(hfile, size, 0, FILE_BEGIN) == 0xFFFFFFFF ||
       !::SetEndOfFile(hfile)) {
         int error = ::GetLastError();

      switch (error) {
         case ERROR_INVALID_HANDLE:
            errno = EBADF;
            break;
         default:
            errno = EIO;
         break;
      }
      return -1;
   }
   return 0;
}

#endif // WIN32

//______________________________________________________________________________
char *Compress(const char *str)
{
   // Remove all blanks from the string str. The returned string has to be
   // deleted by the user.

   static const char* composedTypes[] = {"const ", "signed ","unsigned "};
   static unsigned int composedTypesLen[] = {6, 7, 9};

   if (!str) return 0;

   const char *p = str;
   // allocate 20 extra characters in case of eg, vector<vector<T>>
   char *s, *s1 = new char[strlen(str)+20];
   s = s1;

   while (*p) {
      if (*p != ' ') {
         for (unsigned int i = 0; i < sizeof(composedTypes) / sizeof(char*); ++i) {
            if (!strncmp(p, composedTypes[i], composedTypesLen[i])
                && (p == str || !isalnum(p[-1]))) {
               // the last one will be copied after the for loop
               memcpy(s, composedTypes[i], composedTypesLen[i] - 1);
               p += composedTypesLen[i] - 1;
               s += composedTypesLen[i] - 1;
               continue;
            }
         }
         *s++ = *p;
      }
      p++;
   }
   *s = '\0';

   return s1;
}

//______________________________________________________________________________
void UnCompressTemplate(char*& str)
{
   // Replace ">>" by "> >" except for operator>>.
   // str might be changed; the old string gets deleted in here.

   // Even handles cases like "A<B<operator>>()>>::operator >>()".

   char* pos = strstr(str, ">>");
   char* fixed = 0;
   int countgtgt = 0;
   while (pos) {
      // first run: just count, so we can allocate space for fixed
      ++countgtgt;
      pos = strstr(pos+1, ">>");
   }
   if (!countgtgt)
      return;
   pos = strstr(str, ">>");
   while (pos && pos > str) {
      bool isop = false;
      // check that it's not op>>:
      if (pos - str >= 8) {
         char* posop = pos - 1;
         // remove spaces in front of ">>":
         while (posop >= str && *posop == ' ')
            --posop;
         if (!strncmp("operator", posop - 7, 8)) {
            // it is an operator!
            isop = true;
         }
      }
      if (!isop) {
         // not an operator; we need to add a space.
         if (!fixed) {
            fixed = new char[strlen(str) + countgtgt + 1];
            strcpy(fixed, str);
         }
         fixed[pos - str + 1] = ' ';
         strcpy(fixed + (pos - str) + 2, pos + 1);
      }
      pos = strstr(pos + 1, ">>");
   }
   delete [] str;
   str = fixed;
}

//______________________________________________________________________________
int RemoveLib(const string &solib, bool fullpath, FILE *fp)
{
   // Remove entries from the map file for the specified solib.

   fseek(fp, 0, SEEK_SET);

   // get file size
   struct stat sbuf;
   fstat(fileno(fp), &sbuf);
   size_t siz = sbuf.st_size;

   if (!siz) return 0;

   const char *libbase = solib.c_str();
   if (!fullpath) {
      if ((libbase = strrchr(libbase, '/')))
         libbase++;
   }

   // read file and remove lines matching specified libs
   char *fbuf = new char[siz+1];
   char *fptr = fbuf;

   while (fgets(fptr, 1+siz - size_t(fptr-fbuf), fp)) {

      char *line = new char[strlen(fptr)+1];
      strcpy(line, fptr);
      strtok(line, " ");
      char *lib = strtok(0, " \n");
      if (lib && strcmp(lib, libbase)) {
         fptr += strlen(fptr);
         if (*(fptr-1) != '\n') {
            *fptr = '\n';
            fptr++;
         }
      }
      delete [] line;

      // fgets() should return 0 in this case but doesn't
      if ( (siz - size_t(fptr - fbuf)) <= 0)
         break;
   }

   ftruncate(fileno(fp), 0);

   // write remaining lines back
   if (fptr != fbuf) {
      fseek(fp, 0, SEEK_SET);
      fwrite(fbuf, 1, size_t(fptr-fbuf), fp);
   }

   delete [] fbuf;

   fseek(fp, 0, SEEK_END);

   return 0;
}

//______________________________________________________________________________
int LibMap(const string &solib, const vector<string> &solibdeps,
           const vector<string> &linkdefs, bool fullpath, FILE *fp)
{
   // Write libmap. Returns -1 in case of error.

   vector<string> classes;

   vector<string>::const_iterator lk;
   for (lk = linkdefs.begin(); lk != linkdefs.end(); lk++) {
      const char *linkdef = lk->c_str();
      FILE *lfp;
      char pragma[1024];
      if ((lfp = fopen(linkdef, "r"))) {
         while (fgets(pragma, 1024, lfp)) {
            if (strcmp(strtok(pragma, " "), "#pragma")) continue;
            const char* linkOrCreate = strtok(0, " ");
            bool pragmaLink = (!strcmp(linkOrCreate, "link") &&
                               !strcmp(strtok(0, " "), "C++"));
            bool pragmaCreate = (!strcmp(linkOrCreate, "create") &&
                                 !strcmp(strtok(0," "), "TClass"));

            if (pragmaLink || pragmaCreate) {
               const char *type = pragmaLink ? strtok(0, " ") : "class";
               if (!strncmp(type, "option=", 7) || !strncmp(type, "options=", 8)) {
                  if (strstr(type, "nomap"))
                     continue;
                  type = strtok(0, " ");
               }
               //the following statement had to be commented. Currently CINT
               //cannot autoload when executing a typedef (must be fixed!!!)
               //if (!strncmp(type, "class", 5) || !strcmp(type, "typedef")) {
               // handles class, class+protected and class+private
               if (!strncmp(type, "class", 5)) {
                  char *cls = strtok(0, "-!+;");
                  // just in case remove trailing space and tab
                  while (*cls == ' ') cls++;
                  int len = strlen(cls) - 1;
                  while (cls[len] == ' ' || cls[len] == '\t')
                     cls[len--] = '\0';
                  //no space between tmpl arguments allowed
                  cls = Compress(cls);
                  // except for A<B<C> >!
                  UnCompressTemplate(cls);

                  // don't include "vector<string>" and "std::pair<" classes
                  if (!strncmp(cls, "vector<string>", 14) ||
                      !strncmp(cls, "std::pair<", 10))
                     continue;

                  // replace "::" by "@@" since TEnv uses ":" as delimeter
                  char *s = cls;
                  while (*s) {
                     if (*s == ':')
                        *s = '@';
                     else if (*s == ' ')
                        *s = '-';
                     s++;
                  }
                  classes.push_back(cls);
               }
            }
         }
         fclose(lfp);
      } else {
         fprintf(stderr, "cannot open linkdef file %s\n", linkdef);
      }
   }

   const char *libbase = solib.c_str();
   if (!fullpath) {
      if ((libbase = strrchr(libbase, '/')))
         libbase++;
      else
         libbase = solib.c_str();
   }

   vector<string>::const_iterator it;
   for (it = classes.begin(); it != classes.end(); it++) {
      fprintf(fp, "Library.%-35s %s", ((*it)+":").c_str(), libbase);

      if (solibdeps.size() > 0) {
         vector<string>::const_iterator depit;
         for (depit = solibdeps.begin(); depit != solibdeps.end(); depit++) {
            const char *deplib = depit->c_str();
            if (!fullpath) {
               if ((deplib = strrchr(deplib, '/')))
                  deplib++;
               else
                  deplib = depit->c_str();
            }
            fprintf(fp, " %s", deplib);
         }
      }
      fprintf(fp, "\n");
   }

   return 0;
}

//______________________________________________________________________________
int main(int argc, char **argv)
{
   string         solib;
   vector<string> solibdeps;
   vector<string> linkdefs;
   bool fullpath = false;
   bool replace  = false;
   FILE *fp      = stdout;

   if (argc > 1) {
      int ic = 1;
      if (!strcmp(argv[ic], "-?") || !strcmp(argv[ic], "-h")) {
         fprintf(stderr, usage, argv[0]);
         return 1;
      }
      if (!strcmp(argv[ic], "-f")) {
         fullpath = true;
         ic++;
      }
      if (!strcmp(argv[ic], "-o")) {
         ic++;
         fp = fopen(argv[ic], "w");
         if (!fp) {
            fprintf(stderr, "cannot open output file %s\n", argv[ic]);
            return 1;
         }
         ic++;
      }
      if (!strcmp(argv[ic], "-r")) {
         replace = true;
         ic++;
         fp = fopen(argv[ic], "a+");
         if (!fp) {
            fprintf(stderr, "cannot open output file %s\n", argv[ic]);
            return 1;
         }
         ic++;
      }
      if (!strcmp(argv[ic], "-l")) {
         ic++;
         solib = argv[ic];
#ifdef __APPLE__
         string::size_type i = solib.find(".dylib");
         if (i != string::npos)
            solib.replace(i, 6, ".so");
#endif
         ic++;
      }
      if (!strcmp(argv[ic], "-d")) {
         ic++;
         for (int i = ic; i < argc && argv[i][0] != '-'; i++) {
            string dl = argv[i];
#ifdef __APPLE__
            string::size_type j = dl.find(".dylib");
            if (j != string::npos)
               dl.replace(j, 6, ".so");
#endif
            solibdeps.push_back(dl);
            ic++;
         }
      }
      if (!strcmp(argv[ic], "-c")) {
         ic++;
         for (int i = ic; i < argc; i++) {
            linkdefs.push_back(argv[i]);
            ic++;
         }
      }
   } else {
      fprintf(stderr, usage, argv[0]);
      return 1;
   }

   if (replace) {
#if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__FreeBSD__) && \
    !defined(__OpenBSD__)
      // lock file
      if (lockf(fileno(fp), F_LOCK, (off_t)1) == -1) {
         fprintf(stderr, "rlibmap: locking failed, don't use gmake -j\n");
      }
#endif

      // remove entries for solib to be processed
      RemoveLib(solib, fullpath, fp);
   }

   LibMap(solib, solibdeps, linkdefs, fullpath, fp);

   if (replace) {
#if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__FreeBSD__) && \
    !defined(__OpenBSD__)
      // remove lock
      lseek(fileno(fp), 0, SEEK_SET);
      if (lockf(fileno(fp), F_ULOCK, (off_t)1) == -1) {
         //fprintf(stderr, "rlibmap: error unlocking output file\n");
      }
#endif
   }

   if (fp != stdout)
      fclose(fp);

   return 0;
}
<commit_msg>Add #include needed by gcc 3.2<commit_after>// @(#)root/utils:$Id$
// Author: Fons Rademakers   05/12/2003

/*************************************************************************
 * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

// This program generates a map between class name and shared library.
// Its output is in TEnv format.
// Usage: rlibmap [-f] [-o <mapfile>] -l <sofile> -d <depsofiles>
//                 -c <linkdeffiles>
// -f: output full library path name (not needed when ROOT library
//     search path is used)
// -o: write output to specified file, otherwise to stdout
// -r: replace existing entries in the specified file
// -l: library containing the classes in the specified linkdef files
// -d: libraries on which the -l library depends
// -c: linkdef files containing the list of classes defined in the -l library

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <cctype>
#include <string>
#include <string.h>
#include <vector>
#ifndef WIN32
#   include <unistd.h>
#else
#   define ssize_t int
#   include <io.h>
#   include <sys/types.h>
#endif

#ifdef __APPLE__
#include <AvailabilityMacros.h>
#endif
#if (defined(__FreeBSD__) && (__FreeBSD__ < 4)) || defined(__OpenBSD__) || \
    (defined(__APPLE__) && (!defined(MAC_OS_X_VERSION_10_3) || \
     (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3)))
#include <sys/file.h>
#define lockf(fd, op, sz)   flock((fd), (op))
#ifndef F_LOCK
#define F_LOCK             (LOCK_EX | LOCK_NB)
#endif
#ifndef F_ULOCK
#define F_ULOCK             LOCK_UN
#endif
#endif

#if defined(__CYGWIN__) && defined(__GNUC__)
#define F_LOCK F_WRLCK
#define F_ULOCK F_UNLCK
static int fcntl_lockf(int fd, int op, off_t off)
{
   flock fl;
   fl.l_whence = SEEK_SET;
   fl.l_start  = off;
   fl.l_len    = 0;       // whole file
   fl.l_pid    = getpid();
   fl.l_type   = op;
   return fcntl(fd, F_SETLK, &fl);
}
#define lockf fcntl_lockf
#endif

const char *usage = "Usage: %s [-f] [<-r|-o> <mapfile>] -l <sofile> -d <depsofiles> -c <linkdeffiles>\n";

namespace std {}
using namespace std;

#ifdef WIN32
#include <windows.h>
#include <errno.h>

#define ftruncate(fd, size)  win32_ftruncate(fd, size)

//______________________________________________________________________________
int win32_ftruncate(int fd, ssize_t size)
{
   HANDLE hfile;
   int curpos;

   if (fd < 0) return -1;

   hfile = (HANDLE) _get_osfhandle(fd);
   curpos = ::SetFilePointer(hfile, 0, 0, FILE_CURRENT);
   if (curpos == 0xFFFFFFFF ||
       ::SetFilePointer(hfile, size, 0, FILE_BEGIN) == 0xFFFFFFFF ||
       !::SetEndOfFile(hfile)) {
         int error = ::GetLastError();

      switch (error) {
         case ERROR_INVALID_HANDLE:
            errno = EBADF;
            break;
         default:
            errno = EIO;
         break;
      }
      return -1;
   }
   return 0;
}

#endif // WIN32

//______________________________________________________________________________
char *Compress(const char *str)
{
   // Remove all blanks from the string str. The returned string has to be
   // deleted by the user.

   static const char* composedTypes[] = {"const ", "signed ","unsigned "};
   static unsigned int composedTypesLen[] = {6, 7, 9};

   if (!str) return 0;

   const char *p = str;
   // allocate 20 extra characters in case of eg, vector<vector<T>>
   char *s, *s1 = new char[strlen(str)+20];
   s = s1;

   while (*p) {
      if (*p != ' ') {
         for (unsigned int i = 0; i < sizeof(composedTypes) / sizeof(char*); ++i) {
            if (!strncmp(p, composedTypes[i], composedTypesLen[i])
                && (p == str || !isalnum(p[-1]))) {
               // the last one will be copied after the for loop
               memcpy(s, composedTypes[i], composedTypesLen[i] - 1);
               p += composedTypesLen[i] - 1;
               s += composedTypesLen[i] - 1;
               continue;
            }
         }
         *s++ = *p;
      }
      p++;
   }
   *s = '\0';

   return s1;
}

//______________________________________________________________________________
void UnCompressTemplate(char*& str)
{
   // Replace ">>" by "> >" except for operator>>.
   // str might be changed; the old string gets deleted in here.

   // Even handles cases like "A<B<operator>>()>>::operator >>()".

   char* pos = strstr(str, ">>");
   char* fixed = 0;
   int countgtgt = 0;
   while (pos) {
      // first run: just count, so we can allocate space for fixed
      ++countgtgt;
      pos = strstr(pos+1, ">>");
   }
   if (!countgtgt)
      return;
   pos = strstr(str, ">>");
   while (pos && pos > str) {
      bool isop = false;
      // check that it's not op>>:
      if (pos - str >= 8) {
         char* posop = pos - 1;
         // remove spaces in front of ">>":
         while (posop >= str && *posop == ' ')
            --posop;
         if (!strncmp("operator", posop - 7, 8)) {
            // it is an operator!
            isop = true;
         }
      }
      if (!isop) {
         // not an operator; we need to add a space.
         if (!fixed) {
            fixed = new char[strlen(str) + countgtgt + 1];
            strcpy(fixed, str);
         }
         fixed[pos - str + 1] = ' ';
         strcpy(fixed + (pos - str) + 2, pos + 1);
      }
      pos = strstr(pos + 1, ">>");
   }
   delete [] str;
   str = fixed;
}

//______________________________________________________________________________
int RemoveLib(const string &solib, bool fullpath, FILE *fp)
{
   // Remove entries from the map file for the specified solib.

   fseek(fp, 0, SEEK_SET);

   // get file size
   struct stat sbuf;
   fstat(fileno(fp), &sbuf);
   size_t siz = sbuf.st_size;

   if (!siz) return 0;

   const char *libbase = solib.c_str();
   if (!fullpath) {
      if ((libbase = strrchr(libbase, '/')))
         libbase++;
   }

   // read file and remove lines matching specified libs
   char *fbuf = new char[siz+1];
   char *fptr = fbuf;

   while (fgets(fptr, 1+siz - size_t(fptr-fbuf), fp)) {

      char *line = new char[strlen(fptr)+1];
      strcpy(line, fptr);
      strtok(line, " ");
      char *lib = strtok(0, " \n");
      if (lib && strcmp(lib, libbase)) {
         fptr += strlen(fptr);
         if (*(fptr-1) != '\n') {
            *fptr = '\n';
            fptr++;
         }
      }
      delete [] line;

      // fgets() should return 0 in this case but doesn't
      if ( (siz - size_t(fptr - fbuf)) <= 0)
         break;
   }

   ftruncate(fileno(fp), 0);

   // write remaining lines back
   if (fptr != fbuf) {
      fseek(fp, 0, SEEK_SET);
      fwrite(fbuf, 1, size_t(fptr-fbuf), fp);
   }

   delete [] fbuf;

   fseek(fp, 0, SEEK_END);

   return 0;
}

//______________________________________________________________________________
int LibMap(const string &solib, const vector<string> &solibdeps,
           const vector<string> &linkdefs, bool fullpath, FILE *fp)
{
   // Write libmap. Returns -1 in case of error.

   vector<string> classes;

   vector<string>::const_iterator lk;
   for (lk = linkdefs.begin(); lk != linkdefs.end(); lk++) {
      const char *linkdef = lk->c_str();
      FILE *lfp;
      char pragma[1024];
      if ((lfp = fopen(linkdef, "r"))) {
         while (fgets(pragma, 1024, lfp)) {
            if (strcmp(strtok(pragma, " "), "#pragma")) continue;
            const char* linkOrCreate = strtok(0, " ");
            bool pragmaLink = (!strcmp(linkOrCreate, "link") &&
                               !strcmp(strtok(0, " "), "C++"));
            bool pragmaCreate = (!strcmp(linkOrCreate, "create") &&
                                 !strcmp(strtok(0," "), "TClass"));

            if (pragmaLink || pragmaCreate) {
               const char *type = pragmaLink ? strtok(0, " ") : "class";
               if (!strncmp(type, "option=", 7) || !strncmp(type, "options=", 8)) {
                  if (strstr(type, "nomap"))
                     continue;
                  type = strtok(0, " ");
               }
               //the following statement had to be commented. Currently CINT
               //cannot autoload when executing a typedef (must be fixed!!!)
               //if (!strncmp(type, "class", 5) || !strcmp(type, "typedef")) {
               // handles class, class+protected and class+private
               if (!strncmp(type, "class", 5)) {
                  char *cls = strtok(0, "-!+;");
                  // just in case remove trailing space and tab
                  while (*cls == ' ') cls++;
                  int len = strlen(cls) - 1;
                  while (cls[len] == ' ' || cls[len] == '\t')
                     cls[len--] = '\0';
                  //no space between tmpl arguments allowed
                  cls = Compress(cls);
                  // except for A<B<C> >!
                  UnCompressTemplate(cls);

                  // don't include "vector<string>" and "std::pair<" classes
                  if (!strncmp(cls, "vector<string>", 14) ||
                      !strncmp(cls, "std::pair<", 10))
                     continue;

                  // replace "::" by "@@" since TEnv uses ":" as delimeter
                  char *s = cls;
                  while (*s) {
                     if (*s == ':')
                        *s = '@';
                     else if (*s == ' ')
                        *s = '-';
                     s++;
                  }
                  classes.push_back(cls);
               }
            }
         }
         fclose(lfp);
      } else {
         fprintf(stderr, "cannot open linkdef file %s\n", linkdef);
      }
   }

   const char *libbase = solib.c_str();
   if (!fullpath) {
      if ((libbase = strrchr(libbase, '/')))
         libbase++;
      else
         libbase = solib.c_str();
   }

   vector<string>::const_iterator it;
   for (it = classes.begin(); it != classes.end(); it++) {
      fprintf(fp, "Library.%-35s %s", ((*it)+":").c_str(), libbase);

      if (solibdeps.size() > 0) {
         vector<string>::const_iterator depit;
         for (depit = solibdeps.begin(); depit != solibdeps.end(); depit++) {
            const char *deplib = depit->c_str();
            if (!fullpath) {
               if ((deplib = strrchr(deplib, '/')))
                  deplib++;
               else
                  deplib = depit->c_str();
            }
            fprintf(fp, " %s", deplib);
         }
      }
      fprintf(fp, "\n");
   }

   return 0;
}

//______________________________________________________________________________
int main(int argc, char **argv)
{
   string         solib;
   vector<string> solibdeps;
   vector<string> linkdefs;
   bool fullpath = false;
   bool replace  = false;
   FILE *fp      = stdout;

   if (argc > 1) {
      int ic = 1;
      if (!strcmp(argv[ic], "-?") || !strcmp(argv[ic], "-h")) {
         fprintf(stderr, usage, argv[0]);
         return 1;
      }
      if (!strcmp(argv[ic], "-f")) {
         fullpath = true;
         ic++;
      }
      if (!strcmp(argv[ic], "-o")) {
         ic++;
         fp = fopen(argv[ic], "w");
         if (!fp) {
            fprintf(stderr, "cannot open output file %s\n", argv[ic]);
            return 1;
         }
         ic++;
      }
      if (!strcmp(argv[ic], "-r")) {
         replace = true;
         ic++;
         fp = fopen(argv[ic], "a+");
         if (!fp) {
            fprintf(stderr, "cannot open output file %s\n", argv[ic]);
            return 1;
         }
         ic++;
      }
      if (!strcmp(argv[ic], "-l")) {
         ic++;
         solib = argv[ic];
#ifdef __APPLE__
         string::size_type i = solib.find(".dylib");
         if (i != string::npos)
            solib.replace(i, 6, ".so");
#endif
         ic++;
      }
      if (!strcmp(argv[ic], "-d")) {
         ic++;
         for (int i = ic; i < argc && argv[i][0] != '-'; i++) {
            string dl = argv[i];
#ifdef __APPLE__
            string::size_type j = dl.find(".dylib");
            if (j != string::npos)
               dl.replace(j, 6, ".so");
#endif
            solibdeps.push_back(dl);
            ic++;
         }
      }
      if (!strcmp(argv[ic], "-c")) {
         ic++;
         for (int i = ic; i < argc; i++) {
            linkdefs.push_back(argv[i]);
            ic++;
         }
      }
   } else {
      fprintf(stderr, usage, argv[0]);
      return 1;
   }

   if (replace) {
#if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__FreeBSD__) && \
    !defined(__OpenBSD__)
      // lock file
      if (lockf(fileno(fp), F_LOCK, (off_t)1) == -1) {
         fprintf(stderr, "rlibmap: locking failed, don't use gmake -j\n");
      }
#endif

      // remove entries for solib to be processed
      RemoveLib(solib, fullpath, fp);
   }

   LibMap(solib, solibdeps, linkdefs, fullpath, fp);

   if (replace) {
#if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__FreeBSD__) && \
    !defined(__OpenBSD__)
      // remove lock
      lseek(fileno(fp), 0, SEEK_SET);
      if (lockf(fileno(fp), F_ULOCK, (off_t)1) == -1) {
         //fprintf(stderr, "rlibmap: error unlocking output file\n");
      }
#endif
   }

   if (fp != stdout)
      fclose(fp);

   return 0;
}
<|endoftext|>


<commit_before>/*
*
* Copyright 2013 Telefonica Investigacion y Desarrollo, S.A.U
*
* This file is part of Orion Context Broker.
*
* Orion Context Broker is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Orion Context Broker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
* General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Orion Context Broker. If not, see http://www.gnu.org/licenses/.
*
* For those usages not covered by this license please contact with
* fermin at tid dot es
*
* Author: Ken Zangelin
*/
#include <stdio.h>
#include <string>
#include <vector>

#include "logMsg/logMsg.h"

#include "common/globals.h"
#include "common/Format.h"
#include "common/tag.h"
#include "convenience/UpdateContextAttributeRequest.h"
#include "ngsi/StatusCode.h"

/* ****************************************************************************
*
* Constructor -
*/
UpdateContextAttributeRequest::UpdateContextAttributeRequest()
{
  metadataVector.tagSet("metadata");
}

/* ****************************************************************************
*
* render -
*/
std::string UpdateContextAttributeRequest::render(Format format, std::string indent)
{
  std::string tag = "updateContextAttributeRequest";
  std::string out = "";
  std::string indent2 = indent + "  ";

  out += startTag(indent, tag, format);
  out += valueTag(indent2, "type", type, format);
  out += valueTag(indent2, "contextValue", contextValue, format);
  out += metadataVector.render(format, indent2);
  out += endTag(indent, tag, format);

  return out;
}

/* ****************************************************************************
*
* check -
*/
std::string UpdateContextAttributeRequest::check(RequestType requestType, Format format, std::string indent, std::string predetectedError, int counter)
{
  StatusCode       response;
  std::string      res;

  if (format == (Format) 0)
     format = XML;

  if (predetectedError != "")
  {
    response.code         = SccBadRequest;
    response.reasonPhrase = predetectedError;
  }
  else if (contextValue == "")
  {
    response.code         = SccBadRequest;
    response.reasonPhrase = "empty context value";
  }
  else if ((res = metadataVector.check(requestType, format, indent, predetectedError, counter)) != "OK")
  {
    response.code         = SccBadRequest;
    response.reasonPhrase = res;
  }
  else
    return "OK";

  return response.render(format, indent);
}

/* ****************************************************************************
*
* present -
*/
void UpdateContextAttributeRequest::present(std::string indent)
{
  PRINTF("%stype:         %s", indent.c_str(), type.c_str());
  PRINTF("%scontextValue: %s", indent.c_str(), contextValue.c_str());
  metadataVector.present("ContextMetadata", indent);
}

/* ****************************************************************************
*
* release -
*/
void UpdateContextAttributeRequest::release(void)
{
   metadataVector.release();
}
<commit_msg>FIX rendering<commit_after>/*
*
* Copyright 2013 Telefonica Investigacion y Desarrollo, S.A.U
*
* This file is part of Orion Context Broker.
*
* Orion Context Broker is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Orion Context Broker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
* General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Orion Context Broker. If not, see http://www.gnu.org/licenses/.
*
* For those usages not covered by this license please contact with
* fermin at tid dot es
*
* Author: Ken Zangelin
*/
#include <stdio.h>
#include <string>
#include <vector>

#include "logMsg/logMsg.h"

#include "common/globals.h"
#include "common/Format.h"
#include "common/tag.h"
#include "convenience/UpdateContextAttributeRequest.h"
#include "ngsi/StatusCode.h"

/* ****************************************************************************
*
* Constructor -
*/
UpdateContextAttributeRequest::UpdateContextAttributeRequest()
{
  metadataVector.tagSet("metadata");
}

/* ****************************************************************************
*
* render -
*/
std::string UpdateContextAttributeRequest::render(Format format, std::string indent)
{
  std::string tag = "updateContextAttributeRequest";
  std::string out = "";
  std::string indent2 = indent + "  ";

  out += startTag(indent, tag, format, false);
  out += valueTag(indent2, "type", type, format, true);
  out += valueTag(indent2, "contextValue", contextValue, format, true);
  out += metadataVector.render(format, indent2);
  out += endTag(indent, tag, format);

  return out;
}

/* ****************************************************************************
*
* check -
*/
std::string UpdateContextAttributeRequest::check(RequestType requestType, Format format, std::string indent, std::string predetectedError, int counter)
{
  StatusCode       response;
  std::string      res;

  if (format == (Format) 0)
     format = XML;

  if (predetectedError != "")
  {
    response.code         = SccBadRequest;
    response.reasonPhrase = predetectedError;
  }
  else if (contextValue == "")
  {
    response.code         = SccBadRequest;
    response.reasonPhrase = "empty context value";
  }
  else if ((res = metadataVector.check(requestType, format, indent, predetectedError, counter)) != "OK")
  {
    response.code         = SccBadRequest;
    response.reasonPhrase = res;
  }
  else
    return "OK";

  return response.render(format, indent);
}

/* ****************************************************************************
*
* present -
*/
void UpdateContextAttributeRequest::present(std::string indent)
{
  PRINTF("%stype:         %s", indent.c_str(), type.c_str());
  PRINTF("%scontextValue: %s", indent.c_str(), contextValue.c_str());
  metadataVector.present("ContextMetadata", indent);
}

/* ****************************************************************************
*
* release -
*/
void UpdateContextAttributeRequest::release(void)
{
   metadataVector.release();
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of the Qt Build Suite.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights.  These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "rulesevaluationcontext.h"

#include "artifact.h"
#include "command.h"
#include "transformer.h"
#include <language/language.h>
#include <language/scriptengine.h>
#include <logging/translator.h>
#include <tools/error.h>
#include <tools/fileinfo.h>
#include <tools/progressobserver.h>
#include <tools/qbsassert.h>

#include <QVariant>

namespace qbs {
namespace Internal {

RulesEvaluationContext::RulesEvaluationContext(const Logger &logger)
    : m_engine(new ScriptEngine(logger)), m_observer(0), m_initScopeCalls(0)
{
    m_prepareScriptScope = m_engine->newObject();
    ProcessCommand::setupForJavaScript(m_prepareScriptScope);
    JavaScriptCommand::setupForJavaScript(m_prepareScriptScope);
}

RulesEvaluationContext::~RulesEvaluationContext()
{
    delete m_engine;
}

bool RulesEvaluationContext::isActive() const
{
    return m_initScopeCalls > 0;
}

void RulesEvaluationContext::initializeObserver(const QString &description, int maximumProgress)
{
    if (m_observer)
        m_observer->initialize(description, maximumProgress);
}

void RulesEvaluationContext::incrementProgressValue()
{
    if (m_observer)
        m_observer->incrementProgressValue();
}

void RulesEvaluationContext::checkForCancelation()
{
    if (Q_UNLIKELY(m_observer && m_observer->canceled()))
        throw ErrorInfo(Tr::tr("Build canceled."));
}

void RulesEvaluationContext::initScope()
{
    if (m_initScopeCalls++ > 0)
        return;

    m_engine->setProperty("lastSetupProject", QVariant());
    m_engine->setProperty("lastSetupProduct", QVariant());

    m_engine->clearImportsCache();
    m_engine->pushContext();
    m_scope = m_engine->newObject();
    m_scope.setPrototype(m_prepareScriptScope);
    m_engine->currentContext()->pushScope(m_scope);
}

void RulesEvaluationContext::cleanupScope()
{
    QBS_CHECK(m_initScopeCalls > 0);
    if (--m_initScopeCalls > 0)
        return;

    m_scope = QScriptValue();
    m_engine->currentContext()->popScope();
    m_engine->popContext();
}

RulesEvaluationContext::Scope::Scope(RulesEvaluationContext *evalContext)
    : m_evalContext(evalContext)
{
    evalContext->initScope();
}

RulesEvaluationContext::Scope::~Scope()
{
    m_evalContext->cleanupScope();
}

} // namespace Internal
} // namespace qbs
<commit_msg>Remove dead code<commit_after>/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of the Qt Build Suite.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights.  These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "rulesevaluationcontext.h"

#include "artifact.h"
#include "command.h"
#include "transformer.h"
#include <language/language.h>
#include <language/scriptengine.h>
#include <logging/translator.h>
#include <tools/error.h>
#include <tools/fileinfo.h>
#include <tools/progressobserver.h>
#include <tools/qbsassert.h>

#include <QVariant>

namespace qbs {
namespace Internal {

RulesEvaluationContext::RulesEvaluationContext(const Logger &logger)
    : m_engine(new ScriptEngine(logger)), m_observer(0), m_initScopeCalls(0)
{
    m_prepareScriptScope = m_engine->newObject();
    ProcessCommand::setupForJavaScript(m_prepareScriptScope);
    JavaScriptCommand::setupForJavaScript(m_prepareScriptScope);
}

RulesEvaluationContext::~RulesEvaluationContext()
{
    delete m_engine;
}

bool RulesEvaluationContext::isActive() const
{
    return m_initScopeCalls > 0;
}

void RulesEvaluationContext::initializeObserver(const QString &description, int maximumProgress)
{
    if (m_observer)
        m_observer->initialize(description, maximumProgress);
}

void RulesEvaluationContext::incrementProgressValue()
{
    if (m_observer)
        m_observer->incrementProgressValue();
}

void RulesEvaluationContext::checkForCancelation()
{
    if (Q_UNLIKELY(m_observer && m_observer->canceled()))
        throw ErrorInfo(Tr::tr("Build canceled."));
}

void RulesEvaluationContext::initScope()
{
    if (m_initScopeCalls++ > 0)
        return;

    m_engine->clearImportsCache();
    m_engine->pushContext();
    m_scope = m_engine->newObject();
    m_scope.setPrototype(m_prepareScriptScope);
    m_engine->currentContext()->pushScope(m_scope);
}

void RulesEvaluationContext::cleanupScope()
{
    QBS_CHECK(m_initScopeCalls > 0);
    if (--m_initScopeCalls > 0)
        return;

    m_scope = QScriptValue();
    m_engine->currentContext()->popScope();
    m_engine->popContext();
}

RulesEvaluationContext::Scope::Scope(RulesEvaluationContext *evalContext)
    : m_evalContext(evalContext)
{
    evalContext->initScope();
}

RulesEvaluationContext::Scope::~Scope()
{
    m_evalContext->cleanupScope();
}

} // namespace Internal
} // namespace qbs
<|endoftext|>