<commit_before>/*
 * Copyright (C) 2013-2015 Daniel Nicoletti <dantti12@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB. If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "dispatcher_p.h"

#include "common.h"
#include "application.h"
#include "engine.h"
#include "context.h"
#include "controller.h"
#include "controller_p.h"
#include "action.h"
#include "request_p.h"
#include "dispatchtypepath.h"
#include "dispatchtypechained.h"
#include "utils.h"

#include <QUrl>
#include <QMetaMethod>

using namespace Cutelyst;

Dispatcher::Dispatcher(QObject *parent) : QObject(parent)
  , d_ptr(new DispatcherPrivate(this))
{
    new DispatchTypePath(parent);
    new DispatchTypeChained(parent);
}

Dispatcher::~Dispatcher()
{
    delete d_ptr;
}

void Dispatcher::setupActions(const QVector<Controller*> &controllers, const QVector<Cutelyst::DispatchType *> &dispatchers, bool printActions)
{
    Q_D(Dispatcher);

    d->dispatchers = dispatchers;

    ActionList registeredActions;
    for (Controller *controller : controllers) {
        bool instanceUsed = false;
        const auto actions = controller->actions();
        for (Action *action : actions) {
            bool registered = false;
            if (!d->actions.contains(action->reverse())) {
                if (!action->attributes().contains(QLatin1String("Private"))) {
                    // Register the action with each dispatcher
                    for (DispatchType *dispatch : dispatchers) {
                        if (dispatch->registerAction(action)) {
                            registered = true;
                        }
                    }
                } else {
                    // We register private actions
                    registered = true;
                }
            }

            // The Begin, Auto, End actions are not
            // registered by Dispatchers but we need them
            // as private actions anyway
            if (registered) {
                d->actions.insert(action->ns() + QLatin1Char('/') + action->name(), action);
                d->actionContainer[action->ns()] << action;
                registeredActions.append(action);
                instanceUsed = true;
            } else {
                qCDebug(CUTELYST_DISPATCHER) << "The action" << action->name() << "of"
                                             << action->controller()->objectName()
                                             << "controller was not registered in any dispatcher."
                                                " If you still want to access it internally (via actionFor())"
                                                " you may make it's method private.";
            }
        }

        if (instanceUsed) {
            d->controllers.insert(controller->objectName(), controller);
        }
    }

    if (printActions) {
        d->printActions();
    }

    // Cache root actions, BEFORE the controllers set them
    d->rootActions = d->actionContainer.value(QLatin1String(""));

    for (Controller *controller : controllers) {
        controller->d_ptr->setupFinished();
    }

    // Unregister any dispatcher that is not in use
    int i = 0;
    while (i < d->dispatchers.size()) {
        DispatchType *type = d->dispatchers.at(i);
        if (!type->inUse()) {
            d->dispatchers.removeAt(i);
            continue;
        }
        ++i;
    }

    if (printActions) {
        // List all public actions
        for (DispatchType *dispatch : dispatchers) {
            qCDebug(CUTELYST_DISPATCHER) << dispatch->list().constData();
        }
    }
}

bool Dispatcher::dispatch(Context *c)
{
    Action *action = c->action();
    if (action) {
        return action->controller()->_DISPATCH(c);
    } else {
        const QString path = c->req()->path();
        if (path.isEmpty()) {
            c->error(c->translate("Cutelyst::Dispatcher", "No default action defined"));
        } else {
            c->error(c->translate("Cutelyst::Dispatcher", "Unknown resource '%1'.").arg(path));
        }
    }
    return false;
}

bool Dispatcher::forward(Context *c, Component *component)
{
    Q_ASSERT(component);
    // If the component was an Action
    // the dispatch() would call c->execute
    return c->execute(component);
}

bool Dispatcher::forward(Context *c, const QString &opname)
{
    Q_D(const Dispatcher);

    Action *action = d->command2Action(c, opname, c->request()->args());
    if (action) {
        return action->dispatch(c);
    }

    qCCritical(CUTELYST_DISPATCHER) << "Action not found" << opname << c->request()->args();
    return false;
}

void Dispatcher::prepareAction(Context *c)
{
    Q_D(Dispatcher);

    Request *request = c->request();
    d->prepareAction(c, request->path());

    static const auto &log = CUTELYST_DISPATCHER();
    if (log.isDebugEnabled()) {
        if (!request->match().isEmpty()) {
            qCDebug(log) << "Path is" << request->match();
        }

        if (!request->args().isEmpty()) {
            qCDebug(log) << "Arguments are" << request->args().join(QLatin1Char('/'));
        }
    }
}

void DispatcherPrivate::prepareAction(Context *c, const QString &requestPath) const
{
    QString path = normalizePath(requestPath);
    QStringList args;

    //  "foo/bar"
    //  "foo/" skip
    //  "foo"
    //  ""
    Q_FOREVER {
        // Check out the dispatch types to see if any
        // will handle the path at this level
        for (DispatchType *type : dispatchers) {
            if (type->match(c, path, args) == DispatchType::ExactMatch) {
                return;
            }
        }

        // leave the loop if we are at the root "/"
        if (path.isEmpty()) {
            break;
        }

        int pos = path.lastIndexOf(QLatin1Char('/'));

        QString arg = path.mid(pos + 1);
        args.prepend(Utils::decodePercentEncoding(&arg));

        path.resize(pos);
    }
}

Action *Dispatcher::getAction(const QString &name, const QString &nameSpace) const
{
    Q_D(const Dispatcher);

    if (name.isEmpty()) {
        return 0;
    }

    if (nameSpace.isEmpty()) {
        return d->actions.value(QLatin1Char('/') + name);
    }

    const QString ns = DispatcherPrivate::cleanNamespace(nameSpace);
    return d->actions.value(ns + QLatin1Char('/') + name);
}

Action *Dispatcher::getActionByPath(const QString &path) const
{
    Q_D(const Dispatcher);

    QString _path = path;
    if (_path.startsWith(QLatin1Char('/'))) {
        _path.remove(0, 1);
    }
    if (!_path.contains(QLatin1Char('/'))) {
        _path.prepend(QLatin1Char('/'));
    }
    return d->actions.value(_path);
}

ActionList Dispatcher::getActions(const QString &name, const QString &nameSpace) const
{
    Q_D(const Dispatcher);

    ActionList ret;

    if (name.isEmpty()) {
        return ret;
    }

    const QString ns = DispatcherPrivate::cleanNamespace(nameSpace);
    const ActionList containers = d->getContainers(ns);

    for (Action *action : containers) {
        if (action->name() == name) {
            ret.prepend(action);
        }
    }
    return ret;
}

QMap<QString, Controller *> Dispatcher::controllers() const
{
    Q_D(const Dispatcher);
    return d->controllers;
}

QString Dispatcher::uriForAction(Action *action, const QStringList &captures) const
{
    Q_D(const Dispatcher);
    QString ret;
    for (DispatchType *dispatch : d->dispatchers) {
        ret = dispatch->uriForAction(action, captures);
        if (!ret.isNull()) {
            if (ret.isEmpty()) {
                ret = QStringLiteral("/");
            }
            break;
        }
    }
    return ret;
}

Action *Dispatcher::expandAction(Context *c, Action *action) const
{
    Q_D(const Dispatcher);
    for (DispatchType *dispatch : d->dispatchers) {
        Action *expandedAction = dispatch->expandAction(c, action);
        if (expandedAction) {
            return expandedAction;
        }
    }
    return action;
}

QVector<DispatchType *> Dispatcher::dispatchers() const
{
    Q_D(const Dispatcher);
    return d->dispatchers;
}

QString DispatcherPrivate::cleanNamespace(const QString &ns)
{
    QString ret = ns;
    bool lastWasSlash = true; // remove initial slash
    int nsSize = ns.size();
    for (int i = 0; i < nsSize; ++i) {
        // Mark if the last char was a slash
        // so that two or more consecutive slashes
        // could be converted to just one
        // "a///b" -> "a/b"
        if (ret.at(i) == QLatin1Char('/')) {
            if (lastWasSlash) {
                ret.remove(i, 1);
                --nsSize;
            } else {
                lastWasSlash = true;
            }
        } else {
            lastWasSlash = false;
        }
    }
    return ret;
}

QString DispatcherPrivate::normalizePath(const QString &path)
{
    QString ret = path;
    bool lastSlash = true;
    int i = 0;
    while (i < ret.size()) {
        if (ret.at(i) == QLatin1Char('/')) {
            if (lastSlash) {
                ret.remove(i, 1);
                continue;
            }
            lastSlash = true;
        } else {
            lastSlash = false;
        }
        ++i;
    }

    if (ret.endsWith(QLatin1Char('/'))) {
        ret.resize(ret.size() - 1);
    }
    return ret;
}

void DispatcherPrivate::printActions() const
{
    QVector<QStringList> table;

    QStringList keys = actions.keys();
    keys.sort(Qt::CaseInsensitive);
    for (const QString &key : keys) {
        Action *action = actions.value(key);
        QString path = key;
        if (!path.startsWith(QLatin1Char('/'))) {
            path.prepend(QLatin1Char('/'));
        }

        QStringList row;
        row.append(path);
        row.append(action->className());
        row.append(action->name());
        table.append(row);
    }

    qCDebug(CUTELYST_DISPATCHER) <<  Utils::buildTable(table, {
                                                           QLatin1String("Private"),
                                                           QLatin1String("Class"),
                                                           QLatin1String("Method")
                                                       },
                                                       QLatin1String("Loaded Private actions:")).constData();
}

ActionList DispatcherPrivate::getContainers(const QString &ns) const
{
    ActionList ret;

    if (ns != QLatin1String("/")) {
        int pos = ns.size();
//        qDebug() << pos << ns.mid(0, pos);
        while (pos > 0) {
//            qDebug() << pos << ns.mid(0, pos);
            ret.append(actionContainer.value(ns.mid(0, pos)));
            pos = ns.lastIndexOf(QLatin1Char('/'), pos - 1);
        }
    }
//    qDebug() << actionContainer.size() << rootActions;
    ret.append(rootActions);

    return ret;
}

Action *DispatcherPrivate::command2Action(Context *c, const QString &command, const QStringList &args) const
{
    auto it = actions.constFind(command);
    if (it != actions.constEnd()) {
        return it.value();
    }

    return invokeAsPath(c, command, args);
}

Action *DispatcherPrivate::invokeAsPath(Context *c, const QString &relativePath, const QStringList &args) const
{
    Q_Q(const Dispatcher);

    Action *ret;
    QString path = DispatcherPrivate::actionRel2Abs(c, relativePath);

    int pos = path.lastIndexOf(QLatin1Char('/'));
    int lastPos = path.size();
    do {
        if (pos == -1) {
            ret = q->getAction(path, QString());
            if (ret) {
                return ret;
            }
        } else {
            const QString name = path.mid(pos + 1, lastPos);
            path = path.mid(0, pos);
            ret = q->getAction(name, path);
            if (ret) {
                return ret;
            }
        }

        lastPos = pos;
        pos = path.indexOf(QLatin1Char('/'), pos - 1);
    } while (pos != -1);

    return 0;
}

QString DispatcherPrivate::actionRel2Abs(Context *c, const QString &path)
{
    QString ret;
    if (path.startsWith(QLatin1Char('/'))) {
        ret = path.mid(1);
        return ret;
    }

    const QString ns = qobject_cast<Action *>(c->stack().constLast())->ns();
    if (ns.isEmpty()) {
        ret = path;
    } else {
        ret = ns + QLatin1Char('/') + path;
    }
    return ret;
}

#include "moc_dispatcher.cpp"
<commit_msg>Core: Use getActionsByPath in getActions<commit_after>/*
 * Copyright (C) 2013-2015 Daniel Nicoletti <dantti12@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB. If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "dispatcher_p.h"

#include "common.h"
#include "application.h"
#include "engine.h"
#include "context.h"
#include "controller.h"
#include "controller_p.h"
#include "action.h"
#include "request_p.h"
#include "dispatchtypepath.h"
#include "dispatchtypechained.h"
#include "utils.h"

#include <QUrl>
#include <QMetaMethod>

using namespace Cutelyst;

Dispatcher::Dispatcher(QObject *parent) : QObject(parent)
  , d_ptr(new DispatcherPrivate(this))
{
    new DispatchTypePath(parent);
    new DispatchTypeChained(parent);
}

Dispatcher::~Dispatcher()
{
    delete d_ptr;
}

void Dispatcher::setupActions(const QVector<Controller*> &controllers, const QVector<Cutelyst::DispatchType *> &dispatchers, bool printActions)
{
    Q_D(Dispatcher);

    d->dispatchers = dispatchers;

    ActionList registeredActions;
    for (Controller *controller : controllers) {
        bool instanceUsed = false;
        const auto actions = controller->actions();
        for (Action *action : actions) {
            bool registered = false;
            if (!d->actions.contains(action->reverse())) {
                if (!action->attributes().contains(QLatin1String("Private"))) {
                    // Register the action with each dispatcher
                    for (DispatchType *dispatch : dispatchers) {
                        if (dispatch->registerAction(action)) {
                            registered = true;
                        }
                    }
                } else {
                    // We register private actions
                    registered = true;
                }
            }

            // The Begin, Auto, End actions are not
            // registered by Dispatchers but we need them
            // as private actions anyway
            if (registered) {
                d->actions.insert(action->ns() + QLatin1Char('/') + action->name(), action);
                d->actionContainer[action->ns()] << action;
                registeredActions.append(action);
                instanceUsed = true;
            } else {
                qCDebug(CUTELYST_DISPATCHER) << "The action" << action->name() << "of"
                                             << action->controller()->objectName()
                                             << "controller was not registered in any dispatcher."
                                                " If you still want to access it internally (via actionFor())"
                                                " you may make it's method private.";
            }
        }

        if (instanceUsed) {
            d->controllers.insert(controller->objectName(), controller);
        }
    }

    if (printActions) {
        d->printActions();
    }

    // Cache root actions, BEFORE the controllers set them
    d->rootActions = d->actionContainer.value(QLatin1String(""));

    for (Controller *controller : controllers) {
        controller->d_ptr->setupFinished();
    }

    // Unregister any dispatcher that is not in use
    int i = 0;
    while (i < d->dispatchers.size()) {
        DispatchType *type = d->dispatchers.at(i);
        if (!type->inUse()) {
            d->dispatchers.removeAt(i);
            continue;
        }
        ++i;
    }

    if (printActions) {
        // List all public actions
        for (DispatchType *dispatch : dispatchers) {
            qCDebug(CUTELYST_DISPATCHER) << dispatch->list().constData();
        }
    }
}

bool Dispatcher::dispatch(Context *c)
{
    Action *action = c->action();
    if (action) {
        return action->controller()->_DISPATCH(c);
    } else {
        const QString path = c->req()->path();
        if (path.isEmpty()) {
            c->error(c->translate("Cutelyst::Dispatcher", "No default action defined"));
        } else {
            c->error(c->translate("Cutelyst::Dispatcher", "Unknown resource '%1'.").arg(path));
        }
    }
    return false;
}

bool Dispatcher::forward(Context *c, Component *component)
{
    Q_ASSERT(component);
    // If the component was an Action
    // the dispatch() would call c->execute
    return c->execute(component);
}

bool Dispatcher::forward(Context *c, const QString &opname)
{
    Q_D(const Dispatcher);

    Action *action = d->command2Action(c, opname, c->request()->args());
    if (action) {
        return action->dispatch(c);
    }

    qCCritical(CUTELYST_DISPATCHER) << "Action not found" << opname << c->request()->args();
    return false;
}

void Dispatcher::prepareAction(Context *c)
{
    Q_D(Dispatcher);

    Request *request = c->request();
    d->prepareAction(c, request->path());

    static const auto &log = CUTELYST_DISPATCHER();
    if (log.isDebugEnabled()) {
        if (!request->match().isEmpty()) {
            qCDebug(log) << "Path is" << request->match();
        }

        if (!request->args().isEmpty()) {
            qCDebug(log) << "Arguments are" << request->args().join(QLatin1Char('/'));
        }
    }
}

void DispatcherPrivate::prepareAction(Context *c, const QString &requestPath) const
{
    QString path = normalizePath(requestPath);
    QStringList args;

    //  "foo/bar"
    //  "foo/" skip
    //  "foo"
    //  ""
    Q_FOREVER {
        // Check out the dispatch types to see if any
        // will handle the path at this level
        for (DispatchType *type : dispatchers) {
            if (type->match(c, path, args) == DispatchType::ExactMatch) {
                return;
            }
        }

        // leave the loop if we are at the root "/"
        if (path.isEmpty()) {
            break;
        }

        int pos = path.lastIndexOf(QLatin1Char('/'));

        QString arg = path.mid(pos + 1);
        args.prepend(Utils::decodePercentEncoding(&arg));

        path.resize(pos);
    }
}

Action *Dispatcher::getAction(const QString &name, const QString &nameSpace) const
{
    Q_D(const Dispatcher);

    if (name.isEmpty()) {
        return nullptr;
    }

    if (nameSpace.isEmpty()) {
        return d->actions.value(QLatin1Char('/') + name);
    }

    const QString ns = DispatcherPrivate::cleanNamespace(nameSpace);
    return getActionByPath(ns + QLatin1Char('/') + name);
}

Action *Dispatcher::getActionByPath(const QString &path) const
{
    Q_D(const Dispatcher);

    QString _path = path;
    if (_path.startsWith(QLatin1Char('/'))) {
        _path.remove(0, 1);
    }
    if (!_path.contains(QLatin1Char('/'))) {
        _path.prepend(QLatin1Char('/'));
    }
    return d->actions.value(_path);
}

ActionList Dispatcher::getActions(const QString &name, const QString &nameSpace) const
{
    Q_D(const Dispatcher);

    ActionList ret;

    if (name.isEmpty()) {
        return ret;
    }

    const QString ns = DispatcherPrivate::cleanNamespace(nameSpace);
    const ActionList containers = d->getContainers(ns);

    for (Action *action : containers) {
        if (action->name() == name) {
            ret.prepend(action);
        }
    }
    return ret;
}

QMap<QString, Controller *> Dispatcher::controllers() const
{
    Q_D(const Dispatcher);
    return d->controllers;
}

QString Dispatcher::uriForAction(Action *action, const QStringList &captures) const
{
    Q_D(const Dispatcher);
    QString ret;
    for (DispatchType *dispatch : d->dispatchers) {
        ret = dispatch->uriForAction(action, captures);
        if (!ret.isNull()) {
            if (ret.isEmpty()) {
                ret = QStringLiteral("/");
            }
            break;
        }
    }
    return ret;
}

Action *Dispatcher::expandAction(Context *c, Action *action) const
{
    Q_D(const Dispatcher);
    for (DispatchType *dispatch : d->dispatchers) {
        Action *expandedAction = dispatch->expandAction(c, action);
        if (expandedAction) {
            return expandedAction;
        }
    }
    return action;
}

QVector<DispatchType *> Dispatcher::dispatchers() const
{
    Q_D(const Dispatcher);
    return d->dispatchers;
}

QString DispatcherPrivate::cleanNamespace(const QString &ns)
{
    QString ret = ns;
    bool lastWasSlash = true; // remove initial slash
    int nsSize = ns.size();
    for (int i = 0; i < nsSize; ++i) {
        // Mark if the last char was a slash
        // so that two or more consecutive slashes
        // could be converted to just one
        // "a///b" -> "a/b"
        if (ret.at(i) == QLatin1Char('/')) {
            if (lastWasSlash) {
                ret.remove(i, 1);
                --nsSize;
            } else {
                lastWasSlash = true;
            }
        } else {
            lastWasSlash = false;
        }
    }
    return ret;
}

QString DispatcherPrivate::normalizePath(const QString &path)
{
    QString ret = path;
    bool lastSlash = true;
    int i = 0;
    while (i < ret.size()) {
        if (ret.at(i) == QLatin1Char('/')) {
            if (lastSlash) {
                ret.remove(i, 1);
                continue;
            }
            lastSlash = true;
        } else {
            lastSlash = false;
        }
        ++i;
    }

    if (ret.endsWith(QLatin1Char('/'))) {
        ret.resize(ret.size() - 1);
    }
    return ret;
}

void DispatcherPrivate::printActions() const
{
    QVector<QStringList> table;

    QStringList keys = actions.keys();
    keys.sort(Qt::CaseInsensitive);
    for (const QString &key : keys) {
        Action *action = actions.value(key);
        QString path = key;
        if (!path.startsWith(QLatin1Char('/'))) {
            path.prepend(QLatin1Char('/'));
        }

        QStringList row;
        row.append(path);
        row.append(action->className());
        row.append(action->name());
        table.append(row);
    }

    qCDebug(CUTELYST_DISPATCHER) <<  Utils::buildTable(table, {
                                                           QLatin1String("Private"),
                                                           QLatin1String("Class"),
                                                           QLatin1String("Method")
                                                       },
                                                       QLatin1String("Loaded Private actions:")).constData();
}

ActionList DispatcherPrivate::getContainers(const QString &ns) const
{
    ActionList ret;

    if (ns != QLatin1String("/")) {
        int pos = ns.size();
//        qDebug() << pos << ns.mid(0, pos);
        while (pos > 0) {
//            qDebug() << pos << ns.mid(0, pos);
            ret.append(actionContainer.value(ns.mid(0, pos)));
            pos = ns.lastIndexOf(QLatin1Char('/'), pos - 1);
        }
    }
//    qDebug() << actionContainer.size() << rootActions;
    ret.append(rootActions);

    return ret;
}

Action *DispatcherPrivate::command2Action(Context *c, const QString &command, const QStringList &args) const
{
    auto it = actions.constFind(command);
    if (it != actions.constEnd()) {
        return it.value();
    }

    return invokeAsPath(c, command, args);
}

Action *DispatcherPrivate::invokeAsPath(Context *c, const QString &relativePath, const QStringList &args) const
{
    Q_Q(const Dispatcher);

    Action *ret;
    QString path = DispatcherPrivate::actionRel2Abs(c, relativePath);

    int pos = path.lastIndexOf(QLatin1Char('/'));
    int lastPos = path.size();
    do {
        if (pos == -1) {
            ret = q->getAction(path, QString());
            if (ret) {
                return ret;
            }
        } else {
            const QString name = path.mid(pos + 1, lastPos);
            path = path.mid(0, pos);
            ret = q->getAction(name, path);
            if (ret) {
                return ret;
            }
        }

        lastPos = pos;
        pos = path.indexOf(QLatin1Char('/'), pos - 1);
    } while (pos != -1);

    return 0;
}

QString DispatcherPrivate::actionRel2Abs(Context *c, const QString &path)
{
    QString ret;
    if (path.startsWith(QLatin1Char('/'))) {
        ret = path.mid(1);
        return ret;
    }

    const QString ns = qobject_cast<Action *>(c->stack().constLast())->ns();
    if (ns.isEmpty()) {
        ret = path;
    } else {
        ret = ns + QLatin1Char('/') + path;
    }
    return ret;
}

#include "moc_dispatcher.cpp"
<|endoftext|>


<commit_before>#include "catch.hpp"

#include <shadow.hpp>
#include <vector>
#include <iostream>

struct tca1
{
    int i;
    char c;
};

class tca2
{
public:
    tca2() : c_('a')
    {
    }

    tca2(char c) : c_(std::move(c))
    {
    }

    char
    get_c() const
    {
        return c_;
    }

private:
    char c_;
};

class tca3
{
public:
    tca3(const int& i) : i_(i)
    {
    }

    int
    get_i() const
    {
        return i_;
    }

private:
    int i_;
};

namespace tca_space
{
REGISTER_TYPE_BEGIN()
REGISTER_TYPE(tca1)
REGISTER_TYPE(tca2)
REGISTER_TYPE(tca3)
REGISTER_TYPE_END()

REGISTER_CONSTRUCTOR(tca1, int, char)

REGISTER_CONSTRUCTOR(tca2)
REGISTER_CONSTRUCTOR(tca2, char)

REGISTER_CONSTRUCTOR(tca3, const int&)

SHADOW_INIT()
}

TEST_CASE("get all types", "[reflection_manager]")
{
    auto types_pair = tca_space::manager.types();

    SECTION("find double type")
    {
        auto found = std::find_if(
            types_pair.first, types_pair.second, [](const auto& tp) {
                return tp.name() == std::string("double");
            });

        REQUIRE(found != types_pair.second);

        SECTION("get all constructors for double")
        {
            auto constr_pair = tca_space::manager.constructors_by_type(*found);

            REQUIRE(std::distance(constr_pair.first, constr_pair.second) == 2);

            SECTION("find constructor taking 0 arguments")
            {
                auto found_constr = std::find_if(
                    constr_pair.first, constr_pair.second, [](const auto& ctr) {
                        return ctr.num_parameters() == 0;
                    });

                REQUIRE(found_constr != constr_pair.second);

                SECTION("constructor double with 0 args")
                {
                    // construct with no arg overload
                    auto obj = tca_space::manager.construct(*found_constr);

                    // construct with overload taking iterators to args
                    std::vector<shadow::variable> args;
                    auto obj2 = tca_space::manager.construct(
                        *found_constr, args.begin(), args.end());

                    REQUIRE(obj.type().name() == std::string("double"));
                    REQUIRE(obj2.type().name() == std::string("double"));
                    REQUIRE(tca_space::static_value_cast<double>(obj) ==
                            Approx(0.0));
                    REQUIRE(tca_space::static_value_cast<double>(obj2) ==
                            Approx(0.0));
                }
            }

            SECTION("find constructor taking 1 argument")
            {
                auto found_constr = std::find_if(
                    constr_pair.first, constr_pair.second, [](const auto& ctr) {
                        return ctr.num_parameters() == 1;
                    });

                REQUIRE(found_constr != constr_pair.second);

                SECTION("constructor double with 1 arg")
                {
                    // construct with overload taking iterators to args
                    std::vector<shadow::variable> args{
                        tca_space::static_create<double>(20.0)};
                    auto obj = tca_space::manager.construct(
                        *found_constr, args.begin(), args.end());

                    REQUIRE(obj.type().name() == std::string("double"));
                    REQUIRE(tca_space::static_value_cast<double>(obj) ==
                            Approx(20.0));
                }
            }
        }
    }

    SECTION("find tca1 type")
    {
        auto found = std::find_if(
            types_pair.first, types_pair.second, [](const auto& tp) {
                return tp.name() == std::string("tca1");
            });

        REQUIRE(found != types_pair.second);

        SECTION("get all constructors for tca1")
        {
            auto constr_pair = tca_space::manager.constructors_by_type(*found);

            REQUIRE(std::distance(constr_pair.first, constr_pair.second) == 1);

            SECTION("find constructor taking two args")
            {
                auto found_constr = std::find_if(
                    constr_pair.first, constr_pair.second, [](const auto& ctr) {
                        return ctr.num_parameters() == 2;
                    });

                REQUIRE(found_constr != constr_pair.second);

                SECTION("construct a tca1 with two arguments")
                {
                    std::vector<shadow::variable> args{
                        tca_space::static_create<int>(10),
                        tca_space::static_create<char>('c')};

                    auto obj = tca_space::manager.construct(
                        *found_constr, args.begin(), args.end());

                    REQUIRE(obj.type().name() == std::string("tca1"));
                    REQUIRE(tca_space::static_value_cast<tca1>(obj).i == 10);
                    REQUIRE(tca_space::static_value_cast<tca1>(obj).c == 'c');
                }
            }
        }
    }

    SECTION("find tca2 type")
    {
        auto found = std::find_if(
            types_pair.first, types_pair.second, [](const auto& tp) {
                return tp.name() == std::string("tca2");
            });

        REQUIRE(found != types_pair.second);

        SECTION("get all constructors for tca2")
        {
            auto constr_pair = tca_space::manager.constructors_by_type(*found);

            REQUIRE(std::distance(constr_pair.first, constr_pair.second) == 2);

            SECTION("find default constructor for tca2")
            {
                auto found_constr = std::find_if(
                    constr_pair.first, constr_pair.second, [](const auto& ctr) {
                        return ctr.num_parameters() == 0;
                    });

                REQUIRE(found_constr != constr_pair.second);

                SECTION("construct tca2 with default constructor")
                {
                    auto obj = tca_space::manager.construct(*found_constr);

                    REQUIRE(obj.type().name() == std::string("tca2"));
                    REQUIRE(tca_space::static_value_cast<tca2>(obj).get_c() ==
                            'a');
                }
            }

            SECTION("find constructor for tca2 taking one argument")
            {
                auto found_constr = std::find_if(
                    constr_pair.first, constr_pair.second, [](const auto& ctr) {
                        return ctr.num_parameters() == 1;
                    });

                REQUIRE(found_constr != constr_pair.second);

                SECTION("construct tca2 with one arg constructor")
                {
                    std::vector<shadow::variable> args{
                        tca_space::static_create<char>('w')};

                    auto obj = tca_space::manager.construct(
                        *found_constr, args.begin(), args.end());

                    REQUIRE(obj.type().name() == std::string("tca2"));
                    REQUIRE(tca_space::static_value_cast<tca2>(obj).get_c() ==
                            'w');
                }
            }
        }
    }

    SECTION("find tca3 type")
    {
        auto found = std::find_if(
            types_pair.first, types_pair.second, [](const auto& tp) {
                return tp.name() == std::string("tca3");
            });

        REQUIRE(found != types_pair.second);

        SECTION("get all constructors for tca3")
        {
            auto constr_pair = tca_space::manager.constructors_by_type(*found);

            REQUIRE(std::distance(constr_pair.first, constr_pair.second) == 1);
        }
    }
}
<commit_msg>Add unit test causing segfault. 	modified:   tests/test_constructor_api.cpp<commit_after>#include "catch.hpp"

#include <shadow.hpp>
#include <vector>
#include <iostream>

struct tca1
{
    int i;
    char c;
};

class tca2
{
public:
    tca2() : c_('a')
    {
    }

    tca2(char c) : c_(std::move(c))
    {
    }

    char
    get_c() const
    {
        return c_;
    }

private:
    char c_;
};

class tca3
{
public:
    tca3(const int& i) : i_(i)
    {
    }

    int
    get_i() const
    {
        return i_;
    }

private:
    int i_;
};

namespace tca_space
{
REGISTER_TYPE_BEGIN()
REGISTER_TYPE(tca1)
REGISTER_TYPE(tca2)
REGISTER_TYPE(tca3)
REGISTER_TYPE_END()

REGISTER_CONSTRUCTOR(tca1, int, char)

REGISTER_CONSTRUCTOR(tca2)
REGISTER_CONSTRUCTOR(tca2, char)

REGISTER_CONSTRUCTOR(tca3, const int&)

SHADOW_INIT()
}

TEST_CASE("get all types", "[reflection_manager]")
{
    auto types_pair = tca_space::manager.types();

    SECTION("find double type")
    {
        auto found = std::find_if(
            types_pair.first, types_pair.second, [](const auto& tp) {
                return tp.name() == std::string("double");
            });

        REQUIRE(found != types_pair.second);

        SECTION("get all constructors for double")
        {
            auto constr_pair = tca_space::manager.constructors_by_type(*found);

            REQUIRE(std::distance(constr_pair.first, constr_pair.second) == 2);

            SECTION("find constructor taking 0 arguments")
            {
                auto found_constr = std::find_if(
                    constr_pair.first, constr_pair.second, [](const auto& ctr) {
                        return ctr.num_parameters() == 0;
                    });

                REQUIRE(found_constr != constr_pair.second);

                SECTION("constructor double with 0 args")
                {
                    // construct with no arg overload
                    auto obj = tca_space::manager.construct(*found_constr);

                    // construct with overload taking iterators to args
                    std::vector<shadow::variable> args;
                    auto obj2 = tca_space::manager.construct(
                        *found_constr, args.begin(), args.end());

                    REQUIRE(obj.type().name() == std::string("double"));
                    REQUIRE(obj2.type().name() == std::string("double"));
                    REQUIRE(tca_space::static_value_cast<double>(obj) ==
                            Approx(0.0));
                    REQUIRE(tca_space::static_value_cast<double>(obj2) ==
                            Approx(0.0));
                }
            }

            SECTION("find constructor taking 1 argument")
            {
                auto found_constr = std::find_if(
                    constr_pair.first, constr_pair.second, [](const auto& ctr) {
                        return ctr.num_parameters() == 1;
                    });

                REQUIRE(found_constr != constr_pair.second);

                SECTION("constructor double with 1 arg")
                {
                    // construct with overload taking iterators to args
                    std::vector<shadow::variable> args{
                        tca_space::static_create<double>(20.0)};
                    auto obj = tca_space::manager.construct(
                        *found_constr, args.begin(), args.end());

                    REQUIRE(obj.type().name() == std::string("double"));
                    REQUIRE(tca_space::static_value_cast<double>(obj) ==
                            Approx(20.0));
                }
            }
        }
    }

    SECTION("find tca1 type")
    {
        auto found = std::find_if(
            types_pair.first, types_pair.second, [](const auto& tp) {
                return tp.name() == std::string("tca1");
            });

        REQUIRE(found != types_pair.second);

        SECTION("get all constructors for tca1")
        {
            auto constr_pair = tca_space::manager.constructors_by_type(*found);

            REQUIRE(std::distance(constr_pair.first, constr_pair.second) == 1);

            SECTION("find constructor taking two args")
            {
                auto found_constr = std::find_if(
                    constr_pair.first, constr_pair.second, [](const auto& ctr) {
                        return ctr.num_parameters() == 2;
                    });

                REQUIRE(found_constr != constr_pair.second);

                SECTION("construct a tca1 with two arguments")
                {
                    std::vector<shadow::variable> args{
                        tca_space::static_create<int>(10),
                        tca_space::static_create<char>('c')};

                    auto obj = tca_space::manager.construct(
                        *found_constr, args.begin(), args.end());

                    REQUIRE(obj.type().name() == std::string("tca1"));
                    REQUIRE(tca_space::static_value_cast<tca1>(obj).i == 10);
                    REQUIRE(tca_space::static_value_cast<tca1>(obj).c == 'c');
                }
            }
        }
    }

    SECTION("find tca2 type")
    {
        auto found = std::find_if(
            types_pair.first, types_pair.second, [](const auto& tp) {
                return tp.name() == std::string("tca2");
            });

        REQUIRE(found != types_pair.second);

        SECTION("get all constructors for tca2")
        {
            auto constr_pair = tca_space::manager.constructors_by_type(*found);

            REQUIRE(std::distance(constr_pair.first, constr_pair.second) == 2);

            SECTION("find default constructor for tca2")
            {
                auto found_constr = std::find_if(
                    constr_pair.first, constr_pair.second, [](const auto& ctr) {
                        return ctr.num_parameters() == 0;
                    });

                REQUIRE(found_constr != constr_pair.second);

                SECTION("construct tca2 with default constructor")
                {
                    auto obj = tca_space::manager.construct(*found_constr);

                    REQUIRE(obj.type().name() == std::string("tca2"));
                    REQUIRE(tca_space::static_value_cast<tca2>(obj).get_c() ==
                            'a');
                }
            }

            SECTION("find constructor for tca2 taking one argument")
            {
                auto found_constr = std::find_if(
                    constr_pair.first, constr_pair.second, [](const auto& ctr) {
                        return ctr.num_parameters() == 1;
                    });

                REQUIRE(found_constr != constr_pair.second);

                SECTION("construct tca2 with one arg constructor")
                {
                    std::vector<shadow::variable> args{
                        tca_space::static_create<char>('w')};

                    auto obj = tca_space::manager.construct(
                        *found_constr, args.begin(), args.end());

                    REQUIRE(obj.type().name() == std::string("tca2"));
                    REQUIRE(tca_space::static_value_cast<tca2>(obj).get_c() ==
                            'w');
                }
            }
        }
    }

    SECTION("find tca3 type")
    {
        auto found = std::find_if(
            types_pair.first, types_pair.second, [](const auto& tp) {
                return tp.name() == std::string("tca3");
            });

        REQUIRE(found != types_pair.second);

        SECTION("get all constructors for tca3")
        {
            auto constr_pair = tca_space::manager.constructors_by_type(*found);

            REQUIRE(std::distance(constr_pair.first, constr_pair.second) == 1);

            SECTION("find constructor taking one arg")
            {
                auto found_constr = std::find_if(
                    constr_pair.first, constr_pair.second, [](const auto& ctr) {
                        return ctr.num_parameters() == 1;
                    });

                REQUIRE(found_constr != constr_pair.second);

                SECTION("construct tca3 with one argument")
                {
                    std::vector<shadow::variable> args{
                        tca_space::static_create<int>(100)};

                    auto obj = tca_space::manager.construct(
                        *found_constr, args.begin(), args.end());

                    REQUIRE(obj.type().name() == std::string("tca3"));
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: aquavclevents.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: kz $ $Date: 2007-10-09 15:07:55 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef INCLUDED_AQUAVCLEVENTS_HXX
#define INCLUDED_AQUAVCLEVENTS_HXX

#include <premac.h>
#include <Carbon/Carbon.h>
#include <postmac.h>

/* Definition of custom OpenOffice.org events.

   Avoid conflict with Apple defined event class and type
   definitions by using uppercase letters. Lowercase
   letter definitions are reserved for Apple!
 */
enum {
  cOOoSalUserEventClass = 'OOUE'
};

enum {
  cOOoSalEventUser = 'UEVT',
  cOOoSalEventTimer = 'EVTT',
  cOOoSalEventData = 'EVTD',
  cOOoSalEventParamTypePtr = 'EPPT'
};

/* Definition of all necessary EventTypeSpec's */

const EventTypeSpec cWindowBoundsChangedEvent = { kEventClassWindow, kEventWindowBoundsChanged };
const EventTypeSpec cWindowCloseEvent = { kEventClassWindow, kEventWindowClose };
const EventTypeSpec cOOoSalUserEvent = { cOOoSalUserEventClass, cOOoSalEventUser };
const EventTypeSpec cOOoSalTimerEvent = { cOOoSalUserEventClass, cOOoSalEventTimer };
const EventTypeSpec cWindowActivatedEvent[] = { { kEventClassWindow, kEventWindowActivated },
                                                { kEventClassWindow, kEventWindowDeactivated } };
const EventTypeSpec cWindowPaintEvent = { kEventClassWindow, kEventWindowPaint };
const EventTypeSpec cWindowDrawContentEvent = { kEventClassWindow, kEventWindowDrawContent };

const EventTypeSpec cWindowFocusEvent[] = { { kEventClassWindow, kEventWindowFocusAcquired },
                                            { kEventClassWindow, kEventWindowFocusRelinquish } };

const EventTypeSpec cMouseEnterExitEvent[] = { { kEventClassControl, kEventControlTrackingAreaEntered },
                                               { kEventClassControl, kEventControlTrackingAreaExited } };

const EventTypeSpec cMouseEvent[] = { { kEventClassMouse, kEventMouseDown },
                                      { kEventClassMouse, kEventMouseUp },
                                      { kEventClassMouse, kEventMouseMoved },
                                      { kEventClassMouse, kEventMouseDragged } };
const EventTypeSpec cMouseWheelMovedEvent = { kEventClassMouse, kEventMouseWheelMoved };
const EventTypeSpec cWindowResizeStarted = { kEventClassWindow, kEventWindowResizeStarted };
const EventTypeSpec cWindowResizeCompleted = { kEventClassWindow, kEventWindowResizeCompleted };

/* Events for native menus */
const EventTypeSpec cCommandProcessEvent = { kEventClassCommand, kEventCommandProcess };
const EventTypeSpec cMenuPopulateEvent = { kEventClassMenu, kEventMenuPopulate };
const EventTypeSpec cMenuClosedEvent = { kEventClassMenu, kEventMenuClosed };
const EventTypeSpec cMenuTargetItemEvent = { kEventClassMenu, kEventMenuTargetItem };

/* Events for keyboard */
const EventTypeSpec cKeyboardRawKeyEvents[] = { { kEventClassKeyboard, kEventRawKeyDown},
                        { kEventClassKeyboard, kEventRawKeyUp},
                        { kEventClassKeyboard, kEventRawKeyRepeat},
                        { kEventClassKeyboard, kEventRawKeyModifiersChanged} };

const EventTypeSpec cTextInputEvents[] = { { kEventClassTextInput, kEventTextInputUpdateActiveInputArea},
                                           { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent},
                                           { kEventClassTextInput, kEventTextInputOffsetToPos} };

/* Events for scrollbar */

const EventTypeSpec cAppearanceScrollbarVariantChangedEvent = { kEventClassAppearance, kEventAppearanceScrollBarVariantChanged };

#endif // INCLUDED_AQUAVCLEVENTS_HXX
<commit_msg>INTEGRATION: CWS changefileheader (1.4.168); FILE MERGED 2008/03/28 15:44:01 rt 1.4.168.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: aquavclevents.hxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef INCLUDED_AQUAVCLEVENTS_HXX
#define INCLUDED_AQUAVCLEVENTS_HXX

#include <premac.h>
#include <Carbon/Carbon.h>
#include <postmac.h>

/* Definition of custom OpenOffice.org events.

   Avoid conflict with Apple defined event class and type
   definitions by using uppercase letters. Lowercase
   letter definitions are reserved for Apple!
 */
enum {
  cOOoSalUserEventClass = 'OOUE'
};

enum {
  cOOoSalEventUser = 'UEVT',
  cOOoSalEventTimer = 'EVTT',
  cOOoSalEventData = 'EVTD',
  cOOoSalEventParamTypePtr = 'EPPT'
};

/* Definition of all necessary EventTypeSpec's */

const EventTypeSpec cWindowBoundsChangedEvent = { kEventClassWindow, kEventWindowBoundsChanged };
const EventTypeSpec cWindowCloseEvent = { kEventClassWindow, kEventWindowClose };
const EventTypeSpec cOOoSalUserEvent = { cOOoSalUserEventClass, cOOoSalEventUser };
const EventTypeSpec cOOoSalTimerEvent = { cOOoSalUserEventClass, cOOoSalEventTimer };
const EventTypeSpec cWindowActivatedEvent[] = { { kEventClassWindow, kEventWindowActivated },
                                                { kEventClassWindow, kEventWindowDeactivated } };
const EventTypeSpec cWindowPaintEvent = { kEventClassWindow, kEventWindowPaint };
const EventTypeSpec cWindowDrawContentEvent = { kEventClassWindow, kEventWindowDrawContent };

const EventTypeSpec cWindowFocusEvent[] = { { kEventClassWindow, kEventWindowFocusAcquired },
                                            { kEventClassWindow, kEventWindowFocusRelinquish } };

const EventTypeSpec cMouseEnterExitEvent[] = { { kEventClassControl, kEventControlTrackingAreaEntered },
                                               { kEventClassControl, kEventControlTrackingAreaExited } };

const EventTypeSpec cMouseEvent[] = { { kEventClassMouse, kEventMouseDown },
                                      { kEventClassMouse, kEventMouseUp },
                                      { kEventClassMouse, kEventMouseMoved },
                                      { kEventClassMouse, kEventMouseDragged } };
const EventTypeSpec cMouseWheelMovedEvent = { kEventClassMouse, kEventMouseWheelMoved };
const EventTypeSpec cWindowResizeStarted = { kEventClassWindow, kEventWindowResizeStarted };
const EventTypeSpec cWindowResizeCompleted = { kEventClassWindow, kEventWindowResizeCompleted };

/* Events for native menus */
const EventTypeSpec cCommandProcessEvent = { kEventClassCommand, kEventCommandProcess };
const EventTypeSpec cMenuPopulateEvent = { kEventClassMenu, kEventMenuPopulate };
const EventTypeSpec cMenuClosedEvent = { kEventClassMenu, kEventMenuClosed };
const EventTypeSpec cMenuTargetItemEvent = { kEventClassMenu, kEventMenuTargetItem };

/* Events for keyboard */
const EventTypeSpec cKeyboardRawKeyEvents[] = { { kEventClassKeyboard, kEventRawKeyDown},
                        { kEventClassKeyboard, kEventRawKeyUp},
                        { kEventClassKeyboard, kEventRawKeyRepeat},
                        { kEventClassKeyboard, kEventRawKeyModifiersChanged} };

const EventTypeSpec cTextInputEvents[] = { { kEventClassTextInput, kEventTextInputUpdateActiveInputArea},
                                           { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent},
                                           { kEventClassTextInput, kEventTextInputOffsetToPos} };

/* Events for scrollbar */

const EventTypeSpec cAppearanceScrollbarVariantChangedEvent = { kEventClassAppearance, kEventAppearanceScrollBarVariantChanged };

#endif // INCLUDED_AQUAVCLEVENTS_HXX
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: salcolorutils.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: pluby $ $Date: 2001-03-13 09:44:40 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SV_SALCOLORUTILS_HXX
#define _SV_SALCOLORUTILS_HXX

#ifndef _LIMITS_H
    #include <limits.h>
#endif

#include <premac.h>
#include <ApplicationServices/ApplicationServices.h>
#include <postmac.h>

#ifndef _SV_SALBTYPE_HXX
    #include <salbtype.hxx>
#endif

#ifndef _SV_SALGTYPE_HXX
    #include <salgtype.hxx>
#endif

#ifndef _SV_SALCONST_H
    #include <salconst.h>
#endif

#ifndef _SV_SALMATHUTILS_HXX
    #include <salmathutils.hxx>
#endif

// ------------------------------------------------------------------

SalColor RGBColor2SALColor ( const RGBColor *pRGBColor );

SalColor RGB8BitColor2SALColor ( const RGBColor *pRGBColor );

SalColor RGB16BitColor2SALColor ( const RGBColor *pRGBColor );

SalColor RGB32BitColor2SALColor ( const RGBColor *pRGBColor );

// ------------------------------------------------------------------

RGBColor SALColor2RGBColor ( const SalColor nSalColor );

RGBColor SALColor2RGB32bitColor ( const SalColor nSalColor );

RGBColor SALColor2RGB18bitColor ( const SalColor nSalColor );

RGBColor SALColor2RGB8bitColor ( const SalColor nSalColor );

// ------------------------------------------------------------------

SalColor GetROPSalColor ( SalROPColor nROPColor );

// ------------------------------------------------------------------

RGBColor BitmapColor2RGBColor ( const BitmapColor &rBitmapColor );

void RGBColor2BitmapColor ( const RGBColor  *rRGBColor,
                            BitmapColor     &rBitmapColor
                          );

// ------------------------------------------------------------------

short GetMinColorCount ( const short           nPixMapColorDepth,
                         const BitmapPalette  &rBitmapPalette
                       );

// ------------------------------------------------------------------

void SetBlackForeColor ( );

void SetWhiteBackColor ( );

RGBColor GetBlackColor ( );

RGBColor GetWhiteColor ( );

// ------------------------------------------------------------------

CTabHandle CopyGDeviceCTab ( );

CTabHandle GetCTabFromStdCLUT ( const short nBitDepth );

CTabHandle CopyCTabIndexed ( CTabHandle hCTab );

CTabHandle CopyCTabRGBDirect ( CTabHandle hCTab );

// ------------------------------------------------------------------

CTabHandle CopyPixMapCTab ( PixMapHandle hPixMap );

// ------------------------------------------------------------------

void SetBitmapBufferColorFormat ( const PixMapHandle   mhPixMap,
                                  BitmapBuffer        *rBuffer
                                );

// ------------------------------------------------------------------

#endif  // _SV_SALCOLORUTILS_HXX
<commit_msg>INTEGRATION: CWS ooo19126 (1.4.984); FILE MERGED 2005/09/05 14:43:33 rt 1.4.984.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: salcolorutils.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 10:32:59 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SV_SALCOLORUTILS_HXX
#define _SV_SALCOLORUTILS_HXX

#ifndef _LIMITS_H
    #include <limits.h>
#endif

#include <premac.h>
#include <ApplicationServices/ApplicationServices.h>
#include <postmac.h>

#ifndef _SV_SALBTYPE_HXX
    #include <salbtype.hxx>
#endif

#ifndef _SV_SALGTYPE_HXX
    #include <salgtype.hxx>
#endif

#ifndef _SV_SALCONST_H
    #include <salconst.h>
#endif

#ifndef _SV_SALMATHUTILS_HXX
    #include <salmathutils.hxx>
#endif

// ------------------------------------------------------------------

SalColor RGBColor2SALColor ( const RGBColor *pRGBColor );

SalColor RGB8BitColor2SALColor ( const RGBColor *pRGBColor );

SalColor RGB16BitColor2SALColor ( const RGBColor *pRGBColor );

SalColor RGB32BitColor2SALColor ( const RGBColor *pRGBColor );

// ------------------------------------------------------------------

RGBColor SALColor2RGBColor ( const SalColor nSalColor );

RGBColor SALColor2RGB32bitColor ( const SalColor nSalColor );

RGBColor SALColor2RGB18bitColor ( const SalColor nSalColor );

RGBColor SALColor2RGB8bitColor ( const SalColor nSalColor );

// ------------------------------------------------------------------

SalColor GetROPSalColor ( SalROPColor nROPColor );

// ------------------------------------------------------------------

RGBColor BitmapColor2RGBColor ( const BitmapColor &rBitmapColor );

void RGBColor2BitmapColor ( const RGBColor  *rRGBColor,
                            BitmapColor     &rBitmapColor
                          );

// ------------------------------------------------------------------

short GetMinColorCount ( const short           nPixMapColorDepth,
                         const BitmapPalette  &rBitmapPalette
                       );

// ------------------------------------------------------------------

void SetBlackForeColor ( );

void SetWhiteBackColor ( );

RGBColor GetBlackColor ( );

RGBColor GetWhiteColor ( );

// ------------------------------------------------------------------

CTabHandle CopyGDeviceCTab ( );

CTabHandle GetCTabFromStdCLUT ( const short nBitDepth );

CTabHandle CopyCTabIndexed ( CTabHandle hCTab );

CTabHandle CopyCTabRGBDirect ( CTabHandle hCTab );

// ------------------------------------------------------------------

CTabHandle CopyPixMapCTab ( PixMapHandle hPixMap );

// ------------------------------------------------------------------

void SetBitmapBufferColorFormat ( const PixMapHandle   mhPixMap,
                                  BitmapBuffer        *rBuffer
                                );

// ------------------------------------------------------------------

#endif  // _SV_SALCOLORUTILS_HXX
<|endoftext|>


<commit_before><commit_msg>Remove unused #define<commit_after><|endoftext|>


<commit_before>#include "Halide.h"

namespace {

// Compile a simple pipeline to an object and to C code.
HalideExtern_2(int, an_extern_func, int, int);

class Pipeline : public Halide::Generator<Pipeline> {
public:
    ImageParam input{UInt(16), 2, "input"};
    Func build() {
        Var x, y;

        Func f, g, h;
        f(x, y) = (input(clamp(x+2, 0, input.width()-1), clamp(y-2, 0, input.height()-1)) * 17)/13;
        h.define_extern("an_extern_stage", {f}, Int(16), 0);
        g(x, y) = f(y, x) + f(x, y) + cast<uint16_t>(an_extern_func(x, y)) + h();

        f.compute_root();
        h.compute_root();

        return g;
    }
};

Halide::RegisterGenerator<Pipeline> register_me{"pipeline"};

}  // namespace
<commit_msg>Type fix.<commit_after>#include "Halide.h"

namespace {

// Compile a simple pipeline to an object and to C code.
HalideExtern_2(int, an_extern_func, int, int);

class Pipeline : public Halide::Generator<Pipeline> {
public:
    ImageParam input{UInt(16), 2, "input"};
    Func build() {
        Var x, y;

        Func f, g, h;
        f(x, y) = (input(clamp(x+2, 0, input.width()-1), clamp(y-2, 0, input.height()-1)) * 17)/13;
        h.define_extern("an_extern_stage", {f}, Int(16), 0);
        g(x, y) = cast<uint16_t>(f(y, x) + f(x, y) + an_extern_func(x, y) + h());

        f.compute_root();
        h.compute_root();

        return g;
    }
};

Halide::RegisterGenerator<Pipeline> register_me{"pipeline"};

}  // namespace
<|endoftext|>


<commit_before>#include "LargeRAWFile.h"

using namespace std;

#define BLOCK_COPY_SIZE (UINT64(128*1024*1024))

LargeRAWFile::LargeRAWFile(const std::string& strFilename, UINT64 iHeaderSize) :
  m_strFilename(strFilename),
  m_bIsOpen(false),
  m_bWritable(false),
  m_iHeaderSize(iHeaderSize)
{
}

LargeRAWFile::LargeRAWFile(const std::wstring& wstrFilename, UINT64 iHeaderSize) :
  m_bIsOpen(false),
  m_bWritable(false),
  m_iHeaderSize(iHeaderSize)
{
  string strFilename(wstrFilename.begin(), wstrFilename.end());
  m_strFilename = strFilename;
}

LargeRAWFile::LargeRAWFile(LargeRAWFile &other) :
  m_strFilename(other.m_strFilename+"~"),
  m_bIsOpen(other.m_bIsOpen),
  m_iHeaderSize(other.m_iHeaderSize),
  m_bWritable(other.m_bWritable)
{
  if (m_bIsOpen) {
    UINT64 iDataSize = other.GetCurrentSize();
    Create(iDataSize);

    other.SeekStart();

    unsigned char* pData = new unsigned char[size_t(min(iDataSize, BLOCK_COPY_SIZE))];
    for (UINT64 i = 0;i<iDataSize;i+=BLOCK_COPY_SIZE) {
      UINT64 iCopySize = min(BLOCK_COPY_SIZE, iDataSize-i);

      other.ReadRAW(pData, iCopySize);
      WriteRAW(pData, iCopySize);
    }
    delete [] pData;
  }
}

bool LargeRAWFile::Open(bool bReadWrite) {
  #ifdef _WIN32
    m_StreamFile = CreateFileA(m_strFilename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    m_bIsOpen = m_StreamFile != INVALID_HANDLE_VALUE;
  #else
    m_StreamFile = fopen(m_strFilename.c_str(), (bReadWrite) ? "w+b" : "rb");
    m_bIsOpen = m_StreamFile != NULL;
  #endif

  if (m_bIsOpen && m_iHeaderSize != 0) SeekStart();

  m_bWritable = (m_bIsOpen) ? bReadWrite : false;

  return m_bIsOpen;
}

bool LargeRAWFile::Create(UINT64 iInitialSize) {
#ifdef _WIN32
  m_StreamFile = CreateFileA(m_strFilename.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
  m_bIsOpen = m_StreamFile != INVALID_HANDLE_VALUE;
#else
  m_StreamFile = fopen(m_strFilename.c_str(), "w+b");
  m_bIsOpen = m_StreamFile != NULL;
#endif

  if (m_bIsOpen) {
    SeekPos(iInitialSize);
    SeekStart();
  }

  return m_bIsOpen;
}

void LargeRAWFile::Close() {
  if (m_bIsOpen) {
    #ifdef _WIN32
        CloseHandle(m_StreamFile);
    #else
      fclose(m_StreamFile);
    #endif
    m_bIsOpen =false;
  }
}

UINT64 LargeRAWFile::GetCurrentSize() {
  UINT64 iPrevPos = GetPos();

  SeekStart();
  UINT64 ulStart = GetPos();
  UINT64 ulEnd   = SeekEnd();
  UINT64 ulFileLength = ulEnd - ulStart;

  SeekPos(iPrevPos);

  return ulFileLength;
}

void LargeRAWFile::SeekStart(){
  SeekPos(0);
}

UINT64 LargeRAWFile::SeekEnd(){
  #ifdef _WIN32
    LARGE_INTEGER liTarget, liRealTarget; liTarget.QuadPart = 0;
    SetFilePointerEx(m_StreamFile, liTarget, &liRealTarget, FILE_END);
    return UINT64(liRealTarget.QuadPart)-m_iHeaderSize;
  #else
    if(fseeko(m_StreamFile, 0, SEEK_END)==0)
      return ftello(m_StreamFile)-m_iHeaderSize;//get current position=file size!
    else
      return 0;
  #endif
}

UINT64 LargeRAWFile::GetPos(){
  #ifdef _WIN32
    LARGE_INTEGER liTarget, liRealTarget; liTarget.QuadPart = 0;
    SetFilePointerEx(m_StreamFile, liTarget, &liRealTarget, FILE_CURRENT);
    return UINT64(liRealTarget.QuadPart)-m_iHeaderSize;
  #else
      return ftello(m_StreamFile)-m_iHeaderSize;//get current position=file size!
  #endif
}

void LargeRAWFile::SeekPos(UINT64 iPos){
  #ifdef _WIN32
    LARGE_INTEGER liTarget; liTarget.QuadPart = LONGLONG(iPos+m_iHeaderSize);
    SetFilePointerEx(m_StreamFile, liTarget, NULL, FILE_BEGIN);
  #else
    fseeko(m_StreamFile, off_t(iPos+m_iHeaderSize), SEEK_SET);
  #endif
}

size_t LargeRAWFile::ReadRAW(unsigned char* pData, UINT64 iCount){
  #ifdef _WIN32
    DWORD dwReadBytes;
    ReadFile(m_StreamFile, pData, DWORD(iCount), &dwReadBytes, NULL);
    return dwReadBytes;
  #else
    return fread(pData,1,iCount,m_StreamFile);
  #endif
}

size_t LargeRAWFile::WriteRAW(const unsigned char* pData, UINT64 iCount){
  #ifdef _WIN32
    DWORD dwWrittenBytes;
    WriteFile(m_StreamFile, pData, DWORD(iCount), &dwWrittenBytes, NULL);
    return dwWrittenBytes;
  #else
    return fwrite(pData,1,iCount,m_StreamFile);
  #endif
}

void LargeRAWFile::Delete() {
  if (m_bIsOpen) Close();
  remove(m_strFilename.c_str());
}
<commit_msg>Fix completely ridiculous compiler warning.<commit_after>#include "LargeRAWFile.h"

using namespace std;

#define BLOCK_COPY_SIZE (UINT64(128*1024*1024))

LargeRAWFile::LargeRAWFile(const std::string& strFilename, UINT64 iHeaderSize) :
  m_strFilename(strFilename),
  m_bIsOpen(false),
  m_bWritable(false),
  m_iHeaderSize(iHeaderSize)
{
}

LargeRAWFile::LargeRAWFile(const std::wstring& wstrFilename, UINT64 iHeaderSize) :
  m_bIsOpen(false),
  m_bWritable(false),
  m_iHeaderSize(iHeaderSize)
{
  string strFilename(wstrFilename.begin(), wstrFilename.end());
  m_strFilename = strFilename;
}

LargeRAWFile::LargeRAWFile(LargeRAWFile &other) :
  m_strFilename(other.m_strFilename+"~"),
  m_bIsOpen(other.m_bIsOpen),
  m_bWritable(other.m_bWritable),
  m_iHeaderSize(other.m_iHeaderSize)
{
  if (m_bIsOpen) {
    UINT64 iDataSize = other.GetCurrentSize();
    Create(iDataSize);

    other.SeekStart();

    unsigned char* pData = new unsigned char[size_t(min(iDataSize, BLOCK_COPY_SIZE))];
    for (UINT64 i = 0;i<iDataSize;i+=BLOCK_COPY_SIZE) {
      UINT64 iCopySize = min(BLOCK_COPY_SIZE, iDataSize-i);

      other.ReadRAW(pData, iCopySize);
      WriteRAW(pData, iCopySize);
    }
    delete [] pData;
  }
}

bool LargeRAWFile::Open(bool bReadWrite) {
  #ifdef _WIN32
    m_StreamFile = CreateFileA(m_strFilename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    m_bIsOpen = m_StreamFile != INVALID_HANDLE_VALUE;
  #else
    m_StreamFile = fopen(m_strFilename.c_str(), (bReadWrite) ? "w+b" : "rb");
    m_bIsOpen = m_StreamFile != NULL;
  #endif

  if (m_bIsOpen && m_iHeaderSize != 0) SeekStart();

  m_bWritable = (m_bIsOpen) ? bReadWrite : false;

  return m_bIsOpen;
}

bool LargeRAWFile::Create(UINT64 iInitialSize) {
#ifdef _WIN32
  m_StreamFile = CreateFileA(m_strFilename.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
  m_bIsOpen = m_StreamFile != INVALID_HANDLE_VALUE;
#else
  m_StreamFile = fopen(m_strFilename.c_str(), "w+b");
  m_bIsOpen = m_StreamFile != NULL;
#endif

  if (m_bIsOpen) {
    SeekPos(iInitialSize);
    SeekStart();
  }

  return m_bIsOpen;
}

void LargeRAWFile::Close() {
  if (m_bIsOpen) {
    #ifdef _WIN32
        CloseHandle(m_StreamFile);
    #else
      fclose(m_StreamFile);
    #endif
    m_bIsOpen =false;
  }
}

UINT64 LargeRAWFile::GetCurrentSize() {
  UINT64 iPrevPos = GetPos();

  SeekStart();
  UINT64 ulStart = GetPos();
  UINT64 ulEnd   = SeekEnd();
  UINT64 ulFileLength = ulEnd - ulStart;

  SeekPos(iPrevPos);

  return ulFileLength;
}

void LargeRAWFile::SeekStart(){
  SeekPos(0);
}

UINT64 LargeRAWFile::SeekEnd(){
  #ifdef _WIN32
    LARGE_INTEGER liTarget, liRealTarget; liTarget.QuadPart = 0;
    SetFilePointerEx(m_StreamFile, liTarget, &liRealTarget, FILE_END);
    return UINT64(liRealTarget.QuadPart)-m_iHeaderSize;
  #else
    if(fseeko(m_StreamFile, 0, SEEK_END)==0)
      return ftello(m_StreamFile)-m_iHeaderSize;//get current position=file size!
    else
      return 0;
  #endif
}

UINT64 LargeRAWFile::GetPos(){
  #ifdef _WIN32
    LARGE_INTEGER liTarget, liRealTarget; liTarget.QuadPart = 0;
    SetFilePointerEx(m_StreamFile, liTarget, &liRealTarget, FILE_CURRENT);
    return UINT64(liRealTarget.QuadPart)-m_iHeaderSize;
  #else
      return ftello(m_StreamFile)-m_iHeaderSize;//get current position=file size!
  #endif
}

void LargeRAWFile::SeekPos(UINT64 iPos){
  #ifdef _WIN32
    LARGE_INTEGER liTarget; liTarget.QuadPart = LONGLONG(iPos+m_iHeaderSize);
    SetFilePointerEx(m_StreamFile, liTarget, NULL, FILE_BEGIN);
  #else
    fseeko(m_StreamFile, off_t(iPos+m_iHeaderSize), SEEK_SET);
  #endif
}

size_t LargeRAWFile::ReadRAW(unsigned char* pData, UINT64 iCount){
  #ifdef _WIN32
    DWORD dwReadBytes;
    ReadFile(m_StreamFile, pData, DWORD(iCount), &dwReadBytes, NULL);
    return dwReadBytes;
  #else
    return fread(pData,1,iCount,m_StreamFile);
  #endif
}

size_t LargeRAWFile::WriteRAW(const unsigned char* pData, UINT64 iCount){
  #ifdef _WIN32
    DWORD dwWrittenBytes;
    WriteFile(m_StreamFile, pData, DWORD(iCount), &dwWrittenBytes, NULL);
    return dwWrittenBytes;
  #else
    return fwrite(pData,1,iCount,m_StreamFile);
  #endif
}

void LargeRAWFile::Delete() {
  if (m_bIsOpen) Close();
  remove(m_strFilename.c_str());
}
<|endoftext|>


<commit_before>// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-member-init %t -- -config="{CheckOptions: [{key: "cppcoreguidelines-pro-type-member-init.UseAssignment", value: 1}]}"

struct T {
  int i;
};

struct S {
  bool b;
  // CHECK-FIXES: bool b = false;
  char c;
  // CHECK-FIXES: char c = 0;
  signed char sc;
  // CHECK-FIXES: signed char sc = 0;
  unsigned char uc;
  // CHECK-FIXES: unsigned char uc = 0U;
  int i;
  // CHECK-FIXES: int i = 0;
  unsigned u;
  // CHECK-FIXES: unsigned u = 0U;
  long l;
  // CHECK-FIXES: long l = 0L;
  unsigned long ul;
  // CHECK-FIXES: unsigned long ul = 0UL;
  long long ll;
  // CHECK-FIXES: long long ll = 0LL;
  unsigned long long ull;
  // CHECK-FIXES: unsigned long long ull = 0ULL;
  float f;
  // CHECK-FIXES: float f = 0.0F;
  double d;
  // CHECK-FIXES: double d = 0.0;
  long double ld;
  // CHECK-FIXES: double ld = 0.0L;
  int *ptr;
  // CHECK-FIXES: int *ptr = nullptr;
  T t;
  // CHECK-FIXES: T t{};
  S() {}
  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields:
};
<commit_msg>Make cppcoreguidelines-pro-type-member-init-use-assignment.cpp pass on platforms where char is unsigned<commit_after>// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-member-init %t -- -config="{CheckOptions: [{key: "cppcoreguidelines-pro-type-member-init.UseAssignment", value: 1}]}" -- -fsigned-char

struct T {
  int i;
};

struct S {
  bool b;
  // CHECK-FIXES: bool b = false;
  char c;
  // CHECK-FIXES: char c = 0;
  signed char sc;
  // CHECK-FIXES: signed char sc = 0;
  unsigned char uc;
  // CHECK-FIXES: unsigned char uc = 0U;
  int i;
  // CHECK-FIXES: int i = 0;
  unsigned u;
  // CHECK-FIXES: unsigned u = 0U;
  long l;
  // CHECK-FIXES: long l = 0L;
  unsigned long ul;
  // CHECK-FIXES: unsigned long ul = 0UL;
  long long ll;
  // CHECK-FIXES: long long ll = 0LL;
  unsigned long long ull;
  // CHECK-FIXES: unsigned long long ull = 0ULL;
  float f;
  // CHECK-FIXES: float f = 0.0F;
  double d;
  // CHECK-FIXES: double d = 0.0;
  long double ld;
  // CHECK-FIXES: double ld = 0.0L;
  int *ptr;
  // CHECK-FIXES: int *ptr = nullptr;
  T t;
  // CHECK-FIXES: T t{};
  S() {}
  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields:
};
<|endoftext|>


<commit_before>/*
 * Copyright 2015 - 2016 gtalent2@gmail.com
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
#pragma once

#include <ox/std/std.hpp>

namespace ox {
namespace fs {

using namespace ox::std;

template<typename FsT>
class FileStore {

	public:
		typedef uint16_t InodeId_t;
		typedef FsT FsSize_t;

		struct StatInfo {
			InodeId_t inodeId;
			FsSize_t  size;
		};

	private:
		struct Inode {
			// the next Inode in memory
			FsSize_t prev, next;

			// The following variables should not be assumed to exist
			FsSize_t dataLen;
			InodeId_t m_id;
			uint8_t refs;
			FsSize_t left, right;

			FsSize_t size();
			void setId(InodeId_t);
			void setData(void *data, int size);
			void *data();

			private:
				Inode() = default;
		};

		uint32_t m_version;
		FsSize_t m_size;
		FsSize_t m_firstInode;
		FsSize_t m_rootInode;

	public:
		/**
		 * Initializes the memory chunk of this FileStore was given.
		 * This clears the previous contents.
		 */
		void init();

		/**
		 * Writes the given data to a "file" with the given id.
		 * @param id the id of the file
		 * @param data the contents of the file
		 * @param dataLen the number of bytes data points to
		 */
		int write(void *data, FsSize_t dataLen);

		/**
		 * Writes the given data to a "file" with the given id.
		 * @param id the id of the file
		 * @param data the contents of the file
		 * @param dataLen the number of bytes data points to
		 */
		int write(InodeId_t id, void *data, FsSize_t dataLen);

		/**
		 * Reads the "file" at the given id. You are responsible for freeing
		 * the data when done with it.
		 * @param id id of the "file"
		 * @param data pointer to the pointer where the data is stored
		 * @param size pointer to a value that will be assigned the size of data
		 * @return 0 if read is a success
		 */
		int read(InodeId_t id, void *data, FsSize_t *size);

		/**
		 * Reads the stat information of the inode of the given inode id.
		 * If the returned inode id is 0, then the requested inode was not found.
		 * @param id id of the inode to stat
		 * @return the stat information of the inode of the given inode id
		 */
		StatInfo stat(InodeId_t id);

		static uint8_t version();

		static uint8_t *format(uint8_t *buffer, FsSize_t size);

	private:
		/**
		 * Gets the inode at the given id.
		 * @param root the root node to start comparing on
		 * @param id id of the "file"
		 * @param pathLen number of characters in pathLen
		 * @return the requested Inode, if available
		 */
		Inode *getInode(Inode *root, InodeId_t id);

		/**
		 * Gets an address for a new Inode.
		 * @param size the size of the Inode
		 */
		void *alloc(FsSize_t size);

		/**
		 * Compresses all of the inode into a contiguous space, starting at m_firstInode.
		 */
		void compress();

		/**
		 * Inserts the given insertValue into the tree of the given root.
		 * If the inode already exists, it replaces the old on deletes it.
		 * @return true if the inode was inserted
		 */
		bool insert(Inode *root, Inode *insertValue);

		/**
		 * Gets the FsSize_t associated with the next Inode to be allocated.
		 * @retrun the FsSize_t associated with the next Inode to be allocated
		 */
		FsSize_t iterator();

		Inode *firstInode();

		Inode *lastInode();

		uint8_t *begin() {
			return (uint8_t*) this;
		}

		uint8_t *end() {
			return begin() + this->m_size;
		}

		/**
		 * Converts an actual pointer to a FsSize_t.
		 */
		FsSize_t ptr(void *ptr);

		/**
		 * Converts a FsSize_t to an actual pointer.
		 */
		template<typename T>
		T ptr(FsSize_t ptr) {
			return (T) (begin() + ptr);
		};

};

template<typename FsSize_t>
FsSize_t FileStore<FsSize_t>::Inode::size() {
	return sizeof(Inode) + dataLen;
}

template<typename FsSize_t>
void FileStore<FsSize_t>::Inode::setId(InodeId_t id) {
	this->m_id = id;
}

template<typename FsSize_t>
void FileStore<FsSize_t>::Inode::setData(void *data, int size) {
	memcpy(this->data(), data, size);
	dataLen = size;
}

template<typename FsSize_t>
void *FileStore<FsSize_t>::Inode::data() {
	return this + 1;
}

// FileStore

template<typename FsSize_t>
int FileStore<FsSize_t>::write(void *data, FsSize_t dataLen) {
	return 1;
}

template<typename FsSize_t>
int FileStore<FsSize_t>::write(InodeId_t id, void *data, FsSize_t dataLen) {
	auto retval = 1;
	const FsSize_t size = sizeof(Inode) + dataLen;
	auto inode = (Inode*) alloc(size);
	if (inode) {
		auto root = ptr<Inode*>(m_rootInode);
		inode->m_id = id;
		inode->setData(data, dataLen);
		if (insert(root, inode) || root == inode) {
			retval = 0;
		}
	}
	return retval;
}

template<typename FsSize_t>
int FileStore<FsSize_t>::read(InodeId_t id, void *data, FsSize_t *size) {
	auto inode = getInode(ptr<Inode*>(m_rootInode), id);
	int retval = 1;
	if (inode) {
		if (size) {
			*size = inode->dataLen;
		}
		memcpy(data, inode->data(), inode->dataLen);
		retval = 0;
	}
	return retval;
}

template<typename FsSize_t>
typename FileStore<FsSize_t>::StatInfo FileStore<FsSize_t>::stat(InodeId_t id) {
	auto inode = getInode(ptr<Inode*>(m_rootInode), id);
	StatInfo stat;
	if (inode) {
		stat.size = inode->dataLen;
		stat.inodeId = id;
	} else {
		stat.inodeId = 0;
	}
	return stat;
}

template<typename FsSize_t>
typename FileStore<FsSize_t>::Inode *FileStore<FsSize_t>::getInode(Inode *root, InodeId_t id) {
	Inode *retval = nullptr;

	if (root->m_id > id) {
		if (root->left) {
			retval = getInode(ptr<Inode*>(root->left), id);
		}
	} else if (root->m_id < id) {
		if (root->right) {
			retval = getInode(ptr<Inode*>(root->right), id);
		}
	} else if (root->m_id == id) {
		retval = root;
	}

	return retval;
}

template<typename FsSize_t>
void *FileStore<FsSize_t>::alloc(FsSize_t size) {
	if ((lastInode()->next + size) > (uint64_t) end()) {
		compress();
		if ((lastInode()->next + size) > (uint64_t) end()) {
			return nullptr;
		}
	}

	const auto retval = lastInode()->next;
	const auto inode = ptr<Inode*>(retval);
	memset(inode, 0, size);
	inode->next = retval + size;
	ptr<Inode*>(m_firstInode)->prev = retval;
	return inode;
}

template<typename FsSize_t>
void FileStore<FsSize_t>::compress() {
	auto current = ptr<Inode*>(m_firstInode);
	while (current->next) {
		auto prevEnd = current + current->size();
		current = ptr<Inode*>(current->next);
		if (prevEnd != current) {
			memcpy(prevEnd, current, current->size());
			current = prevEnd;
		}
	}
}

template<typename FsSize_t>
bool FileStore<FsSize_t>::insert(Inode *root, Inode *insertValue) {
	auto retval = false;

	if (root->m_id > insertValue->m_id) {
		if (root->left) {
			retval = insert(ptr<Inode*>(root->left), insertValue);
		} else {
			root->left = ptr(insertValue);
			retval = true;
		}
	} else if (root->m_id < insertValue->m_id) {
		if (root->right) {
			retval = insert(ptr<Inode*>(root->right), insertValue);
		} else {
			root->right = ptr(insertValue);
			retval = true;
		}
	}

	return retval;
}

template<typename FsSize_t>
FsSize_t FileStore<FsSize_t>::iterator() {
	return ptr(lastInode()) + lastInode()->size();
}

template<typename FsSize_t>
FsSize_t FileStore<FsSize_t>::ptr(void *ptr) {
	return ((uint8_t*) ptr) - begin();
}

template<typename FsSize_t>
typename FileStore<FsSize_t>::Inode *FileStore<FsSize_t>::firstInode() {
	return ptr<Inode*>(sizeof(FileStore<FsSize_t>));
}

template<typename FsSize_t>
typename FileStore<FsSize_t>::Inode *FileStore<FsSize_t>::lastInode() {
	return ptr<Inode*>(ptr<Inode*>(m_firstInode)->prev);
}

template<typename FsSize_t>
uint8_t FileStore<FsSize_t>::version() {
	return 0;
};

template<typename FsSize_t>
uint8_t *FileStore<FsSize_t>::format(uint8_t *buffer, FsSize_t size) {
	memset(buffer, 0, size);

	auto *fs = (FileStore*) buffer;
	fs->m_version = FileStore<FsSize_t>::version();
	fs->m_size = size;
	fs->m_rootInode = sizeof(FileStore<FsSize_t>);
	fs->m_firstInode = sizeof(FileStore<FsSize_t>);
	fs->lastInode()->m_id = 0;
	fs->lastInode()->next = sizeof(FileStore<FsSize_t>);

	return (uint8_t*) buffer;
}

typedef FileStore<uint16_t> FileStore16;
typedef FileStore<uint32_t> FileStore32;
typedef FileStore<uint64_t> FileStore64;

}
}
<commit_msg>Fixed tracking last inode.<commit_after>/*
 * Copyright 2015 - 2016 gtalent2@gmail.com
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
#pragma once

#include <ox/std/std.hpp>

namespace ox {
namespace fs {

using namespace ox::std;

template<typename FsT>
class FileStore {

	public:
		typedef uint16_t InodeId_t;
		typedef FsT FsSize_t;

		struct StatInfo {
			InodeId_t inodeId;
			FsSize_t  size;
		};

	private:
		struct Inode {
			// the next Inode in memory
			FsSize_t prev, next;

			// The following variables should not be assumed to exist
			FsSize_t dataLen;
			InodeId_t m_id;
			uint8_t refs;
			FsSize_t left, right;

			FsSize_t size();
			void setId(InodeId_t);
			void setData(void *data, int size);
			void *data();

			private:
				Inode() = default;
		};

		uint32_t m_version;
		FsSize_t m_size;
		FsSize_t m_firstInode;
		FsSize_t m_rootInode;

	public:
		/**
		 * Initializes the memory chunk of this FileStore was given.
		 * This clears the previous contents.
		 */
		void init();

		/**
		 * Writes the given data to a "file" with the given id.
		 * @param id the id of the file
		 * @param data the contents of the file
		 * @param dataLen the number of bytes data points to
		 */
		int write(void *data, FsSize_t dataLen);

		/**
		 * Writes the given data to a "file" with the given id.
		 * @param id the id of the file
		 * @param data the contents of the file
		 * @param dataLen the number of bytes data points to
		 */
		int write(InodeId_t id, void *data, FsSize_t dataLen);

		/**
		 * Reads the "file" at the given id. You are responsible for freeing
		 * the data when done with it.
		 * @param id id of the "file"
		 * @param data pointer to the pointer where the data is stored
		 * @param size pointer to a value that will be assigned the size of data
		 * @return 0 if read is a success
		 */
		int read(InodeId_t id, void *data, FsSize_t *size);

		/**
		 * Reads the stat information of the inode of the given inode id.
		 * If the returned inode id is 0, then the requested inode was not found.
		 * @param id id of the inode to stat
		 * @return the stat information of the inode of the given inode id
		 */
		StatInfo stat(InodeId_t id);

		static uint8_t version();

		static uint8_t *format(uint8_t *buffer, FsSize_t size);

	private:
		/**
		 * Gets the inode at the given id.
		 * @param root the root node to start comparing on
		 * @param id id of the "file"
		 * @param pathLen number of characters in pathLen
		 * @return the requested Inode, if available
		 */
		Inode *getInode(Inode *root, InodeId_t id);

		/**
		 * Gets an address for a new Inode.
		 * @param size the size of the Inode
		 */
		void *alloc(FsSize_t size);

		/**
		 * Compresses all of the inode into a contiguous space, starting at m_firstInode.
		 */
		void compress();

		/**
		 * Inserts the given insertValue into the tree of the given root.
		 * If the inode already exists, it replaces the old on deletes it.
		 * @return true if the inode was inserted
		 */
		bool insert(Inode *root, Inode *insertValue);

		/**
		 * Gets the FsSize_t associated with the next Inode to be allocated.
		 * @retrun the FsSize_t associated with the next Inode to be allocated
		 */
		FsSize_t iterator();

		Inode *firstInode();

		Inode *lastInode();

		uint8_t *begin() {
			return (uint8_t*) this;
		}

		uint8_t *end() {
			return begin() + this->m_size;
		}

		/**
		 * Converts an actual pointer to a FsSize_t.
		 */
		FsSize_t ptr(void *ptr);

		/**
		 * Converts a FsSize_t to an actual pointer.
		 */
		template<typename T>
		T ptr(FsSize_t ptr) {
			return (T) (begin() + ptr);
		};

};

template<typename FsSize_t>
FsSize_t FileStore<FsSize_t>::Inode::size() {
	return sizeof(Inode) + dataLen;
}

template<typename FsSize_t>
void FileStore<FsSize_t>::Inode::setId(InodeId_t id) {
	this->m_id = id;
}

template<typename FsSize_t>
void FileStore<FsSize_t>::Inode::setData(void *data, int size) {
	memcpy(this->data(), data, size);
	dataLen = size;
}

template<typename FsSize_t>
void *FileStore<FsSize_t>::Inode::data() {
	return this + 1;
}

// FileStore

template<typename FsSize_t>
int FileStore<FsSize_t>::write(void *data, FsSize_t dataLen) {
	return 1;
}

template<typename FsSize_t>
int FileStore<FsSize_t>::write(InodeId_t id, void *data, FsSize_t dataLen) {
	auto retval = 1;
	const FsSize_t size = sizeof(Inode) + dataLen;
	//printf("%d\n", m_rootInode);
	auto inode = (Inode*) alloc(size);
	if (inode) {
		auto root = ptr<Inode*>(m_rootInode);
		inode->m_id = id;
		inode->setData(data, dataLen);
		if (insert(root, inode) || root == inode) {
			retval = 0;
		}
	}
	return retval;
}

template<typename FsSize_t>
int FileStore<FsSize_t>::read(InodeId_t id, void *data, FsSize_t *size) {
	auto inode = getInode(ptr<Inode*>(m_rootInode), id);
	int retval = 1;
	if (inode) {
		if (size) {
			*size = inode->dataLen;
		}
		memcpy(data, inode->data(), inode->dataLen);
		retval = 0;
	}
	return retval;
}

template<typename FsSize_t>
typename FileStore<FsSize_t>::StatInfo FileStore<FsSize_t>::stat(InodeId_t id) {
	auto inode = getInode(ptr<Inode*>(m_rootInode), id);
	StatInfo stat;
	if (inode) {
		stat.size = inode->dataLen;
		stat.inodeId = id;
	} else {
		stat.inodeId = 0;
	}
	return stat;
}

template<typename FsSize_t>
typename FileStore<FsSize_t>::Inode *FileStore<FsSize_t>::getInode(Inode *root, InodeId_t id) {
	Inode *retval = nullptr;

	if (root->m_id > id) {
		if (root->left) {
			retval = getInode(ptr<Inode*>(root->left), id);
		}
	} else if (root->m_id < id) {
		if (root->right) {
			retval = getInode(ptr<Inode*>(root->right), id);
		}
	} else if (root->m_id == id) {
		retval = root;
	}

	return retval;
}

template<typename FsSize_t>
void *FileStore<FsSize_t>::alloc(FsSize_t size) {
	if ((lastInode()->next + size) > (uint64_t) end()) {
		compress();
		if ((lastInode()->next + size) > (uint64_t) end()) {
			return nullptr;
		}
	}

	const auto retval = lastInode()->next;
	const auto inode = ptr<Inode*>(retval);
	memset(inode, 0, size);
	inode->next = retval + size;
	ptr<Inode*>(m_firstInode)->prev = retval;
	return inode;
}

template<typename FsSize_t>
void FileStore<FsSize_t>::compress() {
	auto current = ptr<Inode*>(m_firstInode);
	while (current->next) {
		auto prevEnd = current + current->size();
		current = ptr<Inode*>(current->next);
		if (prevEnd != current) {
			memcpy(prevEnd, current, current->size());
			current = prevEnd;
		}
	}
}

template<typename FsSize_t>
bool FileStore<FsSize_t>::insert(Inode *root, Inode *insertValue) {
	auto retval = false;

	if (root->m_id > insertValue->m_id) {
		if (root->left) {
			retval = insert(ptr<Inode*>(root->left), insertValue);
		} else {
			root->left = ptr(insertValue);
			retval = true;
		}
	} else if (root->m_id < insertValue->m_id) {
		if (root->right) {
			retval = insert(ptr<Inode*>(root->right), insertValue);
		} else {
			root->right = ptr(insertValue);
			retval = true;
		}
	}

	return retval;
}

template<typename FsSize_t>
FsSize_t FileStore<FsSize_t>::iterator() {
	return ptr(lastInode()) + lastInode()->size();
}

template<typename FsSize_t>
FsSize_t FileStore<FsSize_t>::ptr(void *ptr) {
	return ((uint8_t*) ptr) - begin();
}

template<typename FsSize_t>
typename FileStore<FsSize_t>::Inode *FileStore<FsSize_t>::firstInode() {
	return ptr<Inode*>(sizeof(FileStore<FsSize_t>));
}

template<typename FsSize_t>
typename FileStore<FsSize_t>::Inode *FileStore<FsSize_t>::lastInode() {
	return ptr<Inode*>(ptr<Inode*>(m_firstInode)->prev);
}

template<typename FsSize_t>
uint8_t FileStore<FsSize_t>::version() {
	return 0;
};

template<typename FsSize_t>
uint8_t *FileStore<FsSize_t>::format(uint8_t *buffer, FsSize_t size) {
	memset(buffer, 0, size);

	auto *fs = (FileStore*) buffer;
	fs->m_version = FileStore<FsSize_t>::version();
	fs->m_size = size;
	fs->m_rootInode = sizeof(FileStore<FsSize_t>);
	fs->m_firstInode = sizeof(FileStore<FsSize_t>);
	fs->firstInode()->prev = fs->m_firstInode;
	fs->lastInode()->next = sizeof(FileStore<FsSize_t>);

	return (uint8_t*) buffer;
}

typedef FileStore<uint16_t> FileStore16;
typedef FileStore<uint32_t> FileStore32;
typedef FileStore<uint64_t> FileStore64;

}
}
<|endoftext|>


<commit_before>/*
 * Use and distribution licensed under the Apache license version 2.
 *
 * See the COPYING file in the root project directory for full text.
 */

#include <iostream>
#include <cctype>
#include <sstream>

#include "parser/error.h"
#include "parser/parse.h"
#include "parser/symbol.h"
#include "parser/token.h"

namespace sqltoast {

static const size_t NUM_CREATE_STATEMENT_PARSERS = 2;
static const parse_func_t create_statement_parsers[2] = {
    &parse_create_table,
    &parse_create_schema
};
static const size_t NUM_DROP_STATEMENT_PARSERS = 2;
static const parse_func_t drop_statement_parsers[2] = {
    &parse_drop_table,
    &parse_drop_schema
};
static const size_t NUM_DELETE_STATEMENT_PARSERS = 1;
static const parse_func_t delete_statement_parsers[1] = {
    &parse_delete
};
static const size_t NUM_SELECT_STATEMENT_PARSERS = 1;
static const parse_func_t select_statement_parsers[1] = {
    &parse_select
};
static const size_t NUM_INSERT_STATEMENT_PARSERS = 1;
static const parse_func_t insert_statement_parsers[1] = {
    &parse_insert
};
static const size_t NUM_UPDATE_STATEMENT_PARSERS = 1;
static const parse_func_t update_statement_parsers[1] = {
    &parse_update
};

void parse_statement(parse_context_t& ctx) {
    // Assumption: the current token will be a keyword
    lexer_t& lex = ctx.lexer;
    token_t& cur_tok = lex.current_token;
    symbol_t cur_sym = cur_tok.symbol;
    std::unique_ptr<statement_t> stmt_p;

    size_t num_parsers = 0;
    const parse_func_t* parsers;
    switch (cur_sym) {
        case SYMBOL_CREATE:
        {
            num_parsers = NUM_CREATE_STATEMENT_PARSERS;
            parsers = create_statement_parsers;
            break;
        }
        case SYMBOL_DELETE:
        {
            num_parsers = NUM_DELETE_STATEMENT_PARSERS;
            parsers = delete_statement_parsers;
            break;
        }
        case SYMBOL_DROP:
        {
            num_parsers = NUM_DROP_STATEMENT_PARSERS;
            parsers = drop_statement_parsers;
            break;
        }
        case SYMBOL_SELECT:
        {
            num_parsers = NUM_SELECT_STATEMENT_PARSERS;
            parsers = select_statement_parsers;
            break;
        }
        case SYMBOL_INSERT:
        {
            num_parsers = NUM_INSERT_STATEMENT_PARSERS;
            parsers = insert_statement_parsers;
            break;
        }
        case SYMBOL_UPDATE:
        {
            num_parsers = NUM_UPDATE_STATEMENT_PARSERS;
            parsers = update_statement_parsers;
            break;
        }
        default:
            return;
    }

    size_t x = 0;
    while (ctx.result.code == PARSE_OK && x < num_parsers) {
        if (parsers[x++](ctx, cur_tok, stmt_p))
            goto push_statement;
    }
    if (ctx.result.code == PARSE_SYNTAX_ERROR) {
        // Already have a nicely-formatted error, so just return
        return;
    } else {
        std::stringstream estr;
        estr << "Failed to recognize any valid SQL statement." << std::endl;
        create_syntax_error_marker(ctx, estr);
    }
push_statement:
    if (ctx.opts.disable_statement_construction)
        return;
    ctx.result.statements.emplace_back(std::move(stmt_p));
}

} // namespace sqltoast
<commit_msg>link in alter table parser into parse_statement()<commit_after>/*
 * Use and distribution licensed under the Apache license version 2.
 *
 * See the COPYING file in the root project directory for full text.
 */

#include <iostream>
#include <cctype>
#include <sstream>

#include "parser/error.h"
#include "parser/parse.h"
#include "parser/symbol.h"
#include "parser/token.h"

namespace sqltoast {

static const size_t NUM_ALTER_STATEMENT_PARSERS = 1;
static const parse_func_t alter_statement_parsers[1] = {
    &parse_alter_table
};
static const size_t NUM_CREATE_STATEMENT_PARSERS = 2;
static const parse_func_t create_statement_parsers[2] = {
    &parse_create_table,
    &parse_create_schema
};
static const size_t NUM_DROP_STATEMENT_PARSERS = 2;
static const parse_func_t drop_statement_parsers[2] = {
    &parse_drop_table,
    &parse_drop_schema
};
static const size_t NUM_DELETE_STATEMENT_PARSERS = 1;
static const parse_func_t delete_statement_parsers[1] = {
    &parse_delete
};
static const size_t NUM_SELECT_STATEMENT_PARSERS = 1;
static const parse_func_t select_statement_parsers[1] = {
    &parse_select
};
static const size_t NUM_INSERT_STATEMENT_PARSERS = 1;
static const parse_func_t insert_statement_parsers[1] = {
    &parse_insert
};
static const size_t NUM_UPDATE_STATEMENT_PARSERS = 1;
static const parse_func_t update_statement_parsers[1] = {
    &parse_update
};

void parse_statement(parse_context_t& ctx) {
    // Assumption: the current token will be a keyword
    lexer_t& lex = ctx.lexer;
    token_t& cur_tok = lex.current_token;
    symbol_t cur_sym = cur_tok.symbol;
    std::unique_ptr<statement_t> stmt_p;

    size_t num_parsers = 0;
    const parse_func_t* parsers;
    switch (cur_sym) {
        case SYMBOL_ALTER:
        {
            num_parsers = NUM_ALTER_STATEMENT_PARSERS;
            parsers = alter_statement_parsers;
            break;
        }
        case SYMBOL_CREATE:
        {
            num_parsers = NUM_CREATE_STATEMENT_PARSERS;
            parsers = create_statement_parsers;
            break;
        }
        case SYMBOL_DELETE:
        {
            num_parsers = NUM_DELETE_STATEMENT_PARSERS;
            parsers = delete_statement_parsers;
            break;
        }
        case SYMBOL_DROP:
        {
            num_parsers = NUM_DROP_STATEMENT_PARSERS;
            parsers = drop_statement_parsers;
            break;
        }
        case SYMBOL_SELECT:
        {
            num_parsers = NUM_SELECT_STATEMENT_PARSERS;
            parsers = select_statement_parsers;
            break;
        }
        case SYMBOL_INSERT:
        {
            num_parsers = NUM_INSERT_STATEMENT_PARSERS;
            parsers = insert_statement_parsers;
            break;
        }
        case SYMBOL_UPDATE:
        {
            num_parsers = NUM_UPDATE_STATEMENT_PARSERS;
            parsers = update_statement_parsers;
            break;
        }
        default:
        {
            std::stringstream estr;
            estr << "Failed to recognize any valid SQL statement." << std::endl;
            create_syntax_error_marker(ctx, estr);
            return;
        }
    }

    size_t x = 0;
    while (ctx.result.code == PARSE_OK && x < num_parsers) {
        if (parsers[x++](ctx, cur_tok, stmt_p))
            goto push_statement;
    }
    if (ctx.result.code == PARSE_SYNTAX_ERROR) {
        // Already have a nicely-formatted error, so just return
        return;
    } else {
        std::stringstream estr;
        estr << "Failed to recognize any valid SQL statement." << std::endl;
        create_syntax_error_marker(ctx, estr);
    }
push_statement:
    if (ctx.opts.disable_statement_construction)
        return;
    ctx.result.statements.emplace_back(std::move(stmt_p));
}

} // namespace sqltoast
<|endoftext|>