<commit_before>// Copyright (c) 2015, Robert Escriva
// 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 Replicant 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.

#define __STDC_LIMIT_MACROS

// POSIX
#include <errno.h>
#include <signal.h>

// po6
#include <po6/error.h>

// e
#include <e/guard.h>

// Replicant
#include <replicant.h>
#include "visibility.h"
#include "common/macros.h"
#include "client/client.h"

#define FAKE_STATUS replicant_returncode _status; replicant_returncode* status = &_status

#define SIGNAL_PROTECT_ERR(X) \
    sigset_t old_sigs; \
    sigset_t all_sigs; \
    sigfillset(&all_sigs); \
    if (pthread_sigmask(SIG_BLOCK, &all_sigs, &old_sigs) < 0) \
    { \
        *status = REPLICANT_INTERNAL; \
        return (X); \
    } \
    e::guard g = e::makeguard(pthread_sigmask, SIG_SETMASK, (sigset_t*)&old_sigs, (sigset_t*)NULL)

#define SIGNAL_PROTECT SIGNAL_PROTECT_ERR(-1);
inline void return_void() {}
#define SIGNAL_PROTECT_VOID SIGNAL_PROTECT_ERR(return_void());

#define C_WRAP_EXCEPT(X) \
    replicant::client* cl = reinterpret_cast<replicant::client*>(_cl); \
    SIGNAL_PROTECT; \
    try \
    { \
        X \
    } \
    catch (po6::error& e) \
    { \
        errno = e; \
        *status = REPLICANT_EXCEPTION; \
        cl->set_error_message("unhandled exception was thrown"); \
        return -1; \
    } \
    catch (std::bad_alloc& ba) \
    { \
        errno = ENOMEM; \
        *status = REPLICANT_SEE_ERRNO; \
        cl->set_error_message("out of memory"); \
        return -1; \
    } \
    catch (...) \
    { \
        *status = REPLICANT_EXCEPTION; \
        cl->set_error_message("unhandled exception was thrown"); \
        return -1; \
    }

#define C_WRAP_EXCEPT_VOID(X) \
    replicant::client* cl = reinterpret_cast<replicant::client*>(_cl); \
    SIGNAL_PROTECT_VOID; \
    try \
    { \
        X \
    } \
    catch (po6::error& e) \
    { \
        errno = e; \
        *status = REPLICANT_EXCEPTION; \
        cl->set_error_message("unhandled exception was thrown"); \
    } \
    catch (std::bad_alloc& ba) \
    { \
        errno = ENOMEM; \
        *status = REPLICANT_SEE_ERRNO; \
        cl->set_error_message("out of memory"); \
    } \
    catch (...) \
    { \
        *status = REPLICANT_EXCEPTION; \
        cl->set_error_message("unhandled exception was thrown"); \
    }

extern "C"
{

REPLICANT_API replicant_client*
replicant_client_create(const char* coordinator, uint16_t port)
{
    FAKE_STATUS;
    SIGNAL_PROTECT_ERR(NULL);
    try
    {
        return reinterpret_cast<replicant_client*>(new replicant::client(coordinator, port));
    }
    catch (po6::error& e)
    {
        errno = e;
        return NULL;
    }
    catch (std::bad_alloc& ba)
    {
        errno = ENOMEM;
        return NULL;
    }
    catch (...)
    {
        return NULL;
    }
}

REPLICANT_API replicant_client*
replicant_client_create_conn_str(const char* conn_str)
{
    FAKE_STATUS;
    SIGNAL_PROTECT_ERR(NULL);
    try
    {
        return reinterpret_cast<replicant_client*>(new replicant::client(conn_str));
    }
    catch (po6::error& e)
    {
        errno = e;
        return NULL;
    }
    catch (std::bad_alloc& ba)
    {
        errno = ENOMEM;
        return NULL;
    }
    catch (...)
    {
        return NULL;
    }
}

REPLICANT_API void
replicant_client_destroy(replicant_client* client)
{
    delete reinterpret_cast<replicant::client*>(client);
}

REPLICANT_API int64_t
replicant_client_poke(struct replicant_client* _cl,
                      replicant_returncode* status)
{
    C_WRAP_EXCEPT(
    return cl->poke(status);
    );
}

REPLICANT_API int64_t
replicant_client_generate_unique_number(struct replicant_client* _cl,
                                        replicant_returncode* status,
                                        uint64_t* number)
{
    C_WRAP_EXCEPT(
    return cl->generate_unique_number(status, number);
    );
}

REPLICANT_API int64_t
replicant_client_new_object(struct replicant_client* _cl,
                            const char* object,
                            const char* path,
                            replicant_returncode* status)
{
    C_WRAP_EXCEPT(
    return cl->new_object(object, path, status);
    );
}

REPLICANT_API int64_t
replicant_client_del_object(struct replicant_client* _cl,
                            const char* object,
                            replicant_returncode* status)
{
    C_WRAP_EXCEPT(
    return cl->del_object(object, status);
    );
}

REPLICANT_API int64_t
replicant_client_kill_object(struct replicant_client* _cl,
                             const char* object,
                             replicant_returncode* status)
{
    C_WRAP_EXCEPT(
    return cl->kill_object(object, status);
    );
}

REPLICANT_API int64_t
replicant_client_backup_object(struct replicant_client* _cl,
                               const char* object,
                               enum replicant_returncode* status,
                               char** state, size_t* state_sz)
{
    C_WRAP_EXCEPT(
    return cl->backup_object(object, status, state, state_sz);
    );
}

REPLICANT_API int64_t
replicant_client_restore_object(struct replicant_client* _cl,
                                const char* object,
                                const char* backup, size_t backup_sz,
                                enum replicant_returncode* status)
{
    C_WRAP_EXCEPT(
    return cl->restore_object(object, backup, backup_sz, status);
    );
}

REPLICANT_API int64_t
replicant_client_list_objects(struct replicant_client* _cl,
                              enum replicant_returncode* status,
                              char** objects)
{
    C_WRAP_EXCEPT(
    return cl->list_objects(status, objects);
    );
}

REPLICANT_API int64_t
replicant_client_call(struct replicant_client* _cl,
                      const char* object,
                      const char* func,
                      const char* input, size_t input_sz,
                      unsigned flags,
                      replicant_returncode* status,
                      char** output, size_t* output_sz)
{
    C_WRAP_EXCEPT(
    return cl->call(object, func, input, input_sz, flags, status, output, output_sz);
    );
}

REPLICANT_API int64_t
replicant_client_cond_wait(struct replicant_client* _cl,
                           const char* object,
                           const char* cond,
                           uint64_t state,
                           replicant_returncode* status,
                           char** data, size_t* data_sz)
{
    C_WRAP_EXCEPT(
    return cl->cond_wait(object, cond, state, status, data, data_sz);
    );
}

REPLICANT_API int64_t
replicant_client_cond_follow(struct replicant_client* _cl,
                             const char* object,
                             const char* cond,
                             enum replicant_returncode* status,
                             uint64_t* state,
                             char** data, size_t* data_sz)
{
    C_WRAP_EXCEPT(
    return cl->cond_follow(object, cond, status, state, data, data_sz);
    );
}

REPLICANT_API int64_t
replicant_client_defended_call(struct replicant_client* _cl,
                               const char* object,
                               const char* enter_func,
                               const char* enter_input, size_t enter_input_sz,
                               const char* exit_func,
                               const char* exit_input, size_t exit_input_sz,
                               enum replicant_returncode* status)
{
    C_WRAP_EXCEPT(
    return cl->defended_call(object, enter_func, enter_input, enter_input_sz,
                             exit_func, exit_input, exit_input_sz, status);
    );
}

REPLICANT_API int
replicant_client_conn_str(struct replicant_client* _cl,
                          enum replicant_returncode* status,
                          char** servers)
{
    C_WRAP_EXCEPT(
    return cl->conn_str(status, servers);
    );
}

REPLICANT_API int64_t
replicant_client_kill_server(struct replicant_client* _cl,
                             uint64_t token,
                             enum replicant_returncode* status)
{
    C_WRAP_EXCEPT(
    return cl->kill_server(token, status);
    );
}

REPLICANT_API int64_t
replicant_client_loop(struct replicant_client* _cl, int timeout,
                      enum replicant_returncode* status)
{
    C_WRAP_EXCEPT(
    return cl->loop(timeout, status);
    );
}

REPLICANT_API int64_t
replicant_client_wait(struct replicant_client* _cl,
                      int64_t specific_op, int timeout,
                      enum replicant_returncode* status)
{
    C_WRAP_EXCEPT(
    return cl->wait(specific_op, timeout, status);
    );
}

REPLICANT_API int
replicant_client_poll_fd(replicant_client* _cl)
{
    FAKE_STATUS;
    C_WRAP_EXCEPT(
    return cl->poll_fd();
    );
}

REPLICANT_API int
replicant_client_block(replicant_client* _cl, int timeout)
{
    FAKE_STATUS;
    C_WRAP_EXCEPT(
    return cl->block(timeout);
    );
}

REPLICANT_API const char*
replicant_client_error_message(replicant_client* _cl)
{
    FAKE_STATUS;
    SIGNAL_PROTECT_ERR(NULL);
    replicant::client* cl = reinterpret_cast<replicant::client*>(_cl);
    return cl->error_message();
}

REPLICANT_API const char*
replicant_client_error_location(replicant_client* _cl)
{
    FAKE_STATUS;
    SIGNAL_PROTECT_ERR(NULL);
    replicant::client* cl = reinterpret_cast<replicant::client*>(_cl);
    return cl->error_location();
}

REPLICANT_API const char*
replicant_returncode_to_string(enum replicant_returncode stat)
{
    FAKE_STATUS;
    SIGNAL_PROTECT_ERR(NULL);
    switch (stat)
    {
        CSTRINGIFY(REPLICANT_SUCCESS);
        CSTRINGIFY(REPLICANT_MAYBE);
        CSTRINGIFY(REPLICANT_SEE_ERRNO);
        CSTRINGIFY(REPLICANT_CLUSTER_JUMP);
        CSTRINGIFY(REPLICANT_COMM_FAILED);
        CSTRINGIFY(REPLICANT_OBJ_NOT_FOUND);
        CSTRINGIFY(REPLICANT_OBJ_EXIST);
        CSTRINGIFY(REPLICANT_FUNC_NOT_FOUND);
        CSTRINGIFY(REPLICANT_COND_NOT_FOUND);
        CSTRINGIFY(REPLICANT_COND_DESTROYED);
        CSTRINGIFY(REPLICANT_SERVER_ERROR);
        CSTRINGIFY(REPLICANT_TIMEOUT);
        CSTRINGIFY(REPLICANT_INTERRUPTED);
        CSTRINGIFY(REPLICANT_NONE_PENDING);
        CSTRINGIFY(REPLICANT_INTERNAL);
        CSTRINGIFY(REPLICANT_EXCEPTION);
        CSTRINGIFY(REPLICANT_GARBAGE);
        default:
            return "unknown replicant_returncode";
    }
}

} // extern "C"
<commit_msg>Implement replicant_client_kill<commit_after>// Copyright (c) 2015, Robert Escriva
// 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 Replicant 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.

#define __STDC_LIMIT_MACROS

// POSIX
#include <errno.h>
#include <signal.h>

// po6
#include <po6/error.h>

// e
#include <e/guard.h>

// Replicant
#include <replicant.h>
#include "visibility.h"
#include "common/macros.h"
#include "client/client.h"

#define FAKE_STATUS replicant_returncode _status; replicant_returncode* status = &_status

#define SIGNAL_PROTECT_ERR(X) \
    sigset_t old_sigs; \
    sigset_t all_sigs; \
    sigfillset(&all_sigs); \
    if (pthread_sigmask(SIG_BLOCK, &all_sigs, &old_sigs) < 0) \
    { \
        *status = REPLICANT_INTERNAL; \
        return (X); \
    } \
    e::guard g = e::makeguard(pthread_sigmask, SIG_SETMASK, (sigset_t*)&old_sigs, (sigset_t*)NULL)

#define SIGNAL_PROTECT SIGNAL_PROTECT_ERR(-1);
inline void return_void() {}
#define SIGNAL_PROTECT_VOID SIGNAL_PROTECT_ERR(return_void());

#define C_WRAP_EXCEPT(X) \
    replicant::client* cl = reinterpret_cast<replicant::client*>(_cl); \
    SIGNAL_PROTECT; \
    try \
    { \
        X \
    } \
    catch (po6::error& e) \
    { \
        errno = e; \
        *status = REPLICANT_EXCEPTION; \
        cl->set_error_message("unhandled exception was thrown"); \
        return -1; \
    } \
    catch (std::bad_alloc& ba) \
    { \
        errno = ENOMEM; \
        *status = REPLICANT_SEE_ERRNO; \
        cl->set_error_message("out of memory"); \
        return -1; \
    } \
    catch (...) \
    { \
        *status = REPLICANT_EXCEPTION; \
        cl->set_error_message("unhandled exception was thrown"); \
        return -1; \
    }

#define C_WRAP_EXCEPT_VOID(X) \
    replicant::client* cl = reinterpret_cast<replicant::client*>(_cl); \
    SIGNAL_PROTECT_VOID; \
    try \
    { \
        X \
    } \
    catch (po6::error& e) \
    { \
        errno = e; \
        *status = REPLICANT_EXCEPTION; \
        cl->set_error_message("unhandled exception was thrown"); \
    } \
    catch (std::bad_alloc& ba) \
    { \
        errno = ENOMEM; \
        *status = REPLICANT_SEE_ERRNO; \
        cl->set_error_message("out of memory"); \
    } \
    catch (...) \
    { \
        *status = REPLICANT_EXCEPTION; \
        cl->set_error_message("unhandled exception was thrown"); \
    }

extern "C"
{

REPLICANT_API replicant_client*
replicant_client_create(const char* coordinator, uint16_t port)
{
    FAKE_STATUS;
    SIGNAL_PROTECT_ERR(NULL);
    try
    {
        return reinterpret_cast<replicant_client*>(new replicant::client(coordinator, port));
    }
    catch (po6::error& e)
    {
        errno = e;
        return NULL;
    }
    catch (std::bad_alloc& ba)
    {
        errno = ENOMEM;
        return NULL;
    }
    catch (...)
    {
        return NULL;
    }
}

REPLICANT_API replicant_client*
replicant_client_create_conn_str(const char* conn_str)
{
    FAKE_STATUS;
    SIGNAL_PROTECT_ERR(NULL);
    try
    {
        return reinterpret_cast<replicant_client*>(new replicant::client(conn_str));
    }
    catch (po6::error& e)
    {
        errno = e;
        return NULL;
    }
    catch (std::bad_alloc& ba)
    {
        errno = ENOMEM;
        return NULL;
    }
    catch (...)
    {
        return NULL;
    }
}

REPLICANT_API void
replicant_client_destroy(replicant_client* client)
{
    delete reinterpret_cast<replicant::client*>(client);
}

REPLICANT_API int64_t
replicant_client_poke(struct replicant_client* _cl,
                      replicant_returncode* status)
{
    C_WRAP_EXCEPT(
    return cl->poke(status);
    );
}

REPLICANT_API int64_t
replicant_client_generate_unique_number(struct replicant_client* _cl,
                                        replicant_returncode* status,
                                        uint64_t* number)
{
    C_WRAP_EXCEPT(
    return cl->generate_unique_number(status, number);
    );
}

REPLICANT_API int64_t
replicant_client_new_object(struct replicant_client* _cl,
                            const char* object,
                            const char* path,
                            replicant_returncode* status)
{
    C_WRAP_EXCEPT(
    return cl->new_object(object, path, status);
    );
}

REPLICANT_API int64_t
replicant_client_del_object(struct replicant_client* _cl,
                            const char* object,
                            replicant_returncode* status)
{
    C_WRAP_EXCEPT(
    return cl->del_object(object, status);
    );
}

REPLICANT_API int64_t
replicant_client_kill_object(struct replicant_client* _cl,
                             const char* object,
                             replicant_returncode* status)
{
    C_WRAP_EXCEPT(
    return cl->kill_object(object, status);
    );
}

REPLICANT_API int64_t
replicant_client_backup_object(struct replicant_client* _cl,
                               const char* object,
                               enum replicant_returncode* status,
                               char** state, size_t* state_sz)
{
    C_WRAP_EXCEPT(
    return cl->backup_object(object, status, state, state_sz);
    );
}

REPLICANT_API int64_t
replicant_client_restore_object(struct replicant_client* _cl,
                                const char* object,
                                const char* backup, size_t backup_sz,
                                enum replicant_returncode* status)
{
    C_WRAP_EXCEPT(
    return cl->restore_object(object, backup, backup_sz, status);
    );
}

REPLICANT_API int64_t
replicant_client_list_objects(struct replicant_client* _cl,
                              enum replicant_returncode* status,
                              char** objects)
{
    C_WRAP_EXCEPT(
    return cl->list_objects(status, objects);
    );
}

REPLICANT_API int64_t
replicant_client_call(struct replicant_client* _cl,
                      const char* object,
                      const char* func,
                      const char* input, size_t input_sz,
                      unsigned flags,
                      replicant_returncode* status,
                      char** output, size_t* output_sz)
{
    C_WRAP_EXCEPT(
    return cl->call(object, func, input, input_sz, flags, status, output, output_sz);
    );
}

REPLICANT_API int64_t
replicant_client_cond_wait(struct replicant_client* _cl,
                           const char* object,
                           const char* cond,
                           uint64_t state,
                           replicant_returncode* status,
                           char** data, size_t* data_sz)
{
    C_WRAP_EXCEPT(
    return cl->cond_wait(object, cond, state, status, data, data_sz);
    );
}

REPLICANT_API int64_t
replicant_client_cond_follow(struct replicant_client* _cl,
                             const char* object,
                             const char* cond,
                             enum replicant_returncode* status,
                             uint64_t* state,
                             char** data, size_t* data_sz)
{
    C_WRAP_EXCEPT(
    return cl->cond_follow(object, cond, status, state, data, data_sz);
    );
}

REPLICANT_API int64_t
replicant_client_defended_call(struct replicant_client* _cl,
                               const char* object,
                               const char* enter_func,
                               const char* enter_input, size_t enter_input_sz,
                               const char* exit_func,
                               const char* exit_input, size_t exit_input_sz,
                               enum replicant_returncode* status)
{
    C_WRAP_EXCEPT(
    return cl->defended_call(object, enter_func, enter_input, enter_input_sz,
                             exit_func, exit_input, exit_input_sz, status);
    );
}

REPLICANT_API int
replicant_client_conn_str(struct replicant_client* _cl,
                          enum replicant_returncode* status,
                          char** servers)
{
    C_WRAP_EXCEPT(
    return cl->conn_str(status, servers);
    );
}

REPLICANT_API int64_t
replicant_client_kill_server(struct replicant_client* _cl,
                             uint64_t token,
                             enum replicant_returncode* status)
{
    C_WRAP_EXCEPT(
    return cl->kill_server(token, status);
    );
}

REPLICANT_API int64_t
replicant_client_loop(struct replicant_client* _cl, int timeout,
                      enum replicant_returncode* status)
{
    C_WRAP_EXCEPT(
    return cl->loop(timeout, status);
    );
}

REPLICANT_API int64_t
replicant_client_wait(struct replicant_client* _cl,
                      int64_t specific_op, int timeout,
                      enum replicant_returncode* status)
{
    C_WRAP_EXCEPT(
    return cl->wait(specific_op, timeout, status);
    );
}

REPLICANT_API int
replicant_client_kill(struct replicant_client* _cl, int64_t id)
{
    FAKE_STATUS;
    C_WRAP_EXCEPT(
    cl->kill(id);
    return 0;
    );
}

REPLICANT_API int
replicant_client_poll_fd(replicant_client* _cl)
{
    FAKE_STATUS;
    C_WRAP_EXCEPT(
    return cl->poll_fd();
    );
}

REPLICANT_API int
replicant_client_block(replicant_client* _cl, int timeout)
{
    FAKE_STATUS;
    C_WRAP_EXCEPT(
    return cl->block(timeout);
    );
}

REPLICANT_API const char*
replicant_client_error_message(replicant_client* _cl)
{
    FAKE_STATUS;
    SIGNAL_PROTECT_ERR(NULL);
    replicant::client* cl = reinterpret_cast<replicant::client*>(_cl);
    return cl->error_message();
}

REPLICANT_API const char*
replicant_client_error_location(replicant_client* _cl)
{
    FAKE_STATUS;
    SIGNAL_PROTECT_ERR(NULL);
    replicant::client* cl = reinterpret_cast<replicant::client*>(_cl);
    return cl->error_location();
}

REPLICANT_API const char*
replicant_returncode_to_string(enum replicant_returncode stat)
{
    FAKE_STATUS;
    SIGNAL_PROTECT_ERR(NULL);
    switch (stat)
    {
        CSTRINGIFY(REPLICANT_SUCCESS);
        CSTRINGIFY(REPLICANT_MAYBE);
        CSTRINGIFY(REPLICANT_SEE_ERRNO);
        CSTRINGIFY(REPLICANT_CLUSTER_JUMP);
        CSTRINGIFY(REPLICANT_COMM_FAILED);
        CSTRINGIFY(REPLICANT_OBJ_NOT_FOUND);
        CSTRINGIFY(REPLICANT_OBJ_EXIST);
        CSTRINGIFY(REPLICANT_FUNC_NOT_FOUND);
        CSTRINGIFY(REPLICANT_COND_NOT_FOUND);
        CSTRINGIFY(REPLICANT_COND_DESTROYED);
        CSTRINGIFY(REPLICANT_SERVER_ERROR);
        CSTRINGIFY(REPLICANT_TIMEOUT);
        CSTRINGIFY(REPLICANT_INTERRUPTED);
        CSTRINGIFY(REPLICANT_NONE_PENDING);
        CSTRINGIFY(REPLICANT_INTERNAL);
        CSTRINGIFY(REPLICANT_EXCEPTION);
        CSTRINGIFY(REPLICANT_GARBAGE);
        default:
            return "unknown replicant_returncode";
    }
}

} // extern "C"
<|endoftext|>


<commit_before>#include <gmock/gmock.h>

#include <cppexpose/variant/Variant.h>
#include <utility>

using namespace cppexpose;

using memberFunc = bool (Variant::*)() const;

bool equal(memberFunc first, memberFunc second)
{
    return first == second;
}

class variantTest : public testing::Test
{
public:
    variantTest()
    {
    }

    virtual void SetUp() override;

protected:

    std::vector<memberFunc> methods;
};

void variantTest::SetUp()
{
    methods.emplace_back(&Variant::isBool);
    methods.emplace_back(&Variant::isEnum);
    methods.emplace_back(&Variant::isVariant);
    methods.emplace_back(&Variant::isString);
    methods.emplace_back(&Variant::isNumber);
    methods.emplace_back(&Variant::isIntegral);
    methods.emplace_back(&Variant::isSignedIntegral);
    methods.emplace_back(&Variant::isUnsignedIntegral);
    methods.emplace_back(&Variant::isFloatingPoint);
    methods.emplace_back(&Variant::isNull);
    methods.emplace_back(&Variant::isVariantArray);
    methods.emplace_back(&Variant::isVariantMap);
}

void testType(Variant &var, std::vector<memberFunc> trueFuncs, const std::vector<memberFunc>& methods)
{
    for(auto& method : methods)
    {
        bool test = (var.*method)();
        if(std::find(trueFuncs.begin(), trueFuncs.end(), method) != trueFuncs.end())
            ASSERT_TRUE(test);
        else
            ASSERT_FALSE(test);
    }
}

void testType(Variant& var, memberFunc trueFunc, const std::vector<memberFunc>& methods)
{
    testType(var, std::vector<memberFunc>({trueFunc}), methods);
}

TEST_F(variantTest, constructorBool)
{
    const bool b = true;

    auto var = Variant(b);

    testType(var, &Variant::isBool, methods);
    ASSERT_TRUE(var.toBool());
}

TEST_F(variantTest, constructorString)
{
    const std::string str = "test";

    auto var = Variant(str);

    testType(var, &Variant::isString, methods);
    ASSERT_EQ(str, var.toString());
}

TEST_F(variantTest, constructorSignedIntegral)
{
   int i = -10;

   auto var = Variant(i);

   testType(var, {&Variant::isIntegral, &Variant::isNumber, &Variant::isSignedIntegral}, methods);
   ASSERT_EQ(i, var.toLongLong());
}

TEST_F(variantTest, constructorUnsignedIntegral)
{
   unsigned int i = 10;

   auto var = Variant(i);

   testType(var, {&Variant::isIntegral, &Variant::isNumber, &Variant::isUnsignedIntegral}, methods);
   ASSERT_EQ(i, var.toLongLong());
}

TEST_F(variantTest, constructorFloat)
{
    float f = 100.0f;

    auto var = Variant(f);

    testType(var, {&Variant::isNumber, &Variant::isFloatingPoint}, methods);
    ASSERT_EQ(f, var.toDouble());
}

TEST_F(variantTest, constructorEmpty)
{
    auto var = Variant();

    testType(var, &Variant::isNull, methods);
}

/*
    methods.emplace_back(&Variant::isVariant);
    methods.emplace_back(&Variant::isNumber);
    methods.emplace_back(&Variant::isIntegral);
    methods.emplace_back(&Variant::isSignedIntegral);
    methods.emplace_back(&Variant::isUnsignedIntegral);
    methods.emplace_back(&Variant::isFloatingPoint);
    methods.emplace_back(&Variant::isNull);
    methods.emplace_back(&Variant::isVariantArray);
    methods.emplace_back(&Variant::isVariantMap);
}*/
<commit_msg>adding more tests for the variant<commit_after>#include <gmock/gmock.h>

#include <cppexpose/variant/Variant.h>
#include <utility>

using namespace cppexpose;

using memberFunc = bool (Variant::*)() const;

bool equal(memberFunc first, memberFunc second)
{
    return first == second;
}

class variantTest : public testing::Test
{
public:
    variantTest()
    {
    }

    virtual void SetUp() override;

protected:

    std::vector<memberFunc> methods;
};

void variantTest::SetUp()
{
    methods.emplace_back(&Variant::isBool);
    methods.emplace_back(&Variant::isEnum);
    methods.emplace_back(&Variant::isVariant);
    methods.emplace_back(&Variant::isString);
    methods.emplace_back(&Variant::isNumber);
    methods.emplace_back(&Variant::isIntegral);
    methods.emplace_back(&Variant::isSignedIntegral);
    methods.emplace_back(&Variant::isUnsignedIntegral);
    methods.emplace_back(&Variant::isFloatingPoint);
    methods.emplace_back(&Variant::isNull);
    methods.emplace_back(&Variant::isVariantArray);
    methods.emplace_back(&Variant::isVariantMap);
}

void testType(Variant &var, std::vector<memberFunc> trueFuncs, const std::vector<memberFunc>& methods)
{
    for(auto& method : methods)
    {
        bool test = (var.*method)();
        if(std::find(trueFuncs.begin(), trueFuncs.end(), method) != trueFuncs.end())
            ASSERT_TRUE(test);
        else
            ASSERT_FALSE(test);
    }
}

void testType(Variant& var, memberFunc trueFunc, const std::vector<memberFunc>& methods)
{
    testType(var, std::vector<memberFunc>({trueFunc}), methods);
}

TEST_F(variantTest, constructorBool)
{
    const bool b = true;

    auto var = Variant(b);

    testType(var, &Variant::isBool, methods);
    ASSERT_TRUE(var.toBool());
}

TEST_F(variantTest, constructorString)
{
    const std::string str = "test";

    auto var = Variant(str);

    testType(var, &Variant::isString, methods);
    ASSERT_EQ(str, var.toString());
}

TEST_F(variantTest, constructorSignedIntegral)
{
   int i = -10;

   auto var = Variant(i);

   testType(var, {&Variant::isIntegral, &Variant::isNumber, &Variant::isSignedIntegral}, methods);
   ASSERT_EQ(i, var.toLongLong());
}

TEST_F(variantTest, constructorUnsignedIntegral)
{
   unsigned int i = 10;

   auto var = Variant(i);

   testType(var, {&Variant::isIntegral, &Variant::isNumber, &Variant::isUnsignedIntegral}, methods);
   ASSERT_EQ(i, var.toLongLong());
}

TEST_F(variantTest, constructorFloat)
{
    float f = 100.0f;

    auto var = Variant(f);

    testType(var, {&Variant::isNumber, &Variant::isFloatingPoint}, methods);
    ASSERT_EQ(f, var.toDouble());
}

TEST_F(variantTest, constructorEmpty)
{
    auto var = Variant();

    testType(var, &Variant::isNull, methods);
}

TEST_F(variantTest, constructorVariantArray)
{
    auto var = Variant(VariantArray());

    testType(var, &Variant::isVariantArray, methods);
}

TEST_F(variantTest, staticConstructorVariantArray)
{
    auto var = Variant::array();

    testType(var, &Variant::isVariantArray, methods);

    var = Variant::array(100u);

    testType(var, &Variant::isVariantArray, methods);
}

TEST_F(variantTest, constructorVariantMap)
{
    auto var = Variant(VariantMap());

    testType(var, &Variant::isVariantMap, methods);
}

TEST_F(variantTest, staticConstructorVariantMap)
{
    auto var = Variant::map();

    testType(var, &Variant::isVariantMap, methods);
}
<|endoftext|>


<commit_before>#include <cstdint>
#include <cstring>
#include <string.h>

#include "Register.hpp"

using namespace std;

Register::Register()
: len(0) {

}

uint64_t Register::getInteger(){
    uint64_t v = *reinterpret_cast<uint64_t*>(this->data);
    return v;
}

void Register::setInteger(uint64_t value){
    if (this->len == 0) {
        this->data = (char*) malloc(sizeof(uint64_t) + sizeof(char));
    } else {
        this->data = (char*) realloc(sizeof(uint64_t) + sizeof(char));
    }
    memcpy(this->data, &value, sizeof(value));
    this->data[sizeof(uint64_t)] = '\0';
    len = sizeof(uint64_t);
}

string Register::getString(){
    return string(this->data);
}

void Register::setString(const string& value){
    if (this->len == 0) {
        this->data = (char*) malloc(value.length() * sizeof(char) + sizeof(char));
    } else {
        this->data = (char*) realloc(value.length() * sizeof(char) + sizeof(char));
    }
    memcpy(this->data, value.c_str(), value.length() * sizeof(char));
    this->data[value.length()] = '\0';
    len = value.length() * sizeof(char);
}

uint64_t Register::hash(){
    return this->hashfun(string(this->data));
}

bool Register::operator==(Register &that) {
    return strcmp(this->data, that.getString().c_str());
}

bool Register::operator==(Register *that) {
    return strcmp(this->data, that->getString().c_str());
}

Register::~Register(){
    free(this->data);
}
<commit_msg>Register realloc on override.<commit_after>#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <string.h>

#include "Register.hpp"

using namespace std;

Register::Register()
: len(0) {

}

uint64_t Register::getInteger(){
    uint64_t v = *reinterpret_cast<uint64_t*>(this->data);
    return v;
}

void Register::setInteger(uint64_t value){
    if (this->len == 0) {
        this->data = (char*) malloc(sizeof(uint64_t) + sizeof(char));
    } else {
        this->data = (char*) realloc(this->data, sizeof(uint64_t) + sizeof(char));
    }
    memcpy(this->data, &value, sizeof(value));
    this->data[sizeof(uint64_t)] = '\0';
    len = sizeof(uint64_t);
}

string Register::getString(){
    return string(this->data);
}

void Register::setString(const string& value){
    if (this->len == 0) {
        this->data = (char*) malloc(value.length() * sizeof(char) + sizeof(char));
    } else {
        this->data = (char*) realloc(this->data, value.length() * sizeof(char) + sizeof(char));
    }
    memcpy(this->data, value.c_str(), value.length() * sizeof(char));
    this->data[value.length()] = '\0';
    len = value.length() * sizeof(char);
}

uint64_t Register::hash(){
    return this->hashfun(string(this->data));
}

bool Register::operator==(Register &that) {
    return strcmp(this->data, that.getString().c_str());
}

bool Register::operator==(Register *that) {
    return strcmp(this->data, that->getString().c_str());
}

Register::~Register(){
    free(this->data);
}
<|endoftext|>


<commit_before>/***************************************************************************
 *  @file       heap.hpp
 *  @author     Yue Wang
 *  @date       30  Aug 2014
 *  @version    2
 *  @remark     CLRS Algorithms implementation in C++ templates.
 ***************************************************************************/
#ifndef HEAP_HPP
#define HEAP_HPP

#include <functional>

namespace clrs { namespace ch6 {

/**
 * @brief parent
 */
template<typename SizeType>
inline SizeType parent(SizeType target)
{
    return (target - 1)/2;
}

/**
 * @brief left
 */
template<typename SizeType>
inline SizeType left(SizeType target)
{
    return 2 * target + 1;
}

/**
 * @brief right
 */
template<typename SizeType>
inline SizeType right(SizeType target)
{
    return 2 * target + 2;
}

/**
 * @brief max_heapify
 * @param rng
 * @param curr
 *
 * @pseudocode MAX-HEAPIFY, Page 154
 * @recurrence T(n) <= T(2n/3) + theta(1)
 * @complx  O(lg n)
 */
template<typename Range>
void max_heapify(Range& rng, typename Range::size_type curr)
{
    //! compare with left child
    auto l = left(curr);
    auto largest = (l < rng.size()  &&  rng[l] > rng[curr])?  l   :   curr;

    //! compare with right child
    auto r = right(curr);
    if(r < rng.size()   &&  rng[r] > rng[largest])  largest = r;

    //! recur
    if(largest != curr)
    {
        std::swap(rng[largest], rng[curr]);
        max_heapify(rng, largest);
    }
}

/**
 * @brief min_heapify
 * @param rng
 * @param curr
 *
 * @recurrence T(n) <= T(2n/3) + theta(1)
 * @complx  O(lg n)
 *
 * for ex6.2-2
 */
template<typename Range>
void min_heapify(Range& rng, typename Range::size_type curr)
{
    //! compare with left child
    auto l = left(curr);
    auto smallest = (l < rng.size()  &&  rng[l] < rng[curr])?  l   :   curr;

    //! compare with right child
    auto r = right(curr);
    if(r < rng.size()   &&  rng[r] < rng[smallest])  smallest = r;

    //! recur
    if(smallest != curr)
    {
        std::swap(rng[smallest], rng[curr]);
        max_heapify(rng, smallest);
    }
}

/**
 * @brief heapify
 * @param rng
 * @param curr
 * @param compare
 *
 * @recurrence T(n) <= T(2n/3) + theta(1)
 * @complx  O(lg n)
 */
template<typename Range, typename Comp = std::greater<typename Range::value_type> >
void heapify(Range& rng, typename Range::size_type curr, Comp compare = Comp())
{
    //! compare with left child
    auto l = left(curr);
    auto extreme = (l < rng.size()  &&  compare(rng[l], rng[curr]))?  l   :   curr;

    //! compare with right child
    auto r = right(curr);
    if(r < rng.size()   &&  compare(rng[r], rng[extreme]))  extreme = r;

    //! recur
    if(extreme != curr)
    {
        std::swap(rng[extreme], rng[curr]);
        heapify(rng, extreme);
    }
}

/**
 * @brief heapify_itera
 * @param rng
 * @param curr
 * @param compare
 *
 * @recurrence T(n) <= T(2n/3) + theta(1)
 * @complx  O(lg n)
 *
 * for ex6.2-5
 */
template<typename Range, typename Comp = std::greater<typename Range::value_type> >
void heapify_itera(Range& rng, typename Range::size_type curr, Comp compare = Comp())
{
    while(true)
    {
        //! find max or min, depending on Comp.
        auto l = left(curr);
        auto extreme =
                (l < rng.size()  &&  compare(rng[l], rng[curr]))?  l   :   curr;
        auto r = right(curr);
        if(r < rng.size()   &&  compare(rng[r], rng[extreme]))
            extreme = r;

        //! iteration check
        if(extreme != curr)
        {
            std::swap(rng[extreme], rng[curr]);
            curr = extreme;
        }
        else    break;
    }
}

}}//namespace
#endif // HEAP_HPP

//! @test   max_heapify, min_heapify, heapify, heapify_itera
//!
//#include <vector>
//#include <iostream>
//#include "../misc/alan.hpp"
//#include "heap.hpp"

//int main()
//{
//    std::vector<int> v {16,4,10,14,7,9,3,2,8,1};
//    std::vector<int> v1,v2,v3,v4,v5,v6;
//    v1 = v2 = v3 = v4 = v5 = v6 = v;

//    //! max heapify
//    clrs::ch6::max_heapify(v1,1);
//    alan::print_container(v1);
//    std::cout << "\n";
//    clrs::ch6::heapify(v2,1,std::greater<int>());
//    alan::print_container(v2);

//    std::cout << "\n\n";

//    //! min heapify
//    clrs::ch6::min_heapify(v3,1);
//    alan::print_container(v3);
//    std::cout << "\n";
//    clrs::ch6::heapify(v4,1,std::less<int>());
//    alan::print_container(v4);

//    //! iteration version
//    std::cout << "\n";
//    clrs::ch6::heapify_itera(v5,1,std::less<int>());
//    alan::print_container(v5);

//    alan::end();
//    return 0;
//}

//! @output
//!
//16 14 10 8 7 9 3 2 4 1
//16 14 10 8 7 9 3 2 4 1

//16 4 10 14 7 9 3 2 8 1
//16 4 10 14 7 9 3 2 8 1
//16 4 10 14 7 9 3 2 8 1
//exit normally

<commit_msg>add  build_max_heap modified:   ch06/heap.hpp<commit_after>/***************************************************************************
 *  @file       heap.hpp
 *  @author     Yue Wang
 *  @date       30  Aug 2014
 *  @version    2
 *  @remark     CLRS Algorithms implementation in C++ templates.
 ***************************************************************************/
#ifndef HEAP_HPP
#define HEAP_HPP

#include <functional>

namespace clrs { namespace ch6 {

/**
 * @brief parent
 */
template<typename SizeType>
inline SizeType parent(SizeType target)
{
    return (target - 1)/2;
}

/**
 * @brief left
 */
template<typename SizeType>
inline SizeType left(SizeType target)
{
    return 2 * target + 1;
}

/**
 * @brief right
 */
template<typename SizeType>
inline SizeType right(SizeType target)
{
    return 2 * target + 2;
}

/**
 * @brief max_heapify
 * @param rng
 * @param curr
 *
 * @pseudocode MAX-HEAPIFY, Page 154
 * @recurrence T(n) <= T(2n/3) + theta(1)
 * @complx  O(lg n)
 */
template<typename Range>
void max_heapify(Range& rng, typename Range::size_type curr)
{
    //! compare with left child
    auto l = left(curr);
    auto largest = (l < rng.size()  &&  rng[l] > rng[curr])?  l   :   curr;

    //! compare with right child
    auto r = right(curr);
    if(r < rng.size()   &&  rng[r] > rng[largest])  largest = r;

    //! recur
    if(largest != curr)
    {
        std::swap(rng[largest], rng[curr]);
        max_heapify(rng, largest);
    }
}

/**
 * @brief min_heapify
 * @param rng
 * @param curr
 *
 * @recurrence T(n) <= T(2n/3) + theta(1)
 * @complx  O(lg n)
 *
 * for ex6.2-2
 */
template<typename Range>
void min_heapify(Range& rng, typename Range::size_type curr)
{
    //! compare with left child
    auto l = left(curr);
    auto smallest = (l < rng.size()  &&  rng[l] < rng[curr])?  l   :   curr;

    //! compare with right child
    auto r = right(curr);
    if(r < rng.size()   &&  rng[r] < rng[smallest])  smallest = r;

    //! recur
    if(smallest != curr)
    {
        std::swap(rng[smallest], rng[curr]);
        max_heapify(rng, smallest);
    }
}

/**
 * @brief heapify
 * @param rng
 * @param curr
 * @param compare
 *
 * @recurrence T(n) <= T(2n/3) + theta(1)
 * @complx  O(lg n)
 */
template<typename Range, typename Comp = std::greater<typename Range::value_type> >
void heapify(Range& rng, typename Range::size_type curr, Comp compare = Comp())
{
    //! compare with left child
    auto l = left(curr);
    auto extreme = (l < rng.size()  &&  compare(rng[l], rng[curr]))?  l   :   curr;

    //! compare with right child
    auto r = right(curr);
    if(r < rng.size()   &&  compare(rng[r], rng[extreme]))  extreme = r;

    //! recur
    if(extreme != curr)
    {
        std::swap(rng[extreme], rng[curr]);
        heapify(rng, extreme);
    }
}

/**
 * @brief heapify_itera
 * @param rng
 * @param curr
 * @param compare
 *
 * @recurrence T(n) <= T(2n/3) + theta(1)
 * @complx  O(lg n)
 *
 * for ex6.2-5
 */
template<typename Range, typename Comp = std::greater<typename Range::value_type> >
void heapify_itera(Range& rng, typename Range::size_type curr, Comp compare = Comp())
{
    while(true)
    {
        //! find max or min, depending on Comp.
        auto l = left(curr);
        auto extreme =
                (l < rng.size()  &&  compare(rng[l], rng[curr]))?  l   :   curr;
        auto r = right(curr);
        if(r < rng.size()   &&  compare(rng[r], rng[extreme]))
            extreme = r;

        //! iteration check
        if(extreme != curr)
        {
            std::swap(rng[extreme], rng[curr]);
            curr = extreme;
        }
        else    break;
    }
}

template<typename Range>
inline void build_max_heap(Range& rng)
{
    using Index = typename Range::difference_type;
    for(Index curr = rng.size()/2 - 1; curr != -1; --curr)
        max_heapify(rng,curr);
}

}}//namespace
#endif // HEAP_HPP

//! @test   max_heapify, min_heapify, heapify, heapify_itera
//!
//#include <vector>
//#include <iostream>
//#include "../misc/alan.hpp"
//#include "heap.hpp"

//int main()
//{
//    std::vector<int> v {16,4,10,14,7,9,3,2,8,1};
//    std::vector<int> v1,v2,v3,v4,v5,v6;
//    v1 = v2 = v3 = v4 = v5 = v6 = v;

//    //! max heapify
//    clrs::ch6::max_heapify(v1,1);
//    alan::print_container(v1);
//    std::cout << "\n";
//    clrs::ch6::heapify(v2,1,std::greater<int>());
//    alan::print_container(v2);

//    std::cout << "\n\n";

//    //! min heapify
//    clrs::ch6::min_heapify(v3,1);
//    alan::print_container(v3);
//    std::cout << "\n";
//    clrs::ch6::heapify(v4,1,std::less<int>());
//    alan::print_container(v4);

//    //! iteration version
//    std::cout << "\n";
//    clrs::ch6::heapify_itera(v5,1,std::less<int>());
//    alan::print_container(v5);

//    alan::end();
//    return 0;
//}
//! @output
//!
//16 14 10 8 7 9 3 2 4 1
//16 14 10 8 7 9 3 2 4 1

//16 4 10 14 7 9 3 2 8 1
//16 4 10 14 7 9 3 2 8 1
//16 4 10 14 7 9 3 2 8 1
//exit normally

<|endoftext|>


<commit_before>/**********************************************************************
 * $Id$
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.refractions.net
 *
 * Copyright (c) Olivier Devillers <Olivier.Devillers@sophia.inria.fr>
 * Copyright (C) 2006 Refractions Research Inc.
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Public Licence as published
 * by the Free Software Foundation.
 * See the COPYING file for more information.
 *
 **********************************************************************
 *
 * Last port: algorithm/RobustDeterminant.java 1.15 (JTS-1.10)
 *
 **********************************************************************/

#include <geos/algorithm/RobustDeterminant.h>
#include <geos/util/IllegalArgumentException.h>

#include <cmath>

#include <geos/platform.h> // for ISNAN, FINITE

#ifdef _MSC_VER
#pragma warning(disable : 4127)
#endif

using namespace std; // for isfinite..

namespace geos {
namespace algorithm { // geos.algorithm

int RobustDeterminant::signOfDet2x2(double x1,double y1,double x2,double y2) {
	// returns -1 if the determinant is negative,
	// returns  1 if the determinant is positive,
	// retunrs  0 if the determinant is null.
	int sign=1;
	double swap;
	double k;
	long count=0;

  // Protect against non-finite numbers
  if ( ISNAN(x1)   || ISNAN(y1)   || ISNAN(x2)   || ISNAN(y2) ||
       !FINITE(x1) || !FINITE(y1) || !FINITE(x2) || !FINITE(y2) )
  {
    throw util::IllegalArgumentException("RobustDeterminant encountered non-finite numbers ");
  }

	/*
	*  testing null entries
	*/
	if ((x1==0.0) || (y2==0.0)) {
		if ((y1==0.0) || (x2==0.0)) {
			return 0;
		} else if (y1>0) {
			if (x2>0) {
				return -sign;
			} else {
				return sign;
			}
		} else {
			if (x2>0) {
				return sign;
			} else {
				return -sign;
			}
		}
	}
	if ((y1==0.0) || (x2==0.0)) {
		if (y2>0) {
			if (x1>0) {
				return sign;
			} else {
				return -sign;
			}
		} else {
			if (x1>0) {
				return -sign;
			} else {
				return sign;
			}
		}
	}

	/*
	*  making y coordinates positive and permuting the entries
	*  so that y2 is the biggest one
	*/
	if (0.0<y1) {
		if (0.0<y2) {
			if (y1<=y2) {
				;
			} else {
				sign=-sign;
				swap=x1;
				x1=x2;
				x2=swap;
				swap=y1;
				y1=y2;
				y2=swap;
			}
		} else {
			if (y1<=-y2) {
				sign=-sign;
				x2=-x2;
				y2=-y2;
			} else {
				swap=x1;
				x1=-x2;
				x2=swap;
				swap=y1;
				y1=-y2;
				y2=swap;
			}
		}
	} else {
		if (0.0<y2) {
			if (-y1<=y2) {
				sign=-sign;
				x1=-x1;
				y1=-y1;
			} else {
				swap=-x1;
				x1=x2;
				x2=swap;
				swap=-y1;
				y1=y2;
				y2=swap;
			}
		} else {
			if (y1>=y2) {
				x1=-x1;
				y1=-y1;
				x2=-x2;
				y2=-y2;
			} else {
				sign=-sign;
				swap=-x1;
				x1=-x2;
				x2=swap;
				swap=-y1;
				y1=-y2;
				y2=swap;
			}
		}
	}

	/*
	*  making x coordinates positive
	*/
	/*
	*  if |x2|<|x1| one can conclude
	*/
	if (0.0<x1) {
		if (0.0<x2) {
			if (x1 <= x2) {
				;
			} else {
				return sign;
			}
		} else {
			return sign;
		}
	} else {
		if (0.0<x2) {
			return -sign;
		} else {
			if (x1 >= x2) {
				sign=-sign;
				x1=-x1;
				x2=-x2;
			} else {
				return -sign;
			}
		}
	}

	/*
	*  all entries strictly positive   x1 <= x2 and y1 <= y2
	*/
	while (true) {
		count=count+1;
		k=std::floor(x2/x1);
		x2=x2-k*x1;
		y2=y2-k*y1;

		/*
		*  testing if R (new U2) is in U1 rectangle
		*/
		if (y2<0.0) {
			return -sign;
		}
		if (y2>y1) {
			return sign;
		}

		/*
		*  finding R'
		*/
		if (x1>x2+x2) {
			if (y1<y2+y2) {
				return sign;
			}
		} else {
			if (y1>y2+y2) {
				return -sign;
			} else {
				x2=x1-x2;
				y2=y1-y2;
				sign=-sign;
			}
		}
		if (y2==0.0) {
			if (x2==0.0) {
				return 0;
			} else {
				return -sign;
			}
		}
		if (x2==0.0) {
			return sign;
		}

		/*
		*  exchange 1 and 2 role.
		*/
		k=std::floor(x1/x2);
		x1=x1-k*x2;
		y1=y1-k*y2;

		/*
		*  testing if R (new U1) is in U2 rectangle
		*/
		if (y1<0.0) {
			return sign;
		}
		if (y1>y2) {
			return -sign;
		}

		/*
		*  finding R'
		*/
		if (x2>x1+x1) {
			if (y2<y1+y1) {
				return -sign;
			}
		} else {
			if (y2>y1+y1) {
				return sign;
			} else {
				x1=x2-x1;
				y1=y2-y1;
				sign=-sign;
			}
		}
		if (y1==0.0) {
			if (x1==0.0) {
				return 0;
			} else {
				return sign;
			}
		}
		if (x1==0.0) {
			return -sign;
		}
	}
}
} // namespace geos.algorithm
} // namespace geos

/**********************************************************************
 * $Log$
 * Revision 1.10  2006/03/21 11:12:23  strk
 * Cleanups: headers inclusion and Log section
 *
 * Revision 1.9  2006/03/21 10:46:03  strk
 * streamlined header inclusion, put original copyright on top
 *
 * Revision 1.8  2006/02/19 19:46:49  strk
 * Packages <-> namespaces mapping for most GEOS internal code (uncomplete, but working). Dir-level libs for index/ subdirs.
 *
 **********************************************************************/

<commit_msg>Drop unused variable<commit_after>/**********************************************************************
 * $Id$
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.refractions.net
 *
 * Copyright (c) Olivier Devillers <Olivier.Devillers@sophia.inria.fr>
 * Copyright (C) 2006 Refractions Research Inc.
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Public Licence as published
 * by the Free Software Foundation.
 * See the COPYING file for more information.
 *
 **********************************************************************
 *
 * Last port: algorithm/RobustDeterminant.java 1.15 (JTS-1.10)
 *
 **********************************************************************/

#include <geos/algorithm/RobustDeterminant.h>
#include <geos/util/IllegalArgumentException.h>

#include <cmath>

#include <geos/platform.h> // for ISNAN, FINITE

#ifdef _MSC_VER
#pragma warning(disable : 4127)
#endif

using namespace std; // for isfinite..

namespace geos {
namespace algorithm { // geos.algorithm

int RobustDeterminant::signOfDet2x2(double x1,double y1,double x2,double y2) {
	// returns -1 if the determinant is negative,
	// returns  1 if the determinant is positive,
	// retunrs  0 if the determinant is null.
	int sign=1;
	double swap;
	double k;

  // Protect against non-finite numbers
  if ( ISNAN(x1)   || ISNAN(y1)   || ISNAN(x2)   || ISNAN(y2) ||
       !FINITE(x1) || !FINITE(y1) || !FINITE(x2) || !FINITE(y2) )
  {
    throw util::IllegalArgumentException("RobustDeterminant encountered non-finite numbers ");
  }

	/*
	*  testing null entries
	*/
	if ((x1==0.0) || (y2==0.0)) {
		if ((y1==0.0) || (x2==0.0)) {
			return 0;
		} else if (y1>0) {
			if (x2>0) {
				return -sign;
			} else {
				return sign;
			}
		} else {
			if (x2>0) {
				return sign;
			} else {
				return -sign;
			}
		}
	}
	if ((y1==0.0) || (x2==0.0)) {
		if (y2>0) {
			if (x1>0) {
				return sign;
			} else {
				return -sign;
			}
		} else {
			if (x1>0) {
				return -sign;
			} else {
				return sign;
			}
		}
	}

	/*
	*  making y coordinates positive and permuting the entries
	*  so that y2 is the biggest one
	*/
	if (0.0<y1) {
		if (0.0<y2) {
			if (y1<=y2) {
				;
			} else {
				sign=-sign;
				swap=x1;
				x1=x2;
				x2=swap;
				swap=y1;
				y1=y2;
				y2=swap;
			}
		} else {
			if (y1<=-y2) {
				sign=-sign;
				x2=-x2;
				y2=-y2;
			} else {
				swap=x1;
				x1=-x2;
				x2=swap;
				swap=y1;
				y1=-y2;
				y2=swap;
			}
		}
	} else {
		if (0.0<y2) {
			if (-y1<=y2) {
				sign=-sign;
				x1=-x1;
				y1=-y1;
			} else {
				swap=-x1;
				x1=x2;
				x2=swap;
				swap=-y1;
				y1=y2;
				y2=swap;
			}
		} else {
			if (y1>=y2) {
				x1=-x1;
				y1=-y1;
				x2=-x2;
				y2=-y2;
			} else {
				sign=-sign;
				swap=-x1;
				x1=-x2;
				x2=swap;
				swap=-y1;
				y1=-y2;
				y2=swap;
			}
		}
	}

	/*
	*  making x coordinates positive
	*/
	/*
	*  if |x2|<|x1| one can conclude
	*/
	if (0.0<x1) {
		if (0.0<x2) {
			if (x1 <= x2) {
				;
			} else {
				return sign;
			}
		} else {
			return sign;
		}
	} else {
		if (0.0<x2) {
			return -sign;
		} else {
			if (x1 >= x2) {
				sign=-sign;
				x1=-x1;
				x2=-x2;
			} else {
				return -sign;
			}
		}
	}

	/*
	*  all entries strictly positive   x1 <= x2 and y1 <= y2
	*/
	while (true) {
		k=std::floor(x2/x1);
		x2=x2-k*x1;
		y2=y2-k*y1;

		/*
		*  testing if R (new U2) is in U1 rectangle
		*/
		if (y2<0.0) {
			return -sign;
		}
		if (y2>y1) {
			return sign;
		}

		/*
		*  finding R'
		*/
		if (x1>x2+x2) {
			if (y1<y2+y2) {
				return sign;
			}
		} else {
			if (y1>y2+y2) {
				return -sign;
			} else {
				x2=x1-x2;
				y2=y1-y2;
				sign=-sign;
			}
		}
		if (y2==0.0) {
			if (x2==0.0) {
				return 0;
			} else {
				return -sign;
			}
		}
		if (x2==0.0) {
			return sign;
		}

		/*
		*  exchange 1 and 2 role.
		*/
		k=std::floor(x1/x2);
		x1=x1-k*x2;
		y1=y1-k*y2;

		/*
		*  testing if R (new U1) is in U2 rectangle
		*/
		if (y1<0.0) {
			return sign;
		}
		if (y1>y2) {
			return -sign;
		}

		/*
		*  finding R'
		*/
		if (x2>x1+x1) {
			if (y2<y1+y1) {
				return -sign;
			}
		} else {
			if (y2>y1+y1) {
				return sign;
			} else {
				x1=x2-x1;
				y1=y2-y1;
				sign=-sign;
			}
		}
		if (y1==0.0) {
			if (x1==0.0) {
				return 0;
			} else {
				return sign;
			}
		}
		if (x1==0.0) {
			return -sign;
		}
	}
}
} // namespace geos.algorithm
} // namespace geos

<|endoftext|>


<commit_before>/*
The MIT License (MIT)

Copyright (c) 2014 CantTouchDis

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

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

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

#include "./Image.h"
#include <cassert>
#include <fstream>
#include <vector>

using std::ofstream;
using std::vector;

// _____________________________________________________________________________
Image::Image(const int width, const int height)
  : _width(width), _height(height)
{
  // We need to be sure, that width and height are both > 0.
  assert(_width > 0);
  assert(_height > 0);
  // Resize the pixel vector and put only black pixels in it.
  _data.assign(_width * _height, Pixel());
}

// _____________________________________________________________________________
Image::~Image()
{
}

// _____________________________________________________________________________
void Image::saveAsBMP(const std::string& filePath) const
{
  // Open the stream.
  ofstream stream(filePath, std::ofstream::out);

  // Check if everything went well.
  if (!stream.good())
  {
    return;
  }

  // Code taken from
  // http://stackoverflow.com/questions/2654480/writing-bmp-image-in-pure-c-c-without-other-libraries.
  unsigned char file[14] = {
    'B', 'M',  // magic
    0, 0, 0, 0,  // size in bytes
    0, 0,  // app data
    0, 0,  // app data
    40 + 14, 0, 0, 0  // start of data offset
  };
  unsigned char info[40] = {
    40, 0, 0, 0,  // info hd size
    0, 0, 0, 0,  // width
    0, 0, 0, 0,  // heigth
    1, 0,  // number color planes
    24, 0,  // bits per pixel
    0, 0, 0, 0,  // compression is none
    0, 0, 0, 0,  // image bits size
    0x13, 0x0B, 0, 0,  // horz resoluition in pixel / m
    0x13, 0x0B, 0, 0,  // vert resolutions (0x03C3 = 96 dpi, 0x0B13 = 72 dpi)
    0, 0, 0, 0,  // #colors in pallete
    0, 0, 0, 0,  // #important colors
  };

  int w = _width;
  int h = _height;

  int padSize  = (4 - w % 4) % 4;
  int sizeData = w * h * 3 + h * padSize;
  int sizeAll  = sizeData + sizeof(file) + sizeof(info);

  file[2] = (unsigned char)(sizeAll);
  file[3] = (unsigned char)(sizeAll >> 8);
  file[4] = (unsigned char)(sizeAll >> 16);
  file[5] = (unsigned char)(sizeAll >> 24);

  info[4] = (unsigned char)(w);
  info[5] = (unsigned char)(w >> 8);
  info[6] = (unsigned char)(w >> 16);
  info[7] = (unsigned char)(w >> 24);

  info[8] = (unsigned char)(h);
  info[9] = (unsigned char)(h >> 8);
  info[10] = (unsigned char)(h >> 16);
  info[11] = (unsigned char)(h >> 24);

  info[24] = (unsigned char)(sizeData);
  info[25] = (unsigned char)(sizeData >> 8);
  info[26] = (unsigned char)(sizeData >> 16);
  info[27] = (unsigned char)(sizeData >> 24);

  stream.write((char*)file, sizeof(file));
  stream.write((char*)info, sizeof(info));

  unsigned char pad[3] = {0, 0, 0};

  for (int y = 0; y < h; ++y)
  {
      for (int x = 0; x < w; ++x)
      {
          const Pixel& tmpPixel = getPixel(x, y);
          unsigned char pixel[3];
          pixel[0] = tmpPixel.r;
          pixel[1] = tmpPixel.g;
          pixel[2] = tmpPixel.b;

          stream.write((char*)pixel, 3);
      }
      stream.write((char*)pad, padSize);
  }
  stream.close();
}

// _____________________________________________________________________________
Pixel* Image::operator()(const int x, const int y)
{
  return &(_data[x + _width * y]);
}

// _____________________________________________________________________________
const Pixel& Image::getPixel(const int x, const int y) const
{
  return _data.at(x + _width * y);
}<commit_msg>Fixed some linting stuff.<commit_after>/*
The MIT License (MIT)

Copyright (c) 2014 CantTouchDis

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

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

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

#include "./Image.h"
#include <cassert>
#include <fstream>
#include <vector>

using std::ofstream;
using std::vector;

// _____________________________________________________________________________
Image::Image(const int width, const int height)
  : _width(width), _height(height) {
  // We need to be sure, that width and height are both > 0.
  assert(_width > 0);
  assert(_height > 0);
  // Resize the pixel vector and put only black pixels in it.
  _data.assign(_width * _height, Pixel());
}

// _____________________________________________________________________________
Image::~Image() {
}

// _____________________________________________________________________________
void Image::saveAsBMP(const std::string& filePath) const {
  // Open the stream.
  ofstream stream(filePath, std::ofstream::out);

  // Check if everything went well.
  if (!stream.good())
  {
    return;
  }

  // Code taken from
  // http://stackoverflow.com/questions/2654480/writing-bmp-image-in-pure-c-c-without-other-libraries.
  unsigned char file[14] = {
    'B', 'M',  // magic
    0, 0, 0, 0,  // size in bytes
    0, 0,  // app data
    0, 0,  // app data
    40 + 14, 0, 0, 0  // start of data offset
  };
  unsigned char info[40] = {
    40, 0, 0, 0,  // info hd size
    0, 0, 0, 0,  // width
    0, 0, 0, 0,  // heigth
    1, 0,  // number color planes
    24, 0,  // bits per pixel
    0, 0, 0, 0,  // compression is none
    0, 0, 0, 0,  // image bits size
    0x13, 0x0B, 0, 0,  // horz resoluition in pixel / m
    0x13, 0x0B, 0, 0,  // vert resolutions (0x03C3 = 96 dpi, 0x0B13 = 72 dpi)
    0, 0, 0, 0,  // #colors in pallete
    0, 0, 0, 0,  // #important colors
  };

  int w = _width;
  int h = _height;

  int padSize  = (4 - w % 4) % 4;
  int sizeData = w * h * 3 + h * padSize;
  int sizeAll  = sizeData + sizeof(file) + sizeof(info);

  file[2] = (unsigned char)(sizeAll);
  file[3] = (unsigned char)(sizeAll >> 8);
  file[4] = (unsigned char)(sizeAll >> 16);
  file[5] = (unsigned char)(sizeAll >> 24);

  info[4] = (unsigned char)(w);
  info[5] = (unsigned char)(w >> 8);
  info[6] = (unsigned char)(w >> 16);
  info[7] = (unsigned char)(w >> 24);

  info[8] = (unsigned char)(h);
  info[9] = (unsigned char)(h >> 8);
  info[10] = (unsigned char)(h >> 16);
  info[11] = (unsigned char)(h >> 24);

  info[24] = (unsigned char)(sizeData);
  info[25] = (unsigned char)(sizeData >> 8);
  info[26] = (unsigned char)(sizeData >> 16);
  info[27] = (unsigned char)(sizeData >> 24);

  stream.write((char*)file, sizeof(file));
  stream.write((char*)info, sizeof(info));

  unsigned char pad[3] = {0, 0, 0};

  for (int y = 0; y < h; ++y)
  {
      for (int x = 0; x < w; ++x)
      {
          const Pixel& tmpPixel = getPixel(x, y);
          unsigned char pixel[3];
          pixel[0] = tmpPixel.r;
          pixel[1] = tmpPixel.g;
          pixel[2] = tmpPixel.b;

          stream.write((char*)pixel, 3);
      }
      stream.write(reinterpret_cast<char*>(pad), padSize);
  }
  stream.close();
}

// _____________________________________________________________________________
Pixel* Image::operator()(const int x, const int y) {
  return &(_data[x + _width * y]);
}

// _____________________________________________________________________________
const Pixel& Image::getPixel(const int x, const int y) const {
  return _data.at(x + _width * y);
}
<|endoftext|>


<commit_before>/*
   (c) Copyright 2001-2011  The world wide DirectFB Open Source Community (directfb.org)
   (c) Copyright 2000-2004  Convergence (integrated media) GmbH

   All rights reserved.

   Written by Denis Oliver Kropp <dok@directfb.org>,
              Andreas Hundt <andi@fischlustig.de>,
              Sven Neumann <neo@directfb.org>,
              Ville Syrjälä <syrjala@sci.fi> and
              Claudio Ciccani <klan@users.sf.net>.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the
   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
*/

#include <config.h>

#include "SaWManManager.h"
#include "SaWManProcess.h"

extern "C" {
#include <directfb_util.h>

#include <direct/debug.h>
#include <direct/mem.h>
#include <direct/memcpy.h>
#include <direct/messages.h>

#include <fusion/conf.h>

#include <core/core.h>
}

D_DEBUG_DOMAIN( DirectFB_SaWManProcess, "DirectFB/SaWManProcess", "DirectFB SaWManProcess" );

/*********************************************************************************************************************/

namespace DirectFB {

DFBResult
ISaWManProcess_Real::SetExiting(
)
{
     D_DEBUG_AT( DirectFB_SaWManProcess, "%s()", __FUNCTION__ );

     /* Set 'cleanly exiting' flag. */
     obj->flags = (SaWManProcessFlags)(obj->flags | SWMPF_EXITING);

     return DFB_OK;
}

DFBResult
ISaWManProcess_Real::RegisterManager(
                    const SaWManRegisterManagerData           *data,
                    SaWManManager                            **ret_manager
)
{
     D_DEBUG_AT( DirectFB_SaWManProcess, "%s()", __FUNCTION__ );

     sawman_lock( m_sawman );

     if (m_sawman->manager.present) {
          sawman_unlock( m_sawman );
          return DFB_BUSY;
     }

     /* Initialize manager data. */
     m_sawman->manager.call      = data->call;
     m_sawman->manager.callbacks = data->callbacks;
     m_sawman->manager.context   = data->context;

     /* Set manager flag for our process. */
     obj->flags = (SaWManProcessFlags)(obj->flags | SWMPF_MANAGER);

     m_sawman->manager.present = true;

     SaWManManager_Init_Dispatch( core, &m_sawman->manager, &m_sawman->manager.call_from );

     sawman_unlock( m_sawman );

     *ret_manager = &m_sawman->manager;

     return DFB_OK;
}

}

<commit_msg>debug: add missing newline<commit_after>/*
   (c) Copyright 2001-2011  The world wide DirectFB Open Source Community (directfb.org)
   (c) Copyright 2000-2004  Convergence (integrated media) GmbH

   All rights reserved.

   Written by Denis Oliver Kropp <dok@directfb.org>,
              Andreas Hundt <andi@fischlustig.de>,
              Sven Neumann <neo@directfb.org>,
              Ville Syrjälä <syrjala@sci.fi> and
              Claudio Ciccani <klan@users.sf.net>.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the
   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
*/

#include <config.h>

#include "SaWManManager.h"
#include "SaWManProcess.h"

extern "C" {
#include <directfb_util.h>

#include <direct/debug.h>
#include <direct/mem.h>
#include <direct/memcpy.h>
#include <direct/messages.h>

#include <fusion/conf.h>

#include <core/core.h>
}

D_DEBUG_DOMAIN( DirectFB_SaWManProcess, "DirectFB/SaWManProcess", "DirectFB SaWManProcess" );

/*********************************************************************************************************************/

namespace DirectFB {

DFBResult
ISaWManProcess_Real::SetExiting(
)
{
     D_DEBUG_AT( DirectFB_SaWManProcess, "%s()\n", __FUNCTION__ );

     /* Set 'cleanly exiting' flag. */
     obj->flags = (SaWManProcessFlags)(obj->flags | SWMPF_EXITING);

     return DFB_OK;
}

DFBResult
ISaWManProcess_Real::RegisterManager(
                    const SaWManRegisterManagerData           *data,
                    SaWManManager                            **ret_manager
)
{
     D_DEBUG_AT( DirectFB_SaWManProcess, "%s()\n", __FUNCTION__ );

     sawman_lock( m_sawman );

     if (m_sawman->manager.present) {
          sawman_unlock( m_sawman );
          return DFB_BUSY;
     }

     /* Initialize manager data. */
     m_sawman->manager.call      = data->call;
     m_sawman->manager.callbacks = data->callbacks;
     m_sawman->manager.context   = data->context;

     /* Set manager flag for our process. */
     obj->flags = (SaWManProcessFlags)(obj->flags | SWMPF_MANAGER);

     m_sawman->manager.present = true;

     SaWManManager_Init_Dispatch( core, &m_sawman->manager, &m_sawman->manager.call_from );

     sawman_unlock( m_sawman );

     *ret_manager = &m_sawman->manager;

     return DFB_OK;
}

}

<|endoftext|>


<commit_before>//===-- Analysis/Writer.cpp - Printing routines for analyses -----*- C++ -*--=//
//
// This library file implements analysis result printing support for
// llvm/Analysis/Writer.h
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/Writer.h"
#include "llvm/Analysis/IntervalPartition.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/InductionVariable.h"
#include "llvm/Assembly/Writer.h"
#include <iterator>
#include <algorithm>
#include <string>
#include <iostream>
using std::ostream;
using std::set;
using std::vector;
using std::string;

//===----------------------------------------------------------------------===//
//  Interval Printing Routines
//===----------------------------------------------------------------------===//

void WriteToOutput(const Interval *I, ostream &o) {
  o << "-------------------------------------------------------------\n"
       << "Interval Contents:\n";

  // Print out all of the basic blocks in the interval...
  copy(I->Nodes.begin(), I->Nodes.end(),
       std::ostream_iterator<BasicBlock*>(o, "\n"));

  o << "Interval Predecessors:\n";
  copy(I->Predecessors.begin(), I->Predecessors.end(),
       std::ostream_iterator<BasicBlock*>(o, "\n"));

  o << "Interval Successors:\n";
  copy(I->Successors.begin(), I->Successors.end(),
       std::ostream_iterator<BasicBlock*>(o, "\n"));
}

void WriteToOutput(const IntervalPartition &IP, ostream &o) {
  copy(IP.begin(), IP.end(), std::ostream_iterator<const Interval *>(o, "\n"));
}

//===----------------------------------------------------------------------===//
//  Dominator Printing Routines
//===----------------------------------------------------------------------===//

ostream &operator<<(ostream &o, const set<BasicBlock*> &BBs) {
  for (set<BasicBlock*>::const_iterator I = BBs.begin(), E = BBs.end();
       I != E; ++I) {
    o << "  ";
    WriteAsOperand(o, (Value*)*I, false);
    o << "\n";
   }
  return o;
}

void WriteToOutput(const DominatorSet &DS, ostream &o) {
  for (DominatorSet::const_iterator I = DS.begin(), E = DS.end(); I != E; ++I) {
    o << "=============================--------------------------------\n"
      << "\nDominator Set For Basic Block\n" << I->first
      << "-------------------------------\n" << I->second << "\n";
  }
}

void WriteToOutput(const ImmediateDominators &ID, ostream &o) {
  for (ImmediateDominators::const_iterator I = ID.begin(), E = ID.end();
       I != E; ++I) {
    o << "=============================--------------------------------\n"
      << "\nImmediate Dominator For Basic Block\n" << I->first
      << "is: \n" << I->second << "\n";
  }
}

static ostream &operator<<(ostream &o, const DominatorTree::Node *Node) {
  return o << Node->getNode() << "\n------------------------------------------\n";

}

static void PrintDomTree(const DominatorTree::Node *N, ostream &o,
                         unsigned Lev) {
  o << "Level #" << Lev << ":  " << N;
  for (DominatorTree::Node::const_iterator I = N->begin(), E = N->end();
       I != E; ++I) {
    PrintDomTree(*I, o, Lev+1);
  }
}

void WriteToOutput(const DominatorTree &DT, ostream &o) {
  o << "=============================--------------------------------\n"
    << "Inorder Dominator Tree:\n";
  PrintDomTree(DT[DT.getRoot()], o, 1);
}

void WriteToOutput(const DominanceFrontier &DF, ostream &o) {
  for (DominanceFrontier::const_iterator I = DF.begin(), E = DF.end();
       I != E; ++I) {
    o << "=============================--------------------------------\n"
      << "\nDominance Frontier For Basic Block\n";
    WriteAsOperand(o, (Value*)I->first, false);
    o << " is: \n" << I->second << "\n";
  }
}

//===----------------------------------------------------------------------===//
//  Loop Printing Routines
//===----------------------------------------------------------------------===//

void WriteToOutput(const Loop *L, ostream &o) {
  o << string(L->getLoopDepth()*2, ' ') << "Loop Containing: ";

  for (unsigned i = 0; i < L->getBlocks().size(); ++i) {
    if (i) o << ",";
    WriteAsOperand(o, (const Value*)L->getBlocks()[i]);
  }
  o << "\n";

  copy(L->getSubLoops().begin(), L->getSubLoops().end(),
       std::ostream_iterator<const Loop*>(o, "\n"));
}

void WriteToOutput(const LoopInfo &LI, ostream &o) {
  copy(LI.getTopLevelLoops().begin(), LI.getTopLevelLoops().end(),
       std::ostream_iterator<const Loop*>(o, "\n"));
}

//===----------------------------------------------------------------------===//
//  Induction Variable Printing Routines
//===----------------------------------------------------------------------===//

void WriteToOutput(const InductionVariable &IV, ostream &o) {
  switch (IV.InductionType) {
  case InductionVariable::Cannonical:   o << "Cannonical ";   break;
  case InductionVariable::SimpleLinear: o << "SimpleLinear "; break;
  case InductionVariable::Linear:       o << "Linear ";       break;
  case InductionVariable::Unknown:      o << "Unrecognized "; break;
  }
  o << "Induction Variable";
  if (IV.Phi) {
    WriteAsOperand(o, (const Value*)IV.Phi);
    o << ":\n" << (const Value*)IV.Phi;
  } else {
    o << "\n";
  }
  if (IV.InductionType == InductionVariable::Unknown) return;

  o << "  Start ="; WriteAsOperand(o, IV.Start);
  o << "  Step =" ; WriteAsOperand(o, IV.Step);
  o << "\n";
}
<commit_msg>Print the contents, not the pointer...<commit_after>//===-- Analysis/Writer.cpp - Printing routines for analyses -----*- C++ -*--=//
//
// This library file implements analysis result printing support for
// llvm/Analysis/Writer.h
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/Writer.h"
#include "llvm/Analysis/IntervalPartition.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/InductionVariable.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/Module.h"
#include <iterator>
#include <algorithm>
#include <string>
#include <iostream>
using std::ostream;
using std::set;
using std::vector;
using std::string;

//===----------------------------------------------------------------------===//
//  Interval Printing Routines
//===----------------------------------------------------------------------===//

void WriteToOutput(const Interval *I, ostream &o) {
  o << "-------------------------------------------------------------\n"
       << "Interval Contents:\n";

  // Print out all of the basic blocks in the interval...
  copy(I->Nodes.begin(), I->Nodes.end(),
       std::ostream_iterator<BasicBlock*>(o, "\n"));

  o << "Interval Predecessors:\n";
  copy(I->Predecessors.begin(), I->Predecessors.end(),
       std::ostream_iterator<BasicBlock*>(o, "\n"));

  o << "Interval Successors:\n";
  copy(I->Successors.begin(), I->Successors.end(),
       std::ostream_iterator<BasicBlock*>(o, "\n"));
}

void WriteToOutput(const IntervalPartition &IP, ostream &o) {
  copy(IP.begin(), IP.end(), std::ostream_iterator<const Interval *>(o, "\n"));
}

//===----------------------------------------------------------------------===//
//  Dominator Printing Routines
//===----------------------------------------------------------------------===//

ostream &operator<<(ostream &o, const set<BasicBlock*> &BBs) {
  for (set<BasicBlock*>::const_iterator I = BBs.begin(), E = BBs.end();
       I != E; ++I) {
    o << "  ";
    WriteAsOperand(o, (Value*)*I, false);
    o << "\n";
   }
  return o;
}

void WriteToOutput(const DominatorSet &DS, ostream &o) {
  for (DominatorSet::const_iterator I = DS.begin(), E = DS.end(); I != E; ++I) {
    o << "=============================--------------------------------\n"
      << "\nDominator Set For Basic Block\n" << I->first
      << "-------------------------------\n" << I->second << "\n";
  }
}

void WriteToOutput(const ImmediateDominators &ID, ostream &o) {
  for (ImmediateDominators::const_iterator I = ID.begin(), E = ID.end();
       I != E; ++I) {
    o << "=============================--------------------------------\n"
      << "\nImmediate Dominator For Basic Block\n" << *I->first
      << "is: \n" << *I->second << "\n";
  }
}

static ostream &operator<<(ostream &o, const DominatorTree::Node *Node) {
  return o << Node->getNode() << "\n------------------------------------------\n";

}

static void PrintDomTree(const DominatorTree::Node *N, ostream &o,
                         unsigned Lev) {
  o << "Level #" << Lev << ":  " << N;
  for (DominatorTree::Node::const_iterator I = N->begin(), E = N->end();
       I != E; ++I) {
    PrintDomTree(*I, o, Lev+1);
  }
}

void WriteToOutput(const DominatorTree &DT, ostream &o) {
  o << "=============================--------------------------------\n"
    << "Inorder Dominator Tree:\n";
  PrintDomTree(DT[DT.getRoot()], o, 1);
}

void WriteToOutput(const DominanceFrontier &DF, ostream &o) {
  for (DominanceFrontier::const_iterator I = DF.begin(), E = DF.end();
       I != E; ++I) {
    o << "=============================--------------------------------\n"
      << "\nDominance Frontier For Basic Block\n";
    WriteAsOperand(o, (Value*)I->first, false);
    o << " is: \n" << I->second << "\n";
  }
}

//===----------------------------------------------------------------------===//
//  Loop Printing Routines
//===----------------------------------------------------------------------===//

void WriteToOutput(const Loop *L, ostream &o) {
  o << string(L->getLoopDepth()*2, ' ') << "Loop Containing: ";

  for (unsigned i = 0; i < L->getBlocks().size(); ++i) {
    if (i) o << ",";
    WriteAsOperand(o, (const Value*)L->getBlocks()[i]);
  }
  o << "\n";

  copy(L->getSubLoops().begin(), L->getSubLoops().end(),
       std::ostream_iterator<const Loop*>(o, "\n"));
}

void WriteToOutput(const LoopInfo &LI, ostream &o) {
  copy(LI.getTopLevelLoops().begin(), LI.getTopLevelLoops().end(),
       std::ostream_iterator<const Loop*>(o, "\n"));
}

//===----------------------------------------------------------------------===//
//  Induction Variable Printing Routines
//===----------------------------------------------------------------------===//

void WriteToOutput(const InductionVariable &IV, ostream &o) {
  switch (IV.InductionType) {
  case InductionVariable::Cannonical:   o << "Cannonical ";   break;
  case InductionVariable::SimpleLinear: o << "SimpleLinear "; break;
  case InductionVariable::Linear:       o << "Linear ";       break;
  case InductionVariable::Unknown:      o << "Unrecognized "; break;
  }
  o << "Induction Variable";
  if (IV.Phi) {
    WriteAsOperand(o, (const Value*)IV.Phi);
    o << ":\n" << (const Value*)IV.Phi;
  } else {
    o << "\n";
  }
  if (IV.InductionType == InductionVariable::Unknown) return;

  o << "  Start ="; WriteAsOperand(o, IV.Start);
  o << "  Step =" ; WriteAsOperand(o, IV.Step);
  o << "\n";
}
<|endoftext|>


<commit_before>/*
===========================================================================
Daemon BSD Source Code
Copyright (c) 2013-2016, Daemon Developers
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 Daemon developers 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 DAEMON DEVELOPERS 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 "Common.h"

#include "../engine/qcommon/q_unicode.h"

namespace Color {

static Color g_color_table[ 32 ] =
{
	{ 0.20f, 0.20f, 0.20f, 1.00f }, // 0 - black    0
	{ 1.00f, 0.00f, 0.00f, 1.00f }, // 1 - red      1
	{ 0.00f, 1.00f, 0.00f, 1.00f }, // 2 - green    2
	{ 1.00f, 1.00f, 0.00f, 1.00f }, // 3 - yellow   3
	{ 0.00f, 0.00f, 1.00f, 1.00f }, // 4 - blue     4
	{ 0.00f, 1.00f, 1.00f, 1.00f }, // 5 - cyan     5
	{ 1.00f, 0.00f, 1.00f, 1.00f }, // 6 - purple   6
	{ 1.00f, 1.00f, 1.00f, 1.00f }, // 7 - white    7
	{ 1.00f, 0.50f, 0.00f, 1.00f }, // 8 - orange   8
	{ 0.50f, 0.50f, 0.50f, 1.00f }, // 9 - md.grey    9
	{ 0.75f, 0.75f, 0.75f, 1.00f }, // : - lt.grey    10    // lt grey for names
	{ 0.75f, 0.75f, 0.75f, 1.00f }, // ; - lt.grey    11
	{ 0.00f, 0.50f, 0.00f, 1.00f }, // < - md.green   12
	{ 0.50f, 0.50f, 0.00f, 1.00f }, // = - md.yellow  13
	{ 0.00f, 0.00f, 0.50f, 1.00f }, // > - md.blue    14
	{ 0.50f, 0.00f, 0.00f, 1.00f }, // ? - md.red   15
	{ 0.50f, 0.25f, 0.00f, 1.00f }, // @ - md.orange  16
	{ 1.00f, 0.60f, 0.10f, 1.00f }, // A - lt.orange  17
	{ 0.00f, 0.50f, 0.50f, 1.00f }, // B - md.cyan    18
	{ 0.50f, 0.00f, 0.50f, 1.00f }, // C - md.purple  19
	{ 0.00f, 0.50f, 1.00f, 1.00f }, // D        20
	{ 0.50f, 0.00f, 1.00f, 1.00f }, // E        21
	{ 0.20f, 0.60f, 0.80f, 1.00f }, // F        22
	{ 0.80f, 1.00f, 0.80f, 1.00f }, // G        23
	{ 0.00f, 0.40f, 0.20f, 1.00f }, // H        24
	{ 1.00f, 0.00f, 0.20f, 1.00f }, // I        25
	{ 0.70f, 0.10f, 0.10f, 1.00f }, // J        26
	{ 0.60f, 0.20f, 0.00f, 1.00f }, // K        27
	{ 0.80f, 0.60f, 0.20f, 1.00f }, // L        28
	{ 0.60f, 0.60f, 0.20f, 1.00f }, // M        29
	{ 1.00f, 1.00f, 0.75f, 1.00f }, // N        30
	{ 1.00f, 1.00f, 0.50f, 1.00f }, // O        31
};

int StrlenNocolor( const char *string )
{
	int len = 0;
	for ( const auto& token : Parser( string ) )
	{
		if ( token.Type() == Token::TokenType::CHARACTER || token.Type() == Token::TokenType::ESCAPE )
		{
			len++;
		}
	}

	return len;
}

char *StripColors( char *string )
{
	std::string output;

	for ( const auto& token : Parser( string ) )
	{
		if ( token.Type() == Token::TokenType::CHARACTER )
		{
			output.append( token.Begin(), token.Size() );
		}
		else if ( token.Type() == Token::TokenType::ESCAPE )
		{
			output.push_back(Constants::ESCAPE);
		}
	}

	strcpy( string, output.c_str() );

	return string;
}

void StripColors( const char *in, char *out, int len )
{
	--len;

	for ( const auto& token : Parser( in ) )
	{
		if ( token.Type() == Token::TokenType::CHARACTER )
		{
			if ( len < token.Size() )
			{
				break;
			}

			strncpy( out, token.Begin(), token.Size() );
			out += token.Size();
			len -= token.Size();
		}
		else if ( token.Type() == Token::TokenType::ESCAPE )
		{
			if ( len < 1 )
			{
				break;
			}
			*out++ = Constants::ESCAPE;
		}
	}

	*out = '\0';
}

std::string StripColors( const std::string& input )
{
	std::string output;

	for ( const auto& token : Parser( input.c_str() ) )
	{
		if ( token.Type() == Token::TokenType::CHARACTER )
		{
			output.append( token.Begin(), token.Size() );
		}
		else if ( token.Type() == Token::TokenType::ESCAPE )
		{
			output.push_back(Constants::ESCAPE);
		}
	}

	return output;
}

namespace detail {

const Color& Indexed( int index )
{
    if ( index < 0 )
        index *= -1;
    return g_color_table[index%32];
}

CONSTEXPR_FUNCTION bool Has8Bits( uint8_t v )
{
	return ( v / 0x11 * 0x11 ) != v;
}

/*
 * This is to be used when colors are needed to be printed in C-like code
 * Uses multiple character arrays to allow multiple calls
 * within the same sequence point
 */
const char* CString ( const Color32Bit& color )
{
	static const int length = 9;
	static const int nstrings = 4;
	static char text[nstrings][length];
	static int i = nstrings-1;

	i = ( i + 1 ) % nstrings;

	Color32Bit intcolor ( color );

	if ( Has8Bits( intcolor.Red() ) || Has8Bits( intcolor.Green() ) || Has8Bits( intcolor.Blue() ) )
	{
		sprintf(text[i], "^#%02x%02x%02x",
			(int)intcolor.Red(),
			(int)intcolor.Green(),
			(int)intcolor.Blue()
		);
	}
	else
	{
		sprintf(text[i], "^x%x%x%x",
			(int) ( intcolor.Red() & 0xf ) ,
			(int) ( intcolor.Green() & 0xf ),
			(int) ( intcolor.Blue() & 0xf )
		);
	}

	return text[i];

}

} // namespace detail

TokenIterator::value_type TokenIterator::NextToken(const char* input)
{
    if ( !input || *input == '\0' )
    {
        return value_type();
    }

    if ( input[0] == Constants::ESCAPE )
    {
        if ( input[1] == Constants::ESCAPE )
        {
            return value_type( input, input+2, value_type::TokenType::ESCAPE );
        }
        else if ( input[1] == Constants::NULL_COLOR )
        {
            return value_type( input, input+2, parent->DefaultColor() );
        }
        else if ( Str::ctoupper( input[1] ) >= '0' && Str::ctoupper( input[1] ) < 'P' )
        {
            return value_type( input, input+2, detail::Indexed( input[1] - '0' ) );
        }
        else if ( std::tolower( input[1] ) == 'x' && Str::cisxdigit( input[2] ) &&
                  Str::cisxdigit( input[3] ) && Str::cisxdigit( input[4] ) )
        {
            return value_type( input, input+5, Color(
                Str::GetHex( input[2] ) / 15.f,
                Str::GetHex( input[3] ) / 15.f,
                Str::GetHex( input[4] ) / 15.f,
                1
            ) );
        }
        else if ( input[1] == '#' )
        {
            bool long_hex = true;
            for ( int i = 0; i < 6; i++ )
            {
                if ( !Str::cisxdigit( input[i+2] ) )
                {
                    long_hex = false;
                    break;
                }
            }
            if ( long_hex )
            {
                return value_type( input, input+8, Color(
                    ( (Str::GetHex( input[2] ) << 4) | Str::GetHex( input[3] ) ) / 255.f,
                    ( (Str::GetHex( input[4] ) << 4) | Str::GetHex( input[5] ) ) / 255.f,
                    ( (Str::GetHex( input[6] ) << 4) | Str::GetHex( input[7] ) ) / 255.f,
                    1
                ) );
            }
        }
    }

    return value_type( input, input + Q_UTF8_Width( input ), value_type::TokenType::CHARACTER );
}

} // namespace Color
<commit_msg>Use Str::ctolower instead of std::tolower<commit_after>/*
===========================================================================
Daemon BSD Source Code
Copyright (c) 2013-2016, Daemon Developers
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 Daemon developers 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 DAEMON DEVELOPERS 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 "Common.h"

#include "../engine/qcommon/q_unicode.h"

namespace Color {

static Color g_color_table[ 32 ] =
{
	{ 0.20f, 0.20f, 0.20f, 1.00f }, // 0 - black    0
	{ 1.00f, 0.00f, 0.00f, 1.00f }, // 1 - red      1
	{ 0.00f, 1.00f, 0.00f, 1.00f }, // 2 - green    2
	{ 1.00f, 1.00f, 0.00f, 1.00f }, // 3 - yellow   3
	{ 0.00f, 0.00f, 1.00f, 1.00f }, // 4 - blue     4
	{ 0.00f, 1.00f, 1.00f, 1.00f }, // 5 - cyan     5
	{ 1.00f, 0.00f, 1.00f, 1.00f }, // 6 - purple   6
	{ 1.00f, 1.00f, 1.00f, 1.00f }, // 7 - white    7
	{ 1.00f, 0.50f, 0.00f, 1.00f }, // 8 - orange   8
	{ 0.50f, 0.50f, 0.50f, 1.00f }, // 9 - md.grey    9
	{ 0.75f, 0.75f, 0.75f, 1.00f }, // : - lt.grey    10    // lt grey for names
	{ 0.75f, 0.75f, 0.75f, 1.00f }, // ; - lt.grey    11
	{ 0.00f, 0.50f, 0.00f, 1.00f }, // < - md.green   12
	{ 0.50f, 0.50f, 0.00f, 1.00f }, // = - md.yellow  13
	{ 0.00f, 0.00f, 0.50f, 1.00f }, // > - md.blue    14
	{ 0.50f, 0.00f, 0.00f, 1.00f }, // ? - md.red   15
	{ 0.50f, 0.25f, 0.00f, 1.00f }, // @ - md.orange  16
	{ 1.00f, 0.60f, 0.10f, 1.00f }, // A - lt.orange  17
	{ 0.00f, 0.50f, 0.50f, 1.00f }, // B - md.cyan    18
	{ 0.50f, 0.00f, 0.50f, 1.00f }, // C - md.purple  19
	{ 0.00f, 0.50f, 1.00f, 1.00f }, // D        20
	{ 0.50f, 0.00f, 1.00f, 1.00f }, // E        21
	{ 0.20f, 0.60f, 0.80f, 1.00f }, // F        22
	{ 0.80f, 1.00f, 0.80f, 1.00f }, // G        23
	{ 0.00f, 0.40f, 0.20f, 1.00f }, // H        24
	{ 1.00f, 0.00f, 0.20f, 1.00f }, // I        25
	{ 0.70f, 0.10f, 0.10f, 1.00f }, // J        26
	{ 0.60f, 0.20f, 0.00f, 1.00f }, // K        27
	{ 0.80f, 0.60f, 0.20f, 1.00f }, // L        28
	{ 0.60f, 0.60f, 0.20f, 1.00f }, // M        29
	{ 1.00f, 1.00f, 0.75f, 1.00f }, // N        30
	{ 1.00f, 1.00f, 0.50f, 1.00f }, // O        31
};

int StrlenNocolor( const char *string )
{
	int len = 0;
	for ( const auto& token : Parser( string ) )
	{
		if ( token.Type() == Token::TokenType::CHARACTER || token.Type() == Token::TokenType::ESCAPE )
		{
			len++;
		}
	}

	return len;
}

char *StripColors( char *string )
{
	std::string output;

	for ( const auto& token : Parser( string ) )
	{
		if ( token.Type() == Token::TokenType::CHARACTER )
		{
			output.append( token.Begin(), token.Size() );
		}
		else if ( token.Type() == Token::TokenType::ESCAPE )
		{
			output.push_back(Constants::ESCAPE);
		}
	}

	strcpy( string, output.c_str() );

	return string;
}

void StripColors( const char *in, char *out, int len )
{
	--len;

	for ( const auto& token : Parser( in ) )
	{
		if ( token.Type() == Token::TokenType::CHARACTER )
		{
			if ( len < token.Size() )
			{
				break;
			}

			strncpy( out, token.Begin(), token.Size() );
			out += token.Size();
			len -= token.Size();
		}
		else if ( token.Type() == Token::TokenType::ESCAPE )
		{
			if ( len < 1 )
			{
				break;
			}
			*out++ = Constants::ESCAPE;
		}
	}

	*out = '\0';
}

std::string StripColors( const std::string& input )
{
	std::string output;

	for ( const auto& token : Parser( input.c_str() ) )
	{
		if ( token.Type() == Token::TokenType::CHARACTER )
		{
			output.append( token.Begin(), token.Size() );
		}
		else if ( token.Type() == Token::TokenType::ESCAPE )
		{
			output.push_back(Constants::ESCAPE);
		}
	}

	return output;
}

namespace detail {

const Color& Indexed( int index )
{
    if ( index < 0 )
        index *= -1;
    return g_color_table[index%32];
}

CONSTEXPR_FUNCTION bool Has8Bits( uint8_t v )
{
	return ( v / 0x11 * 0x11 ) != v;
}

/*
 * This is to be used when colors are needed to be printed in C-like code
 * Uses multiple character arrays to allow multiple calls
 * within the same sequence point
 */
const char* CString ( const Color32Bit& color )
{
	static const int length = 9;
	static const int nstrings = 4;
	static char text[nstrings][length];
	static int i = nstrings-1;

	i = ( i + 1 ) % nstrings;

	Color32Bit intcolor ( color );

	if ( Has8Bits( intcolor.Red() ) || Has8Bits( intcolor.Green() ) || Has8Bits( intcolor.Blue() ) )
	{
		sprintf(text[i], "^#%02x%02x%02x",
			(int)intcolor.Red(),
			(int)intcolor.Green(),
			(int)intcolor.Blue()
		);
	}
	else
	{
		sprintf(text[i], "^x%x%x%x",
			(int) ( intcolor.Red() & 0xf ) ,
			(int) ( intcolor.Green() & 0xf ),
			(int) ( intcolor.Blue() & 0xf )
		);
	}

	return text[i];

}

} // namespace detail

TokenIterator::value_type TokenIterator::NextToken(const char* input)
{
    if ( !input || *input == '\0' )
    {
        return value_type();
    }

    if ( input[0] == Constants::ESCAPE )
    {
        if ( input[1] == Constants::ESCAPE )
        {
            return value_type( input, input+2, value_type::TokenType::ESCAPE );
        }
        else if ( input[1] == Constants::NULL_COLOR )
        {
            return value_type( input, input+2, parent->DefaultColor() );
        }
        else if ( Str::ctoupper( input[1] ) >= '0' && Str::ctoupper( input[1] ) < 'P' )
        {
            return value_type( input, input+2, detail::Indexed( input[1] - '0' ) );
        }
        else if ( Str::ctolower( input[1] ) == 'x' && Str::cisxdigit( input[2] ) &&
                  Str::cisxdigit( input[3] ) && Str::cisxdigit( input[4] ) )
        {
            return value_type( input, input+5, Color(
                Str::GetHex( input[2] ) / 15.f,
                Str::GetHex( input[3] ) / 15.f,
                Str::GetHex( input[4] ) / 15.f,
                1
            ) );
        }
        else if ( input[1] == '#' )
        {
            bool long_hex = true;
            for ( int i = 0; i < 6; i++ )
            {
                if ( !Str::cisxdigit( input[i+2] ) )
                {
                    long_hex = false;
                    break;
                }
            }
            if ( long_hex )
            {
                return value_type( input, input+8, Color(
                    ( (Str::GetHex( input[2] ) << 4) | Str::GetHex( input[3] ) ) / 255.f,
                    ( (Str::GetHex( input[4] ) << 4) | Str::GetHex( input[5] ) ) / 255.f,
                    ( (Str::GetHex( input[6] ) << 4) | Str::GetHex( input[7] ) ) / 255.f,
                    1
                ) );
            }
        }
    }

    return value_type( input, input + Q_UTF8_Width( input ), value_type::TokenType::CHARACTER );
}

} // namespace Color
<|endoftext|>