<commit_before>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium team:
http://bohrium.bitbucket.org

Bohrium 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 3
of the License, or (at your option) any later version.

Bohrium 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 General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __BOHRIUM_BRIDGE_CPP
#define __BOHRIUM_BRIDGE_CPP

#define BH_CPP_QUEUE_MAX 1000

#include <stdexcept>
#include <complex>
#include <list>
#include <map>

#include <bh_component.hpp>
#include "iterator.hpp"

#ifdef DEBUG
#define DEBUG_PRINT(...) do{ fprintf( stderr, __VA_ARGS__ ); } while( false )
#else
#define DEBUG_PRINT(...) do{ } while ( false )
#endif

#define is_aligned(POINTER, BYTE_COUNT) \
    (((uintptr_t)(const void *)(POINTER)) % (BYTE_COUNT) == 0)

namespace bxx {

const double PI_D = 3.141592653589793238462;
const float  PI_F = 3.14159265358979f;
const float  PI   = 3.14159265358979f;

struct Export {
    enum Option {
        NONE        = 0x00,
        RELEASED    = 0x01,
        WO_ALLOC    = 0x02,
        WO_ZEROING  = 0x04
    };
};

template <typename T>   // Forward declaration
class multi_array;

inline int64_t unpack_shape(int64_t *shape, size_t index, size_t arg)
{
    shape[index] = arg;
    return 0;
}

template <typename ...Args>
int64_t unpack_shape(int64_t *shape, size_t index, size_t arg, Args... args)
{
    shape[index] = arg;
    unpack_shape(shape, ++index, args...);

    return 1;
}

inline int64_t nelements_shape(size_t arg)
{
    return arg;
}

template <typename ...Args>
int64_t nelements_shape(size_t arg, Args... args)
{
    return arg*nelements_shape(args...);
}

//
// Extensions
//

#ifndef END
#define END 0
#endif

enum scannable {
    SUM     = BH_ADD_ACCUMULATE,
    PRODUCT = BH_MULTIPLY_ACCUMULATE
};

//
// Slicing
//
class Slice {
public:
    Slice();
    Slice(int begin, int end, size_t step);

    int begin;
    int end;
    size_t step;
};

inline Slice::Slice() : begin(0), end(-1), step(1) {}

inline Slice::Slice(int begin, int end, size_t step)
    : begin(begin), end(end), step(step) {}

inline Slice _(int begin, int end, size_t step)
{
    return Slice(begin, end, step);
}

inline Slice _(int begin, int end)
{
    return _(begin, end, 1);
}

inline Slice _SI(int begin, int end, size_t step)
{
    return _(begin, end, step);
}

inline Slice _SI(int begin, int end)
{
    return _(begin, end, 1);
}

inline Slice _SE(int begin, int end, size_t step)
{
    return _(begin, end-1, step);
}

inline Slice _SE(int begin, int end)
{
    return _(begin, end-1, 1);
}

inline Slice _ALL(void)
{
    return _(0, -1, 1);
}

inline Slice _ABF(void)
{
    return _(1, -1, 1);
}

inline Slice _ABL(void)
{
    return _(0, -2, 1);
}

inline Slice _INNER(void)
{
    return _(1, -2, 1);
}

//
// The Abstraction
//
template <typename T>
class multi_array {
public:
    bh_view meta;

    // ** Constructors **
    multi_array();                              // Empty
    multi_array(const multi_array<T> &operand); // Copy
    multi_array(const uint64_t rank, const int64_t* shapes);
    multi_array(bh_base* base, uint64_t rank, const int64_t start, const int64_t* shape, const int64_t* stride);

    template <typename OtherT>
    multi_array(const multi_array<OtherT> &operand);    // Copy

    template <typename ...Dimensions>                   // Variadic constructor
    multi_array(Dimensions... dims);

    // ** Deconstructor **
    ~multi_array();

    // Types:
    typedef multi_array_iter<T> iterator;

    size_t len() const;
    int64_t shape(int64_t dim) const;             // Probe for the shape of the given dimension
    unsigned long getRank() const;

    // Iterator
    iterator begin();
    iterator end();

    //
    // Operators:
    //
    // =, [], (), -> must be "internal" (nonstatic member functions) and thus declared here.
    //
    // Definitions are provided in:
    //
    // - multi_array.hpp for those implemented by hand ([], ++, --, ostream<< ).
    // - operators.hpp: defined code-generator.
    //
                                                    // Slicing / explicit view
    multi_array<T>& operator[](int rhs);            // Select a single element / dimension
    multi_array<T>& operator[](Slice rhs);          // Select a range (begin, end, step)

    multi_array& operator()(const T& n);            // Update
    multi_array& operator()(multi_array<T>& rhs);

    //
    // Data movement
    //
    multi_array& operator()(const void* data);      // Update / copy from a void pointer

    T* data_export(void);
    void data_import(T* data);

    multi_array& operator=(const T& rhs);           // Initialization / assignment.
    multi_array& operator=(multi_array<T>& rhs);    // Initialization / assignment.

    template <typename In>
    multi_array<T>& operator=(multi_array<In>& rhs);// Initialization / assignment.

    multi_array& operator+=(const T& rhs);          // Compound assignment / increment
    multi_array& operator+=(multi_array& rhs);

    multi_array& operator-=(const T& rhs);
    multi_array& operator-=(multi_array& rhs);

    multi_array& operator*=(const T& rhs);
    multi_array& operator*=(multi_array& rhs);

    multi_array& operator/=(const T& rhs);
    multi_array& operator/=(multi_array &rhs);

    multi_array& operator%=(const T& rhs);
    multi_array& operator%=(multi_array &rhs);

    multi_array& operator>>=(const T& rhs);
    multi_array& operator>>=(multi_array& rhs);

    multi_array& operator<<=(const T& rhs);
    multi_array& operator<<=(multi_array& rhs);

    multi_array& operator&=(const T& rhs);
    multi_array& operator&=(multi_array& rhs);

    multi_array& operator^=(const T& rhs);
    multi_array& operator^=(multi_array& rhs);

    multi_array& operator|=(const T& rhs);
    multi_array& operator|=(multi_array& rhs);

    multi_array& operator++();              // Increment all elements in container
    multi_array& operator++(int);
    multi_array& operator--();              // Decrement all elements in container
    multi_array& operator--(int);

    void link();                            // Bohrium Runtime Specifics
    void link(bh_base* base);               // Bohrium Runtime Specifics
    bh_base* unlink();

    bh_base* getBase() const;

    void* getBaseData(void);                // These are NOT for the faint of heart!
    void setBaseData(void* data);           // These are only intended for the C-bridge.

    bool getTemp() const;
    void setTemp(bool temp);
    bool linked() const;
    bool initialized() const;               // Determine if the array is initialized (has a bh_base)
    bool allocated() const;                 // Determine if the array is intitialized and data for it is allocated
    void sync();

    int getSliceDim(void);
    void setSliceDim(int dim);

protected:
    bool temp_;
    int slicing_dim_;

private:
    void reset_meta();						// Helper, shared among constructors

    template <typename S>
    friend void swap(multi_array<S>& lhs, multi_array<S>& rhs);
};

template <typename T>
inline void swap(multi_array<T>& lhs, multi_array<T>& rhs) {
    using std::swap;
    swap(lhs.temp_, rhs.temp_);
    swap(lhs.slicing_dim_, rhs.slicing_dim_);
    swap(lhs.meta, rhs.meta);
}

template <typename TL, typename TR>
inline
bool identical(multi_array<TL>& left, multi_array<TR>& right)
{
    return static_cast<void*>(&left) == static_cast<void*>(&right);
}

/**
 *  Encapsulation of communication with Bohrium runtime.
 *  Implemented as a Singleton.
 *
 *  Note: Not thread-safe.
 */
class Runtime {
public:
    static Runtime& instance(); // Singleton method

    ~Runtime();         // Deconstructor

    //
    //  Lazy evaluation through instruction queue
    //
    template <typename TO, typename T1, typename T2, typename T3>
    void enqueue(bh_opcode opcode, multi_array<TO>& op0, multi_array<T1>& op1, multi_array<T2>& op2, multi_array<T3>& op3);

    template <typename TO, typename TL, typename TR>
    void enqueue(bh_opcode opcode, multi_array<TO>& op0, multi_array<TL>& op1, multi_array<TR>& op2);

    template <typename TO, typename TL, typename TR>
    void enqueue(bh_opcode opcode, multi_array<TO>& op0, multi_array<TL>& op1, const TR op2);

    template <typename TO, typename TL, typename TR>
    void enqueue(bh_opcode opcode, multi_array<TO>& op0, const TL op1, multi_array<TR>& op2);

    template <typename TO, typename TI>
    void enqueue(bh_opcode opcode, multi_array<TO>& op0, multi_array<TI>& op1);

    template <typename TO, typename TI>
    void enqueue(bh_opcode opcode, multi_array<TO>& op0, const TI op1);

    template <typename TO>
    void enqueue(bh_opcode opcode, multi_array<TO>& op0);

    void enqueue(bh_opcode opcode);

    template <typename TO>
    void enqueue(bh_opcode opcode, multi_array<TO>& op0, const uint64_t op1, const uint64_t op2);

    template <typename T1, typename T2, typename T3>
    void enqueue_extension(const std::string& name, multi_array<T1>& op0, multi_array<T2>& op2, multi_array<T3>& op3);

    size_t flush();
    size_t get_queue_size();

    //
    //  Typechecker
    //
    template <size_t Opcode, typename TO, typename T1, typename T2, typename T3>
    void typecheck(void);

    template <size_t Opcode, typename Out, typename In1, typename In2>
    void typecheck(void);

    template <size_t Opcode, typename Out, typename In1>
    void typecheck(void);

    template <size_t Opcode, typename Out>
    void typecheck(void);

    //
    //  Operand construction
    //

    template <typename T>
    multi_array<T>& create(void);

    /**
        Construct a new "linked" array, that it, it has an
        associated `bh_base`.
        Shape is inherited by `input`.
    **/
    template <typename T, typename OtherT>
    multi_array<T>& create_base(multi_array<OtherT>& input);

    template <typename T>
    multi_array<T>& temp();

    template <typename T, typename OtherT>
    multi_array<T>& temp(multi_array<OtherT>& input);

    template <typename T>
    multi_array<T>& view(multi_array<T>& base);

    template <typename T>
    multi_array<T>& temp_view(multi_array<T>& base);

    void trash(bh_base* base);

    uint64_t getRandSeed(void);                 // Get/set the global random seed and state
    void setRandSeed(uint64_t);

    uint64_t getRandState(void);
    void setRandState(uint64_t);

    std::map<bh_base*, size_t> ref_count;       // Count references to bh_base
    std::map<bh_base*, size_t> ext_allocated;   // Lookup register for externally allocated data

private:

    uint64_t    global_random_seed_;            // Random state and seed
    uint64_t    global_random_state_;           // TODO: Should be encapsulated in a "sugar-layer"

    bohrium::ConfigParser config;               // Bohrium Configuration
    bohrium::component::ComponentFace runtime;  // The Bohrium Runtime i.e. the child of this component

    std::map<std::string, bh_opcode> extensions;// Register of extensions
    size_t extension_count;

    bh_instruction  queue[BH_CPP_QUEUE_MAX];    // Bytecode queue
    size_t          ext_in_queue;
    size_t          queue_size;

    std::list<bh_base*> garbage;                // Collection of bh_base which will
                                                // be deleted when the current batch is flushed.

    Runtime();                                  // Ensure no external instantiation.
    Runtime(Runtime const&);
    void operator=(Runtime const&);

    size_t deallocate_meta(size_t count);       // De-allocate bh_base
    size_t deallocate_ext();                    // De-allocate userdefined functions structs

    size_t execute();                           // Send instructions to Bohrium
    size_t guard();                             // Prevent overflow of instruction-queue

};

}

#include "multi_array.hpp"          // Operand definition.

#include "runtime.hpp"              // Communication with Bohrium runtime
#include "runtime.broadcast.hpp"    // Operand broadcasting
#include "runtime.typechecker.hpp"  // Array operations - typechecker
#include "runtime.operations.hpp"   // Array operations
#include "runtime.extensions.hpp"   // Extensions

#include "reduction.hpp"    // DSEL Reduction
#include "scan.hpp"         // DSEL Scan operation
#include "generator.hpp"    // DSEL Generators
#include "mapping.hpp"      // DSEL Gather / Scatter
#include "grids.hpp"        // DSEL Grid constructors
#include "movement.hpp"     // DSEL Export / import data from arrays
#include "visuals.hpp"      // DSEL Visualization

#include "operators.hpp"    // DSEL Operations via operator-overloads.
#include "sugar.hpp"        // DSEL Additional sugar...

#endif
<commit_msg>Make variadic constructor explicit<commit_after>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium team:
http://bohrium.bitbucket.org

Bohrium 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 3
of the License, or (at your option) any later version.

Bohrium 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 General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __BOHRIUM_BRIDGE_CPP
#define __BOHRIUM_BRIDGE_CPP

#define BH_CPP_QUEUE_MAX 1000

#include <stdexcept>
#include <complex>
#include <list>
#include <map>

#include <bh_component.hpp>
#include "iterator.hpp"

#ifdef DEBUG
#define DEBUG_PRINT(...) do{ fprintf( stderr, __VA_ARGS__ ); } while( false )
#else
#define DEBUG_PRINT(...) do{ } while ( false )
#endif

#define is_aligned(POINTER, BYTE_COUNT) \
    (((uintptr_t)(const void *)(POINTER)) % (BYTE_COUNT) == 0)

namespace bxx {

const double PI_D = 3.141592653589793238462;
const float  PI_F = 3.14159265358979f;
const float  PI   = 3.14159265358979f;

struct Export {
    enum Option {
        NONE        = 0x00,
        RELEASED    = 0x01,
        WO_ALLOC    = 0x02,
        WO_ZEROING  = 0x04
    };
};

template <typename T>   // Forward declaration
class multi_array;

inline int64_t unpack_shape(int64_t *shape, size_t index, size_t arg)
{
    shape[index] = arg;
    return 0;
}

template <typename ...Args>
int64_t unpack_shape(int64_t *shape, size_t index, size_t arg, Args... args)
{
    shape[index] = arg;
    unpack_shape(shape, ++index, args...);

    return 1;
}

inline int64_t nelements_shape(size_t arg)
{
    return arg;
}

template <typename ...Args>
int64_t nelements_shape(size_t arg, Args... args)
{
    return arg*nelements_shape(args...);
}

//
// Extensions
//

#ifndef END
#define END 0
#endif

enum scannable {
    SUM     = BH_ADD_ACCUMULATE,
    PRODUCT = BH_MULTIPLY_ACCUMULATE
};

//
// Slicing
//
class Slice {
public:
    Slice();
    Slice(int begin, int end, size_t step);

    int begin;
    int end;
    size_t step;
};

inline Slice::Slice() : begin(0), end(-1), step(1) {}

inline Slice::Slice(int begin, int end, size_t step)
    : begin(begin), end(end), step(step) {}

inline Slice _(int begin, int end, size_t step)
{
    return Slice(begin, end, step);
}

inline Slice _(int begin, int end)
{
    return _(begin, end, 1);
}

inline Slice _SI(int begin, int end, size_t step)
{
    return _(begin, end, step);
}

inline Slice _SI(int begin, int end)
{
    return _(begin, end, 1);
}

inline Slice _SE(int begin, int end, size_t step)
{
    return _(begin, end-1, step);
}

inline Slice _SE(int begin, int end)
{
    return _(begin, end-1, 1);
}

inline Slice _ALL(void)
{
    return _(0, -1, 1);
}

inline Slice _ABF(void)
{
    return _(1, -1, 1);
}

inline Slice _ABL(void)
{
    return _(0, -2, 1);
}

inline Slice _INNER(void)
{
    return _(1, -2, 1);
}

//
// The Abstraction
//
template <typename T>
class multi_array {
public:
    bh_view meta;

    // ** Constructors **
    multi_array();                              // Empty
    multi_array(const multi_array<T> &operand); // Copy
    multi_array(const uint64_t rank, const int64_t* shapes);
    multi_array(bh_base* base, uint64_t rank, const int64_t start, const int64_t* shape, const int64_t* stride);

    template <typename OtherT>
    multi_array(const multi_array<OtherT> &operand);    // Copy

    template <typename ...Dimensions>                   // Variadic constructor
    explicit multi_array(Dimensions... dims);

    // ** Deconstructor **
    ~multi_array();

    // Types:
    typedef multi_array_iter<T> iterator;

    size_t len() const;
    int64_t shape(int64_t dim) const;             // Probe for the shape of the given dimension
    unsigned long getRank() const;

    // Iterator
    iterator begin();
    iterator end();

    //
    // Operators:
    //
    // =, [], (), -> must be "internal" (nonstatic member functions) and thus declared here.
    //
    // Definitions are provided in:
    //
    // - multi_array.hpp for those implemented by hand ([], ++, --, ostream<< ).
    // - operators.hpp: defined code-generator.
    //
                                                    // Slicing / explicit view
    multi_array<T>& operator[](int rhs);            // Select a single element / dimension
    multi_array<T>& operator[](Slice rhs);          // Select a range (begin, end, step)

    multi_array& operator()(const T& n);            // Update
    multi_array& operator()(multi_array<T>& rhs);

    //
    // Data movement
    //
    multi_array& operator()(const void* data);      // Update / copy from a void pointer

    T* data_export(void);
    void data_import(T* data);

    multi_array& operator=(const T& rhs);           // Initialization / assignment.
    multi_array& operator=(multi_array<T>& rhs);    // Initialization / assignment.

    template <typename In>
    multi_array<T>& operator=(multi_array<In>& rhs);// Initialization / assignment.

    multi_array& operator+=(const T& rhs);          // Compound assignment / increment
    multi_array& operator+=(multi_array& rhs);

    multi_array& operator-=(const T& rhs);
    multi_array& operator-=(multi_array& rhs);

    multi_array& operator*=(const T& rhs);
    multi_array& operator*=(multi_array& rhs);

    multi_array& operator/=(const T& rhs);
    multi_array& operator/=(multi_array &rhs);

    multi_array& operator%=(const T& rhs);
    multi_array& operator%=(multi_array &rhs);

    multi_array& operator>>=(const T& rhs);
    multi_array& operator>>=(multi_array& rhs);

    multi_array& operator<<=(const T& rhs);
    multi_array& operator<<=(multi_array& rhs);

    multi_array& operator&=(const T& rhs);
    multi_array& operator&=(multi_array& rhs);

    multi_array& operator^=(const T& rhs);
    multi_array& operator^=(multi_array& rhs);

    multi_array& operator|=(const T& rhs);
    multi_array& operator|=(multi_array& rhs);

    multi_array& operator++();              // Increment all elements in container
    multi_array& operator++(int);
    multi_array& operator--();              // Decrement all elements in container
    multi_array& operator--(int);

    void link();                            // Bohrium Runtime Specifics
    void link(bh_base* base);               // Bohrium Runtime Specifics
    bh_base* unlink();

    bh_base* getBase() const;

    void* getBaseData(void);                // These are NOT for the faint of heart!
    void setBaseData(void* data);           // These are only intended for the C-bridge.

    bool getTemp() const;
    void setTemp(bool temp);
    bool linked() const;
    bool initialized() const;               // Determine if the array is initialized (has a bh_base)
    bool allocated() const;                 // Determine if the array is intitialized and data for it is allocated
    void sync();

    int getSliceDim(void);
    void setSliceDim(int dim);

protected:
    bool temp_;
    int slicing_dim_;

private:
    void reset_meta();						// Helper, shared among constructors

    template <typename S>
    friend void swap(multi_array<S>& lhs, multi_array<S>& rhs);
};

template <typename T>
inline void swap(multi_array<T>& lhs, multi_array<T>& rhs) {
    using std::swap;
    swap(lhs.temp_, rhs.temp_);
    swap(lhs.slicing_dim_, rhs.slicing_dim_);
    swap(lhs.meta, rhs.meta);
}

template <typename TL, typename TR>
inline
bool identical(multi_array<TL>& left, multi_array<TR>& right)
{
    return static_cast<void*>(&left) == static_cast<void*>(&right);
}

/**
 *  Encapsulation of communication with Bohrium runtime.
 *  Implemented as a Singleton.
 *
 *  Note: Not thread-safe.
 */
class Runtime {
public:
    static Runtime& instance(); // Singleton method

    ~Runtime();         // Deconstructor

    //
    //  Lazy evaluation through instruction queue
    //
    template <typename TO, typename T1, typename T2, typename T3>
    void enqueue(bh_opcode opcode, multi_array<TO>& op0, multi_array<T1>& op1, multi_array<T2>& op2, multi_array<T3>& op3);

    template <typename TO, typename TL, typename TR>
    void enqueue(bh_opcode opcode, multi_array<TO>& op0, multi_array<TL>& op1, multi_array<TR>& op2);

    template <typename TO, typename TL, typename TR>
    void enqueue(bh_opcode opcode, multi_array<TO>& op0, multi_array<TL>& op1, const TR op2);

    template <typename TO, typename TL, typename TR>
    void enqueue(bh_opcode opcode, multi_array<TO>& op0, const TL op1, multi_array<TR>& op2);

    template <typename TO, typename TI>
    void enqueue(bh_opcode opcode, multi_array<TO>& op0, multi_array<TI>& op1);

    template <typename TO, typename TI>
    void enqueue(bh_opcode opcode, multi_array<TO>& op0, const TI op1);

    template <typename TO>
    void enqueue(bh_opcode opcode, multi_array<TO>& op0);

    void enqueue(bh_opcode opcode);

    template <typename TO>
    void enqueue(bh_opcode opcode, multi_array<TO>& op0, const uint64_t op1, const uint64_t op2);

    template <typename T1, typename T2, typename T3>
    void enqueue_extension(const std::string& name, multi_array<T1>& op0, multi_array<T2>& op2, multi_array<T3>& op3);

    size_t flush();
    size_t get_queue_size();

    //
    //  Typechecker
    //
    template <size_t Opcode, typename TO, typename T1, typename T2, typename T3>
    void typecheck(void);

    template <size_t Opcode, typename Out, typename In1, typename In2>
    void typecheck(void);

    template <size_t Opcode, typename Out, typename In1>
    void typecheck(void);

    template <size_t Opcode, typename Out>
    void typecheck(void);

    //
    //  Operand construction
    //

    template <typename T>
    multi_array<T>& create(void);

    /**
        Construct a new "linked" array, that it, it has an
        associated `bh_base`.
        Shape is inherited by `input`.
    **/
    template <typename T, typename OtherT>
    multi_array<T>& create_base(multi_array<OtherT>& input);

    template <typename T>
    multi_array<T>& temp();

    template <typename T, typename OtherT>
    multi_array<T>& temp(multi_array<OtherT>& input);

    template <typename T>
    multi_array<T>& view(multi_array<T>& base);

    template <typename T>
    multi_array<T>& temp_view(multi_array<T>& base);

    void trash(bh_base* base);

    uint64_t getRandSeed(void);                 // Get/set the global random seed and state
    void setRandSeed(uint64_t);

    uint64_t getRandState(void);
    void setRandState(uint64_t);

    std::map<bh_base*, size_t> ref_count;       // Count references to bh_base
    std::map<bh_base*, size_t> ext_allocated;   // Lookup register for externally allocated data

private:

    uint64_t    global_random_seed_;            // Random state and seed
    uint64_t    global_random_state_;           // TODO: Should be encapsulated in a "sugar-layer"

    bohrium::ConfigParser config;               // Bohrium Configuration
    bohrium::component::ComponentFace runtime;  // The Bohrium Runtime i.e. the child of this component

    std::map<std::string, bh_opcode> extensions;// Register of extensions
    size_t extension_count;

    bh_instruction  queue[BH_CPP_QUEUE_MAX];    // Bytecode queue
    size_t          ext_in_queue;
    size_t          queue_size;

    std::list<bh_base*> garbage;                // Collection of bh_base which will
                                                // be deleted when the current batch is flushed.

    Runtime();                                  // Ensure no external instantiation.
    Runtime(Runtime const&);
    void operator=(Runtime const&);

    size_t deallocate_meta(size_t count);       // De-allocate bh_base
    size_t deallocate_ext();                    // De-allocate userdefined functions structs

    size_t execute();                           // Send instructions to Bohrium
    size_t guard();                             // Prevent overflow of instruction-queue

};

}

#include "multi_array.hpp"          // Operand definition.

#include "runtime.hpp"              // Communication with Bohrium runtime
#include "runtime.broadcast.hpp"    // Operand broadcasting
#include "runtime.typechecker.hpp"  // Array operations - typechecker
#include "runtime.operations.hpp"   // Array operations
#include "runtime.extensions.hpp"   // Extensions

#include "reduction.hpp"    // DSEL Reduction
#include "scan.hpp"         // DSEL Scan operation
#include "generator.hpp"    // DSEL Generators
#include "mapping.hpp"      // DSEL Gather / Scatter
#include "grids.hpp"        // DSEL Grid constructors
#include "movement.hpp"     // DSEL Export / import data from arrays
#include "visuals.hpp"      // DSEL Visualization

#include "operators.hpp"    // DSEL Operations via operator-overloads.
#include "sugar.hpp"        // DSEL Additional sugar...

#endif
<|endoftext|>


<commit_before>#ifndef K3_UNIQPOLYBUF
#define K3_UNIQPOLYBUF

#include <unordered_set>

#if HAS_LIBDYNAMIC

#include <boost/serialization/array.hpp>
#include <boost/serialization/string.hpp>
#include <boost/functional/hash.hpp>

#include <yaml-cpp/yaml.h>
#include <rapidjson/document.h>
#include <csvpp/csv.h>
#include "serialization/Json.hpp"

#include "Common.hpp"
#include "collections/STLDataspace.hpp"
#include "collections/Collection.hpp"
#include "FlatPolyBuffer.hpp"

namespace K3 {
namespace Libdynamic {

//////////////////////////////////////////
//
// Buffer functors.

template<typename Tag>
using UPBKey = std::pair<Tag, void*>;

template<class T, typename Tag>
struct UPBEqual : std::binary_function<UPBKey<Tag>, UPBKey<Tag>, bool> {
  bool operator()(const UPBKey<Tag>& left, const UPBKey<Tag>& right) const {
    return T::equalelem(left.first, left.second, right.first, right.second);
  }
};

template<typename T, typename Tag>
struct UPBHash : std::unary_function<UPBKey<Tag>, std::size_t> {
  std::size_t operator()(const UPBKey<Tag>& k) const {
    std::hash<Tag> hash;
    size_t h1 = hash(k.first);
    boost::hash_combine(h1, T::hashelem(k.first, k.second));
    return h1;
  }
};

//////////////////////////////////////////
//
// UniquePolyBuffer

template<class Ignore, class Derived>
class UniquePolyBuffer : public FlatPolyBuffer<Ignore> {
public:
  using Super = FlatPolyBuffer<Ignore>;
  using Tag = typename Super::Tag;

  using FContainer = typename Super::FContainer;
  using VContainer = typename Super::VContainer;
  using TContainer = typename Super::TContainer;

  UniquePolyBuffer() {}

  UniquePolyBuffer(const UniquePolyBuffer& other) : Super(other) {
    keys = other.keys;
  }

  UniquePolyBuffer(UniquePolyBuffer&& other) : Super(other) {
    keys.swap(other.keys);
  }

  UniquePolyBuffer& operator=(const UniquePolyBuffer& other) {
    Super::operator=(other);
    keys = other.keys;
  }

  void rebuildKeys() {
    size_t foffset = 0, sz = Super::size(unit_t{});
    for (size_t i = 0; i < sz; ++i) {
      Tag tg = Super::tag_at(i);
      keys.insert(std::make_pair(tg, reinterpret_cast<void*>(buffer_data(Super::fixed()) + foffset)));
      foffset += Super::elemsize(tg);
    }
  }

  //////////////////////////////////
  //
  // Tag-specific accessors.

  template<typename T>
  unit_t append(Tag tg, const T& t) {
    if ( keys.find(std::make_pair(tg, reinterpret_cast<void*>(const_cast<T*>(&t)))) == keys.end() ) {
      FContainer* ncf = const_cast<FContainer*>(Super::fixedc());
      size_t offset = buffer_size(ncf);
      Super::append(tg, t);
      keys.insert(std::make_pair(tg, buffer_data(ncf)+offset));
    }
    return unit_t{};
  }

  // Clears a container, deleting any backing buffer.
  unit_t clear(unit_t) {
    keys.clear();
    return Super::clear(unit_t{});
  }

  unit_t load(const base_string& str) {
    return load(base_string(str));
  }

  // Restores a flat poly buffer from a string.
  unit_t load(base_string&& str) {
    Super::load(std::forward<base_string>(str));
    rebuildKeys();
    return unit_t{};
  }

  template <class archive>
  void save(archive& a, const unsigned int) const {
    a << boost::serialization::base_object<const Super>(*this);
  }

  template <class archive>
  void load(archive& a, const unsigned int) {
    a >> boost::serialization::base_object<Super>(*this);
    rebuildKeys();
  }

  template <class archive>
  void serialize(archive& a) const {
    a << yas::base_object<const Super>(*this);
  }

  template <class archive>
  void serialize(archive& a) {
    a >> yas::base_object<Super>(*this);
    rebuildKeys();
  }

  BOOST_SERIALIZATION_SPLIT_MEMBER()

private:
  std::unordered_set<UPBKey<Tag>, UPBHash<Derived, Tag>, UPBEqual<Derived, Tag>> keys;
};

}; // end namespace Libdynamic

template<class Ignored, class Derived>
using UniquePolyBuffer = Libdynamic::UniquePolyBuffer<Ignored, Derived>;

}; // end namespace K3

namespace YAML {
template <class E, class Derived>
struct convert<K3::UniquePolyBuffer<E, Derived>> {
  using Tag = typename K3::UniquePolyBuffer<E, Derived>::Tag;
  static Node encode(const K3::UniquePolyBuffer<E, Derived>& c) {
    Node node;
    bool flag = true;
    c.iterate([&c, &node, &flag](Tag tg, size_t idx, size_t offset){
      if (flag) { flag = false; }
      node.push_back(c.yamlencode(tg, idx, offset));
    });
    if (flag) {
      node = YAML::Load("[]");
    }
    return node;
  }

  static bool decode(const Node& node, K3::UniquePolyBuffer<E, Derived>& c) {
    for (auto i : node) {
      c.yamldecode(i);
    }
    return true;
  }
};
}  // namespace YAML

namespace JSON {
using namespace rapidjson;
template <class E, class Derived>
struct convert<K3::UniquePolyBuffer<E, Derived>> {
  using Tag = typename K3::UniquePolyBuffer<E, Derived>::Tag;
  template <class Allocator>
  static Value encode(const K3::UniquePolyBuffer<E, Derived>& c, Allocator& al) {
    Value v;
    v.SetObject();
    v.AddMember("type", Value("UniquePolyBuffer"), al);
    Value inner;
    inner.SetArray();
    c.iterate([&c, &inner, &al](Tag tg, size_t idx, size_t offset){
      inner.PushBack(c.jsonencode(tg, idx, offset, al), al);
    });
    v.AddMember("value", inner.Move(), al);
    return v;
  }
};
}  // namespace JSON

#endif // HAS_LIBDYNAMIC

#endif
<commit_msg>Fixed serialization and elemsize in UPB<commit_after>#ifndef K3_UNIQPOLYBUF
#define K3_UNIQPOLYBUF

#include <unordered_set>

#if HAS_LIBDYNAMIC

#include <boost/serialization/array.hpp>
#include <boost/serialization/string.hpp>
#include <boost/functional/hash.hpp>

#include <yaml-cpp/yaml.h>
#include <rapidjson/document.h>
#include <csvpp/csv.h>
#include "serialization/Json.hpp"

#include "Common.hpp"
#include "collections/STLDataspace.hpp"
#include "collections/Collection.hpp"
#include "FlatPolyBuffer.hpp"

namespace K3 {
namespace Libdynamic {

//////////////////////////////////////////
//
// Buffer functors.

template<typename Tag>
using UPBKey = std::pair<Tag, void*>;

template<class T, typename Tag>
struct UPBEqual : std::binary_function<UPBKey<Tag>, UPBKey<Tag>, bool> {
  bool operator()(const UPBKey<Tag>& left, const UPBKey<Tag>& right) const {
    return T::equalelem(left.first, left.second, right.first, right.second);
  }
};

template<typename T, typename Tag>
struct UPBHash : std::unary_function<UPBKey<Tag>, std::size_t> {
  std::size_t operator()(const UPBKey<Tag>& k) const {
    std::hash<Tag> hash;
    size_t h1 = hash(k.first);
    boost::hash_combine(h1, T::hashelem(k.first, k.second));
    return h1;
  }
};

//////////////////////////////////////////
//
// UniquePolyBuffer

template<class Ignore, class Derived>
class UniquePolyBuffer : public FlatPolyBuffer<Ignore> {
public:
  using Super = FlatPolyBuffer<Ignore>;
  using Tag = typename Super::Tag;

  using FContainer = typename Super::FContainer;
  using VContainer = typename Super::VContainer;
  using TContainer = typename Super::TContainer;

  UniquePolyBuffer() {}

  UniquePolyBuffer(const UniquePolyBuffer& other) : Super(other) {
    keys = other.keys;
  }

  UniquePolyBuffer(UniquePolyBuffer&& other) : Super(other) {
    keys.swap(other.keys);
  }

  UniquePolyBuffer& operator=(const UniquePolyBuffer& other) {
    Super::operator=(other);
    keys = other.keys;
  }

  void rebuildKeys() {
    size_t foffset = 0, sz = Super::size(unit_t{});
    for (size_t i = 0; i < sz; ++i) {
      Tag tg = Super::tag_at(i);
      keys.insert(std::make_pair(tg, reinterpret_cast<void*>(buffer_data(Super::fixed()) + foffset)));
      foffset += this->elemsize(tg);
    }
  }

  //////////////////////////////////
  //
  // Tag-specific accessors.

  template<typename T>
  unit_t append(Tag tg, const T& t) {
    if ( keys.find(std::make_pair(tg, reinterpret_cast<void*>(const_cast<T*>(&t)))) == keys.end() ) {
      FContainer* ncf = const_cast<FContainer*>(Super::fixedc());
      size_t offset = buffer_size(ncf);
      Super::append(tg, t);
      keys.insert(std::make_pair(tg, buffer_data(ncf)+offset));
    }
    return unit_t{};
  }

  // Clears a container, deleting any backing buffer.
  unit_t clear(unit_t) {
    keys.clear();
    return Super::clear(unit_t{});
  }

  unit_t load(const base_string& str) {
    return load(base_string(str));
  }

  // Restores a flat poly buffer from a string.
  unit_t load(base_string&& str) {
    Super::load(std::forward<base_string>(str));
    rebuildKeys();
    return unit_t{};
  }

  template <class archive>
  void save(archive& a, const unsigned int) const {
    a << boost::serialization::base_object<const Super>(*this);
  }

  template <class archive>
  void load(archive& a, const unsigned int) {
    a >> boost::serialization::base_object<Super>(*this);
    rebuildKeys();
  }

  template <class archive>
  void serialize(archive& a) const {
    Super::serialize(a);
  }

  template <class archive>
  void serialize(archive& a) {
    Super::serialize(a);
    rebuildKeys();
  }

  BOOST_SERIALIZATION_SPLIT_MEMBER()

private:
  std::unordered_set<UPBKey<Tag>, UPBHash<Derived, Tag>, UPBEqual<Derived, Tag>> keys;
};

}; // end namespace Libdynamic

template<class Ignored, class Derived>
using UniquePolyBuffer = Libdynamic::UniquePolyBuffer<Ignored, Derived>;

}; // end namespace K3

namespace YAML {
template <class E, class Derived>
struct convert<K3::UniquePolyBuffer<E, Derived>> {
  using Tag = typename K3::UniquePolyBuffer<E, Derived>::Tag;
  static Node encode(const K3::UniquePolyBuffer<E, Derived>& c) {
    Node node;
    bool flag = true;
    c.iterate([&c, &node, &flag](Tag tg, size_t idx, size_t offset){
      if (flag) { flag = false; }
      node.push_back(c.yamlencode(tg, idx, offset));
    });
    if (flag) {
      node = YAML::Load("[]");
    }
    return node;
  }

  static bool decode(const Node& node, K3::UniquePolyBuffer<E, Derived>& c) {
    for (auto i : node) {
      c.yamldecode(i);
    }
    return true;
  }
};
}  // namespace YAML

namespace JSON {
using namespace rapidjson;
template <class E, class Derived>
struct convert<K3::UniquePolyBuffer<E, Derived>> {
  using Tag = typename K3::UniquePolyBuffer<E, Derived>::Tag;
  template <class Allocator>
  static Value encode(const K3::UniquePolyBuffer<E, Derived>& c, Allocator& al) {
    Value v;
    v.SetObject();
    v.AddMember("type", Value("UniquePolyBuffer"), al);
    Value inner;
    inner.SetArray();
    c.iterate([&c, &inner, &al](Tag tg, size_t idx, size_t offset){
      inner.PushBack(c.jsonencode(tg, idx, offset, al), al);
    });
    v.AddMember("value", inner.Move(), al);
    return v;
  }
};
}  // namespace JSON

#endif // HAS_LIBDYNAMIC

#endif
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/ffdc/ffdc_includes.H $     */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
#ifndef __FFDC_INCLUDES_H
#define __FFDC_INCLUDES_H

/// @file ffdc_includes.H
///
/// @brief main file used to export all include files for FFDC procedures
///

#include <p9_collect_some_ffdc.H>

#endif
<commit_msg>FFDC updates - p9_start_cbs<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/ffdc/ffdc_includes.H $     */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
#ifndef __FFDC_INCLUDES_H
#define __FFDC_INCLUDES_H

/// @file ffdc_includes.H
///
/// @brief main file used to export all include files for FFDC procedures
///

#include <p9_collect_some_ffdc.H>
#include <p9_pib2pcb_mux_seq.H>
#endif
<|endoftext|>


<commit_before>//===--- HTMLDiagnostics.cpp - HTML Diagnostics for Paths ----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the HTMLDiagnostics object.
//
//===----------------------------------------------------------------------===//

#include "HTMLDiagnostics.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/FileManager.h"
#include "clang/AST/ASTContext.h"
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/Rewrite/Rewriter.h"
#include "clang/Rewrite/HTMLRewrite.h"
#include "clang/Lex/Lexer.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Streams.h"
#include "llvm/System/Path.h"
#include <fstream>
#include <sstream>

using namespace clang;

//===----------------------------------------------------------------------===//
// Boilerplate.
//===----------------------------------------------------------------------===//

namespace {

class VISIBILITY_HIDDEN HTMLDiagnostics : public PathDiagnosticClient {
  llvm::sys::Path Directory, FilePrefix;
  bool createdDir, noDir;
public:
  HTMLDiagnostics(const std::string& prefix);

  virtual ~HTMLDiagnostics() {}

  virtual void HandlePathDiagnostic(const PathDiagnostic& D);

  void HandlePiece(Rewriter& R, const PathDiagnosticPiece& P,
                   unsigned num, unsigned max);

  void HighlightRange(Rewriter& R, SourceRange Range, unsigned MainFileID);
};

} // end anonymous namespace

HTMLDiagnostics::HTMLDiagnostics(const std::string& prefix)
  : Directory(prefix), FilePrefix(prefix), createdDir(false), noDir(false) {

  // All html files begin with "report"
  FilePrefix.appendComponent("report");
}

PathDiagnosticClient*
clang::CreateHTMLDiagnosticClient(const std::string& prefix) {

  return new HTMLDiagnostics(prefix);
}

//===----------------------------------------------------------------------===//
// Report processing.
//===----------------------------------------------------------------------===//

void HTMLDiagnostics::HandlePathDiagnostic(const PathDiagnostic& D) {

  if (D.empty())
    return;

  // Create the HTML directory if it is missing.

  if (!createdDir) {
    createdDir = true;
    std::string ErrorMsg;
    Directory.createDirectoryOnDisk(true, &ErrorMsg);

    if (!Directory.isDirectory()) {
      llvm::cerr << "warning: could not create directory '"
                 << Directory.toString() << "'\n"
                 << "reason: " << ErrorMsg << '\n';

      noDir = true;

      return;
    }
  }

  if (noDir)
    return;

  // Create a new rewriter to generate HTML.
  SourceManager& SMgr = D.begin()->getLocation().getManager();
  Rewriter R(SMgr);

  // Process the path.

  unsigned n = D.size();
  unsigned max = n;

  for (PathDiagnostic::const_reverse_iterator I=D.rbegin(), E=D.rend();
        I!=E; ++I, --n) {

    HandlePiece(R, *I, n, max);
  }

  // Add line numbers, header, footer, etc.

  unsigned FileID = R.getSourceMgr().getMainFileID();
  html::EscapeText(R, FileID);
  html::AddLineNumbers(R, FileID);

  // Get the full directory name of the analyzed file.

  const FileEntry* Entry = SMgr.getFileEntryForID(FileID);
  std::string DirName(Entry->getDir()->getName());

  if (DirName == ".")
    DirName = llvm::sys::Path::GetCurrentDirectory().toString();

  // Add the name of the file as an
 tag.

  {
    std::ostringstream os;

    os << "
" << html::EscapeText(DirName)
       << "/"    <getName()) << "
\n";

    R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
  }

  // Embed meta-data tags.

  const std::string& BugDesc = D.getDescription();

  if (!BugDesc.empty()) {
    std::ostringstream os;
    os << "\n\n";
    R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
  }

  {
    std::ostringstream os;
    os << "\n\n";
    R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
  }

  {
    std::ostringstream os;
    os << "\n\n";
    R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
  }

  {
    std::ostringstream os;
    os << "\n\n";
    R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
  }

  // Add CSS, header, and footer.

  html::AddHeaderFooterInternalBuiltinCSS(R, FileID);

  // Get the rewrite buffer.
  const RewriteBuffer *Buf = R.getRewriteBufferFor(FileID);

  if (!Buf) {
    llvm::cerr << "warning: no diagnostics generated for main file.\n";
    return;
  }

  // Create the stream to write out the HTML.
  std::ofstream os;

  {
    // Create a path for the target HTML file.
    llvm::sys::Path F(FilePrefix);
    F.makeUnique(false, NULL);

    // Rename the file with an HTML extension.
    llvm::sys::Path H(F);
    H.appendSuffix("html");
    F.renamePathOnDisk(H, NULL);

    os.open(H.toString().c_str());

    if (!os) {
      llvm::cerr << "warning: could not create file '" << F.toString() << "'\n";
      return;
    }
  }

  // Emit the HTML to disk.

  for (RewriteBuffer::iterator I = Buf->begin(), E = Buf->end(); I!=E; ++I) {
    // Expand tabs.
    if (*I == '\t')
      os << "   ";
    else
      os << *I;
  }
}

void HTMLDiagnostics::HandlePiece(Rewriter& R,
                                  const PathDiagnosticPiece& P,
                                  unsigned num, unsigned max) {

  // For now, just draw a box above the line in question, and emit the
  // warning.

  FullSourceLoc Pos = P.getLocation();

  if (!Pos.isValid())
    return;

  SourceManager& SM = R.getSourceMgr();
  FullSourceLoc LPos = Pos.getLogicalLoc();
  unsigned FileID = LPos.getLocation().getFileID();

  assert (&LPos.getManager() == &SM && "SourceManagers are different!");

  unsigned MainFileID = SM.getMainFileID();

  if (FileID != MainFileID)
    return;

  // Compute the column number.  Rewind from the current position to the start
  // of the line.

  unsigned ColNo = LPos.getColumnNumber();
  const char *TokLogicalPtr = LPos.getCharacterData();
  const char *LineStart = TokLogicalPtr-ColNo;

  // Compute the margin offset by counting tabs and non-tabs.

  unsigned PosNo = 0;

  for (const char* c = LineStart; c != TokLogicalPtr; ++c)
    PosNo += *c == '\t' ? 4 : 1;

  // Create the html for the message.

  std::ostringstream os;

  os << "\n
	"
     << "<div id=\"";

  if (num == max)
    os << "EndPath";
  else
    os << "Path" << num;

  os << "\" class=\"msg\" style=\"margin-left:"
     << PosNo << "ex\">";

  if (max > 1)
    os << "[" << num << "] ";

  os << html::EscapeText(P.getString()) << "

";

  // Insert the new html.

  const llvm::MemoryBuffer *Buf = SM.getBuffer(FileID);
  const char* FileStart = Buf->getBufferStart();

  R.InsertStrBefore(SourceLocation::getFileLoc(FileID, LineStart - FileStart),
                    os.str());

  // Now highlight the ranges.

  for (const SourceRange *I = P.ranges_begin(), *E = P.ranges_end();
        I != E; ++I)
    HighlightRange(R, *I, MainFileID);
}

void HTMLDiagnostics::HighlightRange(Rewriter& R, SourceRange Range,
                                     unsigned MainFileID) {

  SourceManager& SourceMgr = R.getSourceMgr();

  SourceLocation LogicalStart = SourceMgr.getLogicalLoc(Range.getBegin());
  unsigned StartLineNo = SourceMgr.getLineNumber(LogicalStart);

  SourceLocation LogicalEnd = SourceMgr.getLogicalLoc(Range.getEnd());
  unsigned EndLineNo = SourceMgr.getLineNumber(LogicalEnd);

  if (EndLineNo < StartLineNo)
    return;

  if (LogicalStart.getFileID() != MainFileID ||
      LogicalEnd.getFileID() != MainFileID)
    return;

  // Compute the column number of the end.
  unsigned EndColNo = SourceMgr.getColumnNumber(LogicalEnd);
  unsigned OldEndColNo = EndColNo;

  if (EndColNo) {
    // Add in the length of the token, so that we cover multi-char tokens.
    EndColNo += Lexer::MeasureTokenLength(Range.getEnd(), SourceMgr);
  }

  // Highlight the range.  Make the span tag the outermost tag for the
  // selected range.

  SourceLocation E =
    LogicalEnd.getFileLocWithOffset(OldEndColNo > EndColNo
                                    ? -(OldEndColNo - EndColNo)
                                    : EndColNo - OldEndColNo);

  R.InsertCStrBefore(LogicalStart, "");
  R.InsertCStrAfter(E, "");

  if (EndLineNo == StartLineNo)
    return;

  // Add in  tags for intermediate lines.

  const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(MainFileID);

  unsigned Pos = SourceMgr.getFullFilePos(LogicalStart);
  unsigned EndPos = SourceMgr.getFullFilePos(E);
  const char* buf = Buf->getBufferStart();

  for (; Pos != EndPos; ++Pos) {

    SourceLocation L = SourceLocation::getFileLoc(MainFileID, Pos);
    unsigned Col = SourceMgr.getColumnNumber(L);

    if (Col == 1) {

      // Start if a new line.  Scan to see if we hit anything that is not
      // whitespace or a newline.

      unsigned PosTmp = Pos;
      bool NewLine = false;

      for ( ; PosTmp != EndPos ; ++PosTmp) {
        switch (buf[PosTmp]) {
          case ' ':
          case '\t': continue;
          case '\n':
            NewLine = true;
            break;
          default:
            break;
        }

        break;
      }

      if (PosTmp == EndPos)
        break;

      Pos = PosTmp;

      // Don't highlight a blank line.
      if (NewLine)
        continue;

      // This line contains text that we should highlight.
      // Ignore leading whitespace.
      L = SourceLocation::getFileLoc(MainFileID, Pos);
      R.InsertCStrAfter(L, "");
    }
    else if (buf[Pos] == '\n')
      R.InsertCStrBefore(L, "");
  }
}
<commit_msg>HTMLDiagnostics now uses the new "getCanonicalID()", "isFromMainFileID()" methods from SourceManager when doing HTML pretty-printing.  This resolves an insidious bug when presenting error reports that only occurred in large source files.<commit_after>//===--- HTMLDiagnostics.cpp - HTML Diagnostics for Paths ----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the HTMLDiagnostics object.
//
//===----------------------------------------------------------------------===//

#include "HTMLDiagnostics.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/FileManager.h"
#include "clang/AST/ASTContext.h"
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/Rewrite/Rewriter.h"
#include "clang/Rewrite/HTMLRewrite.h"
#include "clang/Lex/Lexer.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Streams.h"
#include "llvm/System/Path.h"
#include <fstream>
#include <sstream>

using namespace clang;

//===----------------------------------------------------------------------===//
// Boilerplate.
//===----------------------------------------------------------------------===//

namespace {

class VISIBILITY_HIDDEN HTMLDiagnostics : public PathDiagnosticClient {
  llvm::sys::Path Directory, FilePrefix;
  bool createdDir, noDir;
public:
  HTMLDiagnostics(const std::string& prefix);

  virtual ~HTMLDiagnostics() {}

  virtual void HandlePathDiagnostic(const PathDiagnostic& D);

  void HandlePiece(Rewriter& R, const PathDiagnosticPiece& P,
                   unsigned num, unsigned max);

  void HighlightRange(Rewriter& R, SourceRange Range);
};

} // end anonymous namespace

HTMLDiagnostics::HTMLDiagnostics(const std::string& prefix)
  : Directory(prefix), FilePrefix(prefix), createdDir(false), noDir(false) {

  // All html files begin with "report"
  FilePrefix.appendComponent("report");
}

PathDiagnosticClient*
clang::CreateHTMLDiagnosticClient(const std::string& prefix) {

  return new HTMLDiagnostics(prefix);
}

//===----------------------------------------------------------------------===//
// Report processing.
//===----------------------------------------------------------------------===//

void HTMLDiagnostics::HandlePathDiagnostic(const PathDiagnostic& D) {

  if (D.empty())
    return;

  // Create the HTML directory if it is missing.

  if (!createdDir) {
    createdDir = true;
    std::string ErrorMsg;
    Directory.createDirectoryOnDisk(true, &ErrorMsg);

    if (!Directory.isDirectory()) {
      llvm::cerr << "warning: could not create directory '"
                 << Directory.toString() << "'\n"
                 << "reason: " << ErrorMsg << '\n';

      noDir = true;

      return;
    }
  }

  if (noDir)
    return;

  // Create a new rewriter to generate HTML.
  SourceManager& SMgr = D.begin()->getLocation().getManager();
  Rewriter R(SMgr);

  // Process the path.

  unsigned n = D.size();
  unsigned max = n;

  for (PathDiagnostic::const_reverse_iterator I=D.rbegin(), E=D.rend();
        I!=E; ++I, --n) {

    HandlePiece(R, *I, n, max);
  }

  // Add line numbers, header, footer, etc.

  unsigned FileID = R.getSourceMgr().getMainFileID();
  html::EscapeText(R, FileID);
  html::AddLineNumbers(R, FileID);

  // Get the full directory name of the analyzed file.

  const FileEntry* Entry = SMgr.getFileEntryForID(FileID);
  std::string DirName(Entry->getDir()->getName());

  if (DirName == ".")
    DirName = llvm::sys::Path::GetCurrentDirectory().toString();

  // Add the name of the file as an
 tag.

  {
    std::ostringstream os;

    os << "
" << html::EscapeText(DirName)
       << "/"    <getName()) << "
\n";

    R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
  }

  // Embed meta-data tags.

  const std::string& BugDesc = D.getDescription();

  if (!BugDesc.empty()) {
    std::ostringstream os;
    os << "\n\n";
    R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
  }

  {
    std::ostringstream os;
    os << "\n\n";
    R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
  }

  {
    std::ostringstream os;
    os << "\n\n";
    R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
  }

  {
    std::ostringstream os;
    os << "\n\n";
    R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
  }

  // Add CSS, header, and footer.

  html::AddHeaderFooterInternalBuiltinCSS(R, FileID);

  // Get the rewrite buffer.
  const RewriteBuffer *Buf = R.getRewriteBufferFor(FileID);

  if (!Buf) {
    llvm::cerr << "warning: no diagnostics generated for main file.\n";
    return;
  }

  // Create the stream to write out the HTML.
  std::ofstream os;

  {
    // Create a path for the target HTML file.
    llvm::sys::Path F(FilePrefix);
    F.makeUnique(false, NULL);

    // Rename the file with an HTML extension.
    llvm::sys::Path H(F);
    H.appendSuffix("html");
    F.renamePathOnDisk(H, NULL);

    os.open(H.toString().c_str());

    if (!os) {
      llvm::cerr << "warning: could not create file '" << F.toString() << "'\n";
      return;
    }
  }

  // Emit the HTML to disk.

  for (RewriteBuffer::iterator I = Buf->begin(), E = Buf->end(); I!=E; ++I) {
    // Expand tabs.
    if (*I == '\t')
      os << "   ";
    else
      os << *I;
  }
}

void HTMLDiagnostics::HandlePiece(Rewriter& R,
                                  const PathDiagnosticPiece& P,
                                  unsigned num, unsigned max) {

  // For now, just draw a box above the line in question, and emit the
  // warning.

  FullSourceLoc Pos = P.getLocation();

  if (!Pos.isValid())
    return;

  SourceManager& SM = R.getSourceMgr();
  FullSourceLoc LPos = Pos.getLogicalLoc();
  unsigned FileID = SM.getCanonicalFileID(LPos.getLocation());

  assert (&LPos.getManager() == &SM && "SourceManagers are different!");

  if (!SM.isFromMainFile(LPos.getLocation()))
    return;

  // Compute the column number.  Rewind from the current position to the start
  // of the line.

  unsigned ColNo = LPos.getColumnNumber();
  const char *TokLogicalPtr = LPos.getCharacterData();
  const char *LineStart = TokLogicalPtr-ColNo;

  // Compute the margin offset by counting tabs and non-tabs.

  unsigned PosNo = 0;

  for (const char* c = LineStart; c != TokLogicalPtr; ++c)
    PosNo += *c == '\t' ? 4 : 1;

  // Create the html for the message.

  std::ostringstream os;

  os << "\n
	"
     << "<div id=\"";

  if (num == max)
    os << "EndPath";
  else
    os << "Path" << num;

  os << "\" class=\"msg\" style=\"margin-left:"
     << PosNo << "ex\">";

  if (max > 1)
    os << "[" << num << "] ";

  os << html::EscapeText(P.getString()) << "

";

  // Insert the new html.

  const llvm::MemoryBuffer *Buf = SM.getBuffer(FileID);
  const char* FileStart = Buf->getBufferStart();

  R.InsertStrBefore(SourceLocation::getFileLoc(FileID, LineStart - FileStart),
                    os.str());

  // Now highlight the ranges.

  for (const SourceRange *I = P.ranges_begin(), *E = P.ranges_end();
        I != E; ++I)
    HighlightRange(R, *I);
}

void HTMLDiagnostics::HighlightRange(Rewriter& R, SourceRange Range) {

  SourceManager& SM = R.getSourceMgr();

  SourceLocation LogicalStart = SM.getLogicalLoc(Range.getBegin());
  unsigned StartLineNo = SM.getLineNumber(LogicalStart);

  SourceLocation LogicalEnd = SM.getLogicalLoc(Range.getEnd());
  unsigned EndLineNo = SM.getLineNumber(LogicalEnd);

  if (EndLineNo < StartLineNo)
    return;

  if (!SM.isFromMainFile(LogicalStart) ||
      !SM.isFromMainFile(LogicalEnd))
    return;

  // Compute the column number of the end.
  unsigned EndColNo = SM.getColumnNumber(LogicalEnd);
  unsigned OldEndColNo = EndColNo;

  if (EndColNo) {
    // Add in the length of the token, so that we cover multi-char tokens.
    EndColNo += Lexer::MeasureTokenLength(Range.getEnd(), SM);
  }

  // Highlight the range.  Make the span tag the outermost tag for the
  // selected range.

  SourceLocation E =
    LogicalEnd.getFileLocWithOffset(OldEndColNo > EndColNo
                                    ? -(OldEndColNo - EndColNo)
                                    : EndColNo - OldEndColNo);

  R.InsertCStrBefore(LogicalStart, "");
  R.InsertCStrAfter(E, "");

  if (EndLineNo == StartLineNo)
    return;

  // Add in  tags for intermediate lines.

  unsigned FileID = SM.getCanonicalFileID(LogicalStart);
  const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FileID);

  unsigned Pos = SM.getFullFilePos(LogicalStart);
  unsigned EndPos = SM.getFullFilePos(E);
  const char* buf = Buf->getBufferStart();

  for (; Pos != EndPos; ++Pos) {

    SourceLocation L = SourceLocation::getFileLoc(FileID, Pos);
    unsigned Col = SM.getColumnNumber(L);

    if (Col == 1) {

      // Start if a new line.  Scan to see if we hit anything that is not
      // whitespace or a newline.

      unsigned PosTmp = Pos;
      bool NewLine = false;

      for ( ; PosTmp != EndPos ; ++PosTmp) {
        switch (buf[PosTmp]) {
          case ' ':
          case '\t': continue;
          case '\n':
            NewLine = true;
            break;
          default:
            break;
        }

        break;
      }

      if (PosTmp == EndPos)
        break;

      Pos = PosTmp;

      // Don't highlight a blank line.
      if (NewLine)
        continue;

      // This line contains text that we should highlight.
      // Ignore leading whitespace.
      L = SourceLocation::getFileLoc(FileID, Pos);
      R.InsertCStrAfter(L, "");
    }
    else if (buf[Pos] == '\n')
      R.InsertCStrBefore(L, "");
  }
}
<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip>

int main(int argc, char *argv[])
{
    std::cout << "     |";
    for (int x = 1; x<=12; ++x)
    {
        std:: cout <<std::setw(5)<< x <<"|";

    }
    std:: cout <<std::endl;

    for(int x = 0; x<=12; ++x)
    {
        std::cout << "-----+";
    }
    std::cout << std::endl;

    for(int y = 1; y<=12; ++y)
    {
        std::cout<<std::setw(5)<< y << "|";

        for (int x=1; x<=12; ++x)
        {
            std::cout<<std::setw(5)<<x*y << "|";
        }
        std::cout<< std::endl;

        for(int x =0; x<=12; ++x)
        {
            std::cout << "-----+";
        }
        std::cout <<std::endl;
    }

}
<commit_msg>created Header comment. closes #83<commit_after>/*
 * Xtable - Program that calculates a multiplication table from 1 t0 12.
 *
 * Author- Moses Olawoyin < m.bastford@gmail.com>
 *
 * Date -15 March 2015.
 *
 */

#include <iostream>
#include <iomanip>

int main(int argc, char *argv[])
{
    std::cout << "     |";
    for (int x = 1; x<=12; ++x)
    {
        std:: cout <<std::setw(5)<< x <<"|";

    }
    std:: cout <<std::endl;

    for(int x = 0; x<=12; ++x)
    {
        std::cout << "-----+";
    }
    std::cout << std::endl;

    for(int y = 1; y<=12; ++y)
    {
        std::cout<<std::setw(5)<< y << "|";

        for (int x=1; x<=12; ++x)
        {
            std::cout<<std::setw(5)<<x*y << "|";
        }
        std::cout<< std::endl;

        for(int x =0; x<=12; ++x)
        {
            std::cout << "-----+";
        }
        std::cout <<std::endl;
    }

}
<|endoftext|>


<commit_before>#pragma once

#include "internal/opengl.hpp"
#include "color.hpp"
#include "managed_texture.hpp"
#include "../geometry/point2d.hpp"
#include "../geometry/rect2d.hpp"
#include "../std/vector.hpp"
#include "../3party/boost/boost/gil/gil_all.hpp"
#include "../3party/boost/boost/mpl/vector_c.hpp"
#include "../platform/platform.hpp"
#include "../coding/lodepng_io.hpp"
#include "../std/iostream.hpp"

namespace gil = boost::gil;
namespace mpl = boost::mpl;

namespace yg
{
  namespace gl
  {
    template <unsigned Denom>
    struct DownsampleImpl
    {
      template <typename Ch1, typename Ch2>
      void operator()(Ch1 const & ch1, Ch2 & ch2) const
      {
        ch2 = ch1 / Denom;
      }
    };

    template <unsigned FromBig, unsigned ToSmall>
    struct Downsample
    {
      static const int Denom = 1 << (FromBig - ToSmall);

      template <typename SrcP, typename DstP>
      void operator()(SrcP const & src, DstP & dst) const
      {
        static_for_each(src, dst, DownsampleImpl<Denom>());
      }
    };

    struct RGBA8Traits
    {
      typedef gil::rgba8_pixel_t pixel_t;
      typedef gil::rgba8c_pixel_t const_pixel_t;
      typedef gil::rgba8_view_t view_t;
      typedef gil::rgba8c_view_t const_view_t;
      typedef gil::rgba8_image_t image_t;

      static const int maxChannelVal = 255;

      static const int gl_pixel_data_type = GL_UNSIGNED_BYTE;

      typedef Downsample<8, 8> color_converter;
    };

    struct RGBA4Traits
    {
      typedef gil::packed_pixel_type<
          unsigned short,
          mpl::vector4_c<unsigned, 4, 4, 4, 4>,
          gil::abgr_layout_t
      >::type pixel_t;

      typedef gil::memory_based_step_iterator<pixel_t*> iterator_t;
      typedef gil::memory_based_2d_locator<iterator_t> locator_t;
      typedef gil::image_view<locator_t> view_t;

      typedef pixel_t const const_pixel_t;

      typedef gil::memory_based_step_iterator<pixel_t const *> const_iterator_t;
      typedef gil::memory_based_2d_locator<const_iterator_t> const_locator_t;
      typedef gil::image_view<const_locator_t> const_view_t;

      typedef gil::image<pixel_t, false> image_t;

      static const int maxChannelVal = 15;

      static const int gl_pixel_data_type = GL_UNSIGNED_SHORT_4_4_4_4;

      typedef Downsample<8, 4> color_converter;
    };

    template <typename Traits, bool IsBacked>
    class Texture{};

    inline m2::PointU const GetDimensions(string const & fileName)
    {
      gil::point2<ptrdiff_t> size = gil::lodepng_read_dimensions(GetPlatform().ResourcesDir() + fileName);
      return m2::PointU(size.x, size.y);
    }

    template <typename Traits>
    class Texture<Traits, false> : public BaseTexture
    {
    private:

      void upload(void * data)
      {
        makeCurrent();

        OGLCHECK(glTexImage2D(
          GL_TEXTURE_2D,
          0,
          GL_RGBA,
          width(),
          height(),
          0,
          GL_RGBA,
          Traits::gl_pixel_data_type,
          data));
      }

    public:

      Texture(string const & fileName) : BaseTexture(GetDimensions(fileName))
      {
        typename Traits::image_t image(width(), height());
        gil::lodepng_read_and_convert_image((GetPlatform().ResourcesDir() + fileName).c_str(), image, typename Traits::color_converter());
        upload(&gil::view(image)(0, 0));
      }

      Texture(unsigned width, unsigned height)
        : BaseTexture(width, height)
      {
        upload(0);
      }

      void dump(char const *){}
    };

    template <typename Traits>
    class Texture<Traits, true> : public ManagedTexture
    {
    public:

      typedef typename Traits::pixel_t pixel_t;
      typedef typename Traits::const_pixel_t const_pixel_t;
      typedef typename Traits::view_t view_t;
      typedef typename Traits::const_view_t const_view_t;
      typedef typename Traits::image_t image_t;

      static const int maxChannelVal = Traits::maxChannelVal;
      static const int gl_pixel_data_type = Traits::gl_pixel_data_type;

    private:

      /// system memory copy of texture data
      image_t m_image;
      /// system memory buffer for the purpose of correct working of glTexSubImage2D.
      /// in OpenGL ES 1.1 there are no way to specify GL_UNPACK_ROW_LENGTH so
      /// the data supplied to glTexSubImage2D should be continous.
      vector<pixel_t> m_auxData;

      void upload();
      void updateDirty(m2::RectU const & r);

    public:

      /// Create the texture loading it from file
      Texture(string const & fileName);
      /// Create the texture with the predefined dimensions
      Texture(size_t width, size_t height);
      Texture(m2::RectU const & r);

      /// You can call this anytime, regardless the locking status of the texture.
      const_view_t const_view() const;
      /// You can call this on locked texture only. All your changess to this view's data will be
      /// uploaded to the video memory on unlock()
      view_t view();

      void fill(yg::Color const & c);

      /// dump the texture into the file.
      void dump(char const * fileName);
      /// videomem -> sysmem texture image transfer.
      /// @warning could be very slow. use with caution.
      void readback();

      void randomize();
    };

    typedef Texture<RGBA8Traits, true> RGBA8Texture;
    typedef Texture<RGBA4Traits, true> RGBA4Texture;

    typedef Texture<RGBA8Traits, false> RawRGBA8Texture;
    typedef Texture<RGBA4Traits, false> RawRGBA4Texture;

    template <typename Traits>
    Texture<Traits, true>::Texture(const m2::RectU &r)
      : ManagedTexture(r.SizeX(), r.SizeY()), m_image(r.SizeX(), r.SizeY())
    {
      upload();
      m_auxData.resize(width * height);
    }

    template <typename Traits>
    Texture<Traits, true>::Texture(size_t width, size_t height)
      : ManagedTexture(width, height), m_image(width, height)
    {
      upload();
      m_auxData.resize(width * height);
    }

    template <typename Traits>
    Texture<Traits, true>::Texture(string const & fileName) : ManagedTexture(GetDimensions(fileName))
    {
      lock();
      gil::lodepng_read_and_convert_image(GetPlatform().ReadPathForFile(fileName).c_str(), m_image, typename Traits::color_converter());
      unlock();
      upload();
      m_image.recreate(0, 0);
    }

    template <typename Traits>
    typename Texture<Traits, true>::view_t Texture<Traits, true>::view()
    {
      ASSERT(m_isLocked, ("non const access to unlocked texture!"));
      return gil::view(m_image);
    }

    template <typename Traits>
    typename Texture<Traits, true>::const_view_t Texture<Traits, true>::const_view() const
    {
      return gil::const_view(m_image);
    }

    template <typename Traits>
    void Texture<Traits, true>::upload()
    {
      makeCurrent();

      OGLCHECK(glTexImage2D(
         GL_TEXTURE_2D,
         0,
         GL_RGBA,
         width(),
         height(),
         0,
         GL_RGBA,
         Traits::gl_pixel_data_type,
         &gil::const_view(m_image)(0, 0)));
    }

    template <typename Traits>
    void Texture<Traits, true>::updateDirty(m2::RectU const & r)
    {
      makeCurrent();

//      m_auxData.resize(r.SizeX() * r.SizeY());

      view_t auxView = gil::interleaved_view(
          r.SizeX(), r.SizeY(),
          (pixel_t*)&m_auxData[0],
          r.SizeX() * sizeof(pixel_t));

      gil::copy_pixels(
          gil::subimage_view(gil::const_view(m_image),
                             r.minX(), r.minY(),
                             r.SizeX(), r.SizeY()),
          auxView);

      OGLCHECK(glTexSubImage2D(
          GL_TEXTURE_2D,
          0,
          r.minX(),
          r.minY(),
          r.SizeX(),
          r.SizeY(),
          GL_RGBA,
          Traits::gl_pixel_data_type,
          &m_auxData[0]
      ));
    }

    template <typename Traits>
    void Texture<Traits, true>::randomize()
    {
      makeCurrent();
      lock();
      view_t v = view();

      for (size_t y = 0; y < height(); ++y)
        for (size_t x = 0; x < width(); ++x)
          v(x, y) = pixel_t(rand() % maxChannelVal, rand() % maxChannelVal, rand() % maxChannelVal, maxChannelVal);

      addDirtyRect(m2::RectU(0, 0, width(), height()));

      unlock();
    }

    template <typename Traits>
    void Texture<Traits, true>::readback()
    {
      makeCurrent();
#ifndef OMIM_GL_ES
      OGLCHECK(glGetTexImage(
          GL_TEXTURE_2D,
          0,
          GL_RGBA,
          Traits::gl_pixel_data_type,
          &gil::view(m_image)(0, 0)));
#else
          ASSERT(false, ("no glGetTexImage function in OpenGL ES"));
#endif
    }

    template <typename Traits>
    void Texture<Traits, true>::dump(char const * fileName)
    {
      readback();
      std::string const fullPath = GetPlatform().WritablePathForFile(fileName);
#ifndef OMIM_GL_ES
      boost::gil::lodepng_write_view(fullPath, gil::const_view(m_image));
#endif
    }

    template <typename Traits>
    void Texture<Traits, true>::fill(yg::Color const & c)
    {
      makeCurrent();
      lock();
      view_t v = view();

      pixel_t val((c.r / 255.0f) * maxChannelVal,
                  (c.g / 255.0f) * maxChannelVal,
                  (c.b / 255.0f) * maxChannelVal,
                  (c.a / 255.0f) * maxChannelVal);

      for (size_t y = 0; y < height(); ++y)
        for (size_t x = 0; x < width(); ++x)
          v(x, y) = val;

      addDirtyRect(m2::RectU(0, 0, width(), height()));
      unlock();
    }
  }
}
<commit_msg>Fixed merge build errors<commit_after>#pragma once

#include "internal/opengl.hpp"
#include "color.hpp"
#include "managed_texture.hpp"
#include "../geometry/point2d.hpp"
#include "../geometry/rect2d.hpp"
#include "../std/vector.hpp"
#include "../3party/boost/boost/gil/gil_all.hpp"
#include "../3party/boost/boost/mpl/vector_c.hpp"
#include "../platform/platform.hpp"
#include "../coding/lodepng_io.hpp"
#include "../std/iostream.hpp"

namespace gil = boost::gil;
namespace mpl = boost::mpl;

namespace yg
{
  namespace gl
  {
    template <unsigned Denom>
    struct DownsampleImpl
    {
      template <typename Ch1, typename Ch2>
      void operator()(Ch1 const & ch1, Ch2 & ch2) const
      {
        ch2 = ch1 / Denom;
      }
    };

    template <unsigned FromBig, unsigned ToSmall>
    struct Downsample
    {
      static const int Denom = 1 << (FromBig - ToSmall);

      template <typename SrcP, typename DstP>
      void operator()(SrcP const & src, DstP & dst) const
      {
        static_for_each(src, dst, DownsampleImpl<Denom>());
      }
    };

    struct RGBA8Traits
    {
      typedef gil::rgba8_pixel_t pixel_t;
      typedef gil::rgba8c_pixel_t const_pixel_t;
      typedef gil::rgba8_view_t view_t;
      typedef gil::rgba8c_view_t const_view_t;
      typedef gil::rgba8_image_t image_t;

      static const int maxChannelVal = 255;

      static const int gl_pixel_data_type = GL_UNSIGNED_BYTE;

      typedef Downsample<8, 8> color_converter;
    };

    struct RGBA4Traits
    {
      typedef gil::packed_pixel_type<
          unsigned short,
          mpl::vector4_c<unsigned, 4, 4, 4, 4>,
          gil::abgr_layout_t
      >::type pixel_t;

      typedef gil::memory_based_step_iterator<pixel_t*> iterator_t;
      typedef gil::memory_based_2d_locator<iterator_t> locator_t;
      typedef gil::image_view<locator_t> view_t;

      typedef pixel_t const const_pixel_t;

      typedef gil::memory_based_step_iterator<pixel_t const *> const_iterator_t;
      typedef gil::memory_based_2d_locator<const_iterator_t> const_locator_t;
      typedef gil::image_view<const_locator_t> const_view_t;

      typedef gil::image<pixel_t, false> image_t;

      static const int maxChannelVal = 15;

      static const int gl_pixel_data_type = GL_UNSIGNED_SHORT_4_4_4_4;

      typedef Downsample<8, 4> color_converter;
    };

    template <typename Traits, bool IsBacked>
    class Texture{};

    inline m2::PointU const GetDimensions(string const & fileName)
    {
      gil::point2<ptrdiff_t> size = gil::lodepng_read_dimensions(GetPlatform().ReadPathForFile(fileName));
      return m2::PointU(size.x, size.y);
    }

    template <typename Traits>
    class Texture<Traits, false> : public BaseTexture
    {
    private:

      void upload(void * data)
      {
        makeCurrent();

        OGLCHECK(glTexImage2D(
          GL_TEXTURE_2D,
          0,
          GL_RGBA,
          width(),
          height(),
          0,
          GL_RGBA,
          Traits::gl_pixel_data_type,
          data));
      }

    public:

      Texture(string const & fileName) : BaseTexture(GetDimensions(fileName))
      {
        typename Traits::image_t image(width(), height());
        gil::lodepng_read_and_convert_image(GetPlatform().ReadPathForFile(fileName), image, typename Traits::color_converter());
        upload(&gil::view(image)(0, 0));
      }

      Texture(unsigned width, unsigned height)
        : BaseTexture(width, height)
      {
        upload(0);
      }

      void dump(char const *){}
    };

    template <typename Traits>
    class Texture<Traits, true> : public ManagedTexture
    {
    public:

      typedef typename Traits::pixel_t pixel_t;
      typedef typename Traits::const_pixel_t const_pixel_t;
      typedef typename Traits::view_t view_t;
      typedef typename Traits::const_view_t const_view_t;
      typedef typename Traits::image_t image_t;

      static const int maxChannelVal = Traits::maxChannelVal;
      static const int gl_pixel_data_type = Traits::gl_pixel_data_type;

    private:

      /// system memory copy of texture data
      image_t m_image;
      /// system memory buffer for the purpose of correct working of glTexSubImage2D.
      /// in OpenGL ES 1.1 there are no way to specify GL_UNPACK_ROW_LENGTH so
      /// the data supplied to glTexSubImage2D should be continous.
      vector<pixel_t> m_auxData;

      void upload();
      void updateDirty(m2::RectU const & r);

    public:

      /// Create the texture loading it from file
      Texture(string const & fileName);
      /// Create the texture with the predefined dimensions
      Texture(size_t width, size_t height);
      Texture(m2::RectU const & r);

      /// You can call this anytime, regardless the locking status of the texture.
      const_view_t const_view() const;
      /// You can call this on locked texture only. All your changess to this view's data will be
      /// uploaded to the video memory on unlock()
      view_t view();

      void fill(yg::Color const & c);

      /// dump the texture into the file.
      void dump(char const * fileName);
      /// videomem -> sysmem texture image transfer.
      /// @warning could be very slow. use with caution.
      void readback();

      void randomize();
    };

    typedef Texture<RGBA8Traits, true> RGBA8Texture;
    typedef Texture<RGBA4Traits, true> RGBA4Texture;

    typedef Texture<RGBA8Traits, false> RawRGBA8Texture;
    typedef Texture<RGBA4Traits, false> RawRGBA4Texture;

    template <typename Traits>
    Texture<Traits, true>::Texture(const m2::RectU &r)
      : ManagedTexture(r.SizeX(), r.SizeY()), m_image(r.SizeX(), r.SizeY())
    {
      upload();
      m_auxData.resize(width * height);
    }

    template <typename Traits>
    Texture<Traits, true>::Texture(size_t width, size_t height)
      : ManagedTexture(width, height), m_image(width, height)
    {
      upload();
      m_auxData.resize(width * height);
    }

    template <typename Traits>
    Texture<Traits, true>::Texture(string const & fileName) : ManagedTexture(GetDimensions(fileName))
    {
      lock();
      gil::lodepng_read_and_convert_image(GetPlatform().ReadPathForFile(fileName).c_str(), m_image, typename Traits::color_converter());
      unlock();
      upload();
      m_image.recreate(0, 0);
    }

    template <typename Traits>
    typename Texture<Traits, true>::view_t Texture<Traits, true>::view()
    {
      ASSERT(m_isLocked, ("non const access to unlocked texture!"));
      return gil::view(m_image);
    }

    template <typename Traits>
    typename Texture<Traits, true>::const_view_t Texture<Traits, true>::const_view() const
    {
      return gil::const_view(m_image);
    }

    template <typename Traits>
    void Texture<Traits, true>::upload()
    {
      makeCurrent();

      OGLCHECK(glTexImage2D(
         GL_TEXTURE_2D,
         0,
         GL_RGBA,
         width(),
         height(),
         0,
         GL_RGBA,
         Traits::gl_pixel_data_type,
         &gil::const_view(m_image)(0, 0)));
    }

    template <typename Traits>
    void Texture<Traits, true>::updateDirty(m2::RectU const & r)
    {
      makeCurrent();

//      m_auxData.resize(r.SizeX() * r.SizeY());

      view_t auxView = gil::interleaved_view(
          r.SizeX(), r.SizeY(),
          (pixel_t*)&m_auxData[0],
          r.SizeX() * sizeof(pixel_t));

      gil::copy_pixels(
          gil::subimage_view(gil::const_view(m_image),
                             r.minX(), r.minY(),
                             r.SizeX(), r.SizeY()),
          auxView);

      OGLCHECK(glTexSubImage2D(
          GL_TEXTURE_2D,
          0,
          r.minX(),
          r.minY(),
          r.SizeX(),
          r.SizeY(),
          GL_RGBA,
          Traits::gl_pixel_data_type,
          &m_auxData[0]
      ));
    }

    template <typename Traits>
    void Texture<Traits, true>::randomize()
    {
      makeCurrent();
      lock();
      view_t v = view();

      for (size_t y = 0; y < height(); ++y)
        for (size_t x = 0; x < width(); ++x)
          v(x, y) = pixel_t(rand() % maxChannelVal, rand() % maxChannelVal, rand() % maxChannelVal, maxChannelVal);

      addDirtyRect(m2::RectU(0, 0, width(), height()));

      unlock();
    }

    template <typename Traits>
    void Texture<Traits, true>::readback()
    {
      makeCurrent();
#ifndef OMIM_GL_ES
      OGLCHECK(glGetTexImage(
          GL_TEXTURE_2D,
          0,
          GL_RGBA,
          Traits::gl_pixel_data_type,
          &gil::view(m_image)(0, 0)));
#else
          ASSERT(false, ("no glGetTexImage function in OpenGL ES"));
#endif
    }

    template <typename Traits>
    void Texture<Traits, true>::dump(char const * fileName)
    {
      readback();
      std::string const fullPath = GetPlatform().WritablePathForFile(fileName);
#ifndef OMIM_GL_ES
      boost::gil::lodepng_write_view(fullPath, gil::const_view(m_image));
#endif
    }

    template <typename Traits>
    void Texture<Traits, true>::fill(yg::Color const & c)
    {
      makeCurrent();
      lock();
      view_t v = view();

      pixel_t val((c.r / 255.0f) * maxChannelVal,
                  (c.g / 255.0f) * maxChannelVal,
                  (c.b / 255.0f) * maxChannelVal,
                  (c.a / 255.0f) * maxChannelVal);

      for (size_t y = 0; y < height(); ++y)
        for (size_t x = 0; x < width(); ++x)
          v(x, y) = val;

      addDirtyRect(m2::RectU(0, 0, width(), height()));
      unlock();
    }
  }
}
<|endoftext|>


<commit_before>/**
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>
#include <string.h>

#include <string>
#include <vector>

#include <gtest/gtest.h>

#include <stout/flags.hpp>
#include <stout/foreach.hpp>
#include <stout/subcommand.hpp>

using std::string;
using std::vector;

class TestSubcommand : public Subcommand
{
public:
  struct Flags : public flags::FlagsBase
  {
    Flags()
    {
      add(&b, "b", "bool");
      add(&i, "i", "int");
      add(&s, "s", "string");
      add(&s2, "s2", "string with single quote");
      add(&s3, "s3", "string with double quote");
      add(&d, "d", "Duration");
      add(&y, "y", "Bytes");
      add(&j, "j", "JSON::Object");
    }

    void populate()
    {
      b = true;
      i = 42;
      s = "hello";
      s2 = "we're";
      s3 = "\"geek\"";
      d = Seconds(10);
      y = Bytes(100);

      JSON::Object object;
      object.values["strings"] = "string";
      object.values["integer1"] = 1;
      object.values["integer2"] = -1;
      object.values["double1"] = 1;
      object.values["double2"] = -1;
      object.values["double3"] = -1.42;

      JSON::Object nested;
      nested.values["string"] = "string";
      object.values["nested"] = nested;

      JSON::Array array;
      array.values.push_back(nested);
      object.values["array"] = array;

      j = object;
    }

    Option<bool> b;
    Option<int> i;
    Option<string> s;
    Option<string> s2;
    Option<string> s3;
    Option<Duration> d;
    Option<Bytes> y;
    Option<JSON::Object> j;
  };

  explicit TestSubcommand(const string& name) : Subcommand(name) {}

  Flags flags;

protected:
  virtual int execute() { return 0; }
  virtual flags::FlagsBase* getFlags() { return &flags; }
};

// Generates a vector of arguments from flags.
static vector<string> getArgv(const flags::FlagsBase& flags)
{
  vector<string> argv;
  foreachpair (const string& name, const flags::Flag& flag, flags) {
    Option<string> value = flag.stringify(flags);
    if (value.isSome()) {
      argv.push_back("--" + name + "=" + value.get());
    }
  }
  return argv;
}

TEST(SubcommandTest, Flags)
{
  TestSubcommand::Flags flags;
  flags.populate();

  // Construct the command line arguments.
  vector<string> _argv = getArgv(flags);
  int argc = _argv.size() + 2;
  char** argv = new char*[argc];
  argv[0] = (char*) "command";
  argv[1] = (char*) "subcommand";
  for (int i = 2; i < argc; i++) {
    argv[i] = ::strdup(_argv[i - 2].c_str());
  }

  TestSubcommand subcommand("subcommand");

  ASSERT_EQ(0, Subcommand::dispatch(
      None(),
      argc,
      argv,
      &subcommand));

  EXPECT_EQ(flags.b, subcommand.flags.b);
  EXPECT_EQ(flags.i, subcommand.flags.i);
  EXPECT_EQ(flags.s, subcommand.flags.s);
  EXPECT_EQ(flags.s2, subcommand.flags.s2);
  EXPECT_EQ(flags.s3, subcommand.flags.s3);
  EXPECT_EQ(flags.d, subcommand.flags.d);
  EXPECT_EQ(flags.y, subcommand.flags.y);
  EXPECT_EQ(flags.j, subcommand.flags.j);

  for (int i = 2; i < argc; i++) {
    ::free(argv[i]);
  }
  delete argv;
}

TEST(SubcommandTest, Dispatch)
{
  TestSubcommand subcommand("subcommand");
  TestSubcommand subcommand2("subcommand2");

  int argc = 2;
  char* argv[] = {
    (char*) "command",
    (char*) "subcommand"
  };

  EXPECT_EQ(1, Subcommand::dispatch(
      None(),
      argc,
      argv,
      &subcommand2));

  // Duplicated subcommand names.
  EXPECT_EQ(1, Subcommand::dispatch(
      None(),
      argc,
      argv,
      &subcommand,
      &subcommand));

  EXPECT_EQ(0, Subcommand::dispatch(
      None(),
      argc,
      argv,
      &subcommand,
      &subcommand2));
}
<commit_msg>Fixed a bad delete call.<commit_after>/**
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>
#include <string.h>

#include <string>
#include <vector>

#include <gtest/gtest.h>

#include <stout/flags.hpp>
#include <stout/foreach.hpp>
#include <stout/subcommand.hpp>

using std::string;
using std::vector;

class TestSubcommand : public Subcommand
{
public:
  struct Flags : public flags::FlagsBase
  {
    Flags()
    {
      add(&b, "b", "bool");
      add(&i, "i", "int");
      add(&s, "s", "string");
      add(&s2, "s2", "string with single quote");
      add(&s3, "s3", "string with double quote");
      add(&d, "d", "Duration");
      add(&y, "y", "Bytes");
      add(&j, "j", "JSON::Object");
    }

    void populate()
    {
      b = true;
      i = 42;
      s = "hello";
      s2 = "we're";
      s3 = "\"geek\"";
      d = Seconds(10);
      y = Bytes(100);

      JSON::Object object;
      object.values["strings"] = "string";
      object.values["integer1"] = 1;
      object.values["integer2"] = -1;
      object.values["double1"] = 1;
      object.values["double2"] = -1;
      object.values["double3"] = -1.42;

      JSON::Object nested;
      nested.values["string"] = "string";
      object.values["nested"] = nested;

      JSON::Array array;
      array.values.push_back(nested);
      object.values["array"] = array;

      j = object;
    }

    Option<bool> b;
    Option<int> i;
    Option<string> s;
    Option<string> s2;
    Option<string> s3;
    Option<Duration> d;
    Option<Bytes> y;
    Option<JSON::Object> j;
  };

  explicit TestSubcommand(const string& name) : Subcommand(name) {}

  Flags flags;

protected:
  virtual int execute() { return 0; }
  virtual flags::FlagsBase* getFlags() { return &flags; }
};

// Generates a vector of arguments from flags.
static vector<string> getArgv(const flags::FlagsBase& flags)
{
  vector<string> argv;
  foreachpair (const string& name, const flags::Flag& flag, flags) {
    Option<string> value = flag.stringify(flags);
    if (value.isSome()) {
      argv.push_back("--" + name + "=" + value.get());
    }
  }
  return argv;
}

TEST(SubcommandTest, Flags)
{
  TestSubcommand::Flags flags;
  flags.populate();

  // Construct the command line arguments.
  vector<string> _argv = getArgv(flags);
  int argc = _argv.size() + 2;
  char** argv = new char*[argc];
  argv[0] = (char*) "command";
  argv[1] = (char*) "subcommand";
  for (int i = 2; i < argc; i++) {
    argv[i] = ::strdup(_argv[i - 2].c_str());
  }

  TestSubcommand subcommand("subcommand");

  ASSERT_EQ(0, Subcommand::dispatch(
      None(),
      argc,
      argv,
      &subcommand));

  EXPECT_EQ(flags.b, subcommand.flags.b);
  EXPECT_EQ(flags.i, subcommand.flags.i);
  EXPECT_EQ(flags.s, subcommand.flags.s);
  EXPECT_EQ(flags.s2, subcommand.flags.s2);
  EXPECT_EQ(flags.s3, subcommand.flags.s3);
  EXPECT_EQ(flags.d, subcommand.flags.d);
  EXPECT_EQ(flags.y, subcommand.flags.y);
  EXPECT_EQ(flags.j, subcommand.flags.j);

  for (int i = 2; i < argc; i++) {
    ::free(argv[i]);
  }
  delete[] argv;
}

TEST(SubcommandTest, Dispatch)
{
  TestSubcommand subcommand("subcommand");
  TestSubcommand subcommand2("subcommand2");

  int argc = 2;
  char* argv[] = {
    (char*) "command",
    (char*) "subcommand"
  };

  EXPECT_EQ(1, Subcommand::dispatch(
      None(),
      argc,
      argv,
      &subcommand2));

  // Duplicated subcommand names.
  EXPECT_EQ(1, Subcommand::dispatch(
      None(),
      argc,
      argv,
      &subcommand,
      &subcommand));

  EXPECT_EQ(0, Subcommand::dispatch(
      None(),
      argc,
      argv,
      &subcommand,
      &subcommand2));
}
<|endoftext|>


<commit_before>
#include "Lbl.h"

namespace XLS
{

const wchar_t* const AutoFilterDefineNames[] =
{
    L"_FilterDatabase",			// English
    L"_FilterDatenbank",		// German
    L"_"		// Russian

};

Lbl::Lbl()
:	rgce(false)
{
}

Lbl::~Lbl()
{
}

BaseObjectPtr Lbl::clone()
{
	return BaseObjectPtr(new Lbl(*this));
}

void Lbl::writeFields(CFRecord& record)
{
	unsigned short flags = 0;
	SETBIT(flags, 0, fHidden);
	SETBIT(flags, 1, fFunc);
	SETBIT(flags, 2, fOB);
	SETBIT(flags, 3, fProc);
	SETBIT(flags, 4, fCalcExp);
	SETBIT(flags, 5, fBuiltin);
	SETBITS(flags, 6, 11, fGrp);
	SETBIT(flags, 13, fPublished);
	SETBIT(flags, 14, fWorkbookParam);

	record << flags << chKey;
	unsigned char cch = static_cast<std::wstring >(Name).length();
	record << cch;
	record.registerDelayedDataReceiver(NULL, sizeof(unsigned short)/*cce*/);
	record.reserveNunBytes(2);
	record << itab;
	record.reserveNunBytes(4);

	if(!fBuiltin)
	{
		Name_bin = Name;
		record << Name_bin;
	}
	else
	{
		//Name_bin.setSize(1); // this is to process built-in string values

		// fix
		Name_bin.setSize(cch); // this is to process built-in string values

		unsigned char index;
		if(Name == std::wstring (L"_xlnm.Consolidate_Area"))
		{
			index = 0;
		}
		else if(Name == std::wstring (L"_xlnm.Auto_Open"))
		{
			index = 1;
		}
		else if(Name == std::wstring (L"_xlnm.Auto_Close"))
		{
			index = 2;
		}
		else if(Name == std::wstring (L"_xlnm.Extract"))
		{
			index = 3;
		}
		else if(Name == std::wstring (L"_xlnm.Database"))
		{
			index = 4;
		}
		else if(Name == std::wstring (L"_xlnm.Criteria"))
		{
			index = 5;
		}
		else if(Name == std::wstring (L"_xlnm.Print_Area"))
		{
			index = 6;
		}
		else if(Name == std::wstring (L"_xlnm.Print_Titles"))
		{
			index = 7;
		}
		else if(Name == std::wstring (L"_xlnm.Recorder"))
		{
			index = 8;
		}
		else if(Name == std::wstring (L"_xlnm.Data_Form"))
		{
			index = 9;
		}
		else if(Name == std::wstring (L"_xlnm.Auto_Activate"))
		{
			index = 10;
		}
		else if(Name == std::wstring (L"_xlnm.Auto_Deactivate"))
		{
			index = 11;
		}
		else if(Name == std::wstring (L"_xlnm.Sheet_Title"))
		{
			index = 12;
		}
		else if(Name == std::wstring (L"_xlnm._FilterDatabase"))
		{
			index = 13;
		}
		else
		{
			throw;// EXCEPT::RT::WrongBiffRecord(L"Unsupported value of built-in name.", record.getTypeString());
		}

		// fix
		Name_bin = Name;
		(static_cast<std::wstring>(Name_bin)).at(0) = index;
		record << Name_bin;

	}
	rgce.store(record);
	record.registerDelayedDataSource(rgce.getCCE(), rt_Lbl);
}

void Lbl::readFields(CFRecord& record)
{
	unsigned short flags;
	record >> flags >> chKey;

	fHidden			= GETBIT(flags, 0);
	fFunc			= GETBIT(flags, 1);
	fOB				= GETBIT(flags, 2);
	fProc			= GETBIT(flags, 3);
	fCalcExp		= GETBIT(flags, 4);
	fBuiltin		= GETBIT(flags, 5);
	fGrp			= GETBITS(flags, 6, 11);
	fPublished		= GETBIT(flags, 13);
	fWorkbookParam	= GETBIT(flags, 14);

	unsigned char cch;
	unsigned short cce;
	record >> cch >> cce;
	record.skipNunBytes(2);
	record >> itab;

	record.skipNunBytes(4);

	if (record.getGlobalWorkbookInfo()->Version < 0x600)
	{
		LPAnsiStringNoCch s;
		s.setSize(cch);
		record >> s;
		Name_bin = s;
	}
	else
	{
		Name_bin.setSize(cch); // this is to process built-in string values
		record >> Name_bin;
	}

	rgce.load(record, cce);

	if(!fBuiltin)
	{
		Name = Name_bin.getEscaped_ST_Xstring();

		for (int i = 0 ; i < 3; i++)
		{
			int res = Name_bin.value().find(AutoFilterDefineNames[i]);
			if (res >=0)
			{
				Name = Name_bin = (L"_xlnm._FilterDatabase");
				break;
			}
		}
	}
	else
	{
		unsigned char index = (static_cast<std::wstring>(Name_bin)).c_str()[0];
		switch(index)
		{
			case 0x00:
				Name =  (L"_xlnm.Consolidate_Area");
				break;
			case 0x01:
				Name =  (L"_xlnm.Auto_Open");
				break;
			case 0x02:
				Name =  (L"_xlnm.Auto_Close");
				break;
			case 0x03:
				Name =  (L"_xlnm.Extract");
				break;
			case 0x04:
				Name =  (L"_xlnm.Database");
				break;
			case 0x05:
				Name =  (L"_xlnm.Criteria");
				break;
			case 0x06:
				Name =  (L"_xlnm.Print_Area");
				break;
			case 0x07:
				Name =  (L"_xlnm.Print_Titles");
				break;
			case 0x08:
				Name =  (L"_xlnm.Recorder");
				break;
			case 0x09:
				Name =  (L"_xlnm.Data_Form");
				break;
			case 0x0A:
				Name =  (L"_xlnm.Auto_Activate");
				break;
			case 0x0B:
				Name =  (L"_xlnm.Auto_Deactivate");
				break;
			case 0x0C:
				Name =  (L"_xlnm.Sheet_Title");
				break;
			case 0x0D:
				Name =  (L"_xlnm._FilterDatabase");
				break;
			default:
				throw;// EXCEPT::RT::WrongBiffRecord(L"Unsupported value of built-in name.", record.getTypeString());
		}
	}
}

const XLUnicodeStringNoCch Lbl::getName() const
{
	return Name_bin;
}

} // namespace XLS

<commit_msg>XlsFormat - файл переписан в кодировке utf8<commit_after>
#include "Lbl.h"

namespace XLS
{

const wchar_t* const AutoFilterDefineNames[] =
{
    L"_FilterDatabase",			// English
    L"_FilterDatenbank",		// German
    L"_ФильтрБазыДанных"		// Russian

};

Lbl::Lbl()
:	rgce(false)
{
}

Lbl::~Lbl()
{
}

BaseObjectPtr Lbl::clone()
{
	return BaseObjectPtr(new Lbl(*this));
}

void Lbl::writeFields(CFRecord& record)
{
	unsigned short flags = 0;
	SETBIT(flags, 0, fHidden);
	SETBIT(flags, 1, fFunc);
	SETBIT(flags, 2, fOB);
	SETBIT(flags, 3, fProc);
	SETBIT(flags, 4, fCalcExp);
	SETBIT(flags, 5, fBuiltin);
	SETBITS(flags, 6, 11, fGrp);
	SETBIT(flags, 13, fPublished);
	SETBIT(flags, 14, fWorkbookParam);

	record << flags << chKey;
	unsigned char cch = static_cast<std::wstring >(Name).length();
	record << cch;
	record.registerDelayedDataReceiver(NULL, sizeof(unsigned short)/*cce*/);
	record.reserveNunBytes(2);
	record << itab;
	record.reserveNunBytes(4);

	if(!fBuiltin)
	{
		Name_bin = Name;
		record << Name_bin;
	}
	else
	{
		//Name_bin.setSize(1); // this is to process built-in string values

		// fix
		Name_bin.setSize(cch); // this is to process built-in string values

		unsigned char index;
		if(Name == std::wstring (L"_xlnm.Consolidate_Area"))
		{
			index = 0;
		}
		else if(Name == std::wstring (L"_xlnm.Auto_Open"))
		{
			index = 1;
		}
		else if(Name == std::wstring (L"_xlnm.Auto_Close"))
		{
			index = 2;
		}
		else if(Name == std::wstring (L"_xlnm.Extract"))
		{
			index = 3;
		}
		else if(Name == std::wstring (L"_xlnm.Database"))
		{
			index = 4;
		}
		else if(Name == std::wstring (L"_xlnm.Criteria"))
		{
			index = 5;
		}
		else if(Name == std::wstring (L"_xlnm.Print_Area"))
		{
			index = 6;
		}
		else if(Name == std::wstring (L"_xlnm.Print_Titles"))
		{
			index = 7;
		}
		else if(Name == std::wstring (L"_xlnm.Recorder"))
		{
			index = 8;
		}
		else if(Name == std::wstring (L"_xlnm.Data_Form"))
		{
			index = 9;
		}
		else if(Name == std::wstring (L"_xlnm.Auto_Activate"))
		{
			index = 10;
		}
		else if(Name == std::wstring (L"_xlnm.Auto_Deactivate"))
		{
			index = 11;
		}
		else if(Name == std::wstring (L"_xlnm.Sheet_Title"))
		{
			index = 12;
		}
		else if(Name == std::wstring (L"_xlnm._FilterDatabase"))
		{
			index = 13;
		}
		else
		{
			throw;// EXCEPT::RT::WrongBiffRecord(L"Unsupported value of built-in name.", record.getTypeString());
		}

		// fix
		Name_bin = Name;
		(static_cast<std::wstring>(Name_bin)).at(0) = index;
		record << Name_bin;

	}
	rgce.store(record);
	record.registerDelayedDataSource(rgce.getCCE(), rt_Lbl);
}

void Lbl::readFields(CFRecord& record)
{
	unsigned short flags;
	record >> flags >> chKey;

	fHidden			= GETBIT(flags, 0);
	fFunc			= GETBIT(flags, 1);
	fOB				= GETBIT(flags, 2);
	fProc			= GETBIT(flags, 3);
	fCalcExp		= GETBIT(flags, 4);
	fBuiltin		= GETBIT(flags, 5);
	fGrp			= GETBITS(flags, 6, 11);
	fPublished		= GETBIT(flags, 13);
	fWorkbookParam	= GETBIT(flags, 14);

	unsigned char cch;
	unsigned short cce;
	record >> cch >> cce;
	record.skipNunBytes(2);
	record >> itab;

	record.skipNunBytes(4);

	if (record.getGlobalWorkbookInfo()->Version < 0x600)
	{
		LPAnsiStringNoCch s;
		s.setSize(cch);
		record >> s;
		Name_bin = s;
	}
	else
	{
		Name_bin.setSize(cch); // this is to process built-in string values
		record >> Name_bin;
	}

	rgce.load(record, cce);

	if(!fBuiltin)
	{
		Name = Name_bin.getEscaped_ST_Xstring();

		for (int i = 0 ; i < 3; i++)
		{
			int res = Name_bin.value().find(AutoFilterDefineNames[i]);
			if (res >=0)
			{
				Name = Name_bin = (L"_xlnm._FilterDatabase");
				break;
			}
		}
	}
	else
	{
		unsigned char index = (static_cast<std::wstring>(Name_bin)).c_str()[0];
		switch(index)
		{
			case 0x00:
				Name =  (L"_xlnm.Consolidate_Area");
				break;
			case 0x01:
				Name =  (L"_xlnm.Auto_Open");
				break;
			case 0x02:
				Name =  (L"_xlnm.Auto_Close");
				break;
			case 0x03:
				Name =  (L"_xlnm.Extract");
				break;
			case 0x04:
				Name =  (L"_xlnm.Database");
				break;
			case 0x05:
				Name =  (L"_xlnm.Criteria");
				break;
			case 0x06:
				Name =  (L"_xlnm.Print_Area");
				break;
			case 0x07:
				Name =  (L"_xlnm.Print_Titles");
				break;
			case 0x08:
				Name =  (L"_xlnm.Recorder");
				break;
			case 0x09:
				Name =  (L"_xlnm.Data_Form");
				break;
			case 0x0A:
				Name =  (L"_xlnm.Auto_Activate");
				break;
			case 0x0B:
				Name =  (L"_xlnm.Auto_Deactivate");
				break;
			case 0x0C:
				Name =  (L"_xlnm.Sheet_Title");
				break;
			case 0x0D:
				Name =  (L"_xlnm._FilterDatabase");
				break;
			default:
				throw;// EXCEPT::RT::WrongBiffRecord(L"Unsupported value of built-in name.", record.getTypeString());
		}
	}
}

const XLUnicodeStringNoCch Lbl::getName() const
{
	return Name_bin;
}

} // namespace XLS

<|endoftext|>