<commit_before>#include "BloomFilter.h"
#include "System/Log.h"

static int32_t table32[256];
static int32_t table40[256];
static int32_t table48[256];
static int32_t table54[256];
static int32_t mods[BLOOMFILTER_P_DEGREE];

static int32_t HashRabin(ReadBuffer& r)
{
    int32_t         w;
    unsigned        s, start;

    w = 0;
    start = 0;

    if (r.GetLength() == 0)
        return 0;

    if (r.GetLength() % 2 == 1)
    {
        w = r.GetCharAt(0) & 0xFFFF;
        start = 1;
    }

    for (s = start; s < (r.GetLength() - 1); s += 2)
    {
        w = table32[w & 0xFF] ^
            table40[(((uint32_t)w) >> 8)  & 0xFF] ^
            table48[(((uint32_t)w) >> 16) & 0xFF] ^
            table54[(((uint32_t)w) >> 24) & 0xFF] ^
            ((r.GetCharAt(s) & 0xFFFF) << 16) ^ (r.GetCharAt(s + 1) & 0xFFFF);
    }

    return w;
}

static int32_t HashRabin(int32_t r)
{
    int32_t w;

    w = r;

    w =
     table32[w & 0xFF] ^
     table40[(((uint32_t)w) >> 8)  & 0xFF] ^
     table48[(((uint32_t)w) >> 16) & 0xFF] ^
     table54[(((uint32_t)w) >> 24) & 0xFF] ^ r;

    return w;
}

void BloomFilter::StaticInit()
{
    unsigned i, j, c;

    mods[0] = BLOOMFILTER_POLYNOMIAL;
    for (i = 1; i < BLOOMFILTER_P_DEGREE; i++)
    {
        mods[i] = mods[i - 1] << 1;
        if ((mods[i - 1] & BLOOMFILTER_X_P_DEGREE) != 0)
            mods[i] ^= BLOOMFILTER_POLYNOMIAL;
    }

    for (i = 0; i < 256; i++)
    {
        c = i;
        for (j = 0; j < 8 && c != 0; j++)
        {
            if ((c & 1) != 0)
            {
                table32[i] ^= mods[j];
                table40[i] ^= mods[j + 8];
                table48[i] ^= mods[j + 16];
                table54[i] ^= mods[j + 24];
            }
            c = ((unsigned)(c) >> 1);
        }
    }
}

void BloomFilter::SetSize(uint32_t size)
{
    buffer.Allocate(size);
    buffer.SetLength(size);
    buffer.Zero();
}

void BloomFilter::Add(ReadBuffer& key)
{
    unsigned    i, k, j, bitindex;
    char*       p;
    unsigned    hashes[BLOOMFILTER_NUM_FUNCTIONS];

    GetHashes(hashes, key);

    for (i = 0; i < BLOOMFILTER_NUM_FUNCTIONS; i++)
    {
        bitindex = hashes[i];
        k = bitindex / 8;
        j = bitindex % 8;
        p = buffer.GetBuffer() + k;
        *p |= (1 << j);
    }
}

void BloomFilter::SetBuffer(ReadBuffer& buffer_)
{
    buffer.Write(buffer_);
}

bool BloomFilter::Check(ReadBuffer& key)
{
    bool        res;
    unsigned    i, k, j, bitindex;
    char        c;
    unsigned    hashes[BLOOMFILTER_NUM_FUNCTIONS];

    res = true;

    GetHashes(hashes, key);

    for (i = 0; i < BLOOMFILTER_NUM_FUNCTIONS; i++)
    {
        bitindex = hashes[i];
        k = bitindex / 8;
        j = bitindex % 8;
        c = *(buffer.GetBuffer() + k);
        res &= (((c >> j) & 1));
        if (!res)
            break;
    }

    return res;
}

Buffer& BloomFilter::GetBuffer()
{
    return buffer;
}

void BloomFilter::Reset()
{
    buffer.Reset();
}

//int32_t BloomFilter::GetHash(unsigned fnum, int32_t original)
//{
//    unsigned    i;
//    int32_t     hash;
//
//    hash = original;
//    for (i = 0; i < fnum; i++)
//        hash = HashRabin(hash);
//
//    hash = hash % (buffer.GetLength() * 8);
//
//    if (hash < 0)
//        hash = -hash;
//
//    return hash;
//}

void BloomFilter::GetHashes(unsigned hashes[], ReadBuffer& key)
{
    unsigned    i;
    int32_t     hash;

    hash = HashRabin(key);

    for (i = 0; i < BLOOMFILTER_NUM_FUNCTIONS; i++)
    {
        hashes[i] = hash % (buffer.GetLength() * 8);
        hash = HashRabin(hash);
    }
}

unsigned BloomFilter::BitCount(uint32_t u)
{
    uint32_t    count;

    count = u
          - ((u >> 1) & 033333333333)
          - ((u >> 2) & 011111111111);
    return ((count + (count >> 3)) & 030707070707) % 63;
}<commit_msg>Removed uncommented part from BloomFilter.<commit_after>#include "BloomFilter.h"
#include "System/Log.h"

static int32_t table32[256];
static int32_t table40[256];
static int32_t table48[256];
static int32_t table54[256];
static int32_t mods[BLOOMFILTER_P_DEGREE];

static int32_t HashRabin(ReadBuffer& r)
{
    int32_t         w;
    unsigned        s, start;

    w = 0;
    start = 0;

    if (r.GetLength() == 0)
        return 0;

    if (r.GetLength() % 2 == 1)
    {
        w = r.GetCharAt(0) & 0xFFFF;
        start = 1;
    }

    for (s = start; s < (r.GetLength() - 1); s += 2)
    {
        w = table32[w & 0xFF] ^
            table40[(((uint32_t)w) >> 8)  & 0xFF] ^
            table48[(((uint32_t)w) >> 16) & 0xFF] ^
            table54[(((uint32_t)w) >> 24) & 0xFF] ^
            ((r.GetCharAt(s) & 0xFFFF) << 16) ^ (r.GetCharAt(s + 1) & 0xFFFF);
    }

    return w;
}

static int32_t HashRabin(int32_t r)
{
    int32_t w;

    w = r;

    w =
     table32[w & 0xFF] ^
     table40[(((uint32_t)w) >> 8)  & 0xFF] ^
     table48[(((uint32_t)w) >> 16) & 0xFF] ^
     table54[(((uint32_t)w) >> 24) & 0xFF] ^ r;

    return w;
}

void BloomFilter::StaticInit()
{
    unsigned i, j, c;

    mods[0] = BLOOMFILTER_POLYNOMIAL;
    for (i = 1; i < BLOOMFILTER_P_DEGREE; i++)
    {
        mods[i] = mods[i - 1] << 1;
        if ((mods[i - 1] & BLOOMFILTER_X_P_DEGREE) != 0)
            mods[i] ^= BLOOMFILTER_POLYNOMIAL;
    }

    for (i = 0; i < 256; i++)
    {
        c = i;
        for (j = 0; j < 8 && c != 0; j++)
        {
            if ((c & 1) != 0)
            {
                table32[i] ^= mods[j];
                table40[i] ^= mods[j + 8];
                table48[i] ^= mods[j + 16];
                table54[i] ^= mods[j + 24];
            }
            c = ((unsigned)(c) >> 1);
        }
    }
}

void BloomFilter::SetSize(uint32_t size)
{
    buffer.Allocate(size);
    buffer.SetLength(size);
    buffer.Zero();
}

void BloomFilter::Add(ReadBuffer& key)
{
    unsigned    i, k, j, bitindex;
    char*       p;
    unsigned    hashes[BLOOMFILTER_NUM_FUNCTIONS];

    GetHashes(hashes, key);

    for (i = 0; i < BLOOMFILTER_NUM_FUNCTIONS; i++)
    {
        bitindex = hashes[i];
        k = bitindex / 8;
        j = bitindex % 8;
        p = buffer.GetBuffer() + k;
        *p |= (1 << j);
    }
}

void BloomFilter::SetBuffer(ReadBuffer& buffer_)
{
    buffer.Write(buffer_);
}

bool BloomFilter::Check(ReadBuffer& key)
{
    bool        res;
    unsigned    i, k, j, bitindex;
    char        c;
    unsigned    hashes[BLOOMFILTER_NUM_FUNCTIONS];

    res = true;

    GetHashes(hashes, key);

    for (i = 0; i < BLOOMFILTER_NUM_FUNCTIONS; i++)
    {
        bitindex = hashes[i];
        k = bitindex / 8;
        j = bitindex % 8;
        c = *(buffer.GetBuffer() + k);
        res &= (((c >> j) & 1));
        if (!res)
            break;
    }

    return res;
}

Buffer& BloomFilter::GetBuffer()
{
    return buffer;
}

void BloomFilter::Reset()
{
    buffer.Reset();
}

void BloomFilter::GetHashes(unsigned hashes[], ReadBuffer& key)
{
    unsigned    i;
    int32_t     hash;

    hash = HashRabin(key);

    for (i = 0; i < BLOOMFILTER_NUM_FUNCTIONS; i++)
    {
        hashes[i] = hash % (buffer.GetLength() * 8);
        hash = HashRabin(hash);
    }
}

unsigned BloomFilter::BitCount(uint32_t u)
{
    uint32_t    count;

    count = u
          - ((u >> 1) & 033333333333)
          - ((u >> 2) & 011111111111);
    return ((count + (count >> 3)) & 030707070707) % 63;
}<|endoftext|>


<commit_before>// Copyright (c) 2017 offa
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions.
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include "danek/internal/UidIdentifierProcessor.h"
#include "danek/ConfigurationException.h"
#include "danek/StringBuffer.h"
#include <gmock/gmock.h>

using danek::UidIdentifierProcessor;
using danek::StringBuffer;
using danek::ConfigurationException;
using namespace testing;

class UidIdentifierProcessorTest : public testing::Test
{
};

TEST(UidIdentifierProcessorTest, expandString)
{
    UidIdentifierProcessor p;
    StringBuffer str{"abc"};

    p.expand(str);
    EXPECT_THAT(str.str(), StrEq("abc"));
}

TEST(UidIdentifierProcessorTest, expandWithScope)
{
    UidIdentifierProcessor p;
    StringBuffer str{"a.b.c"};

    p.expand(str);
    EXPECT_THAT(str.str(), StrEq("a.b.c"));
}

TEST(UidIdentifierProcessorTest, expandWithScopeAndUid)
{
    UidIdentifierProcessor p;
    StringBuffer str{"a.uid-b.uid-0013-c"};

    p.expand(str);
    EXPECT_THAT(str.str(), StrEq("a.uid-000000000-b.uid-000000001-c"));
}

TEST(UidIdentifierProcessorTest, expandWithUid)
{
    UidIdentifierProcessor p;
    StringBuffer str{"uid-xyz"};

    p.expand(str);
    EXPECT_THAT(str.str(), StrEq("uid-000000000-xyz"));
}

TEST(UidIdentifierProcessorTest, expandWithUidIncreasesUid)
{
    UidIdentifierProcessor p;
    StringBuffer str{"uid-x.uid-y.uid-z"};

    p.expand(str);
    EXPECT_THAT(str.str(), StrEq("uid-000000000-x.uid-000000001-y.uid-000000002-z"));
}

TEST(UidIdentifierProcessorTest, expandMaintaintsUidState)
{
    UidIdentifierProcessor p;
    StringBuffer str{"uid-x"};
    StringBuffer str2{"uid-y"};
    StringBuffer str3{"uid-z"};

    p.expand(str);
    p.expand(str2);
    p.expand(str3);
    EXPECT_THAT(str.str(), StrEq("uid-000000000-x"));
    EXPECT_THAT(str2.str(), StrEq("uid-000000001-y"));
    EXPECT_THAT(str3.str(), StrEq("uid-000000002-z"));
}

TEST(UidIdentifierProcessorTest, expandWithUidAndNumber)
{
    UidIdentifierProcessor p;
    StringBuffer str{"uid-01234-xyz"};

    p.expand(str);
    EXPECT_THAT(str.str(), StrEq("uid-000000000-xyz"));
}

TEST(UidIdentifierProcessorTest, expandWithWithouthUidSuffixThrows)
{
    UidIdentifierProcessor p;
    StringBuffer str{"uid-"};
    StringBuffer str2{"uid--"};
    StringBuffer str3{"uid--abc"};
    StringBuffer str4{"uid-9abc"};
    StringBuffer str5{"uid-123-"};
    StringBuffer str6{"uid-123--a"};
    StringBuffer str7{"uid-123-456a"};

    EXPECT_THROW(p.expand(str), ConfigurationException);
    EXPECT_THROW(p.expand(str2), ConfigurationException);
    EXPECT_THROW(p.expand(str3), ConfigurationException);
    EXPECT_THROW(p.expand(str4), ConfigurationException);
    EXPECT_THROW(p.expand(str5), ConfigurationException);
    EXPECT_THROW(p.expand(str6), ConfigurationException);
    EXPECT_THROW(p.expand(str7), ConfigurationException);
}

TEST(UidIdentifierProcessorTest, unexpandString)
{
    UidIdentifierProcessor p;
    StringBuffer str;

    const auto result = p.unexpand("abc", str);
    EXPECT_THAT(result, StrEq("abc"));
}

TEST(UidIdentifierProcessorTest, unexpandWithScope)
{
    UidIdentifierProcessor p;
    StringBuffer str;

    const auto result = p.unexpand("a.b.c", str);
    EXPECT_THAT(result, StrEq("a.b.c"));
}

TEST(UidIdentifierProcessorTest, unexpandWithScopeAndUid)
{
    UidIdentifierProcessor p;
    StringBuffer str;

    const auto result = p.unexpand("a.uid-000000000-b.uid-000000001-c", str);
    EXPECT_THAT(result, StrEq("a.uid-b.uid-c"));
}

TEST(UidIdentifierProcessorTest, unexpandWithUid)
{
    UidIdentifierProcessor p;
    StringBuffer str;

    const auto result = p.unexpand("uid-xyz", str);
    EXPECT_THAT(result, StrEq("uid-xyz"));
}

TEST(UidIdentifierProcessorTest, unexpandWithUidAndNumber)
{
    UidIdentifierProcessor p;
    StringBuffer str;

    const auto result = p.unexpand("uid-000000003-xyz", str);
    EXPECT_THAT(result, StrEq("uid-xyz"));
}

TEST(UidIdentifierProcessorTest, unexpandWithUidAndUidWithNumbers)
{
    UidIdentifierProcessor p;
    StringBuffer str;

    const auto result = p.unexpand("uid-000000000-x.uid-y.uid-000000002-z", str);
    EXPECT_THAT(result, StrEq("uid-x.uid-y.uid-z"));
}

TEST(UidIdentifierProcessorTest, unexpandWithDifferentUid)
{
    UidIdentifierProcessor p;
    StringBuffer str;
    StringBuffer str2;
    StringBuffer str3;

    const auto result1 =  p.unexpand("uid-000000000-x", str);
    const auto result2 = p.unexpand("uid-000000001-y", str2);
    const auto result3 = p.unexpand("uid-000000002-z", str3);
    EXPECT_THAT(result1, StrEq("uid-x"));
    EXPECT_THAT(result2, StrEq("uid-y"));
    EXPECT_THAT(result3, StrEq("uid-z"));
}

<commit_msg>Test case added.<commit_after>// Copyright (c) 2017 offa
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions.
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include "danek/internal/UidIdentifierProcessor.h"
#include "danek/ConfigurationException.h"
#include "danek/StringBuffer.h"
#include <gmock/gmock.h>

using danek::UidIdentifierProcessor;
using danek::StringBuffer;
using danek::ConfigurationException;
using namespace testing;

class UidIdentifierProcessorTest : public testing::Test
{
};

TEST(UidIdentifierProcessorTest, expandString)
{
    UidIdentifierProcessor p;
    StringBuffer str{"abc"};

    p.expand(str);
    EXPECT_THAT(str.str(), StrEq("abc"));
}

TEST(UidIdentifierProcessorTest, expandWithScope)
{
    UidIdentifierProcessor p;
    StringBuffer str{"a.b.c"};

    p.expand(str);
    EXPECT_THAT(str.str(), StrEq("a.b.c"));
}

TEST(UidIdentifierProcessorTest, expandWithScopeAndUid)
{
    UidIdentifierProcessor p;
    StringBuffer str{"a.uid-b.uid-0013-c"};

    p.expand(str);
    EXPECT_THAT(str.str(), StrEq("a.uid-000000000-b.uid-000000001-c"));
}

TEST(UidIdentifierProcessorTest, expandWithUid)
{
    UidIdentifierProcessor p;
    StringBuffer str{"uid-xyz"};

    p.expand(str);
    EXPECT_THAT(str.str(), StrEq("uid-000000000-xyz"));
}

TEST(UidIdentifierProcessorTest, expandWithUidIncreasesUid)
{
    UidIdentifierProcessor p;
    StringBuffer str{"uid-x.uid-y.uid-z"};

    p.expand(str);
    EXPECT_THAT(str.str(), StrEq("uid-000000000-x.uid-000000001-y.uid-000000002-z"));
}

TEST(UidIdentifierProcessorTest, expandMaintaintsUidState)
{
    UidIdentifierProcessor p;
    StringBuffer str{"uid-x"};
    StringBuffer str2{"uid-y"};
    StringBuffer str3{"uid-z33"};

    p.expand(str);
    p.expand(str2);
    p.expand(str3);
    EXPECT_THAT(str.str(), StrEq("uid-000000000-x"));
    EXPECT_THAT(str2.str(), StrEq("uid-000000001-y"));
    EXPECT_THAT(str3.str(), StrEq("uid-000000002-z33"));
}

TEST(UidIdentifierProcessorTest, expandWithUidAndNumber)
{
    UidIdentifierProcessor p;
    StringBuffer str{"uid-01234-xyz12"};

    p.expand(str);
    EXPECT_THAT(str.str(), StrEq("uid-000000000-xyz12"));
}

TEST(UidIdentifierProcessorTest, expandWithWithouthUidSuffixThrows)
{
    UidIdentifierProcessor p;
    StringBuffer str{"uid-"};
    StringBuffer str2{"uid--"};
    StringBuffer str3{"uid--abc"};
    StringBuffer str4{"uid-9abc"};
    StringBuffer str5{"uid-123-"};
    StringBuffer str6{"uid-123--a"};
    StringBuffer str7{"uid-123-456a"};

    EXPECT_THROW(p.expand(str), ConfigurationException);
    EXPECT_THROW(p.expand(str2), ConfigurationException);
    EXPECT_THROW(p.expand(str3), ConfigurationException);
    EXPECT_THROW(p.expand(str4), ConfigurationException);
    EXPECT_THROW(p.expand(str5), ConfigurationException);
    EXPECT_THROW(p.expand(str6), ConfigurationException);
    EXPECT_THROW(p.expand(str7), ConfigurationException);
}

TEST(UidIdentifierProcessorTest, unexpandString)
{
    UidIdentifierProcessor p;
    StringBuffer str;

    const auto result = p.unexpand("abc", str);
    EXPECT_THAT(result, StrEq("abc"));
}

TEST(UidIdentifierProcessorTest, unexpandWithScope)
{
    UidIdentifierProcessor p;
    StringBuffer str;

    const auto result = p.unexpand("a.b.c", str);
    EXPECT_THAT(result, StrEq("a.b.c"));
}

TEST(UidIdentifierProcessorTest, unexpandWithScopeAndUid)
{
    UidIdentifierProcessor p;
    StringBuffer str;

    const auto result = p.unexpand("a.uid-000000000-b.uid-000000001-c", str);
    EXPECT_THAT(result, StrEq("a.uid-b.uid-c"));
}

TEST(UidIdentifierProcessorTest, unexpandWithUid)
{
    UidIdentifierProcessor p;
    StringBuffer str;

    const auto result = p.unexpand("uid-xyz", str);
    EXPECT_THAT(result, StrEq("uid-xyz"));
}

TEST(UidIdentifierProcessorTest, unexpandWithUidAndNumber)
{
    UidIdentifierProcessor p;
    StringBuffer str;

    const auto result = p.unexpand("uid-000000003-xyz", str);
    EXPECT_THAT(result, StrEq("uid-xyz"));
}

TEST(UidIdentifierProcessorTest, unexpandWithUidAndUidWithNumbers)
{
    UidIdentifierProcessor p;
    StringBuffer str;

    const auto result = p.unexpand("uid-000000000-x.uid-y.uid-000000002-z", str);
    EXPECT_THAT(result, StrEq("uid-x.uid-y.uid-z"));
}

TEST(UidIdentifierProcessorTest, unexpandWithDifferentUid)
{
    UidIdentifierProcessor p;
    StringBuffer str;
    StringBuffer str2;
    StringBuffer str3;

    const auto result1 =  p.unexpand("uid-000000000-x", str);
    const auto result2 = p.unexpand("uid-000000001-y", str2);
    const auto result3 = p.unexpand("uid-000000002-z", str3);
    EXPECT_THAT(result1, StrEq("uid-x"));
    EXPECT_THAT(result2, StrEq("uid-y"));
    EXPECT_THAT(result3, StrEq("uid-z"));
}

<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/lib/p9_hcd_common.H $      */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,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                                                     */
///
/// @file p9_hcd_common.H
/// @brief common hcode includes
///

// *HWP HWP Owner          : David Du       <daviddu@us.ibm.com>
// *HWP Backup HWP Owner   : Greg Still     <stillgs@us.ibm.com>
// *HWP FW Owner           : Sangeetha T S  <sangeet2@in.ibm.com>
// *HWP Team               : PM
// *HWP Consumed by        : SBE:SGPE:CME
// *HWP Level              : 2

#ifndef __P9_HCD_COMMON_H__
#define __P9_HCD_COMMON_H__

//-------------------------
// Macros
//-------------------------

// Create a multi-bit mask of \a n bits starting at bit \a b
#define BITS64(b, n) ((0xffffffffffffffffull << (64 - (n))) >> (b))

// Create a single bit mask at bit \a b
#define BIT64(b) BITS64((b), 1)

// The BUF_* macros apply operations to a newly constructed buffer
#define BUF_SET(bit)   fapi2::buffer<uint64_t>().setBit<bit>()
#define BUF_UNSET(bit) fapi2::buffer<uint64_t>().flush<1>().clearBit<bit>()
#define BUF_INSERT(start,size,val) \
    fapi2::buffer<uint64_t>().insertFromRight<start,size>(val)
#define BUF_REPLACE(start,size,val) \
    fapi2::buffer<uint64_t>().flush<1>().insertFromRight<start,size>(val)

// The following DATA_* and MASK_* macros assume you have
// "fapi2::buffer<uint64_t> l_data64" declared

// The DATA_* macros apply operations to a buffer contains existing data
#define DATA_BIT(buf,op,bit)             buf.op##Bit<bit>()
#define DATA_SET(bit)                    DATA_BIT(l_data64,set,bit)
#define DATA_UNSET(bit)                  DATA_BIT(l_data64,clear,bit)
#define DATA_FIELD(buf,start,size,val)   buf.insertFromRight<start,size>(val)
#define DATA_INSERT(start,size,val)      DATA_FIELD(l_data64,start,size,val)

// The MASK_* macros apply operations to a buffer to create a new data mask
// data previously stored in the buffer will be overwritten.
#define MASK_FLUSH(buf,mask)             buf.flush<mask>()
#define MASK_ZERO                        MASK_FLUSH(l_data64,0)
#define MASK_ALL                         MASK_FLUSH(l_data64,1)
#define MASK_BIT(buf,mask,op,bit)        buf.flush<mask>().op##Bit<bit>()
#define MASK_SET(bit)                    MASK_BIT(l_data64,0,set,bit)
#define MASK_UNSET(bit)                  MASK_BIT(l_data64,1,clear,bit)
#define MASK_FIELD(buf,mask,start,size,val) \
    buf.flush<mask>().insertFromRight<start,size>(val)
#define MASK_OR(start,size,val)          MASK_FIELD(l_data64,0,start,size,val)
#define MASK_AND(start,size,val)         MASK_FIELD(l_data64,1,start,size,val)
#define MASK_CLR(start,size,val)         MASK_FIELD(l_data64,0,start,size,val)

//-------------------------
// Constants
//-------------------------

namespace p9hcd
{

// Constants to calculate hcd poll timeout intervals
enum P9_HCD_COMMON_TIMEOUT_CONSTANTS
{
    CYCLES_PER_MS       = 500000, // PPE FREQ 500MHZ
    INSTS_PER_POLL_LOOP = 8       //
};

// Init Vectors for Register Setup
enum P9_HCD_COMMON_INIT_VECTORS
{
    // 0     -  CHIPLET_ENABLE
    // 1     -  PCB_EP_RESET
    // 3     -  PLL_TEST_EN
    // 4     -  PLLRST
    // 5     -  PLLBYP
    // 12    -  VITL_MPW1
    // 13    -  VITL_MPW2
    // 14    -  VITL_MPW3
    // 18    -  FENCE_EN
    NET_CTRL0_INIT_VECTOR = (BIT64(0) | BIT64(1) | BITS64(3, 3) | BITS64(12, 3) | BIT64(18)),
    HANG_PULSE1_INIT_VECTOR = BIT64(5)
};

// Clock Control Constants
enum P9_HCD_COMMON_CLK_CTRL_CONSTANTS
{
    CLK_STOP_CMD                             = BIT64(0),
    CLK_START_CMD                            = BIT64(1),
    CLK_SLAVE_MODE                           = BIT64(2),
    CLK_MASTER_MODE                          = BIT64(3),
    CLK_REGION_DPLL                          = BIT64(14),
    CLK_REGION_L2                            = BITS64(8, 2),
    CLK_REGION_ALL_BUT_DPLL_L2               = BITS64(4, 4) | BITS64(10, 4),
    CLK_REGION_ALL                           = BITS64(4, 11),
    CLK_THOLD_ALL                            = BITS64(48, 3),
    CLK_THOLD_NSL_ARY                        = BITS64(49, 2)
};

// Clock Control Vectors
enum P9_HCD_COMMON_CLK_CTRL_VECTORS
{
    CLK_START_REGION_ALL_THOLD_NSL_ARY =
        (CLK_START_CMD | CLK_MASTER_MODE | CLK_REGION_ALL | CLK_THOLD_NSL_ARY),
    CLK_START_REGION_ALL_THOLD_ALL =
        (CLK_START_CMD | CLK_MASTER_MODE | CLK_REGION_ALL | CLK_THOLD_ALL),
    CLK_START_REGION_ALL_BUT_DPLL_L2_THOLD_NSL_ARY =
        (CLK_START_CMD | CLK_MASTER_MODE | CLK_REGION_ALL_BUT_DPLL_L2 | CLK_THOLD_NSL_ARY),
    CLK_START_REGION_ALL_BUT_DPLL_L2_THOLD_ALL =
        (CLK_START_CMD | CLK_MASTER_MODE | CLK_REGION_ALL_BUT_DPLL_L2 | CLK_THOLD_ALL),
    CLK_START_REGION_L2_THOLD_NSL_ARY =
        (CLK_START_CMD | CLK_MASTER_MODE | CLK_REGION_L2 | CLK_THOLD_NSL_ARY),
    CLK_START_REGION_L2_THOLD_ALL =
        (CLK_START_CMD | CLK_MASTER_MODE | CLK_REGION_L2 | CLK_THOLD_ALL),
    CLK_START_REGION_DPLL_THOLD_NSL_ARY =
        (CLK_START_CMD | CLK_MASTER_MODE | CLK_REGION_DPLL | CLK_THOLD_NSL_ARY),
    CLK_START_REGION_DPLL_THOLD_ALL =
        (CLK_START_CMD | CLK_MASTER_MODE | CLK_REGION_DPLL | CLK_THOLD_ALL)
};

// SCAN0 Constants
enum P9_HCD_COMMON_SCAN0_CONSTANTS
{
    SCAN0_REGION_ALL                         = 0x7FF,
    SCAN0_REGION_ALL_BUT_PLL                 = 0x7FE,
    SCAN0_REGION_PLL                         = 0x001,
    SCAN0_REGION_CORE_ONLY                   = 0x300,
    SCAN0_TYPE_ALL_BUT_GPTR_REPR_TIME        = 0xDCF,
    SCAN0_TYPE_GPTR_REPR_TIME                = 0x230,
    SCAN0_TYPE_REPR_TIME                     = 0x030,
    SCAN0_TYPE_GPTR                          = 0x200,
    SCAN0_TYPE_FUNC_BNDY                     = 0x808
};
//OCC FLag defines
enum PM_GPE_OCCFLG_DEFS
{
    SGPE_ACTIVE    = 8
};

// XSR defines
enum XSR_DEFS
{
    HALTED_STATE    = 0
};

// XCR defines
enum XCR_DEFS
{
    CLEAR_DEBUG_STATUS = 0,
    HALT               = 1,
    RESUME             = 2,
    SINGLE_STEP        = 3,
    TOGGLE_XSR_TRH     = 4,
    SOFT_RESET         = 5,
    HARD_RESET         = 6,
    FORCE_HALT         = 7
};

} // END OF NAMESPACE p9hcd

/// @todo needs to review this
/// SCAN Repeats(from P8)
#define GENERIC_CC_SCAN0_MAXIMUM   8191
#define SCAN0_FUNC_FLUSH_LENGTH    8000
#define SCAN0_GPTR_FLUSH_LENGTH    14000
#define P9_HCD_SCAN_FUNC_REPEAT    \
    ((SCAN0_FUNC_FLUSH_LENGTH / GENERIC_CC_SCAN0_MAXIMUM)+1)
#define P9_HCD_SCAN_GPTR_REPEAT    \
    ((SCAN0_GPTR_FLUSH_LENGTH / GENERIC_CC_SCAN0_MAXIMUM)+1)

/// @todo remove these once correct header contains them
/// Scom addresses missing from p9_quad_scom_addresses.H
#define EQ_QPPM_QCCR_WCLEAR              0x100F01BE
#define EQ_QPPM_QCCR_WOR                 0x100F01BF

#endif  // __P9_HCD_COMMON_H__
<commit_msg>HWP-CORE/CACHE: Update Istep 4 procedures regressed on model 34<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/lib/p9_hcd_common.H $      */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,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                                                     */
///
/// @file p9_hcd_common.H
/// @brief common hcode includes
///

// *HWP HWP Owner          : David Du       <daviddu@us.ibm.com>
// *HWP Backup HWP Owner   : Greg Still     <stillgs@us.ibm.com>
// *HWP FW Owner           : Sangeetha T S  <sangeet2@in.ibm.com>
// *HWP Team               : PM
// *HWP Consumed by        : SBE:SGPE:CME
// *HWP Level              : 2

#ifndef __P9_HCD_COMMON_H__
#define __P9_HCD_COMMON_H__

//-------------------------
// Macros
//-------------------------

// Create a multi-bit mask of \a n bits starting at bit \a b
#define BITS64(b, n) ((0xffffffffffffffffull << (64 - (n))) >> (b))
#define BITS32(b, n) ((0xffffffff            << (32 - (n))) >> (b))
#define BITS16(b, n) ((0xffff                << (16 - (n))) >> (b))
#define BITS8(b, n)  ((0xff                  << (8  - (n))) >> (b))

// Create a single bit mask at bit \a b
#define BIT64(b) BITS64((b), 1)
#define BIT32(b) BITS32((b), 1)
#define BIT16(b) BITS16((b), 1)
#define BIT8(b)  BITS8((b), 1)

// Create a amount of shift to bit location \a b
#define SHIFT64(b) (63-b)
#define SHIFT32(b) (31-b)
#define SHIFT16(b) (15-b)
#define SHIFT8(b)  (7-b)

// The BUF_* macros apply operations to a newly constructed buffer
#define BUF_SET(bit)   fapi2::buffer<uint64_t>().setBit<bit>()
#define BUF_UNSET(bit) fapi2::buffer<uint64_t>().flush<1>().clearBit<bit>()
#define BUF_INSERT(start,size,val) \
    fapi2::buffer<uint64_t>().insertFromRight<start,size>(val)
#define BUF_REPLACE(start,size,val) \
    fapi2::buffer<uint64_t>().flush<1>().insertFromRight<start,size>(val)
// The following DATA_* and MASK_* macros assume you have
// "fapi2::buffer<uint64_t> l_data64" declared

// The DATA_* macros apply operations to a buffer contains existing data
#define DATA_BIT(buf,op,bit)             buf.op##Bit<bit>()
#define DATA_SET(bit)                    DATA_BIT(l_data64,set,bit)
#define DATA_UNSET(bit)                  DATA_BIT(l_data64,clear,bit)
#define DATA_FIELD(buf,start,size,val)   buf.insertFromRight<start,size>(val)
#define DATA_INSERT(start,size,val)      DATA_FIELD(l_data64,start,size,val)

// The MASK_* macros apply operations to a buffer to create a new data mask
// data previously stored in the buffer will be overwritten.
#define MASK_FLUSH(buf,mask)             buf.flush<mask>()
#define MASK_ZERO                        MASK_FLUSH(l_data64,0)
#define MASK_ALL                         MASK_FLUSH(l_data64,1)
#define MASK_BIT(buf,mask,op,bit)        buf.flush<mask>().op##Bit<bit>()
#define MASK_SET(bit)                    MASK_BIT(l_data64,0,set,bit)
#define MASK_UNSET(bit)                  MASK_BIT(l_data64,1,clear,bit)
#define MASK_FIELD(buf,mask,start,size,val) \
    buf.flush<mask>().insertFromRight<start,size>(val)
#define MASK_OR(start,size,val)          MASK_FIELD(l_data64,0,start,size,val)
#define MASK_AND(start,size,val)         MASK_FIELD(l_data64,1,start,size,val)
#define MASK_CLR(start,size,val)         MASK_FIELD(l_data64,0,start,size,val)

//-------------------------
// Constants
//-------------------------

namespace p9hcd
{

// Bit masks used by CME hcode
enum P9_HCD_CME_CORE_MASKS
{
    LEFT_CORE  = 0x2,
    RIGHT_CORE = 0x1,
    BOTH_CORES = 0x3,
    NO_CORE    = 0x0
};

// Control parameters for PCB Aribter
enum P9_HCD_PCB_ARBITER_CTRL
{
    REQUEST_ARBITER = 1,
    RELEASE_ARBITER = 0
};

// Constants to calculate hcd poll timeout intervals
enum P9_HCD_COMMON_TIMEOUT_CONSTANTS
{
    CYCLES_PER_MS       = 500000, // PPE FREQ 500MHZ
    INSTS_PER_POLL_LOOP = 8       //
};

// Init Vectors for Register Setup
enum P9_HCD_COMMON_INIT_VECTORS
{
    // 0     -  CHIPLET_ENABLE
    // 1     -  PCB_EP_RESET
    // 3     -  PLL_TEST_EN
    // 4     -  PLLRST
    // 5     -  PLLBYP
    // 12    -  VITL_MPW1
    // 13    -  VITL_MPW2
    // 14    -  VITL_MPW3
    // 18    -  FENCE_EN
    NET_CTRL0_INIT_VECTOR = (BIT64(0) | BIT64(1) | BITS64(3, 3) | BITS64(12, 3) | BIT64(18)),
    HANG_PULSE1_INIT_VECTOR = BIT64(5)
};

// Clock Control Constants
enum P9_HCD_COMMON_CLK_CTRL_CONSTANTS
{
    CLK_STOP_CMD                             = BIT64(0),
    CLK_START_CMD                            = BIT64(1),
    CLK_SLAVE_MODE                           = BIT64(2),
    CLK_MASTER_MODE                          = BIT64(3),
    CLK_REGION_ANEP                          = BIT64(10),
    CLK_REGION_DPLL                          = BIT64(14),
    CLK_REGION_L2                            = BITS64(8, 2),
    CLK_REGION_ALL_BUT_DPLL_L2               = BITS64(4, 4) | BITS64(10, 4),
    CLK_REGION_ALL                           = BITS64(4, 11),
    CLK_THOLD_ALL                            = BITS64(48, 3),
    CLK_THOLD_NSL_ARY                        = BITS64(49, 2)
};

// Clock Control Vectors
enum P9_HCD_COMMON_CLK_CTRL_VECTORS
{
    CLK_START_REGION_ALL_THOLD_NSL_ARY =
        (CLK_START_CMD | CLK_REGION_ALL | CLK_THOLD_NSL_ARY),
    CLK_START_REGION_ALL_THOLD_ALL =
        (CLK_START_CMD | CLK_REGION_ALL | CLK_THOLD_ALL),
    CLK_START_REGION_ALL_BUT_DPLL_L2_THOLD_NSL_ARY =
        (CLK_START_CMD | CLK_REGION_ALL_BUT_DPLL_L2 | CLK_THOLD_NSL_ARY),
    CLK_START_REGION_ALL_BUT_DPLL_L2_THOLD_ALL =
        (CLK_START_CMD | CLK_REGION_ALL_BUT_DPLL_L2 | CLK_THOLD_ALL),
    CLK_START_REGION_L2_THOLD_NSL_ARY =
        (CLK_START_CMD | CLK_REGION_L2 | CLK_THOLD_NSL_ARY),
    CLK_START_REGION_L2_THOLD_ALL =
        (CLK_START_CMD | CLK_REGION_L2 | CLK_THOLD_ALL),
    CLK_START_REGION_DPLL_THOLD_NSL_ARY =
        (CLK_START_CMD | CLK_REGION_DPLL | CLK_THOLD_NSL_ARY),
    CLK_START_REGION_DPLL_THOLD_ALL =
        (CLK_START_CMD | CLK_REGION_DPLL | CLK_THOLD_ALL),
    CLK_START_REGION_ANEP_THOLD_NSL_ARY =
        (CLK_START_CMD | CLK_REGION_ANEP | CLK_THOLD_NSL_ARY),
    CLK_START_REGION_ANEP_THOLD_ALL =
        (CLK_START_CMD | CLK_REGION_ANEP | CLK_THOLD_ALL)
};

// SCAN0 Constants
enum P9_HCD_COMMON_SCAN0_CONSTANTS
{
    SCAN0_REGION_ALL                         = 0x7FF,
    SCAN0_REGION_ALL_BUT_PLL                 = 0x7FE,
    SCAN0_REGION_ALL_BUT_ANEP_PLL            = 0x7EE,
    SCAN0_REGION_PLL                         = 0x001,
    SCAN0_REGION_DPLL_ANEP                   = 0x011,
    SCAN0_REGION_CORE_ONLY                   = 0x300,
    SCAN0_REGION_PERV_CORE                   = 0x700,
    SCAN0_TYPE_ALL_BUT_GPTR_REPR_TIME        = 0xDCF,
    SCAN0_TYPE_GPTR_REPR_TIME                = 0x230,
    SCAN0_TYPE_REPR_TIME                     = 0x030,
    SCAN0_TYPE_GPTR                          = 0x200,
    SCAN0_TYPE_FUNC                          = 0x800,
    SCAN0_TYPE_FUNC_BNDY                     = 0x808
};
//OCC FLag defines
enum PM_GPE_OCCFLG_DEFS
{
    SGPE_ACTIVE    = 8
};

// XSR defines
enum XSR_DEFS
{
    HALTED_STATE    = 0
};

// XCR defines
enum XCR_DEFS
{
    CLEAR_DEBUG_STATUS = 0,
    HALT               = 1,
    RESUME             = 2,
    SINGLE_STEP        = 3,
    TOGGLE_XSR_TRH     = 4,
    SOFT_RESET         = 5,
    HARD_RESET         = 6,
    FORCE_HALT         = 7
};

} // END OF NAMESPACE p9hcd

/// @todo needs to review this
/// SCAN Repeats(from P8)
/*
#define GENERIC_CC_SCAN0_MAXIMUM   8191
#define SCAN0_FUNC_FLUSH_LENGTH    8000
#define SCAN0_GPTR_FLUSH_LENGTH    14000
#define P9_HCD_SCAN_FUNC_REPEAT    \
    ((SCAN0_FUNC_FLUSH_LENGTH / GENERIC_CC_SCAN0_MAXIMUM)+1)
#define P9_HCD_SCAN_GPTR_REPEAT    \
    ((SCAN0_GPTR_FLUSH_LENGTH / GENERIC_CC_SCAN0_MAXIMUM)+1)
*/
#define P9_HCD_SCAN_FUNC_REPEAT 40
#define P9_HCD_SCAN_GPTR_REPEAT 40

/// @todo remove these once correct header contains them
/// Scom addresses missing from p9_quad_scom_addresses.H
#define EQ_QPPM_QCCR_WOR                 0x100F01BF
#define CME_LCL_SICR_OR                  0xc0000510
#define CME_LCL_SICR_CLR                 0xc0000518
#define CME_LCL_SISR                     0xc0000520

#endif  // __P9_HCD_COMMON_H__
<|endoftext|>


<commit_before>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// 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 <thread>

#include "SurgSim/Collision/CcdDcdCollision.h"
#include "SurgSim/Collision/ContactCalculation.h"
#include "SurgSim/Collision/DefaultContactCalculation.h"
#include "SurgSim/Collision/Representation.h"
#include "SurgSim/Framework/Log.h"

namespace SurgSim
{
namespace Collision
{

ContactCalculation::TableType ContactCalculation::m_contactDcdCalculations;
ContactCalculation::TableType ContactCalculation::m_contactCcdCalculations;
std::once_flag ContactCalculation::m_initializationFlag;

ContactCalculation::ContactCalculation()
{
}

ContactCalculation::~ContactCalculation()
{
}

void ContactCalculation::registerDcdContactCalculation(const std::shared_ptr<ContactCalculation>& calculation)
{
	std::call_once(m_initializationFlag, ContactCalculation::initializeTables);

	privateDcdRegister(calculation, calculation->getShapeTypes());
}

void ContactCalculation::registerCcdContactCalculation(const std::shared_ptr<ContactCalculation>& calculation)
{
	std::call_once(m_initializationFlag, ContactCalculation::initializeTables);

	privateCcdRegister(calculation, calculation->getShapeTypes());
}

const ContactCalculation::TableType& ContactCalculation::getDcdContactTable()
{
	std::call_once(m_initializationFlag, ContactCalculation::initializeTables);

	return m_contactDcdCalculations;
}

const ContactCalculation::TableType& ContactCalculation::getCcdContactTable()
{
	std::call_once(m_initializationFlag, ContactCalculation::initializeTables);

	return m_contactCcdCalculations;
}

void ContactCalculation::calculateContact(std::shared_ptr<CollisionPair> pair)
{
	doCalculateContact(pair);
}

std::list<std::shared_ptr<Contact>> ContactCalculation::calculateDcdContact(
									 const Math::PosedShape<std::shared_ptr<Math::Shape>> posedShape1,
									 const Math::PosedShape<std::shared_ptr<Math::Shape>> posedShape2)
{
	auto types = getShapeTypes();
	auto incoming = std::make_pair(posedShape1.getShape()->getType(), posedShape2.getShape()->getType());
	if (incoming == types)
	{
		return doCalculateDcdContact(posedShape1, posedShape2);
	}

	if (incoming.first == types.second && incoming.second == types.first)
	{
		auto contacts = doCalculateDcdContact(posedShape2, posedShape1);
		for (const auto& contact : contacts)
		{
			contact->normal = -contact->normal;
			contact->force = -contact->force;
			std::swap(contact->penetrationPoints.first, contact->penetrationPoints.second);
		}
		return contacts;
	}

	if (types.first != Math::SHAPE_TYPE_NONE && types.second != Math::SHAPE_TYPE_NONE)
	{
		SURGSIM_FAILURE() << "Incorrect shape type for this calculation expected "
						  << types.first << ", " << types.second
						  << " received " << incoming.first << ", " << incoming.second << ".";
	}

	return std::list<std::shared_ptr<Contact>>();
}

void ContactCalculation::doCalculateContact(std::shared_ptr<CollisionPair> pair)
{
	std::pair<int, int> shapeTypes = getShapeTypes();
	int firstShapeType = pair->getFirst()->getShapeType();
	int secondShapeType = pair->getSecond()->getShapeType();

	if (firstShapeType != secondShapeType && firstShapeType == shapeTypes.second &&
		secondShapeType == shapeTypes.first)
	{
		pair->swapRepresentations();
		std::swap(firstShapeType, secondShapeType);
	}

	if (shapeTypes.first != SurgSim::Math::SHAPE_TYPE_NONE)
	{
		SURGSIM_ASSERT(firstShapeType == shapeTypes.first) <<
				"First Object, wrong type of object" << firstShapeType;
	}

	if (shapeTypes.second != SurgSim::Math::SHAPE_TYPE_NONE)
	{
		SURGSIM_ASSERT(secondShapeType == shapeTypes.second) <<
				"Second Object, wrong type of object" << secondShapeType;
	}

	auto& shape1 = pair->getFirst()->getPosedShape();

	auto& shape2 = pair->getSecond()->getPosedShape();

	std::list<std::shared_ptr<Contact>> contacts;
	if (pair->getType() == Collision::CollisionDetectionType::COLLISION_DETECTION_TYPE_DISCRETE)
	{
		Math::PosedShape<std::shared_ptr<Math::Shape>> posedShape1(shape1, pair->getFirst()->getPose());
		Math::PosedShape<std::shared_ptr<Math::Shape>> posedShape2(shape2, pair->getSecond()->getPose());
		contacts = doCalculateDcdContact(posedShape1, posedShape2);
	}
	else if (pair->getType() == Collision::CollisionDetectionType::COLLISION_DETECTION_TYPE_CONTINUOUS)
	{
		contacts = doCalculateCcdContact(
					   pair->getFirst()->getPosedShapeMotion(),
					   pair->getSecond()->getPosedShapeMotion());
	}
	else
	{
		SURGSIM_FAILURE() << "Invalid collision detection type, neither discrete nor continuous";
	}

	for (auto& contact : contacts)
	{
		pair->addContact(contact);
	}
}

std::list<std::shared_ptr<Contact>> ContactCalculation::doCalculateDcdContact(
									 const Math::PosedShape<std::shared_ptr<Math::Shape>>& posedShape1,
									 const Math::PosedShape<std::shared_ptr<Math::Shape>>& posedShape2)
{
	SURGSIM_FAILURE() << "Not implemented";
	return std::list<std::shared_ptr<Contact>>();
}

std::list<std::shared_ptr<Contact>> ContactCalculation::doCalculateCcdContact(
									 const Math::PosedShapeMotion<std::shared_ptr<Math::Shape>>& posedShapeMotion1,
									 const Math::PosedShapeMotion<std::shared_ptr<Math::Shape>>& posedShapeMotion2)
{
	SURGSIM_FAILURE() << "Not implemented";
	return std::list<std::shared_ptr<Contact>>();
}

void ContactCalculation::initializeTables()
{
	// Fill up both tables with default empty contact calculation
	for (int i = 0; i < SurgSim::Math::SHAPE_TYPE_COUNT; ++i)
	{
		for (int j = 0; j < SurgSim::Math::SHAPE_TYPE_COUNT; ++j)
		{
			m_contactDcdCalculations[i][j].reset(new Collision::DefaultContactCalculation(false));
			m_contactCcdCalculations[i][j].reset(new Collision::DefaultContactCalculation(false));
		}
	}

	// Fill up the Dcd contact calculation table
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::BoxCapsuleContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::BoxDoubleSidedPlaneContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::BoxPlaneContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::BoxSphereContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::CapsuleSphereContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::OctreeCapsuleContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::OctreeDoubleSidedPlaneContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::OctreePlaneContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::OctreeSphereContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::SegmentMeshTriangleMeshContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::SphereSphereContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::SphereDoubleSidedPlaneContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::SpherePlaneContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::TriangleMeshParticlesContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::TriangleMeshPlaneContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::TriangleMeshTriangleMeshContact>());

	const std::array<int, Math::SHAPE_TYPE_COUNT> allshapes =
	{
		Math::SHAPE_TYPE_BOX,
		Math::SHAPE_TYPE_CAPSULE,
		Math::SHAPE_TYPE_CYLINDER,
		Math::SHAPE_TYPE_DOUBLESIDEDPLANE,
		Math::SHAPE_TYPE_MESH,
		Math::SHAPE_TYPE_OCTREE,
		Math::SHAPE_TYPE_PARTICLES,
		Math::SHAPE_TYPE_PLANE,
		Math::SHAPE_TYPE_SPHERE,
		Math::SHAPE_TYPE_SURFACEMESH,
		Math::SHAPE_TYPE_SEGMENTMESH,
		Math::SHAPE_TYPE_COMPOUNDSHAPE
	};

	for (auto type : allshapes)
	{
		ContactCalculation::privateDcdRegister(std::make_shared<Collision::CompoundShapeContact>(
				std::make_pair(Math::SHAPE_TYPE_COMPOUNDSHAPE, type)));
	}

	ContactCalculation::privateCcdRegister(std::make_shared<Collision::SegmentSelfContact>());
	ContactCalculation::privateCcdRegister(std::make_shared<Collision::SegmentMeshTriangleMeshContact>());
}

void ContactCalculation::privateDcdRegister(
	const std::shared_ptr<ContactCalculation>& calculation)
{
	privateDcdRegister(calculation, calculation->getShapeTypes());
}

void ContactCalculation::privateDcdRegister(
	const std::shared_ptr<ContactCalculation>& calculation,
	const std::pair<int, int>& types)
{
	m_contactDcdCalculations[types.first][types.second] = calculation;
	m_contactDcdCalculations[types.second][types.first] = calculation;
}

void ContactCalculation::privateCcdRegister(
	const std::shared_ptr<ContactCalculation>& calculation)
{
	privateCcdRegister(calculation, calculation->getShapeTypes());
}

void ContactCalculation::privateCcdRegister(
	const std::shared_ptr<ContactCalculation>& calculation,
	const std::pair<int, int>& types)
{
	m_contactCcdCalculations[types.first][types.second] = calculation;
	m_contactCcdCalculations[types.second][types.first] = calculation;
}

}; // namespace Collision
}; // namespace SurgSim
<commit_msg>Fix Linux build<commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2013-2016, SimQuest Solutions Inc.
//
// 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 <thread>

#include "SurgSim/Collision/CcdDcdCollision.h"
#include "SurgSim/Collision/ContactCalculation.h"
#include "SurgSim/Collision/DefaultContactCalculation.h"
#include "SurgSim/Collision/Representation.h"
#include "SurgSim/Framework/Log.h"

namespace SurgSim
{
namespace Collision
{

ContactCalculation::TableType ContactCalculation::m_contactDcdCalculations;
ContactCalculation::TableType ContactCalculation::m_contactCcdCalculations;
std::once_flag ContactCalculation::m_initializationFlag;

ContactCalculation::ContactCalculation()
{
}

ContactCalculation::~ContactCalculation()
{
}

void ContactCalculation::registerDcdContactCalculation(const std::shared_ptr<ContactCalculation>& calculation)
{
	std::call_once(m_initializationFlag, ContactCalculation::initializeTables);

	privateDcdRegister(calculation, calculation->getShapeTypes());
}

void ContactCalculation::registerCcdContactCalculation(const std::shared_ptr<ContactCalculation>& calculation)
{
	std::call_once(m_initializationFlag, ContactCalculation::initializeTables);

	privateCcdRegister(calculation, calculation->getShapeTypes());
}

const ContactCalculation::TableType& ContactCalculation::getDcdContactTable()
{
	std::call_once(m_initializationFlag, ContactCalculation::initializeTables);

	return m_contactDcdCalculations;
}

const ContactCalculation::TableType& ContactCalculation::getCcdContactTable()
{
	std::call_once(m_initializationFlag, ContactCalculation::initializeTables);

	return m_contactCcdCalculations;
}

void ContactCalculation::calculateContact(std::shared_ptr<CollisionPair> pair)
{
	doCalculateContact(pair);
}

std::list<std::shared_ptr<Contact>> ContactCalculation::calculateDcdContact(
									 const Math::PosedShape<std::shared_ptr<Math::Shape>> posedShape1,
									 const Math::PosedShape<std::shared_ptr<Math::Shape>> posedShape2)
{
	auto types = getShapeTypes();
	auto incoming = std::make_pair(posedShape1.getShape()->getType(), posedShape2.getShape()->getType());
	if (incoming == types)
	{
		return doCalculateDcdContact(posedShape1, posedShape2);
	}

	if (incoming.first == types.second && incoming.second == types.first)
	{
		auto contacts = doCalculateDcdContact(posedShape2, posedShape1);
		for (const auto& contact : contacts)
		{
			contact->normal = -contact->normal;
			contact->force = -contact->force;
			std::swap(contact->penetrationPoints.first, contact->penetrationPoints.second);
		}
		return contacts;
	}

	if (types.first != Math::SHAPE_TYPE_NONE && types.second != Math::SHAPE_TYPE_NONE)
	{
		SURGSIM_FAILURE() << "Incorrect shape type for this calculation expected "
						  << types.first << ", " << types.second
						  << " received " << incoming.first << ", " << incoming.second << ".";
	}

	return std::list<std::shared_ptr<Contact>>();
}

void ContactCalculation::doCalculateContact(std::shared_ptr<CollisionPair> pair)
{
	std::pair<int, int> shapeTypes = getShapeTypes();
	int firstShapeType = pair->getFirst()->getShapeType();
	int secondShapeType = pair->getSecond()->getShapeType();

	if (firstShapeType != secondShapeType && firstShapeType == shapeTypes.second &&
		secondShapeType == shapeTypes.first)
	{
		pair->swapRepresentations();
		std::swap(firstShapeType, secondShapeType);
	}

	if (shapeTypes.first != SurgSim::Math::SHAPE_TYPE_NONE)
	{
		SURGSIM_ASSERT(firstShapeType == shapeTypes.first) <<
				"First Object, wrong type of object" << firstShapeType;
	}

	if (shapeTypes.second != SurgSim::Math::SHAPE_TYPE_NONE)
	{
		SURGSIM_ASSERT(secondShapeType == shapeTypes.second) <<
				"Second Object, wrong type of object" << secondShapeType;
	}

	std::shared_ptr<Math::Shape> shape1 = pair->getFirst()->getPosedShape();

	std::shared_ptr<Math::Shape> shape2 = pair->getSecond()->getPosedShape();

	std::list<std::shared_ptr<Contact>> contacts;
	if (pair->getType() == Collision::CollisionDetectionType::COLLISION_DETECTION_TYPE_DISCRETE)
	{
		Math::PosedShape<std::shared_ptr<Math::Shape>> posedShape1(shape1, pair->getFirst()->getPose());
		Math::PosedShape<std::shared_ptr<Math::Shape>> posedShape2(shape2, pair->getSecond()->getPose());
		contacts = doCalculateDcdContact(posedShape1, posedShape2);
	}
	else if (pair->getType() == Collision::CollisionDetectionType::COLLISION_DETECTION_TYPE_CONTINUOUS)
	{
		contacts = doCalculateCcdContact(
					   pair->getFirst()->getPosedShapeMotion(),
					   pair->getSecond()->getPosedShapeMotion());
	}
	else
	{
		SURGSIM_FAILURE() << "Invalid collision detection type, neither discrete nor continuous";
	}

	for (auto& contact : contacts)
	{
		pair->addContact(contact);
	}
}

std::list<std::shared_ptr<Contact>> ContactCalculation::doCalculateDcdContact(
									 const Math::PosedShape<std::shared_ptr<Math::Shape>>& posedShape1,
									 const Math::PosedShape<std::shared_ptr<Math::Shape>>& posedShape2)
{
	SURGSIM_FAILURE() << "Not implemented";
	return std::list<std::shared_ptr<Contact>>();
}

std::list<std::shared_ptr<Contact>> ContactCalculation::doCalculateCcdContact(
									 const Math::PosedShapeMotion<std::shared_ptr<Math::Shape>>& posedShapeMotion1,
									 const Math::PosedShapeMotion<std::shared_ptr<Math::Shape>>& posedShapeMotion2)
{
	SURGSIM_FAILURE() << "Not implemented";
	return std::list<std::shared_ptr<Contact>>();
}

void ContactCalculation::initializeTables()
{
	// Fill up both tables with default empty contact calculation
	for (int i = 0; i < SurgSim::Math::SHAPE_TYPE_COUNT; ++i)
	{
		for (int j = 0; j < SurgSim::Math::SHAPE_TYPE_COUNT; ++j)
		{
			m_contactDcdCalculations[i][j].reset(new Collision::DefaultContactCalculation(false));
			m_contactCcdCalculations[i][j].reset(new Collision::DefaultContactCalculation(false));
		}
	}

	// Fill up the Dcd contact calculation table
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::BoxCapsuleContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::BoxDoubleSidedPlaneContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::BoxPlaneContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::BoxSphereContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::CapsuleSphereContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::OctreeCapsuleContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::OctreeDoubleSidedPlaneContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::OctreePlaneContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::OctreeSphereContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::SegmentMeshTriangleMeshContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::SphereSphereContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::SphereDoubleSidedPlaneContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::SpherePlaneContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::TriangleMeshParticlesContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::TriangleMeshPlaneContact>());
	ContactCalculation::privateDcdRegister(std::make_shared<Collision::TriangleMeshTriangleMeshContact>());

	const std::array<int, Math::SHAPE_TYPE_COUNT> allshapes =
	{
		Math::SHAPE_TYPE_BOX,
		Math::SHAPE_TYPE_CAPSULE,
		Math::SHAPE_TYPE_CYLINDER,
		Math::SHAPE_TYPE_DOUBLESIDEDPLANE,
		Math::SHAPE_TYPE_MESH,
		Math::SHAPE_TYPE_OCTREE,
		Math::SHAPE_TYPE_PARTICLES,
		Math::SHAPE_TYPE_PLANE,
		Math::SHAPE_TYPE_SPHERE,
		Math::SHAPE_TYPE_SURFACEMESH,
		Math::SHAPE_TYPE_SEGMENTMESH,
		Math::SHAPE_TYPE_COMPOUNDSHAPE
	};

	for (auto type : allshapes)
	{
		ContactCalculation::privateDcdRegister(std::make_shared<Collision::CompoundShapeContact>(
				std::make_pair(Math::SHAPE_TYPE_COMPOUNDSHAPE, type)));
	}

	ContactCalculation::privateCcdRegister(std::make_shared<Collision::SegmentSelfContact>());
	ContactCalculation::privateCcdRegister(std::make_shared<Collision::SegmentMeshTriangleMeshContact>());
}

void ContactCalculation::privateDcdRegister(
	const std::shared_ptr<ContactCalculation>& calculation)
{
	privateDcdRegister(calculation, calculation->getShapeTypes());
}

void ContactCalculation::privateDcdRegister(
	const std::shared_ptr<ContactCalculation>& calculation,
	const std::pair<int, int>& types)
{
	m_contactDcdCalculations[types.first][types.second] = calculation;
	m_contactDcdCalculations[types.second][types.first] = calculation;
}

void ContactCalculation::privateCcdRegister(
	const std::shared_ptr<ContactCalculation>& calculation)
{
	privateCcdRegister(calculation, calculation->getShapeTypes());
}

void ContactCalculation::privateCcdRegister(
	const std::shared_ptr<ContactCalculation>& calculation,
	const std::pair<int, int>& types)
{
	m_contactCcdCalculations[types.first][types.second] = calculation;
	m_contactCcdCalculations[types.second][types.first] = calculation;
}

}; // namespace Collision
}; // namespace SurgSim
<|endoftext|>


<commit_before>/*
    This file is part of Magnum.

    Copyright © 2010, 2011, 2012, 2013, 2014
              Vladimír Vondruš <mosra@centrum.cz>

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

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

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

#include <Corrade/TestSuite/Compare/Container.h>

#include "Magnum/BufferImage.h"
#include "Magnum/ColorFormat.h"
#include "Magnum/Test/AbstractOpenGLTester.h"

namespace Magnum { namespace Test {

class BufferImageTest: public AbstractOpenGLTester {
    public:
        explicit BufferImageTest();

        void construct();
        void constructCopy();
        void constructMove();

        void setData();
};

BufferImageTest::BufferImageTest() {
    addTests({&BufferImageTest::construct,
              &BufferImageTest::constructCopy,
              &BufferImageTest::constructMove,

              &BufferImageTest::setData});
}

void BufferImageTest::construct() {
    const unsigned char data[] = { 'a', 0, 0, 0, 'b', 0, 0, 0, 'c', 0, 0, 0 };
    BufferImage2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data, BufferUsage::StaticDraw);

    #ifndef MAGNUM_TARGET_GLES
    const auto imageData = a.buffer().data<UnsignedByte>();
    #endif

    MAGNUM_VERIFY_NO_ERROR();

    CORRADE_COMPARE(a.format(), ColorFormat::Red);
    CORRADE_COMPARE(a.type(), ColorType::UnsignedByte);
    CORRADE_COMPARE(a.size(), Vector2i(1, 3));

    /** @todo How to verify the contents in ES? */
    #ifndef MAGNUM_TARGET_GLES
    CORRADE_COMPARE_AS(std::vector<UnsignedByte>(imageData.begin(), imageData.end()),
                       std::vector<UnsignedByte>(data, data + 12),
                       TestSuite::Compare::Container);
    #endif
}

void BufferImageTest::constructCopy() {
    CORRADE_VERIFY(!(std::is_constructible<BufferImage2D, const BufferImage2D&>{}));
    CORRADE_VERIFY(!(std::is_assignable<BufferImage2D, const BufferImage2D&>{}));
}

void BufferImageTest::constructMove() {
    const unsigned char data[3] = { 'a', 'b', 'c' };
    BufferImage2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data, BufferUsage::StaticDraw);
    const Int id = a.buffer().id();

    MAGNUM_VERIFY_NO_ERROR();
    CORRADE_VERIFY(id > 0);

    BufferImage2D b(std::move(a));

    CORRADE_COMPARE(a.buffer().id(), 0);
    CORRADE_COMPARE(a.size(), Vector2i());

    CORRADE_COMPARE(b.format(), ColorFormat::Red);
    CORRADE_COMPARE(b.type(), ColorType::UnsignedByte);
    CORRADE_COMPARE(b.size(), Vector2i(1, 3));
    CORRADE_COMPARE(b.buffer().id(), id);

    const unsigned short data2[2*4] = { 1, 2, 3, 4, 5, 6, 7, 8 };
    BufferImage2D c(ColorFormat::RGBA, ColorType::UnsignedShort, {2, 1}, data2, BufferUsage::StaticDraw);
    const Int cId = c.buffer().id();
    c = std::move(b);

    MAGNUM_VERIFY_NO_ERROR();

    CORRADE_VERIFY(cId > 0);
    CORRADE_COMPARE(b.buffer().id(), cId);
    CORRADE_COMPARE(b.size(), Vector2i(2, 1));

    CORRADE_COMPARE(c.format(), ColorFormat::Red);
    CORRADE_COMPARE(c.type(), ColorType::UnsignedByte);
    CORRADE_COMPARE(c.size(), Vector2i(1, 3));
    CORRADE_COMPARE(c.buffer().id(), id);
}

void BufferImageTest::setData() {
    const unsigned char data[3] = { 'a', 'b', 'c' };
    BufferImage2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data, BufferUsage::StaticDraw);

    const unsigned short data2[2*4] = { 1, 2, 3, 4, 5, 6, 7, 8 };
    a.setData(ColorFormat::RGBA, ColorType::UnsignedShort, {2, 1}, data2, BufferUsage::StaticDraw);

    #ifndef MAGNUM_TARGET_GLES
    const auto imageData = a.buffer().data<UnsignedShort>();
    #endif

    MAGNUM_VERIFY_NO_ERROR();

    CORRADE_COMPARE(a.format(), ColorFormat::RGBA);
    CORRADE_COMPARE(a.type(), ColorType::UnsignedShort);
    CORRADE_COMPARE(a.size(), Vector2i(2, 1));

    /** @todo How to verify the contents in ES? */
    #ifndef MAGNUM_TARGET_GLES
    CORRADE_COMPARE_AS(std::vector<UnsignedShort>(imageData.begin(), imageData.end()),
                       std::vector<UnsignedShort>(data2, data2 + 8),
                       TestSuite::Compare::Container);
    #endif
}

}}

CORRADE_TEST_MAIN(Magnum::Test::BufferImageTest)
<commit_msg>Fixed OOB memory access in test.<commit_after>/*
    This file is part of Magnum.

    Copyright © 2010, 2011, 2012, 2013, 2014
              Vladimír Vondruš <mosra@centrum.cz>

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

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

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

#include <Corrade/TestSuite/Compare/Container.h>

#include "Magnum/BufferImage.h"
#include "Magnum/ColorFormat.h"
#include "Magnum/Test/AbstractOpenGLTester.h"

namespace Magnum { namespace Test {

class BufferImageTest: public AbstractOpenGLTester {
    public:
        explicit BufferImageTest();

        void construct();
        void constructCopy();
        void constructMove();

        void setData();
};

BufferImageTest::BufferImageTest() {
    addTests({&BufferImageTest::construct,
              &BufferImageTest::constructCopy,
              &BufferImageTest::constructMove,

              &BufferImageTest::setData});
}

void BufferImageTest::construct() {
    const unsigned char data[] = { 'a', 0, 0, 0, 'b', 0, 0, 0, 'c', 0, 0, 0 };
    BufferImage2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data, BufferUsage::StaticDraw);

    #ifndef MAGNUM_TARGET_GLES
    const auto imageData = a.buffer().data<UnsignedByte>();
    #endif

    MAGNUM_VERIFY_NO_ERROR();

    CORRADE_COMPARE(a.format(), ColorFormat::Red);
    CORRADE_COMPARE(a.type(), ColorType::UnsignedByte);
    CORRADE_COMPARE(a.size(), Vector2i(1, 3));

    /** @todo How to verify the contents in ES? */
    #ifndef MAGNUM_TARGET_GLES
    CORRADE_COMPARE_AS(std::vector<UnsignedByte>(imageData.begin(), imageData.end()),
                       std::vector<UnsignedByte>(data, data + 12),
                       TestSuite::Compare::Container);
    #endif
}

void BufferImageTest::constructCopy() {
    CORRADE_VERIFY(!(std::is_constructible<BufferImage2D, const BufferImage2D&>{}));
    CORRADE_VERIFY(!(std::is_assignable<BufferImage2D, const BufferImage2D&>{}));
}

void BufferImageTest::constructMove() {
    const unsigned char data[4] = { 'a', 'b', 'c', 'd' };
    BufferImage2D a(ColorFormat::Red, ColorType::UnsignedByte, {4, 1}, data, BufferUsage::StaticDraw);
    const Int id = a.buffer().id();

    MAGNUM_VERIFY_NO_ERROR();
    CORRADE_VERIFY(id > 0);

    BufferImage2D b(std::move(a));

    CORRADE_COMPARE(a.buffer().id(), 0);
    CORRADE_COMPARE(a.size(), Vector2i());

    CORRADE_COMPARE(b.format(), ColorFormat::Red);
    CORRADE_COMPARE(b.type(), ColorType::UnsignedByte);
    CORRADE_COMPARE(b.size(), Vector2i(4, 1));
    CORRADE_COMPARE(b.buffer().id(), id);

    const unsigned short data2[2*4] = { 1, 2, 3, 4, 5, 6, 7, 8 };
    BufferImage2D c(ColorFormat::RGBA, ColorType::UnsignedShort, {1, 2}, data2, BufferUsage::StaticDraw);
    const Int cId = c.buffer().id();
    c = std::move(b);

    MAGNUM_VERIFY_NO_ERROR();

    CORRADE_VERIFY(cId > 0);
    CORRADE_COMPARE(b.buffer().id(), cId);
    CORRADE_COMPARE(b.size(), Vector2i(1, 2));

    CORRADE_COMPARE(c.format(), ColorFormat::Red);
    CORRADE_COMPARE(c.type(), ColorType::UnsignedByte);
    CORRADE_COMPARE(c.size(), Vector2i(4, 1));
    CORRADE_COMPARE(c.buffer().id(), id);
}

void BufferImageTest::setData() {
    const unsigned char data[4] = { 'a', 'b', 'c', 'd' };
    BufferImage2D a(ColorFormat::Red, ColorType::UnsignedByte, {4, 1}, data, BufferUsage::StaticDraw);

    const unsigned short data2[2*4] = { 1, 2, 3, 4, 5, 6, 7, 8 };
    a.setData(ColorFormat::RGBA, ColorType::UnsignedShort, {1, 2}, data2, BufferUsage::StaticDraw);

    #ifndef MAGNUM_TARGET_GLES
    const auto imageData = a.buffer().data<UnsignedShort>();
    #endif

    MAGNUM_VERIFY_NO_ERROR();

    CORRADE_COMPARE(a.format(), ColorFormat::RGBA);
    CORRADE_COMPARE(a.type(), ColorType::UnsignedShort);
    CORRADE_COMPARE(a.size(), Vector2i(1, 2));

    /** @todo How to verify the contents in ES? */
    #ifndef MAGNUM_TARGET_GLES
    CORRADE_COMPARE_AS(std::vector<UnsignedShort>(imageData.begin(), imageData.end()),
                       std::vector<UnsignedShort>(data2, data2 + 8),
                       TestSuite::Compare::Container);
    #endif
}

}}

CORRADE_TEST_MAIN(Magnum::Test::BufferImageTest)
<|endoftext|>


<commit_before>//
// Created by michael on 14.08.15.
//

#include "ExploreRegionTemplate.h"
#include "../../World/Space/SpaceWorldModel.h"

using namespace std;
using namespace weave;

ExploreRegionTemplate::ExploreRegionTemplate(string title,
                                             vector<TemplateQuestProperty> properties,
                                             vector<TemplateQuestDescription> descriptions)
        : Template(title, properties, descriptions) {
}

vector<ModelAction> ExploreRegionTemplate::GetPropertyCandidates(const TemplateQuestProperty &property,
                                                                 const WorldModel &worldModel) const {
    vector<ModelAction> properties;
    const SpaceWorldModel &spaceModel = (const SpaceWorldModel &) worldModel;
    std::shared_ptr<WorldEntity> entity;
    if (property.GetName().compare("location") == 0) {
        entity = spaceModel.CreateLocation();
    } else if (property.GetName().compare("sponsor") == 0) {
        entity = spaceModel.CreateAgent();
    }
    ModelAction modelAction(ActionType::CREATE, entity);
    properties.push_back(std::move(modelAction));
    return properties;
}

Quest ExploreRegionTemplate::ToQuest(const vector<QuestPropertyValue> &questPropertyValues) const {
    const string &description = getBestFittingDescription(questPropertyValues);
    const string &title = getTitle(questPropertyValues);
    return Quest(Proposed, title, description);
}
<commit_msg>Better string comparison<commit_after>//
// Created by michael on 14.08.15.
//

#include "ExploreRegionTemplate.h"
#include "../../World/Space/SpaceWorldModel.h"

using namespace std;
using namespace weave;

ExploreRegionTemplate::ExploreRegionTemplate(string title,
                                             vector<TemplateQuestProperty> properties,
                                             vector<TemplateQuestDescription> descriptions)
        : Template(title, properties, descriptions) {
}

vector<ModelAction> ExploreRegionTemplate::GetPropertyCandidates(const TemplateQuestProperty &property,
                                                                 const WorldModel &worldModel) const {
    vector<ModelAction> properties;
    const SpaceWorldModel &spaceModel = (const SpaceWorldModel &) worldModel;
    std::shared_ptr<WorldEntity> entity;
    if (property.GetName() == "location") {
        entity = spaceModel.CreateLocation();
    } else if (property.GetName() == "sponsor") {
        entity = spaceModel.CreateAgent();
    }
    ModelAction modelAction(ActionType::CREATE, entity);
    properties.push_back(std::move(modelAction));
    return properties;
}

Quest ExploreRegionTemplate::ToQuest(const vector<QuestPropertyValue> &questPropertyValues) const {
    const string &description = getBestFittingDescription(questPropertyValues);
    const string &title = getTitle(questPropertyValues);
    return Quest(Proposed, title, description);
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016-2017 mvs developers
 *
 * This file is part of metaverse-explorer.
 *
 * metaverse-explorer is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <metaverse/explorer/json_helper.hpp>
#include <metaverse/explorer/dispatch.hpp>
#include <metaverse/explorer/extensions/commands/importaccount.hpp>
#include <metaverse/explorer/extensions/command_extension_func.hpp>
#include <metaverse/explorer/extensions/command_assistant.hpp>
#include <metaverse/explorer/extensions/exception.hpp>
#include <metaverse/explorer/commands/offline_commands_impl.hpp>

namespace libbitcoin {
namespace explorer {
namespace commands {
using namespace bc::explorer::config;

console_result importaccount::invoke (Json::Value& jv_output,
         libbitcoin::server::server_node& node)
{

    // parameter account name check
    auto& blockchain = node.chain_impl();
    if (blockchain.is_account_exist(auth_.name))
     throw account_existed_exception{"account already exist"};

#ifdef NDEBUG
	if (auth_.name.length() > 128 || auth_.name.length() < 3 ||
	    option_.passwd.length() > 128 || option_.passwd.length() < 6)
	    throw argument_exceed_limit_exception{"name length in [3, 128], password length in [6, 128]"};
#endif

    // are vliad mnemonic words.
    auto&& seed = get_mnemonic_to_seed(option_.language, argument_.words);
    // is vliad seed.
    auto&& hd_pri_key = get_hd_new(seed);

    auto&& mnemonic = bc::join(argument_.words);

    // create account
    auto acc = std::make_shared<bc::chain::account>();
    acc->set_name(auth_.name);
    acc->set_passwd(option_.passwd);
    acc->set_mnemonic(mnemonic, option_.passwd);
    //acc->set_hd_index(option_.hd_index); // hd_index updated in getnewaddress

    // flush to db
    blockchain.store_account(acc);

    // generate all account address
    auto& root = jv_output;
    root["name"] = auth_.name;
    root["mnemonic"] = mnemonic;
    if (get_api_version() == 1) {
        root["hd_index"] += option_.hd_index;
    } else {
        root["hd_index"] = option_.hd_index;
    }

    uint32_t idx = 0;
    auto&& str_idx = std::to_string(option_.hd_index);
    const char* cmds2[]{"getnewaddress", auth_.name.c_str(), option_.passwd.c_str(), "-n", str_idx.c_str()};
    Json::Value addresses;

    if (dispatch_command(5, cmds2, addresses, node, 2) != console_result::okay) {
        throw address_generate_exception{"getnewaddress got exception."};
    }

    root["addresses"] = addresses["addresses"];

    return console_result::okay;
}

} // namespace commands
} // namespace explorer
} // namespace libbitcoin

<commit_msg>fix importaccount rpc call mnemonic parse error<commit_after>/**
 * Copyright (c) 2016-2017 mvs developers
 *
 * This file is part of metaverse-explorer.
 *
 * metaverse-explorer is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <boost/algorithm/string.hpp>
#include <metaverse/explorer/json_helper.hpp>
#include <metaverse/explorer/dispatch.hpp>
#include <metaverse/explorer/extensions/commands/importaccount.hpp>
#include <metaverse/explorer/extensions/command_extension_func.hpp>
#include <metaverse/explorer/extensions/command_assistant.hpp>
#include <metaverse/explorer/extensions/exception.hpp>
#include <metaverse/explorer/commands/offline_commands_impl.hpp>

namespace libbitcoin {
namespace explorer {
namespace commands {
using namespace bc::explorer::config;

console_result importaccount::invoke (Json::Value& jv_output,
         libbitcoin::server::server_node& node)
{

    // parameter account name check
    auto& blockchain = node.chain_impl();
    if (blockchain.is_account_exist(auth_.name))
     throw account_existed_exception{"account already exist"};

#ifdef NDEBUG
	if (auth_.name.length() > 128 || auth_.name.length() < 3 ||
	    option_.passwd.length() > 128 || option_.passwd.length() < 6)
	    throw argument_exceed_limit_exception{"name length in [3, 128], password length in [6, 128]"};
#endif

    if (argument_.words.size() == 1)
    {
        boost::split(argument_.words, argument_.words[0], boost::is_any_of(" "));
    }

    // are vliad mnemonic words.
    auto&& seed = get_mnemonic_to_seed(option_.language, argument_.words);
    // is vliad seed.
    auto&& hd_pri_key = get_hd_new(seed);

    auto&& mnemonic = bc::join(argument_.words);

    // create account
    auto acc = std::make_shared<bc::chain::account>();
    acc->set_name(auth_.name);
    acc->set_passwd(option_.passwd);
    acc->set_mnemonic(mnemonic, option_.passwd);
    //acc->set_hd_index(option_.hd_index); // hd_index updated in getnewaddress

    // flush to db
    blockchain.store_account(acc);

    // generate all account address
    auto& root = jv_output;
    root["name"] = auth_.name;
    root["mnemonic"] = mnemonic;
    if (get_api_version() == 1) {
        root["hd_index"] += option_.hd_index;
    } else {
        root["hd_index"] = option_.hd_index;
    }

    uint32_t idx = 0;
    auto&& str_idx = std::to_string(option_.hd_index);
    const char* cmds2[]{"getnewaddress", auth_.name.c_str(), option_.passwd.c_str(), "-n", str_idx.c_str()};
    Json::Value addresses;

    if (dispatch_command(5, cmds2, addresses, node, 2) != console_result::okay) {
        throw address_generate_exception{"getnewaddress got exception."};
    }

    root["addresses"] = addresses["addresses"];

    return console_result::okay;
}

} // namespace commands
} // namespace explorer
} // namespace libbitcoin

<|endoftext|>


<commit_before>// Scintilla source code edit control
/** @file LexMatlab.cxx
 ** Lexer for Matlab.
 ** Written by Jos Fonseca
 **
 ** Changes by Christoph Dalitz 2003/12/04:
 **   - added support for Octave
 **   - Strings can now be included both in single or double quotes
 **
 ** Changes by John Donoghue 2012/04/02
 **   - added block comment (and nested block comments)
 **   - added ... displayed as a comment
 **   - removed unused IsAWord functions
 **   - added some comments
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>

#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"

#include "WordList.h"
#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "CharacterSet.h"
#include "LexerModule.h"

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

static bool IsMatlabCommentChar(int c) {
	return (c == '%') ;
}

static bool IsOctaveCommentChar(int c) {
	return (c == '%' || c == '#') ;
}

static bool IsMatlabComment(Accessor &styler, int pos, int len) {
	return len > 0 && IsMatlabCommentChar(styler[pos]) ;
}

static bool IsOctaveComment(Accessor &styler, int pos, int len) {
	return len > 0 && IsOctaveCommentChar(styler[pos]) ;
}

static void ColouriseMatlabOctaveDoc(
            unsigned int startPos, int length, int initStyle,
            WordList *keywordlists[], Accessor &styler,
            bool (*IsCommentChar)(int),
            bool ismatlab) {

	WordList &keywords = *keywordlists[0];

	styler.StartAt(startPos);

	// boolean for when the ' is allowed to be transpose vs the start/end
	// of a string
	bool transpose = false;

	// approximate position of first non space character in a line
	int nonSpaceColumn = -1;
	// approximate column position of the current character in a line
	int column = 0;

        // use the line state of each line to store the block comment depth
	int curLine = styler.GetLine(startPos);
        int commentDepth = curLine > 0 ? styler.GetLineState(curLine-1) : 0;

	StyleContext sc(startPos, length, initStyle, styler);

	for (; sc.More(); sc.Forward(), column++) {

               	if(sc.atLineStart) {
			// set the line state to the current commentDepth
			curLine = styler.GetLine(sc.currentPos);
                        styler.SetLineState(curLine, commentDepth);

			// reset the column to 0, nonSpace to -1 (not set)
			column = 0;
			nonSpaceColumn = -1;
		}

		// save the column position of first non space character in a line
		if((nonSpaceColumn == -1) && (! IsASpace(sc.ch)))
		{
			nonSpaceColumn = column;
		}

		// check for end of states
		if (sc.state == SCE_MATLAB_OPERATOR) {
			if (sc.chPrev == '.') {
				if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\' || sc.ch == '^') {
					sc.ForwardSetState(SCE_MATLAB_DEFAULT);
					transpose = false;
				} else if (sc.ch == '\'') {
					sc.ForwardSetState(SCE_MATLAB_DEFAULT);
					transpose = true;
                                } else if(sc.ch == '.' && sc.chNext == '.') {
                                        // we werent an operator, but a '...'
                                        sc.ChangeState(SCE_MATLAB_COMMENT);
                                        transpose = false;
				} else {
					sc.SetState(SCE_MATLAB_DEFAULT);
				}
			} else {
				sc.SetState(SCE_MATLAB_DEFAULT);
			}
		} else if (sc.state == SCE_MATLAB_KEYWORD) {
			if (!isalnum(sc.ch) && sc.ch != '_') {
				char s[100];
				sc.GetCurrentLowered(s, sizeof(s));
				if (keywords.InList(s)) {
					sc.SetState(SCE_MATLAB_DEFAULT);
					transpose = false;
				} else {
					sc.ChangeState(SCE_MATLAB_IDENTIFIER);
					sc.SetState(SCE_MATLAB_DEFAULT);
					transpose = true;
				}
			}
		} else if (sc.state == SCE_MATLAB_NUMBER) {
			if (!isdigit(sc.ch) && sc.ch != '.'
			        && !(sc.ch == 'e' || sc.ch == 'E')
			        && !((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E'))) {
				sc.SetState(SCE_MATLAB_DEFAULT);
				transpose = true;
			}
		} else if (sc.state == SCE_MATLAB_STRING) {
			if (sc.ch == '\'') {
				if (sc.chNext == '\'') {
 					sc.Forward();
				} else {
					sc.ForwardSetState(SCE_MATLAB_DEFAULT);
 				}
			}
		} else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) {
			if (sc.ch == '\\') {
				if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
					sc.Forward();
				}
			} else if (sc.ch == '\"') {
				sc.ForwardSetState(SCE_MATLAB_DEFAULT);
			}
		} else if (sc.state == SCE_MATLAB_COMMAND) {
			if (sc.atLineEnd) {
				sc.SetState(SCE_MATLAB_DEFAULT);
				transpose = false;
			}
		} else if (sc.state == SCE_MATLAB_COMMENT) {
			// end or start of a nested a block comment?
			if( IsCommentChar(sc.ch) && sc.chNext == '}' && nonSpaceColumn == column) {
                           	if(commentDepth > 0) commentDepth --;

				curLine = styler.GetLine(sc.currentPos);
				styler.SetLineState(curLine, commentDepth);
				sc.Forward();

				if (commentDepth == 0) {
					sc.ForwardSetState(SCE_D_DEFAULT);
					transpose = false;
				}
                        }
                        else if( IsCommentChar(sc.ch) && sc.chNext == '{' && nonSpaceColumn == column)
                        {
 				commentDepth ++;

				curLine = styler.GetLine(sc.currentPos);
				styler.SetLineState(curLine, commentDepth);
				sc.Forward();
				transpose = false;

                        } else if(commentDepth == 0) {
				// single line comment
				if (sc.atLineEnd || sc.ch == '\r' || sc.ch == '\n') {
					sc.SetState(SCE_MATLAB_DEFAULT);
					transpose = false;
				}
			}
		}

		// check start of a new state
		if (sc.state == SCE_MATLAB_DEFAULT) {
			if (IsCommentChar(sc.ch)) {
				// ncrement depth if we are a block comment
				if(sc.chNext == '{' && nonSpaceColumn == column)
					commentDepth ++;
				curLine = styler.GetLine(sc.currentPos);
				styler.SetLineState(curLine, commentDepth);
				sc.SetState(SCE_MATLAB_COMMENT);
			} else if (sc.ch == '!' && sc.chNext != '=' ) {
				if(ismatlab) {
					sc.SetState(SCE_MATLAB_COMMAND);
				} else {
					sc.SetState(SCE_MATLAB_OPERATOR);
				}
			} else if (sc.ch == '\'') {
				if (transpose) {
					sc.SetState(SCE_MATLAB_OPERATOR);
				} else {
					sc.SetState(SCE_MATLAB_STRING);
				}
			} else if (sc.ch == '"') {
				sc.SetState(SCE_MATLAB_DOUBLEQUOTESTRING);
			} else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
				sc.SetState(SCE_MATLAB_NUMBER);
			} else if (isalpha(sc.ch)) {
				sc.SetState(SCE_MATLAB_KEYWORD);
			} else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '\\') {
				if (sc.ch == ')' || sc.ch == ']') {
					transpose = true;
				} else {
					transpose = false;
				}
				sc.SetState(SCE_MATLAB_OPERATOR);
			} else {
				transpose = false;
			}
		}
	}
	sc.Complete();
}

static void ColouriseMatlabDoc(unsigned int startPos, int length, int initStyle,
                               WordList *keywordlists[], Accessor &styler) {
	ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar, true);
}

static void ColouriseOctaveDoc(unsigned int startPos, int length, int initStyle,
                               WordList *keywordlists[], Accessor &styler) {
	ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar, false);
}

static void FoldMatlabOctaveDoc(unsigned int startPos, int length, int,
                                WordList *[], Accessor &styler,
                                bool (*IsComment)(Accessor&, int, int)) {

	int endPos = startPos + length;

	// Backtrack to previous line in case need to fix its fold status
	int lineCurrent = styler.GetLine(startPos);
	if (startPos > 0) {
		if (lineCurrent > 0) {
			lineCurrent--;
			startPos = styler.LineStart(lineCurrent);
		}
	}
	int spaceFlags = 0;
	int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsComment);
	char chNext = styler[startPos];
	for (int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);

		if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
			int lev = indentCurrent;
			int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsComment);
			if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
				// Only non whitespace lines can be headers
				if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
					lev |= SC_FOLDLEVELHEADERFLAG;
				} else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
					// Line after is blank so check the next - maybe should continue further?
					int spaceFlags2 = 0;
					int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsComment);
					if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
						lev |= SC_FOLDLEVELHEADERFLAG;
					}
				}
			}
			indentCurrent = indentNext;
			styler.SetLevel(lineCurrent, lev);
			lineCurrent++;
		}
	}
}

static void FoldMatlabDoc(unsigned int startPos, int length, int initStyle,
                          WordList *keywordlists[], Accessor &styler) {
	FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabComment);
}

static void FoldOctaveDoc(unsigned int startPos, int length, int initStyle,
                          WordList *keywordlists[], Accessor &styler) {
	FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveComment);
}

static const char * const matlabWordListDesc[] = {
	"Keywords",
	0
};

static const char * const octaveWordListDesc[] = {
	"Keywords",
	0
};

LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc, matlabWordListDesc);

LexerModule lmOctave(SCLEX_OCTAVE, ColouriseOctaveDoc, "octave", FoldOctaveDoc, octaveWordListDesc);
<commit_msg>Support transpose character after {} operator<commit_after>// Scintilla source code edit control
/** @file LexMatlab.cxx
 ** Lexer for Matlab.
 ** Written by Jos Fonseca
 **
 ** Changes by Christoph Dalitz 2003/12/04:
 **   - added support for Octave
 **   - Strings can now be included both in single or double quotes
 **
 ** Changes by John Donoghue 2012/04/02
 **   - added block comment (and nested block comments)
 **   - added ... displayed as a comment
 **   - removed unused IsAWord functions
 **   - added some comments
 **
 ** Changes by John Donoghue 2014/08/01
 **   - fix allowed transpose ' after {} operator
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>

#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"

#include "WordList.h"
#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "CharacterSet.h"
#include "LexerModule.h"

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

static bool IsMatlabCommentChar(int c) {
	return (c == '%') ;
}

static bool IsOctaveCommentChar(int c) {
	return (c == '%' || c == '#') ;
}

static bool IsMatlabComment(Accessor &styler, int pos, int len) {
	return len > 0 && IsMatlabCommentChar(styler[pos]) ;
}

static bool IsOctaveComment(Accessor &styler, int pos, int len) {
	return len > 0 && IsOctaveCommentChar(styler[pos]) ;
}

static void ColouriseMatlabOctaveDoc(
            unsigned int startPos, int length, int initStyle,
            WordList *keywordlists[], Accessor &styler,
            bool (*IsCommentChar)(int),
            bool ismatlab) {

	WordList &keywords = *keywordlists[0];

	styler.StartAt(startPos);

	// boolean for when the ' is allowed to be transpose vs the start/end
	// of a string
	bool transpose = false;

	// approximate position of first non space character in a line
	int nonSpaceColumn = -1;
	// approximate column position of the current character in a line
	int column = 0;

        // use the line state of each line to store the block comment depth
	int curLine = styler.GetLine(startPos);
        int commentDepth = curLine > 0 ? styler.GetLineState(curLine-1) : 0;

	StyleContext sc(startPos, length, initStyle, styler);

	for (; sc.More(); sc.Forward(), column++) {

               	if(sc.atLineStart) {
			// set the line state to the current commentDepth
			curLine = styler.GetLine(sc.currentPos);
                        styler.SetLineState(curLine, commentDepth);

			// reset the column to 0, nonSpace to -1 (not set)
			column = 0;
			nonSpaceColumn = -1;
		}

		// save the column position of first non space character in a line
		if((nonSpaceColumn == -1) && (! IsASpace(sc.ch)))
		{
			nonSpaceColumn = column;
		}

		// check for end of states
		if (sc.state == SCE_MATLAB_OPERATOR) {
			if (sc.chPrev == '.') {
				if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\' || sc.ch == '^') {
					sc.ForwardSetState(SCE_MATLAB_DEFAULT);
					transpose = false;
				} else if (sc.ch == '\'') {
					sc.ForwardSetState(SCE_MATLAB_DEFAULT);
					transpose = true;
                                } else if(sc.ch == '.' && sc.chNext == '.') {
                                        // we werent an operator, but a '...'
                                        sc.ChangeState(SCE_MATLAB_COMMENT);
                                        transpose = false;
				} else {
					sc.SetState(SCE_MATLAB_DEFAULT);
				}
			} else {
				sc.SetState(SCE_MATLAB_DEFAULT);
			}
		} else if (sc.state == SCE_MATLAB_KEYWORD) {
			if (!isalnum(sc.ch) && sc.ch != '_') {
				char s[100];
				sc.GetCurrentLowered(s, sizeof(s));
				if (keywords.InList(s)) {
					sc.SetState(SCE_MATLAB_DEFAULT);
					transpose = false;
				} else {
					sc.ChangeState(SCE_MATLAB_IDENTIFIER);
					sc.SetState(SCE_MATLAB_DEFAULT);
					transpose = true;
				}
			}
		} else if (sc.state == SCE_MATLAB_NUMBER) {
			if (!isdigit(sc.ch) && sc.ch != '.'
			        && !(sc.ch == 'e' || sc.ch == 'E')
			        && !((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E'))) {
				sc.SetState(SCE_MATLAB_DEFAULT);
				transpose = true;
			}
		} else if (sc.state == SCE_MATLAB_STRING) {
			if (sc.ch == '\'') {
				if (sc.chNext == '\'') {
 					sc.Forward();
				} else {
					sc.ForwardSetState(SCE_MATLAB_DEFAULT);
 				}
			}
		} else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) {
			if (sc.ch == '\\') {
				if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
					sc.Forward();
				}
			} else if (sc.ch == '\"') {
				sc.ForwardSetState(SCE_MATLAB_DEFAULT);
			}
		} else if (sc.state == SCE_MATLAB_COMMAND) {
			if (sc.atLineEnd) {
				sc.SetState(SCE_MATLAB_DEFAULT);
				transpose = false;
			}
		} else if (sc.state == SCE_MATLAB_COMMENT) {
			// end or start of a nested a block comment?
			if( IsCommentChar(sc.ch) && sc.chNext == '}' && nonSpaceColumn == column) {
                           	if(commentDepth > 0) commentDepth --;

				curLine = styler.GetLine(sc.currentPos);
				styler.SetLineState(curLine, commentDepth);
				sc.Forward();

				if (commentDepth == 0) {
					sc.ForwardSetState(SCE_D_DEFAULT);
					transpose = false;
				}
                        }
                        else if( IsCommentChar(sc.ch) && sc.chNext == '{' && nonSpaceColumn == column)
                        {
 				commentDepth ++;

				curLine = styler.GetLine(sc.currentPos);
				styler.SetLineState(curLine, commentDepth);
				sc.Forward();
				transpose = false;

                        } else if(commentDepth == 0) {
				// single line comment
				if (sc.atLineEnd || sc.ch == '\r' || sc.ch == '\n') {
					sc.SetState(SCE_MATLAB_DEFAULT);
					transpose = false;
				}
			}
		}

		// check start of a new state
		if (sc.state == SCE_MATLAB_DEFAULT) {
			if (IsCommentChar(sc.ch)) {
				// ncrement depth if we are a block comment
				if(sc.chNext == '{' && nonSpaceColumn == column)
					commentDepth ++;
				curLine = styler.GetLine(sc.currentPos);
				styler.SetLineState(curLine, commentDepth);
				sc.SetState(SCE_MATLAB_COMMENT);
			} else if (sc.ch == '!' && sc.chNext != '=' ) {
				if(ismatlab) {
					sc.SetState(SCE_MATLAB_COMMAND);
				} else {
					sc.SetState(SCE_MATLAB_OPERATOR);
				}
			} else if (sc.ch == '\'') {
				if (transpose) {
					sc.SetState(SCE_MATLAB_OPERATOR);
				} else {
					sc.SetState(SCE_MATLAB_STRING);
				}
			} else if (sc.ch == '"') {
				sc.SetState(SCE_MATLAB_DOUBLEQUOTESTRING);
			} else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
				sc.SetState(SCE_MATLAB_NUMBER);
			} else if (isalpha(sc.ch)) {
				sc.SetState(SCE_MATLAB_KEYWORD);
			} else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '\\') {
				if (sc.ch == ')' || sc.ch == ']' || sc.ch == '}') {
					transpose = true;
				} else {
					transpose = false;
				}
				sc.SetState(SCE_MATLAB_OPERATOR);
			} else {
				transpose = false;
			}
		}
	}
	sc.Complete();
}

static void ColouriseMatlabDoc(unsigned int startPos, int length, int initStyle,
                               WordList *keywordlists[], Accessor &styler) {
	ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar, true);
}

static void ColouriseOctaveDoc(unsigned int startPos, int length, int initStyle,
                               WordList *keywordlists[], Accessor &styler) {
	ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar, false);
}

static void FoldMatlabOctaveDoc(unsigned int startPos, int length, int,
                                WordList *[], Accessor &styler,
                                bool (*IsComment)(Accessor&, int, int)) {

	int endPos = startPos + length;

	// Backtrack to previous line in case need to fix its fold status
	int lineCurrent = styler.GetLine(startPos);
	if (startPos > 0) {
		if (lineCurrent > 0) {
			lineCurrent--;
			startPos = styler.LineStart(lineCurrent);
		}
	}
	int spaceFlags = 0;
	int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsComment);
	char chNext = styler[startPos];
	for (int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);

		if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
			int lev = indentCurrent;
			int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsComment);
			if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
				// Only non whitespace lines can be headers
				if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
					lev |= SC_FOLDLEVELHEADERFLAG;
				} else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
					// Line after is blank so check the next - maybe should continue further?
					int spaceFlags2 = 0;
					int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsComment);
					if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
						lev |= SC_FOLDLEVELHEADERFLAG;
					}
				}
			}
			indentCurrent = indentNext;
			styler.SetLevel(lineCurrent, lev);
			lineCurrent++;
		}
	}
}

static void FoldMatlabDoc(unsigned int startPos, int length, int initStyle,
                          WordList *keywordlists[], Accessor &styler) {
	FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabComment);
}

static void FoldOctaveDoc(unsigned int startPos, int length, int initStyle,
                          WordList *keywordlists[], Accessor &styler) {
	FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveComment);
}

static const char * const matlabWordListDesc[] = {
	"Keywords",
	0
};

static const char * const octaveWordListDesc[] = {
	"Keywords",
	0
};

LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc, matlabWordListDesc);

LexerModule lmOctave(SCLEX_OCTAVE, ColouriseOctaveDoc, "octave", FoldOctaveDoc, octaveWordListDesc);
<|endoftext|>