<commit_before>/*
 * This file is part of the UnTech Editor Suite.
 * Copyright (c) 2016 - 2018, Marcus Rowe <undisbeliever@gmail.com>.
 * Distributed under The MIT License: https://opensource.org/licenses/MIT
 */

#include "animationframesmanager.h"
#include "animationframecommands.h"
#include "gui-qt/common/abstractidmaplistmodel.h"
#include "gui-qt/metasprite/abstractmsdocument.h"
#include "gui-qt/metasprite/abstractselection.h"

using namespace UnTech::GuiQt::MetaSprite::Animation;

const QStringList AnimationFramesManager::FLIP_STRINGS({ QString(),
                                                         QString::fromUtf8("hFlip"),
                                                         QString::fromUtf8("vFlip"),
                                                         QString::fromUtf8("hvFlip") });

AnimationFramesManager::AnimationFramesManager(QObject* parent)
    : PropertyTableManager(parent)
    , _document(nullptr)
    , _animation(nullptr)
{
    using Type = PropertyType;

    setItemsMovable(true);

    addProperty(tr("Frame"), PropertyId::FRAME, Type::IDSTRING);
    addProperty(tr("Flip"), PropertyId::FLIP, Type::COMBO, FLIP_STRINGS, QVariantList{ 0, 1, 2, 3 });
    addProperty(tr("Dur"), PropertyId::DURATION, Type::UNSIGNED);
    addProperty(tr("Duration"), PropertyId::DURATION_STRING, Type::STRING);
}

void AnimationFramesManager::setDocument(AbstractMsDocument* document)
{
    Q_ASSERT(document != nullptr);

    if (_document) {
        _document->disconnect(this);
        _document->selection()->disconnect(this);
    }
    _document = document;

    onSelectedAnimationChanged();
    connect(_document->selection(), &AbstractSelection::selectedAnimationChanged,
            this, &AnimationFramesManager::onSelectedAnimationChanged);

    connect(_document, &AbstractMsDocument::animationDataChanged,
            this, &AnimationFramesManager::onAnimationDataChanged);

    connect(_document, &AbstractMsDocument::animationFrameChanged,
            this, &AnimationFramesManager::onAnimationFrameChanged);
    connect(_document, &AbstractMsDocument::animationFrameAdded,
            this, &AnimationFramesManager::onAnimationFrameAdded);
    connect(_document, &AbstractMsDocument::animationFrameAboutToBeRemoved,
            this, &AnimationFramesManager::onAnimationFrameAboutToBeRemoved);
    connect(_document, &AbstractMsDocument::animationFrameMoved,
            this, &AnimationFramesManager::onAnimationFrameMoved);
}

void AnimationFramesManager::updateParameters(int index, int id, QVariant& param1, QVariant& param2) const
{
    Q_UNUSED(param2);

    if (_animation == nullptr
        || index < 0
        || (unsigned)index >= _animation->frames.size()) {

        return;
    }

    switch ((PropertyId)id) {
    case PropertyId::FRAME:
        param1 = _document->frameListModel()->displayList();
        break;

    case PropertyId::FLIP:
    case PropertyId::DURATION:
    case PropertyId::DURATION_STRING:
        break;
    };
}

void AnimationFramesManager::onSelectedAnimationChanged()
{
    MSA::Animation* animation = _document->selection()->selectedAnimation();

    if (_animation != animation) {
        _animation = animation;
        emit dataReset();
    }
}

void AnimationFramesManager::onAnimationDataChanged(const void* animation)
{
    if (animation == _animation) {
        emit dataChanged();
    }
}

void AnimationFramesManager::onAnimationFrameChanged(const void* animation, unsigned index)
{
    if (animation == _animation) {
        emit itemChanged(index);
    }
}

void AnimationFramesManager::onAnimationFrameAdded(const void* animation, unsigned index)
{
    if (animation == _animation) {
        emit itemAdded(index);
    }
}

void AnimationFramesManager::onAnimationFrameAboutToBeRemoved(const void* animation, unsigned index)
{
    if (animation == _animation) {
        emit itemRemoved(index);
    }
}

void AnimationFramesManager::onAnimationFrameMoved(const void* animation, unsigned oldPos, unsigned newPos)
{
    if (animation == _animation) {
        emit itemMoved(oldPos, newPos);
    }
}

int AnimationFramesManager::rowCount() const
{
    if (_animation) {
        return _animation->frames.size();
    }
    else {
        return 0;
    }
}

QVariant AnimationFramesManager::data(int index, int id) const
{
    if (_animation == nullptr
        || index < 0
        || (unsigned)index >= _animation->frames.size()) {

        return QVariant();
    }

    const MSA::AnimationFrame& aFrame = _animation->frames.at(index);
    unsigned flipIndex = (aFrame.frame.vFlip << 1) | aFrame.frame.hFlip;

    switch ((PropertyId)id) {
    case PropertyId::FRAME:
        return QString::fromStdString(aFrame.frame.name);

    case PropertyId::FLIP:
        return flipIndex;

    case PropertyId::DURATION:
        return aFrame.duration;

    case PropertyId::DURATION_STRING: {
        return QString::fromStdString(_animation->durationFormat.durationToString(aFrame.duration));
    }
    };

    return QVariant();
}

bool AnimationFramesManager::setData(int index, int id, const QVariant& value)
{
    if (_animation == nullptr
        || index < 0
        || (unsigned)index >= _animation->frames.size()) {

        return false;
    }

    const auto& oldFrame = _animation->frames.at(index);
    MSA::AnimationFrame aFrame = oldFrame;

    switch ((PropertyId)id) {
    case PropertyId::FRAME:
        aFrame.frame.name = value.toString().toStdString();
        break;

    case PropertyId::FLIP:
        aFrame.frame.hFlip = value.toUInt() & 1;
        aFrame.frame.vFlip = value.toUInt() & 2;
        break;

    case PropertyId::DURATION:
        aFrame.duration = value.toUInt();
        break;

    case PropertyId::DURATION_STRING:
        return false;
    };

    if (aFrame != oldFrame) {
        _document->undoStack()->push(
            new ChangeAnimationFrame(_document, _animation, index, aFrame));

        return true;
    }

    return false;
}

bool AnimationFramesManager::canInsertItem()
{
    return _animation != nullptr
           && _animation->frames.can_insert();
}

bool AnimationFramesManager::canCloneItem(int index)
{
    return _animation != nullptr
           && _animation->frames.can_insert()
           && index >= 0 && (unsigned)index < _animation->frames.size();
}

bool AnimationFramesManager::insertItem(int index)
{
    if (_animation == nullptr
        || _animation->frames.can_insert() == false
        || index < 0 || (unsigned)index > _animation->frames.size()) {

        return false;
    }

    _document->undoStack()->push(
        new AddAnimationFrame(_document, _animation, index));

    return true;
}

bool AnimationFramesManager::cloneItem(int index)
{
    if (_animation == nullptr
        || _animation->frames.can_insert() == false
        || index < 0 || (unsigned)index > _animation->frames.size()) {

        return false;
    }

    _document->undoStack()->push(
        new CloneAnimationFrame(_document, _animation, index));

    return true;
}

bool AnimationFramesManager::removeItem(int index)
{
    if (_animation == nullptr
        || index < 0 || (unsigned)index >= _animation->frames.size()) {

        return false;
    }

    _document->undoStack()->push(
        new RemoveAnimationFrame(_document, _animation, index));

    return true;
}

bool AnimationFramesManager::moveItem(int from, int to)
{
    if (_animation == nullptr
        || from == to
        || from < 0 || (unsigned)from >= _animation->frames.size()
        || to < 0 || (unsigned)to >= _animation->frames.size()) {

        return false;
    }

    _document->undoStack()->push(
        new MoveAnimationFrame(_document, _animation, from, to));

    return true;
}
<commit_msg>Fix nullptr segfault in AnimationFramesManager<commit_after>/*
 * This file is part of the UnTech Editor Suite.
 * Copyright (c) 2016 - 2018, Marcus Rowe <undisbeliever@gmail.com>.
 * Distributed under The MIT License: https://opensource.org/licenses/MIT
 */

#include "animationframesmanager.h"
#include "animationframecommands.h"
#include "gui-qt/common/abstractidmaplistmodel.h"
#include "gui-qt/metasprite/abstractmsdocument.h"
#include "gui-qt/metasprite/abstractselection.h"

using namespace UnTech::GuiQt::MetaSprite::Animation;

const QStringList AnimationFramesManager::FLIP_STRINGS({ QString(),
                                                         QString::fromUtf8("hFlip"),
                                                         QString::fromUtf8("vFlip"),
                                                         QString::fromUtf8("hvFlip") });

AnimationFramesManager::AnimationFramesManager(QObject* parent)
    : PropertyTableManager(parent)
    , _document(nullptr)
    , _animation(nullptr)
{
    using Type = PropertyType;

    setItemsMovable(true);

    addProperty(tr("Frame"), PropertyId::FRAME, Type::IDSTRING);
    addProperty(tr("Flip"), PropertyId::FLIP, Type::COMBO, FLIP_STRINGS, QVariantList{ 0, 1, 2, 3 });
    addProperty(tr("Dur"), PropertyId::DURATION, Type::UNSIGNED);
    addProperty(tr("Duration"), PropertyId::DURATION_STRING, Type::STRING);
}

void AnimationFramesManager::setDocument(AbstractMsDocument* document)
{
    if (_document) {
        _document->disconnect(this);
        _document->selection()->disconnect(this);
    }
    _document = document;

    _animation = nullptr;
    emit dataReset();

    if (_document) {
        onSelectedAnimationChanged();

        connect(_document->selection(), &AbstractSelection::selectedAnimationChanged,
                this, &AnimationFramesManager::onSelectedAnimationChanged);

        connect(_document, &AbstractMsDocument::animationDataChanged,
                this, &AnimationFramesManager::onAnimationDataChanged);

        connect(_document, &AbstractMsDocument::animationFrameChanged,
                this, &AnimationFramesManager::onAnimationFrameChanged);
        connect(_document, &AbstractMsDocument::animationFrameAdded,
                this, &AnimationFramesManager::onAnimationFrameAdded);
        connect(_document, &AbstractMsDocument::animationFrameAboutToBeRemoved,
                this, &AnimationFramesManager::onAnimationFrameAboutToBeRemoved);
        connect(_document, &AbstractMsDocument::animationFrameMoved,
                this, &AnimationFramesManager::onAnimationFrameMoved);
    }
}

void AnimationFramesManager::updateParameters(int index, int id, QVariant& param1, QVariant& param2) const
{
    Q_UNUSED(param2);

    if (_animation == nullptr
        || index < 0
        || (unsigned)index >= _animation->frames.size()) {

        return;
    }

    switch ((PropertyId)id) {
    case PropertyId::FRAME:
        param1 = _document->frameListModel()->displayList();
        break;

    case PropertyId::FLIP:
    case PropertyId::DURATION:
    case PropertyId::DURATION_STRING:
        break;
    };
}

void AnimationFramesManager::onSelectedAnimationChanged()
{
    MSA::Animation* animation = _document->selection()->selectedAnimation();

    if (_animation != animation) {
        _animation = animation;
        emit dataReset();
    }
}

void AnimationFramesManager::onAnimationDataChanged(const void* animation)
{
    if (animation == _animation) {
        emit dataChanged();
    }
}

void AnimationFramesManager::onAnimationFrameChanged(const void* animation, unsigned index)
{
    if (animation == _animation) {
        emit itemChanged(index);
    }
}

void AnimationFramesManager::onAnimationFrameAdded(const void* animation, unsigned index)
{
    if (animation == _animation) {
        emit itemAdded(index);
    }
}

void AnimationFramesManager::onAnimationFrameAboutToBeRemoved(const void* animation, unsigned index)
{
    if (animation == _animation) {
        emit itemRemoved(index);
    }
}

void AnimationFramesManager::onAnimationFrameMoved(const void* animation, unsigned oldPos, unsigned newPos)
{
    if (animation == _animation) {
        emit itemMoved(oldPos, newPos);
    }
}

int AnimationFramesManager::rowCount() const
{
    if (_animation) {
        return _animation->frames.size();
    }
    else {
        return 0;
    }
}

QVariant AnimationFramesManager::data(int index, int id) const
{
    if (_animation == nullptr
        || index < 0
        || (unsigned)index >= _animation->frames.size()) {

        return QVariant();
    }

    const MSA::AnimationFrame& aFrame = _animation->frames.at(index);
    unsigned flipIndex = (aFrame.frame.vFlip << 1) | aFrame.frame.hFlip;

    switch ((PropertyId)id) {
    case PropertyId::FRAME:
        return QString::fromStdString(aFrame.frame.name);

    case PropertyId::FLIP:
        return flipIndex;

    case PropertyId::DURATION:
        return aFrame.duration;

    case PropertyId::DURATION_STRING: {
        return QString::fromStdString(_animation->durationFormat.durationToString(aFrame.duration));
    }
    };

    return QVariant();
}

bool AnimationFramesManager::setData(int index, int id, const QVariant& value)
{
    if (_animation == nullptr
        || index < 0
        || (unsigned)index >= _animation->frames.size()) {

        return false;
    }

    const auto& oldFrame = _animation->frames.at(index);
    MSA::AnimationFrame aFrame = oldFrame;

    switch ((PropertyId)id) {
    case PropertyId::FRAME:
        aFrame.frame.name = value.toString().toStdString();
        break;

    case PropertyId::FLIP:
        aFrame.frame.hFlip = value.toUInt() & 1;
        aFrame.frame.vFlip = value.toUInt() & 2;
        break;

    case PropertyId::DURATION:
        aFrame.duration = value.toUInt();
        break;

    case PropertyId::DURATION_STRING:
        return false;
    };

    if (aFrame != oldFrame) {
        _document->undoStack()->push(
            new ChangeAnimationFrame(_document, _animation, index, aFrame));

        return true;
    }

    return false;
}

bool AnimationFramesManager::canInsertItem()
{
    return _animation != nullptr
           && _animation->frames.can_insert();
}

bool AnimationFramesManager::canCloneItem(int index)
{
    return _animation != nullptr
           && _animation->frames.can_insert()
           && index >= 0 && (unsigned)index < _animation->frames.size();
}

bool AnimationFramesManager::insertItem(int index)
{
    if (_animation == nullptr
        || _animation->frames.can_insert() == false
        || index < 0 || (unsigned)index > _animation->frames.size()) {

        return false;
    }

    _document->undoStack()->push(
        new AddAnimationFrame(_document, _animation, index));

    return true;
}

bool AnimationFramesManager::cloneItem(int index)
{
    if (_animation == nullptr
        || _animation->frames.can_insert() == false
        || index < 0 || (unsigned)index > _animation->frames.size()) {

        return false;
    }

    _document->undoStack()->push(
        new CloneAnimationFrame(_document, _animation, index));

    return true;
}

bool AnimationFramesManager::removeItem(int index)
{
    if (_animation == nullptr
        || index < 0 || (unsigned)index >= _animation->frames.size()) {

        return false;
    }

    _document->undoStack()->push(
        new RemoveAnimationFrame(_document, _animation, index));

    return true;
}

bool AnimationFramesManager::moveItem(int from, int to)
{
    if (_animation == nullptr
        || from == to
        || from < 0 || (unsigned)from >= _animation->frames.size()
        || to < 0 || (unsigned)to >= _animation->frames.size()) {

        return false;
    }

    _document->undoStack()->push(
        new MoveAnimationFrame(_document, _animation, from, to));

    return true;
}
<|endoftext|>


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

using namespace fapi2;

constexpr uint64_t literal_0xFE00000000000000 = 0xFE00000000000000;
constexpr uint64_t literal_0x0000000000000000 = 0x0000000000000000;
constexpr uint64_t literal_0b00111001000000101111111111111 = 0b00111001000000101111111111111;
constexpr uint64_t literal_0b00000000000000000000000000000 = 0b00000000000000000000000000000;
constexpr uint64_t literal_0b11000110001010010000000000000 = 0b11000110001010010000000000000;
constexpr uint64_t literal_0x000 = 0x000;
constexpr uint64_t literal_0b00000 = 0b00000;

fapi2::ReturnCode p9_psi_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& TGT0)
{
    {
        fapi2::ATTR_EC_Type   l_chip_ec;
        fapi2::ATTR_NAME_Type l_chip_id;
        FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, TGT0, l_chip_id));
        FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_EC, TGT0, l_chip_ec));
        fapi2::buffer<uint64_t> l_scom_buffer;
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x4011803ull, l_scom_buffer ));

            l_scom_buffer.insert<0, 7, 0, uint64_t>(literal_0xFE00000000000000 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x4011803ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x4011806ull, l_scom_buffer ));

            l_scom_buffer.insert<0, 7, 0, uint64_t>(literal_0x0000000000000000 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x4011806ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x4011807ull, l_scom_buffer ));

            l_scom_buffer.insert<0, 7, 0, uint64_t>(literal_0x0000000000000000 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x4011807ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x5012903ull, l_scom_buffer ));

            l_scom_buffer.insert<0, 29, 35, uint64_t>(literal_0b00111001000000101111111111111 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x5012903ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x5012906ull, l_scom_buffer ));

            l_scom_buffer.insert<0, 29, 35, uint64_t>(literal_0b00000000000000000000000000000 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x5012906ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x5012907ull, l_scom_buffer ));

            l_scom_buffer.insert<0, 29, 35, uint64_t>(literal_0b11000110001010010000000000000 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x5012907ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x501290full, l_scom_buffer ));

            l_scom_buffer.insert<16, 12, 52, uint64_t>(literal_0x000 );
            l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b00000 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x501290full, l_scom_buffer));
        }

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

using namespace fapi2;

constexpr uint64_t literal_0xFE00000000000000 = 0xFE00000000000000;
constexpr uint64_t literal_0x0000000000000000 = 0x0000000000000000;
constexpr uint64_t literal_0b00111111000000100000011011111 = 0b00111111000000100000011011111;
constexpr uint64_t literal_0b00000000000000000000000000000 = 0b00000000000000000000000000000;
constexpr uint64_t literal_0b11000000001010011111100100000 = 0b11000000001010011111100100000;
constexpr uint64_t literal_0x000 = 0x000;
constexpr uint64_t literal_0b00000 = 0b00000;

fapi2::ReturnCode p9_psi_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& TGT0)
{
    {
        fapi2::ATTR_EC_Type   l_chip_ec;
        fapi2::ATTR_NAME_Type l_chip_id;
        FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, TGT0, l_chip_id));
        FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_EC, TGT0, l_chip_ec));
        fapi2::buffer<uint64_t> l_scom_buffer;
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x4011803ull, l_scom_buffer ));

            l_scom_buffer.insert<0, 7, 0, uint64_t>(literal_0xFE00000000000000 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x4011803ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x4011806ull, l_scom_buffer ));

            l_scom_buffer.insert<0, 7, 0, uint64_t>(literal_0x0000000000000000 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x4011806ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x4011807ull, l_scom_buffer ));

            l_scom_buffer.insert<0, 7, 0, uint64_t>(literal_0x0000000000000000 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x4011807ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x5012903ull, l_scom_buffer ));

            l_scom_buffer.insert<0, 29, 35, uint64_t>(literal_0b00111111000000100000011011111 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x5012903ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x5012906ull, l_scom_buffer ));

            l_scom_buffer.insert<0, 29, 35, uint64_t>(literal_0b00000000000000000000000000000 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x5012906ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x5012907ull, l_scom_buffer ));

            l_scom_buffer.insert<0, 29, 35, uint64_t>(literal_0b11000000001010011111100100000 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x5012907ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x501290full, l_scom_buffer ));

            l_scom_buffer.insert<16, 12, 52, uint64_t>(literal_0x000 );
            l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b00000 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x501290full, l_scom_buffer));
        }

    };
fapi_try_exit:
    return fapi2::current_err;
}
<|endoftext|>


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

   The MIT License

   Copyright (c) 2009 Scientific Computing and Imaging Institute,
   University of Utah.

   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 <Modules/Legacy/Fields/GetFieldBoundary.h>
#include <Core/Algorithms/Legacy/Fields/MeshDerivatives/GetFieldBoundary.h>

using namespace SCIRun;
using namespace SCIRun::Core::Datatypes;
using namespace SCIRun::Dataflow::Networks;
using namespace SCIRun::Modules::Fields;

GetFieldBoundary::GetFieldBoundary()
  : Module(ModuleLookupInfo("GetFieldBoundary", "NewField", "SCIRun"), false)
{
  algo_ = algoFactory_->create(get_module_name(), getLogger());
}

void
GetFieldBoundary::execute()
{
  FieldHandle field;

  get_input_handle("Field",field,true);

  // If parameters changed, do algorithm
  if (inputs_changed_ ||
      !oport_cached("BoundaryField") ||
      !oport_cached("Mapping"))
  {
    update_state(Executing);

    FieldHandle ofield;
    MatrixHandle mapping;

    if (!(algo_.run(field,ofield,mapping))) return;

    send_output_handle("BoundaryField", ofield);
    send_output_handle("Mapping", mapping);
  }
}
<commit_msg>Change input function call<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2009 Scientific Computing and Imaging Institute,
   University of Utah.

   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 <Modules/Legacy/Fields/GetFieldBoundary.h>
#include <Core/Algorithms/Legacy/Fields/MeshDerivatives/GetFieldBoundary.h>

using namespace SCIRun;
using namespace SCIRun::Core::Datatypes;
using namespace SCIRun::Dataflow::Networks;
using namespace SCIRun::Modules::Fields;

GetFieldBoundary::GetFieldBoundary()
  : Module(ModuleLookupInfo("GetFieldBoundary", "NewField", "SCIRun"), false)
{
  algo_ = algoFactory_->create(get_module_name(), getLogger());
}

void
GetFieldBoundary::execute()
{
  FieldHandle field = getRequiredInput(Field);

  // If parameters changed, do algorithm
  if (inputs_changed_ ||
      !oport_cached("BoundaryField") ||
      !oport_cached("Mapping"))
  {
    update_state(Executing);

    FieldHandle ofield;
    MatrixHandle mapping;

    if (!(algo_.run(field,ofield,mapping))) return;

    send_output_handle("BoundaryField", ofield);
    send_output_handle("Mapping", mapping);
  }
}
<|endoftext|>


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

#if defined(_WIN32)
#   define _WIN32_LEAN_AND_MEAN
#   define NOMINMAX
#   include <windows.h>
#else
#    include <sys/stat.h>   // S_ISREG, stat
#   include <dirent.h>  // opendir, readir, DIR
#   include <unistd.h>  // rmdir, mkdir
#endif

#include "u_file.h"
#include "u_algorithm.h"
#include "u_misc.h"

namespace u {

file::file()
    : m_handle(nullptr)
{
}

file::file(FILE *fp)
    : m_handle(fp)
{
}

file::file(file &&other)
    : m_handle(other.m_handle)
{
    other.m_handle = nullptr;
}

file::~file() {
    if (m_handle)
        fclose(m_handle);
}

file &file::operator=(file &&other) {
    m_handle = other.m_handle;
    other.m_handle = nullptr;
    return *this;
}

file::operator FILE*() {
    return m_handle;
}

FILE *file::get() const {
    return m_handle;
}

void file::close() {
    fclose(m_handle);
    m_handle = nullptr;
}

u::string fixPath(const u::string &path) {
    u::string fix = path;
    for (char *it = &fix[0]; (it = strpbrk(it, "/\\")); *it++ = u::kPathSep)
        ;
    return fix;
}

// file system stuff
bool exists(const u::string &inputPath, pathType type) {
    u::string &&path = u::move(u::fixPath(inputPath));
    if (type == kFile)
        return dir::isFile(path);

    // type == kDirectory
#if defined(_WIN32)
    const DWORD attribs = GetFileAttributesA(inputPath.c_str());
    if (attribs == INVALID_FILE_ATTRIBUTES)
        return false;
    if (!(attribs & FILE_ATTRIBUTE_DIRECTORY))
        return false;
#else
    struct stat info;
    if (stat(path.c_str(), &info) != 0)
        return false; // Couldn't stat directory
    if (!(info.st_mode & S_IFDIR))
        return false; // Not a directory
#endif
    return true;
}

bool remove(const u::string &path, pathType type) {
    u::string &&fix = u::move(fixPath(path));
    if (type == kFile) {
#if defined(_WIN32)
        return DeleteFileA(&fix[0]) != 0;
#else
        return ::remove(&fix[0]) == 0;
#endif
    }

    // type == kDirectory
#if defined(_WIN32)
    return RemoveDirectoryA(&fix[0]) != 0;
#else
    return ::rmdir(&fix[0]) == 0;
#endif
}

bool mkdir(const u::string &dir) {
    u::string &&fix = u::move(u::fixPath(dir));
#if defined(_WIN32)
    return CreateDirectoryA(&fix[0], nullptr) != 0;
#else
    return ::mkdir(&fix[0], 0775);
#endif
}

u::file fopen(const u::string& infile, const char *type) {
    return ::fopen(fixPath(infile).c_str(), type);
}

bool getline(u::file &fp, u::string &line) {
    line.clear();
    for (;;) {
        char buf[256];
        if (!fgets(buf, sizeof buf, fp.get())) {
            if (feof(fp.get()))
                return !line.empty();
            abort();
        }
        size_t n = strlen(buf);
        if (n && buf[n - 1] == '\n')
            --n;
        if (n && buf[n - 1] == '\r')
            --n;
        line.append(buf, n);
        if (n < sizeof buf - 1)
            return true;
    }
    return false;
}

u::optional<u::string> getline(u::file &fp) {
    u::string s;
    if (!getline(fp, s))
        return u::none;
    return u::move(s);
}

u::optional<u::vector<unsigned char>> read(const u::string &file, const char *mode) {
    auto fp = u::fopen(file, mode);
    if (!fp)
        return u::none;
    u::vector<unsigned char> data;
    if (fseek(fp.get(), 0, SEEK_END) != 0)
        return u::none;
    const auto size = ftell(fp.get());
    if (size <= 0)
        return u::none;
    data.resize(size);
    if (fseek(fp.get(), 0, SEEK_SET) != 0)
        return u::none;
    if (fread(&data[0], data.size(), 1, fp.get()) != 1)
        return u::none;
    return data;
}

bool write(const u::vector<unsigned char> &data, const u::string &file, const char *mode) {
    auto fp = u::fopen(file, mode);
    if (!fp)
        return false;
    if (fwrite(&data[0], data.size(), 1, fp.get()) != 1)
        return false;
    return true;
}

///! dir
#if !defined(_WIN32)
#include <unistd.h>
#include <dirent.h>

#define IS_IGNORE(X) ((X)->d_name[0] == '.' && !(X)->d_name[1+((X)->d_name[1]=='.')])

///! dir::const_iterator
dir::const_iterator::const_iterator(void *handle)
    : m_handle(handle)
    , m_name(nullptr)
{
    if (!m_handle)
        return;
    // Ignore "." and ".."
    struct dirent *next = readdir((DIR *)m_handle);
    while (next && IS_IGNORE(next))
        next = readdir((DIR *)m_handle);
    m_name = next ? next->d_name : nullptr;
}

dir::const_iterator &dir::const_iterator::operator++() {
    struct dirent *next = readdir((DIR *)m_handle);
    while (next && IS_IGNORE(next))
        next = readdir((DIR *)m_handle);
    m_name = next ? next->d_name : nullptr;
    return *this;
}

///! dir
dir::dir(const char *where)
    : m_handle((void *)opendir(where))
{
}

dir::~dir() {
    if (m_handle)
        closedir((DIR *)m_handle);
}

bool dir::isFile(const char *fileName) {
    struct stat buff;
    if (stat(fileName, &buff) != 0)
        return false;
    return S_ISREG(buff.st_mode);
}

#else
#define IS_IGNORE(X) ((X).cFileName[0] == '.' && !(X).cFileName[1+((X).cFileName[1]=='.')])

struct findContext {
    findContext(const char *where);
    ~findContext();
    HANDLE handle;
    WIN32_FIND_DATA findData;
};

inline findContext::findContext(const char *where)
    : handle(INVALID_HANDLE_VALUE)
{
    static constexpr const char kPathExtra[] = "\\*";
    const size_t length = strlen(where);
    U_ASSERT(length + sizeof kPathExtra < MAX_PATH);
    char path[MAX_PATH];
    memcpy((void *)path, (const void *)where, length);
    memcpy((void *)&path[length], (const void *)kPathExtra, sizeof kPathExtra);
    if (!(handle = FindFirstFileA(path, &findData)))
        return;
    // Ignore "." and ".."
    if (IS_IGNORE(findData)) {
        BOOL next = FindNextFileA(handle, &findData);
        while (next && IS_IGNORE(findData))
            next = FindNextFileA(handle, &findData);
    }
}

inline findContext::~findContext() {
    if (handle != INVALID_HANDLE_VALUE)
        FindClose(handle);
}

///! dir::const_iterator
dir::const_iterator::const_iterator(void *handle)
    : m_handle(handle)
    , m_name(((findContext*)m_handle)->findData.cFileName)
{
}

dir::const_iterator &dir::const_iterator::operator++() {
    findContext *context = (findContext*)m_handle;
    BOOL next = FindNextFileA(context->handle, &context->findData);
    // Ignore "." and ".."
    while (next && IS_IGNORE(context->findData))
        next = FindNextFileA(context->handle, &context->findData);
    m_name = next ? context->findData.cFileName : nullptr;
    return *this;
}

///! dir
dir::dir(const char *where)
    : m_handle(new findContext(where))
{
}

dir::~dir() {
    delete (findContext*)m_handle;
}

bool dir::isFile(const char *fileName) {
    const DWORD attribs = GetFileAttributesA(fileName);
    if (attribs == INVALID_FILE_ATTRIBUTES)
        return false;
    if (attribs & FILE_ATTRIBUTE_DIRECTORY)
        return false;
    return true;
}
#endif

}
<commit_msg>Apparently this is undefined<commit_after>#include <stdlib.h>
#include <string.h>

#if defined(_WIN32)
#   define _WIN32_LEAN_AND_MEAN
#   define NOMINMAX
#   include <windows.h>
#else
#    include <sys/stat.h>   // S_ISREG, stat
#   include <dirent.h>  // opendir, readir, DIR
#   include <unistd.h>  // rmdir, mkdir
#endif

#include "u_file.h"
#include "u_algorithm.h"
#include "u_misc.h"

namespace u {

file::file()
    : m_handle(nullptr)
{
}

file::file(FILE *fp)
    : m_handle(fp)
{
}

file::file(file &&other)
    : m_handle(other.m_handle)
{
    other.m_handle = nullptr;
}

file::~file() {
    if (m_handle)
        fclose(m_handle);
}

file &file::operator=(file &&other) {
    m_handle = other.m_handle;
    other.m_handle = nullptr;
    return *this;
}

file::operator FILE*() {
    return m_handle;
}

FILE *file::get() const {
    return m_handle;
}

void file::close() {
    fclose(m_handle);
    m_handle = nullptr;
}

u::string fixPath(const u::string &path) {
    u::string fix = path;
    for (char *it = &fix[0]; (it = strpbrk(it, "/\\")); *it++ = u::kPathSep)
        ;
    return fix;
}

// file system stuff
bool exists(const u::string &inputPath, pathType type) {
    u::string &&path = u::fixPath(inputPath);
    if (type == kFile)
        return dir::isFile(path);

    // type == kDirectory
#if defined(_WIN32)
    const DWORD attribs = GetFileAttributesA(inputPath.c_str());
    if (attribs == INVALID_FILE_ATTRIBUTES)
        return false;
    if (!(attribs & FILE_ATTRIBUTE_DIRECTORY))
        return false;
#else
    struct stat info;
    if (stat(path.c_str(), &info) != 0)
        return false; // Couldn't stat directory
    if (!(info.st_mode & S_IFDIR))
        return false; // Not a directory
#endif
    return true;
}

bool remove(const u::string &path, pathType type) {
    u::string &&fix = u::fixPath(path);
    if (type == kFile) {
#if defined(_WIN32)
        return DeleteFileA(&fix[0]) != 0;
#else
        return ::remove(&fix[0]) == 0;
#endif
    }

    // type == kDirectory
#if defined(_WIN32)
    return RemoveDirectoryA(&fix[0]) != 0;
#else
    return ::rmdir(&fix[0]) == 0;
#endif
}

bool mkdir(const u::string &dir) {
    u::string &&fix = u::fixPath(dir);
#if defined(_WIN32)
    return CreateDirectoryA(&fix[0], nullptr) != 0;
#else
    return ::mkdir(&fix[0], 0775);
#endif
}

u::file fopen(const u::string& infile, const char *type) {
    return ::fopen(fixPath(infile).c_str(), type);
}

bool getline(u::file &fp, u::string &line) {
    line.clear();
    for (;;) {
        char buf[256];
        if (!fgets(buf, sizeof buf, fp.get())) {
            if (feof(fp.get()))
                return !line.empty();
            abort();
        }
        size_t n = strlen(buf);
        if (n && buf[n - 1] == '\n')
            --n;
        if (n && buf[n - 1] == '\r')
            --n;
        line.append(buf, n);
        if (n < sizeof buf - 1)
            return true;
    }
    return false;
}

u::optional<u::string> getline(u::file &fp) {
    u::string s;
    if (!getline(fp, s))
        return u::none;
    return u::move(s);
}

u::optional<u::vector<unsigned char>> read(const u::string &file, const char *mode) {
    auto fp = u::fopen(file, mode);
    if (!fp)
        return u::none;
    u::vector<unsigned char> data;
    if (fseek(fp.get(), 0, SEEK_END) != 0)
        return u::none;
    const auto size = ftell(fp.get());
    if (size <= 0)
        return u::none;
    data.resize(size);
    if (fseek(fp.get(), 0, SEEK_SET) != 0)
        return u::none;
    if (fread(&data[0], data.size(), 1, fp.get()) != 1)
        return u::none;
    return data;
}

bool write(const u::vector<unsigned char> &data, const u::string &file, const char *mode) {
    auto fp = u::fopen(file, mode);
    if (!fp)
        return false;
    if (fwrite(&data[0], data.size(), 1, fp.get()) != 1)
        return false;
    return true;
}

///! dir
#if !defined(_WIN32)
#include <unistd.h>
#include <dirent.h>

#define IS_IGNORE(X) ((X)->d_name[0] == '.' && !(X)->d_name[1+((X)->d_name[1]=='.')])

///! dir::const_iterator
dir::const_iterator::const_iterator(void *handle)
    : m_handle(handle)
    , m_name(nullptr)
{
    if (!m_handle)
        return;
    // Ignore "." and ".."
    struct dirent *next = readdir((DIR *)m_handle);
    while (next && IS_IGNORE(next))
        next = readdir((DIR *)m_handle);
    m_name = next ? next->d_name : nullptr;
}

dir::const_iterator &dir::const_iterator::operator++() {
    struct dirent *next = readdir((DIR *)m_handle);
    while (next && IS_IGNORE(next))
        next = readdir((DIR *)m_handle);
    m_name = next ? next->d_name : nullptr;
    return *this;
}

///! dir
dir::dir(const char *where)
    : m_handle((void *)opendir(where))
{
}

dir::~dir() {
    if (m_handle)
        closedir((DIR *)m_handle);
}

bool dir::isFile(const char *fileName) {
    struct stat buff;
    if (stat(fileName, &buff) != 0)
        return false;
    return S_ISREG(buff.st_mode);
}

#else
#define IS_IGNORE(X) ((X).cFileName[0] == '.' && !(X).cFileName[1+((X).cFileName[1]=='.')])

struct findContext {
    findContext(const char *where);
    ~findContext();
    HANDLE handle;
    WIN32_FIND_DATA findData;
};

inline findContext::findContext(const char *where)
    : handle(INVALID_HANDLE_VALUE)
{
    static constexpr const char kPathExtra[] = "\\*";
    const size_t length = strlen(where);
    U_ASSERT(length + sizeof kPathExtra < MAX_PATH);
    char path[MAX_PATH];
    memcpy((void *)path, (const void *)where, length);
    memcpy((void *)&path[length], (const void *)kPathExtra, sizeof kPathExtra);
    if (!(handle = FindFirstFileA(path, &findData)))
        return;
    // Ignore "." and ".."
    if (IS_IGNORE(findData)) {
        BOOL next = FindNextFileA(handle, &findData);
        while (next && IS_IGNORE(findData))
            next = FindNextFileA(handle, &findData);
    }
}

inline findContext::~findContext() {
    if (handle != INVALID_HANDLE_VALUE)
        FindClose(handle);
}

///! dir::const_iterator
dir::const_iterator::const_iterator(void *handle)
    : m_handle(handle)
    , m_name(((findContext*)m_handle)->findData.cFileName)
{
}

dir::const_iterator &dir::const_iterator::operator++() {
    findContext *context = (findContext*)m_handle;
    BOOL next = FindNextFileA(context->handle, &context->findData);
    // Ignore "." and ".."
    while (next && IS_IGNORE(context->findData))
        next = FindNextFileA(context->handle, &context->findData);
    m_name = next ? context->findData.cFileName : nullptr;
    return *this;
}

///! dir
dir::dir(const char *where)
    : m_handle(new findContext(where))
{
}

dir::~dir() {
    delete (findContext*)m_handle;
}

bool dir::isFile(const char *fileName) {
    const DWORD attribs = GetFileAttributesA(fileName);
    if (attribs == INVALID_FILE_ATTRIBUTES)
        return false;
    if (attribs & FILE_ATTRIBUTE_DIRECTORY)
        return false;
    return true;
}
#endif

}
<|endoftext|>


<commit_before>/**
 * Copyright 2012 Thinkbox Software 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.
 *
 * This file contains definitions for working with prt data types at runtime and compile time.
 * See http://www.thinkboxsoftware.com/krak-prt-file-format/ for more details.
 */

#pragma once

#include <string>
#include <stdexcept>

#include <string>

#pragma warning( push, 3 )
#include <half.h>
#pragma warning( pop )

#include <cctype>
#include <string>

#if defined(WIN32) || defined(_WIN64)
#if _MSC_VER >= 1600
#define HAS_CSTDINT_TYPES
#define STDNAMESPACE std
#include <cstdint>
#endif
#else
#define HAS_CSTDINT_TYPES
#define STDNAMESPACE
#include <stdint.h>
#endif

namespace prtio{
namespace data_types{

	//This list contains all the types defined in the PRT file spec at
	//http://www.thinkboxsoftware.com/krak-prt-file-format/
	enum enum_t{
		type_int16,
		type_int32,
		type_int64,
		type_float16,
		type_float32,
		type_float64,
		type_uint16,
		type_uint32,
		type_uint64,
		type_int8,
		type_uint8,
		type_count //This must be the last entry. It's a marker for the number of possible inputs
	};

	typedef half   float16_t;
	typedef float  float32_t;
	typedef double float64_t;

//I foresee this changing depending on the platform & compiler.
#ifndef HAS_CSTDINT_TYPES
	typedef char      int8_t;
	typedef short     int16_t;
	typedef int       int32_t;
	typedef long long int64_t;

	typedef unsigned char      uint8_t;
	typedef unsigned short     uint16_t;
	typedef unsigned int       uint32_t;
	typedef unsigned long long uint64_t;
#else
	using STDNAMESPACE::int8_t;
	using STDNAMESPACE::int16_t;
	using STDNAMESPACE::int32_t;
	using STDNAMESPACE::int64_t;

	using STDNAMESPACE::uint8_t;
	using STDNAMESPACE::uint16_t;
	using STDNAMESPACE::uint32_t;
	using STDNAMESPACE::uint64_t;
#endif

	//This global array may be indexed using the corresponding type enumeration. For example, the size of
	//a float32 is sizes[type_float32].
	const std::size_t sizes[] = {
		sizeof(int16_t), sizeof(int32_t), sizeof(int64_t),
		sizeof(float16_t), sizeof(float32_t), sizeof(float64_t),
		sizeof(uint16_t), sizeof(uint32_t), sizeof(uint64_t),
		sizeof(int8_t), sizeof(uint8_t)
	};

	//This global array maps from enum_t values to names. For example the name for type_float32 is names[type_float32].
	const char* names[] = {
		"int16", "int32", "int64",
		"float16", "float32", "float64",
		"uint16", "uint32", "uint64",
		"int8", "uint8"
	};

	/**
	 * The traits template class and it specializations exist to provide compile time information about a mapping
	 * from C++ types to PRT io types.
	 * @tparam T The type we are mapping into the PRT file io enumeration types.
	 * @note traits<T>::data_type() returns the enum_t value of the equivalent PRT io type for T.
	 */
	template <typename T>
	struct traits;

#define PRT_TRAITS_IMPL( type, enumVal ) \
	template <> \
	struct traits< type >{ \
		inline static enum_t data_type(){ \
			return enumVal; \
		} \
	};

	PRT_TRAITS_IMPL( int8_t , type_int8 );
	PRT_TRAITS_IMPL( int16_t, type_int16 );
	PRT_TRAITS_IMPL( int32_t, type_int32 );
	PRT_TRAITS_IMPL( int64_t, type_int64 );

	PRT_TRAITS_IMPL( uint8_t , type_uint8 );
	PRT_TRAITS_IMPL( uint16_t, type_uint16 );
	PRT_TRAITS_IMPL( uint32_t, type_uint32 );
	PRT_TRAITS_IMPL( uint64_t, type_uint64 );

	PRT_TRAITS_IMPL( float16_t, type_float16 );
	PRT_TRAITS_IMPL( float32_t, type_float32 );
	PRT_TRAITS_IMPL( float64_t, type_float64 );

#if defined(WIN32) || defined(_WIN64)
	//Windows treats long and int as separate types.
	PRT_TRAITS_IMPL( long, type_int32 );
	PRT_TRAITS_IMPL( unsigned long, type_uint32 );
#endif

#undef PRT_TRAITS_IMPL

	/**
	 * Extracts a data_type::enum_t from a string representation.
	 */
	std::pair<enum_t,std::size_t> parse_data_type( const std::string& typeString ){
		std::string::const_iterator it = typeString.begin(), itEnd = typeString.end();

		//Skip beginning whitespace
		for( ; it != itEnd && std::isspace(*it); ++it )
			;

		//The type comes first, ending at whitespace or a [ bracket.
		std::string::const_iterator typeStart = it;
		for( ; it != itEnd && !std::isspace(*it) && (*it) != '['; ++it )
			;
		std::string::const_iterator typeEnd = it;

		if( it == itEnd )
			throw std::runtime_error( "Invalid data type string: \"" + typeString + "\"" );

		//Skip whitespace until an open bracket.
		for( ; it != itEnd && std::isspace(*it); ++it )
			;

		//Make sure we closed the arity in brackets correctly
		if( it == itEnd || (*it) != '[' )
			throw std::runtime_error( "Invalid data type string: \"" + typeString + "\"" );

		std::string::const_iterator arityStart = ++it;
		for( ; it != itEnd && std::isdigit(*it); ++it )
			;

		if( it == itEnd || (*it) != ']' || ++it != itEnd )
			throw std::runtime_error( "Invalid data type string: \"" + typeString + "\"" );

		enum_t resultType = type_count;
		std::size_t resultArity = 0;

		for( int i = 0, iEnd = type_count; i < iEnd && resultType == type_count; ++i ){
			if( std::strncmp( names[i], &*typeStart, (typeEnd - typeStart) ) == 0 )
				resultType = static_cast<enum_t>( i );
		}

		resultArity = static_cast<std::size_t>( atoi( &*arityStart ) );

		return std::make_pair( resultType, resultArity );
	}

}//namespace data_types
}//namespace prtio
<commit_msg>Add static to const char array so that it is defined only once Add inline into template function so that it is declared only once If the above is not done, multiple include of headers will result in compiler errors<commit_after>/**
 * Copyright 2012 Thinkbox Software 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.
 *
 * This file contains definitions for working with prt data types at runtime and compile time.
 * See http://www.thinkboxsoftware.com/krak-prt-file-format/ for more details.
 */

#pragma once

#include <string>
#include <stdexcept>

#include <string>

#pragma warning( push, 3 )
#include <half.h>
#pragma warning( pop )

#include <cctype>
#include <string>

#if defined(WIN32) || defined(_WIN64)
#if _MSC_VER >= 1600
#define HAS_CSTDINT_TYPES
#define STDNAMESPACE std
#include <cstdint>
#endif
#else
#define HAS_CSTDINT_TYPES
#define STDNAMESPACE
#include <stdint.h>
#endif

namespace prtio{
namespace data_types{

	//This list contains all the types defined in the PRT file spec at
	//http://www.thinkboxsoftware.com/krak-prt-file-format/
	enum enum_t{
		type_int16,
		type_int32,
		type_int64,
		type_float16,
		type_float32,
		type_float64,
		type_uint16,
		type_uint32,
		type_uint64,
		type_int8,
		type_uint8,
		type_count //This must be the last entry. It's a marker for the number of possible inputs
	};

	typedef half   float16_t;
	typedef float  float32_t;
	typedef double float64_t;

//I foresee this changing depending on the platform & compiler.
#ifndef HAS_CSTDINT_TYPES
	typedef char      int8_t;
	typedef short     int16_t;
	typedef int       int32_t;
	typedef long long int64_t;

	typedef unsigned char      uint8_t;
	typedef unsigned short     uint16_t;
	typedef unsigned int       uint32_t;
	typedef unsigned long long uint64_t;
#else
	using STDNAMESPACE::int8_t;
	using STDNAMESPACE::int16_t;
	using STDNAMESPACE::int32_t;
	using STDNAMESPACE::int64_t;

	using STDNAMESPACE::uint8_t;
	using STDNAMESPACE::uint16_t;
	using STDNAMESPACE::uint32_t;
	using STDNAMESPACE::uint64_t;
#endif

	//This global array may be indexed using the corresponding type enumeration. For example, the size of
	//a float32 is sizes[type_float32].
	const std::size_t sizes[] = {
		sizeof(int16_t), sizeof(int32_t), sizeof(int64_t),
		sizeof(float16_t), sizeof(float32_t), sizeof(float64_t),
		sizeof(uint16_t), sizeof(uint32_t), sizeof(uint64_t),
		sizeof(int8_t), sizeof(uint8_t)
	};

	//This global array maps from enum_t values to names. For example the name for type_float32 is names[type_float32].
	static const char* names[] = {
		"int16", "int32", "int64",
		"float16", "float32", "float64",
		"uint16", "uint32", "uint64",
		"int8", "uint8"
	};

	/**
	 * The traits template class and it specializations exist to provide compile time information about a mapping
	 * from C++ types to PRT io types.
	 * @tparam T The type we are mapping into the PRT file io enumeration types.
	 * @note traits<T>::data_type() returns the enum_t value of the equivalent PRT io type for T.
	 */
	template <typename T>
	struct traits;

#define PRT_TRAITS_IMPL( type, enumVal ) \
	template <> \
	struct traits< type >{ \
		inline static enum_t data_type(){ \
			return enumVal; \
		} \
	};

	PRT_TRAITS_IMPL( int8_t , type_int8 );
	PRT_TRAITS_IMPL( int16_t, type_int16 );
	PRT_TRAITS_IMPL( int32_t, type_int32 );
	PRT_TRAITS_IMPL( int64_t, type_int64 );

	PRT_TRAITS_IMPL( uint8_t , type_uint8 );
	PRT_TRAITS_IMPL( uint16_t, type_uint16 );
	PRT_TRAITS_IMPL( uint32_t, type_uint32 );
	PRT_TRAITS_IMPL( uint64_t, type_uint64 );

	PRT_TRAITS_IMPL( float16_t, type_float16 );
	PRT_TRAITS_IMPL( float32_t, type_float32 );
	PRT_TRAITS_IMPL( float64_t, type_float64 );

#if defined(WIN32) || defined(_WIN64)
	//Windows treats long and int as separate types.
	PRT_TRAITS_IMPL( long, type_int32 );
	PRT_TRAITS_IMPL( unsigned long, type_uint32 );
#endif

#undef PRT_TRAITS_IMPL

	/**
	 * Extracts a data_type::enum_t from a string representation.
	 */
	inline std::pair<enum_t,std::size_t> parse_data_type( const std::string& typeString ){
		std::string::const_iterator it = typeString.begin(), itEnd = typeString.end();

		//Skip beginning whitespace
		for( ; it != itEnd && std::isspace(*it); ++it )
			;

		//The type comes first, ending at whitespace or a [ bracket.
		std::string::const_iterator typeStart = it;
		for( ; it != itEnd && !std::isspace(*it) && (*it) != '['; ++it )
			;
		std::string::const_iterator typeEnd = it;

		if( it == itEnd )
			throw std::runtime_error( "Invalid data type string: \"" + typeString + "\"" );

		//Skip whitespace until an open bracket.
		for( ; it != itEnd && std::isspace(*it); ++it )
			;

		//Make sure we closed the arity in brackets correctly
		if( it == itEnd || (*it) != '[' )
			throw std::runtime_error( "Invalid data type string: \"" + typeString + "\"" );

		std::string::const_iterator arityStart = ++it;
		for( ; it != itEnd && std::isdigit(*it); ++it )
			;

		if( it == itEnd || (*it) != ']' || ++it != itEnd )
			throw std::runtime_error( "Invalid data type string: \"" + typeString + "\"" );

		enum_t resultType = type_count;
		std::size_t resultArity = 0;

		for( int i = 0, iEnd = type_count; i < iEnd && resultType == type_count; ++i ){
			if( std::strncmp( names[i], &*typeStart, (typeEnd - typeStart) ) == 0 )
				resultType = static_cast<enum_t>( i );
		}

		resultArity = static_cast<std::size_t>( atoi( &*arityStart ) );

		return std::make_pair( resultType, resultArity );
	}

}//namespace data_types
}//namespace prtio
<|endoftext|>


<commit_before>#include <ros/ros.h>
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <opencv/cxcore.h>
#include <std_msgs/Float64.h>
#include <std_msgs/String.h>
#include <scan2image/ScanImage.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sensor_msgs/LaserScan.h>
#include <algorithm>
#include "scan2image.h"

#include "calibration_camera_lidar/projection_matrix.h"
#include <sensor_msgs/CameraInfo.h>

#if 1 // AXE
#define XSTR(x) #x
#define STR(x) XSTR(x)
#endif

static cv::Mat cameraExtrinsicMat;
static cv::Mat cameraMat;
static cv::Mat distCoeff;
static cv::Size imageSize;

ros::Publisher transformed_point_data;
static bool isProjection;
static bool isIntrinsic;
Scan_image scan_image;

void trans_depth_points_to_image_points(Scan_points_dataset* scan_points_dataset, Image_points_dataset* image_points_dataset)
{
    float camera_x;
    float camera_y;
    float camera_z;
    int i;

    for(i = 0; i < (int)scan_points_dataset->scan_points.x.size(); i++) {

        /*
         * Coordinate transformation. Change from laser range finder coordinate to camera coordinate
         */
        camera_x = (cameraExtrinsicMat.at<double>(0,0) * scan_points_dataset->scan_points.x.at(i)*1000
                    + cameraExtrinsicMat.at<double>(0,1) * scan_points_dataset->scan_points.y.at(i)*1000
                    + cameraExtrinsicMat.at<double>(0,2) * scan_points_dataset->scan_points.z.at(i)*1000)
            + (cameraExtrinsicMat.at<double>(0,3));
        camera_y = (cameraExtrinsicMat.at<double>(1,0) * scan_points_dataset->scan_points.x.at(i)*1000
                    + cameraExtrinsicMat.at<double>(1,1) * scan_points_dataset->scan_points.y.at(i)*1000
                    + cameraExtrinsicMat.at<double>(1,2) * scan_points_dataset->scan_points.z.at(i)*1000)
            + (cameraExtrinsicMat.at<double>(1,3));
        camera_z = (cameraExtrinsicMat.at<double>(2,0) * scan_points_dataset->scan_points.x.at(i)*1000
                    + cameraExtrinsicMat.at<double>(2,1) * scan_points_dataset->scan_points.y.at(i)*1000
                    + cameraExtrinsicMat.at<double>(2,2) * scan_points_dataset->scan_points.z.at(i)*1000)
            + (cameraExtrinsicMat.at<double>(2,3));
        if (camera_z >= 0.0) {
            /*
             * Projection transformation. Change from camera coordinate to image coordinate
             */
            image_points_dataset->image_points.x.push_back((camera_x * cameraMat.at<double>(0,0) / camera_z) + cameraMat.at<double>(0,2));
            image_points_dataset->image_points.y.push_back((camera_y * cameraMat.at<double>(1,1) / camera_z) + cameraMat.at<double>(1,2));
            /*
             * Calculate euclidean distance from the camera to objects
             */
            image_points_dataset->distance.push_back(sqrt(camera_x * camera_x + camera_y * camera_y + camera_z * camera_z) * 100); //unit of length is centimeter

            /*
             * Copy to intensity
             */
            if(!(scan_points_dataset->intensity.empty())){
                image_points_dataset->intensity.push_back(scan_points_dataset->intensity.at(i));
            }
        }
    }
}

static void projection_callback(const calibration_camera_lidar::projection_matrix& msg)
{
    printf("projection\n");

	cameraExtrinsicMat = cv::Mat(4,4,CV_64F);
	for (int row=0; row<4; row++) {
		for (int col=0; col<4; col++) {
			cameraExtrinsicMat.at<double>(row, col) = msg.projection_matrix[row * 4 + col];
            printf("%f\t", cameraExtrinsicMat.at<double>(row, col));
		}
        printf("\n");
	}
    isProjection = true;
}

static void intrinsic_callback(const sensor_msgs::CameraInfo& msg)
{
    printf("intrinsic\n");

    if (!isIntrinsic || imageSize.height != msg.height || imageSize.width != msg.width) {
        if (isIntrinsic) {
            free(scan_image.distance);
            free(scan_image.intensity);
        }
        scan_image.distance = (float *)calloc(msg.height * msg.width, sizeof(float));
        scan_image.intensity = (float *)calloc(msg.height * msg.width, sizeof(float));
        scan_image.max_y = NO_DATA;
        scan_image.min_y = NO_DATA;

    }

	imageSize.height = msg.height;
	imageSize.width = msg.width;

	cameraMat = cv::Mat(3,3, CV_64F);
	for (int row=0; row<3; row++) {
		for (int col=0; col<3; col++) {
			cameraMat.at<double>(row, col) = msg.K[row * 3 + col];
            printf("%f\t", cameraMat.at<double>(row, col));
		}
        printf("\n");
	}

	distCoeff = cv::Mat(1,5,CV_64F);
	for (int col=0; col<5; col++) {
		distCoeff.at<double>(col) = msg.D[col];
	}
    isIntrinsic = true;
}

void scanCallback(const sensor_msgs::LaserScan::ConstPtr& msg)
{
    if (!(isIntrinsic && isProjection)){
        return;
    }

    static Scan_points_dataset scan_points_dataset;
    static Image_points_dataset image_points_dataset;
    static int i;
    static int count;
    static int stored_num[MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT];

//    ROS_INFO("angle_min[%f]\nangle_max:[%f]\nangle_increment:[%f]\ntime_increment:[%f]\nscan_time:[%f]\nrange_min:[%f]\nrange_max:[%f]\n", msg->angle_min * 180 / 3.141592, msg->angle_max * 180 / 3.141592, msg->angle_increment * 180 / 3.141592, msg->time_increment, msg->scan_time, msg->range_min, msg->range_max);

    /*
     * Initialize
     */
    scan_points_dataset.scan_points.x.resize(msg->ranges.size());
    scan_points_dataset.scan_points.y.resize(msg->ranges.size());
    scan_points_dataset.scan_points.z.resize(msg->ranges.size());
    scan_points_dataset.intensity.resize(msg->intensities.size());
    image_points_dataset.image_points.x.clear();
    image_points_dataset.image_points.y.clear();
    image_points_dataset.distance.clear();
    image_points_dataset.intensity.clear();
    count = 0;

    /*
     * Change to three dimentional coordinate. And copy intensity
     */
    for(i = 0; i < (int)msg->ranges.size(); i++) {
        scan_points_dataset.scan_points.x.at(i) = msg->ranges.at(i) * sin(msg->angle_min + msg->angle_increment * i); //unit of length is meter
        scan_points_dataset.scan_points.y.at(i) = 0; //unit of length is meter
        scan_points_dataset.scan_points.z.at(i) = msg->ranges.at(i) * cos(msg->angle_min + msg->angle_increment * i); //unit of length is meter
        if(!(msg->intensities.empty())){
            scan_points_dataset.intensity.at(i) = msg->intensities.at(i);
        }
    }

    /*
     * Change from laser range finder coordinate to image coordinate
     */
    trans_depth_points_to_image_points(&scan_points_dataset, &image_points_dataset);

    /*
     * Judge out of image frame. And Determine max_y and min_y
     */
    for (i = 0, count = 0; i < (int)image_points_dataset.image_points.x.size(); i++) {
        /* Judge NaN */
        if(isnan(image_points_dataset.image_points.x.at(i)) == 1 || isnan(image_points_dataset.image_points.y.at(i)) == 1) {
            std::cout <<"Not a Number is i:" << i << std::endl;
            continue;
        }
        /* Judge out of X-axis image */
        if(0 > (int)image_points_dataset.image_points.x.at(i) || (int)image_points_dataset.image_points.x.at(i) > imageSize.width - 1) {
            continue;
        }
        /* Judge out of Y-axis image */
        if(0 > (int)image_points_dataset.image_points.y.at(i) || (int)image_points_dataset.image_points.y.at(i) > imageSize.height - 1) {
            continue;
        }

        scan_image.distance[(int)image_points_dataset.image_points.x.at(i) * imageSize.height + (int)image_points_dataset.image_points.y.at(i)] = image_points_dataset.distance.at(i);

        if(!msg->intensities.empty()){
            scan_image.intensity[(int)image_points_dataset.image_points.x.at(i) * imageSize.height + (int)image_points_dataset.image_points.y.at(i)] = image_points_dataset.intensity.at(i);
        }

        if ((scan_image.max_y < (int)image_points_dataset.image_points.y.at(i)) || (scan_image.max_y == NO_DATA)) {
            scan_image.max_y = (int)image_points_dataset.image_points.y.at(i);
        } else if ((scan_image.min_y > (int)image_points_dataset.image_points.y.at(i)) || (scan_image.min_y == NO_DATA)) {
            scan_image.min_y = (int)image_points_dataset.image_points.y.at(i);
        }

        /* for init zero */
        stored_num[count] = (int)image_points_dataset.image_points.x.at(i) * imageSize.height + (int)image_points_dataset.image_points.y.at(i);
        count++;
    }

    /*
     * Create message(Topic)
     */
    scan2image::ScanImage scan_image_msg;
    scan_image_msg.header = msg->header;
    scan_image_msg.distance.assign(scan_image.distance, scan_image.distance + imageSize.width * imageSize.height);
    scan_image_msg.intensity.assign(scan_image.intensity, scan_image.intensity + imageSize.width * imageSize.height);
    scan_image_msg.max_y = scan_image.max_y;
    scan_image_msg.min_y = scan_image.min_y;

    /*
     * Publish message(Topic)
     */
    transformed_point_data.publish(scan_image_msg);

    /*
     * Init zero
     */
    for (i = 0; i < count; ++i) {
        scan_image.distance[stored_num[i]] = 0;
    }
    scan_image.max_y = NO_DATA;
    scan_image.min_y = NO_DATA;
}

int main(int argc, char **argv)
{
    isProjection = false;
    isIntrinsic = false;
    ros::init(argc, argv, "scan2image");
    ros::NodeHandle n;
    ros::Subscriber sub = n.subscribe("scan", 1, scanCallback);
    ros::Subscriber projection_sub = n.subscribe("projection_matrix", 1, projection_callback);
    ros::Subscriber intrinsic_sub = n.subscribe("camera/camera_info", 1, intrinsic_callback);
    transformed_point_data = n.advertise<scan2image::ScanImage>("scan_image", 1);

    ros::spin();

    free(scan_image.distance);
    free(scan_image.intensity);
    return 0;
}
<commit_msg>change from static variable to auto variable<commit_after>#include <ros/ros.h>
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <opencv/cxcore.h>
#include <std_msgs/Float64.h>
#include <std_msgs/String.h>
#include <scan2image/ScanImage.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sensor_msgs/LaserScan.h>
#include <algorithm>
#include "scan2image.h"

#include "calibration_camera_lidar/projection_matrix.h"
#include <sensor_msgs/CameraInfo.h>

#if 1 // AXE
#define XSTR(x) #x
#define STR(x) XSTR(x)
#endif

static cv::Mat cameraExtrinsicMat;
static cv::Mat cameraMat;
static cv::Mat distCoeff;
static cv::Size imageSize;

ros::Publisher transformed_point_data;
static bool isProjection;
static bool isIntrinsic;
Scan_image scan_image;

void trans_depth_points_to_image_points(Scan_points_dataset* scan_points_dataset, Image_points_dataset* image_points_dataset)
{
    float camera_x;
    float camera_y;
    float camera_z;
    int i;

    for(i = 0; i < (int)scan_points_dataset->scan_points.x.size(); i++) {

        /*
         * Coordinate transformation. Change from laser range finder coordinate to camera coordinate
         */
        camera_x = (cameraExtrinsicMat.at<double>(0,0) * scan_points_dataset->scan_points.x.at(i)*1000
                    + cameraExtrinsicMat.at<double>(0,1) * scan_points_dataset->scan_points.y.at(i)*1000
                    + cameraExtrinsicMat.at<double>(0,2) * scan_points_dataset->scan_points.z.at(i)*1000)
            + (cameraExtrinsicMat.at<double>(0,3));
        camera_y = (cameraExtrinsicMat.at<double>(1,0) * scan_points_dataset->scan_points.x.at(i)*1000
                    + cameraExtrinsicMat.at<double>(1,1) * scan_points_dataset->scan_points.y.at(i)*1000
                    + cameraExtrinsicMat.at<double>(1,2) * scan_points_dataset->scan_points.z.at(i)*1000)
            + (cameraExtrinsicMat.at<double>(1,3));
        camera_z = (cameraExtrinsicMat.at<double>(2,0) * scan_points_dataset->scan_points.x.at(i)*1000
                    + cameraExtrinsicMat.at<double>(2,1) * scan_points_dataset->scan_points.y.at(i)*1000
                    + cameraExtrinsicMat.at<double>(2,2) * scan_points_dataset->scan_points.z.at(i)*1000)
            + (cameraExtrinsicMat.at<double>(2,3));
        if (camera_z >= 0.0) {
            /*
             * Projection transformation. Change from camera coordinate to image coordinate
             */
            image_points_dataset->image_points.x.push_back((camera_x * cameraMat.at<double>(0,0) / camera_z) + cameraMat.at<double>(0,2));
            image_points_dataset->image_points.y.push_back((camera_y * cameraMat.at<double>(1,1) / camera_z) + cameraMat.at<double>(1,2));
            /*
             * Calculate euclidean distance from the camera to objects
             */
            image_points_dataset->distance.push_back(sqrt(camera_x * camera_x + camera_y * camera_y + camera_z * camera_z) * 100); //unit of length is centimeter

            /*
             * Copy to intensity
             */
            if(!(scan_points_dataset->intensity.empty())){
                image_points_dataset->intensity.push_back(scan_points_dataset->intensity.at(i));
            }
        }
    }
}

static void projection_callback(const calibration_camera_lidar::projection_matrix& msg)
{
    printf("projection\n");

	cameraExtrinsicMat = cv::Mat(4,4,CV_64F);
	for (int row=0; row<4; row++) {
		for (int col=0; col<4; col++) {
			cameraExtrinsicMat.at<double>(row, col) = msg.projection_matrix[row * 4 + col];
            printf("%f\t", cameraExtrinsicMat.at<double>(row, col));
		}
        printf("\n");
	}
    isProjection = true;
}

static void intrinsic_callback(const sensor_msgs::CameraInfo& msg)
{
    printf("intrinsic\n");

    if (!isIntrinsic || imageSize.height != msg.height || imageSize.width != msg.width) {
        if (isIntrinsic) {
            free(scan_image.distance);
            free(scan_image.intensity);
        }
        scan_image.distance = (float *)calloc(msg.height * msg.width, sizeof(float));
        scan_image.intensity = (float *)calloc(msg.height * msg.width, sizeof(float));
        scan_image.max_y = NO_DATA;
        scan_image.min_y = NO_DATA;

    }

	imageSize.height = msg.height;
	imageSize.width = msg.width;

	cameraMat = cv::Mat(3,3, CV_64F);
	for (int row=0; row<3; row++) {
		for (int col=0; col<3; col++) {
			cameraMat.at<double>(row, col) = msg.K[row * 3 + col];
            printf("%f\t", cameraMat.at<double>(row, col));
		}
        printf("\n");
	}

	distCoeff = cv::Mat(1,5,CV_64F);
	for (int col=0; col<5; col++) {
		distCoeff.at<double>(col) = msg.D[col];
	}
    isIntrinsic = true;
}

void scanCallback(const sensor_msgs::LaserScan::ConstPtr& msg)
{
    if (!(isIntrinsic && isProjection)){
        return;
    }

    static Scan_points_dataset scan_points_dataset;
    static Image_points_dataset image_points_dataset;
    static int stored_num[MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT];
    int i;
    int count;

//    ROS_INFO("angle_min[%f]\nangle_max:[%f]\nangle_increment:[%f]\ntime_increment:[%f]\nscan_time:[%f]\nrange_min:[%f]\nrange_max:[%f]\n", msg->angle_min * 180 / 3.141592, msg->angle_max * 180 / 3.141592, msg->angle_increment * 180 / 3.141592, msg->time_increment, msg->scan_time, msg->range_min, msg->range_max);

    /*
     * Initialize
     */
    scan_points_dataset.scan_points.x.resize(msg->ranges.size());
    scan_points_dataset.scan_points.y.resize(msg->ranges.size());
    scan_points_dataset.scan_points.z.resize(msg->ranges.size());
    scan_points_dataset.intensity.resize(msg->intensities.size());
    image_points_dataset.image_points.x.clear();
    image_points_dataset.image_points.y.clear();
    image_points_dataset.distance.clear();
    image_points_dataset.intensity.clear();
    count = 0;

    /*
     * Change to three dimentional coordinate. And copy intensity
     */
    for(i = 0; i < (int)msg->ranges.size(); i++) {
        scan_points_dataset.scan_points.x.at(i) = msg->ranges.at(i) * sin(msg->angle_min + msg->angle_increment * i); //unit of length is meter
        scan_points_dataset.scan_points.y.at(i) = 0; //unit of length is meter
        scan_points_dataset.scan_points.z.at(i) = msg->ranges.at(i) * cos(msg->angle_min + msg->angle_increment * i); //unit of length is meter
        if(!(msg->intensities.empty())){
            scan_points_dataset.intensity.at(i) = msg->intensities.at(i);
        }
    }

    /*
     * Change from laser range finder coordinate to image coordinate
     */
    trans_depth_points_to_image_points(&scan_points_dataset, &image_points_dataset);

    /*
     * Judge out of image frame. And Determine max_y and min_y
     */
    for (i = 0, count = 0; i < (int)image_points_dataset.image_points.x.size(); i++) {
        /* Judge NaN */
        if(isnan(image_points_dataset.image_points.x.at(i)) == 1 || isnan(image_points_dataset.image_points.y.at(i)) == 1) {
            std::cout <<"Not a Number is i:" << i << std::endl;
            continue;
        }
        /* Judge out of X-axis image */
        if(0 > (int)image_points_dataset.image_points.x.at(i) || (int)image_points_dataset.image_points.x.at(i) > imageSize.width - 1) {
            continue;
        }
        /* Judge out of Y-axis image */
        if(0 > (int)image_points_dataset.image_points.y.at(i) || (int)image_points_dataset.image_points.y.at(i) > imageSize.height - 1) {
            continue;
        }

        scan_image.distance[(int)image_points_dataset.image_points.x.at(i) * imageSize.height + (int)image_points_dataset.image_points.y.at(i)] = image_points_dataset.distance.at(i);

        if(!msg->intensities.empty()){
            scan_image.intensity[(int)image_points_dataset.image_points.x.at(i) * imageSize.height + (int)image_points_dataset.image_points.y.at(i)] = image_points_dataset.intensity.at(i);
        }

        if ((scan_image.max_y < (int)image_points_dataset.image_points.y.at(i)) || (scan_image.max_y == NO_DATA)) {
            scan_image.max_y = (int)image_points_dataset.image_points.y.at(i);
        } else if ((scan_image.min_y > (int)image_points_dataset.image_points.y.at(i)) || (scan_image.min_y == NO_DATA)) {
            scan_image.min_y = (int)image_points_dataset.image_points.y.at(i);
        }

        /* for init zero */
        stored_num[count] = (int)image_points_dataset.image_points.x.at(i) * imageSize.height + (int)image_points_dataset.image_points.y.at(i);
        count++;
    }

    /*
     * Create message(Topic)
     */
    scan2image::ScanImage scan_image_msg;
    scan_image_msg.header = msg->header;
    scan_image_msg.distance.assign(scan_image.distance, scan_image.distance + imageSize.width * imageSize.height);
    scan_image_msg.intensity.assign(scan_image.intensity, scan_image.intensity + imageSize.width * imageSize.height);
    scan_image_msg.max_y = scan_image.max_y;
    scan_image_msg.min_y = scan_image.min_y;

    /*
     * Publish message(Topic)
     */
    transformed_point_data.publish(scan_image_msg);

    /*
     * Init zero
     */
    for (i = 0; i < count; ++i) {
        scan_image.distance[stored_num[i]] = 0;
    }
    scan_image.max_y = NO_DATA;
    scan_image.min_y = NO_DATA;
}

int main(int argc, char **argv)
{
    isProjection = false;
    isIntrinsic = false;
    ros::init(argc, argv, "scan2image");
    ros::NodeHandle n;
    ros::Subscriber sub = n.subscribe("scan", 1, scanCallback);
    ros::Subscriber projection_sub = n.subscribe("projection_matrix", 1, projection_callback);
    ros::Subscriber intrinsic_sub = n.subscribe("camera/camera_info", 1, intrinsic_callback);
    transformed_point_data = n.advertise<scan2image::ScanImage>("scan_image", 1);

    ros::spin();

    free(scan_image.distance);
    free(scan_image.intensity);
    return 0;
}
<|endoftext|>


<commit_before>//==============================================================================
// Main source file
//==============================================================================

#include <QCoreApplication>
#include <QMap>
#include <QProcess>
#include <QString>

//==============================================================================

#include <iostream>

//==============================================================================

typedef QMap<QString, QStringList> Tests;

//==============================================================================

int main(int pArgc, char *pArgv[])
{
    // Retrieve the different arguments that were passed

    QStringList args = QStringList();

    for (int i = 1; i < pArgc; ++i)
        args << pArgv[i];

    // The different tests that are  to be run

    Tests tests;

    tests["CellMLSupport"] = QStringList() << "test";

    // Run the different tests

    QString exePath = QCoreApplication(pArgc, pArgv).applicationDirPath();
    QStringList failedTests = QStringList();
    int res = 0;

    Tests::const_iterator iter = tests.constBegin();

    while (iter != tests.constEnd()) {
        if (iter != tests.constBegin()) {
            std::cout << std::endl;
            std::cout << std::endl;
            std::cout << std::endl;
        }

        std::cout << "********* " << qPrintable(iter.key()) << " *********" << std::endl;
        std::cout << std::endl;

        foreach (const QString &test, iter.value()) {
            QString testName = QString("%1_%2").arg(iter.key(), test);

            // On Linux and Mac OS X, if we want to load plugins, we must
            // execute the test from the directory where the test is, so...

            ::chdir(qPrintable(exePath));

            // Execute the test itself

            int testRes = QProcess::execute(QString("%1/%2").arg(exePath, testName), args);

            if (testRes)
                failedTests << testName;

            res = res?res:testRes;

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

        std::cout << qPrintable(QString("*").repeated(9+1+iter.key().count()+1+9)) << std::endl;

        ++iter;
    }

    // Reporting

    std::cout << std::endl;
    std::cout << std::endl;
    std::cout << std::endl;
    std::cout << "********* Reporting *********" << std::endl;
    std::cout << std::endl;

    if (failedTests.isEmpty()) {
        std::cout << "All the tests passed!" << std::endl;
    } else {
        if (failedTests.count() == 1)
            std::cout << "The following test failed:" << std::endl;
        else
            std::cout << "The following tests failed:" << std::endl;

        foreach (const QString &failedTest, failedTests)
            std::cout << " - " << qPrintable(failedTest) << std::endl;
    }

    std::cout << std::endl;
    std::cout << "*****************************" << std::endl;

    // Return the overall outcome of the tests

    return res;
}

//==============================================================================
// End of file
//==============================================================================
<commit_msg>Fixed an issue (which I thought didn't exist) with regards to the running of tests.<commit_after>//==============================================================================
// Main source file
//==============================================================================

#include <QCoreApplication>
#include <QMap>
#include <QProcess>
#include <QString>

//==============================================================================

#include <iostream>

//==============================================================================

typedef QMap<QString, QStringList> Tests;

//==============================================================================

int main(int pArgc, char *pArgv[])
{
    // Retrieve the different arguments that were passed

    QStringList args = QStringList();

    for (int i = 1; i < pArgc; ++i)
        args << pArgv[i];

    // The different tests that are  to be run

    Tests tests;

    tests["CellMLSupport"] = QStringList() << "test";

    // Run the different tests

    QString exePath = QCoreApplication(pArgc, pArgv).applicationDirPath();
    QStringList failedTests = QStringList();
    int res = 0;

    Tests::const_iterator iter = tests.constBegin();

    while (iter != tests.constEnd()) {
        if (iter != tests.constBegin()) {
            std::cout << std::endl;
            std::cout << std::endl;
            std::cout << std::endl;
        }

        std::cout << "********* " << qPrintable(iter.key()) << " *********" << std::endl;
        std::cout << std::endl;

        foreach (const QString &test, iter.value()) {
            QString testName = QString("%1_%2").arg(iter.key(), test);

            // On Linux and Mac OS X, if we want to load plugins, we must
            // execute the test from the directory where the test is, so...

#ifndef Q_WS_WIN
            ::chdir(qPrintable(exePath));
#endif

            // Execute the test itself

            int testRes = QProcess::execute(QString("%1/%2").arg(exePath, testName), args);

            if (testRes)
                failedTests << testName;

            res = res?res:testRes;

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

        std::cout << qPrintable(QString("*").repeated(9+1+iter.key().count()+1+9)) << std::endl;

        ++iter;
    }

    // Reporting

    std::cout << std::endl;
    std::cout << std::endl;
    std::cout << std::endl;
    std::cout << "********* Reporting *********" << std::endl;
    std::cout << std::endl;

    if (failedTests.isEmpty()) {
        std::cout << "All the tests passed!" << std::endl;
    } else {
        if (failedTests.count() == 1)
            std::cout << "The following test failed:" << std::endl;
        else
            std::cout << "The following tests failed:" << std::endl;

        foreach (const QString &failedTest, failedTests)
            std::cout << " - " << qPrintable(failedTest) << std::endl;
    }

    std::cout << std::endl;
    std::cout << "*****************************" << std::endl;

    // Return the overall outcome of the tests

    return res;
}

//==============================================================================
// End of file
//==============================================================================
<|endoftext|>


<commit_before>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

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

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

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

*/

#include <iostream>
#include <boost/config.hpp>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h> // for exit()
#include "setup_transfer.hpp" // for tests_failure

int test_main();

#include "libtorrent/assert.hpp"
#include "libtorrent/file.hpp"
#include <signal.h>

void sig_handler(int sig)
{
	char stack_text[10000];

#if (defined TORRENT_DEBUG && !TORRENT_NO_ASSERTS) || TORRENT_RELEASE_ASSERTS
	print_backtrace(stack_text, sizeof(stack_text), 30);
#elif defined __FUNCTION__
	strcat(stack_text, __FUNCTION__);
#else
	stack_text[0] = 0;
#endif
	char const* sig_name = 0;
	switch (sig)
	{
#define SIG(x) case x: sig_name = #x; break
		SIG(SIGSEGV);
#ifdef SIGBUS
		SIG(SIGBUS);
#endif
		SIG(SIGILL);
		SIG(SIGABRT);
		SIG(SIGFPE);
#ifdef SIGSYS
		SIG(SIGSYS);
#endif
#undef SIG
	};
	fprintf(stderr, "signal: %s caught:\n%s\n", sig_name, stack_text);
	exit(138);
}

using namespace libtorrent;

int main()
{
#ifdef O_NONBLOCK
	// on darwin, stdout is set to non-blocking mode by default
	// which sometimes causes tests to fail with EAGAIN just
	// by printing logs
	int flags = fcntl(fileno(stdout), F_GETFL, 0);
	fcntl(fileno(stdout), F_SETFL, flags & ~O_NONBLOCK);
	flags = fcntl(fileno(stderr), F_GETFL, 0);
	fcntl(fileno(stderr), F_SETFL, flags & ~O_NONBLOCK);
#endif

	signal(SIGSEGV, &sig_handler);
#ifdef SIGBUS
	signal(SIGBUS, &sig_handler);
#endif
	signal(SIGILL, &sig_handler);
	signal(SIGABRT, &sig_handler);
	signal(SIGFPE, &sig_handler);
#ifdef SIGSYS
	signal(SIGSYS, &sig_handler);
#endif

	char dir[40];
	snprintf(dir, sizeof(dir), "test_tmp_%u", rand());
	std::string test_dir = complete(dir);
	error_code ec;
	create_directory(test_dir, ec);
	if (ec)
	{
		fprintf(stderr, "Failed to create test directory: %s\n", ec.message().c_str());
		return 1;
	}
#ifdef TORRENT_WINDOWS
	SetCurrentDirectoryA(dir);
#else
	chdir(dir);
#endif

#ifndef BOOST_NO_EXCEPTIONS
	try
	{
#endif
		test_main();
#ifndef BOOST_NO_EXCEPTIONS
	}
	catch (std::exception const& e)
	{
		std::cerr << "Terminated with exception: \"" << e.what() << "\"\n";
		tests_failure = true;
	}
	catch (...)
	{
		std::cerr << "Terminated with unknown exception\n";
		tests_failure = true;
	}
#endif
	fflush(stdout);
	fflush(stderr);
	remove_all(test_dir, ec);
	if (ec)
		fprintf(stderr, "failed to remove test dir: %s\n", ec.message().c_str());
	return tests_failure ? 1 : 0;
}

<commit_msg>initialize random number generator for tests<commit_after>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

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

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

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

*/

#include <iostream>
#include <boost/config.hpp>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h> // for exit()
#include "setup_transfer.hpp" // for tests_failure

int test_main();

#include "libtorrent/assert.hpp"
#include "libtorrent/file.hpp"
#include <signal.h>

void sig_handler(int sig)
{
	char stack_text[10000];

#if (defined TORRENT_DEBUG && !TORRENT_NO_ASSERTS) || TORRENT_RELEASE_ASSERTS
	print_backtrace(stack_text, sizeof(stack_text), 30);
#elif defined __FUNCTION__
	strcat(stack_text, __FUNCTION__);
#else
	stack_text[0] = 0;
#endif
	char const* sig_name = 0;
	switch (sig)
	{
#define SIG(x) case x: sig_name = #x; break
		SIG(SIGSEGV);
#ifdef SIGBUS
		SIG(SIGBUS);
#endif
		SIG(SIGILL);
		SIG(SIGABRT);
		SIG(SIGFPE);
#ifdef SIGSYS
		SIG(SIGSYS);
#endif
#undef SIG
	};
	fprintf(stderr, "signal: %s caught:\n%s\n", sig_name, stack_text);
	exit(138);
}

using namespace libtorrent;

int main()
{
	srand(total_microseconds(time_now_hires() - min_time()));
#ifdef O_NONBLOCK
	// on darwin, stdout is set to non-blocking mode by default
	// which sometimes causes tests to fail with EAGAIN just
	// by printing logs
	int flags = fcntl(fileno(stdout), F_GETFL, 0);
	fcntl(fileno(stdout), F_SETFL, flags & ~O_NONBLOCK);
	flags = fcntl(fileno(stderr), F_GETFL, 0);
	fcntl(fileno(stderr), F_SETFL, flags & ~O_NONBLOCK);
#endif

	signal(SIGSEGV, &sig_handler);
#ifdef SIGBUS
	signal(SIGBUS, &sig_handler);
#endif
	signal(SIGILL, &sig_handler);
	signal(SIGABRT, &sig_handler);
	signal(SIGFPE, &sig_handler);
#ifdef SIGSYS
	signal(SIGSYS, &sig_handler);
#endif

	char dir[40];
	snprintf(dir, sizeof(dir), "test_tmp_%u", rand());
	std::string test_dir = complete(dir);
	error_code ec;
	create_directory(test_dir, ec);
	if (ec)
	{
		fprintf(stderr, "Failed to create test directory: %s\n", ec.message().c_str());
		return 1;
	}
#ifdef TORRENT_WINDOWS
	SetCurrentDirectoryA(dir);
#else
	chdir(dir);
#endif

#ifndef BOOST_NO_EXCEPTIONS
	try
	{
#endif
		test_main();
#ifndef BOOST_NO_EXCEPTIONS
	}
	catch (std::exception const& e)
	{
		std::cerr << "Terminated with exception: \"" << e.what() << "\"\n";
		tests_failure = true;
	}
	catch (...)
	{
		std::cerr << "Terminated with unknown exception\n";
		tests_failure = true;
	}
#endif
	fflush(stdout);
	fflush(stderr);
	remove_all(test_dir, ec);
	if (ec)
		fprintf(stderr, "failed to remove test dir: %s\n", ec.message().c_str());
	return tests_failure ? 1 : 0;
}

<|endoftext|>


<commit_before>#include "fly/logger/styler.hpp"
#include "fly/types/string/string.hpp"

// clang-format off
// Due to a missing #include in catch_reporter_registrars.hpp, this must be included first.
#include "catch2/interfaces/catch_interfaces_reporter.hpp"
// clang-format on

#include "catch2/catch_reporter_registrars.hpp"
#include "catch2/catch_session.hpp"
#include "catch2/catch_test_case_info.hpp"
#include "catch2/reporters/catch_reporter_console.hpp"

#include <chrono>
#include <cstdint>
#include <string>
#include <vector>

/**
 * A Catch2 test reporter for reporting colorful test and section names to console.
 */
class FlyReporter : public Catch::ConsoleReporter
{
public:
    explicit FlyReporter(const Catch::ReporterConfig &config) : Catch::ConsoleReporter(config)
    {
    }

    ~FlyReporter() override = default;

    static std::string getDescription()
    {
        return "Catch2 test reporter for libfly";
    }

    void testRunStarting(const Catch::TestRunInfo &info) override
    {
        Catch::ConsoleReporter::testRunStarting(info);
        m_test_start = std::chrono::steady_clock::now();
    }

    void testRunEnded(const Catch::TestRunStats &stats) override
    {
        Catch::ConsoleReporter::testRunEnded(stats);

        const auto end = std::chrono::steady_clock::now();
        const auto duration = std::chrono::duration<double>(end - m_test_start);

        // ConsoleReporter prints a second newline above, so go up one line before logging the time.
        stream << fly::logger::Styler(
                      fly::logger::Cursor::Up,
                      fly::logger::Style::Bold,
                      fly::logger::Color::Cyan)
               << "Total time ";
        stream << fly::String::format("{:.3f} seconds\n\n", duration.count());
    }

    void testCaseStarting(const Catch::TestCaseInfo &info) override
    {
        Catch::ConsoleReporter::testCaseStarting(info);

        stream_header(fly::logger::Color::Green, fly::String::format("{} Test", info.name));
        m_current_test_case_start = std::chrono::steady_clock::now();
    }

    void sectionStarting(const Catch::SectionInfo &info) override
    {
        Catch::ConsoleReporter::sectionStarting(info);
        std::size_t level = m_section_level++;

        if (level == 0)
        {
            m_sections.push_back(info.name);
            return;
        }

        auto path = fly::String::join('/', m_sections.back(), info.name);

        if (auto it = std::find(m_sections.begin(), m_sections.end(), path); it != m_sections.end())
        {
            std::swap(*it, *(m_sections.end() - 1));
            return;
        }

        const fly::logger::Styler style(fly::logger::Color::Cyan, fly::logger::Style::Italic);
        stream << style << "[ ";

        if (level != 1)
        {
            stream << fly::String::format("{: >{}}└─➤ ", "", (level - 2) * 4);
        }

        stream << fly::String::format("{} ]\n", info.name);

        m_sections.push_back(std::move(path));
    }

    void sectionEnded(const Catch::SectionStats &stats) override
    {
        Catch::ConsoleReporter::sectionEnded(stats);
        --m_section_level;
    }

    void testCaseEnded(const Catch::TestCaseStats &stats) override
    {
        Catch::ConsoleReporter::testCaseEnded(stats);

        const auto end = std::chrono::steady_clock::now();
        const auto duration = std::chrono::duration<double>(end - m_current_test_case_start);

        const std::string &name = stats.testInfo->name;

        if (stats.totals.assertions.allOk())
        {
            stream_header(
                fly::logger::Color::Green,
                fly::String::format("PASSED {} ({:.3f} seconds)", name, duration.count()));
        }
        else
        {
            stream_header(
                fly::logger::Color::Red,
                fly::String::format("FAILED {} ({:.3f} seconds)", name, duration.count()));
        }

        stream << '\n';
        m_sections.clear();
    }

private:
    void stream_header(fly::logger::Color::StandardColor color, std::string message)
    {
        stream << fly::logger::Styler(fly::logger::Style::Bold, color)
               << fly::String::format("[==== {} ====]\n", message);
    }

    std::chrono::steady_clock::time_point m_test_start;
    std::chrono::steady_clock::time_point m_current_test_case_start;

    std::vector<std::string> m_sections;
    std::size_t m_section_level {0};
};

CATCH_REGISTER_REPORTER("libfly", FlyReporter)

int main(int argc, char **argv)
{
    return Catch::Session().run(argc, argv);
}
<commit_msg>Move libfly Catch2 reporter method definitions out-of-line<commit_after>#include "fly/logger/styler.hpp"
#include "fly/types/string/string.hpp"

// clang-format off
// Due to a missing #include in catch_reporter_registrars.hpp, this must be included first.
#include "catch2/interfaces/catch_interfaces_reporter.hpp"
// clang-format on

#include "catch2/catch_reporter_registrars.hpp"
#include "catch2/catch_session.hpp"
#include "catch2/catch_test_case_info.hpp"
#include "catch2/reporters/catch_reporter_console.hpp"

#include <chrono>
#include <cstdint>
#include <string>
#include <vector>

/**
 * A Catch2 test reporter for reporting colorful test and section names to console.
 */
class FlyReporter : public Catch::ConsoleReporter
{
public:
    explicit FlyReporter(const Catch::ReporterConfig &config);
    ~FlyReporter() override = default;

    static std::string getDescription();

    void testRunStarting(const Catch::TestRunInfo &info) override;
    void testCaseStarting(const Catch::TestCaseInfo &info) override;
    void sectionStarting(const Catch::SectionInfo &info) override;
    void sectionEnded(const Catch::SectionStats &stats) override;
    void testCaseEnded(const Catch::TestCaseStats &stats) override;
    void testRunEnded(const Catch::TestRunStats &stats) override;

private:
    void stream_header(fly::logger::Color::StandardColor color, std::string message);

    std::chrono::steady_clock::time_point m_test_start;
    std::chrono::steady_clock::time_point m_current_test_case_start;

    std::vector<std::string> m_sections;
    std::size_t m_section_level {0};
};

//==================================================================================================
FlyReporter::FlyReporter(const Catch::ReporterConfig &config) : Catch::ConsoleReporter(config)
{
}

//==================================================================================================
std::string FlyReporter::getDescription()
{
    return "Catch2 test reporter for libfly";
}

//==================================================================================================
void FlyReporter::testRunStarting(const Catch::TestRunInfo &info)
{
    Catch::ConsoleReporter::testRunStarting(info);
    m_test_start = std::chrono::steady_clock::now();
}

//==================================================================================================
void FlyReporter::testCaseStarting(const Catch::TestCaseInfo &info)
{
    Catch::ConsoleReporter::testCaseStarting(info);

    stream_header(fly::logger::Color::Green, fly::String::format("{} Test", info.name));
    m_current_test_case_start = std::chrono::steady_clock::now();
}

//==================================================================================================
void FlyReporter::sectionStarting(const Catch::SectionInfo &info)
{
    Catch::ConsoleReporter::sectionStarting(info);
    std::size_t level = m_section_level++;

    if (level == 0)
    {
        m_sections.push_back(info.name);
        return;
    }

    auto section = fly::String::join('/', m_sections.back(), info.name);

    if (auto it = std::find(m_sections.begin(), m_sections.end(), section); it != m_sections.end())
    {
        std::swap(*it, *(m_sections.end() - 1));
        return;
    }

    const fly::logger::Styler style(fly::logger::Color::Cyan, fly::logger::Style::Italic);
    stream << style << "[ ";

    if (level != 1)
    {
        stream << fly::String::format("{: >{}}└─➤ ", "", (level - 2) * 4);
    }

    stream << fly::String::format("{} ]\n", info.name);

    m_sections.push_back(std::move(section));
}

//==================================================================================================
void FlyReporter::sectionEnded(const Catch::SectionStats &stats)
{
    Catch::ConsoleReporter::sectionEnded(stats);
    --m_section_level;
}

//==================================================================================================
void FlyReporter::testCaseEnded(const Catch::TestCaseStats &stats)
{
    Catch::ConsoleReporter::testCaseEnded(stats);

    const auto end = std::chrono::steady_clock::now();
    const auto duration = std::chrono::duration<double>(end - m_current_test_case_start);

    const std::string &name = stats.testInfo->name;

    if (stats.totals.assertions.allOk())
    {
        stream_header(
            fly::logger::Color::Green,
            fly::String::format("PASSED {} ({:.3f} seconds)", name, duration.count()));
    }
    else
    {
        stream_header(
            fly::logger::Color::Red,
            fly::String::format("FAILED {} ({:.3f} seconds)", name, duration.count()));
    }

    stream << '\n';
    m_sections.clear();
}

//==================================================================================================
void FlyReporter::testRunEnded(const Catch::TestRunStats &stats)
{
    Catch::ConsoleReporter::testRunEnded(stats);

    const auto end = std::chrono::steady_clock::now();
    const auto duration = std::chrono::duration<double>(end - m_test_start);

    // ConsoleReporter prints a second newline above, so go up one line before logging the time.
    stream << fly::logger::Styler(fly::logger::Cursor::Up);

    stream << fly::logger::Styler(fly::logger::Style::Bold, fly::logger::Color::Cyan)
           << "Total time ";
    stream << fly::String::format("{:.3f} seconds\n\n", duration.count());
}

//==================================================================================================
void FlyReporter::stream_header(fly::logger::Color::StandardColor color, std::string message)
{
    stream << fly::logger::Styler(fly::logger::Style::Bold, color)
           << fly::String::format("[==== {} ====]\n", message);
}

//==================================================================================================
CATCH_REGISTER_REPORTER("libfly", FlyReporter)

int main(int argc, char **argv)
{
    return Catch::Session().run(argc, argv);
}
<|endoftext|>