<commit_before>/*************************************************************************
 *
 *  $RCSfile: scripttypedetector.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2004-03-08 17:17:18 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <com/sun/star/i18n/CTLScriptType.hpp>
#include <com/sun/star/i18n/ScriptDirection.hpp>
#include <com/sun/star/i18n/UnicodeScript.hpp>
#include <scripttypedetector.hxx>
#include <i18nutil/unicode.hxx>

//      ----------------------------------------------------
//      class ScriptTypeDetector
//      ----------------------------------------------------;

using namespace com::sun::star::i18n;

ScriptTypeDetector::ScriptTypeDetector()
{
}

ScriptTypeDetector::~ScriptTypeDetector()
{
}

static sal_Int16 scriptDirection[] = {
    ScriptDirection::LEFT_TO_RIGHT,     // DirectionProperty_LEFT_TO_RIGHT = 0,
    ScriptDirection::RIGHT_TO_LEFT,     // DirectionProperty_RIGHT_TO_LEFT = 1,
    ScriptDirection::LEFT_TO_RIGHT,     // DirectionProperty_EUROPEAN_NUMBER = 2,
    ScriptDirection::LEFT_TO_RIGHT,     // DirectionProperty_EUROPEAN_NUMBER_SEPARATOR = 3,
    ScriptDirection::LEFT_TO_RIGHT,     // DirectionProperty_EUROPEAN_NUMBER_TERMINATOR = 4,
    ScriptDirection::RIGHT_TO_LEFT,     // DirectionProperty_ARABIC_NUMBER = 5,
    ScriptDirection::NEUTRAL,           // DirectionProperty_COMMON_NUMBER_SEPARATOR = 6,
    ScriptDirection::NEUTRAL,           // DirectionProperty_BLOCK_SEPARATOR = 7,
    ScriptDirection::NEUTRAL,           // DirectionProperty_SEGMENT_SEPARATOR = 8,
    ScriptDirection::NEUTRAL,           // DirectionProperty_WHITE_SPACE_NEUTRAL = 9,
    ScriptDirection::NEUTRAL,           // DirectionProperty_OTHER_NEUTRAL = 10,
    ScriptDirection::LEFT_TO_RIGHT,     // DirectionProperty_LEFT_TO_RIGHT_EMBEDDING = 11,
    ScriptDirection::LEFT_TO_RIGHT,     // DirectionProperty_LEFT_TO_RIGHT_OVERRIDE = 12,
    ScriptDirection::RIGHT_TO_LEFT,     // DirectionProperty_RIGHT_TO_LEFT_ARABIC = 13,
    ScriptDirection::RIGHT_TO_LEFT,     // DirectionProperty_RIGHT_TO_LEFT_EMBEDDING = 14,
    ScriptDirection::RIGHT_TO_LEFT,     // DirectionProperty_RIGHT_TO_LEFT_OVERRIDE = 15,
    ScriptDirection::NEUTRAL,           // DirectionProperty_POP_DIRECTIONAL_FORMAT = 16,
    ScriptDirection::NEUTRAL,           // DirectionProperty_DIR_NON_SPACING_MARK = 17,
    ScriptDirection::NEUTRAL,           // DirectionProperty_BOUNDARY_NEUTRAL = 18,
};

sal_Int16 SAL_CALL
ScriptTypeDetector::getScriptDirection( const ::rtl::OUString& Text, sal_Int32 nPos, sal_Int16 defaultScriptDirection ) throw (::com::sun::star::uno::RuntimeException)
{
    sal_Int16 dir = scriptDirection[unicode::getUnicodeDirection(Text[nPos])];
    return (dir == ScriptDirection::NEUTRAL) ? defaultScriptDirection : dir;
}

// return value '-1' means either the direction on nPos is not same as scriptDirection or nPos is out of range.
sal_Int32 SAL_CALL
ScriptTypeDetector::beginOfScriptDirection( const ::rtl::OUString& Text, sal_Int32 nPos, sal_Int16 scriptDirection ) throw (::com::sun::star::uno::RuntimeException)
{
        sal_Int32 cPos = nPos;

        if (cPos < Text.getLength()) {
            for (; cPos >= 0; cPos--) {
                if (scriptDirection != getScriptDirection(Text, cPos, scriptDirection))
                    break;
            }
            return cPos == nPos ? -1 : cPos + 1;
        }
}

sal_Int32 SAL_CALL
ScriptTypeDetector::endOfScriptDirection( const ::rtl::OUString& Text, sal_Int32 nPos, sal_Int16 scriptDirection ) throw (::com::sun::star::uno::RuntimeException)
{
        sal_Int32 cPos = nPos;
        sal_Int32 len = Text.getLength();

        if (cPos >=0) {
            for (; cPos < len; cPos++) {
                if (scriptDirection != getScriptDirection(Text, cPos, scriptDirection))
                    break;
            }
        }
        return cPos == nPos ? -1 : cPos;
}

sal_Int16 SAL_CALL
ScriptTypeDetector::getCTLScriptType( const ::rtl::OUString& Text, sal_Int32 nPos ) throw (::com::sun::star::uno::RuntimeException)
{
    static ScriptTypeList typeList[] = {
        { UnicodeScript_kHebrew, UnicodeScript_kHebrew, CTLScriptType::CTL_HEBREW },    // 10
        { UnicodeScript_kArabic, UnicodeScript_kArabic, CTLScriptType::CTL_ARABIC },    // 11
        { UnicodeScript_kDevanagari, UnicodeScript_kDevanagari, CTLScriptType::CTL_INDIC },     // 14
        { UnicodeScript_kThai, UnicodeScript_kThai, CTLScriptType::CTL_THAI },      // 24
        { UnicodeScript_kScriptCount, UnicodeScript_kScriptCount,   CTLScriptType::CTL_UNKNOWN }    // 88
    };

    return unicode::getUnicodeScriptType(Text[nPos], typeList, CTLScriptType::CTL_UNKNOWN);
}

// Begin of Script Type is inclusive.
sal_Int32 SAL_CALL
ScriptTypeDetector::beginOfCTLScriptType( const ::rtl::OUString& Text, sal_Int32 nPos ) throw (::com::sun::star::uno::RuntimeException)
{
    if (nPos < 0)
        return 0;
    else if (nPos >= Text.getLength())
        return Text.getLength();
    else {
        sal_Int16 cType = getCTLScriptType(Text, nPos);
        for (nPos--; nPos >= 0; nPos--) {
            if (cType != getCTLScriptType(Text, nPos))
                break;
        }
        return nPos + 1;
    }
}

// End of the Script Type is exclusive, the return value pointing to the begin of next script type
sal_Int32 SAL_CALL
ScriptTypeDetector::endOfCTLScriptType( const ::rtl::OUString& Text, sal_Int32 nPos ) throw (::com::sun::star::uno::RuntimeException)
{
    if (nPos < 0)
        return 0;
    else if (nPos >= Text.getLength())
        return Text.getLength();
    else {
        sal_Int16 cType = getCTLScriptType(Text, nPos);
        sal_Int32 len = Text.getLength();
        for (nPos++; nPos < len; nPos++) {
            if (cType != getCTLScriptType(Text, nPos))
                break;
        }
        return nPos;
    }
}

const sal_Char sDetector[] = "draft.com.sun.star.i18n.ScriptTypeDetector";

rtl::OUString SAL_CALL
ScriptTypeDetector::getImplementationName() throw( ::com::sun::star::uno::RuntimeException )
{
    return ::rtl::OUString::createFromAscii(sDetector);
}

sal_Bool SAL_CALL
ScriptTypeDetector::supportsService(const rtl::OUString& ServiceName) throw( ::com::sun::star::uno::RuntimeException )
{
    return !ServiceName.compareToAscii(sDetector);
}

::com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
ScriptTypeDetector::getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException )
{
    ::com::sun::star::uno::Sequence< ::rtl::OUString > aRet(1);
    aRet[0] = ::rtl::OUString::createFromAscii(sDetector);
    return aRet;
}

<commit_msg>INTEGRATION: CWS localedata5 (1.5.62); FILE MERGED 2005/05/19 17:20:12 er 1.5.62.1: #i47962# eliminate warning: control reached end of non-void function (could had been reached)<commit_after>/*************************************************************************
 *
 *  $RCSfile: scripttypedetector.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2005-07-21 14:27:06 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <com/sun/star/i18n/CTLScriptType.hpp>
#include <com/sun/star/i18n/ScriptDirection.hpp>
#include <com/sun/star/i18n/UnicodeScript.hpp>
#include <scripttypedetector.hxx>
#include <i18nutil/unicode.hxx>

//      ----------------------------------------------------
//      class ScriptTypeDetector
//      ----------------------------------------------------;

using namespace com::sun::star::i18n;

ScriptTypeDetector::ScriptTypeDetector()
{
}

ScriptTypeDetector::~ScriptTypeDetector()
{
}

static sal_Int16 scriptDirection[] = {
    ScriptDirection::LEFT_TO_RIGHT,     // DirectionProperty_LEFT_TO_RIGHT = 0,
    ScriptDirection::RIGHT_TO_LEFT,     // DirectionProperty_RIGHT_TO_LEFT = 1,
    ScriptDirection::LEFT_TO_RIGHT,     // DirectionProperty_EUROPEAN_NUMBER = 2,
    ScriptDirection::LEFT_TO_RIGHT,     // DirectionProperty_EUROPEAN_NUMBER_SEPARATOR = 3,
    ScriptDirection::LEFT_TO_RIGHT,     // DirectionProperty_EUROPEAN_NUMBER_TERMINATOR = 4,
    ScriptDirection::RIGHT_TO_LEFT,     // DirectionProperty_ARABIC_NUMBER = 5,
    ScriptDirection::NEUTRAL,           // DirectionProperty_COMMON_NUMBER_SEPARATOR = 6,
    ScriptDirection::NEUTRAL,           // DirectionProperty_BLOCK_SEPARATOR = 7,
    ScriptDirection::NEUTRAL,           // DirectionProperty_SEGMENT_SEPARATOR = 8,
    ScriptDirection::NEUTRAL,           // DirectionProperty_WHITE_SPACE_NEUTRAL = 9,
    ScriptDirection::NEUTRAL,           // DirectionProperty_OTHER_NEUTRAL = 10,
    ScriptDirection::LEFT_TO_RIGHT,     // DirectionProperty_LEFT_TO_RIGHT_EMBEDDING = 11,
    ScriptDirection::LEFT_TO_RIGHT,     // DirectionProperty_LEFT_TO_RIGHT_OVERRIDE = 12,
    ScriptDirection::RIGHT_TO_LEFT,     // DirectionProperty_RIGHT_TO_LEFT_ARABIC = 13,
    ScriptDirection::RIGHT_TO_LEFT,     // DirectionProperty_RIGHT_TO_LEFT_EMBEDDING = 14,
    ScriptDirection::RIGHT_TO_LEFT,     // DirectionProperty_RIGHT_TO_LEFT_OVERRIDE = 15,
    ScriptDirection::NEUTRAL,           // DirectionProperty_POP_DIRECTIONAL_FORMAT = 16,
    ScriptDirection::NEUTRAL,           // DirectionProperty_DIR_NON_SPACING_MARK = 17,
    ScriptDirection::NEUTRAL,           // DirectionProperty_BOUNDARY_NEUTRAL = 18,
};

sal_Int16 SAL_CALL
ScriptTypeDetector::getScriptDirection( const ::rtl::OUString& Text, sal_Int32 nPos, sal_Int16 defaultScriptDirection ) throw (::com::sun::star::uno::RuntimeException)
{
    sal_Int16 dir = scriptDirection[unicode::getUnicodeDirection(Text[nPos])];
    return (dir == ScriptDirection::NEUTRAL) ? defaultScriptDirection : dir;
}

// return value '-1' means either the direction on nPos is not same as scriptDirection or nPos is out of range.
sal_Int32 SAL_CALL
ScriptTypeDetector::beginOfScriptDirection( const ::rtl::OUString& Text, sal_Int32 nPos, sal_Int16 scriptDirection ) throw (::com::sun::star::uno::RuntimeException)
{
        sal_Int32 cPos = nPos;

        if (cPos < Text.getLength()) {
            for (; cPos >= 0; cPos--) {
                if (scriptDirection != getScriptDirection(Text, cPos, scriptDirection))
                    break;
            }
        }
        return cPos == nPos ? -1 : cPos + 1;
}

sal_Int32 SAL_CALL
ScriptTypeDetector::endOfScriptDirection( const ::rtl::OUString& Text, sal_Int32 nPos, sal_Int16 scriptDirection ) throw (::com::sun::star::uno::RuntimeException)
{
        sal_Int32 cPos = nPos;
        sal_Int32 len = Text.getLength();

        if (cPos >=0) {
            for (; cPos < len; cPos++) {
                if (scriptDirection != getScriptDirection(Text, cPos, scriptDirection))
                    break;
            }
        }
        return cPos == nPos ? -1 : cPos;
}

sal_Int16 SAL_CALL
ScriptTypeDetector::getCTLScriptType( const ::rtl::OUString& Text, sal_Int32 nPos ) throw (::com::sun::star::uno::RuntimeException)
{
    static ScriptTypeList typeList[] = {
        { UnicodeScript_kHebrew, UnicodeScript_kHebrew, CTLScriptType::CTL_HEBREW },    // 10
        { UnicodeScript_kArabic, UnicodeScript_kArabic, CTLScriptType::CTL_ARABIC },    // 11
        { UnicodeScript_kDevanagari, UnicodeScript_kDevanagari, CTLScriptType::CTL_INDIC },     // 14
        { UnicodeScript_kThai, UnicodeScript_kThai, CTLScriptType::CTL_THAI },      // 24
        { UnicodeScript_kScriptCount, UnicodeScript_kScriptCount,   CTLScriptType::CTL_UNKNOWN }    // 88
    };

    return unicode::getUnicodeScriptType(Text[nPos], typeList, CTLScriptType::CTL_UNKNOWN);
}

// Begin of Script Type is inclusive.
sal_Int32 SAL_CALL
ScriptTypeDetector::beginOfCTLScriptType( const ::rtl::OUString& Text, sal_Int32 nPos ) throw (::com::sun::star::uno::RuntimeException)
{
    if (nPos < 0)
        return 0;
    else if (nPos >= Text.getLength())
        return Text.getLength();
    else {
        sal_Int16 cType = getCTLScriptType(Text, nPos);
        for (nPos--; nPos >= 0; nPos--) {
            if (cType != getCTLScriptType(Text, nPos))
                break;
        }
        return nPos + 1;
    }
}

// End of the Script Type is exclusive, the return value pointing to the begin of next script type
sal_Int32 SAL_CALL
ScriptTypeDetector::endOfCTLScriptType( const ::rtl::OUString& Text, sal_Int32 nPos ) throw (::com::sun::star::uno::RuntimeException)
{
    if (nPos < 0)
        return 0;
    else if (nPos >= Text.getLength())
        return Text.getLength();
    else {
        sal_Int16 cType = getCTLScriptType(Text, nPos);
        sal_Int32 len = Text.getLength();
        for (nPos++; nPos < len; nPos++) {
            if (cType != getCTLScriptType(Text, nPos))
                break;
        }
        return nPos;
    }
}

const sal_Char sDetector[] = "draft.com.sun.star.i18n.ScriptTypeDetector";

rtl::OUString SAL_CALL
ScriptTypeDetector::getImplementationName() throw( ::com::sun::star::uno::RuntimeException )
{
    return ::rtl::OUString::createFromAscii(sDetector);
}

sal_Bool SAL_CALL
ScriptTypeDetector::supportsService(const rtl::OUString& ServiceName) throw( ::com::sun::star::uno::RuntimeException )
{
    return !ServiceName.compareToAscii(sDetector);
}

::com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
ScriptTypeDetector::getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException )
{
    ::com::sun::star::uno::Sequence< ::rtl::OUString > aRet(1);
    aRet[0] = ::rtl::OUString::createFromAscii(sDetector);
    return aRet;
}

<|endoftext|>


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

#if !defined(__APPLE__)
#include "iceoryx_posh/iceoryx_posh_config.hpp"
#include "iceoryx_posh/internal/roudi/memory/mempool_collection_memory_block.hpp"
#include "iceoryx_posh/mepoo/mepoo_config.hpp"
#include "iceoryx_posh/roudi/memory/posix_shm_memory_provider.hpp"
#include "iceoryx_utils/posix_wrapper/posix_access_rights.hpp"
#include "test.hpp"

#include <thread>
namespace
{
using namespace ::testing;

TEST(ShmCreatorDeathTest, AllocatingTooMuchMemoryLeadsToExitWithSIGBUS)
{
    const iox::ShmName_t TEST_SHM_NAME{"/test_name"};
    // try a config with high memory requirements, expect failure
    iox::mepoo::MePooConfig badconfig;
    badconfig.addMemPool({1 << 30, 100});
    iox::roudi::MemPoolCollectionMemoryBlock badmempools(badconfig);
    iox::roudi::PosixShmMemoryProvider badShmProvider(
        TEST_SHM_NAME, iox::posix::AccessMode::readWrite, iox::posix::OwnerShip::mine);
    badShmProvider.addMemoryBlock(&badmempools);

    EXPECT_DEATH(badShmProvider.create(),
                 "\033\\[0;1;97;41mFatal error:\033\\[m the available memory is insufficient. Cannot allocate mempools "
                 "in shared memory. Please make sure that enough memory is available. For this, consider also the "
                 "memory which is required for the \\[/iceoryx_mgmt\\] segment. Please refer to "
                 "share\\/doc\\/iceoryx\\/FAQ.md in your release delivery.");

    // try again with a config with low memory requirements; success clears shared memory allocated by the OS in e.g.
    // /dev/shm
    iox::mepoo::MePooConfig goodconfig;
    goodconfig.addMemPool({1024, 1});
    iox::roudi::MemPoolCollectionMemoryBlock goodmempools(goodconfig);
    iox::roudi::PosixShmMemoryProvider goodShmProvider(
        TEST_SHM_NAME, iox::posix::AccessMode::readWrite, iox::posix::OwnerShip::mine);
    goodShmProvider.addMemoryBlock(&goodmempools);
    goodShmProvider.create();
}
} // namespace

#endif
<commit_msg>iox-#542 removed posix wrapper error message from death test in posh integration test<commit_after>// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

#if !defined(__APPLE__)
#include "iceoryx_posh/iceoryx_posh_config.hpp"
#include "iceoryx_posh/internal/roudi/memory/mempool_collection_memory_block.hpp"
#include "iceoryx_posh/mepoo/mepoo_config.hpp"
#include "iceoryx_posh/roudi/memory/posix_shm_memory_provider.hpp"
#include "iceoryx_utils/posix_wrapper/posix_access_rights.hpp"
#include "test.hpp"

#include <thread>
namespace
{
using namespace ::testing;

TEST(ShmCreatorDeathTest, AllocatingTooMuchMemoryLeadsToExitWithSIGBUS)
{
    const iox::ShmName_t TEST_SHM_NAME{"/test_name"};
    // try a config with high memory requirements, expect failure
    iox::mepoo::MePooConfig badconfig;
    badconfig.addMemPool({1 << 30, 100});
    iox::roudi::MemPoolCollectionMemoryBlock badmempools(badconfig);
    iox::roudi::PosixShmMemoryProvider badShmProvider(
        TEST_SHM_NAME, iox::posix::AccessMode::readWrite, iox::posix::OwnerShip::mine);
    badShmProvider.addMemoryBlock(&badmempools);

    EXPECT_DEATH(badShmProvider.create(), ".*");

    // try again with a config with low memory requirements; success clears shared memory allocated by the OS in e.g.
    // /dev/shm
    iox::mepoo::MePooConfig goodconfig;
    goodconfig.addMemPool({1024, 1});
    iox::roudi::MemPoolCollectionMemoryBlock goodmempools(goodconfig);
    iox::roudi::PosixShmMemoryProvider goodShmProvider(
        TEST_SHM_NAME, iox::posix::AccessMode::readWrite, iox::posix::OwnerShip::mine);
    goodShmProvider.addMemoryBlock(&goodmempools);
    goodShmProvider.create();
}
} // namespace

#endif
<|endoftext|>


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

#include <votca/tools/histogramnew.h>

namespace votca { namespace tools {

HistogramNew::HistogramNew()
{
    _min=_max=_step=0;
    _weight = 1.;
    _periodic=false;
}

HistogramNew::HistogramNew(const HistogramNew &hist)
    : _min(hist._min), _max(hist._max), _step(hist._step),
      _weight(hist._weight), _periodic(hist._periodic)
{}

void HistogramNew::Initialize(double min, double max, int nbins)
{
    _min = min; _max = max;
    _step = (_max - _min)/nbins;
    _weight = 1.;
    _data.resize(nbins);
    _nbins = nbins;

    for(double v=_min, i=0; i<nbins; v+=_step,++i)
        _data.x(i)=v;

    _data.y()=ub::zero_vector<double>(_nbins);
    _data.yerr()=ub::zero_vector<double>(_nbins);
    _data.flags()=ub::scalar_vector<char>(_nbins, 'i');
}

void HistogramNew::Process(const double &v, double scale)
{
    int i = (int) ((v - _min) / _step + 0.5);

    if (i < 0 || i >= _nbins) {
        if(!_periodic) return;
        if(i<0) i = _nbins - ((-i) % _nbins);
        else i = i % _nbins;
    }
    _data.y(i) += _weight * scale;
}

void HistogramNew::Normalize()
{
    double area = 0;

    area=ub::norm_1(_data.x()) * _step;

    _weight /= area;
    double scale = 1./area;

    _data.y() *= scale;
}

void HistogramNew::Clear()
{
    _weight = 1.;
    _data.y() = ub::zero_vector<double>(_nbins);
    _data.yerr() = ub::zero_vector<double>(_nbins);
}

}}
<commit_msg>fixed HistogramNew::Normalize - was used anywhere so far<commit_after>/*
 * Copyright 2009-2011 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <votca/tools/histogramnew.h>

namespace votca { namespace tools {

HistogramNew::HistogramNew()
{
    _min=_max=_step=0;
    _weight = 1.;
    _periodic=false;
}

HistogramNew::HistogramNew(const HistogramNew &hist)
    : _min(hist._min), _max(hist._max), _step(hist._step),
      _weight(hist._weight), _periodic(hist._periodic)
{}

void HistogramNew::Initialize(double min, double max, int nbins)
{
    _min = min; _max = max;
    _step = (_max - _min)/nbins;
    _weight = 1.;
    _data.resize(nbins);
    _nbins = nbins;

    for(double v=_min, i=0; i<nbins; v+=_step,++i)
        _data.x(i)=v;

    _data.y()=ub::zero_vector<double>(_nbins);
    _data.yerr()=ub::zero_vector<double>(_nbins);
    _data.flags()=ub::scalar_vector<char>(_nbins, 'i');
}

void HistogramNew::Process(const double &v, double scale)
{
    int i = (int) ((v - _min) / _step + 0.5);

    if (i < 0 || i >= _nbins) {
        if(!_periodic) return;
        if(i<0) i = _nbins - ((-i) % _nbins);
        else i = i % _nbins;
    }
    _data.y(i) += _weight * scale;
}

void HistogramNew::Normalize()
{
    double area = 0;

    area=ub::norm_1(_data.y()) * _step;

    double scale = 1./area;

    _data.y() *= scale;
}

void HistogramNew::Clear()
{
    _weight = 1.;
    _data.y() = ub::zero_vector<double>(_nbins);
    _data.yerr() = ub::zero_vector<double>(_nbins);
}

}}
<|endoftext|>


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

#include <algorithm>
#include <cassert>
#include <votca/tools/edge.h>
#include <votca/tools/reducedgraph.h>

using namespace std;

namespace votca {
namespace tools {

class GraphNode;

bool compareChainWithChains_(const vector<int>& chain,
                             const vector<vector<int>>& chains) {
  bool match = false;
  for (const vector<int>& chain2 : chains) {
    if (chain2.size() == chain.size()) {
      match = true;
      for (size_t index = 0; index < chain.size(); ++index) {
        if (chain2.at(index) != chain.at(index)) {
          match = false;
          break;
        }
      }  // Cycle vertices in each chain
      if (match) return true;
    }  // Chains same size
  }
  return false;
}

set<int> getVertexJunctions_(const vector<ReducedEdge>& reduced_edges) {
  unordered_map<int, int> vertex_count;
  for (ReducedEdge reduced_edge : reduced_edges) {
    // if loop, increment value is double and the first index is skipped to
    // prevent over counting of the first number
    int increment = 1;
    size_t index = 0;
    if (reduced_edge.loop()) {
      ++index;
      increment = 2;
    }
    vector<int> chain = reduced_edge.getChain();
    for (; index < chain.size(); ++index) {
      if (vertex_count.count(chain.at(index))) {
        vertex_count[chain.at(index)] += increment;
      } else {
        vertex_count[chain.at(index)] = increment;
      }
    }
  }
  set<int> junctions;
  for (pair<int, int> vertex_and_count : vertex_count) {
    if (vertex_and_count.second > 2) {
      junctions.insert(vertex_and_count.first);
    }
  }
  return junctions;
}

void addEdgeIfNotLoop_(
    vector<Edge>& edges, const ReducedEdge reduced_edge,
    unordered_map<Edge, vector<vector<int>>>& expanded_edges) {

  Edge edge(reduced_edge.getEndPoint1(), reduced_edge.getEndPoint2());
  if (expanded_edges.count(edge)) {
    bool match =
        compareChainWithChains_(reduced_edge.getChain(), expanded_edges[edge]);
    if (!match) {
      expanded_edges[edge].push_back(reduced_edge.getChain());
    }
  } else {
    expanded_edges[edge].push_back(reduced_edge.getChain());
  }
  edges.push_back(edge);
}

void orderChainAfterInitialVertex_(vector<int>& chain) {
  size_t ignore_first_and_last_vertex = 2;
  size_t total_number_to_parse =
      (chain.size() - ignore_first_and_last_vertex) / 2;
  bool reverse_vector = false;
  for (size_t count = 0; count < (total_number_to_parse); ++count) {
    if (chain.at(chain.size() - count - 1) < chain.at(count + 1)) {
      reverse_vector = true;
      break;
    }
  }

  if (reverse_vector) {
    reverse(chain.begin(), chain.end());
  }
}

bool reordereAndStoreChainIfDoesNotExist_(
    vector<Edge>& edges,
    unordered_map<Edge, vector<vector<int>>>& expanded_edges, vector<int> chain,
    int vertex, size_t& chain_index) {

  Edge edge(vertex, vertex);
  edges.push_back(edge);
  vector<int> new_chain;
  for (size_t index = 0; index < chain.size(); ++index) {
    if (((chain_index + index) % chain.size()) == 0) {
      ++chain_index;
    }
    int new_chain_index = (chain_index + index) % chain.size();
    new_chain.push_back(chain.at(new_chain_index));
  }
  // Ensure that the new_chain is sorted so after the first vertex they are
  // ordered from smallest to largest
  orderChainAfterInitialVertex_(new_chain);
  bool match = compareChainWithChains_(new_chain, expanded_edges[edge]);
  if (!match) {
    expanded_edges[edge].push_back(new_chain);
    return true;
  }
  return false;
}

void ReducedGraph::init_(vector<ReducedEdge> reduced_edges,
                         unordered_map<int, GraphNode> nodes) {
  vector<Edge> edges;
  nodes_ = nodes;

  junctions_ = getVertexJunctions_(reduced_edges);

  for (const ReducedEdge& reduced_edge : reduced_edges) {

    if (reduced_edge.loop() &&
        junctions_.count(reduced_edge.getEndPoint1()) == 0) {
      vector<int> chain = reduced_edge.getChain();
      size_t chain_index = 0;
      bool edge_added = false;
      for (int vertex : chain) {
        if (junctions_.count(vertex)) {
          edge_added = reordereAndStoreChainIfDoesNotExist_(
              edges, expanded_edges_, chain, vertex, chain_index);
          break;
        }
        ++chain_index;
      }
      if (!edge_added) {
        addEdgeIfNotLoop_(edges, reduced_edge, expanded_edges_);
      }
    } else {
      addEdgeIfNotLoop_(edges, reduced_edge, expanded_edges_);
    }
  }

  edge_container_ = EdgeContainer(edges);

  calcId_();
}

set<int> getAllVertices_(const std::vector<ReducedEdge>& reduced_edges) {
  set<int> vertices;
  for (const ReducedEdge& reduced_edge : reduced_edges) {
    vector<int> chain = reduced_edge.getChain();
    for (const int vertex : chain) {
      vertices.insert(vertex);
    }
  }
  return vertices;
}

ReducedGraph::ReducedGraph(std::vector<ReducedEdge> reduced_edges) {

  set<int> vertices = getAllVertices_(reduced_edges);
  unordered_map<int, GraphNode> nodes;
  for (const int vertex : vertices) {
    GraphNode gn;
    nodes[vertex] = gn;
  }
  init_(reduced_edges, nodes);
}

ReducedGraph::ReducedGraph(std::vector<ReducedEdge> reduced_edges,
                           unordered_map<int, GraphNode> nodes) {

  set<int> vertices = getAllVertices_(reduced_edges);
  if (nodes.size() < vertices.size()) {
    throw invalid_argument(
        "The number of nodes passed into a reduced graph "
        "must be greater or equivalent to the number of vertices");
  }
  for (const int vertex : vertices) {
    if (nodes.count(vertex) == 0) {
      throw invalid_argument("A vertex is missing its corresponding node.");
    }
  }
  init_(reduced_edges, nodes);

  // Add all the nodes that are isolated
  for (pair<const int, GraphNode>& id_and_node : nodes) {
    if (vertices.count(id_and_node.first) == 0) {
      edge_container_.addVertex(id_and_node.first);
    }
  }
}

Graph ReducedGraph::expandGraph() {
  vector<Edge> all_expanded_edges;
  for (const pair<Edge, vector<vector<int>>> edge_and_vertices :
       expanded_edges_) {
    vector<vector<Edge>> edges_local = expandEdge(edge_and_vertices.first);
    for (vector<Edge>& edges : edges_local) {
      all_expanded_edges.insert(all_expanded_edges.end(), edges.begin(),
                                edges.end());
    }
  }
  return Graph(all_expanded_edges, nodes_);
}

vector<vector<Edge>> ReducedGraph::expandEdge(const Edge& edge) const {
  vector<vector<Edge>> all_edges;
  vector<vector<int>> chains = expanded_edges_.at(edge);
  for (vector<int> vertices : chains) {
    vector<Edge> edges;
    for (size_t index = 0; index < (vertices.size() - 1); ++index) {
      Edge edge_temp(vertices.at(index), vertices.at(index + 1));
      edges.push_back(edge_temp);
    }
    all_edges.push_back(edges);
  }
  return all_edges;
}

set<int> getAllConnectedVertices_(
    const unordered_map<Edge, vector<vector<int>>>& expanded_edges) {
  set<int> all_vertices;

  for (const auto& edge_and_chains : expanded_edges) {
    for (vector<int> chain : edge_and_chains.second) {
      all_vertices.insert(chain.begin(), chain.end());
    }
  }
  return all_vertices;
}
vector<pair<int, GraphNode>> ReducedGraph::getNodes() const {
  vector<int> vertices = edge_container_.getVertices();
  vector<pair<int, GraphNode>> nodes;
  for (const int vertex : vertices) {
    pair<int, GraphNode> id_and_node(vertex, nodes_.at(vertex));
    nodes.push_back(id_and_node);
  }

  set<int> all_connected_vertices = getAllConnectedVertices_(expanded_edges_);
  // Grab the nodes that are not attached to any edges
  for (pair<int, GraphNode> id_and_node : nodes_) {
    if (!all_connected_vertices.count(id_and_node.first)) {
      nodes.push_back(id_and_node);
    }
  }
  return nodes;
}
/*
bool ReducedGraph::edgeExist(const Edge& edge) const {
  return edge_container_.edgeExist(edge);
}*/

vector<Edge> ReducedGraph::getEdges() {
  /*  vector<Edge> edges_unfiltered = edge_container_.getEdges();
    vector<Edge> edges;
    for(const Edge edge : edges_unfiltered){
     if(edge.loop()){
      // Find which vertex if any is a junction if it is return the edge so that
      // it points to the junction
      vector<vector<int>> chains = expanded_edges_.at(edge);
      // If it is a loop there should only be a single junction at most
      assert(chains.size()==1);
      for(int vertex : chains.at(0)){
        if(junctions_.count(vertex)){
          Edge edge(vertex,vertex);
          edges.push_back(edge);
          break;
        }
      }
     }else{
      edges.push_back(edge);
     }
     }
    return edges;*/
  return edge_container_.getEdges();
}

vector<int> ReducedGraph::getVertices() const {
  // Get all the vertices that are in the reduced graph
  vector<int> vertices = edge_container_.getVertices();
  return vertices;
}

vector<int> ReducedGraph::getVerticesDegree(int degree) const {
  if (degree == 0) {
    set<int> all_connected_vertices = getAllConnectedVertices_(expanded_edges_);
    vector<int> vertices;
    for (const pair<int, GraphNode> id_and_node : nodes_) {
      if (all_connected_vertices.count(id_and_node.first) == false) {
        vertices.push_back(id_and_node.first);
      }
      return vertices;
    }
  }
  return edge_container_.getVerticesDegree(degree);
}

ostream& operator<<(ostream& os, const ReducedGraph graph) {
  os << "Graph" << endl;
  for (const pair<int, GraphNode>& id_and_node : graph.nodes_) {
    os << "Node " << id_and_node.first << endl;
    os << id_and_node.second << endl;
  }

  os << endl;
  os << graph.edge_container_ << endl;

  os << endl;
  os << "Expanded Edge Chains" << endl;

  for (const pair<const Edge, vector<vector<int>>>& edge_and_chains :
       graph.expanded_edges_) {
    for (const vector<int>& chain : edge_and_chains.second) {
      for (const int vertex : chain) {
        os << vertex << " ";
      }
      os << endl;
    }
    os << endl;
  }

  return os;
}

}  // namespace tools
}  // namespace votca
<commit_msg>Added some function descriptions for internal functions of reduced graph also deleted some unneeded commented out functionality<commit_after>/*
 *            Copyright 2009-2019 The VOTCA Development Team
 *                       (http://www.votca.org)
 *
 *      Licensed under the Apache License, Version 2.0 (the "License")
 *
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *              http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <algorithm>
#include <cassert>
#include <votca/tools/edge.h>
#include <votca/tools/reducedgraph.h>

using namespace std;

namespace votca {
namespace tools {

class GraphNode;

/**
 * \brief Function will compare a chain with a vector of chains
 *
 * If the one of the chains in the vector of chains is equivalent will return
 * true. A chain is simply a vector of integers where each integer represents
 * a vertex along an edge. The vertices appear in the chain in the same order
 * as they exist in a graph.
 **/
bool compareChainWithChains_(const vector<int>& chain,
                             const vector<vector<int>>& chains) {
  bool match = false;
  for (const vector<int>& chain2 : chains) {
    if (chain2.size() == chain.size()) {
      match = true;
      for (size_t index = 0; index < chain.size(); ++index) {
        if (chain2.at(index) != chain.at(index)) {
          match = false;
          break;
        }
      }  // Cycle vertices in each chain
      if (match) return true;
    }  // Chains same size
  }
  return false;
}

/**
 * \brief Given a vector of Reduced Edges will find and return junctions if any
 * exist
 *
 * A junction is a vertex in a graph that has 3 or more edges eminating from it.
 *
 * Consider three reduced edges given by
 *
 * Edge   Reduced Edge when Expanded (chain of vertices)
 * 1, 5  :  1 - 3 - 4 - 6 - 5
 * 5, 10 :  5 - 2 - 10
 * 5, 9  :  5 - 8 - 9
 *
 * Graph:
 *
 * 1 - 3 - 4 - 6 - 5 - 2 - 10
 *                 |
 *                 8 - 9
 *
 * Reduced Graph:
 *
 * 1 - 5 - 10
 *     |
 *     9
 *
 * Here vertex 5 would be found to be a junction
 *
 * @param[in,out] - vector of reduced edges
 * @return - set of integers containing junctions
 **/
set<int> getVertexJunctions_(const vector<ReducedEdge>& reduced_edges) {
  unordered_map<int, int> vertex_count;
  for (ReducedEdge reduced_edge : reduced_edges) {
    // if loop, increment value is double and the first index is skipped to
    // prevent over counting of the first number
    int increment = 1;
    size_t index = 0;
    if (reduced_edge.loop()) {
      ++index;
      increment = 2;
    }
    vector<int> chain = reduced_edge.getChain();
    for (; index < chain.size(); ++index) {
      if (vertex_count.count(chain.at(index))) {
        vertex_count[chain.at(index)] += increment;
      } else {
        vertex_count[chain.at(index)] = increment;
      }
    }
  }
  set<int> junctions;
  for (pair<int, int> vertex_and_count : vertex_count) {
    if (vertex_and_count.second > 2) {
      junctions.insert(vertex_and_count.first);
    }
  }
  return junctions;
}

/**
 * \breif function adds an edge to an unordered_map and a vector if it is found
 * to not be a loop
 *
 * A loop is an edge that essentially makes a circle. In an edge that is a loop
 * will have both end points equal to the samve vertex. E.g. a reduced edge
 * like this:
 *
 * Edge  Expanded edge (chain of vertices)
 * 2, 2 : 2 - 4 - 3 - 5 - 2
 *
 * Graph
 *
 *  2 - 4
 *  |   |
 *  5 - 3
 *
 * Reduced Graph
 *
 *  - 2
 *  |_|
 *
 * @param[in,out] - vector of edges, an edge is added to the vector if it is not
 * a loop
 * @param[in] - a reduced edge, the edge to be added
 * @param[in,out] - an unordered_map that stores the edge and its chain if it
 * is found to not be a loop
 **/
void addEdgeIfNotLoop_(
    vector<Edge>& edges, const ReducedEdge reduced_edge,
    unordered_map<Edge, vector<vector<int>>>& expanded_edges) {

  Edge edge(reduced_edge.getEndPoint1(), reduced_edge.getEndPoint2());
  if (expanded_edges.count(edge)) {
    bool match =
        compareChainWithChains_(reduced_edge.getChain(), expanded_edges[edge]);
    if (!match) {
      expanded_edges[edge].push_back(reduced_edge.getChain());
    }
  } else {
    expanded_edges[edge].push_back(reduced_edge.getChain());
  }
  edges.push_back(edge);
}

/**
 * \brief This is a helper function used to help store the vertex chain in a
 * reproducable order
 *
 * Ordering chains in a reproducable manner enable quicker comparison between
 * chains.
 *
 * E.g. Given a chain
 *
 * End Point 1
 * v
 * 1 - 4 - 3 - 5 - 6 - 2 - 1
 *                         ^
 *                      End Point 2
 *
 * This function will ensure that it is reordered such that the next consecutive
 * number in the chain after end point 2 is the lower number, in this case the
 * two numbers that are compared are 4 and 2. The 2 is smaller so the chain is
 * reordered.
 *
 * 1 - 2 - 6 - 5 - 3 - 4 - 1
 *
 * @param[in,out] - vector of integers containing the chain
 **/
void orderChainAfterInitialVertex_(vector<int>& chain) {
  size_t ignore_first_and_last_vertex = 2;
  size_t total_number_to_parse =
      (chain.size() - ignore_first_and_last_vertex) / 2;
  bool reverse_vector = false;
  for (size_t count = 0; count < (total_number_to_parse); ++count) {
    if (chain.at(chain.size() - count - 1) < chain.at(count + 1)) {
      reverse_vector = true;
      break;
    }
  }

  if (reverse_vector) {
    reverse(chain.begin(), chain.end());
  }
}

bool reorderAndStoreChainIfDoesNotExist_(
    vector<Edge>& edges,
    unordered_map<Edge, vector<vector<int>>>& expanded_edges, vector<int> chain,
    int vertex, size_t& chain_index) {

  Edge edge(vertex, vertex);
  edges.push_back(edge);
  vector<int> new_chain;
  for (size_t index = 0; index < chain.size(); ++index) {
    if (((chain_index + index) % chain.size()) == 0) {
      ++chain_index;
    }
    int new_chain_index = (chain_index + index) % chain.size();
    new_chain.push_back(chain.at(new_chain_index));
  }
  // Ensure that the new_chain is sorted so after the first vertex they are
  // ordered from smallest to largest
  orderChainAfterInitialVertex_(new_chain);
  bool match = compareChainWithChains_(new_chain, expanded_edges[edge]);
  if (!match) {
    expanded_edges[edge].push_back(new_chain);
    return true;
  }
  return false;
}

void ReducedGraph::init_(vector<ReducedEdge> reduced_edges,
                         unordered_map<int, GraphNode> nodes) {
  vector<Edge> edges;
  nodes_ = nodes;

  junctions_ = getVertexJunctions_(reduced_edges);

  for (const ReducedEdge& reduced_edge : reduced_edges) {

    if (reduced_edge.loop() &&
        junctions_.count(reduced_edge.getEndPoint1()) == 0) {
      vector<int> chain = reduced_edge.getChain();
      size_t chain_index = 0;
      bool edge_added = false;
      for (int vertex : chain) {
        if (junctions_.count(vertex)) {
          edge_added = reorderAndStoreChainIfDoesNotExist_(
              edges, expanded_edges_, chain, vertex, chain_index);
          break;
        }
        ++chain_index;
      }
      if (!edge_added) {
        addEdgeIfNotLoop_(edges, reduced_edge, expanded_edges_);
      }
    } else {
      addEdgeIfNotLoop_(edges, reduced_edge, expanded_edges_);
    }
  }

  edge_container_ = EdgeContainer(edges);

  calcId_();
}

set<int> getAllVertices_(const std::vector<ReducedEdge>& reduced_edges) {
  set<int> vertices;
  for (const ReducedEdge& reduced_edge : reduced_edges) {
    vector<int> chain = reduced_edge.getChain();
    for (const int vertex : chain) {
      vertices.insert(vertex);
    }
  }
  return vertices;
}

ReducedGraph::ReducedGraph(std::vector<ReducedEdge> reduced_edges) {

  set<int> vertices = getAllVertices_(reduced_edges);
  unordered_map<int, GraphNode> nodes;
  for (const int vertex : vertices) {
    GraphNode gn;
    nodes[vertex] = gn;
  }
  init_(reduced_edges, nodes);
}

ReducedGraph::ReducedGraph(std::vector<ReducedEdge> reduced_edges,
                           unordered_map<int, GraphNode> nodes) {

  set<int> vertices = getAllVertices_(reduced_edges);
  if (nodes.size() < vertices.size()) {
    throw invalid_argument(
        "The number of nodes passed into a reduced graph "
        "must be greater or equivalent to the number of vertices");
  }
  for (const int vertex : vertices) {
    if (nodes.count(vertex) == 0) {
      throw invalid_argument("A vertex is missing its corresponding node.");
    }
  }
  init_(reduced_edges, nodes);

  // Add all the nodes that are isolated
  for (pair<const int, GraphNode>& id_and_node : nodes) {
    if (vertices.count(id_and_node.first) == 0) {
      edge_container_.addVertex(id_and_node.first);
    }
  }
}

Graph ReducedGraph::expandGraph() {
  vector<Edge> all_expanded_edges;
  for (const pair<Edge, vector<vector<int>>> edge_and_vertices :
       expanded_edges_) {
    vector<vector<Edge>> edges_local = expandEdge(edge_and_vertices.first);
    for (vector<Edge>& edges : edges_local) {
      all_expanded_edges.insert(all_expanded_edges.end(), edges.begin(),
                                edges.end());
    }
  }
  return Graph(all_expanded_edges, nodes_);
}

vector<vector<Edge>> ReducedGraph::expandEdge(const Edge& edge) const {
  vector<vector<Edge>> all_edges;
  vector<vector<int>> chains = expanded_edges_.at(edge);
  for (vector<int> vertices : chains) {
    vector<Edge> edges;
    for (size_t index = 0; index < (vertices.size() - 1); ++index) {
      Edge edge_temp(vertices.at(index), vertices.at(index + 1));
      edges.push_back(edge_temp);
    }
    all_edges.push_back(edges);
  }
  return all_edges;
}

set<int> getAllConnectedVertices_(
    const unordered_map<Edge, vector<vector<int>>>& expanded_edges) {
  set<int> all_vertices;

  for (const auto& edge_and_chains : expanded_edges) {
    for (vector<int> chain : edge_and_chains.second) {
      all_vertices.insert(chain.begin(), chain.end());
    }
  }
  return all_vertices;
}
vector<pair<int, GraphNode>> ReducedGraph::getNodes() const {
  vector<int> vertices = edge_container_.getVertices();
  vector<pair<int, GraphNode>> nodes;
  for (const int vertex : vertices) {
    pair<int, GraphNode> id_and_node(vertex, nodes_.at(vertex));
    nodes.push_back(id_and_node);
  }

  set<int> all_connected_vertices = getAllConnectedVertices_(expanded_edges_);
  // Grab the nodes that are not attached to any edges
  for (pair<int, GraphNode> id_and_node : nodes_) {
    if (!all_connected_vertices.count(id_and_node.first)) {
      nodes.push_back(id_and_node);
    }
  }
  return nodes;
}

vector<int> ReducedGraph::getVertices() const {
  // Get all the vertices that are in the reduced graph
  vector<int> vertices = edge_container_.getVertices();
  return vertices;
}

vector<int> ReducedGraph::getVerticesDegree(int degree) const {
  if (degree == 0) {
    set<int> all_connected_vertices = getAllConnectedVertices_(expanded_edges_);
    vector<int> vertices;
    for (const pair<int, GraphNode> id_and_node : nodes_) {
      if (all_connected_vertices.count(id_and_node.first) == false) {
        vertices.push_back(id_and_node.first);
      }
      return vertices;
    }
  }
  return edge_container_.getVerticesDegree(degree);
}

ostream& operator<<(ostream& os, const ReducedGraph graph) {
  os << "Graph" << endl;
  for (const pair<int, GraphNode>& id_and_node : graph.nodes_) {
    os << "Node " << id_and_node.first << endl;
    os << id_and_node.second << endl;
  }

  os << endl;
  os << graph.edge_container_ << endl;

  os << endl;
  os << "Expanded Edge Chains" << endl;

  for (const pair<const Edge, vector<vector<int>>>& edge_and_chains :
       graph.expanded_edges_) {
    for (const vector<int>& chain : edge_and_chains.second) {
      for (const int vertex : chain) {
        os << vertex << " ";
      }
      os << endl;
    }
    os << endl;
  }

  return os;
}

}  // namespace tools
}  // namespace votca
<|endoftext|>


<commit_before>#include "logging.hh"
#include "nixexpr.hh"
#include "util.hh"

#include <gtest/gtest.h>

namespace nix {

    /* ----------------------------------------------------------------------------
     * logEI
     * --------------------------------------------------------------------------*/

    TEST(logEI, catpuresBasicProperties) {

        MakeError(TestError, Error);
        ErrorInfo::programName = std::optional("error-unit-test");

        try {
            throw TestError("an error for testing purposes");
        } catch (Error &e) {
            testing::internal::CaptureStderr();
            logger->logEI(e.info());
            auto str = testing::internal::GetCapturedStderr();

            ASSERT_STREQ(str.c_str(),"\x1B[31;1merror:\x1B[0m\x1B[34;1m --- TestError ------------------------------------ error-unit-test\x1B[0m\nan error for testing purposes\n");
        }
    }

    TEST(logEI, appendingHintsToPreviousError) {

        MakeError(TestError, Error);
        ErrorInfo::programName = std::optional("error-unit-test");

        try {
            auto e = Error("initial error");
            throw TestError(e.info());
        } catch (Error &e) {
            ErrorInfo ei = e.info();
            ei.hint = hintfmt("%s; subsequent error message.", normaltxt(e.info().hint ? e.info().hint->str() : ""));

            testing::internal::CaptureStderr();
            logger->logEI(ei);
            auto str = testing::internal::GetCapturedStderr();

            ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- TestError ------------------------------------ error-unit-test\x1B[0m\n\x1B[33;1m\x1B[0minitial error\x1B[0m; subsequent error message.\n");
        }

    }

    TEST(logEI, picksUpSysErrorExitCode) {

        MakeError(TestError, Error);
        ErrorInfo::programName = std::optional("error-unit-test");

        try {
            auto x = readFile(-1);
        }
        catch (SysError &e) {
            testing::internal::CaptureStderr();
            logError(e.info());
            auto str = testing::internal::GetCapturedStderr();

            ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- SysError ------------------------------------- error-unit-test\x1B[0m\n\x1B[33;1m\x1B[0mstatting file\x1B[0m: \x1B[33;1mBad file descriptor\x1B[0m\n");

        }
    }

    TEST(logEI, loggingErrorOnInfoLevel) {
        testing::internal::CaptureStderr();

        logger->logEI({ .level = lvlInfo,
                .name = "Info name",
                .description = "Info description",
                });

        auto str = testing::internal::GetCapturedStderr();
        ASSERT_STREQ(str.c_str(), "\x1B[32;1minfo:\x1B[0m\x1B[34;1m --- Info name ------------------------------------- error-unit-test\x1B[0m\nInfo description\n");
    }

    TEST(logEI, loggingErrorOnTalkativeLevel) {
        testing::internal::CaptureStderr();

        logger->logEI({ .level = lvlTalkative,
                        .name = "Talkative name",
                        .description = "Talkative description",
                        });

        auto str = testing::internal::GetCapturedStderr();
        // XXX: why is this the empty string?
        ASSERT_STREQ(str.c_str(), "");
    }

    TEST(logEI, loggingErrorOnChattyLevel) {
        testing::internal::CaptureStderr();

        logger->logEI({ .level = lvlChatty,
                        .name = "Chatty name",
                        .description = "Talkative description",
                        });

        auto str = testing::internal::GetCapturedStderr();
        // XXX: why is this the empty string?
        ASSERT_STREQ(str.c_str(), "");
    }

    TEST(logEI, loggingErrorOnDebugLevel) {
        testing::internal::CaptureStderr();

        logger->logEI({ .level = lvlDebug,
                        .name = "Debug name",
                        .description = "Debug description",
                        });

        auto str = testing::internal::GetCapturedStderr();
        // XXX: why is this the empty string?
        ASSERT_STREQ(str.c_str(), "");
    }

    TEST(logEI, loggingErrorOnVomitLevel) {
        testing::internal::CaptureStderr();

        logger->logEI({ .level = lvlVomit,
                        .name = "Vomit name",
                        .description = "Vomit description",
                        });

        auto str = testing::internal::GetCapturedStderr();
        // XXX: why is this the empty string?
        ASSERT_STREQ(str.c_str(), "");
    }

    /* ----------------------------------------------------------------------------
     * logError
     * --------------------------------------------------------------------------*/

    TEST(logError, logErrorWithoutHintOrCode) {
        testing::internal::CaptureStderr();

        logError({
                .name = "name",
                .description = "error description",
                });

        auto str = testing::internal::GetCapturedStderr();
        ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- name ----------------------------------------- error-unit-test\x1B[0m\nerror description\n");
    }

    TEST(logError, logErrorWithPreviousAndNextLinesOfCode) {
        SymbolTable testTable;
        auto problem_file = testTable.create("myfile.nix");

        testing::internal::CaptureStderr();

        logError({
                .name = "error name",
                .description = "error with code lines",
                .hint = hintfmt("this hint has %1% templated %2%!!",
                        "yellow",
                        "values"),
                .nixCode = NixCode {
                .errPos = Pos(problem_file, 40, 13),
                .prevLineOfCode = "previous line of code",
                .errLineOfCode = "this is the problem line of code",
                .nextLineOfCode = "next line of code",
                }});

        auto str = testing::internal::GetCapturedStderr();
        ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- error name ----------------------------------- error-unit-test\x1B[0m\nin file: \x1B[34;1mmyfile.nix (40:13)\x1B[0m\n\nerror with code lines\n\n    39| previous line of code\n    40| this is the problem line of code\n      |             \x1B[31;1m^\x1B[0m\n    41| next line of code\n\nthis hint has \x1B[33;1myellow\x1B[0m templated \x1B[33;1mvalues\x1B[0m!!\n");
    }

    TEST(logError, logErrorWithoutLinesOfCode) {
        SymbolTable testTable;
        auto problem_file = testTable.create("myfile.nix");
        testing::internal::CaptureStderr();

        logError({
                .name = "error name",
                .description = "error without any code lines.",
                .hint = hintfmt("this hint has %1% templated %2%!!",
                        "yellow",
                        "values"),
                .nixCode = NixCode {
                .errPos = Pos(problem_file, 40, 13)
                }});

        auto str = testing::internal::GetCapturedStderr();
        ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- error name ----------------------------------- error-unit-test\x1B[0m\nin file: \x1B[34;1mmyfile.nix (40:13)\x1B[0m\n\nerror without any code lines.\n\nthis hint has \x1B[33;1myellow\x1B[0m templated \x1B[33;1mvalues\x1B[0m!!\n");
    }

    TEST(logError, logErrorWithOnlyHintAndName) {
        SymbolTable testTable;
        auto problem_file = testTable.create("myfile.nix");
        testing::internal::CaptureStderr();

        logError({
                .name = "error name",
                .hint = hintfmt("hint %1%", "only"),
                .nixCode = NixCode {
                .errPos = Pos(problem_file, 40, 13)
                }});

        auto str = testing::internal::GetCapturedStderr();
        ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- error name ----------------------------------- error-unit-test\x1B[0m\nin file: \x1B[34;1mmyfile.nix (40:13)\x1B[0m\n\nhint \x1B[33;1monly\x1B[0m\n");

    }

    /* ----------------------------------------------------------------------------
     * logWarning
     * --------------------------------------------------------------------------*/

    TEST(logWarning, logWarningWithNameDescriptionAndHint) {
        testing::internal::CaptureStderr();

        logWarning({
            .name = "name",
            .description = "error description",
            .hint = hintfmt("there was a %1%", "warning"),
        });

        auto str = testing::internal::GetCapturedStderr();
        ASSERT_STREQ(str.c_str(), "\x1B[33;1mwarning:\x1B[0m\x1B[34;1m --- name --------------------------------------- error-unit-test\x1B[0m\nerror description\n\nthere was a \x1B[33;1mwarning\x1B[0m\n");
    }

    TEST(logWarning, logWarningWithFileLineNumAndCode) {

        SymbolTable testTable;
        auto problem_file = testTable.create("myfile.nix");

        testing::internal::CaptureStderr();

        logWarning({
                .name = "warning name",
                .description = "warning description",
                .hint = hintfmt("this hint has %1% templated %2%!!",
                        "yellow",
                        "values"),
                .nixCode = NixCode {
                .errPos = Pos(problem_file, 40, 13),
                .prevLineOfCode = std::nullopt,
                .errLineOfCode = "this is the problem line of code",
                .nextLineOfCode = std::nullopt
                }});

        auto str = testing::internal::GetCapturedStderr();
        ASSERT_STREQ(str.c_str(), "\x1B[33;1mwarning:\x1B[0m\x1B[34;1m --- warning name ------------------------------- error-unit-test\x1B[0m\nin file: \x1B[34;1mmyfile.nix (40:13)\x1B[0m\n\nwarning description\n\n    40| this is the problem line of code\n      |             \x1B[31;1m^\x1B[0m\n\nthis hint has \x1B[33;1myellow\x1B[0m templated \x1B[33;1mvalues\x1B[0m!!\n");
    }

}
<commit_msg>set verbosity levels<commit_after>#include "logging.hh"
#include "nixexpr.hh"
#include "util.hh"

#include <gtest/gtest.h>

namespace nix {

    /* ----------------------------------------------------------------------------
     * logEI
     * --------------------------------------------------------------------------*/

    TEST(logEI, catpuresBasicProperties) {

        MakeError(TestError, Error);
        ErrorInfo::programName = std::optional("error-unit-test");

        try {
            throw TestError("an error for testing purposes");
        } catch (Error &e) {
            testing::internal::CaptureStderr();
            logger->logEI(e.info());
            auto str = testing::internal::GetCapturedStderr();

            ASSERT_STREQ(str.c_str(),"\x1B[31;1merror:\x1B[0m\x1B[34;1m --- TestError ------------------------------------ error-unit-test\x1B[0m\nan error for testing purposes\n");
        }
    }

    TEST(logEI, appendingHintsToPreviousError) {

        MakeError(TestError, Error);
        ErrorInfo::programName = std::optional("error-unit-test");

        try {
            auto e = Error("initial error");
            throw TestError(e.info());
        } catch (Error &e) {
            ErrorInfo ei = e.info();
            ei.hint = hintfmt("%s; subsequent error message.", normaltxt(e.info().hint ? e.info().hint->str() : ""));

            testing::internal::CaptureStderr();
            logger->logEI(ei);
            auto str = testing::internal::GetCapturedStderr();

            ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- TestError ------------------------------------ error-unit-test\x1B[0m\n\x1B[33;1m\x1B[0minitial error\x1B[0m; subsequent error message.\n");
        }

    }

    TEST(logEI, picksUpSysErrorExitCode) {

        MakeError(TestError, Error);
        ErrorInfo::programName = std::optional("error-unit-test");

        try {
            auto x = readFile(-1);
        }
        catch (SysError &e) {
            testing::internal::CaptureStderr();
            logError(e.info());
            auto str = testing::internal::GetCapturedStderr();

            ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- SysError ------------------------------------- error-unit-test\x1B[0m\n\x1B[33;1m\x1B[0mstatting file\x1B[0m: \x1B[33;1mBad file descriptor\x1B[0m\n");

        }
    }

    TEST(logEI, loggingErrorOnInfoLevel) {
        testing::internal::CaptureStderr();

        logger->logEI({ .level = lvlInfo,
                .name = "Info name",
                .description = "Info description",
                });

        auto str = testing::internal::GetCapturedStderr();
        ASSERT_STREQ(str.c_str(), "\x1B[32;1minfo:\x1B[0m\x1B[34;1m --- Info name ------------------------------------- error-unit-test\x1B[0m\nInfo description\n");
    }

    TEST(logEI, loggingErrorOnTalkativeLevel) {
        verbosity = lvlTalkative;

        testing::internal::CaptureStderr();

        logger->logEI({ .level = lvlTalkative,
                        .name = "Talkative name",
                        .description = "Talkative description",
                        });

        auto str = testing::internal::GetCapturedStderr();
        ASSERT_STREQ(str.c_str(), "\x1B[32;1mtalk:\x1B[0m\x1B[34;1m --- Talkative name -------------------------------- error-unit-test\x1B[0m\nTalkative description\n");
    }

    TEST(logEI, loggingErrorOnChattyLevel) {
        verbosity = lvlChatty;

        testing::internal::CaptureStderr();

        logger->logEI({ .level = lvlChatty,
                        .name = "Chatty name",
                        .description = "Talkative description",
                        });

        auto str = testing::internal::GetCapturedStderr();
        ASSERT_STREQ(str.c_str(), "\x1B[32;1mchat:\x1B[0m\x1B[34;1m --- Chatty name ----------------------------------- error-unit-test\x1B[0m\nTalkative description\n");
    }

    TEST(logEI, loggingErrorOnDebugLevel) {
        verbosity = lvlDebug;

        testing::internal::CaptureStderr();

        logger->logEI({ .level = lvlDebug,
                        .name = "Debug name",
                        .description = "Debug description",
                        });

        auto str = testing::internal::GetCapturedStderr();
        ASSERT_STREQ(str.c_str(), "\x1B[33;1mdebug:\x1B[0m\x1B[34;1m --- Debug name ----------------------------------- error-unit-test\x1B[0m\nDebug description\n");
    }

    TEST(logEI, loggingErrorOnVomitLevel) {
        verbosity = lvlVomit;

        testing::internal::CaptureStderr();

        logger->logEI({ .level = lvlVomit,
                        .name = "Vomit name",
                        .description = "Vomit description",
                        });

        auto str = testing::internal::GetCapturedStderr();
        ASSERT_STREQ(str.c_str(), "\x1B[32;1mvomit:\x1B[0m\x1B[34;1m --- Vomit name ----------------------------------- error-unit-test\x1B[0m\nVomit description\n");
    }

    /* ----------------------------------------------------------------------------
     * logError
     * --------------------------------------------------------------------------*/

    TEST(logError, logErrorWithoutHintOrCode) {
        testing::internal::CaptureStderr();

        logError({
                .name = "name",
                .description = "error description",
                });

        auto str = testing::internal::GetCapturedStderr();
        ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- name ----------------------------------------- error-unit-test\x1B[0m\nerror description\n");
    }

    TEST(logError, logErrorWithPreviousAndNextLinesOfCode) {
        SymbolTable testTable;
        auto problem_file = testTable.create("myfile.nix");

        testing::internal::CaptureStderr();

        logError({
                .name = "error name",
                .description = "error with code lines",
                .hint = hintfmt("this hint has %1% templated %2%!!",
                        "yellow",
                        "values"),
                .nixCode = NixCode {
                .errPos = Pos(problem_file, 40, 13),
                .prevLineOfCode = "previous line of code",
                .errLineOfCode = "this is the problem line of code",
                .nextLineOfCode = "next line of code",
                }});

        auto str = testing::internal::GetCapturedStderr();
        ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- error name ----------------------------------- error-unit-test\x1B[0m\nin file: \x1B[34;1mmyfile.nix (40:13)\x1B[0m\n\nerror with code lines\n\n    39| previous line of code\n    40| this is the problem line of code\n      |             \x1B[31;1m^\x1B[0m\n    41| next line of code\n\nthis hint has \x1B[33;1myellow\x1B[0m templated \x1B[33;1mvalues\x1B[0m!!\n");
    }

    TEST(logError, logErrorWithoutLinesOfCode) {
        SymbolTable testTable;
        auto problem_file = testTable.create("myfile.nix");
        testing::internal::CaptureStderr();

        logError({
                .name = "error name",
                .description = "error without any code lines.",
                .hint = hintfmt("this hint has %1% templated %2%!!",
                        "yellow",
                        "values"),
                .nixCode = NixCode {
                .errPos = Pos(problem_file, 40, 13)
                }});

        auto str = testing::internal::GetCapturedStderr();
        ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- error name ----------------------------------- error-unit-test\x1B[0m\nin file: \x1B[34;1mmyfile.nix (40:13)\x1B[0m\n\nerror without any code lines.\n\nthis hint has \x1B[33;1myellow\x1B[0m templated \x1B[33;1mvalues\x1B[0m!!\n");
    }

    TEST(logError, logErrorWithOnlyHintAndName) {
        SymbolTable testTable;
        auto problem_file = testTable.create("myfile.nix");
        testing::internal::CaptureStderr();

        logError({
                .name = "error name",
                .hint = hintfmt("hint %1%", "only"),
                .nixCode = NixCode {
                .errPos = Pos(problem_file, 40, 13)
                }});

        auto str = testing::internal::GetCapturedStderr();
        ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- error name ----------------------------------- error-unit-test\x1B[0m\nin file: \x1B[34;1mmyfile.nix (40:13)\x1B[0m\n\nhint \x1B[33;1monly\x1B[0m\n");

    }

    /* ----------------------------------------------------------------------------
     * logWarning
     * --------------------------------------------------------------------------*/

    TEST(logWarning, logWarningWithNameDescriptionAndHint) {
        testing::internal::CaptureStderr();

        logWarning({
            .name = "name",
            .description = "error description",
            .hint = hintfmt("there was a %1%", "warning"),
        });

        auto str = testing::internal::GetCapturedStderr();
        ASSERT_STREQ(str.c_str(), "\x1B[33;1mwarning:\x1B[0m\x1B[34;1m --- name --------------------------------------- error-unit-test\x1B[0m\nerror description\n\nthere was a \x1B[33;1mwarning\x1B[0m\n");
    }

    TEST(logWarning, logWarningWithFileLineNumAndCode) {

        SymbolTable testTable;
        auto problem_file = testTable.create("myfile.nix");

        testing::internal::CaptureStderr();

        logWarning({
                .name = "warning name",
                .description = "warning description",
                .hint = hintfmt("this hint has %1% templated %2%!!",
                        "yellow",
                        "values"),
                .nixCode = NixCode {
                .errPos = Pos(problem_file, 40, 13),
                .prevLineOfCode = std::nullopt,
                .errLineOfCode = "this is the problem line of code",
                .nextLineOfCode = std::nullopt
                }});

        auto str = testing::internal::GetCapturedStderr();
        ASSERT_STREQ(str.c_str(), "\x1B[33;1mwarning:\x1B[0m\x1B[34;1m --- warning name ------------------------------- error-unit-test\x1B[0m\nin file: \x1B[34;1mmyfile.nix (40:13)\x1B[0m\n\nwarning description\n\n    40| this is the problem line of code\n      |             \x1B[31;1m^\x1B[0m\n\nthis hint has \x1B[33;1myellow\x1B[0m templated \x1B[33;1mvalues\x1B[0m!!\n");
    }

}
<|endoftext|>


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

#ifndef __LINUX_ROUTING_HANDLE_HPP__
#define __LINUX_ROUTING_HANDLE_HPP__

#include <stdint.h>

#include <netlink/route/tc.h>

namespace routing {

// The Linux kernel Traffic Control (TC) uses handles to uniqely
// identify the queueing disciplines (qdiscs), classes and filters
// attached to a network interface. The most common type of handle is
// identified by primary and secondary device numbers (sometimes
// called major and minor numbers) and written as primary:secondary.
// Handles provide the mechanism by which TC classes, qdiscs and
// filters can be connected together to create complex network traffic
// policing policies.
class Handle
{
public:
  explicit constexpr Handle(uint32_t _handle) : handle(_handle) {}

  constexpr Handle(uint16_t primary, uint16_t secondary)
    : handle((((uint32_t) primary) << 16) + secondary) {}

  // NOTE: This is used to construct a classid. The higher 16 bits of
  // the given 'parent' will be the primary and the lower 16 bits is
  // specified by the given 'id'.
  constexpr Handle(const Handle& parent, uint16_t id)
    : handle((((uint32_t) parent.primary()) << 16) + id) {}

  constexpr bool operator == (const Handle& that) const
  {
    return handle == that.handle;
  }

  constexpr bool operator != (const Handle& that) const
  {
    return handle != that.handle;
  }

  constexpr uint16_t primary() const { return handle >> 16; }
  constexpr uint16_t secondary() const { return handle & 0x0000ffff; }
  constexpr uint32_t get() const { return handle; }

protected:
  uint32_t handle;
};

// Packets flowing from the device driver to the network stack are
// called ingress traffic, and packets flowing from the network stack
// to the device driver are called egress traffic (shown below).
//
//        +---------+
//        | Network |
//        |  Stack  |
//        |---------|
//        |  eth0   |
//        +---------+
//           ^   |
//   Ingress |   | Egress
//           |   |
//    -------+   +------>
//
// The root handles for both ingress and egress are immutable.
constexpr Handle EGRESS_ROOT = Handle(TC_H_ROOT);
constexpr Handle INGRESS_ROOT = Handle(TC_H_INGRESS);

} // namespace routing {

#endif // __LINUX_ROUTING_HANDLE_HPP__
<commit_msg>Added output stream operation for handle to use in port_mapping.cpp.<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef __LINUX_ROUTING_HANDLE_HPP__
#define __LINUX_ROUTING_HANDLE_HPP__

#include <stdint.h>

#include <ostream>

#include <netlink/route/tc.h>

namespace routing {

// The Linux kernel Traffic Control (TC) uses handles to uniqely
// identify the queueing disciplines (qdiscs), classes and filters
// attached to a network interface. The most common type of handle is
// identified by primary and secondary device numbers (sometimes
// called major and minor numbers) and written as primary:secondary.
// Handles provide the mechanism by which TC classes, qdiscs and
// filters can be connected together to create complex network traffic
// policing policies.
class Handle
{
public:
  explicit constexpr Handle(uint32_t _handle) : handle(_handle) {}

  constexpr Handle(uint16_t primary, uint16_t secondary)
    : handle((((uint32_t) primary) << 16) + secondary) {}

  // NOTE: This is used to construct a classid. The higher 16 bits of
  // the given 'parent' will be the primary and the lower 16 bits is
  // specified by the given 'id'.
  constexpr Handle(const Handle& parent, uint16_t id)
    : handle((((uint32_t) parent.primary()) << 16) + id) {}

  constexpr bool operator == (const Handle& that) const
  {
    return handle == that.handle;
  }

  constexpr bool operator != (const Handle& that) const
  {
    return handle != that.handle;
  }

  constexpr uint16_t primary() const { return handle >> 16; }
  constexpr uint16_t secondary() const { return handle & 0x0000ffff; }
  constexpr uint32_t get() const { return handle; }

protected:
  uint32_t handle;
};

inline std::ostream& operator << (std::ostream& out, const Handle& handle)
{
  out << std::hex << handle.primary() << ":" << handle.secondary() << std::dec;
  return out;
}

// Packets flowing from the device driver to the network stack are
// called ingress traffic, and packets flowing from the network stack
// to the device driver are called egress traffic (shown below).
//
//        +---------+
//        | Network |
//        |  Stack  |
//        |---------|
//        |  eth0   |
//        +---------+
//           ^   |
//   Ingress |   | Egress
//           |   |
//    -------+   +------>
//
// The root handles for both ingress and egress are immutable.
constexpr Handle EGRESS_ROOT = Handle(TC_H_ROOT);
constexpr Handle INGRESS_ROOT = Handle(TC_H_INGRESS);

} // namespace routing {

#endif // __LINUX_ROUTING_HANDLE_HPP__
<|endoftext|>