<commit_before>#include "kontsevich_graph_series.hpp"
#include "util/cartesian_product.hpp"

template <class T>
size_t KontsevichGraphSeries<T>::precision() const
{
    return d_precision;
}

template <class T>
size_t KontsevichGraphSeries<T>::precision(size_t new_precision)
{
    return d_precision = new_precision;
}

template <class T>
void KontsevichGraphSeries<T>::reduce()
{
    auto current_term = this->begin();
    while (current_term != this->end())
    {
        current_term->second.reduce();
        if (current_term->second.size() == 0)
            current_term = this->erase(current_term);
        else
            ++current_term;
    }
}

template <class T>
KontsevichGraphSeries<T> KontsevichGraphSeries<T>::operator()(std::vector< KontsevichGraphSeries<T> > arguments)
{
    KontsevichGraphSeries<T> result;
    // Theoretical precision of the result (may be the theoretical maximum):
    size_t new_precision = precision();
    for (auto& argument : arguments)
        new_precision = std::min(new_precision, argument.precision());
    result.precision(new_precision);
    // Return zero if the series itself or any of its arguments are zero:
    if (this->empty())
        return result;
    for (auto& argument : arguments)
        if (argument.empty())
            return result;
    // Practical precision (actually considering the data available):
    size_t practical_precision = std::min(this->rbegin()->first, new_precision);
    std::vector<size_t> argument_sizes(arguments.size());
    for (size_t i = 0; i != arguments.size(); ++i)
    {
        argument_sizes[i] = arguments[i].rbegin()->first + 1;
    }
    // Actual composition:
    for (size_t n = 0; n <= practical_precision; ++n)
    {
        CartesianProduct multilinearity_indices(argument_sizes);
        for (auto arg_indices = multilinearity_indices.begin(); arg_indices != multilinearity_indices.end(); ++arg_indices) // Multi-linearity
        {
            size_t total_order = n;
            for (size_t i = 0; i != arguments.size(); ++i)
                total_order += (*arg_indices)[i];
            if (total_order > new_precision)
                continue;
            std::vector< KontsevichGraphSum<T> > args(arguments.size());
            for (size_t i = 0; i != arguments.size(); ++i)
                args[i] = arguments[i][(*arg_indices)[i]];
            result[total_order] += (*this)[n](args);
        }
    }
    return result;
}

template <class T>
KontsevichGraphSeries<T>& KontsevichGraphSeries<T>::operator+=(const KontsevichGraphSeries<T>& rhs)
{
    size_t practical_precision = this->rbegin()->first;
    for (size_t n = 0; n <= practical_precision; ++n)
    {
        try {
            (*this)[n] += rhs.at(n);
        }
        catch (std::out_of_range) {}
    }
    return *this;
}

template <class T>
KontsevichGraphSeries<T> operator+(KontsevichGraphSeries<T> lhs, const KontsevichGraphSeries<T> &rhs)
{
    lhs += rhs;
    return lhs;
}

template <class T>
KontsevichGraphSeries<T>& KontsevichGraphSeries<T>::operator-=(const KontsevichGraphSeries<T>& rhs)
{
    size_t practical_precision = this->rbegin()->first;
    for (size_t n = 0; n <= practical_precision; ++n)
    {
        try {
            (*this)[n] -= rhs.at(n);
        }
        catch (std::out_of_range) { }
    }
    return *this;
}

template <class T>
KontsevichGraphSeries<T> operator-(KontsevichGraphSeries<T> lhs, const KontsevichGraphSeries<T>& rhs)
{
    lhs -= rhs;
    return lhs;
}

template <class T>
std::ostream& operator<<(std::ostream& os, const KontsevichGraphSeries<T>& series)
{
    if (series.size() == 0)
        return os << "0";
    auto final_term = series.end();
    --final_term;
    for (auto term = series.begin(); term != series.end(); term++)
    {
        if (term->first == 0)
            os << term->second;
        else
            os << "(" << term->second << ")*h^" << term->first;
        if (term != final_term)
            os << " + ";
    }
    return os;
}
<commit_msg>Don't compute (way) too many coefficients when taking the star product of series with limited precision.<commit_after>#include "kontsevich_graph_series.hpp"
#include "util/cartesian_product.hpp"

template <class T>
size_t KontsevichGraphSeries<T>::precision() const
{
    return d_precision;
}

template <class T>
size_t KontsevichGraphSeries<T>::precision(size_t new_precision)
{
    return d_precision = new_precision;
}

template <class T>
void KontsevichGraphSeries<T>::reduce()
{
    auto current_term = this->begin();
    while (current_term != this->end())
    {
        current_term->second.reduce();
        if (current_term->second.size() == 0)
            current_term = this->erase(current_term);
        else
            ++current_term;
    }
}

template <class T>
KontsevichGraphSeries<T> KontsevichGraphSeries<T>::operator()(std::vector< KontsevichGraphSeries<T> > arguments)
{
    KontsevichGraphSeries<T> result;
    // Theoretical precision of the result (may be the theoretical maximum):
    size_t new_precision = precision();
    for (auto& argument : arguments)
        new_precision = std::min(new_precision, argument.precision());
    result.precision(new_precision);
    // Return zero if the series itself or any of its arguments are zero:
    if (this->empty())
        return result;
    for (auto& argument : arguments)
        if (argument.empty())
            return result;
    // Practical precision (actually considering the data available):
    size_t practical_precision = std::min(this->rbegin()->first, new_precision);
    std::vector<size_t> argument_sizes(arguments.size());
    for (size_t i = 0; i != arguments.size(); ++i)
    {
        argument_sizes[i] = arguments[i].rbegin()->first + 1;
    }
    // Actual composition:
    for (size_t n = 0; n <= practical_precision; ++n)
    {
        CartesianProduct multilinearity_indices(argument_sizes);
        for (auto arg_indices = multilinearity_indices.begin(); arg_indices != multilinearity_indices.end(); ++arg_indices) // Multi-linearity
        {
            size_t total_order = n;
            for (size_t i = 0; i != arguments.size(); ++i)
                total_order += (*arg_indices)[i];
            if (total_order > practical_precision)
                continue;
            std::vector< KontsevichGraphSum<T> > args(arguments.size());
            for (size_t i = 0; i != arguments.size(); ++i)
                args[i] = arguments[i][(*arg_indices)[i]];
            result[total_order] += (*this)[n](args);
        }
    }
    return result;
}

template <class T>
KontsevichGraphSeries<T>& KontsevichGraphSeries<T>::operator+=(const KontsevichGraphSeries<T>& rhs)
{
    size_t practical_precision = this->rbegin()->first;
    for (size_t n = 0; n <= practical_precision; ++n)
    {
        try {
            (*this)[n] += rhs.at(n);
        }
        catch (std::out_of_range) {}
    }
    return *this;
}

template <class T>
KontsevichGraphSeries<T> operator+(KontsevichGraphSeries<T> lhs, const KontsevichGraphSeries<T> &rhs)
{
    lhs += rhs;
    return lhs;
}

template <class T>
KontsevichGraphSeries<T>& KontsevichGraphSeries<T>::operator-=(const KontsevichGraphSeries<T>& rhs)
{
    size_t practical_precision = this->rbegin()->first;
    for (size_t n = 0; n <= practical_precision; ++n)
    {
        try {
            (*this)[n] -= rhs.at(n);
        }
        catch (std::out_of_range) { }
    }
    return *this;
}

template <class T>
KontsevichGraphSeries<T> operator-(KontsevichGraphSeries<T> lhs, const KontsevichGraphSeries<T>& rhs)
{
    lhs -= rhs;
    return lhs;
}

template <class T>
std::ostream& operator<<(std::ostream& os, const KontsevichGraphSeries<T>& series)
{
    if (series.size() == 0)
        return os << "0";
    auto final_term = series.end();
    --final_term;
    for (auto term = series.begin(); term != series.end(); term++)
    {
        if (term->first == 0)
            os << term->second;
        else
            os << "(" << term->second << ")*h^" << term->first;
        if (term != final_term)
            os << " + ";
    }
    return os;
}
<|endoftext|>


<commit_before>#include "ev3api.h"
#include "SoundPlayTask.h"
#include "app.h"

#define SILENT_MODE 1

void Play(const char* fileName)
{
    memfile_t mem;
    ev3_memfile_load(fileName, &mem);
    ev3_speaker_set_volume(10);
    ev3_speaker_play_file(&mem, SOUND_MANUAL_STOP);
    ev3_memfile_free(&mem);
}

// 音声再生タスク
void sound_play_task(intptr_t exinf)
{
    intptr_t id;
    SoundType type;
    while(1){
        rcv_dtq(DT_QID, &id);
        type = (SoundType)id;
        switch(type)
        {
            case SensorInitialStart:
                Play("/ev3rt/sound/S01.wav");
                break;
            case SensorInitialEnd:
                Play("/ev3rt/sound/S02.wav");
                break;
            case LCourseStart:
                Play("/ev3rt/sound/S03.wav");
                break;
            case RCourseStart:
                Play("/ev3rt/sound/S04.wav");
                break;
            case BlockEnd:
                Play("/ev3rt/sound/S05.wav");
                break;
            case RuleReceive:
                Play("/ev3rt/sound/S06.wav");
                break;
            case PIDReceive:
                Play("/ev3rt/sound/S07.wav");
                break;
        }
    }
}

void PlaySound(SoundType s)
{
#ifndef SILENT_MODE
    snd_dtq(DT_QID, s);
#endif
}<commit_msg>音声再生を有効化<commit_after>#include "ev3api.h"
#include "SoundPlayTask.h"
#include "app.h"

//#define SILENT_MODE 1

void Play(const char* fileName)
{
    memfile_t mem;
    ev3_memfile_load(fileName, &mem);
    ev3_speaker_set_volume(10);
    ev3_speaker_play_file(&mem, SOUND_MANUAL_STOP);
    ev3_memfile_free(&mem);
}

// 音声再生タスク
void sound_play_task(intptr_t exinf)
{
    intptr_t id;
    SoundType type;
    while(1){
        rcv_dtq(DT_QID, &id);
        type = (SoundType)id;
        switch(type)
        {
            case SensorInitialStart:
                Play("/ev3rt/sound/S01.wav");
                break;
            case SensorInitialEnd:
                Play("/ev3rt/sound/S02.wav");
                break;
            case LCourseStart:
                Play("/ev3rt/sound/S03.wav");
                break;
            case RCourseStart:
                Play("/ev3rt/sound/S04.wav");
                break;
            case BlockEnd:
                Play("/ev3rt/sound/S05.wav");
                break;
            case RuleReceive:
                Play("/ev3rt/sound/S06.wav");
                break;
            case PIDReceive:
                Play("/ev3rt/sound/S07.wav");
                break;
        }
    }
}

void PlaySound(SoundType s)
{
#ifndef SILENT_MODE
    snd_dtq(DT_QID, s);
#endif
}<|endoftext|>


<commit_before>/***************************************************************************
 * Copyright (c) 2009-2010 Open Information Security Foundation
 * Copyright (c) 2010-2013 Qualys, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.

 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.

 * - Neither the name of the Qualys, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ***************************************************************************/

/**
 * @file
 * @author Ivan Ristic <ivanr@webkreator.com>
 */

#include <iostream>
#include <gtest/gtest.h>
#include <htp/htp.h>
#include <htp/htp_transaction.h>
#include <htp/htp_base64.h>
#include "test.h"

class Multipart : public testing::Test {
protected:

    virtual void SetUp() {
        cfg = htp_config_create();
        htp_config_set_server_personality(cfg, HTP_SERVER_APACHE_2);
    }

    virtual void TearDown() {
        htp_config_destroy(cfg);
    }

    htp_cfg_t *cfg;
};

TEST_F(Multipart, Test1) {
    char boundary[] = "---------------------------41184676334";

    htp_mpartp_t *mpartp = htp_mpartp_create(cfg);
    htp_mpartp_init_boundary_ex(mpartp, boundary);

    char* parts[999];

    size_t i = 0;
    parts[i++] = (char *) "-----------------------------41184676334\r\n";
    parts[i++] = (char *) "Content-Disposition: form-data;\n name=\"field1\"\r\n";
    parts[i++] = (char *) "\r\n";
    parts[i++] = (char *) "0123456789\r\n-";
    parts[i++] = (char *) "-------------";
    parts[i++] = (char *) "---------------41184676334\r\n";
    parts[i++] = (char *) "Content-Disposition: form-data;\n name=\"field2\"\r\n";
    parts[i++] = (char *) "\r\n";
    parts[i++] = (char *) "0123456789\r\n-";
    parts[i++] = (char *) "-------------";
    parts[i++] = (char *) "--------------X\r\n";
    parts[i++] = (char *) "-----------------------------41184676334\r\n";
    parts[i++] = (char *) "Content-Disposition: form-data;\n";
    parts[i++] = (char *) " ";
    parts[i++] = (char *) "name=\"field3\"\r\n";
    parts[i++] = (char *) "\r\n";
    parts[i++] = (char *) "9876543210\r\n";
    parts[i++] = (char *) "-----------------------------41184676334\r\n";
    parts[i++] = (char *) "Content-Disposition: form-data; name=\"file1\"; filename=\"New Text Document.txt\"\r\nContent-Type: text/plain\r\n\r\n";
    parts[i++] = (char *) "1FFFFFFFFFFFFFFFFFFFFFFFFFFF\r\n";
    parts[i++] = (char *) "2FFFFFFFFFFFFFFFFFFFFFFFFFFE\r";
    parts[i++] = (char *) "3FFFFFFFFFFFFFFFFFFFFFFFFFFF\r\n4FFFFFFFFFFFFFFFFFFFFFFFFF123456789";
    parts[i++] = (char *) "\r\n";
    parts[i++] = (char *) "-----------------------------41184676334\r\n";
    parts[i++] = (char *) "Content-Disposition: form-data; name=\"file2\"; filename=\"New Text Document.txt\"\r\n";
    parts[i++] = (char *) "Content-Type: text/plain\r\n";
    parts[i++] = (char *) "\r\n";
    parts[i++] = (char *) "FFFFFFFFFFFFFFFFFFFFFFFFFFFZ";
    // Final boundary should not go here
    parts[i++] = NULL;

    i = 0;
    for (;;) {
        if (parts[i] == NULL) break;
        htp_mpartp_parse(mpartp, (const unsigned char *) parts[i], strlen(parts[i]));
        i++;
    }

    // Send the final boundary
    htp_mpartp_parse(mpartp, (const unsigned char *) &"\r\n", 2);
    htp_mpartp_parse(mpartp, (const unsigned char *) boundary, strlen(boundary));
    htp_mpartp_parse(mpartp, (const unsigned char *) &"--", 2);

    htp_mpartp_finalize(mpartp);

    // Examine the result
    htp_multipart_t *body = htp_mpartp_get_multipart(mpartp);
    ASSERT_TRUE(body != NULL);

    for (size_t i = 0, n = htp_list_size(body->parts); i < n; i++) {
        htp_multipart_part_t *part = (htp_multipart_part_t *) htp_list_get(body->parts, i);

        switch (i) {
            case 0:
                ASSERT_TRUE(bstr_cmp_c(part->name, "field1") == 0);
                ASSERT_EQ(part->type, MULTIPART_PART_TEXT);
                ASSERT_TRUE(part->value != NULL);
                ASSERT_TRUE(bstr_cmp_c(part->value, "0123456789") == 0);
                break;
            case 1:
                ASSERT_TRUE(bstr_cmp_c(part->name, "field2") == 0);
                ASSERT_EQ(part->type, MULTIPART_PART_TEXT);
                ASSERT_TRUE(bstr_cmp_c(part->value, "0123456789\r\n----------------------------X") == 0);
                break;
            case 2:
                ASSERT_TRUE(bstr_cmp_c(part->name, "field3") == 0);
                ASSERT_EQ(part->type, MULTIPART_PART_TEXT);
                ASSERT_TRUE(part->value != NULL);
                ASSERT_TRUE(bstr_cmp_c(part->value, "9876543210") == 0);
                break;
            case 3:
                ASSERT_TRUE(bstr_cmp_c(part->name, "file1") == 0);
                ASSERT_EQ(part->type, MULTIPART_PART_FILE);
                break;
            case 4:
                ASSERT_TRUE(bstr_cmp_c(part->name, "file2") == 0);
                ASSERT_EQ(part->type, MULTIPART_PART_FILE);
                break;
            default:
                FAIL() << "More parts than expected";
                break;
        }
    }

    htp_mpartp_destroy(&mpartp);
}

TEST_F(Multipart, Test2) {
    htp_mpartp_t *mpartp = htp_mpartp_create(cfg);
    htp_mpartp_init_boundary_ex(mpartp, "BBB");

    const char *i1 = "x0000x\n--BBB\n\nx1111x\n--\nx2222x\n--";
    const char *i2 = "BBB\n\nx3333x\n--B";
    const char *i3 = "B\n\nx4444x\n--BB\r";
    const char *i4 = "\n--B";
    const char *i5 = "B";
    const char *i6 = "B\n\nx5555x\r";
    const char *i7 = "\n--x6666x\r";
    const char *i8 = "-";
    const char *i9 = "-";

    htp_mpartp_parse(mpartp, (const unsigned char *) i1, strlen(i1));
    htp_mpartp_parse(mpartp, (const unsigned char *) i2, strlen(i2));
    htp_mpartp_parse(mpartp, (const unsigned char *) i3, strlen(i3));
    htp_mpartp_parse(mpartp, (const unsigned char *) i4, strlen(i4));
    htp_mpartp_parse(mpartp, (const unsigned char *) i5, strlen(i5));
    htp_mpartp_parse(mpartp, (const unsigned char *) i6, strlen(i6));
    htp_mpartp_parse(mpartp, (const unsigned char *) i7, strlen(i7));
    htp_mpartp_parse(mpartp, (const unsigned char *) i8, strlen(i8));
    htp_mpartp_parse(mpartp, (const unsigned char *) i9, strlen(i9));
    htp_mpartp_finalize(mpartp);

    htp_multipart_t *body = htp_mpartp_get_multipart(mpartp);
    ASSERT_TRUE(body != NULL);

    for (size_t i = 0, n = htp_list_size(body->parts); i < n; i++) {
        htp_multipart_part_t *part = (htp_multipart_part_t *) htp_list_get(body->parts, i);

        switch (i) {
            case 0:
                ASSERT_EQ(part->type, 3);
                ASSERT_TRUE(part->value == NULL); // Not keeping prologue data at the moment
                break;
            case 1:
                ASSERT_EQ(part->type, 1);
                ASSERT_TRUE(part->value != NULL);
                ASSERT_TRUE(bstr_cmp_c(part->value, "x1111x\n--\nx2222x") == 0);
                break;
            case 2:
                ASSERT_EQ(part->type, 1);
                ASSERT_TRUE(part->value != NULL);
                ASSERT_TRUE(bstr_cmp_c(part->value, "x3333x\n--BB\n\nx4444x\n--BB") == 0);
                break;
            case 3:
                ASSERT_EQ(part->type, 1);
                ASSERT_TRUE(part->value != NULL);
                ASSERT_TRUE(bstr_cmp_c(part->value, "x5555x\r\n--x6666x\r--") == 0);
                break;
            default:
                FAIL();

        }
    }

    htp_mpartp_destroy(&mpartp);
}
<commit_msg>New multipart tests.<commit_after>/***************************************************************************
 * Copyright (c) 2009-2010 Open Information Security Foundation
 * Copyright (c) 2010-2013 Qualys, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.

 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.

 * - Neither the name of the Qualys, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ***************************************************************************/

/**
 * @file
 * @author Ivan Ristic <ivanr@webkreator.com>
 */

#include <iostream>
#include <gtest/gtest.h>
#include <htp/htp.h>
#include <htp/htp_transaction.h>
#include <htp/htp_base64.h>
#include "test.h"

class Multipart : public testing::Test {
protected:

    virtual void SetUp() {
        cfg = htp_config_create();
        htp_config_set_server_personality(cfg, HTP_SERVER_APACHE_2);
    }

    virtual void TearDown() {
        htp_config_destroy(cfg);
    }

    htp_cfg_t *cfg;
};

TEST_F(Multipart, Test1) {
    char boundary[] = "---------------------------41184676334";

    htp_mpartp_t *mpartp = htp_mpartp_create(cfg);
    htp_mpartp_init_boundary_ex(mpartp, boundary);

    char *parts[999];

    size_t i = 0;
    parts[i++] = (char *) "-----------------------------41184676334\r\n";
    parts[i++] = (char *) "Content-Disposition: form-data;\n name=\"field1\"\r\n";
    parts[i++] = (char *) "\r\n";
    parts[i++] = (char *) "0123456789\r\n-";
    parts[i++] = (char *) "-------------";
    parts[i++] = (char *) "---------------41184676334\r\n";
    parts[i++] = (char *) "Content-Disposition: form-data;\n name=\"field2\"\r\n";
    parts[i++] = (char *) "\r\n";
    parts[i++] = (char *) "0123456789\r\n-";
    parts[i++] = (char *) "-------------";
    parts[i++] = (char *) "--------------X\r\n";
    parts[i++] = (char *) "-----------------------------41184676334\r\n";
    parts[i++] = (char *) "Content-Disposition: form-data;\n";
    parts[i++] = (char *) " ";
    parts[i++] = (char *) "name=\"field3\"\r\n";
    parts[i++] = (char *) "\r\n";
    parts[i++] = (char *) "9876543210\r\n";
    parts[i++] = (char *) "-----------------------------41184676334\r\n";
    parts[i++] = (char *) "Content-Disposition: form-data; name=\"file1\"; filename=\"New Text Document.txt\"\r\nContent-Type: text/plain\r\n\r\n";
    parts[i++] = (char *) "1FFFFFFFFFFFFFFFFFFFFFFFFFFF\r\n";
    parts[i++] = (char *) "2FFFFFFFFFFFFFFFFFFFFFFFFFFE\r";
    parts[i++] = (char *) "3FFFFFFFFFFFFFFFFFFFFFFFFFFF\r\n4FFFFFFFFFFFFFFFFFFFFFFFFF123456789";
    parts[i++] = (char *) "\r\n";
    parts[i++] = (char *) "-----------------------------41184676334\r\n";
    parts[i++] = (char *) "Content-Disposition: form-data; name=\"file2\"; filename=\"New Text Document.txt\"\r\n";
    parts[i++] = (char *) "Content-Type: text/plain\r\n";
    parts[i++] = (char *) "\r\n";
    parts[i++] = (char *) "FFFFFFFFFFFFFFFFFFFFFFFFFFFZ";
    // The final boundary should not go here
    parts[i++] = NULL;

    i = 0;
    for (;;) {
        if (parts[i] == NULL) break;
        htp_mpartp_parse(mpartp, (const unsigned char *) parts[i], strlen(parts[i]));
        i++;
    }

    // Send the final boundary
    htp_mpartp_parse(mpartp, (const unsigned char *) &"\r\n", 2);
    htp_mpartp_parse(mpartp, (const unsigned char *) boundary, strlen(boundary));
    htp_mpartp_parse(mpartp, (const unsigned char *) &"--", 2);

    htp_mpartp_finalize(mpartp);

    // Examine the result
    htp_multipart_t *body = htp_mpartp_get_multipart(mpartp);
    ASSERT_TRUE(body != NULL);

    for (size_t i = 0, n = htp_list_size(body->parts); i < n; i++) {
        htp_multipart_part_t *part = (htp_multipart_part_t *) htp_list_get(body->parts, i);

        switch (i) {
            case 0:
                ASSERT_TRUE(bstr_cmp_c(part->name, "field1") == 0);
                ASSERT_EQ(part->type, MULTIPART_PART_TEXT);
                ASSERT_TRUE(part->value != NULL);
                ASSERT_TRUE(bstr_cmp_c(part->value, "0123456789") == 0);
                break;
            case 1:
                ASSERT_TRUE(bstr_cmp_c(part->name, "field2") == 0);
                ASSERT_EQ(part->type, MULTIPART_PART_TEXT);
                ASSERT_TRUE(bstr_cmp_c(part->value, "0123456789\r\n----------------------------X") == 0);
                break;
            case 2:
                ASSERT_TRUE(bstr_cmp_c(part->name, "field3") == 0);
                ASSERT_EQ(part->type, MULTIPART_PART_TEXT);
                ASSERT_TRUE(part->value != NULL);
                ASSERT_TRUE(bstr_cmp_c(part->value, "9876543210") == 0);
                break;
            case 3:
                ASSERT_TRUE(bstr_cmp_c(part->name, "file1") == 0);
                ASSERT_EQ(part->type, MULTIPART_PART_FILE);
                break;
            case 4:
                ASSERT_TRUE(bstr_cmp_c(part->name, "file2") == 0);
                ASSERT_EQ(part->type, MULTIPART_PART_FILE);
                break;
            default:
                FAIL() << "More parts than expected";
                break;
        }
    }

    htp_mpartp_destroy(&mpartp);
}

TEST_F(Multipart, Test2) {
    htp_mpartp_t *mpartp = htp_mpartp_create(cfg);
    htp_mpartp_init_boundary_ex(mpartp, "BBB");

    const char *i1 = "x0000x\n--BBB\n\nx1111x\n--\nx2222x\n--";
    const char *i2 = "BBB\n\nx3333x\n--B";
    const char *i3 = "B\n\nx4444x\n--BB\r";
    const char *i4 = "\n--B";
    const char *i5 = "B";
    const char *i6 = "B\n\nx5555x\r";
    const char *i7 = "\n--x6666x\r";
    const char *i8 = "-";
    const char *i9 = "-";

    htp_mpartp_parse(mpartp, (const unsigned char *) i1, strlen(i1));
    htp_mpartp_parse(mpartp, (const unsigned char *) i2, strlen(i2));
    htp_mpartp_parse(mpartp, (const unsigned char *) i3, strlen(i3));
    htp_mpartp_parse(mpartp, (const unsigned char *) i4, strlen(i4));
    htp_mpartp_parse(mpartp, (const unsigned char *) i5, strlen(i5));
    htp_mpartp_parse(mpartp, (const unsigned char *) i6, strlen(i6));
    htp_mpartp_parse(mpartp, (const unsigned char *) i7, strlen(i7));
    htp_mpartp_parse(mpartp, (const unsigned char *) i8, strlen(i8));
    htp_mpartp_parse(mpartp, (const unsigned char *) i9, strlen(i9));
    htp_mpartp_finalize(mpartp);

    htp_multipart_t *body = htp_mpartp_get_multipart(mpartp);
    ASSERT_TRUE(body != NULL);

    for (size_t i = 0, n = htp_list_size(body->parts); i < n; i++) {
        htp_multipart_part_t *part = (htp_multipart_part_t *) htp_list_get(body->parts, i);

        switch (i) {
            case 0:
                ASSERT_EQ(part->type, 3);
                ASSERT_TRUE(part->value == NULL); // Not keeping prologue data at the moment
                break;
            case 1:
                ASSERT_EQ(part->type, 1);
                ASSERT_TRUE(part->value != NULL);
                ASSERT_TRUE(bstr_cmp_c(part->value, "x1111x\n--\nx2222x") == 0);
                break;
            case 2:
                ASSERT_EQ(part->type, 1);
                ASSERT_TRUE(part->value != NULL);
                ASSERT_TRUE(bstr_cmp_c(part->value, "x3333x\n--BB\n\nx4444x\n--BB") == 0);
                break;
            case 3:
                ASSERT_EQ(part->type, 1);
                ASSERT_TRUE(part->value != NULL);
                ASSERT_TRUE(bstr_cmp_c(part->value, "x5555x\r\n--x6666x\r--") == 0);
                break;
            default:
                FAIL();

        }
    }

    htp_mpartp_destroy(&mpartp);
}

static void Multipart_Helper(htp_cfg_t *cfg, char *parts[]) {
    char boundary[] = "0123456789";

    htp_mpartp_t *mpartp = htp_mpartp_create(cfg);
    htp_mpartp_init_boundary_ex(mpartp, boundary);

    size_t i = 0;
    for (;;) {
        if (parts[i] == NULL) break;
        htp_mpartp_parse(mpartp, (const unsigned char *) parts[i], strlen(parts[i]));
        i++;
    }

    htp_mpartp_finalize(mpartp);

    // Examine the result
    htp_multipart_t *body = htp_mpartp_get_multipart(mpartp);
    ASSERT_TRUE(body != NULL);

    ASSERT_TRUE(htp_list_size(body->parts) == 2);

    for (size_t i = 0, n = htp_list_size(body->parts); i < n; i++) {
        htp_multipart_part_t *part = (htp_multipart_part_t *) htp_list_get(body->parts, i);

        switch (i) {
            case 0:
                ASSERT_EQ(part->type, MULTIPART_PART_TEXT);
                ASSERT_TRUE(part->name != NULL);
                ASSERT_TRUE(bstr_cmp_c(part->name, "field1") == 0);
                ASSERT_TRUE(part->value != NULL);
                ASSERT_TRUE(bstr_cmp_c(part->value, "ABCDEF") == 0);
                break;
            case 1:
                ASSERT_EQ(part->type, MULTIPART_PART_TEXT);
                ASSERT_TRUE(part->name != NULL);
                ASSERT_TRUE(bstr_cmp_c(part->name, "field2") == 0);
                ASSERT_TRUE(part->value != NULL);
                ASSERT_TRUE(bstr_cmp_c(part->value, "GHIJKL") == 0);
                break;
        }
    }

    htp_mpartp_destroy(&mpartp);
}

TEST_F(Multipart, Test3) {
    char *parts[] = {
        "--0123456789\r\n"
        "Content-Disposition: form-data;\n name=\"field1\"\r\n"
        "\r\n"
        "ABCDEF"
        "\r\n--0123456789\r\n"
        "Content-Disposition: form-data;\n name=\"field2\"\r\n"
        "\r\n"
        "GHIJKL"
        "\r\n--0123456789--",
        NULL
    };

    Multipart_Helper(cfg, parts);
}

TEST_F(Multipart, Test4) {
    char *parts[] = {
        "\r\n--0123456789\r\n"
        "Content-Disposition: form-data;\n name=\"field1\"\r\n"
        "\r\n"
        "ABCDEF"
        "\r\n--0123456789\r\n"
        "Content-Disposition: form-data;\n name=\"field2\"\r\n"
        "\r\n"
        "GHIJKL"
        "\r\n--0123456789--",
        NULL
    };

    Multipart_Helper(cfg, parts);
}

TEST_F(Multipart, Test5) {
    char *parts[] = {
        "\n--0123456789\r\n"
        "Content-Disposition: form-data;\n name=\"field1\"\r\n"
        "\r\n"
        "ABCDEF"
        "\r\n--0123456789\r\n"
        "Content-Disposition: form-data;\n name=\"field2\"\r\n"
        "\r\n"
        "GHIJKL"
        "\r\n--0123456789--",
        NULL
    };

    Multipart_Helper(cfg, parts);
}

TEST_F(Multipart, Test6) {
    char *parts[] = {
        "\n--0123456789\r\n"
        "Content-Disposition: form-data;\n name=\"field1\"\r\n"
        "\r\n"
        "ABCDEF"
        "\r\n--0123456789\r\n"
        "Content-Disposition: form-data;\n name=\"field2\"\r\n"
        "\r\n"
        "GHIJKL"
        "\r\n--0123456789--",
        NULL
    };

    Multipart_Helper(cfg, parts);
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2007, Un Shyam
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include <algorithm>
#include <iostream>

#include "libtorrent/hasher.hpp"
#include "libtorrent/pe_crypto.hpp"
#include "libtorrent/session.hpp"
#include <boost/filesystem/convenience.hpp>

#include "setup_transfer.hpp"
#include "test.hpp"

#ifndef TORRENT_DISABLE_ENCRYPTION

void display_pe_policy(libtorrent::pe_settings::enc_policy policy)
{
	using namespace libtorrent;
	using std::cerr;

	if (policy == pe_settings::disabled) cerr << "disabled ";
	else if (policy == pe_settings::enabled) cerr << "enabled ";
	else if (policy == pe_settings::forced) cerr << "forced ";
}

void display_pe_settings(libtorrent::pe_settings s)
{
	using namespace libtorrent;
	using std::cerr;

	cerr << "out_enc_policy - ";
	display_pe_policy(s.out_enc_policy);
	cerr << "\tin_enc_policy - ";
	display_pe_policy(s.in_enc_policy);

	cerr << "\nenc_level - ";
	if (s.allowed_enc_level == pe_settings::plaintext) cerr << "plaintext ";
	else if (s.allowed_enc_level == pe_settings::rc4) cerr << "rc4 ";
	else if (s.allowed_enc_level == pe_settings::both) cerr << "both ";

	cerr << "\t\tprefer_rc4 - ";
	(s.prefer_rc4) ? cerr << "true" : cerr << "false";
	cerr << "\n\n";
}

void test_transfer(libtorrent::pe_settings::enc_policy policy,
		   libtorrent::pe_settings::enc_level level = libtorrent::pe_settings::both,
		   bool pref_rc4 = false)
{
	using namespace libtorrent;
	using std::cerr;

	session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48800, 49000));
	session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49800, 50000));
	pe_settings s;

	s.out_enc_policy = libtorrent::pe_settings::enabled;
	s.in_enc_policy = libtorrent::pe_settings::enabled;

	s.allowed_enc_level = pe_settings::both;
	ses2.set_pe_settings(s);

	s.out_enc_policy = policy;
	s.in_enc_policy = policy;
	s.allowed_enc_level = level;
	s.prefer_rc4 = pref_rc4;
	ses1.set_pe_settings(s);

// 	s = ses1.get_pe_settings();
// 	cerr << " Session1 \n";
// 	display_pe_settings(s);
// 	s = ses2.get_pe_settings();
// 	cerr << " Session2 \n";
// 	display_pe_settings(s);

	torrent_handle tor1;
	torrent_handle tor2;

	using boost::tuples::ignore;
	boost::tie(tor1, tor2, ignore) = setup_transfer(&ses1, &ses2, 0, true, false, true, "_pe");

	std::cerr << "waiting for transfer to complete\n";

	for (int i = 0; i < 50; ++i)
	{
		tor2.status();
		print_alerts(ses1, "ses1");
		print_alerts(ses2, "ses2");

		if (tor2.is_seed()) break;
		test_sleep(100);
	}

	TEST_CHECK(tor2.is_seed());
 	if (tor2.is_seed()) std::cerr << "done\n";

	using boost::filesystem::remove_all;
	remove_all("./tmp1_pe");
	remove_all("./tmp2_pe");
	remove_all("./tmp3_pe");
}

int test_main()
{
	using namespace libtorrent;
	int repcount = 1024;

	for (int rep = 0; rep < repcount; ++rep)
	{
		DH_key_exchange DH1, DH2;

		DH1.compute_secret(DH2.get_local_key());
		DH2.compute_secret(DH1.get_local_key());

		TEST_CHECK(std::equal(DH1.get_secret(), DH1.get_secret() + 96, DH2.get_secret()));
	}

	DH_key_exchange DH1, DH2;
	DH1.compute_secret(DH2.get_local_key());
	DH2.compute_secret(DH1.get_local_key());

	TEST_CHECK(std::equal(DH1.get_secret(), DH1.get_secret() + 96, DH2.get_secret()));

	sha1_hash test1_key = hasher("test1_key",8).final();
	sha1_hash test2_key = hasher("test2_key",8).final();

	RC4_handler RC41 (test2_key, test1_key);
	RC4_handler RC42 (test1_key, test2_key);

	for (int rep = 0; rep < repcount; ++rep)
	{
		std::size_t buf_len = rand() % (512 * 1024);
		char* buf = new char[buf_len];
		char* zero_buf = new char[buf_len];

		std::fill(buf, buf + buf_len, 0);
		std::fill(zero_buf, zero_buf + buf_len, 0);

		RC41.encrypt(buf, buf_len);
		RC42.decrypt(buf, buf_len);
		TEST_CHECK(std::equal(buf, buf + buf_len, zero_buf));

		RC42.encrypt(buf, buf_len);
		RC41.decrypt(buf, buf_len);
		TEST_CHECK(std::equal(buf, buf + buf_len, zero_buf));

		delete[] buf;
		delete[] zero_buf;
	}

	test_transfer(pe_settings::disabled);

	test_transfer(pe_settings::forced, pe_settings::plaintext);
	test_transfer(pe_settings::forced, pe_settings::rc4);
	test_transfer(pe_settings::forced, pe_settings::both, false);
	test_transfer(pe_settings::forced, pe_settings::both, true);

	test_transfer(pe_settings::enabled, pe_settings::plaintext);
	test_transfer(pe_settings::enabled, pe_settings::rc4);
	test_transfer(pe_settings::enabled, pe_settings::both, false);
	test_transfer(pe_settings::enabled, pe_settings::both, true);

	return 0;
}

#else

int test_main()
{
	std::cerr << "PE test not run because it's disabled" << std::endl;
	return 0;
}

#endif

<commit_msg>updated pe_crypto test to build<commit_after>/*

Copyright (c) 2007, Un Shyam
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include <algorithm>
#include <iostream>

#include "libtorrent/hasher.hpp"
#include "libtorrent/pe_crypto.hpp"
#include "libtorrent/session.hpp"
#include <boost/filesystem/convenience.hpp>

#include "setup_transfer.hpp"
#include "test.hpp"

#ifndef TORRENT_DISABLE_ENCRYPTION

void display_pe_policy(libtorrent::pe_settings::enc_policy policy)
{
	using namespace libtorrent;
	using std::cerr;

	if (policy == pe_settings::disabled) cerr << "disabled ";
	else if (policy == pe_settings::enabled) cerr << "enabled ";
	else if (policy == pe_settings::forced) cerr << "forced ";
}

void display_pe_settings(libtorrent::pe_settings s)
{
	using namespace libtorrent;
	using std::cerr;

	cerr << "out_enc_policy - ";
	display_pe_policy(s.out_enc_policy);
	cerr << "\tin_enc_policy - ";
	display_pe_policy(s.in_enc_policy);

	cerr << "\nenc_level - ";
	if (s.allowed_enc_level == pe_settings::plaintext) cerr << "plaintext ";
	else if (s.allowed_enc_level == pe_settings::rc4) cerr << "rc4 ";
	else if (s.allowed_enc_level == pe_settings::both) cerr << "both ";

	cerr << "\t\tprefer_rc4 - ";
	(s.prefer_rc4) ? cerr << "true" : cerr << "false";
	cerr << "\n\n";
}

void test_transfer(libtorrent::pe_settings::enc_policy policy,
		   libtorrent::pe_settings::enc_level level = libtorrent::pe_settings::both,
		   bool pref_rc4 = false)
{
	using namespace libtorrent;
	using std::cerr;

	session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48800, 49000));
	session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49800, 50000));
	pe_settings s;

	s.out_enc_policy = libtorrent::pe_settings::enabled;
	s.in_enc_policy = libtorrent::pe_settings::enabled;

	s.allowed_enc_level = pe_settings::both;
	ses2.set_pe_settings(s);

	s.out_enc_policy = policy;
	s.in_enc_policy = policy;
	s.allowed_enc_level = level;
	s.prefer_rc4 = pref_rc4;
	ses1.set_pe_settings(s);

// 	s = ses1.get_pe_settings();
// 	cerr << " Session1 \n";
// 	display_pe_settings(s);
// 	s = ses2.get_pe_settings();
// 	cerr << " Session2 \n";
// 	display_pe_settings(s);

	torrent_handle tor1;
	torrent_handle tor2;

	using boost::tuples::ignore;
	boost::tie(tor1, tor2, ignore) = setup_transfer(&ses1, &ses2, 0, true, false, true, "_pe");

	std::cerr << "waiting for transfer to complete\n";

	for (int i = 0; i < 50; ++i)
	{
		tor2.status();
		print_alerts(ses1, "ses1");
		print_alerts(ses2, "ses2");

		if (tor2.is_seed()) break;
		test_sleep(100);
	}

	TEST_CHECK(tor2.is_seed());
 	if (tor2.is_seed()) std::cerr << "done\n";

	using boost::filesystem::remove_all;
	remove_all("./tmp1_pe");
	remove_all("./tmp2_pe");
	remove_all("./tmp3_pe");
}

int test_main()
{
	using namespace libtorrent;
	int repcount = 1024;

	for (int rep = 0; rep < repcount; ++rep)
	{
		dh_key_exchange DH1, DH2;

		DH1.compute_secret(DH2.get_local_key());
		DH2.compute_secret(DH1.get_local_key());

		TEST_CHECK(std::equal(DH1.get_secret(), DH1.get_secret() + 96, DH2.get_secret()));
	}

	dh_key_exchange DH1, DH2;
	DH1.compute_secret(DH2.get_local_key());
	DH2.compute_secret(DH1.get_local_key());

	TEST_CHECK(std::equal(DH1.get_secret(), DH1.get_secret() + 96, DH2.get_secret()));

	sha1_hash test1_key = hasher("test1_key",8).final();
	sha1_hash test2_key = hasher("test2_key",8).final();

	RC4_handler RC41(test2_key, test1_key);
	RC4_handler RC42(test1_key, test2_key);

	for (int rep = 0; rep < repcount; ++rep)
	{
		std::size_t buf_len = rand() % (512 * 1024);
		char* buf = new char[buf_len];
		char* zero_buf = new char[buf_len];

		std::fill(buf, buf + buf_len, 0);
		std::fill(zero_buf, zero_buf + buf_len, 0);

		RC41.encrypt(buf, buf_len);
		RC42.decrypt(buf, buf_len);
		TEST_CHECK(std::equal(buf, buf + buf_len, zero_buf));

		RC42.encrypt(buf, buf_len);
		RC41.decrypt(buf, buf_len);
		TEST_CHECK(std::equal(buf, buf + buf_len, zero_buf));

		delete[] buf;
		delete[] zero_buf;
	}

	test_transfer(pe_settings::disabled);

	test_transfer(pe_settings::forced, pe_settings::plaintext);
	test_transfer(pe_settings::forced, pe_settings::rc4);
	test_transfer(pe_settings::forced, pe_settings::both, false);
	test_transfer(pe_settings::forced, pe_settings::both, true);

	test_transfer(pe_settings::enabled, pe_settings::plaintext);
	test_transfer(pe_settings::enabled, pe_settings::rc4);
	test_transfer(pe_settings::enabled, pe_settings::both, false);
	test_transfer(pe_settings::enabled, pe_settings::both, true);

	return 0;
}

#else

int test_main()
{
	std::cerr << "PE test not run because it's disabled" << std::endl;
	return 0;
}

#endif

<|endoftext|>


<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2013 James Hughes.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

/// \author James Hughes
/// \date   December 2013

#ifndef IAUNS_GLM_AABB_HPP
#define IAUNS_GLM_AABB_HPP

#include <glm/glm.hpp>

namespace CPM_GLM_AABB_NS {

/// Standalone axis aligned bounding box implemented built on top of GLM.
class AABB
{
public:
  /// Builds a null AABB.
  AABB();

  /// Builds an AABB that encompasses a sphere of \p radius and \p center.
  AABB(const glm::vec3& center, glm::float_t radius);

  /// Builds an AABB that contains the two points.
  AABB(const glm::vec3& p1, const glm::vec3& p2);

  /// Copy constructor.
  AABB(const AABB& aabb);

  ~AABB();

  /// Set the AABB as NULL (not set).
  void setNull()      {mMin = glm::vec3(1.0); mMax = glm::vec3(-1.0);}

  /// Returns true if AABB is NULL (not set).
  bool isNull() const {return mMin.x > mMax.x || mMin.y > mMax.y || mMin.z > mMax.z;}

  /// Extend the bounding box on all sides by \p val.
  void extend(glm::float_t val);

  /// Expand the AABB to include point \p p.
  void extend(const glm::vec3& p);

  /// Expand the AABB to include a sphere centered at \p center and of radius \p
  /// radius.
  void extend(const glm::vec3& center, glm::float_t radius);

  /// Expand the AABB to encompass the given AABB.
  void extend(const AABB& aabb);

  /// Expand the AABB to include a disk centered at \p center, with normal \p
  /// normal, and radius \p radius.
  /// \todo Untested -- This function is not represented in our unit tests.
  void extendDisk(const glm::vec3& center, const glm::vec3& normal,
                  glm::float_t radius);

  /// Translates AABB by vector \p v.
  void translate(const glm::vec3& v);

  /// Scale the AABB by \p scale, centered around \p origin.
  void scale(const glm::vec3& scale, const glm::vec3& origin);

  /// Retrieves the center of the AABB.
  glm::vec3 getCenter() const;

  /// Retrieves the diagonal vector (computed as mMax - mMin).
  /// If the AABB is NULL, then a vector of all zeros is returned.
  glm::vec3 getDiagonal() const;

  /// Retrieves the longest edge.
  /// If the AABB is NULL, then 0 is returned.
  glm::float_t getLongestEdge() const;

  /// Retrieves the shortest edge.
  /// If the AABB is NULL, then 0 is returned.
  glm::float_t getShortestEdge() const;

  /// Retrieves the AABB's minimum point.
  glm::vec3 getMin() const {return mMin;}

  /// Retrieves the AABB's maximum point.
  glm::vec3 getMax() const {return mMax;}

  /// Returns true if AABBs share a face overlap.
  /// \todo Untested -- This function is not represented in our unit tests.
  bool overlaps(const AABB& bb) const;

  /// Type returned from call to intersect.
  enum INTERSECTION_TYPE { INSIDE, INTERSECT, OUTSIDE };
  /// Returns one of the intersection types. If either of the aabbs are invalid,
  /// then OUTSIDE is returned.
  INTERSECTION_TYPE intersect(const AABB& bb) const;

  /// Function from SCIRun. Here is a summary of SCIRun's description:
  /// Returns true if the two AABB's are similar. If diff is 1.0, the two
  /// bboxes have to have about 50% overlap each for x,y,z. If diff is 0.0,
  /// they have to have 100% overlap.
  /// If either of the two AABBs is NULL, then false is returned.
  /// \todo Untested -- This function is not represented in our unit tests.
  bool isSimilarTo(const AABB& b, glm::float_t diff = 0.5) const;

private:

  glm::vec3 mMin;   ///< Minimum point.
  glm::vec3 mMax;   ///< Maximum point.
};

} // namespace CPM_GLM_AABB_NS

#endif
<commit_msg>Replaced doxygen todo statements.<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2013 James Hughes.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

/// \author James Hughes
/// \date   December 2013

#ifndef IAUNS_GLM_AABB_HPP
#define IAUNS_GLM_AABB_HPP

#include <glm/glm.hpp>

namespace CPM_GLM_AABB_NS {

/// Standalone axis aligned bounding box implemented built on top of GLM.
class AABB
{
public:
  /// Builds a null AABB.
  AABB();

  /// Builds an AABB that encompasses a sphere of \p radius and \p center.
  AABB(const glm::vec3& center, glm::float_t radius);

  /// Builds an AABB that contains the two points.
  AABB(const glm::vec3& p1, const glm::vec3& p2);

  /// Copy constructor.
  AABB(const AABB& aabb);

  ~AABB();

  /// Set the AABB as NULL (not set).
  void setNull()      {mMin = glm::vec3(1.0); mMax = glm::vec3(-1.0);}

  /// Returns true if AABB is NULL (not set).
  bool isNull() const {return mMin.x > mMax.x || mMin.y > mMax.y || mMin.z > mMax.z;}

  /// Extend the bounding box on all sides by \p val.
  void extend(glm::float_t val);

  /// Expand the AABB to include point \p p.
  void extend(const glm::vec3& p);

  /// Expand the AABB to include a sphere centered at \p center and of radius \p
  /// radius.
  void extend(const glm::vec3& center, glm::float_t radius);

  /// Expand the AABB to encompass the given AABB.
  void extend(const AABB& aabb);

  /// Expand the AABB to include a disk centered at \p center, with normal \p
  /// normal, and radius \p radius.
  /// \xxx Untested -- This function is not represented in our unit tests.
  void extendDisk(const glm::vec3& center, const glm::vec3& normal,
                  glm::float_t radius);

  /// Translates AABB by vector \p v.
  void translate(const glm::vec3& v);

  /// Scale the AABB by \p scale, centered around \p origin.
  void scale(const glm::vec3& scale, const glm::vec3& origin);

  /// Retrieves the center of the AABB.
  glm::vec3 getCenter() const;

  /// Retrieves the diagonal vector (computed as mMax - mMin).
  /// If the AABB is NULL, then a vector of all zeros is returned.
  glm::vec3 getDiagonal() const;

  /// Retrieves the longest edge.
  /// If the AABB is NULL, then 0 is returned.
  glm::float_t getLongestEdge() const;

  /// Retrieves the shortest edge.
  /// If the AABB is NULL, then 0 is returned.
  glm::float_t getShortestEdge() const;

  /// Retrieves the AABB's minimum point.
  glm::vec3 getMin() const {return mMin;}

  /// Retrieves the AABB's maximum point.
  glm::vec3 getMax() const {return mMax;}

  /// Returns true if AABBs share a face overlap.
  /// \xxx Untested -- This function is not represented in our unit tests.
  bool overlaps(const AABB& bb) const;

  /// Type returned from call to intersect.
  enum INTERSECTION_TYPE { INSIDE, INTERSECT, OUTSIDE };
  /// Returns one of the intersection types. If either of the aabbs are invalid,
  /// then OUTSIDE is returned.
  INTERSECTION_TYPE intersect(const AABB& bb) const;

  /// Function from SCIRun. Here is a summary of SCIRun's description:
  /// Returns true if the two AABB's are similar. If diff is 1.0, the two
  /// bboxes have to have about 50% overlap each for x,y,z. If diff is 0.0,
  /// they have to have 100% overlap.
  /// If either of the two AABBs is NULL, then false is returned.
  /// \xxx Untested -- This function is not represented in our unit tests.
  bool isSimilarTo(const AABB& b, glm::float_t diff = 0.5) const;

private:

  glm::vec3 mMin;   ///< Minimum point.
  glm::vec3 mMax;   ///< Maximum point.
};

} // namespace CPM_GLM_AABB_NS

#endif
<|endoftext|>


<commit_before>/********** tell emacs we use -*- c++ -*- style comments *******************
 $Revision: 1.5 $  $Author: trey $  $Date: 2006-06-15 16:10:57 $

 @file    zmdpBenchmark.cc
 @brief   No brief

 Copyright (c) 2002-2006, Trey Smith.  All rights reserved.

 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 <assert.h>
#include <sys/time.h>
#include <getopt.h>

#include <iostream>
#include <fstream>

#include "solverUtils.h"
#include "TestDriver.h"

using namespace std;
using namespace MatrixUtils;
using namespace zmdp;

struct BenchmarkParams {
  int minOrder;
  int maxOrder;
  int numIterations;

  BenchmarkParams(void);
};

BenchmarkParams::BenchmarkParams(void) {
  minOrder = 0;
  maxOrder = 3;
  numIterations = 100;
}

void doBenchmark(const SolverParams& p, const BenchmarkParams& bp)
{
  init_matrix_utils();

  SolverObjects so;
  constructSolverObjects(so, p);

  if (NULL != p.outPolicyFileName) {
    if (!so.bounds->getSupportsPolicyOutput()) {
      cerr << "ERROR: -o specified, but with selected options, policy output is not supported:" << endl;
      cerr << "  in order to enable policy output, problem must be a POMDP; if" << endl;
      cout << "  it is, try adding the '-v convex' and '--lower-bound' options" << endl;
      exit(EXIT_FAILURE);
    }
  }

  TestDriver x;
  x.batchTestIncremental(/* numIterations = */ bp.numIterations,
			 so,
			 /* numSteps = */ 251,
			 /* targetPrecision = */ p.targetPrecision,
			 /* minOrder = */ bp.minOrder,
			 /* maxOrder = */ bp.maxOrder,
			 /* ticksPerOrder = */ 10,
			 /* incPlotFileName = */ "inc.plot",
			 /* boundsFileName = */ "bounds.plot",
			 /* simFileName = */ "sim.plot",
			 /* outPolicyFileName = */ p.outPolicyFileName);
  x.printRewards();
}

void usage(const char* cmdName) {
  cerr <<
    "usage: " << cmdName << " OPTIONS <model>\n"
    "  -h or --help           Print this help\n"
    "  --version              Print version information (CFLAGS used at compilation)\n"
    "\n"
    "Solver options:\n"
    "  -s or --search         Specifies search strategy. Valid choices:\n"
    "                           rtdp, lrtdp, hdp, hsvi, frtdp [default: frtdp]\n"
    "  -t or --type           Specifies problem type. Valid choices:\n"
    "                           racetrack, pomdp [default: infer from model filename]\n"
    "  -v or --value          Specifies value function representation. Valid choices\n"
    "                         depend on problem type. With -t pomdp, choices are:\n"
    "                           point, convex [default: convex]\n"
    "                         For other problem types, choices are:\n"
    "                           point [default: point]\n"
    "  -f or --fast           Use fast (but very picky) alternate POMDP parser\n"
    "  -p or --precision      Set target precision in solution quality; run ends when\n"
    "                           target is reached [default: 1e-3]\n"
    "  --weak-heuristic       Avoid spending time generating a good upper bound heuristic\n"
    "                           (only valid for some problems, interpretation depends on\n"
    "                            the problem; e.g. sets h_U = 0 for racetrack)\n"
    "  --lower-bound          Forces zmdpBenchmark to maintain a lower bound and use it for\n"
    "                           action selection, even if it is not used during search.\n"
    "  --upper-bound          Forces zmdpBenchmark to use the upper bound for action selection\n"
    "                           (normally the lower bound is used if it is available).\n"
    "\n"
    "Performance evaluation and output options:\n"
    "  -i or --iterations     Set number of simulation iterations at each policy\n"
    "                           evaluation epoch [default: 100]\n"
    "  --min-eval             If minEval=k, start logging policy evaluation epochs\n"
    "                           after 10^k seconds of policy improvement [default: 0]\n"
    "  --max-eval             If maxEval=k, run ends after at most 10^k seconds of policy\n"
    "                           improvement [default: 3]\n"
    "  -o or --output         Specify name of policy output file (if specified,a policy\n"
    "                           is saved at each evaluation epoch) [default: no output]\n"
    "\n"
    "Examples:\n"
    "  " << cmdName << " RockSample_4_4.pomdp\n"
    "  " << cmdName << " large-b.racetrack\n"
    "  " << cmdName << " --min-eval -1 RockSample_4_4.pomdp\n"
    "  " << cmdName << " --search lrtdp --value point RockSample_4_4.pomdp\n"
    "  " << cmdName << " -f RockSample_5_7.pomdp\n"
    "\n"
;
  exit(-1);
}

int main(int argc, char **argv) {
  static char shortOptions[] = "hs:t:v:fi:o:";
  static struct option longOptions[]={
    {"help",          0,NULL,'h'},
    {"version",       0,NULL,'V'},
    {"search",        1,NULL,'s'},
    {"type",          1,NULL,'t'},
    {"value",         1,NULL,'v'},
    {"fast",          0,NULL,'f'},
    {"precision",     1,NULL,'p'},
    {"weak-heuristic",0,NULL,'W'},
    {"lower-bound",   0,NULL,'L'},
    {"upper-bound",   0,NULL,'U'},
    {"iterations",    1,NULL,'i'},
    {"min-eval",      1,NULL,'X'},
    {"max-eval",      1,NULL,'Y'},
    {"output",        1,NULL,'o'},
    {NULL,0,0,0}
  };

  SolverParams p;
  BenchmarkParams bp;

  // save arguments for debug printout later
  ostringstream outs;
  for (int i=1; i < argc; i++) {
    outs << argv[i] << " ";
  }

  p.cmdName = argv[0];
  while (1) {
    char optchar = getopt_long(argc,argv,shortOptions,longOptions,NULL);
    if (optchar == -1) break;

    switch (optchar) {
    case 'h': // help
      usage(argv[0]);
      break;
    case 'V': // version
      cout << "CFLAGS = " << CFLAGS << endl;
      exit(EXIT_SUCCESS);
      break;
    case 's': // search
      p.setStrategy(optarg);
      break;
    case 't': // type
      p.setProbType(optarg);
      break;
    case 'v': // value
      p.setValueRepr(optarg);
      break;
    case 'f': // fast
      p.useFastParser = true;
      break;
    case 'p': // precision
      p.targetPrecision = atof(optarg);
      break;
    case 'W': // weak-heuristic
      p.useHeuristic = false;
      break;
    case 'L': // lower-bound
      p.forceLowerBound = true;
      break;
    case 'U': // upper-bound
      p.forceUpperBoundActionSelection = true;
      break;
    case 'i': // iterations
      bp.numIterations = atoi(optarg);
      break;
    case 'X': // min-eval
      bp.minOrder = atoi(optarg);
      break;
    case 'Y': // max-eval
      bp.maxOrder = atoi(optarg);
      break;
    case 'o': // output
      p.outPolicyFileName = optarg;
      break;

    case '?': // unknown option
    case ':': // option with missing parameter
      // getopt() prints an informative error message
      cerr << endl;
      usage(argv[0]);
      break;
    default:
      abort(); // never reach this point
    }
  }
  if (argc-optind != 1) {
    cerr << "ERROR: wrong number of arguments (should be 1)" << endl << endl;
    usage(argv[0]);
  }

  p.probName = argv[optind++];
  p.inferMissingValues();

  printf("CFLAGS = %s\n", CFLAGS);
  printf("ARGS = %s\n", outs.str().c_str());
  fflush(stdout);

  doBenchmark(p, bp);

  // signal we are done -- an external batch process that runs zmdpBenchmark
  // can check for completion by polling for existence of this file
  // (which may be easier that using fork()/wait(), depending on the
  // implementation)
  FILE *fp = fopen("/tmp/zmdpBenchmark_done", "w");
  fprintf(fp, "success\n");
  fclose(fp);

  return 0;
}

/***************************************************************************
 * REVISION HISTORY:
 * $Log: not supported by cvs2svn $
 * Revision 1.4  2006/04/28 17:57:41  trey
 * changed to use apache license
 *
 * Revision 1.3  2006/04/27 23:19:03  trey
 * renamed Interleave -> TestDriver
 *
 * Revision 1.2  2006/04/27 23:08:18  trey
 * reordered getopt data structure to match usage()
 *
 * Revision 1.1  2006/04/27 20:19:22  trey
 * refactored command-line interface code, renamed solveMDP to zmdpBenchmark
 *
 * Revision 1.4  2006/04/12 19:23:22  trey
 * added wrtdp support and extra error checking for parameters
 *
 * Revision 1.3  2006/04/10 20:27:05  trey
 * added --lower-bound and --upper-bound args
 *
 * Revision 1.2  2006/04/07 20:15:40  trey
 * solveMDP now uses a strong heuristic by default; improved usage() help
 *
 * Revision 1.1  2006/04/07 19:40:41  trey
 * switched back to a unified binary for all algorithms, turns out it cuts down on code maintenance
 *
 *
 ***************************************************************************/
<commit_msg>added debug output<commit_after>/********** tell emacs we use -*- c++ -*- style comments *******************
 $Revision: 1.6 $  $Author: trey $  $Date: 2006-07-26 20:52:57 $

 @file    zmdpBenchmark.cc
 @brief   No brief

 Copyright (c) 2002-2006, Trey Smith.  All rights reserved.

 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 <assert.h>
#include <sys/time.h>
#include <getopt.h>

#include <iostream>
#include <fstream>

#include "solverUtils.h"
#include "TestDriver.h"

using namespace std;
using namespace MatrixUtils;
using namespace zmdp;

struct BenchmarkParams {
  int minOrder;
  int maxOrder;
  int numIterations;

  BenchmarkParams(void);
};

BenchmarkParams::BenchmarkParams(void) {
  minOrder = 0;
  maxOrder = 3;
  numIterations = 100;
}

void doBenchmark(const SolverParams& p, const BenchmarkParams& bp)
{
  init_matrix_utils();

  printf("reading input files\n");
  SolverObjects so;
  constructSolverObjects(so, p);

  if (NULL != p.outPolicyFileName) {
    if (!so.bounds->getSupportsPolicyOutput()) {
      cerr << "ERROR: -o specified, but with selected options, policy output is not supported:" << endl;
      cerr << "  in order to enable policy output, problem must be a POMDP; if" << endl;
      cout << "  it is, try adding the '-v convex' and '--lower-bound' options" << endl;
      exit(EXIT_FAILURE);
    }
  }

  TestDriver x;
  x.batchTestIncremental(/* numIterations = */ bp.numIterations,
			 so,
			 /* numSteps = */ 251,
			 /* targetPrecision = */ p.targetPrecision,
			 /* minOrder = */ bp.minOrder,
			 /* maxOrder = */ bp.maxOrder,
			 /* ticksPerOrder = */ 10,
			 /* incPlotFileName = */ "inc.plot",
			 /* boundsFileName = */ "bounds.plot",
			 /* simFileName = */ "sim.plot",
			 /* outPolicyFileName = */ p.outPolicyFileName);
  x.printRewards();
}

void usage(const char* cmdName) {
  cerr <<
    "usage: " << cmdName << " OPTIONS <model>\n"
    "  -h or --help           Print this help\n"
    "  --version              Print version information (CFLAGS used at compilation)\n"
    "\n"
    "Solver options:\n"
    "  -s or --search         Specifies search strategy. Valid choices:\n"
    "                           rtdp, lrtdp, hdp, hsvi, frtdp [default: frtdp]\n"
    "  -t or --type           Specifies problem type. Valid choices:\n"
    "                           racetrack, pomdp [default: infer from model filename]\n"
    "  -v or --value          Specifies value function representation. Valid choices\n"
    "                         depend on problem type. With -t pomdp, choices are:\n"
    "                           point, convex [default: convex]\n"
    "                         For other problem types, choices are:\n"
    "                           point [default: point]\n"
    "  -f or --fast           Use fast (but very picky) alternate POMDP parser\n"
    "  -p or --precision      Set target precision in solution quality; run ends when\n"
    "                           target is reached [default: 1e-3]\n"
    "  --weak-heuristic       Avoid spending time generating a good upper bound heuristic\n"
    "                           (only valid for some problems, interpretation depends on\n"
    "                            the problem; e.g. sets h_U = 0 for racetrack)\n"
    "  --lower-bound          Forces zmdpBenchmark to maintain a lower bound and use it for\n"
    "                           action selection, even if it is not used during search.\n"
    "  --upper-bound          Forces zmdpBenchmark to use the upper bound for action selection\n"
    "                           (normally the lower bound is used if it is available).\n"
    "\n"
    "Performance evaluation and output options:\n"
    "  -i or --iterations     Set number of simulation iterations at each policy\n"
    "                           evaluation epoch [default: 100]\n"
    "  --min-eval             If minEval=k, start logging policy evaluation epochs\n"
    "                           after 10^k seconds of policy improvement [default: 0]\n"
    "  --max-eval             If maxEval=k, run ends after at most 10^k seconds of policy\n"
    "                           improvement [default: 3]\n"
    "  -o or --output         Specify name of policy output file (if specified,a policy\n"
    "                           is saved at each evaluation epoch) [default: no output]\n"
    "\n"
    "Examples:\n"
    "  " << cmdName << " RockSample_4_4.pomdp\n"
    "  " << cmdName << " large-b.racetrack\n"
    "  " << cmdName << " --min-eval -1 RockSample_4_4.pomdp\n"
    "  " << cmdName << " --search lrtdp --value point RockSample_4_4.pomdp\n"
    "  " << cmdName << " -f RockSample_5_7.pomdp\n"
    "\n"
;
  exit(-1);
}

int main(int argc, char **argv) {
  static char shortOptions[] = "hs:t:v:fi:o:";
  static struct option longOptions[]={
    {"help",          0,NULL,'h'},
    {"version",       0,NULL,'V'},
    {"search",        1,NULL,'s'},
    {"type",          1,NULL,'t'},
    {"value",         1,NULL,'v'},
    {"fast",          0,NULL,'f'},
    {"precision",     1,NULL,'p'},
    {"weak-heuristic",0,NULL,'W'},
    {"lower-bound",   0,NULL,'L'},
    {"upper-bound",   0,NULL,'U'},
    {"iterations",    1,NULL,'i'},
    {"min-eval",      1,NULL,'X'},
    {"max-eval",      1,NULL,'Y'},
    {"output",        1,NULL,'o'},
    {NULL,0,0,0}
  };

  SolverParams p;
  BenchmarkParams bp;

  // save arguments for debug printout later
  ostringstream outs;
  for (int i=1; i < argc; i++) {
    outs << argv[i] << " ";
  }

  p.cmdName = argv[0];
  while (1) {
    char optchar = getopt_long(argc,argv,shortOptions,longOptions,NULL);
    if (optchar == -1) break;

    switch (optchar) {
    case 'h': // help
      usage(argv[0]);
      break;
    case 'V': // version
      cout << "CFLAGS = " << CFLAGS << endl;
      exit(EXIT_SUCCESS);
      break;
    case 's': // search
      p.setStrategy(optarg);
      break;
    case 't': // type
      p.setProbType(optarg);
      break;
    case 'v': // value
      p.setValueRepr(optarg);
      break;
    case 'f': // fast
      p.useFastParser = true;
      break;
    case 'p': // precision
      p.targetPrecision = atof(optarg);
      break;
    case 'W': // weak-heuristic
      p.useHeuristic = false;
      break;
    case 'L': // lower-bound
      p.forceLowerBound = true;
      break;
    case 'U': // upper-bound
      p.forceUpperBoundActionSelection = true;
      break;
    case 'i': // iterations
      bp.numIterations = atoi(optarg);
      break;
    case 'X': // min-eval
      bp.minOrder = atoi(optarg);
      break;
    case 'Y': // max-eval
      bp.maxOrder = atoi(optarg);
      break;
    case 'o': // output
      p.outPolicyFileName = optarg;
      break;

    case '?': // unknown option
    case ':': // option with missing parameter
      // getopt() prints an informative error message
      cerr << endl;
      usage(argv[0]);
      break;
    default:
      abort(); // never reach this point
    }
  }
  if (argc-optind != 1) {
    cerr << "ERROR: wrong number of arguments (should be 1)" << endl << endl;
    usage(argv[0]);
  }

  p.probName = argv[optind++];
  p.inferMissingValues();

  printf("CFLAGS = %s\n", CFLAGS);
  printf("ARGS = %s\n", outs.str().c_str());
  fflush(stdout);

  doBenchmark(p, bp);

  // signal we are done -- an external batch process that runs zmdpBenchmark
  // can check for completion by polling for existence of this file
  // (which may be easier that using fork()/wait(), depending on the
  // implementation)
  FILE *fp = fopen("/tmp/zmdpBenchmark_done", "w");
  fprintf(fp, "success\n");
  fclose(fp);

  return 0;
}

/***************************************************************************
 * REVISION HISTORY:
 * $Log: not supported by cvs2svn $
 * Revision 1.5  2006/06/15 16:10:57  trey
 * restructured so zmdpBenchmark can output policies
 *
 * Revision 1.4  2006/04/28 17:57:41  trey
 * changed to use apache license
 *
 * Revision 1.3  2006/04/27 23:19:03  trey
 * renamed Interleave -> TestDriver
 *
 * Revision 1.2  2006/04/27 23:08:18  trey
 * reordered getopt data structure to match usage()
 *
 * Revision 1.1  2006/04/27 20:19:22  trey
 * refactored command-line interface code, renamed solveMDP to zmdpBenchmark
 *
 * Revision 1.4  2006/04/12 19:23:22  trey
 * added wrtdp support and extra error checking for parameters
 *
 * Revision 1.3  2006/04/10 20:27:05  trey
 * added --lower-bound and --upper-bound args
 *
 * Revision 1.2  2006/04/07 20:15:40  trey
 * solveMDP now uses a strong heuristic by default; improved usage() help
 *
 * Revision 1.1  2006/04/07 19:40:41  trey
 * switched back to a unified binary for all algorithms, turns out it cuts down on code maintenance
 *
 *
 ***************************************************************************/
<|endoftext|>


<commit_before>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/sync_file_system/drive_backend/drive_backend_util.h"

#include "base/logging.h"
#include "base/memory/scoped_vector.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/threading/thread_restrictions.h"
#include "chrome/browser/drive/drive_api_util.h"
#include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h"
#include "chrome/browser/sync_file_system/drive_backend/leveldb_wrapper.h"
#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
#include "chrome/browser/sync_file_system/logger.h"
#include "google_apis/drive/drive_api_parser.h"
#include "third_party/leveldatabase/src/include/leveldb/status.h"

namespace sync_file_system {
namespace drive_backend {

void PutVersionToDB(int64 version, LevelDBWrapper* db) {
  DCHECK(db);
  db->Put(kDatabaseVersionKey, base::Int64ToString(version));
}

void PutServiceMetadataToDB(const ServiceMetadata& service_metadata,
                            LevelDBWrapper* db) {
  DCHECK(db);

  std::string value;
  bool success = service_metadata.SerializeToString(&value);
  DCHECK(success);
  db->Put(kServiceMetadataKey, value);
}

void PutFileMetadataToDB(const FileMetadata& file, LevelDBWrapper* db) {
  DCHECK(db);

  std::string value;
  bool success = file.SerializeToString(&value);
  DCHECK(success);
  db->Put(kFileMetadataKeyPrefix + file.file_id(), value);
}

void PutFileTrackerToDB(const FileTracker& tracker, LevelDBWrapper* db) {
  DCHECK(db);

  std::string value;
  bool success = tracker.SerializeToString(&value);
  DCHECK(success);
  db->Put(kFileTrackerKeyPrefix + base::Int64ToString(tracker.tracker_id()),
          value);
}

void PutFileMetadataDeletionToDB(const std::string& file_id,
                                 LevelDBWrapper* db) {
  DCHECK(db);
  db->Delete(kFileMetadataKeyPrefix + file_id);
}

void PutFileTrackerDeletionToDB(int64 tracker_id, LevelDBWrapper* db) {
  DCHECK(db);
  db->Delete(kFileTrackerKeyPrefix + base::Int64ToString(tracker_id));
}

bool HasFileAsParent(const FileDetails& details, const std::string& file_id) {
  for (int i = 0; i < details.parent_folder_ids_size(); ++i) {
    if (details.parent_folder_ids(i) == file_id)
      return true;
  }
  return false;
}

bool IsAppRoot(const FileTracker& tracker) {
  return tracker.tracker_kind() == TRACKER_KIND_APP_ROOT ||
      tracker.tracker_kind() == TRACKER_KIND_DISABLED_APP_ROOT;
}

std::string GetTrackerTitle(const FileTracker& tracker) {
  if (tracker.has_synced_details())
    return tracker.synced_details().title();
  return std::string();
}

SyncStatusCode DriveApiErrorCodeToSyncStatusCode(
    google_apis::DriveApiErrorCode error) {
  // NOTE: Please update DriveFileSyncService::UpdateServiceState when you add
  // more error code mapping.
  switch (error) {
    case google_apis::HTTP_SUCCESS:
    case google_apis::HTTP_CREATED:
    case google_apis::HTTP_NO_CONTENT:
    case google_apis::HTTP_FOUND:
      return SYNC_STATUS_OK;

    case google_apis::HTTP_NOT_MODIFIED:
      return SYNC_STATUS_NOT_MODIFIED;

    case google_apis::HTTP_CONFLICT:
    case google_apis::HTTP_PRECONDITION:
      return SYNC_STATUS_HAS_CONFLICT;

    case google_apis::HTTP_UNAUTHORIZED:
      return SYNC_STATUS_AUTHENTICATION_FAILED;

    case google_apis::DRIVE_NO_CONNECTION:
      return SYNC_STATUS_NETWORK_ERROR;

    case google_apis::HTTP_INTERNAL_SERVER_ERROR:
    case google_apis::HTTP_BAD_GATEWAY:
    case google_apis::HTTP_SERVICE_UNAVAILABLE:
    case google_apis::DRIVE_CANCELLED:
    case google_apis::DRIVE_NOT_READY:
      return SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE;

    case google_apis::HTTP_NOT_FOUND:
    case google_apis::HTTP_GONE:
      return SYNC_FILE_ERROR_NOT_FOUND;

    case google_apis::DRIVE_FILE_ERROR:
      return SYNC_FILE_ERROR_FAILED;

    case google_apis::HTTP_FORBIDDEN:
      return SYNC_STATUS_ACCESS_FORBIDDEN;

    case google_apis::HTTP_RESUME_INCOMPLETE:
    case google_apis::HTTP_BAD_REQUEST:
    case google_apis::HTTP_LENGTH_REQUIRED:
    case google_apis::HTTP_NOT_IMPLEMENTED:
    case google_apis::DRIVE_PARSE_ERROR:
    case google_apis::DRIVE_RESPONSE_TOO_LARGE:
    case google_apis::DRIVE_OTHER_ERROR:
      return SYNC_STATUS_FAILED;

    case google_apis::DRIVE_NO_SPACE:
      return SYNC_FILE_ERROR_NO_SPACE;
  }

  // There's a case where DriveService layer returns DriveApiErrorCode==-1
  // when network is unavailable. (http://crbug.com/223042)
  // TODO(kinuko,nhiroki): We should identify from where this undefined error
  // code is coming.
  if (error == -1)
    return SYNC_STATUS_NETWORK_ERROR;

  util::Log(logging::LOG_WARNING,
            FROM_HERE,
            "Got unexpected error: %d",
            static_cast<int>(error));
  return SYNC_STATUS_FAILED;
}

bool RemovePrefix(const std::string& str, const std::string& prefix,
                  std::string* out) {
  if (!base::StartsWithASCII(str, prefix, true)) {
    if (out)
      *out = str;
    return false;
  }

  if (out)
    *out = str.substr(prefix.size());
  return true;
}

scoped_ptr<ServiceMetadata> InitializeServiceMetadata(LevelDBWrapper* db) {
  base::ThreadRestrictions::AssertIOAllowed();
  DCHECK(db);

  scoped_ptr<ServiceMetadata> service_metadata;

  std::string value;
  leveldb::Status status = db->Get(kServiceMetadataKey, &value);
  if (status.ok()) {
    service_metadata.reset(new ServiceMetadata);
    if (!service_metadata->ParseFromString(value))
      service_metadata.reset();
  } else if (status.IsNotFound()) {
    service_metadata.reset(new ServiceMetadata);
    service_metadata->set_next_tracker_id(1);
  }

  return service_metadata.Pass();
}

}  // namespace drive_backend
}  // namespace sync_file_system
<commit_msg>Remove an obsolete hack for Drive error codes.<commit_after>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/sync_file_system/drive_backend/drive_backend_util.h"

#include "base/logging.h"
#include "base/memory/scoped_vector.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/threading/thread_restrictions.h"
#include "chrome/browser/drive/drive_api_util.h"
#include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h"
#include "chrome/browser/sync_file_system/drive_backend/leveldb_wrapper.h"
#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
#include "chrome/browser/sync_file_system/logger.h"
#include "google_apis/drive/drive_api_parser.h"
#include "third_party/leveldatabase/src/include/leveldb/status.h"

namespace sync_file_system {
namespace drive_backend {

void PutVersionToDB(int64 version, LevelDBWrapper* db) {
  DCHECK(db);
  db->Put(kDatabaseVersionKey, base::Int64ToString(version));
}

void PutServiceMetadataToDB(const ServiceMetadata& service_metadata,
                            LevelDBWrapper* db) {
  DCHECK(db);

  std::string value;
  bool success = service_metadata.SerializeToString(&value);
  DCHECK(success);
  db->Put(kServiceMetadataKey, value);
}

void PutFileMetadataToDB(const FileMetadata& file, LevelDBWrapper* db) {
  DCHECK(db);

  std::string value;
  bool success = file.SerializeToString(&value);
  DCHECK(success);
  db->Put(kFileMetadataKeyPrefix + file.file_id(), value);
}

void PutFileTrackerToDB(const FileTracker& tracker, LevelDBWrapper* db) {
  DCHECK(db);

  std::string value;
  bool success = tracker.SerializeToString(&value);
  DCHECK(success);
  db->Put(kFileTrackerKeyPrefix + base::Int64ToString(tracker.tracker_id()),
          value);
}

void PutFileMetadataDeletionToDB(const std::string& file_id,
                                 LevelDBWrapper* db) {
  DCHECK(db);
  db->Delete(kFileMetadataKeyPrefix + file_id);
}

void PutFileTrackerDeletionToDB(int64 tracker_id, LevelDBWrapper* db) {
  DCHECK(db);
  db->Delete(kFileTrackerKeyPrefix + base::Int64ToString(tracker_id));
}

bool HasFileAsParent(const FileDetails& details, const std::string& file_id) {
  for (int i = 0; i < details.parent_folder_ids_size(); ++i) {
    if (details.parent_folder_ids(i) == file_id)
      return true;
  }
  return false;
}

bool IsAppRoot(const FileTracker& tracker) {
  return tracker.tracker_kind() == TRACKER_KIND_APP_ROOT ||
      tracker.tracker_kind() == TRACKER_KIND_DISABLED_APP_ROOT;
}

std::string GetTrackerTitle(const FileTracker& tracker) {
  if (tracker.has_synced_details())
    return tracker.synced_details().title();
  return std::string();
}

SyncStatusCode DriveApiErrorCodeToSyncStatusCode(
    google_apis::DriveApiErrorCode error) {
  // NOTE: Please update DriveFileSyncService::UpdateServiceState when you add
  // more error code mapping.
  switch (error) {
    case google_apis::HTTP_SUCCESS:
    case google_apis::HTTP_CREATED:
    case google_apis::HTTP_NO_CONTENT:
    case google_apis::HTTP_FOUND:
      return SYNC_STATUS_OK;

    case google_apis::HTTP_NOT_MODIFIED:
      return SYNC_STATUS_NOT_MODIFIED;

    case google_apis::HTTP_CONFLICT:
    case google_apis::HTTP_PRECONDITION:
      return SYNC_STATUS_HAS_CONFLICT;

    case google_apis::HTTP_UNAUTHORIZED:
      return SYNC_STATUS_AUTHENTICATION_FAILED;

    case google_apis::DRIVE_NO_CONNECTION:
      return SYNC_STATUS_NETWORK_ERROR;

    case google_apis::HTTP_INTERNAL_SERVER_ERROR:
    case google_apis::HTTP_BAD_GATEWAY:
    case google_apis::HTTP_SERVICE_UNAVAILABLE:
    case google_apis::DRIVE_CANCELLED:
    case google_apis::DRIVE_NOT_READY:
      return SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE;

    case google_apis::HTTP_NOT_FOUND:
    case google_apis::HTTP_GONE:
      return SYNC_FILE_ERROR_NOT_FOUND;

    case google_apis::DRIVE_FILE_ERROR:
      return SYNC_FILE_ERROR_FAILED;

    case google_apis::HTTP_FORBIDDEN:
      return SYNC_STATUS_ACCESS_FORBIDDEN;

    case google_apis::HTTP_RESUME_INCOMPLETE:
    case google_apis::HTTP_BAD_REQUEST:
    case google_apis::HTTP_LENGTH_REQUIRED:
    case google_apis::HTTP_NOT_IMPLEMENTED:
    case google_apis::DRIVE_PARSE_ERROR:
    case google_apis::DRIVE_RESPONSE_TOO_LARGE:
    case google_apis::DRIVE_OTHER_ERROR:
      return SYNC_STATUS_FAILED;

    case google_apis::DRIVE_NO_SPACE:
      return SYNC_FILE_ERROR_NO_SPACE;
  }

  NOTREACHED();
  return SYNC_STATUS_FAILED;
}

bool RemovePrefix(const std::string& str, const std::string& prefix,
                  std::string* out) {
  if (!base::StartsWithASCII(str, prefix, true)) {
    if (out)
      *out = str;
    return false;
  }

  if (out)
    *out = str.substr(prefix.size());
  return true;
}

scoped_ptr<ServiceMetadata> InitializeServiceMetadata(LevelDBWrapper* db) {
  base::ThreadRestrictions::AssertIOAllowed();
  DCHECK(db);

  scoped_ptr<ServiceMetadata> service_metadata;

  std::string value;
  leveldb::Status status = db->Get(kServiceMetadataKey, &value);
  if (status.ok()) {
    service_metadata.reset(new ServiceMetadata);
    if (!service_metadata->ParseFromString(value))
      service_metadata.reset();
  } else if (status.IsNotFound()) {
    service_metadata.reset(new ServiceMetadata);
    service_metadata->set_next_tracker_id(1);
  }

  return service_metadata.Pass();
}

}  // namespace drive_backend
}  // namespace sync_file_system
<|endoftext|>


<commit_before>//===-- ARMAsmBackend.cpp - ARM Assembler Backend -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/Target/TargetAsmBackend.h"
#include "ARM.h"
//FIXME: add #include "ARMFixupKinds.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/ELFObjectWriter.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MachObjectWriter.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Target/TargetAsmBackend.h"
using namespace llvm;

namespace {
class ARMAsmBackend : public TargetAsmBackend {
public:
  ARMAsmBackend(const Target &T)
    : TargetAsmBackend(T) {
  }

  bool MayNeedRelaxation(const MCInst &Inst) const;

  void RelaxInstruction(const MCInst &Inst, MCInst &Res) const;

  bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const;
};

bool ARMAsmBackend::MayNeedRelaxation(const MCInst &Inst) const {
  // FIXME: Thumb targets, different move constant targets..
  return false;
}

void ARMAsmBackend::RelaxInstruction(const MCInst &Inst, MCInst &Res) const {
  assert(0 && "ARMAsmBackend::RelaxInstruction() unimplemented");
  return;
}

bool ARMAsmBackend::WriteNopData(uint64_t Count, MCObjectWriter *OW) const {
  assert(0 && "ARMAsmBackend::WriteNopData() unimplemented");
  if ((Count % 4) != 0) {
    // Fixme: % 2 for Thumb?
    return false;
  }
  return false;
};
} // end anonymous namespace

namespace {
// FIXME: This should be in a separate file.
// ELF is an ELF of course...
class ELFARMAsmBackend : public ARMAsmBackend {
public:
  Triple::OSType OSType;
  ELFARMAsmBackend(const Target &T, Triple::OSType _OSType)
    : ARMAsmBackend(T), OSType(_OSType) {
    HasAbsolutizedSet = true;
    HasScatteredSymbols = true;
  }

  void ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
                  uint64_t Value) const;

  bool isVirtualSection(const MCSection &Section) const {
    const MCSectionELF &SE = static_cast<const MCSectionELF&>(Section);
    return SE.getType() == MCSectionELF::SHT_NOBITS;
  }

  MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
    return new ELFObjectWriter(OS, /*Is64Bit=*/false,
                               OSType,
                               /*IsLittleEndian=*/true,
                               /*HasRelocationAddend=*/false);
  }
};

// Fixme: can we raise this to share code bet. Darwin and ELF?
void ELFARMAsmBackend::ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
                                  uint64_t Value) const {
  assert(0 && "ELFARMAsmBackend::ApplyFixup() unimplemented");
}

// FIXME: This should be in a separate file.
class DarwinARMAsmBackend : public ARMAsmBackend {
public:
  DarwinARMAsmBackend(const Target &T)
    : ARMAsmBackend(T) {
    HasAbsolutizedSet = true;
    HasScatteredSymbols = true;
    assert(0 && "DarwinARMAsmBackend::DarwinARMAsmBackend() unimplemented");
  }

  void ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
                  uint64_t Value) const;

  bool isVirtualSection(const MCSection &Section) const {
    const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section);
    return (SMO.getType() == MCSectionMachO::S_ZEROFILL ||
            SMO.getType() == MCSectionMachO::S_GB_ZEROFILL ||
            SMO.getType() == MCSectionMachO::S_THREAD_LOCAL_ZEROFILL);
  }

  MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
    return new MachObjectWriter(OS, /*Is64Bit=*/false);
  }

  virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
    return false;
  }
};

void DarwinARMAsmBackend::ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
                                  uint64_t Value) const {
  assert(0 && "DarwinARMAsmBackend::ApplyFixup() unimplemented");
}
} // end anonymous namespace

TargetAsmBackend *llvm::createARMAsmBackend(const Target &T,
                                            const std::string &TT) {
  switch (Triple(TT).getOS()) {
  case Triple::Darwin:
    return new DarwinARMAsmBackend(T);
  case Triple::MinGW32:
  case Triple::Cygwin:
  case Triple::Win32:
    assert(0 && "Windows not supported on ARM");
  default:
    return new ELFARMAsmBackend(T, Triple(TT).getOS());
  }
}
<commit_msg>Remove misplaced ';'. Make buildbots happy, hopefully.<commit_after>//===-- ARMAsmBackend.cpp - ARM Assembler Backend -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/Target/TargetAsmBackend.h"
#include "ARM.h"
//FIXME: add #include "ARMFixupKinds.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/ELFObjectWriter.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MachObjectWriter.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Target/TargetAsmBackend.h"
using namespace llvm;

namespace {
class ARMAsmBackend : public TargetAsmBackend {
public:
  ARMAsmBackend(const Target &T)
    : TargetAsmBackend(T) {
  }

  bool MayNeedRelaxation(const MCInst &Inst) const;

  void RelaxInstruction(const MCInst &Inst, MCInst &Res) const;

  bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const;
};

bool ARMAsmBackend::MayNeedRelaxation(const MCInst &Inst) const {
  // FIXME: Thumb targets, different move constant targets..
  return false;
}

void ARMAsmBackend::RelaxInstruction(const MCInst &Inst, MCInst &Res) const {
  assert(0 && "ARMAsmBackend::RelaxInstruction() unimplemented");
  return;
}

bool ARMAsmBackend::WriteNopData(uint64_t Count, MCObjectWriter *OW) const {
  assert(0 && "ARMAsmBackend::WriteNopData() unimplemented");
  if ((Count % 4) != 0) {
    // Fixme: % 2 for Thumb?
    return false;
  }
  return false;
}
} // end anonymous namespace

namespace {
// FIXME: This should be in a separate file.
// ELF is an ELF of course...
class ELFARMAsmBackend : public ARMAsmBackend {
public:
  Triple::OSType OSType;
  ELFARMAsmBackend(const Target &T, Triple::OSType _OSType)
    : ARMAsmBackend(T), OSType(_OSType) {
    HasAbsolutizedSet = true;
    HasScatteredSymbols = true;
  }

  void ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
                  uint64_t Value) const;

  bool isVirtualSection(const MCSection &Section) const {
    const MCSectionELF &SE = static_cast<const MCSectionELF&>(Section);
    return SE.getType() == MCSectionELF::SHT_NOBITS;
  }

  MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
    return new ELFObjectWriter(OS, /*Is64Bit=*/false,
                               OSType,
                               /*IsLittleEndian=*/true,
                               /*HasRelocationAddend=*/false);
  }
};

// Fixme: can we raise this to share code bet. Darwin and ELF?
void ELFARMAsmBackend::ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
                                  uint64_t Value) const {
  assert(0 && "ELFARMAsmBackend::ApplyFixup() unimplemented");
}

// FIXME: This should be in a separate file.
class DarwinARMAsmBackend : public ARMAsmBackend {
public:
  DarwinARMAsmBackend(const Target &T)
    : ARMAsmBackend(T) {
    HasAbsolutizedSet = true;
    HasScatteredSymbols = true;
    assert(0 && "DarwinARMAsmBackend::DarwinARMAsmBackend() unimplemented");
  }

  void ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
                  uint64_t Value) const;

  bool isVirtualSection(const MCSection &Section) const {
    const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section);
    return (SMO.getType() == MCSectionMachO::S_ZEROFILL ||
            SMO.getType() == MCSectionMachO::S_GB_ZEROFILL ||
            SMO.getType() == MCSectionMachO::S_THREAD_LOCAL_ZEROFILL);
  }

  MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
    return new MachObjectWriter(OS, /*Is64Bit=*/false);
  }

  virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
    return false;
  }
};

void DarwinARMAsmBackend::ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
                                  uint64_t Value) const {
  assert(0 && "DarwinARMAsmBackend::ApplyFixup() unimplemented");
}
} // end anonymous namespace

TargetAsmBackend *llvm::createARMAsmBackend(const Target &T,
                                            const std::string &TT) {
  switch (Triple(TT).getOS()) {
  case Triple::Darwin:
    return new DarwinARMAsmBackend(T);
  case Triple::MinGW32:
  case Triple::Cygwin:
  case Triple::Win32:
    assert(0 && "Windows not supported on ARM");
  default:
    return new ELFARMAsmBackend(T, Triple(TT).getOS());
  }
}
<|endoftext|>


<commit_before><commit_msg>test: re-enable http/1 pipelining test<commit_after><|endoftext|>