<commit_before>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (C) 2008 Sacha Schutz <istdasklar@free.fr>
 * Copyright (C) 2010 Kim Jung Nissen <jungnissen@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "detectlinux.h"

#include "inputthread.h"
#include "detectlinuxprivate.h"

#include <core/debughelper.h>

#include <QtCore/QDir>
#include <QtCore/QCoreApplication>
#include <QtGui/QMessageBox>
#include <QtCore/QDebug>

// #include <libudev.h>

using namespace GluonInput;

DetectLinux::DetectLinux( QObject* parent )
    : Detect( parent )
    , d( new DetectLinuxPrivate )
{
}

DetectLinux::~DetectLinux()
{
    //    kDebug()<<"clear device...";
    //    foreach ( KCLInput * input, m_inputList)
    //    {
    //        delete input;
    //    }
}

bool DetectLinux::isReadable()
{
    QDir event( "/dev/input/by-path/" );
    QStringList readableInputFiles;
    QStringList unreadableInputFiles;
    QString file;
    QFileInfoList inputFileInfoList;

    inputFileInfoList = event.entryInfoList( QDir::Files );
    foreach( QFileInfo inputFileInfo, inputFileInfoList )
    {
        file = inputFileInfo.filePath();
        if( access( file.toUtf8(), R_OK ) != -1 )
            readableInputFiles.append( file );
        else
            unreadableInputFiles.append( file );
    }

    return unreadableInputFiles.isEmpty();
}

void DetectLinux::detectDevices()
{
    DetectLinux* detect = this;
    detect->clear();
    QDir event( "/dev/input/by-path/" );
    QStringList readableInputFiles;
    QStringList unreadableInputFiles;
    QString file;
    QFileInfoList inputFileInfoList;
    QList<struct input_id> processedInputs;
    // bool processed;

    // struct udev *udev;
    // struct udev_enumerate *enumerate;
    // struct udev_list_entry *devices;
    // struct udev_list_entry *dev_list_entry;
    // struct udev_device *dev;
    // struct udev_device *parent_dev;
    // struct input_id currentInputDeviceInfo;

    inputFileInfoList = event.entryInfoList( QDir::Files );
    foreach( const QFileInfo& inputFileInfo, inputFileInfoList )
    {
        if( inputFileInfo.isReadable() )
            readableInputFiles.append( file );
        else
            unreadableInputFiles.append( file );
    }

    foreach( const QString & name, readableInputFiles )
    {
        InputDevice* device = 0;
        InputThread* thread = new InputThread( name );
        if( !thread->error() )
        {
            switch( thread->deviceType() )
            {
            case GluonInput::KeyboardDevice:
                device = new Keyboard( thread );
                detect->addKeyboard( static_cast<Keyboard*>( device ) );
                break;

            case GluonInput::MouseDevice:
                device = new Mouse( thread );
                detect->addMouse( static_cast<Mouse*>( device ) );
                break;

            case GluonInput::TouchpadDevice:
                device = new Mouse( thread );
                detect->addMouse( static_cast<Mouse*>( device ) );
                break;

            case GluonInput::JoystickDevice:
                device = new Joystick( thread );
                detect->addJoystick( static_cast<Joystick*>( device ) );
                break;

            case GluonInput::TouchDevice:
                device = new Touch( thread );
                detect->addTouch( static_cast<Touch*>( device ) );
                break;

            case GluonInput::UnknownDevice:
                device = new InputDevice( thread );
                detect->addUnknown( device );
                break;
            }

            processedInputs.append( thread->device_info() );
            detect->addInput( device );
        }
    }
    // }
    // #ifdef 0
    // [> Create the udev object <]
    // udev = udev_new();
    // if (!udev)
    // qWarning() << "Cannot create udev" << endl;

    // [> Create a list of the devices in the 'hidraw' subsystem. <]
    // enumerate = udev_enumerate_new(udev);
    // udev_enumerate_add_match_subsystem(enumerate, "input");
    // udev_enumerate_scan_devices(enumerate);
    // devices = udev_enumerate_get_list_entry(enumerate);
    /* For each item enumerated, print out its information.
     * udev_list_entry_foreach is a macro which expands to
     * a loop. The loop will be executed for each member in
     * devices, setting dev_list_entry to a list entry
     * which contains the device's path in /sys.
     */
    // udev_list_entry_foreach(dev_list_entry, devices) {
    // const char *path;

    // [> Get the filename of the /sys entry for the device
    // and create a udev_device object (dev) representing it */
    // path = udev_list_entry_get_name(dev_list_entry);
    // dev = udev_device_new_from_syspath(udev, path);

    // parent_dev = udev_device_get_parent_with_subsystem_devtype(dev, "input", 0);
    // if (parent_dev) {
    // udev_device_unref(parent_dev);
    // continue;
    // }

    // if (udev_device_get_sysattr_value(dev, "id/bustype"))
    // currentInputDeviceInfo.bustype = atoi(udev_device_get_sysattr_value(dev, "id/bustype"));
    // if (udev_device_get_sysattr_value(dev, "id/vendor"))
    // currentInputDeviceInfo.vendor = atoi(udev_device_get_sysattr_value(dev,"id/vendor"));
    // if (udev_device_get_sysattr_value(dev, "id/product"))
    // currentInputDeviceInfo.product = atoi(udev_device_get_sysattr_value(dev, "id/product"));
    // if (udev_device_get_sysattr_value(dev, "id/version"))
    // currentInputDeviceInfo.version = atoi(udev_device_get_sysattr_value(dev, "id/version"));

    /* The input device has been already processed, has read access
     * credential
     */
    // processed = false;
    // foreach(struct input_id inputID, processedInputs) {
    // if (inputID.bustype == currentInputDeviceInfo.bustype
    // && inputID.vendor == currentInputDeviceInfo.vendor
    // && inputID.product == currentInputDeviceInfo.product
    // && inputID.version == currentInputDeviceInfo.version) {
    // processed = true;
    // break;
    // }
    // }

    // if (processed)
    // continue;

    // InputDevice *device = 0;
    // InputThread *thread = new InputThread(dev);
    // if (!thread->error()) {
    // switch (thread->deviceType()) {
    // case GluonInput::KeyboardDevice:
    // device = new Keyboard(thread);
    // detect->addKeyboard(static_cast<Keyboard *>(device));
    // break;

    // case GluonInput::MouseDevice:
    // device = new Mouse(thread);
    // detect->addMouse(static_cast<Mouse *>(device));
    // break;

    // case GluonInput::TouchpadDevice:
    // device = new Mouse(thread);
    // detect->addMouse(static_cast<Mouse *>(device));
    // break;

    // case GluonInput::JoystickDevice:
    // device = new Joystick(thread);
    // detect->addJoystick(static_cast<Joystick *>(device));
    // break;

    // case GluonInput::TouchDevice:
    // device = new Touch(thread);
    // detect->addTouch(static_cast<Touch *>(device));
    // break;

    // case GluonInput::UnknownDevice:
    // device = new InputDevice(thread);
    // detect->addUnknown(device);
    // break;
    // }

    // detect->addInput(device);
    // }
    // }

    // [> Free the enumerator object <]
    // udev_enumerate_unref(enumerate);

    // udev_unref(udev);
    // #endif
}

void DetectLinux::setAllEnabled( bool enable )
{
    foreach( InputDevice * input, inputList() )
    {
        input->setEnabled( enable );
    }
}

void DetectLinux::clear()
{
    d->inputList.clear();
    d->keyboardList.clear();
    d->mouseList.clear();
    d->joystickList.clear();
    d->touchList.clear();
    d->unknownList.clear();
}

void DetectLinux::addInput( InputDevice* i )
{
    d->inputList.append( i );
}

void DetectLinux::addKeyboard( Keyboard* keyboard )
{
    d->keyboardList.append( keyboard );
}

void DetectLinux::addMouse( Mouse* mouse )
{
    d->mouseList.append( mouse );
}

void DetectLinux::addJoystick( Joystick* joystick )
{
    d->joystickList.append( joystick );
}

void DetectLinux::addTouch( Touch* touch )
{
    d->touchList.append( touch );
}

void DetectLinux::addUnknown( InputDevice* i )
{
    d->unknownList.append( i );
}

QList<InputDevice*> DetectLinux::inputList()
{
    return d->inputList;
}

QList<Keyboard*> DetectLinux::keyboardList()
{
    return d->keyboardList;
}

QList<Mouse*> DetectLinux::mouseList()
{
    return d->mouseList;
}

QList<Joystick*> DetectLinux::joystickList()
{
    return d->joystickList;
}

QList<Touch*> DetectLinux::touchList()
{
    return d->touchList;
}

QList<InputDevice*> DetectLinux::unknownDeviceList()
{
    return d->unknownList;
}

#include "detectlinux.moc"
<commit_msg>Fix the low-level linux inputmanagement and the file name culprit.<commit_after>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (C) 2008 Sacha Schutz <istdasklar@free.fr>
 * Copyright (C) 2010 Kim Jung Nissen <jungnissen@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "detectlinux.h"

#include "inputthread.h"
#include "detectlinuxprivate.h"

#include <core/debughelper.h>

#include <QtCore/QDir>
#include <QtCore/QCoreApplication>
#include <QtGui/QMessageBox>
#include <QtCore/QDebug>

// #include <libudev.h>

using namespace GluonInput;

DetectLinux::DetectLinux( QObject* parent )
    : Detect( parent )
    , d( new DetectLinuxPrivate )
{
}

DetectLinux::~DetectLinux()
{
    //    kDebug()<<"clear device...";
    //    foreach ( KCLInput * input, m_inputList)
    //    {
    //        delete input;
    //    }
}

bool DetectLinux::isReadable()
{
    QDir event( "/dev/input/by-path/" );
    QStringList readableInputFiles;
    QStringList unreadableInputFiles;
    QString file;
    QFileInfoList inputFileInfoList;

    inputFileInfoList = event.entryInfoList( QDir::Files );
    foreach( QFileInfo inputFileInfo, inputFileInfoList )
    {
        file = inputFileInfo.filePath();
        if( access( file.toUtf8(), R_OK ) != -1 )
            readableInputFiles.append( file );
        else
            unreadableInputFiles.append( file );
    }

    return unreadableInputFiles.isEmpty();
}

void DetectLinux::detectDevices()
{
    DetectLinux* detect = this;
    detect->clear();
    QDir event( "/dev/input/by-path/" );
    QStringList readableInputFiles;
    QStringList unreadableInputFiles;
    QString file;
    QFileInfoList inputFileInfoList;
    QList<struct input_id> processedInputs;
    // bool processed;

    // struct udev *udev;
    // struct udev_enumerate *enumerate;
    // struct udev_list_entry *devices;
    // struct udev_list_entry *dev_list_entry;
    // struct udev_device *dev;
    // struct udev_device *parent_dev;
    // struct input_id currentInputDeviceInfo;

    inputFileInfoList = event.entryInfoList( QDir::Files );
    foreach( const QFileInfo& inputFileInfo, inputFileInfoList )
    {
        file = inputFileInfo.filePath();
        if( inputFileInfo.isReadable() )
            readableInputFiles.append( file );
        else
            unreadableInputFiles.append( file );
    }

    foreach( const QString & name, readableInputFiles )
    {
        InputDevice* device = 0;
        InputThread* thread = new InputThread( name );
        if( !thread->error() )
        {
            switch( thread->deviceType() )
            {
            case GluonInput::KeyboardDevice:
                device = new Keyboard( thread );
                detect->addKeyboard( static_cast<Keyboard*>( device ) );
                break;

            case GluonInput::MouseDevice:
                device = new Mouse( thread );
                detect->addMouse( static_cast<Mouse*>( device ) );
                break;

            case GluonInput::TouchpadDevice:
                device = new Mouse( thread );
                detect->addMouse( static_cast<Mouse*>( device ) );
                break;

            case GluonInput::JoystickDevice:
                device = new Joystick( thread );
                detect->addJoystick( static_cast<Joystick*>( device ) );
                break;

            case GluonInput::TouchDevice:
                device = new Touch( thread );
                detect->addTouch( static_cast<Touch*>( device ) );
                break;

            case GluonInput::UnknownDevice:
                device = new InputDevice( thread );
                detect->addUnknown( device );
                break;
            }

            processedInputs.append( thread->device_info() );
            detect->addInput( device );
        }
    }
    // }
    // #ifdef 0
    // [> Create the udev object <]
    // udev = udev_new();
    // if (!udev)
    // qWarning() << "Cannot create udev" << endl;

    // [> Create a list of the devices in the 'hidraw' subsystem. <]
    // enumerate = udev_enumerate_new(udev);
    // udev_enumerate_add_match_subsystem(enumerate, "input");
    // udev_enumerate_scan_devices(enumerate);
    // devices = udev_enumerate_get_list_entry(enumerate);
    /* For each item enumerated, print out its information.
     * udev_list_entry_foreach is a macro which expands to
     * a loop. The loop will be executed for each member in
     * devices, setting dev_list_entry to a list entry
     * which contains the device's path in /sys.
     */
    // udev_list_entry_foreach(dev_list_entry, devices) {
    // const char *path;

    // [> Get the filename of the /sys entry for the device
    // and create a udev_device object (dev) representing it */
    // path = udev_list_entry_get_name(dev_list_entry);
    // dev = udev_device_new_from_syspath(udev, path);

    // parent_dev = udev_device_get_parent_with_subsystem_devtype(dev, "input", 0);
    // if (parent_dev) {
    // udev_device_unref(parent_dev);
    // continue;
    // }

    // if (udev_device_get_sysattr_value(dev, "id/bustype"))
    // currentInputDeviceInfo.bustype = atoi(udev_device_get_sysattr_value(dev, "id/bustype"));
    // if (udev_device_get_sysattr_value(dev, "id/vendor"))
    // currentInputDeviceInfo.vendor = atoi(udev_device_get_sysattr_value(dev,"id/vendor"));
    // if (udev_device_get_sysattr_value(dev, "id/product"))
    // currentInputDeviceInfo.product = atoi(udev_device_get_sysattr_value(dev, "id/product"));
    // if (udev_device_get_sysattr_value(dev, "id/version"))
    // currentInputDeviceInfo.version = atoi(udev_device_get_sysattr_value(dev, "id/version"));

    /* The input device has been already processed, has read access
     * credential
     */
    // processed = false;
    // foreach(struct input_id inputID, processedInputs) {
    // if (inputID.bustype == currentInputDeviceInfo.bustype
    // && inputID.vendor == currentInputDeviceInfo.vendor
    // && inputID.product == currentInputDeviceInfo.product
    // && inputID.version == currentInputDeviceInfo.version) {
    // processed = true;
    // break;
    // }
    // }

    // if (processed)
    // continue;

    // InputDevice *device = 0;
    // InputThread *thread = new InputThread(dev);
    // if (!thread->error()) {
    // switch (thread->deviceType()) {
    // case GluonInput::KeyboardDevice:
    // device = new Keyboard(thread);
    // detect->addKeyboard(static_cast<Keyboard *>(device));
    // break;

    // case GluonInput::MouseDevice:
    // device = new Mouse(thread);
    // detect->addMouse(static_cast<Mouse *>(device));
    // break;

    // case GluonInput::TouchpadDevice:
    // device = new Mouse(thread);
    // detect->addMouse(static_cast<Mouse *>(device));
    // break;

    // case GluonInput::JoystickDevice:
    // device = new Joystick(thread);
    // detect->addJoystick(static_cast<Joystick *>(device));
    // break;

    // case GluonInput::TouchDevice:
    // device = new Touch(thread);
    // detect->addTouch(static_cast<Touch *>(device));
    // break;

    // case GluonInput::UnknownDevice:
    // device = new InputDevice(thread);
    // detect->addUnknown(device);
    // break;
    // }

    // detect->addInput(device);
    // }
    // }

    // [> Free the enumerator object <]
    // udev_enumerate_unref(enumerate);

    // udev_unref(udev);
    // #endif
}

void DetectLinux::setAllEnabled( bool enable )
{
    foreach( InputDevice * input, inputList() )
    {
        input->setEnabled( enable );
    }
}

void DetectLinux::clear()
{
    d->inputList.clear();
    d->keyboardList.clear();
    d->mouseList.clear();
    d->joystickList.clear();
    d->touchList.clear();
    d->unknownList.clear();
}

void DetectLinux::addInput( InputDevice* i )
{
    d->inputList.append( i );
}

void DetectLinux::addKeyboard( Keyboard* keyboard )
{
    d->keyboardList.append( keyboard );
}

void DetectLinux::addMouse( Mouse* mouse )
{
    d->mouseList.append( mouse );
}

void DetectLinux::addJoystick( Joystick* joystick )
{
    d->joystickList.append( joystick );
}

void DetectLinux::addTouch( Touch* touch )
{
    d->touchList.append( touch );
}

void DetectLinux::addUnknown( InputDevice* i )
{
    d->unknownList.append( i );
}

QList<InputDevice*> DetectLinux::inputList()
{
    return d->inputList;
}

QList<Keyboard*> DetectLinux::keyboardList()
{
    return d->keyboardList;
}

QList<Mouse*> DetectLinux::mouseList()
{
    return d->mouseList;
}

QList<Joystick*> DetectLinux::joystickList()
{
    return d->joystickList;
}

QList<Touch*> DetectLinux::touchList()
{
    return d->touchList;
}

QList<InputDevice*> DetectLinux::unknownDeviceList()
{
    return d->unknownList;
}

#include "detectlinux.moc"
<|endoftext|>


<commit_before>
/*++
Copyright (c) 2015 Microsoft Corporation

--*/

#include "qe_arith.h"
#include "qe.h"
#include "th_rewriter.h"
#include "smt2parser.h"
#include "arith_decl_plugin.h"
#include "reg_decl_plugins.h"
#include "arith_rewriter.h"
#include "ast_pp.h"
#include "qe_util.h"
#include "smt_context.h"
#include "expr_abstract.h"

static expr_ref parse_fml(ast_manager& m, char const* str) {
    expr_ref result(m);
    cmd_context ctx(false, &m);
    ctx.set_ignore_check(true);
    std::ostringstream buffer;
    buffer << "(declare-const x Real)\n"
           << "(declare-const y Real)\n"
           << "(declare-const z Real)\n"
           << "(declare-const u Real)\n"
           << "(declare-const v Real)\n"
           << "(declare-const t Real)\n"
           << "(declare-const a Real)\n"
           << "(declare-const b Real)\n"
           << "(assert " << str << ")\n";
    std::istringstream is(buffer.str());
    VERIFY(parse_smt2_commands(ctx, is));
    SASSERT(ctx.begin_assertions() != ctx.end_assertions());
    result = *ctx.begin_assertions();
    return result;
}

static char const* example1 = "(and (<= x 3.0) (<= (* 3.0 x) y) (<= z y))";
static char const* example2 = "(and (<= z x) (<= x 3.0) (<= (* 3.0 x) y) (<= z y))";
static char const* example3 = "(and (<= z x) (<= x 3.0) (< (* 3.0 x) y) (<= z y))";
static char const* example4 = "(and (<= z x) (<= x 3.0) (not (>= (* 3.0 x) y)) (<= z y))";
static char const* example5 = "(and (<= y x) (<= z x) (<= x u) (<= x v) (<= x t))";

static char const* example6 = "(and (<= 0 (+ x z))\
     (>= y x) \
     (<= y x)\
     (<= (- u y) 0.0)\
     (>= x (+ v z))\
     (>= x 0.0)\
     (<= x 1.0))";

static void test(char const *ex) {
    smt_params params;
    params.m_model = true;
    ast_manager m;
    reg_decl_plugins(m);
    arith_util a(m);
    expr_ref fml = parse_fml(m, ex);
    app_ref_vector vars(m);
    expr_ref_vector lits(m);
    vars.push_back(m.mk_const(symbol("x"), a.mk_real()));
    qe::flatten_and(fml, lits);

    smt::context ctx(m, params);
    ctx.assert_expr(fml);
    lbool result = ctx.check();
    SASSERT(result == l_true);
    ref<model> md;
    ctx.get_model(md);
    expr_ref pr = qe::arith_project(*md, vars, lits);

    std::cout << mk_pp(fml, m) << "\n";
    std::cout << mk_pp(pr, m) << "\n";

}

static void test2(char const *ex) {
    smt_params params;
    params.m_model = true;
    ast_manager m;
    reg_decl_plugins(m);
    arith_util a(m);
    expr_ref fml = parse_fml(m, ex);
    app_ref_vector vars(m);
    expr_ref_vector lits(m);
    vars.push_back(m.mk_const(symbol("x"), a.mk_real()));
    vars.push_back(m.mk_const(symbol("y"), a.mk_real()));
    vars.push_back(m.mk_const(symbol("z"), a.mk_real()));
    qe::flatten_and(fml, lits);

    smt::context ctx(m, params);
    ctx.push();
    ctx.assert_expr(fml);
    lbool result = ctx.check();
    SASSERT(result == l_true);
    ref<model> md;
    ctx.get_model(md);
    ctx.pop(1);

    std::cout << mk_pp(fml, m) << "\n";

    expr_ref pr2(m), fml2(m);
    expr_ref_vector bound(m);
    ptr_vector<sort> sorts;
    svector<symbol> names;
    for (unsigned i = 0; i < vars.size(); ++i) {
        bound.push_back(vars[i].get());
        names.push_back(vars[i]->get_decl()->get_name());
        sorts.push_back(m.get_sort(vars[i].get()));
    }
    expr_abstract(m, 0, bound.size(), bound.c_ptr(), fml, fml2);
    fml2 = m.mk_exists(bound.size(), sorts.c_ptr(), names.c_ptr(), fml2);
    qe::expr_quant_elim qe(m, params);
    expr_ref pr1 = qe::arith_project(*md, vars, lits);
    qe(m.mk_true(), fml2, pr2);
    std::cout << mk_pp(pr1, m) << "\n";
    std::cout << mk_pp(pr2, m) << "\n";

    expr_ref npr2(m);
    npr2 = m.mk_not(pr2);
    ctx.push();
    ctx.assert_expr(pr1);
    ctx.assert_expr(npr2);
    VERIFY(l_false == ctx.check());
    ctx.pop(1);

}

void tst_qe_arith() {
    test2(example6);
    return;
    test(example1);
    test(example2);
    test(example3);
    test(example4);
    test(example5);
}
<commit_msg>fix build break<commit_after>
/*++
Copyright (c) 2015 Microsoft Corporation

--*/

#include "qe_arith.h"
#include "qe.h"
#include "th_rewriter.h"
#include "smt2parser.h"
#include "arith_decl_plugin.h"
#include "reg_decl_plugins.h"
#include "arith_rewriter.h"
#include "ast_pp.h"
#include "qe_util.h"
#include "smt_context.h"
#include "expr_abstract.h"

static expr_ref parse_fml(ast_manager& m, char const* str) {
    expr_ref result(m);
    cmd_context ctx(false, &m);
    ctx.set_ignore_check(true);
    std::ostringstream buffer;
    buffer << "(declare-const x Real)\n"
           << "(declare-const y Real)\n"
           << "(declare-const z Real)\n"
           << "(declare-const u Real)\n"
           << "(declare-const v Real)\n"
           << "(declare-const t Real)\n"
           << "(declare-const a Real)\n"
           << "(declare-const b Real)\n"
           << "(assert " << str << ")\n";
    std::istringstream is(buffer.str());
    VERIFY(parse_smt2_commands(ctx, is));
    SASSERT(ctx.begin_assertions() != ctx.end_assertions());
    result = *ctx.begin_assertions();
    return result;
}

static char const* example1 = "(and (<= x 3.0) (<= (* 3.0 x) y) (<= z y))";
static char const* example2 = "(and (<= z x) (<= x 3.0) (<= (* 3.0 x) y) (<= z y))";
static char const* example3 = "(and (<= z x) (<= x 3.0) (< (* 3.0 x) y) (<= z y))";
static char const* example4 = "(and (<= z x) (<= x 3.0) (not (>= (* 3.0 x) y)) (<= z y))";
static char const* example5 = "(and (<= y x) (<= z x) (<= x u) (<= x v) (<= x t))";

static char const* example6 = "(and (<= 0 (+ x z))\
     (>= y x) \
     (<= y x)\
     (<= (- u y) 0.0)\
     (>= x (+ v z))\
     (>= x 0.0)\
     (<= x 1.0))";

static void test(char const *ex) {
    smt_params params;
    params.m_model = true;
    ast_manager m;
    reg_decl_plugins(m);
    arith_util a(m);
    expr_ref fml = parse_fml(m, ex);
    app_ref_vector vars(m);
    expr_ref_vector lits(m);
    vars.push_back(m.mk_const(symbol("x"), a.mk_real()));
    flatten_and(fml, lits);

    smt::context ctx(m, params);
    ctx.assert_expr(fml);
    lbool result = ctx.check();
    SASSERT(result == l_true);
    ref<model> md;
    ctx.get_model(md);
    expr_ref pr = qe::arith_project(*md, vars, lits);

    std::cout << mk_pp(fml, m) << "\n";
    std::cout << mk_pp(pr, m) << "\n";

}

static void test2(char const *ex) {
    smt_params params;
    params.m_model = true;
    ast_manager m;
    reg_decl_plugins(m);
    arith_util a(m);
    expr_ref fml = parse_fml(m, ex);
    app_ref_vector vars(m);
    expr_ref_vector lits(m);
    vars.push_back(m.mk_const(symbol("x"), a.mk_real()));
    vars.push_back(m.mk_const(symbol("y"), a.mk_real()));
    vars.push_back(m.mk_const(symbol("z"), a.mk_real()));
    flatten_and(fml, lits);

    smt::context ctx(m, params);
    ctx.push();
    ctx.assert_expr(fml);
    lbool result = ctx.check();
    SASSERT(result == l_true);
    ref<model> md;
    ctx.get_model(md);
    ctx.pop(1);

    std::cout << mk_pp(fml, m) << "\n";

    expr_ref pr2(m), fml2(m);
    expr_ref_vector bound(m);
    ptr_vector<sort> sorts;
    svector<symbol> names;
    for (unsigned i = 0; i < vars.size(); ++i) {
        bound.push_back(vars[i].get());
        names.push_back(vars[i]->get_decl()->get_name());
        sorts.push_back(m.get_sort(vars[i].get()));
    }
    expr_abstract(m, 0, bound.size(), bound.c_ptr(), fml, fml2);
    fml2 = m.mk_exists(bound.size(), sorts.c_ptr(), names.c_ptr(), fml2);
    qe::expr_quant_elim qe(m, params);
    expr_ref pr1 = qe::arith_project(*md, vars, lits);
    qe(m.mk_true(), fml2, pr2);
    std::cout << mk_pp(pr1, m) << "\n";
    std::cout << mk_pp(pr2, m) << "\n";

    expr_ref npr2(m);
    npr2 = m.mk_not(pr2);
    ctx.push();
    ctx.assert_expr(pr1);
    ctx.assert_expr(npr2);
    VERIFY(l_false == ctx.check());
    ctx.pop(1);

}

void tst_qe_arith() {
    test2(example6);
    return;
    test(example1);
    test(example2);
    test(example3);
    test(example4);
    test(example5);
}
<|endoftext|>


<commit_before>/** @file

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

#include "YamlSNIConfig.h"

#include <unordered_map>
#include <set>
#include <string_view>

#include <yaml-cpp/yaml.h>
#include <openssl/ssl.h>

#include "P_SNIActionPerformer.h"

#include "tscore/Diags.h"
#include "tscore/EnumDescriptor.h"
#include "tscore/Errata.h"
#include "tscore/ink_assert.h"

#include "records/I_RecCore.h"
#include "records/I_RecHttp.h"

namespace
{
// Assuming node is value of [TS_tunnel_alpn]
void
load_tunnel_alpn(std::vector<int> &dst, const YAML::Node &node)
{
  if (!node.IsSequence()) {
    throw YAML::ParserException(node.Mark(), "\"tunnel_alpn\" is not sequence");
  }

  for (const auto &alpn : node) {
    auto value = alpn.as<std::string>();
    int index  = globalSessionProtocolNameRegistry.indexFor(value);
    if (index == SessionProtocolNameRegistry::INVALID) {
      throw YAML::ParserException(alpn.Mark(), "unknown value \"" + value + "\"");
    } else {
      dst.push_back(index);
    }
  }
}
} // namespace

ts::Errata
YamlSNIConfig::loader(const char *cfgFilename)
{
  try {
    YAML::Node config = YAML::LoadFile(cfgFilename);
    if (config.IsNull()) {
      return ts::Errata();
    }

    if (!config["sni"]) {
      return ts::Errata::Message(1, 1, "expected a toplevel 'sni' node");
    }

    config = config["sni"];
    if (!config.IsSequence()) {
      return ts::Errata::Message(1, 1, "expected sequence");
    }

    for (auto it = config.begin(); it != config.end(); ++it) {
      items.push_back(it->as<YamlSNIConfig::Item>());
    }
  } catch (std::exception &ex) {
    return ts::Errata::Message(1, 1, ex.what());
  }

  return ts::Errata();
}

void
YamlSNIConfig::Item::EnableProtocol(YamlSNIConfig::TLSProtocol proto)
{
  if (proto <= YamlSNIConfig::TLSProtocol::TLS_MAX) {
    if (protocol_unset) {
      protocol_mask  = TLSValidProtocols::max_mask;
      protocol_unset = false;
    }
    switch (proto) {
    case YamlSNIConfig::TLSProtocol::TLSv1:
      protocol_mask &= ~SSL_OP_NO_TLSv1;
      break;
    case YamlSNIConfig::TLSProtocol::TLSv1_1:
      protocol_mask &= ~SSL_OP_NO_TLSv1_1;
      break;
    case YamlSNIConfig::TLSProtocol::TLSv1_2:
      protocol_mask &= ~SSL_OP_NO_TLSv1_2;
      break;
    case YamlSNIConfig::TLSProtocol::TLSv1_3:
#ifdef SSL_OP_NO_TLSv1_3
      protocol_mask &= ~SSL_OP_NO_TLSv1_3;
#endif
      break;
    }
  }
}

VerifyClient::~VerifyClient() {}

TsEnumDescriptor LEVEL_DESCRIPTOR         = {{{"NONE", 0}, {"MODERATE", 1}, {"STRICT", 2}}};
TsEnumDescriptor POLICY_DESCRIPTOR        = {{{"DISABLED", 0}, {"PERMISSIVE", 1}, {"ENFORCED", 2}}};
TsEnumDescriptor PROPERTIES_DESCRIPTOR    = {{{"NONE", 0}, {"SIGNATURE", 0x1}, {"NAME", 0x2}, {"ALL", 0x3}}};
TsEnumDescriptor TLS_PROTOCOLS_DESCRIPTOR = {{{"TLSv1", 0}, {"TLSv1_1", 1}, {"TLSv1_2", 2}, {"TLSv1_3", 3}}};

std::set<std::string> valid_sni_config_keys = {TS_fqdn,
                                               TS_disable_h2,
                                               TS_verify_client,
                                               TS_verify_client_ca_certs,
                                               TS_tunnel_route,
                                               TS_forward_route,
                                               TS_partial_blind_route,
                                               TS_tunnel_alpn,
                                               TS_tunnel_prewarm,
                                               TS_tunnel_prewarm_min,
                                               TS_tunnel_prewarm_max,
                                               TS_tunnel_prewarm_rate,
                                               TS_tunnel_prewarm_connect_timeout,
                                               TS_tunnel_prewarm_inactive_timeout,
                                               TS_tunnel_prewarm_srv,
                                               TS_verify_server_policy,
                                               TS_verify_server_properties,
                                               TS_client_cert,
                                               TS_client_key,
                                               TS_client_sni_policy,
                                               TS_http2,
                                               TS_ip_allow,
#if TS_USE_HELLO_CB || defined(OPENSSL_IS_BORINGSSL)
                                               TS_valid_tls_versions_in,
#endif
                                               TS_host_sni_policy};

namespace YAML
{
template <> struct convert<YamlSNIConfig::Item> {
  static bool
  decode(const Node &node, YamlSNIConfig::Item &item)
  {
    for (const auto &elem : node) {
      if (std::none_of(valid_sni_config_keys.begin(), valid_sni_config_keys.end(),
                       [&elem](const std::string &s) { return s == elem.first.as<std::string>(); })) {
        throw YAML::ParserException(elem.first.Mark(), "unsupported key " + elem.first.as<std::string>());
      }
    }

    if (node[TS_fqdn]) {
      item.fqdn = node[TS_fqdn].as<std::string>();
    } else {
      return false; // servername must be present
    }
    if (node[TS_disable_h2]) {
      item.offer_h2 = false;
    }
    if (node[TS_http2]) {
      item.offer_h2 = node[TS_http2].as<bool>();
    }

    // enum
    if (node[TS_verify_client]) {
      auto value = node[TS_verify_client].as<std::string>();
      int level  = LEVEL_DESCRIPTOR.get(value);
      if (level < 0) {
        throw YAML::ParserException(node[TS_verify_client].Mark(), "unknown value \"" + value + "\"");
      }
      item.verify_client_level = static_cast<uint8_t>(level);
    }

    if (node[TS_verify_client_ca_certs]) {
#if !TS_HAS_VERIFY_CERT_STORE
      // TS was compiled with an older version of the OpenSSL interface, that doesn't have
      // SSL_set1_verify_cert_store().  We need this macro in order to set the CA certs for verifying clients
      // after the client sends the SNI server name.
      //
      throw YAML::ParserException(node[TS_verify_client_ca_certs].Mark(),
                                  std::string(TS_verify_client_ca_certs) + " requires features from OpenSSL 1.0.2 or later");
#else
      std::string file, dir;
      auto const &n = node[TS_verify_client_ca_certs];

      if (n.IsMap()) {
        for (const auto &elem : n) {
          std::string key = elem.first.as<std::string>();
          if ("file" == key) {
            if (!file.empty()) {
              throw YAML::ParserException(elem.first.Mark(), "duplicate key \"file\"");
            }
            file = elem.second.as<std::string>();

          } else if ("dir" == key) {
            if (!dir.empty()) {
              throw YAML::ParserException(elem.first.Mark(), "duplicate key \"dir\"");
            }
            dir = elem.second.as<std::string>();

          } else {
            throw YAML::ParserException(elem.first.Mark(), "unsupported key " + elem.first.as<std::string>());
          }
        }
      } else {
        // Value should be string scalar with file.
        //
        file = n.as<std::string>();
      }
      ink_assert(!(file.empty() && dir.empty()));

      if (!file.empty() && (file[0] != '/')) {
        file = RecConfigReadConfigDir() + '/' + file;
      }
      if (!dir.empty() && (dir[0] != '/')) {
        dir = RecConfigReadConfigDir() + '/' + dir;
      }
      item.verify_client_ca_file = file;
      item.verify_client_ca_dir  = dir;
#endif
    }

    if (node[TS_host_sni_policy]) {
      auto value           = node[TS_host_sni_policy].as<std::string>();
      int policy           = POLICY_DESCRIPTOR.get(value);
      item.host_sni_policy = static_cast<uint8_t>(policy);
    }

    YamlSNIConfig::TunnelPreWarm t_prewarm = YamlSNIConfig::TunnelPreWarm::UNSET;
    uint32_t t_min                         = item.tunnel_prewarm_min;
    int32_t t_max                          = item.tunnel_prewarm_max;
    double t_rate                          = item.tunnel_prewarm_rate;
    uint32_t t_connect_timeout             = item.tunnel_prewarm_connect_timeout;
    uint32_t t_inactive_timeout            = item.tunnel_prewarm_inactive_timeout;
    bool t_srv                             = item.tunnel_prewarm_srv;

    if (node[TS_tunnel_prewarm]) {
      auto is_prewarm_enabled = node[TS_tunnel_prewarm].as<bool>();
      if (is_prewarm_enabled) {
        t_prewarm = YamlSNIConfig::TunnelPreWarm::ENABLED;
      } else {
        t_prewarm = YamlSNIConfig::TunnelPreWarm::DISABLED;
      }
    }
    if (node[TS_tunnel_prewarm_min]) {
      t_min = node[TS_tunnel_prewarm_min].as<uint32_t>();
    }
    if (node[TS_tunnel_prewarm_max]) {
      t_max = node[TS_tunnel_prewarm_max].as<int32_t>();
    }
    if (node[TS_tunnel_prewarm_rate]) {
      t_rate = node[TS_tunnel_prewarm_rate].as<double>();
    }
    if (node[TS_tunnel_prewarm_connect_timeout]) {
      t_connect_timeout = node[TS_tunnel_prewarm_connect_timeout].as<uint32_t>();
    }
    if (node[TS_tunnel_prewarm_inactive_timeout]) {
      t_inactive_timeout = node[TS_tunnel_prewarm_inactive_timeout].as<uint32_t>();
    }
    if (node[TS_tunnel_prewarm_srv]) {
      t_srv = node[TS_tunnel_prewarm_srv].as<bool>();
    }

    if (node[TS_tunnel_route]) {
      item.tunnel_destination = node[TS_tunnel_route].as<std::string>();
      item.tunnel_type        = SNIRoutingType::BLIND;
    } else if (node[TS_forward_route]) {
      item.tunnel_destination              = node[TS_forward_route].as<std::string>();
      item.tunnel_type                     = SNIRoutingType::FORWARD;
      item.tunnel_prewarm                  = t_prewarm;
      item.tunnel_prewarm_min              = t_min;
      item.tunnel_prewarm_max              = t_max;
      item.tunnel_prewarm_rate             = t_rate;
      item.tunnel_prewarm_connect_timeout  = t_connect_timeout;
      item.tunnel_prewarm_inactive_timeout = t_inactive_timeout;
      item.tunnel_prewarm_srv              = t_srv;
    } else if (node[TS_partial_blind_route]) {
      item.tunnel_destination              = node[TS_partial_blind_route].as<std::string>();
      item.tunnel_type                     = SNIRoutingType::PARTIAL_BLIND;
      item.tunnel_prewarm                  = t_prewarm;
      item.tunnel_prewarm_min              = t_min;
      item.tunnel_prewarm_max              = t_max;
      item.tunnel_prewarm_rate             = t_rate;
      item.tunnel_prewarm_connect_timeout  = t_connect_timeout;
      item.tunnel_prewarm_inactive_timeout = t_inactive_timeout;
      item.tunnel_prewarm_srv              = t_srv;

      if (node[TS_tunnel_alpn]) {
        load_tunnel_alpn(item.tunnel_alpn, node[TS_tunnel_alpn]);
      }
    }

    if (node[TS_verify_server_policy]) {
      auto value = node[TS_verify_server_policy].as<std::string>();
      int policy = POLICY_DESCRIPTOR.get(value);
      if (policy < 0) {
        throw YAML::ParserException(node[TS_verify_server_policy].Mark(), "unknown value \"" + value + "\"");
      }
      item.verify_server_policy = static_cast<YamlSNIConfig::Policy>(policy);
    }

    if (node[TS_verify_server_properties]) {
      auto value     = node[TS_verify_server_properties].as<std::string>();
      int properties = PROPERTIES_DESCRIPTOR.get(value);
      if (properties < 0) {
        throw YAML::ParserException(node[TS_verify_server_properties].Mark(), "unknown value \"" + value + "\"");
      }
      item.verify_server_properties = static_cast<YamlSNIConfig::Property>(properties);
    }

    if (node[TS_client_cert]) {
      item.client_cert = node[TS_client_cert].as<std::string>();
    }
    if (node[TS_client_key]) {
      item.client_key = node[TS_client_key].as<std::string>();
    }
    if (node[TS_client_sni_policy]) {
      item.client_sni_policy = node[TS_client_sni_policy].as<std::string>();
    }

    if (node[TS_ip_allow]) {
      item.ip_allow = node[TS_ip_allow].as<std::string>();
    }
    if (node[TS_valid_tls_versions_in]) {
      for (unsigned int i = 0; i < node[TS_valid_tls_versions_in].size(); i++) {
        auto value   = node[TS_valid_tls_versions_in][i].as<std::string>();
        int protocol = TLS_PROTOCOLS_DESCRIPTOR.get(value);
        item.EnableProtocol(static_cast<YamlSNIConfig::TLSProtocol>(protocol));
      }
    }
    return true;
  }
};
} // namespace YAML
<commit_msg>Relax key validation of sni.yaml (#8549)<commit_after>/** @file

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

#include "YamlSNIConfig.h"

#include <unordered_map>
#include <set>
#include <string_view>

#include <yaml-cpp/yaml.h>
#include <openssl/ssl.h>

#include "P_SNIActionPerformer.h"

#include "tscore/Diags.h"
#include "tscore/EnumDescriptor.h"
#include "tscore/Errata.h"
#include "tscore/ink_assert.h"

#include "records/I_RecCore.h"
#include "records/I_RecHttp.h"

namespace
{
// Assuming node is value of [TS_tunnel_alpn]
void
load_tunnel_alpn(std::vector<int> &dst, const YAML::Node &node)
{
  if (!node.IsSequence()) {
    throw YAML::ParserException(node.Mark(), "\"tunnel_alpn\" is not sequence");
  }

  for (const auto &alpn : node) {
    auto value = alpn.as<std::string>();
    int index  = globalSessionProtocolNameRegistry.indexFor(value);
    if (index == SessionProtocolNameRegistry::INVALID) {
      throw YAML::ParserException(alpn.Mark(), "unknown value \"" + value + "\"");
    } else {
      dst.push_back(index);
    }
  }
}
} // namespace

ts::Errata
YamlSNIConfig::loader(const char *cfgFilename)
{
  try {
    YAML::Node config = YAML::LoadFile(cfgFilename);
    if (config.IsNull()) {
      return ts::Errata();
    }

    if (!config["sni"]) {
      return ts::Errata::Message(1, 1, "expected a toplevel 'sni' node");
    }

    config = config["sni"];
    if (!config.IsSequence()) {
      return ts::Errata::Message(1, 1, "expected sequence");
    }

    for (auto it = config.begin(); it != config.end(); ++it) {
      items.push_back(it->as<YamlSNIConfig::Item>());
    }
  } catch (std::exception &ex) {
    return ts::Errata::Message(1, 1, ex.what());
  }

  return ts::Errata();
}

void
YamlSNIConfig::Item::EnableProtocol(YamlSNIConfig::TLSProtocol proto)
{
  if (proto <= YamlSNIConfig::TLSProtocol::TLS_MAX) {
    if (protocol_unset) {
      protocol_mask  = TLSValidProtocols::max_mask;
      protocol_unset = false;
    }
    switch (proto) {
    case YamlSNIConfig::TLSProtocol::TLSv1:
      protocol_mask &= ~SSL_OP_NO_TLSv1;
      break;
    case YamlSNIConfig::TLSProtocol::TLSv1_1:
      protocol_mask &= ~SSL_OP_NO_TLSv1_1;
      break;
    case YamlSNIConfig::TLSProtocol::TLSv1_2:
      protocol_mask &= ~SSL_OP_NO_TLSv1_2;
      break;
    case YamlSNIConfig::TLSProtocol::TLSv1_3:
#ifdef SSL_OP_NO_TLSv1_3
      protocol_mask &= ~SSL_OP_NO_TLSv1_3;
#endif
      break;
    }
  }
}

VerifyClient::~VerifyClient() {}

TsEnumDescriptor LEVEL_DESCRIPTOR         = {{{"NONE", 0}, {"MODERATE", 1}, {"STRICT", 2}}};
TsEnumDescriptor POLICY_DESCRIPTOR        = {{{"DISABLED", 0}, {"PERMISSIVE", 1}, {"ENFORCED", 2}}};
TsEnumDescriptor PROPERTIES_DESCRIPTOR    = {{{"NONE", 0}, {"SIGNATURE", 0x1}, {"NAME", 0x2}, {"ALL", 0x3}}};
TsEnumDescriptor TLS_PROTOCOLS_DESCRIPTOR = {{{"TLSv1", 0}, {"TLSv1_1", 1}, {"TLSv1_2", 2}, {"TLSv1_3", 3}}};

std::set<std::string> valid_sni_config_keys = {TS_fqdn,
                                               TS_disable_h2,
                                               TS_verify_client,
                                               TS_verify_client_ca_certs,
                                               TS_tunnel_route,
                                               TS_forward_route,
                                               TS_partial_blind_route,
                                               TS_tunnel_alpn,
                                               TS_tunnel_prewarm,
                                               TS_tunnel_prewarm_min,
                                               TS_tunnel_prewarm_max,
                                               TS_tunnel_prewarm_rate,
                                               TS_tunnel_prewarm_connect_timeout,
                                               TS_tunnel_prewarm_inactive_timeout,
                                               TS_tunnel_prewarm_srv,
                                               TS_verify_server_policy,
                                               TS_verify_server_properties,
                                               TS_client_cert,
                                               TS_client_key,
                                               TS_client_sni_policy,
                                               TS_http2,
                                               TS_ip_allow,
#if TS_USE_HELLO_CB || defined(OPENSSL_IS_BORINGSSL)
                                               TS_valid_tls_versions_in,
#endif
                                               TS_host_sni_policy};

namespace YAML
{
template <> struct convert<YamlSNIConfig::Item> {
  static bool
  decode(const Node &node, YamlSNIConfig::Item &item)
  {
    for (const auto &elem : node) {
      if (std::none_of(valid_sni_config_keys.begin(), valid_sni_config_keys.end(),
                       [&elem](const std::string &s) { return s == elem.first.as<std::string>(); })) {
        Warning("unsupported key '%s' in SNI config", elem.first.as<std::string>().c_str());
      }
    }

    if (node[TS_fqdn]) {
      item.fqdn = node[TS_fqdn].as<std::string>();
    } else {
      return false; // servername must be present
    }
    if (node[TS_disable_h2]) {
      item.offer_h2 = false;
    }
    if (node[TS_http2]) {
      item.offer_h2 = node[TS_http2].as<bool>();
    }

    // enum
    if (node[TS_verify_client]) {
      auto value = node[TS_verify_client].as<std::string>();
      int level  = LEVEL_DESCRIPTOR.get(value);
      if (level < 0) {
        throw YAML::ParserException(node[TS_verify_client].Mark(), "unknown value \"" + value + "\"");
      }
      item.verify_client_level = static_cast<uint8_t>(level);
    }

    if (node[TS_verify_client_ca_certs]) {
#if !TS_HAS_VERIFY_CERT_STORE
      // TS was compiled with an older version of the OpenSSL interface, that doesn't have
      // SSL_set1_verify_cert_store().  We need this macro in order to set the CA certs for verifying clients
      // after the client sends the SNI server name.
      //
      throw YAML::ParserException(node[TS_verify_client_ca_certs].Mark(),
                                  std::string(TS_verify_client_ca_certs) + " requires features from OpenSSL 1.0.2 or later");
#else
      std::string file, dir;
      auto const &n = node[TS_verify_client_ca_certs];

      if (n.IsMap()) {
        for (const auto &elem : n) {
          std::string key = elem.first.as<std::string>();
          if ("file" == key) {
            if (!file.empty()) {
              throw YAML::ParserException(elem.first.Mark(), "duplicate key \"file\"");
            }
            file = elem.second.as<std::string>();

          } else if ("dir" == key) {
            if (!dir.empty()) {
              throw YAML::ParserException(elem.first.Mark(), "duplicate key \"dir\"");
            }
            dir = elem.second.as<std::string>();

          } else {
            throw YAML::ParserException(elem.first.Mark(), "unsupported key " + elem.first.as<std::string>());
          }
        }
      } else {
        // Value should be string scalar with file.
        //
        file = n.as<std::string>();
      }
      ink_assert(!(file.empty() && dir.empty()));

      if (!file.empty() && (file[0] != '/')) {
        file = RecConfigReadConfigDir() + '/' + file;
      }
      if (!dir.empty() && (dir[0] != '/')) {
        dir = RecConfigReadConfigDir() + '/' + dir;
      }
      item.verify_client_ca_file = file;
      item.verify_client_ca_dir  = dir;
#endif
    }

    if (node[TS_host_sni_policy]) {
      auto value           = node[TS_host_sni_policy].as<std::string>();
      int policy           = POLICY_DESCRIPTOR.get(value);
      item.host_sni_policy = static_cast<uint8_t>(policy);
    }

    YamlSNIConfig::TunnelPreWarm t_prewarm = YamlSNIConfig::TunnelPreWarm::UNSET;
    uint32_t t_min                         = item.tunnel_prewarm_min;
    int32_t t_max                          = item.tunnel_prewarm_max;
    double t_rate                          = item.tunnel_prewarm_rate;
    uint32_t t_connect_timeout             = item.tunnel_prewarm_connect_timeout;
    uint32_t t_inactive_timeout            = item.tunnel_prewarm_inactive_timeout;
    bool t_srv                             = item.tunnel_prewarm_srv;

    if (node[TS_tunnel_prewarm]) {
      auto is_prewarm_enabled = node[TS_tunnel_prewarm].as<bool>();
      if (is_prewarm_enabled) {
        t_prewarm = YamlSNIConfig::TunnelPreWarm::ENABLED;
      } else {
        t_prewarm = YamlSNIConfig::TunnelPreWarm::DISABLED;
      }
    }
    if (node[TS_tunnel_prewarm_min]) {
      t_min = node[TS_tunnel_prewarm_min].as<uint32_t>();
    }
    if (node[TS_tunnel_prewarm_max]) {
      t_max = node[TS_tunnel_prewarm_max].as<int32_t>();
    }
    if (node[TS_tunnel_prewarm_rate]) {
      t_rate = node[TS_tunnel_prewarm_rate].as<double>();
    }
    if (node[TS_tunnel_prewarm_connect_timeout]) {
      t_connect_timeout = node[TS_tunnel_prewarm_connect_timeout].as<uint32_t>();
    }
    if (node[TS_tunnel_prewarm_inactive_timeout]) {
      t_inactive_timeout = node[TS_tunnel_prewarm_inactive_timeout].as<uint32_t>();
    }
    if (node[TS_tunnel_prewarm_srv]) {
      t_srv = node[TS_tunnel_prewarm_srv].as<bool>();
    }

    if (node[TS_tunnel_route]) {
      item.tunnel_destination = node[TS_tunnel_route].as<std::string>();
      item.tunnel_type        = SNIRoutingType::BLIND;
    } else if (node[TS_forward_route]) {
      item.tunnel_destination              = node[TS_forward_route].as<std::string>();
      item.tunnel_type                     = SNIRoutingType::FORWARD;
      item.tunnel_prewarm                  = t_prewarm;
      item.tunnel_prewarm_min              = t_min;
      item.tunnel_prewarm_max              = t_max;
      item.tunnel_prewarm_rate             = t_rate;
      item.tunnel_prewarm_connect_timeout  = t_connect_timeout;
      item.tunnel_prewarm_inactive_timeout = t_inactive_timeout;
      item.tunnel_prewarm_srv              = t_srv;
    } else if (node[TS_partial_blind_route]) {
      item.tunnel_destination              = node[TS_partial_blind_route].as<std::string>();
      item.tunnel_type                     = SNIRoutingType::PARTIAL_BLIND;
      item.tunnel_prewarm                  = t_prewarm;
      item.tunnel_prewarm_min              = t_min;
      item.tunnel_prewarm_max              = t_max;
      item.tunnel_prewarm_rate             = t_rate;
      item.tunnel_prewarm_connect_timeout  = t_connect_timeout;
      item.tunnel_prewarm_inactive_timeout = t_inactive_timeout;
      item.tunnel_prewarm_srv              = t_srv;

      if (node[TS_tunnel_alpn]) {
        load_tunnel_alpn(item.tunnel_alpn, node[TS_tunnel_alpn]);
      }
    }

    if (node[TS_verify_server_policy]) {
      auto value = node[TS_verify_server_policy].as<std::string>();
      int policy = POLICY_DESCRIPTOR.get(value);
      if (policy < 0) {
        throw YAML::ParserException(node[TS_verify_server_policy].Mark(), "unknown value \"" + value + "\"");
      }
      item.verify_server_policy = static_cast<YamlSNIConfig::Policy>(policy);
    }

    if (node[TS_verify_server_properties]) {
      auto value     = node[TS_verify_server_properties].as<std::string>();
      int properties = PROPERTIES_DESCRIPTOR.get(value);
      if (properties < 0) {
        throw YAML::ParserException(node[TS_verify_server_properties].Mark(), "unknown value \"" + value + "\"");
      }
      item.verify_server_properties = static_cast<YamlSNIConfig::Property>(properties);
    }

    if (node[TS_client_cert]) {
      item.client_cert = node[TS_client_cert].as<std::string>();
    }
    if (node[TS_client_key]) {
      item.client_key = node[TS_client_key].as<std::string>();
    }
    if (node[TS_client_sni_policy]) {
      item.client_sni_policy = node[TS_client_sni_policy].as<std::string>();
    }

    if (node[TS_ip_allow]) {
      item.ip_allow = node[TS_ip_allow].as<std::string>();
    }
    if (node[TS_valid_tls_versions_in]) {
      for (unsigned int i = 0; i < node[TS_valid_tls_versions_in].size(); i++) {
        auto value   = node[TS_valid_tls_versions_in][i].as<std::string>();
        int protocol = TLS_PROTOCOLS_DESCRIPTOR.get(value);
        item.EnableProtocol(static_cast<YamlSNIConfig::TLSProtocol>(protocol));
      }
    }
    return true;
  }
};
} // namespace YAML
<|endoftext|>


<commit_before>#include "CStateManager.h"

#include "CApplication.h"

CStateManager::CStateManager()
    : CurrentState(0)
{}

void CStateManager::OnGameTickStart(float const Elapsed)
{
    if (CurrentState)
        CurrentState->OnGameTickStart(Elapsed);
}

void CStateManager::OnGameTickEnd(float const Elapsed)
{
    if (CurrentState)
        CurrentState->OnGameTickEnd(Elapsed);
}

void CStateManager::OnRenderStart(float const Elapsed)
{
    if (CurrentState)
        CurrentState->OnRenderStart(Elapsed);
}

void CStateManager::OnRenderEnd(float const Elapsed)
{
    if (CurrentState)
        CurrentState->OnRenderEnd(Elapsed);
}

void CStateManager::OnMouseEvent(SMouseEvent const & Event)
{
    if (CurrentState)
        CurrentState->OnMouseEvent(Event);
}

void CStateManager::OnKeyboardEvent(SKeyboardEvent const & Event)
{
    if (CurrentState)
        CurrentState->OnKeyboardEvent(Event);
}

void CStateManager::setState(IState * State)
{
   NextState = State;
}

void CStateManager::doStateChange()
{
	if (! NextState)
		return;

	if (CurrentState)
	{
		CurrentState->disconnect();
		CApplication::get().getGUIEngine().removeAllWidgets();
      CApplication::get().getSceneManager().Lights.clear();
		CApplication::get().getSceneManager().removeAllSceneObjects();
		CurrentState->end();
	}

	CurrentState = NextState;
	NextState = NULL;

	CurrentState->connect();
	CurrentState->begin();

	CApplication::get().getSceneManager().blurSceneIn(0.3f, CApplication::get().getRunTime());
}

void CStateManager::shutDown()
{
	if (CurrentState)
		CurrentState->end();

	CurrentState = 0;
}
<commit_msg>+ Formatting and reference safety for state manager<commit_after>#include "CStateManager.h"

#include "CApplication.h"

CStateManager::CStateManager()
	: CurrentState(0)
{}

void CStateManager::OnGameTickStart(float const Elapsed)
{
	if (CurrentState)
		CurrentState->OnGameTickStart(Elapsed);
}

void CStateManager::OnGameTickEnd(float const Elapsed)
{
	if (CurrentState)
		CurrentState->OnGameTickEnd(Elapsed);
}

void CStateManager::OnRenderStart(float const Elapsed)
{
	if (CurrentState)
		CurrentState->OnRenderStart(Elapsed);
}

void CStateManager::OnRenderEnd(float const Elapsed)
{
	if (CurrentState)
		CurrentState->OnRenderEnd(Elapsed);
}

void CStateManager::OnMouseEvent(SMouseEvent const & Event)
{
	if (CurrentState)
		CurrentState->OnMouseEvent(Event);
}

void CStateManager::OnKeyboardEvent(SKeyboardEvent const & Event)
{
	if (CurrentState)
		CurrentState->OnKeyboardEvent(Event);
}

void CStateManager::setState(IState * State)
{
	NextState = State;
}

void CStateManager::doStateChange()
{
	if (! NextState)
		return;

	if (CurrentState)
	{
		CurrentState->disconnect();
		if (& CApplication::get().getGUIEngine())
			CApplication::get().getGUIEngine().removeAllWidgets();
		if (& CApplication::get().getSceneManager())
		{
			CApplication::get().getSceneManager().Lights.clear();
			CApplication::get().getSceneManager().removeAllSceneObjects();
		}
		CurrentState->end();
	}

	CurrentState = NextState;
	NextState = NULL;

	CurrentState->connect();
	CurrentState->begin();

	//CApplication::get().getSceneManager().blurSceneIn(0.3f, CApplication::get().getRunTime());
}

void CStateManager::shutDown()
{
	if (CurrentState)
		CurrentState->end();

	CurrentState = 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2009 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <math.h>
#include <boost/tokenizer.hpp>
#include <iostream>
#include <fstream>
#include <boost/program_options.hpp>
#include <topologyreader.h>
#include "version.h"

using namespace std;

void help_text(void)
{
    votca::csg::HelpTextHeader("csg_dump");
    cout << "Print atoms that are read from topology file to help"
        " debugging atom naming.\n\n";
}

int main(int argc, char** argv)
{
    // initialize the readers/writers,
    // this will be combined in an initialize function later
//    TrajectoryReader::RegisterPlugins();
    TopologyReader::RegisterPlugins();

    // lets read in some program options
    namespace po = boost::program_options;

    // Declare the supported options.
    po::options_description desc("Allowed options");

    // let cg_engine add some program options
    desc.add_options()
    ("help", "produce this help message")
    //("version", "show version info")
    ("top", boost::program_options::value<string>(), "atomistic topology file");

    // now read in the command line
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);

    // does the user want help?
    if (vm.count("help")) {
        help_text();
        cout << desc << endl;
        return 0;
    }

    if(!vm.count("top")) {
        cout << "no topology specified\n";
        return 0;
    }

    // try to run the cg process, go through the frames, etc...
    try {
        Topology top;
        TopologyReader *reader;
        reader = TopReaderFactory().Create(vm["top"].as<string>());
        if(reader == NULL)
            throw std::runtime_error("input format not supported: " + vm["top"].as<string>());

        reader->ReadTopology(vm["top"].as<string>(), top);
        cout << "I have " << top.BeadCount() << " beads in " << top.MoleculeCount() << " molecules" << endl;

        MoleculeContainer::iterator mol;
        for(mol=top.Molecules().begin(); mol!=top.Molecules().end();++mol) {
            cout << "molecule: " << (*mol)->getId() + 1 << " " << (*mol)->getName()
              << " beads: " << (*mol)->BeadCount() << endl;
            for(int i=0; i<(*mol)->BeadCount(); ++i) {
                cout << (*mol)->getBeadId(i) << " " <<
                    (*mol)->getBeadName(i) << " " << (*mol)->getBead(i)->getType()->getName() << endl;
            }
        }
    }
    // did an error occour?
    catch(std::exception &error) {
        cerr << "An error occoured!" << endl << error.what() << endl;
    }
    return 0;
}

<commit_msg>fixed typo<commit_after>/*
 * Copyright 2009 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <math.h>
#include <boost/tokenizer.hpp>
#include <iostream>
#include <fstream>
#include <boost/program_options.hpp>
#include <topologyreader.h>
#include "version.h"

using namespace std;

void help_text(void)
{
    votca::csg::HelpTextHeader("csg_dump");
    cout << "Print atoms that are read from topology file to help"
        " debugging atom naming.\n\n";
}

int main(int argc, char** argv)
{
    // initialize the readers/writers,
    // this will be combined in an initialize function later
//    TrajectoryReader::RegisterPlugins();
    TopologyReader::RegisterPlugins();

    // lets read in some program options
    namespace po = boost::program_options;

    // Declare the supported options.
    po::options_description desc("Allowed options");

    // let cg_engine add some program options
    desc.add_options()
    ("help", "produce this help message")
    //("version", "show version info")
    ("top", boost::program_options::value<string>(), "atomistic topology file");

    // now read in the command line
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);

    // does the user want help?
    if (vm.count("help")) {
        help_text();
        cout << desc << endl;
        return 0;
    }

    if(!vm.count("top")) {
        cout << "no topology specified\n";
        return 0;
    }

    // try to run the cg process, go through the frames, etc...
    try {
        Topology top;
        TopologyReader *reader;
        reader = TopReaderFactory().Create(vm["top"].as<string>());
        if(reader == NULL)
            throw std::runtime_error("input format not supported: " + vm["top"].as<string>());

        reader->ReadTopology(vm["top"].as<string>(), top);
        cout << "I have " << top.BeadCount() << " beads in " << top.MoleculeCount() << " molecules" << endl;

        MoleculeContainer::iterator mol;
        for(mol=top.Molecules().begin(); mol!=top.Molecules().end();++mol) {
            cout << "molecule: " << (*mol)->getId() + 1 << " " << (*mol)->getName()
              << " beads: " << (*mol)->BeadCount() << endl;
            for(int i=0; i<(*mol)->BeadCount(); ++i) {
                cout << (*mol)->getBeadId(i) << " " <<
                    (*mol)->getBeadName(i) << " " << (*mol)->getBead(i)->getType()->getName() << endl;
            }
        }
    }
    // did an error occour?
    catch(std::exception &error) {
        cerr << "An error occured!" << endl << error.what() << endl;
    }
    return 0;
}

<|endoftext|>


<commit_before>/* trials.cpp - CS 472 Project #3: Genetic Programming
 * Copyright 2014 Andrew Schwartzmeyer
 *
 * Source file for the trials namespace
 */

#include <algorithm>
#include <cassert>
#include <ctime>
#include <future>
#include <tuple>

#include "trials.hpp"
#include "../algorithm/algorithm.hpp"
#include "../individual/individual.hpp"
#include "../options/options.hpp"

namespace trials
{
  using individual::Individual;

  // Push results
  void
  push_results(const std::time_t& time, unsigned int& trial,
	       const unsigned int trials, std::vector<Individual>& candidates,
	       const options::Options& options)
  {
    // Spawn blocks number of async threads.
    std::vector<std::future<const Individual>> results;
    results.reserve(trials);

    auto task = [&time, &trial, &options]() mutable
      { return async(std::launch::async,
		     algorithm::genetic, time, ++trial, options); };
    generate_n(back_inserter(results), trials, task);
    // Gather future results.
    for (std::future<const Individual>& result : results)
      candidates.emplace_back(result.get());
  }

  // Spawn trials number of threads in blocks.
  const std::tuple<int, individual::Individual>
  run(const std::time_t& time, const options::Options& options)
  {
    const unsigned long hardware_threads = std::thread::hardware_concurrency();
    const unsigned long blocks = (hardware_threads != 0) ? hardware_threads : 2;

    unsigned int trial = 0;
    std::vector<Individual> candidates;

    // Spawn trials in chunks of size blocks.
    for (unsigned long t = 0; t < options.trials / blocks; ++t)
      push_results(time, trial, blocks, candidates, options);

    // Spawn remaining trials.
    push_results(time, trial, options.trials % blocks, candidates, options);

    // Retrieve best element.
    auto compare = [](const Individual& a, const Individual&b)
      { return a.get_score() > b.get_score(); };
    auto best = min_element(begin(candidates), end(candidates), compare);

    /* Get which trial was best.  Filenames are not zero-indexed so
       increase by one. */
    return std::make_tuple(distance(begin(candidates), best) + 1, *best);
  }
}
<commit_msg>Given 1 trial, avoid spawning thread (for testing)<commit_after>/* trials.cpp - CS 472 Project #3: Genetic Programming
 * Copyright 2014 Andrew Schwartzmeyer
 *
 * Source file for the trials namespace
 */

#include <algorithm>
#include <ctime>
#include <future>
#include <tuple>

#include "trials.hpp"
#include "../individual/individual.hpp"
#include "../options/options.hpp"

// Forward declaration of algorithm::genetic
namespace algorithm
{
  const individual::Individual
  genetic(const std::time_t&, int, const options::Options&);
}

namespace trials
{
  using individual::Individual;

  /* Delegate for run.  Given time, trial number, total trials, vector
     of candidate Individual solutions, and options, spawn the
     numbered trials in asynchronous threads, pushing results to
     candidates. */
  void
  push_results(const std::time_t&, int&, int, std::vector<Individual>&,
	       const options::Options&);

  /* Given time and options, spawn trials in blocks of the appropriate
     size for hardware (determined at runtime, defaulting to two), and
     spawn any remaining trials.  Return the best Individual result
     from the trials along with its trial number as a tuple. */
  const std::tuple<int, individual::Individual>
  run(const std::time_t& time, const options::Options& opts)
  {
    const unsigned long hardware_threads = std::thread::hardware_concurrency();
    const unsigned long blocks = (hardware_threads != 0) ? hardware_threads : 2;

    int trial = 0;
    std::vector<Individual> candidates;

    // Run the genetic algorithm (program).
    if (opts.trials == 1) // Spawn single non-threaded trial.
      candidates.push_back(algorithm::genetic(time, trial, opts));
    else // Spawn trials in separate threads.
      {
	// Spawn trials in chunks of size blocks.
	for (unsigned long t = 0; t < opts.trials / blocks; ++t)
	  push_results(time, trial, blocks, candidates, opts);

	// Spawn remaining trials.
	push_results(time, trial, opts.trials % blocks, candidates, opts);
      }

    // Retrieve best element.
    auto compare = [](const Individual& a, const Individual& b)
      { return a.get_score() > b.get_score(); };
    auto best = min_element(begin(candidates), end(candidates), compare);

    /* Get which trial was best.  Filenames are not zero-indexed so
       increment by one. */
    return std::make_tuple(distance(begin(candidates), best) + 1, *best);
  }

  void
  push_results(const std::time_t& time, int& trial, int trials,
	       std::vector<Individual>& candidates, const options::Options& opts)
  {
    // Spawn blocks number of async threads.
    std::vector<std::future<const Individual>> results;
    results.reserve(trials);

    auto task = [&time, &trial, &opts]() mutable
      { return async(std::launch::async,
		     algorithm::genetic, time, ++trial, opts); };
    generate_n(back_inserter(results), trials, task);

    // Gather future results.
    for (auto& result : results) candidates.push_back(result.get());
  }
}
<|endoftext|>


<commit_before>/**
* Copyright (C) Mellanox Technologies Ltd. 2001-2013.  ALL RIGHTS RESERVED.
*
* $COPYRIGHT$
* $HEADER$
*/

#include "test.h"

extern "C" {
#include <ucs/config/parser.h>
#include <ucs/config/global_opts.h>
}

#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>

namespace ucs {

test_base::test_base() : m_state(NEW) {
}

test_base::~test_base() {
    ucs_assertv_always(m_state == FINISHED ||
                       m_state == SKIPPED ||
                       m_state == ABORTED,
                       "state=%d", m_state);
}

void test_base::set_config(void *opts, ucs_config_field_t *fields,
                           const std::string& name, const std::string& value)
{
    ucs_status_t status = ucs_config_parser_set_value(opts, fields, name.c_str(),
                                                      value.c_str());
    if (status != UCS_OK) {
        GTEST_FAIL() << "Invalid UCS configuration for " << name << " : " << value;
    }
}

void test_base::set_config(const std::string& name, const std::string& value)
{
    set_config(&ucs_global_opts, ucs_global_opts_table, name, value);
}

void test_base::push_config()
{
    m_config_stack.push_back(ucs_global_opts_t());
    ucs_config_parser_clone_opts(&ucs_global_opts, &m_config_stack.back(),
                                 ucs_global_opts_table);
}

void test_base::pop_config()
{
    ucs_config_parser_release_opts(&ucs_global_opts, ucs_global_opts_table);
    ucs_global_opts = m_config_stack.back();
}

void test_base::set_multi_config(const std::string& multi_config) {
    std::vector<std::string> tokens;
    boost::split(tokens, multi_config, boost::is_any_of("="));
    set_config(tokens[0], tokens[1]);
}

void test_base::SetUpProxy() {
    ucs_assert(m_state == NEW);
    m_num_valgrind_errors_before = VALGRIND_COUNT_ERRORS;

    try {
        init();
        m_state = RUNNING;
    } catch (test_skip_exception&) {
        detail::message_stream("SKIP");
        m_state = SKIPPED;
    } catch (test_abort_exception&) {
        m_state = ABORTED;
    }
}

void test_base::TearDownProxy() {
    ucs_assertv_always(m_state == FINISHED ||
                       m_state == SKIPPED ||
                       m_state == ABORTED,
                       "state=%d", m_state);
    cleanup();
    int num_valgrind_errors = VALGRIND_COUNT_ERRORS - m_num_valgrind_errors_before;
    if (num_valgrind_errors > 0) {
        ADD_FAILURE() << "Got " << num_valgrind_errors << " valgrind errors during the test";
    }
}

void test_base::TestBodyProxy() {
    if (m_state == RUNNING) {
        try {
            test_body();
            m_state = FINISHED;
        } catch (test_skip_exception&) {
            detail::message_stream("SKIP");
            m_state = SKIPPED;
        }
    } else if (m_state == SKIPPED) {
    } else if (m_state == ABORTED) {
    }
}

void test_base::init() {
}

void test_base::cleanup() {
}

}
<commit_msg>UCS/TEST: Catch test_abort exception<commit_after>/**
* Copyright (C) Mellanox Technologies Ltd. 2001-2013.  ALL RIGHTS RESERVED.
*
* $COPYRIGHT$
* $HEADER$
*/

#include "test.h"

extern "C" {
#include <ucs/config/parser.h>
#include <ucs/config/global_opts.h>
}

#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>

namespace ucs {

test_base::test_base() : m_state(NEW) {
}

test_base::~test_base() {
    ucs_assertv_always(m_state == FINISHED ||
                       m_state == SKIPPED ||
                       m_state == ABORTED,
                       "state=%d", m_state);
}

void test_base::set_config(void *opts, ucs_config_field_t *fields,
                           const std::string& name, const std::string& value)
{
    ucs_status_t status = ucs_config_parser_set_value(opts, fields, name.c_str(),
                                                      value.c_str());
    if (status != UCS_OK) {
        GTEST_FAIL() << "Invalid UCS configuration for " << name << " : " << value;
    }
}

void test_base::set_config(const std::string& name, const std::string& value)
{
    set_config(&ucs_global_opts, ucs_global_opts_table, name, value);
}

void test_base::push_config()
{
    m_config_stack.push_back(ucs_global_opts_t());
    ucs_config_parser_clone_opts(&ucs_global_opts, &m_config_stack.back(),
                                 ucs_global_opts_table);
}

void test_base::pop_config()
{
    ucs_config_parser_release_opts(&ucs_global_opts, ucs_global_opts_table);
    ucs_global_opts = m_config_stack.back();
}

void test_base::set_multi_config(const std::string& multi_config) {
    std::vector<std::string> tokens;
    boost::split(tokens, multi_config, boost::is_any_of("="));
    set_config(tokens[0], tokens[1]);
}

void test_base::SetUpProxy() {
    ucs_assert(m_state == NEW);
    m_num_valgrind_errors_before = VALGRIND_COUNT_ERRORS;

    try {
        init();
        m_state = RUNNING;
    } catch (test_skip_exception&) {
        detail::message_stream("SKIP");
        m_state = SKIPPED;
    } catch (test_abort_exception&) {
        m_state = ABORTED;
    }
}

void test_base::TearDownProxy() {
    ucs_assertv_always(m_state == FINISHED ||
                       m_state == SKIPPED ||
                       m_state == ABORTED,
                       "state=%d", m_state);
    cleanup();
    int num_valgrind_errors = VALGRIND_COUNT_ERRORS - m_num_valgrind_errors_before;
    if (num_valgrind_errors > 0) {
        ADD_FAILURE() << "Got " << num_valgrind_errors << " valgrind errors during the test";
    }
}

void test_base::TestBodyProxy() {
    if (m_state == RUNNING) {
        try {
            test_body();
            m_state = FINISHED;
        } catch (test_skip_exception&) {
            detail::message_stream("SKIP");
            m_state = SKIPPED;
        } catch (test_abort_exception&) {
            m_state = ABORTED;
        }
    } else if (m_state == SKIPPED) {
    } else if (m_state == ABORTED) {
    }
}

void test_base::init() {
}

void test_base::cleanup() {
}

}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkProbeFilter.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkProbeFilter.hh"

vtkProbeFilter::vtkProbeFilter()
{
  this->Source = NULL;
}

void vtkProbeFilter::Execute()
{
  int cellId, ptId;
  float *x, tol2;
  vtkCell *cell;
  vtkPointData *pd, *outPD;
  int numPts, subId;
  vtkDataSet *source=this->Source, *input=this->Input;
  vtkDataSet *output=this->Output;
  float pcoords[3], *weights=new float[input->GetMaxCellSize()];

  vtkDebugMacro(<<"Probing data");

  pd = source->GetPointData();
  numPts = input->GetNumberOfPoints();
//
// Allocate storage for output PointData
//
  outPD = output->GetPointData();
  outPD->InterpolateAllocate(pd);
//
// Use tolerance as a function of size of source data
//
  tol2 = source->GetLength();
  tol2 = tol2*tol2 / 1000.0;
//
// Loop over all input points, interpolating source data
//
  for (ptId=0; ptId < numPts; ptId++)
    {
    x = input->GetPoint(ptId);
    cellId = source->FindCell(x,NULL,tol2,subId,pcoords,weights);
    if ( cellId >= 0 )
      {
      cell = source->GetCell(cellId);
      outPD->InterpolatePoint(pd,ptId,&(cell->PointIds),weights);
      }
    else
      {
      outPD->NullPoint(ptId);
      }
    }
  delete [] weights;
}

// Description:
// Overload update method because execution can branch two ways (Input
// and Source). Also input and output are abstract.
void vtkProbeFilter::Update()
{
  // make sure output has been created
  if ( !this->Output )
    {
    vtkErrorMacro(<< "No output has been created...need to set input");
    return;
    }

  // make sure input is available
  if ( this->Source == NULL || this->Input == NULL )
    {
    vtkErrorMacro(<< "No input...can't execute!");
    return;
    }

  // prevent chasing our tail
  if (this->Updating) return;

  this->Updating = 1;
  this->Source->Update();
  this->Input->Update();
  this->Updating = 0;

  if (this->Source->GetMTime() > this->ExecuteTime ||
  this->Input->GetMTime() > this->ExecuteTime ||
  this->GetMTime() > this->ExecuteTime || this->GetDataReleased() )
    {
    if ( this->StartMethod ) (*this->StartMethod)(this->StartMethodArg);
    this->Output->CopyStructure(this->Input);
    this->Execute();
    this->ExecuteTime.Modified();
    this->SetDataReleased(0);
    if ( this->EndMethod ) (*this->EndMethod)(this->EndMethodArg);
    }

  if ( this->Source->ShouldIReleaseData() ) this->Source->ReleaseData();
  if ( this->Input->ShouldIReleaseData() ) this->Input->ReleaseData();
}

void vtkProbeFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkDataSetToDataSetFilter::PrintSelf(os,indent);

  os << indent << "Source: " << this->Source << "\n";
}
<commit_msg>fixed a bad memory bug<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkProbeFilter.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkProbeFilter.hh"

vtkProbeFilter::vtkProbeFilter()
{
  this->Source = NULL;
}

void vtkProbeFilter::Execute()
{
  int cellId, ptId;
  float *x, tol2;
  vtkCell *cell;
  vtkPointData *pd, *outPD;
  int numPts, subId;
  vtkDataSet *source=this->Source, *input=this->Input;
  vtkDataSet *output=this->Output;
  float pcoords[3], *weights=new float[source->GetMaxCellSize()];

  vtkDebugMacro(<<"Probing data");

  pd = source->GetPointData();
  numPts = input->GetNumberOfPoints();
//
// Allocate storage for output PointData
//
  outPD = output->GetPointData();
  outPD->InterpolateAllocate(pd);
//
// Use tolerance as a function of size of source data
//
  tol2 = source->GetLength();
  tol2 = tol2*tol2 / 1000.0;
//
// Loop over all input points, interpolating source data
//
  for (ptId=0; ptId < numPts; ptId++)
    {
    x = input->GetPoint(ptId);
    cellId = source->FindCell(x,NULL,tol2,subId,pcoords,weights);
    if ( cellId >= 0 )
      {
      cell = source->GetCell(cellId);
      outPD->InterpolatePoint(pd,ptId,&(cell->PointIds),weights);
      }
    else
      {
      outPD->NullPoint(ptId);
      }
    }
  delete [] weights;
}

// Description:
// Overload update method because execution can branch two ways (Input
// and Source). Also input and output are abstract.
void vtkProbeFilter::Update()
{
  // make sure output has been created
  if ( !this->Output )
    {
    vtkErrorMacro(<< "No output has been created...need to set input");
    return;
    }

  // make sure input is available
  if ( this->Source == NULL || this->Input == NULL )
    {
    vtkErrorMacro(<< "No input...can't execute!");
    return;
    }

  // prevent chasing our tail
  if (this->Updating) return;

  this->Updating = 1;
  this->Source->Update();
  this->Input->Update();
  this->Updating = 0;

  if (this->Source->GetMTime() > this->ExecuteTime ||
  this->Input->GetMTime() > this->ExecuteTime ||
  this->GetMTime() > this->ExecuteTime || this->GetDataReleased() )
    {
    if ( this->StartMethod ) (*this->StartMethod)(this->StartMethodArg);
    this->Output->CopyStructure(this->Input);
    this->Execute();
    this->ExecuteTime.Modified();
    this->SetDataReleased(0);
    if ( this->EndMethod ) (*this->EndMethod)(this->EndMethodArg);
    }

  if ( this->Source->ShouldIReleaseData() ) this->Source->ReleaseData();
  if ( this->Input->ShouldIReleaseData() ) this->Input->ReleaseData();
}

void vtkProbeFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkDataSetToDataSetFilter::PrintSelf(os,indent);

  os << indent << "Source: " << this->Source << "\n";
}
<|endoftext|>


<commit_before>// __BEGIN_LICENSE__
//
// Copyright (C) 2006 United States Government as represented by the
// Administrator of the National Aeronautics and Space Administration
// (NASA).  All Rights Reserved.
//
// Copyright 2006 Carnegie Mellon University. All rights reserved.
//
// This software is distributed under the NASA Open Source Agreement
// (NOSA), version 1.3.  The NOSA has been approved by the Open Source
// Initiative.  See the file COPYING at the top of the distribution
// directory tree for the complete NOSA document.
//
// THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
// KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
// LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
// SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
// A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
// THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
// DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
//
// __END_LICENSE__
#ifdef _MSC_VER
#pragma warning(disable:4244)
#pragma warning(disable:4267)
#pragma warning(disable:4996)
#endif

#include <string>
#include <fstream>
#include <vector>
#include <sys/types.h>
#include <sys/stat.h>

#include <boost/operators.hpp>
#include <boost/program_options.hpp>
namespace po = boost::program_options;
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/convenience.hpp>
#include <boost/filesystem/fstream.hpp>
namespace fs = boost::filesystem;

#include <vw/Core/Debugging.h>
#include <vw/Image/BlockRasterize.h>
#include <vw/FileIO/DiskImageView.h>
#include <vw/Mosaic/QuadTreeGenerator.h>
#include <vw/Mosaic/ImageComposite.h>

std::vector<std::string> image_files;
std::string mosaic_name;
std::string file_type;
unsigned int cache_size;
int patch_size, patch_overlap;
bool draft;
bool qtree;

template <class PixelT>
void do_blend() {
  vw::mosaic::ImageComposite<PixelT> composite;
  if( draft ) composite.set_draft_mode( true );

  for(unsigned int i=0; i < image_files.size(); i++) {
      std::cout << "Adding file: " << image_files[i] << std::endl;
  }

  std::map<std::string,fs::path> image_files;
  std::map<std::string,fs::path> offset_files;
  fs::path source_dir_path( mosaic_name, fs::native );
  fs::directory_iterator pi( source_dir_path ), pend;
  for( ; pi != pend; ++pi ) {
    if( extension(*pi) == ".offset" )
      offset_files[basename(*pi)] = *pi;
    else image_files[basename(*pi)] = *pi;
  }
  std::map<std::string,fs::path>::iterator ofi=offset_files.begin(), ofend=offset_files.end();
  for( ; ofi != ofend; ++ofi ) {
    std::map<std::string,fs::path>::iterator ifi = image_files.find( ofi->first );
    if( ifi != image_files.end() ) {
      fs::ifstream offset( ofi->second );
      int x, y;
      offset >> x >> y;
      std::cout << "Importing image file " << ifi->second.string() << " at offet (" << x << "," << y << ")" << std::endl;
      composite.insert( vw::DiskImageView<PixelT>( ifi->second.string(), false ), x, y );
    }
  }

  vw::vw_out(vw::InfoMessage) << "Preparing the composite..." << std::endl;
  composite.prepare();
  if( qtree ) {
    vw::vw_out(vw::InfoMessage) << "Preparing the quadtree..." << std::endl;
    vw::mosaic::ImageQuadTreeGenerator<PixelT > quadtree( mosaic_name, composite );
    quadtree.set_output_image_file_type( file_type );
    quadtree.set_patch_size( patch_size );
    quadtree.set_patch_overlap( patch_overlap );
    vw::vw_out(vw::InfoMessage) << "Generating..." << std::endl;
    quadtree.generate();
    vw::vw_out(vw::InfoMessage) << "Done!" << std::endl;
  }
  else {
    vw::vw_out(vw::InfoMessage) << "Blending..." << std::endl;
    write_image( mosaic_name+".blend."+file_type, composite );
    vw::vw_out(vw::InfoMessage) << "Done!" << std::endl;
  }
}

int main( int argc, char *argv[] ) {
  try {
    po::options_description desc("Options");
    desc.add_options()
      ("help", "Display this help message")
      ("input-dir", po::value<std::string>(&mosaic_name), "Explicitly specify the input directory")
      ("file-type", po::value<std::string>(&file_type)->default_value("png"), "Output file type")
      ("patch-size", po::value<int>(&patch_size)->default_value(256), "Patch size, in pixels")
      ("patch-overlap", po::value<int>(&patch_overlap)->default_value(0), "Patch overlap, in pixels (must be even)")
      ("cache", po::value<unsigned>(&cache_size)->default_value(1024), "Cache size, in megabytes")
      ("draft", "Draft mode (no blending)")
      ("qtree", "Output in quadtree format")
      ("grayscale", "Process in grayscale only")
      ("verbose", "Verbose output");
    po::positional_options_description p;
    p.add("input-dir", 1);

    po::variables_map vm;
    po::store( po::command_line_parser( argc, argv ).options(desc).positional(p).run(), vm );
    po::notify( vm );

    if( vm.count("help") ) {
      std::cout << desc << std::endl;
      return 1;
    }

    if( vm.count("input-dir") != 1 ) {
      std::cout << "Error: Must specify one (and only one) input directory!" << std::endl;
      std::cout << desc << std::endl;
      return 1;
    }

    if( vm.count("verbose") ) {
      vw::set_debug_level(vw::VerboseDebugMessage);
    }

    if( vm.count("draft") ) draft = true; else draft = false;
    if( vm.count("qtree") ) qtree = true; else qtree = false;

    if( patch_size <= 0 ) {
      std::cerr << "Error: The patch size must be a positive number!  (You specified " << patch_size << ".)" << std::endl;
      std::cout << desc << std::endl;
      return 1;
    }

    if( patch_overlap<0 || patch_overlap>=patch_size || patch_overlap%2==1 ) {
      std::cerr << "Error: The patch overlap must be an even number nonnegative number" << std::endl;
      std::cerr << "smaller than the patch size!  (You specified " << patch_overlap << ".)" << std::endl;
      std::cout << desc << std::endl;
      return 1;
    }

    vw::Cache::system_cache().resize( cache_size*1024*1024 );

    if( vm.count("grayscale") ) {
      do_blend<vw::PixelGrayA<float> >();
    }
    else {
      do_blend<vw::PixelRGBA<float> >();
    }

  }
  catch( std::exception &err ) {
    vw::vw_out(vw::ErrorMessage) << "Error: " << err.what() << std::endl << "Aborting!" << std::endl;
    return 1;
  }
  return 0;
}
<commit_msg>clean up the blend tool a bit<commit_after>// __BEGIN_LICENSE__
//
// Copyright (C) 2006 United States Government as represented by the
// Administrator of the National Aeronautics and Space Administration
// (NASA).  All Rights Reserved.
//
// Copyright 2006 Carnegie Mellon University. All rights reserved.
//
// This software is distributed under the NASA Open Source Agreement
// (NOSA), version 1.3.  The NOSA has been approved by the Open Source
// Initiative.  See the file COPYING at the top of the distribution
// directory tree for the complete NOSA document.
//
// THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
// KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
// LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
// SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
// A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
// THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
// DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
//
// __END_LICENSE__
#ifdef _MSC_VER
#pragma warning(disable:4244)
#pragma warning(disable:4267)
#pragma warning(disable:4996)
#endif

#include <string>
#include <fstream>
#include <vector>
#include <sys/types.h>
#include <sys/stat.h>

#include <boost/operators.hpp>
#include <boost/program_options.hpp>
namespace po = boost::program_options;
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/convenience.hpp>
#include <boost/filesystem/fstream.hpp>
namespace fs = boost::filesystem;

#include <vw/Core/Debugging.h>
#include <vw/Image/BlockRasterize.h>
#include <vw/FileIO/DiskImageView.h>
#include <vw/Mosaic/QuadTreeGenerator.h>
#include <vw/Mosaic/ImageComposite.h>

using namespace std;
using namespace vw;

string mosaic_name;
string file_type;
unsigned int cache_size;
int patch_size, patch_overlap;
bool draft;
bool qtree;

template <class PixelT>
void do_blend() {
  mosaic::ImageComposite<PixelT> composite;
  if( draft ) composite.set_draft_mode( true );

  map<string,fs::path> image_files;
  map<string,fs::path> offset_files;
  fs::path source_dir_path( mosaic_name, fs::native );
  fs::directory_iterator pi( source_dir_path ), pend;
  for( ; pi != pend; ++pi ) {
    if( extension(*pi) == ".offset" )
      offset_files[basename(*pi)] = *pi;
    else image_files[basename(*pi)] = *pi;
  }
  map<string,fs::path>::iterator ofi=offset_files.begin(), ofend=offset_files.end();
  for( ; ofi != ofend; ++ofi ) {
    map<string,fs::path>::iterator ifi = image_files.find( ofi->first );
    if( ifi != image_files.end() ) {
      fs::ifstream offset( ofi->second );
      int x, y;
      offset >> x >> y;
      cout << "Importing image file " << ifi->second.string() << " at offet (" << x << "," << y << ")" << endl;
      composite.insert( DiskImageView<PixelT>( ifi->second.string(), false ), x, y );
    }
  }

  vw_out(InfoMessage) << "Preparing the composite..." << endl;
  composite.prepare();
  if( qtree ) {
    vw_out(InfoMessage) << "Preparing the quadtree..." << endl;
    mosaic::ImageQuadTreeGenerator<PixelT > quadtree( mosaic_name, composite );
    quadtree.set_output_image_file_type( file_type );
    quadtree.set_patch_size( patch_size );
    quadtree.set_patch_overlap( patch_overlap );
    vw_out(InfoMessage) << "Generating..." << endl;
    quadtree.generate();
    vw_out(InfoMessage) << "Done!" << endl;
  }
  else {
    vw_out(InfoMessage) << "Blending..." << endl;
    write_image( mosaic_name+".blend."+file_type, composite );
    vw_out(InfoMessage) << "Done!" << endl;
  }
}

int main( int argc, char *argv[] ) {
  try {
    po::options_description desc("Options");
    desc.add_options()
      ("help", "Display this help message")
      ("input-dir", po::value<string>(&mosaic_name), "Explicitly specify the input directory")
      ("file-type", po::value<string>(&file_type)->default_value("png"), "Output file type")
      ("patch-size", po::value<int>(&patch_size)->default_value(256), "Patch size, in pixels")
      ("patch-overlap", po::value<int>(&patch_overlap)->default_value(0), "Patch overlap, in pixels (must be even)")
      ("cache", po::value<unsigned>(&cache_size)->default_value(1024), "Cache size, in megabytes")
      ("draft", "Draft mode (no blending)")
      ("qtree", "Output in quadtree format")
      ("grayscale", "Process in grayscale only")
      ("verbose", "Verbose output");
    po::positional_options_description p;
    p.add("input-dir", 1);

    po::variables_map vm;
    po::store( po::command_line_parser( argc, argv ).options(desc).positional(p).run(), vm );
    po::notify( vm );

    if( vm.count("help") ) {
      cout << desc << endl;
      return 1;
    }

    if( vm.count("input-dir") != 1 ) {
      cout << "Error: Must specify one (and only one) input directory!" << endl;
      cout << desc << endl;
      return 1;
    }

    if( vm.count("verbose") ) {
      set_debug_level(VerboseDebugMessage);
    }

    if( vm.count("draft") ) draft = true; else draft = false;
    if( vm.count("qtree") ) qtree = true; else qtree = false;

    if( patch_size <= 0 ) {
      cerr << "Error: The patch size must be a positive number!  (You specified " << patch_size << ".)" << endl;
      cout << desc << endl;
      return 1;
    }

    if( patch_overlap<0 || patch_overlap>=patch_size || patch_overlap%2==1 ) {
      cerr << "Error: The patch overlap must be an even number nonnegative number" << endl;
      cerr << "smaller than the patch size!  (You specified " << patch_overlap << ".)" << endl;
      cout << desc << endl;
      return 1;
    }

    Cache::system_cache().resize( cache_size*1024*1024 );

    if( vm.count("grayscale") ) {
      do_blend<PixelGrayA<float> >();
    }
    else {
      do_blend<PixelRGBA<float> >();
    }

  }
  catch( exception &err ) {
    vw_out(ErrorMessage) << "Error: " << err.what() << endl << "Aborting!" << endl;
    return 1;
  }
  return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 Yandex LLC. All rights reserved.
// Author: Vasily Chekalkin <bacek@yandex-team.ru>

#include "sdch_encoding_handler.h"

#include <cassert>

#include "sdch_pool_alloc.h"
#include "sdch_request_context.h"

namespace sdch {

EncodingHandler::EncodingHandler(RequestContext* ctx, Handler* next)
    : Handler(next), ctx_(ctx), cursize_(0) {
  assert(next_);

  // Output Dictionary server_id first
  next_->on_data(reinterpret_cast<const char*>(ctx_->dict->server_dictid), 9);

  enc_ = pool_alloc<open_vcdiff::VCDiffStreamingEncoder>(
      ctx_->request,
      ctx_->dict->hashed_dict->hashed_dict.get(),
      open_vcdiff::VCD_FORMAT_INTERLEAVED | open_vcdiff::VCD_FORMAT_CHECKSUM,
      false);
	enc_->StartEncodingToInterface(this);
}

EncodingHandler::~EncodingHandler() {}

bool EncodingHandler::init(RequestContext* ctx) {
  return true;
}

ssize_t EncodingHandler::on_data(const char* buf, size_t len) {
  // It will call ".append" which will pass it to the next_
  auto oldsize = cursize_;
  enc_->EncodeChunkToInterface(buf, len, this);
  return cursize_ - oldsize;
}

void EncodingHandler::on_finish() {
  enc_->FinishEncodingToInterface(this);
  return next_->on_finish();
}

open_vcdiff::OutputStringInterface& EncodingHandler::append(const char* s,
                                                            size_t n) {
  next_->on_data(s, n);
  cursize_ += n;
  return *this;
}

void EncodingHandler::clear() { cursize_ = 0; }

void EncodingHandler::push_back(char c) { append(&c, 1); }

void EncodingHandler::ReserveAdditionalBytes(size_t res_arg) {
  // NOOP
}

size_t EncodingHandler::size() const { return cursize_; }

}  // namespace sdch
<commit_msg>Move EncodingHandler initialization into .init method<commit_after>// Copyright (c) 2015 Yandex LLC. All rights reserved.
// Author: Vasily Chekalkin <bacek@yandex-team.ru>

#include "sdch_encoding_handler.h"

#include <cassert>

#include "sdch_pool_alloc.h"
#include "sdch_request_context.h"

namespace sdch {

EncodingHandler::EncodingHandler(RequestContext* ctx, Handler* next)
    : Handler(next), ctx_(ctx), cursize_(0) {
  assert(next_);

}

EncodingHandler::~EncodingHandler() {}

bool EncodingHandler::init(RequestContext* ctx) {
  enc_ = pool_alloc<open_vcdiff::VCDiffStreamingEncoder>(
      ctx_->request,
      ctx_->dict->hashed_dict->hashed_dict.get(),
      open_vcdiff::VCD_FORMAT_INTERLEAVED | open_vcdiff::VCD_FORMAT_CHECKSUM,
      false);
  if (enc_ == nullptr)
    return false;

	if (!enc_->StartEncodingToInterface(this))
    return false;

  // Output Dictionary server_id first
  next_->on_data(reinterpret_cast<const char*>(ctx_->dict->server_dictid), 9);

  return true;
}

ssize_t EncodingHandler::on_data(const char* buf, size_t len) {
  // It will call ".append" which will pass it to the next_
  auto oldsize = cursize_;
  enc_->EncodeChunkToInterface(buf, len, this);
  return cursize_ - oldsize;
}

void EncodingHandler::on_finish() {
  enc_->FinishEncodingToInterface(this);
  return next_->on_finish();
}

open_vcdiff::OutputStringInterface& EncodingHandler::append(const char* s,
                                                            size_t n) {
  next_->on_data(s, n);
  cursize_ += n;
  return *this;
}

void EncodingHandler::clear() { cursize_ = 0; }

void EncodingHandler::push_back(char c) { append(&c, 1); }

void EncodingHandler::ReserveAdditionalBytes(size_t res_arg) {
  // NOOP
}

size_t EncodingHandler::size() const { return cursize_; }

}  // namespace sdch
<|endoftext|>