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

    Copyright (C) 2007 Frank Osterfeld <frank.osterfeld@kdemail.net>

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

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

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "subscriptionlistview.h"
#include "subscriptionlistmodel.h"
#include "subscriptionlistdelegate.h"
#include "akregatorconfig.h"

#include <QHeaderView>
#include <QStack>
#include <QPointer>

#include <KMenu>
#include <KLocale>
#include <KDebug>
#include <KConfigGroup>

#include <cassert>

using namespace Akregator;

namespace {

QModelIndex prevIndex( const QModelIndex& idx )
{
    if ( !idx.isValid() )
        return QModelIndex();
    const QAbstractItemModel* const model = idx.model();
    assert( model );

    if ( idx.row() > 0 )
    {
        QModelIndex i = idx.sibling( idx.row() - 1, idx.column() );
        while ( model->hasChildren( i ) )
            i = i.child( model->rowCount( i ) - 1, i.column() );
        return i;
    }
    else
        return idx.parent();
}

QModelIndex prevFeedIndex( const QModelIndex& idx, bool allowPassed = false )
{
    QModelIndex prev = allowPassed ? idx : prevIndex( idx );
    while ( prev.isValid() && prev.data( SubscriptionListModel::IsAggregationRole ).toBool() )
        prev = prevIndex( prev );
    return prev;
}

QModelIndex prevUnreadFeedIndex( const QModelIndex& idx, bool allowPassed = false )
{
    QModelIndex prev = allowPassed ? idx : prevIndex( idx );
    while ( prev.isValid() && ( prev.data( SubscriptionListModel::IsAggregationRole ).toBool() || prev.sibling( prev.row(), SubscriptionListModel::UnreadCountColumn ).data().toInt() == 0 ) )
        prev = prevIndex( prev );
    return prev;
}

QModelIndex lastLeaveChild( const QAbstractItemModel* const model )
{
    assert( model );
    if ( model->rowCount() == 0 )
        return QModelIndex();
    QModelIndex idx = model->index( model->rowCount() - 1, 0 );
    while ( model->hasChildren( idx ) )
        idx = idx.child( model->rowCount( idx ) - 1, idx.column() );
    return idx;
}

QModelIndex nextIndex( const QModelIndex& idx )
{
    if ( !idx.isValid() )
        return QModelIndex();
    const QAbstractItemModel* const model = idx.model();
    assert( model );
    if ( model->hasChildren( idx ) )
        return idx.child( 0, idx.column() );
    QModelIndex i = idx;
    while ( true )
    {
        if ( !i.isValid() )
            return i;
        const int siblings = model->rowCount( i.parent() );
        if ( i.row() + 1 < siblings )
            return i.sibling( i.row() + 1, i.column() );
        i = i.parent();
    }
}

QModelIndex nextFeedIndex( const QModelIndex& idx )
{
    QModelIndex next = nextIndex( idx );
    while ( next.isValid() && next.data( SubscriptionListModel::IsAggregationRole ).toBool() )
        next = nextIndex( next );
    return next;
}

QModelIndex nextUnreadFeedIndex( const QModelIndex& idx )
{
    QModelIndex next = nextIndex( idx );
    while ( next.isValid() && ( next.data( SubscriptionListModel::IsAggregationRole ).toBool() || next.sibling( next.row(), SubscriptionListModel::UnreadCountColumn ).data().toInt() == 0 ) )
        next = nextIndex( next );
    return next;
}

}

Akregator::SubscriptionListView::SubscriptionListView( QWidget* parent ) : QTreeView( parent )
{
    setFocusPolicy( Qt::NoFocus );
    setSelectionMode( QAbstractItemView::SingleSelection );
    setRootIsDecorated( false );
    setAlternatingRowColors( true );
    setContextMenuPolicy( Qt::CustomContextMenu );
    setDragDropMode( QAbstractItemView::DragDrop );
    setDropIndicatorShown( true );
    setAcceptDrops( true );
    setUniformRowHeights( true );
    setItemDelegate( new SubscriptionListDelegate( this ) );
    connect( header(), SIGNAL( customContextMenuRequested( const QPoint & ) ), this, SLOT( showHeaderMenu( const QPoint& ) ) );

    loadHeaderSettings();
}

Akregator::SubscriptionListView::~SubscriptionListView()
{
    saveHeaderSettings();
}

void Akregator::SubscriptionListView::setModel( QAbstractItemModel* m )
{
    if ( model() )
        m_headerState = header()->saveState();

    QTreeView::setModel( m );

    if ( m )
        header()->restoreState( m_headerState );

    QStack<QModelIndex> stack;
    stack.push( rootIndex() );
    while ( !stack.isEmpty() )
    {
        const QModelIndex i = stack.pop();
        const int childCount = m->rowCount( i );
        for ( int j = 0; j < childCount; ++j )
        {
            const QModelIndex child = m->index( j, 0, i );
            if ( child.isValid() )
                stack.push( child );
        }
        setExpanded( i, i.data( Akregator::SubscriptionListModel::IsOpenRole ).toBool() );
    }

    header()->setContextMenuPolicy( Qt::CustomContextMenu );
}

void Akregator::SubscriptionListView::showHeaderMenu( const QPoint& pos )
{
    if( ! model() )
        return;

    QPointer<KMenu> menu = new KMenu( this );
    menu->addTitle( i18n( "Columns" ) );
    menu->setAttribute( Qt::WA_DeleteOnClose );
    connect(menu, SIGNAL( triggered( QAction* ) ), this, SLOT( headerMenuItemTriggered( QAction* ) ) );

    for (int i = 0; i < model()->columnCount(); i++)
    {
        QString col = model()->headerData( i, Qt::Horizontal, Qt::DisplayRole ).toString();
        QAction* act = menu->addAction( col );
        act->setCheckable( true );
        act->setChecked( !header()->isSectionHidden( i ) );
        act->setData( i );
    }

    menu->popup( header()->mapToGlobal( pos ) );
}

void Akregator::SubscriptionListView::headerMenuItemTriggered( QAction* act )
{
    assert( act );
    const int col = act->data().toInt();
    if ( act->isChecked() )
        header()->showSection( col );
    else
        header()->hideSection( col );
}

void Akregator::SubscriptionListView::saveHeaderSettings()
{
    if ( model() )
        m_headerState = header()->saveState();
    KConfigGroup conf( Settings::self()->config(), "General" );
    conf.writeEntry( "SubscriptionListHeaders", m_headerState.toBase64() );
}

void Akregator::SubscriptionListView::loadHeaderSettings()
{
    const KConfigGroup conf( Settings::self()->config(), "General" );
    m_headerState = QByteArray::fromBase64( conf.readEntry( "SubscriptionListHeaders" ).toAscii() );
    header()->restoreState( m_headerState );		// needed, even with Qt 4.5
}

void Akregator::SubscriptionListView::slotPrevFeed()
{
    if ( !model() )
        return;
    const QModelIndex current = currentIndex();
    QModelIndex prev = prevFeedIndex( current );
    if ( !prev.isValid() )
    {
        prev = prevFeedIndex( lastLeaveChild( model() ), true );
    }
    if ( prev.isValid() )
        setCurrentIndex( prev );

}

void Akregator::SubscriptionListView::slotNextFeed()
{
    if ( !model() )
        return;
    emit userActionTakingPlace();
    const QModelIndex current = currentIndex();
    QModelIndex next = nextFeedIndex( current );
    if ( !next.isValid() )
        next = nextFeedIndex( model()->index( 0, 0 ) );
    if ( next.isValid() )
        setCurrentIndex( next );
}

void Akregator::SubscriptionListView::slotPrevUnreadFeed()
{
    if ( !model() )
        return;
    emit userActionTakingPlace();
    const QModelIndex current = currentIndex();
    QModelIndex prev = prevUnreadFeedIndex( current );
    if ( !prev.isValid() )
        prev = prevUnreadFeedIndex( lastLeaveChild( model() ), true );
    if ( prev.isValid() )
        setCurrentIndex( prev );
}

void Akregator::SubscriptionListView::slotNextUnreadFeed()
{
    if ( !model() )
        return;
    emit userActionTakingPlace();
    const QModelIndex current = currentIndex();
    QModelIndex next = nextUnreadFeedIndex( current );
    if ( !next.isValid() )
        next = nextUnreadFeedIndex( model()->index( 0, 0 ) );
    if ( next.isValid() )
        setCurrentIndex( next );
}

void SubscriptionListView::slotItemBegin()
{

}

void SubscriptionListView::slotItemEnd()
{
}

void SubscriptionListView::slotItemLeft()
{

}

void SubscriptionListView::slotItemRight()
{

}

void SubscriptionListView::slotItemUp()
{

}

void SubscriptionListView::slotItemDown()
{

}

void Akregator::SubscriptionListView::ensureNodeVisible( Akregator::TreeNode* )
{
}

void Akregator::SubscriptionListView::startNodeRenaming( Akregator::TreeNode* node )
{
    Q_UNUSED( node );
    const QModelIndex current = currentIndex();
    if ( !current.isValid() )
        return;
    edit( current );
}

#include "subscriptionlistview.moc"
<commit_msg>bring back keyboard navigation for the feed list (up, down, left, right, top, bottom)<commit_after>/*
    This file is part of Akregator.

    Copyright (C) 2007 Frank Osterfeld <frank.osterfeld@kdemail.net>

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

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

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "subscriptionlistview.h"
#include "subscriptionlistmodel.h"
#include "subscriptionlistdelegate.h"
#include "akregatorconfig.h"

#include <QHeaderView>
#include <QStack>
#include <QPointer>

#include <KMenu>
#include <KLocale>
#include <KDebug>
#include <KConfigGroup>

#include <cassert>

using namespace Akregator;

static QModelIndex prevIndex( const QModelIndex& idx )
{
    if ( !idx.isValid() )
        return QModelIndex();
    const QAbstractItemModel* const model = idx.model();
    assert( model );

    if ( idx.row() > 0 )
    {
        QModelIndex i = idx.sibling( idx.row() - 1, idx.column() );
        while ( model->hasChildren( i ) )
            i = i.child( model->rowCount( i ) - 1, i.column() );
        return i;
    }
    else
        return idx.parent();
}

static QModelIndex prevFeedIndex( const QModelIndex& idx, bool allowPassed = false )
{
    QModelIndex prev = allowPassed ? idx : prevIndex( idx );
    while ( prev.isValid() && prev.data( SubscriptionListModel::IsAggregationRole ).toBool() )
        prev = prevIndex( prev );
    return prev;
}

static QModelIndex prevUnreadFeedIndex( const QModelIndex& idx, bool allowPassed = false )
{
    QModelIndex prev = allowPassed ? idx : prevIndex( idx );
    while ( prev.isValid() && ( prev.data( SubscriptionListModel::IsAggregationRole ).toBool() || prev.sibling( prev.row(), SubscriptionListModel::UnreadCountColumn ).data().toInt() == 0 ) )
        prev = prevIndex( prev );
    return prev;
}

static QModelIndex lastLeaveChild( const QAbstractItemModel* const model )
{
    assert( model );
    if ( model->rowCount() == 0 )
        return QModelIndex();
    QModelIndex idx = model->index( model->rowCount() - 1, 0 );
    while ( model->hasChildren( idx ) )
        idx = idx.child( model->rowCount( idx ) - 1, idx.column() );
    return idx;
}

static QModelIndex nextIndex( const QModelIndex& idx )
{
    if ( !idx.isValid() )
        return QModelIndex();
    const QAbstractItemModel* const model = idx.model();
    assert( model );
    if ( model->hasChildren( idx ) )
        return idx.child( 0, idx.column() );
    QModelIndex i = idx;
    while ( true )
    {
        if ( !i.isValid() )
            return i;
        const int siblings = model->rowCount( i.parent() );
        if ( i.row() + 1 < siblings )
            return i.sibling( i.row() + 1, i.column() );
        i = i.parent();
    }
}

static QModelIndex nextFeedIndex( const QModelIndex& idx )
{
    QModelIndex next = nextIndex( idx );
    while ( next.isValid() && next.data( SubscriptionListModel::IsAggregationRole ).toBool() )
        next = nextIndex( next );
    return next;
}

static QModelIndex nextUnreadFeedIndex( const QModelIndex& idx )
{
    QModelIndex next = nextIndex( idx );
    while ( next.isValid() && ( next.data( SubscriptionListModel::IsAggregationRole ).toBool() || next.sibling( next.row(), SubscriptionListModel::UnreadCountColumn ).data().toInt() == 0 ) )
        next = nextIndex( next );
    return next;
}

Akregator::SubscriptionListView::SubscriptionListView( QWidget* parent ) : QTreeView( parent )
{
    setFocusPolicy( Qt::NoFocus );
    setSelectionMode( QAbstractItemView::SingleSelection );
    setRootIsDecorated( false );
    setAlternatingRowColors( true );
    setContextMenuPolicy( Qt::CustomContextMenu );
    setDragDropMode( QAbstractItemView::DragDrop );
    setDropIndicatorShown( true );
    setAcceptDrops( true );
    setUniformRowHeights( true );
    setItemDelegate( new SubscriptionListDelegate( this ) );
    connect( header(), SIGNAL( customContextMenuRequested( const QPoint & ) ), this, SLOT( showHeaderMenu( const QPoint& ) ) );

    loadHeaderSettings();
}

Akregator::SubscriptionListView::~SubscriptionListView()
{
    saveHeaderSettings();
}

void Akregator::SubscriptionListView::setModel( QAbstractItemModel* m )
{
    if ( model() )
        m_headerState = header()->saveState();

    QTreeView::setModel( m );

    if ( m )
        header()->restoreState( m_headerState );

    QStack<QModelIndex> stack;
    stack.push( rootIndex() );
    while ( !stack.isEmpty() )
    {
        const QModelIndex i = stack.pop();
        const int childCount = m->rowCount( i );
        for ( int j = 0; j < childCount; ++j )
        {
            const QModelIndex child = m->index( j, 0, i );
            if ( child.isValid() )
                stack.push( child );
        }
        setExpanded( i, i.data( Akregator::SubscriptionListModel::IsOpenRole ).toBool() );
    }

    header()->setContextMenuPolicy( Qt::CustomContextMenu );
}

void Akregator::SubscriptionListView::showHeaderMenu( const QPoint& pos )
{
    if( ! model() )
        return;

    QPointer<KMenu> menu = new KMenu( this );
    menu->addTitle( i18n( "Columns" ) );
    menu->setAttribute( Qt::WA_DeleteOnClose );
    connect(menu, SIGNAL( triggered( QAction* ) ), this, SLOT( headerMenuItemTriggered( QAction* ) ) );

    for (int i = 0; i < model()->columnCount(); i++)
    {
        QString col = model()->headerData( i, Qt::Horizontal, Qt::DisplayRole ).toString();
        QAction* act = menu->addAction( col );
        act->setCheckable( true );
        act->setChecked( !header()->isSectionHidden( i ) );
        act->setData( i );
    }

    menu->popup( header()->mapToGlobal( pos ) );
}

void Akregator::SubscriptionListView::headerMenuItemTriggered( QAction* act )
{
    assert( act );
    const int col = act->data().toInt();
    if ( act->isChecked() )
        header()->showSection( col );
    else
        header()->hideSection( col );
}

void Akregator::SubscriptionListView::saveHeaderSettings()
{
    if ( model() )
        m_headerState = header()->saveState();
    KConfigGroup conf( Settings::self()->config(), "General" );
    conf.writeEntry( "SubscriptionListHeaders", m_headerState.toBase64() );
}

void Akregator::SubscriptionListView::loadHeaderSettings()
{
    const KConfigGroup conf( Settings::self()->config(), "General" );
    m_headerState = QByteArray::fromBase64( conf.readEntry( "SubscriptionListHeaders" ).toAscii() );
    header()->restoreState( m_headerState );		// needed, even with Qt 4.5
}

void Akregator::SubscriptionListView::slotPrevFeed()
{
    if ( !model() )
        return;
    const QModelIndex current = currentIndex();
    QModelIndex prev = prevFeedIndex( current );
    if ( !prev.isValid() )
    {
        prev = prevFeedIndex( lastLeaveChild( model() ), true );
    }
    if ( prev.isValid() )
        setCurrentIndex( prev );

}

void Akregator::SubscriptionListView::slotNextFeed()
{
    if ( !model() )
        return;
    emit userActionTakingPlace();
    const QModelIndex current = currentIndex();
    QModelIndex next = nextFeedIndex( current );
    if ( !next.isValid() )
        next = nextFeedIndex( model()->index( 0, 0 ) );
    if ( next.isValid() )
        setCurrentIndex( next );
}

void Akregator::SubscriptionListView::slotPrevUnreadFeed()
{
    if ( !model() )
        return;
    emit userActionTakingPlace();
    const QModelIndex current = currentIndex();
    QModelIndex prev = prevUnreadFeedIndex( current );
    if ( !prev.isValid() )
        prev = prevUnreadFeedIndex( lastLeaveChild( model() ), true );
    if ( prev.isValid() )
        setCurrentIndex( prev );
}

void Akregator::SubscriptionListView::slotNextUnreadFeed()
{
    if ( !model() )
        return;
    emit userActionTakingPlace();
    const QModelIndex current = currentIndex();
    QModelIndex next = nextUnreadFeedIndex( current );
    if ( !next.isValid() )
        next = nextUnreadFeedIndex( model()->index( 0, 0 ) );
    if ( next.isValid() )
        setCurrentIndex( next );
}

void SubscriptionListView::slotItemBegin()
{
    if ( !model() )
        return;
    emit userActionTakingPlace();
    setCurrentIndex( nextFeedIndex( model()->index( 0, 0 ) ) );
}

void SubscriptionListView::slotItemEnd()
{
    if ( !model() )
        return;
    emit userActionTakingPlace();
    setCurrentIndex( lastLeaveChild( model() ) );
}

void SubscriptionListView::slotItemLeft()
{
    if ( !model() )
        return;
    emit userActionTakingPlace();
    const QModelIndex current = currentIndex();
    if ( !current.isValid() ) {
        setCurrentIndex( nextFeedIndex( model()->index( 0, 0 ) ) );
        return;
    }
    if ( current.parent().isValid() )
        setCurrentIndex( current.parent() );
}

void SubscriptionListView::slotItemRight()
{
    if ( !model() )
        return;
    emit userActionTakingPlace();
    const QModelIndex current = currentIndex();
    if ( !current.isValid() ) {
        setCurrentIndex( nextFeedIndex( model()->index( 0, 0 ) ) );
        return;
    }
    if ( model()->rowCount( current ) > 0 )
        setCurrentIndex( current.child( 0, 0 ) );
}

void SubscriptionListView::slotItemUp()
{
    if ( !model() )
        return;
    emit userActionTakingPlace();
    const QModelIndex current = currentIndex();
    QModelIndex prev = current.row() > 0 ? current.sibling( current.row() - 1, current.column() ) : current.parent();
    if ( !prev.isValid() )
        prev = lastLeaveChild( model() );
    if ( prev.isValid() )
        setCurrentIndex( prev );
}

void SubscriptionListView::slotItemDown()
{
    if ( !model() )
        return;
    emit userActionTakingPlace();
    const QModelIndex current = currentIndex();
    if ( current.row() >= model()->rowCount( current.parent() ) )
        return;
    setCurrentIndex( current.sibling( current.row() + 1, current.column() ) );
}

void Akregator::SubscriptionListView::ensureNodeVisible( Akregator::TreeNode* )
{
}

void Akregator::SubscriptionListView::startNodeRenaming( Akregator::TreeNode* node )
{
    Q_UNUSED( node );
    const QModelIndex current = currentIndex();
    if ( !current.isValid() )
        return;
    edit( current );
}

#include "subscriptionlistview.moc"
<|endoftext|>


<commit_before>//
// Created by cheyulin on 8/4/16.
//

#include <functional>
#include <iostream>

using namespace std;

struct MyClass {
    void PrintHello() {
        //function_object() is ret_function, then we call ret_function()
        cout << "Ret:" << function_object()(1) << endl;
        //Directly call function_object2
        function_object2();
        function_object3();
    }

    //function_object hold ret_function, whole type is function<void(void)> object
    //functional programming:
    function<int(int)> function_object() {
        function<int(int)> ret_function;
        ret_function = [](int integer) -> int {
            cout << "Hello World:" << integer << endl;
            return -1;
        };
        return ret_function;
    }

    function<void()> function_object2 = []() {
        cout << "Hello World 2" << endl;
    };

    function<void()> function_object3() {
        cout << "Hello World 3" << endl;
        return [] {};
    }
};

int main() {
    MyClass().PrintHello();
    function<void(void)> function_object4 = []() {
        cout << "Hello World 4" << endl;
    };
    function_object4();
}<commit_msg>add more examples<commit_after>//
// Created by cheyulin on 8/4/16.
//

#include <functional>
#include <iostream>

using namespace std;

struct MyClass {
    void PrintHello() {
        //function_object() is ret_function, then we call ret_function()
        cout << "Ret:" << function_object()(111) << endl;
        cout << "Ret:" << function_object0(2.0)(222)<<endl;
        //Directly call function_object2
        function_object2();
        function_object3();
    }

    //function_object hold ret_function, whole type is function<void(void)> object
    //functional programming:
    function<int(int)> function_object() {
        function<int(int)> ret_function;
        ret_function = [](int integer) -> int {
            cout << "Hello World:" << integer << endl;
            return -1;
        };
        return ret_function;
    }

    function<int(int)> function_object0(float my_float) {
        cout << "function_object0, my float:" << my_float << endl;
        function<int(int)> ret_function;
        ret_function = [](int integer) -> int {
            cout << "Hello World:" << integer << endl;
            return -2;
        };
        return ret_function;
    }

    function<void()> function_object2 = []() {
        cout << "Hello World 2" << endl;
    };

    function<void()> function_object3() {
        cout << "Hello World 3" << endl;
        return [] {};
    }
};

int main() {
    MyClass().PrintHello();
    function<void(void)> function_object4 = []() {
        cout << "Hello World 4" << endl;
    };
    function_object4();
}<|endoftext|>


<commit_before>//
// XYO Build
//
// Copyright (c) 2014 Grigore Stefan, <g_stefan@yahoo.com>
// Created by Grigore Stefan <g_stefan@yahoo.com>
//
// The MIT License (MIT) <http://opensource.org/licenses/MIT>
//

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

#ifdef XYO_OS_TYPE_WIN
#include <windows.h>
#endif

#ifdef XYO_OS_TYPE_WIN
#ifdef XYO_MEMORY_LEAK_DETECTOR
#include "vld.h"
#endif
#endif

#include "libquantum-script.hpp"

#include "xyo-build-licence.hpp"
#include "xyo-build-copyright.hpp"
#ifndef XYO_BUILD_NO_VERSION
#include "xyo-build-version.hpp"
#endif

//#define QUANTUM_SCRIPT_VM_DEBUG_RUNTIME

using namespace XYO;
using namespace XYO::XY;
using namespace XYO::XO;
using namespace Quantum::Script;

bool isError;

QUANTUM_SCRIPT_INSTRUCTION_DEFINE(Build_isError);

QUANTUM_SCRIPT_INSTRUCTION_IMPLEMENT(Build_isError) {
#ifdef QUANTUM_SCRIPT_DEBUG_RUNTIME
	printf("#%p    build-is-error\n", context->currentProgramCounter);
#endif

	TPointer<Variable> operand1;
	operand1 = context->getArgument(0);
	if (operand1) {
		isError=Process::toBoolean(operand1);
	};
	return;
};

class Application :
	public virtual IMain {
		XYO_XY_DEFINE_PRIVATE_COPY(Application);
	protected:

		static bool initExecutive(Executive *);

		void showUsage();
		void showLicence();

	public:

		inline Application() {
		};

		int main(int cmdN, char *cmdS[]);

};

bool Application::initExecutive(Executive *executive) {
	//executive->configPrintStackTraceLimit=1;
	if (executive->compileString(
		    "\n"
		    "function With(this_,proc_){\n"
		    "\tproc_.call(this_);\n"
		    "};\n"
		    "function ForEach(what_,proc_,this_){\n"
		    "\tfor(var key in what_){\n"
		    "\t\tproc_.call(this_,key,what_[key]);\n"
		    "\t};\n"
		    "};\n"
	    ) != 0) {
		return false;
	};
	if (executive->compileString("Script.include(\"xyo-build.include/shell.js\");") != 0) {
		return false;
	};
	if (executive->compileString("var Build={};") != 0) {
		return false;
	};
	if (!executive->setVmFunction("Build.isError(flag)", InstructionBuild_isError, NULL)) {
		return false;
	};

	return true;
};

void Application::showUsage() {
#ifdef XYO_BUILD_NO_VERSION
	printf("XYO Build\n");
#else
	printf("XYO Build - version %s build %s [%s]\n", XYO::Build::Version::getVersion(), XYO::Build::Version::getBuild(), XYO::Build::Version::getDatetime());
#endif
	printf("%s\n\n", XYO::Build::Copyright::fullCopyright());

	printf("%s\n",
	       "options:\n"
	       "    --licence           show licence\n"
	       "    --help              this help\n"
	       "    --script script.js  execute script file [default is workspace.xyo-build.js]\n"
	      );
};

void Application::showLicence() {
	printf("%s", XYO::Build::Licence::content());
};

int Application::main(int cmdN, char *cmdS[]) {
	int i;
	char *opt;
	const char *script_;

	for (i = 1; i < cmdN; ++i) {
		if (strncmp(cmdS[i], "--", 2) == 0) {
			opt = &cmdS[i][2];
			if (strcmp(opt, "help") == 0) {
				showUsage();
				return 0;
			};
			if (strcmp(opt, "licence") == 0) {
				showLicence();
				if (cmdN == 2) {
					return 0;
				};
			};
			continue;
		};
	};

	script_ = "workspace.xyo-build.js";

	for (i = 1; i < cmdN; ++i) {
		if (i == 1) {
			if (strlen(cmdS[i]) >= 3) {
				if (strcmp(&cmdS[i][strlen(cmdS[i]) - 3], ".js") == 0) {
					if (strncmp(cmdS[i], "--", 2) != 0) {
						script_ = cmdS[i];
						continue;
					};
				};
			};
		};
		if (strcmp(cmdS[i], "--script") == 0) {
			++i;
			if (i < cmdN) {
				script_ = cmdS[i];
			};
			continue;
		};
	};

	String scriptConfig=(ExecutiveX::getExecutive()).pathExecutable;
	scriptConfig<<"/xyo-build.config.js";
	scriptConfig=StringX::replace(scriptConfig,"\\","/");

	String script;
	script << "\n"
	       "function BuildError(message){\n"
	       "\tthis.message=message;\n"
	       "\tthis.name=\"Build\";\n"
	       "};\n"
	       "BuildError.prototype=new Error();\n"
	       "function ___main(){\n"
	       "\tScript.include(\"xyo-build.include/build.js\");\n"
	       "\tif(Shell.fileExists(\""<<scriptConfig<<"\")){\n"
	       "\t\tScript.include(\""<<scriptConfig<<"\");\n"
	       "\t};\n"
	       "\tScript.include(\"xyo-build.include/make.js\");\n"
	       "\tScript.include(\"xyo-build.include/project.js\");\n"
	       "\tScript.include(\"xyo-build.include/solution.js\");\n"
	       "\tScript.include(\"xyo-build.include/platform.js\");\n"
	       "\tBuild.parseCommandLine();\n"
	       "\tif(Build.cmdMode()){\n"
	       "\t}else{\n"
	       "\t\tBuild.includeScript(\"" << script_ << "\");\n"
	       "\t\tPlatform.build(Build.mode_);\n"
	       "\t};\n"
	       "};\n"
	       "function ___exec(){\n"
	       "\ttry{\n"
	       "\t\t___main();\n"
	       "\t}catch(e){\n"
	       "\t\tBuild.isError(true);\n"
	       "\t\tConsole.writeLn(e.toString());\n"
	       "\t\tif(e instanceof BuildError){}else{\n"
	       "\t\t\tConsole.write(e.stackTrace);\n"
	       "\t\t};\n"
	       "\t};\n"
	       "};\n"
	       "___exec();\n";

	if(ExecutiveX::initExecutive(cmdN,cmdS,initExecutive)) {
		if(ExecutiveX::executeString(script)) {
			ExecutiveX::executeEnd();
			return 0;
		};
	};

	fflush(stdout);
	printf("%s\n",(ExecutiveX::getError()).value());
	printf("%s",(ExecutiveX::getStackTrace()).value());
	fflush(stdout);
	ExecutiveX::executeEnd();
	return -1;
};

XYO_XY_MAIN_STD(Application);

#ifdef QUANTUM_SCRIPT_AMALGAM
#include "quantum-script-amalgam.cpp"
#endif

<commit_msg>update<commit_after>//
// XYO Build
//
// Copyright (c) 2014 Grigore Stefan, <g_stefan@yahoo.com>
// Created by Grigore Stefan <g_stefan@yahoo.com>
//
// The MIT License (MIT) <http://opensource.org/licenses/MIT>
//

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

#ifdef XYO_OS_TYPE_WIN
#include <windows.h>
#endif

#ifdef XYO_OS_TYPE_WIN
#ifdef XYO_MEMORY_LEAK_DETECTOR
#include "vld.h"
#endif
#endif

#include "libquantum-script.hpp"

#include "xyo-build-licence.hpp"
#include "xyo-build-copyright.hpp"
#ifndef XYO_BUILD_NO_VERSION
#include "xyo-build-version.hpp"
#endif

//#define QUANTUM_SCRIPT_VM_DEBUG_RUNTIME

using namespace XYO;
using namespace XYO::XY;
using namespace XYO::XO;
using namespace Quantum::Script;

bool isError;

QUANTUM_SCRIPT_INSTRUCTION_DEFINE(Build_isError);

QUANTUM_SCRIPT_INSTRUCTION_IMPLEMENT(Build_isError) {
#ifdef QUANTUM_SCRIPT_DEBUG_RUNTIME
	printf("#%p    build-is-error\n", context->currentProgramCounter);
#endif

	TPointer<Variable> operand1;
	operand1 = context->getArgument(0);
	if (operand1) {
		isError=operand1->toBoolean();
	};
	return;
};

class Application :
	public virtual IMain {
		XYO_XY_DEFINE_PRIVATE_COPY(Application);
	protected:

		static bool initExecutive(Executive *);

		void showUsage();
		void showLicence();

	public:

		inline Application() {
		};

		int main(int cmdN, char *cmdS[]);

};

bool Application::initExecutive(Executive *executive) {
	//executive->configPrintStackTraceLimit=1;
	if (executive->compileString(
		    "\n"
		    "function With(this_,proc_){\n"
		    "\tproc_.call(this_);\n"
		    "};\n"
		    "function ForEach(what_,proc_,this_){\n"
		    "\tfor(var key in what_){\n"
		    "\t\tproc_.call(this_,key,what_[key]);\n"
		    "\t};\n"
		    "};\n"
	    ) != 0) {
		return false;
	};
	if (executive->compileString("Script.include(\"xyo-build.include/shell.js\");") != 0) {
		return false;
	};
	if (executive->compileString("var Build={};") != 0) {
		return false;
	};
	if (!executive->setVmFunction("Build.isError(flag)", InstructionBuild_isError, NULL)) {
		return false;
	};

	return true;
};

void Application::showUsage() {
#ifdef XYO_BUILD_NO_VERSION
	printf("XYO Build\n");
#else
	printf("XYO Build - version %s build %s [%s]\n", XYO::Build::Version::getVersion(), XYO::Build::Version::getBuild(), XYO::Build::Version::getDatetime());
#endif
	printf("%s\n\n", XYO::Build::Copyright::fullCopyright());

	printf("%s\n",
	       "options:\n"
	       "    --licence           show licence\n"
	       "    --help              this help\n"
	       "    --script script.js  execute script file [default is workspace.xyo-build.js]\n"
	      );
};

void Application::showLicence() {
	printf("%s", XYO::Build::Licence::content());
};

int Application::main(int cmdN, char *cmdS[]) {
	int i;
	char *opt;
	const char *script_;

	for (i = 1; i < cmdN; ++i) {
		if (strncmp(cmdS[i], "--", 2) == 0) {
			opt = &cmdS[i][2];
			if (strcmp(opt, "help") == 0) {
				showUsage();
				return 0;
			};
			if (strcmp(opt, "licence") == 0) {
				showLicence();
				if (cmdN == 2) {
					return 0;
				};
			};
			continue;
		};
	};

	script_ = "workspace.xyo-build.js";

	for (i = 1; i < cmdN; ++i) {
		if (i == 1) {
			if (strlen(cmdS[i]) >= 3) {
				if (strcmp(&cmdS[i][strlen(cmdS[i]) - 3], ".js") == 0) {
					if (strncmp(cmdS[i], "--", 2) != 0) {
						script_ = cmdS[i];
						continue;
					};
				};
			};
		};
		if (strcmp(cmdS[i], "--script") == 0) {
			++i;
			if (i < cmdN) {
				script_ = cmdS[i];
			};
			continue;
		};
	};

	String scriptConfig=(ExecutiveX::getExecutive()).pathExecutable;
	scriptConfig<<"/xyo-build.config.js";
	scriptConfig=StringX::replace(scriptConfig,"\\","/");

	String script;
	script << "\n"
	       "function BuildError(message){\n"
	       "\tthis.message=message;\n"
	       "\tthis.name=\"Build\";\n"
	       "};\n"
	       "BuildError.prototype=new Error();\n"
	       "function ___main(){\n"
	       "\tScript.include(\"xyo-build.include/build.js\");\n"
	       "\tif(Shell.fileExists(\""<<scriptConfig<<"\")){\n"
	       "\t\tScript.include(\""<<scriptConfig<<"\");\n"
	       "\t};\n"
	       "\tScript.include(\"xyo-build.include/make.js\");\n"
	       "\tScript.include(\"xyo-build.include/project.js\");\n"
	       "\tScript.include(\"xyo-build.include/solution.js\");\n"
	       "\tScript.include(\"xyo-build.include/platform.js\");\n"
	       "\tBuild.parseCommandLine();\n"
	       "\tif(Build.cmdMode()){\n"
	       "\t}else{\n"
	       "\t\tBuild.includeScript(\"" << script_ << "\");\n"
	       "\t\tPlatform.build(Build.mode_);\n"
	       "\t};\n"
	       "};\n"
	       "function ___exec(){\n"
	       "\ttry{\n"
	       "\t\t___main();\n"
	       "\t}catch(e){\n"
	       "\t\tBuild.isError(true);\n"
	       "\t\tConsole.writeLn(e.toString());\n"
	       "\t\tif(e instanceof BuildError){}else{\n"
	       "\t\t\tConsole.write(e.stackTrace);\n"
	       "\t\t};\n"
	       "\t};\n"
	       "};\n"
	       "___exec();\n";

	if(ExecutiveX::initExecutive(cmdN,cmdS,initExecutive)) {
		if(ExecutiveX::executeString(script)) {
			ExecutiveX::executeEnd();
			return 0;
		};
	};

	fflush(stdout);
	printf("%s\n",(ExecutiveX::getError()).value());
	printf("%s",(ExecutiveX::getStackTrace()).value());
	fflush(stdout);
	ExecutiveX::executeEnd();
	return -1;
};

XYO_XY_MAIN_STD(Application);

#ifdef QUANTUM_SCRIPT_AMALGAM
#include "quantum-script-amalgam.cpp"
#endif

<|endoftext|>


<commit_before>/**
 * Copyright (c) 2011-2015 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef LIBBITCOIN_NETWORK_CONNECTIONS_HPP
#define LIBBITCOIN_NETWORK_CONNECTIONS_HPP

#include <atomic>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <string>
#include <vector>
#include <bitcoin/bitcoin.hpp>
#include <bitcoin/network/channel.hpp>
#include <bitcoin/network/define.hpp>
#include <bitcoin/bitcoin/message/address.hpp>

namespace libbitcoin {
namespace network {

/// Pool of active connections, thread and lock safe.
class BCT_API connections
  : public enable_shared_from_base<connections>
{
public:
    typedef std::shared_ptr<connections> ptr;
    typedef std::function<void(bool)> truth_handler;
    typedef std::function<void(size_t)> count_handler;
    typedef std::function<void(const code&)> result_handler;
    typedef std::function<void(const code&, channel::ptr)> channel_handler;

    /// Construct an instance.
    connections();

    /// Validate connections stopped.
    ~connections();

    /// This class is not copyable.
    connections(const connections&) = delete;
    void operator=(const connections&) = delete;

    /// Send a message to all channels, with completion handlers.
    /// Complete always returns success, use channel handler for failure codes.
    template <typename Message>
    void broadcast(const Message& message, channel_handler handle_channel,
        result_handler handle_complete)
    {
        // We cannot use a synchronizer here because handler closure in loop.
        auto counter = std::make_shared<std::atomic<size_t>>(channels_.size());

        for (const auto channel: safe_copy())
        {
            const auto handle_send = [=](code ec)
            {
                handle_channel(ec, channel);

                if (counter->fetch_sub(1) == 1)
                    handle_complete(error::success);
            };

            // No pre-serialize, channels may have different protocol versions.
            channel->send(message, handle_send);
        }
    }

    /// Subscribe to all incoming messages of a type.
    template <class Message>
    void subscribe(message_handler<Message>&& handler)
    {
        for (const auto channel: safe_copy())
            channel->subscribe(
                std::forward<message_handler<Message>>(handler));
    }

    virtual void stop(const code& ec);
    virtual void count(count_handler handler) const;
    virtual void store(channel::ptr channel, result_handler handler);
    virtual void remove(channel::ptr channel, result_handler handler);
    virtual void exists(const config::authority& authority,
        truth_handler handler) const;
    config::authority::list authority_list();

private:
    typedef std::vector<channel::ptr> list;

    list safe_copy() const;
    size_t safe_count() const;
    code safe_store(channel::ptr channel);
    bool safe_remove(channel::ptr channel);
    bool safe_exists(const config::authority& address) const;

    list channels_;
    std::atomic<bool> stopped_;
    mutable upgrade_mutex mutex_;
};

} // namespace network
} // namespace libbitcoin

#endif
<commit_msg>fix nullptr handler<commit_after>/**
 * Copyright (c) 2011-2015 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef LIBBITCOIN_NETWORK_CONNECTIONS_HPP
#define LIBBITCOIN_NETWORK_CONNECTIONS_HPP

#include <atomic>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <string>
#include <vector>
#include <bitcoin/bitcoin.hpp>
#include <bitcoin/network/channel.hpp>
#include <bitcoin/network/define.hpp>
#include <bitcoin/bitcoin/message/address.hpp>

namespace libbitcoin {
namespace network {

/// Pool of active connections, thread and lock safe.
class BCT_API connections
  : public enable_shared_from_base<connections>
{
public:
    typedef std::shared_ptr<connections> ptr;
    typedef std::function<void(bool)> truth_handler;
    typedef std::function<void(size_t)> count_handler;
    typedef std::function<void(const code&)> result_handler;
    typedef std::function<void(const code&, channel::ptr)> channel_handler;

    /// Construct an instance.
    connections();

    /// Validate connections stopped.
    ~connections();

    /// This class is not copyable.
    connections(const connections&) = delete;
    void operator=(const connections&) = delete;

    /// Send a message to all channels, with completion handlers.
    /// Complete always returns success, use channel handler for failure codes.
    template <typename Message>
    void broadcast(const Message& message, channel_handler handle_channel,
        result_handler handle_complete)
    {
        // We cannot use a synchronizer here because handler closure in loop.
        auto counter = std::make_shared<std::atomic<size_t>>(channels_.size());

        for (const auto channel: safe_copy())
        {
            const auto handle_send = [=](code ec)
            {
                handle_channel(ec, channel);

                if (counter->fetch_sub(1) == 1)
                    handle_complete(error::success);
            };

            // No pre-serialize, channels may have different protocol versions.
            channel->send(message, handle_send);
        }
    }

    /// Subscribe to all incoming messages of a type.
    template <class Message>
    void subscribe(message_handler<Message>&& handler)
    {
        for (const auto channel: safe_copy())
        {
        	auto handler_copy = handler;
        	channel->subscribe(std::move(handler_copy));//by jianglh
//            channel->subscribe(
//                std::forward<message_handler<Message>>(handler));
        }
    }

    virtual void stop(const code& ec);
    virtual void count(count_handler handler) const;
    virtual void store(channel::ptr channel, result_handler handler);
    virtual void remove(channel::ptr channel, result_handler handler);
    virtual void exists(const config::authority& authority,
        truth_handler handler) const;
    config::authority::list authority_list();

private:
    typedef std::vector<channel::ptr> list;

    list safe_copy() const;
    size_t safe_count() const;
    code safe_store(channel::ptr channel);
    bool safe_remove(channel::ptr channel);
    bool safe_exists(const config::authority& address) const;

    list channels_;
    std::atomic<bool> stopped_;
    mutable upgrade_mutex mutex_;
};

} // namespace network
} // namespace libbitcoin

#endif
<|endoftext|>


<commit_before>#include "ToggleButton.h"
#include "Timer.h"
#include "Arduino.h"

const bool ToggleButton::IS_POS_LOGIC = false;
const bool ToggleButton::IS_NEG_LOGIC = true;
const int  ToggleButton::BTN_NC       = -1;
const int  ToggleButton::IND_NC       = -1;

const int  ToggleButton::s_defaultKeyPollTime = 50;

//-----------------------------------------------------------------------------

class MyDebounceTimerAdatper : public TimerAdapter
{
private:
  ToggleButton* m_toggleButton;
  bool m_lastWasButtonPressed;

public:
  MyDebounceTimerAdatper(ToggleButton* toggleButton)
  : m_toggleButton(toggleButton)
  , m_lastWasButtonPressed(false)
  { }

  void timeExpired()
  {
    if (0 != m_toggleButton)
    {
      bool currentIsButtonPressed = m_toggleButton->isButtonPressed();

      if (m_lastWasButtonPressed != currentIsButtonPressed)
      {
        m_lastWasButtonPressed = currentIsButtonPressed;
        if (currentIsButtonPressed)
        {
          m_toggleButton->toggle();
        }
      }
    }
  }
};

//-----------------------------------------------------------------------------

ToggleButton::ToggleButton(int buttonPin, int indicatorPin, bool isButtonNegativeLogic, ToggleButtonAdapter* adapter)
: m_debounceTimer(new Timer(new MyDebounceTimerAdatper(this), Timer::IS_RECURRING, s_defaultKeyPollTime))
, m_adapter(adapter)
, m_isButtonNegativeLogic(isButtonNegativeLogic)
, m_isActive(false)
, m_buttonPin(buttonPin)
, m_indicatorPin(indicatorPin)
{
  if (0 <= m_buttonPin)
  {
    pinMode(m_buttonPin, INPUT);
    digitalWrite(m_buttonPin, m_isButtonNegativeLogic ? HIGH : LOW); // pull
  }
  if (0 <= m_indicatorPin)
  {
    pinMode(m_indicatorPin, OUTPUT);
    digitalWrite(m_indicatorPin, m_isActive);
  }
}

ToggleButton::~ToggleButton()
{
  delete m_debounceTimer->adapter();
  delete m_debounceTimer; m_debounceTimer = 0;
}

ToggleButtonAdapter* ToggleButton::adapter()
{
  return m_adapter;
}

void ToggleButton::attachAdapter(ToggleButtonAdapter* adapter)
{
  m_adapter = adapter;
}

bool ToggleButton::isActive()
{
  return m_isActive;
}

void ToggleButton::setIsActive(bool isActive)
{
  bool changed = (isActive != m_isActive);
  m_isActive = isActive;
  if (0 <= m_indicatorPin)
  {
    digitalWrite(m_indicatorPin, m_isActive);
  }
  if ((0 != m_adapter) && (changed))
  {
    m_adapter->notifyStatusChanged(m_isActive);
  }
}

void ToggleButton::toggle()
{
  m_isActive = !m_isActive;
  digitalWrite(m_indicatorPin, m_isActive);
  if (0 != m_adapter)
  {
    m_adapter->notifyStatusChanged(m_isActive);
  }
}

bool ToggleButton::isButtonPressed()
{
  bool pressed = false;
  if (0 <= m_buttonPin)
  {
    pressed = digitalRead(m_buttonPin);
    pressed = (m_isButtonNegativeLogic ? !pressed : pressed);
  }
  return pressed;
}

<commit_msg>Bug fix: toggle() avoid writing status to pin when not real indicator pin is configured.<commit_after>#include "ToggleButton.h"
#include "Timer.h"
#include "Arduino.h"

const bool ToggleButton::IS_POS_LOGIC = false;
const bool ToggleButton::IS_NEG_LOGIC = true;
const int  ToggleButton::BTN_NC       = -1;
const int  ToggleButton::IND_NC       = -1;

const int  ToggleButton::s_defaultKeyPollTime = 50;

//-----------------------------------------------------------------------------

class MyDebounceTimerAdatper : public TimerAdapter
{
private:
  ToggleButton* m_toggleButton;
  bool m_lastWasButtonPressed;

public:
  MyDebounceTimerAdatper(ToggleButton* toggleButton)
  : m_toggleButton(toggleButton)
  , m_lastWasButtonPressed(false)
  { }

  void timeExpired()
  {
    if (0 != m_toggleButton)
    {
      bool currentIsButtonPressed = m_toggleButton->isButtonPressed();

      if (m_lastWasButtonPressed != currentIsButtonPressed)
      {
        m_lastWasButtonPressed = currentIsButtonPressed;
        if (currentIsButtonPressed)
        {
          m_toggleButton->toggle();
        }
      }
    }
  }
};

//-----------------------------------------------------------------------------

ToggleButton::ToggleButton(int buttonPin, int indicatorPin, bool isButtonNegativeLogic, ToggleButtonAdapter* adapter)
: m_debounceTimer(new Timer(new MyDebounceTimerAdatper(this), Timer::IS_RECURRING, s_defaultKeyPollTime))
, m_adapter(adapter)
, m_isButtonNegativeLogic(isButtonNegativeLogic)
, m_isActive(false)
, m_buttonPin(buttonPin)
, m_indicatorPin(indicatorPin)
{
  if (0 <= m_buttonPin)
  {
    pinMode(m_buttonPin, INPUT);
    digitalWrite(m_buttonPin, m_isButtonNegativeLogic ? HIGH : LOW); // pull
  }
  if (0 <= m_indicatorPin)
  {
    pinMode(m_indicatorPin, OUTPUT);
    digitalWrite(m_indicatorPin, m_isActive);
  }
}

ToggleButton::~ToggleButton()
{
  delete m_debounceTimer->adapter();
  delete m_debounceTimer; m_debounceTimer = 0;
}

ToggleButtonAdapter* ToggleButton::adapter()
{
  return m_adapter;
}

void ToggleButton::attachAdapter(ToggleButtonAdapter* adapter)
{
  m_adapter = adapter;
}

bool ToggleButton::isActive()
{
  return m_isActive;
}

void ToggleButton::setIsActive(bool isActive)
{
  bool changed = (isActive != m_isActive);
  m_isActive = isActive;
  if (0 <= m_indicatorPin)
  {
    digitalWrite(m_indicatorPin, m_isActive);
  }
  if ((0 != m_adapter) && (changed))
  {
    m_adapter->notifyStatusChanged(m_isActive);
  }
}

void ToggleButton::toggle()
{
  m_isActive = !m_isActive;
  if (0 <= m_indicatorPin)
  {
    digitalWrite(m_indicatorPin, m_isActive);
  }
  if (0 != m_adapter)
  {
    m_adapter->notifyStatusChanged(m_isActive);
  }
}

bool ToggleButton::isButtonPressed()
{
  bool pressed = false;
  if (0 <= m_buttonPin)
  {
    pressed = digitalRead(m_buttonPin);
    pressed = (m_isButtonNegativeLogic ? !pressed : pressed);
  }
  return pressed;
}

<|endoftext|>


<commit_before>/*
   Copyright (c) 2009-2013, Jack Poulson
   All rights reserved.

   This file is part of Elemental and is under the BSD 2-Clause License,
   which can be found in the LICENSE file in the root directory, or at
   http://opensource.org/licenses/BSD-2-Clause
*/
#pragma once
#ifndef ELEM_LAPACK_QR_TS_HPP
#define ELEM_LAPACK_QR_TS_HPP

#include "elemental/blas-like/level1/MakeTriangular.hpp"
#include "elemental/lapack-like/ExpandPackedReflectors.hpp"
#include "elemental/lapack-like/QR.hpp"

namespace elem {
namespace qr {
namespace ts {

template<typename F>
struct TreeData
{
    Matrix<F> QR0, t0;
    std::vector<Matrix<F>> QRList;
    std::vector<Matrix<F>> tList;

    TreeData( Int numStages=0 )
    : QRList(numStages), tList(numStages)
    { }

    TreeData( TreeData<F>&& treeData )
    : QR0(std::move(treeData.QR0)),
      t0(std::move(treeData.t0)),
      QRList(std::move(treeData.QRList)),
      tList(std::move(treeData.tList))
    { }

    TreeData<F>& operator=( TreeData<F>&& treeData )
    {
        QR0 = std::move(treeData.QR0);
        t0 = std::move(treeData.t0);
        QRList = std::move(treeData.QRList);
        tList = std::move(treeData.tList);
        return *this;
    }
};

template<typename F,Distribution U>
inline void
Reduce( const DistMatrix<F,U,STAR>& A, TreeData<F>& treeData )
{
#ifndef RELEASE
    CallStackEntry cse("qr::ts::Reduce");
#endif
    const Int m =  A.Height();
    const Int n = A.Width();
    const mpi::Comm colComm = A.ColComm();
    const Int p = mpi::CommSize( colComm );
    if( p == 1 )
        return;
    const Int rank = mpi::CommRank( colComm );
    if( m < p*n )
        LogicError("TSQR currently assumes height >= width*numProcesses");
    if( !PowerOfTwo(p) )
        LogicError("TSQR currently requires power-of-two number of processes");
    const Int logp = Log2(p);
    auto lastZ = LockedView( treeData.QR0, 0, 0, n, n );
    treeData.QRList.resize( logp );
    treeData.tList.resize( logp );

    // Run the binary tree reduction
    Matrix<F> ZTop(n,n,n), ZBot(n,n,n);
    for( Int stage=0; stage<logp; ++stage )
    {
        // Pack, then send and receive n x n matrices
        const Int partner = Unsigned(rank) ^ (Unsigned(1)<<stage);
        const bool top = rank < partner;
        if( top )
        {
            ZTop = lastZ;
            MakeTriangular( UPPER, ZTop );
            mpi::Recv( ZBot.Buffer(), n*n, partner, colComm );
        }
        else
        {
            ZBot = lastZ;
            MakeTriangular( UPPER, ZBot );
            mpi::Send( ZBot.LockedBuffer(), n*n, partner, colComm );
            break;
        }

        auto& Q = treeData.QRList[stage];
        auto& t = treeData.tList[stage];
        Q.ResizeTo( 2*n, n, 2*n );
        t.ResizeTo( n, 1 );
        auto QTop = View( Q, 0, 0, n, n );
        auto QBot = View( Q, n, 0, n, n );
        QTop = ZTop;
        QBot = ZBot;

        // Note that the last QR is not performed by this routine, as many
        // higher-level routines, such as TS-SVT, are simplified if the final
        // small matrix is left alone.
        if( stage < logp-1 )
        {
            // TODO: Exploit double-triangular structure
            QR( Q, t );
            lastZ = LockedView( Q, 0, 0, n, n );
        }
    }
}

template<typename F,Distribution U>
inline Matrix<F>&
RootQR( const DistMatrix<F,U,STAR>& A, TreeData<F>& treeData )
{
    const Int p = mpi::CommSize( A.ColComm() );
    const Int rank = mpi::CommRank( A.ColComm() );
    if( rank != 0 )
        LogicError("This process does not have access to the root QR");
    if( p == 1 )
        return treeData.QR0;
    else
        return treeData.QRList.back();
}

template<typename F,Distribution U>
inline const Matrix<F>&
RootQR( const DistMatrix<F,U,STAR>& A, const TreeData<F>& treeData )
{
    const Int p = mpi::CommSize( A.ColComm() );
    const Int rank = mpi::CommRank( A.ColComm() );
    if( rank != 0 )
        LogicError("This process does not have access to the root QR");
    if( p == 1 )
        return treeData.QR0;
    else
        return treeData.QRList.back();
}

template<typename F,Distribution U>
inline Matrix<F>&
RootPhases( const DistMatrix<F,U,STAR>& A, TreeData<F>& treeData )
{
    const Int p = mpi::CommSize( A.ColComm() );
    const Int rank = mpi::CommRank( A.ColComm() );
    if( rank != 0 )
        LogicError("This process does not have access to the root phases");
    if( p == 1 )
        return treeData.t0;
    else
        return treeData.tList.back();
}

template<typename F,Distribution U>
inline const Matrix<F>&
RootPhases( const DistMatrix<F,U,STAR>& A, const TreeData<F>& treeData )
{
    const Int p = mpi::CommSize( A.ColComm() );
    const Int rank = mpi::CommRank( A.ColComm() );
    if( rank != 0 )
        LogicError("This process does not have access to the root phases");
    if( p == 1 )
        return treeData.t0;
    else
        return treeData.tList.back();
}

template<typename F,Distribution U>
inline void
Scatter( DistMatrix<F,U,STAR>& A, const TreeData<F>& treeData )
{
#ifndef RELEASE
    CallStackEntry cse("qr::ts::Scatter");
#endif
    const Int m =  A.Height();
    const Int n = A.Width();
    const mpi::Comm colComm = A.ColComm();
    const Int p = mpi::CommSize( colComm );
    if( p == 1 )
        return;
    const Int rank = mpi::CommRank( colComm );
    if( m < p*n )
        LogicError("TSQR currently assumes height >= width*numProcesses");
    if( !PowerOfTwo(p) )
        LogicError("TSQR currently requires power-of-two number of processes");
    const Int logp = Log2(p);

    // Run the binary tree scatter
    Matrix<F> Z(2*n,n,2*n), ZHalf(n,n,n);
    if( rank == 0 )
        Z = RootQR( A, treeData );
    auto ZTop = View( Z, 0, 0, n, n );
    auto ZBot = View( Z, n, 0, n, n );
    for( Int revStage=0; revStage<logp; ++revStage )
    {
        const Int stage = (logp-1)-revStage;
        // Skip this stage if the first stage bits of our rank are not zero
        if( stage>0 && (Unsigned(rank) & ((Unsigned(1)<<stage)-1)) )
            continue;

        const Int partner = rank ^ (1u<<stage);
        const bool top = rank < partner;
        if( top )
        {
            if( stage < logp-1 )
            {
                // Multiply by the current Q
                ZTop = ZHalf;
                MakeZeros( ZBot );
                // TODO: Exploit sparsity?
                ApplyQ
                ( LEFT, NORMAL,
                  treeData.QRList[stage], treeData.tList[stage], Z );
            }
            // Send bottom-half to partner and keep top half
            ZHalf = ZBot;
            mpi::Send( ZHalf.LockedBuffer(), n*n, partner, colComm );
            ZHalf = ZTop;
        }
        else
        {
            // Recv top half from partner
            mpi::Recv( ZHalf.Buffer(), n*n, partner, colComm );
        }
    }

    // Apply the initial Q
    MakeZeros( A.Matrix() );
    auto ATop = View( A.Matrix(), 0, 0, n, n );
    ATop = ZHalf;
    // TODO: Exploit sparsity
    ApplyQ( LEFT, NORMAL, treeData.QR0, treeData.t0, A.Matrix() );
}

template<typename F,Distribution U>
inline DistMatrix<F,STAR,STAR>
FormR( const DistMatrix<F,U,STAR>& A, const TreeData<F>& treeData )
{
    const Grid& g = A.Grid();
    DistMatrix<F,CIRC,CIRC> RRoot(g);
    if( A.ColRank() == 0 )
    {
        const Int n = A.Width();
        auto RTop = LockedView( RootQR(A,treeData), 0, 0, n, n );
        RRoot.CopyFromRoot( RTop );
        MakeTriangular( UPPER, RRoot );
    }
    else
        RRoot.CopyFromNonRoot();
    DistMatrix<F,STAR,STAR> R(g);
    R = RRoot;
    return R;
}

// NOTE: This is destructive
template<typename F,Distribution U>
inline void
FormQ( DistMatrix<F,U,STAR>& A, TreeData<F>& treeData )
{
    const Int p = mpi::CommSize( A.ColComm() );
    if( p == 1 )
    {
        A.Matrix() = treeData.QR0;
        ExpandPackedReflectors
        ( LOWER, VERTICAL, UNCONJUGATED, 0,
          A.Matrix(), RootPhases(A,treeData) );
    }
    else
    {
        if( A.ColRank() == 0 )
            ExpandPackedReflectors
            ( LOWER, VERTICAL, UNCONJUGATED, 0,
              RootQR(A,treeData), RootPhases(A,treeData) );
        Scatter( A, treeData );
    }
}

} // namespace ts

template<typename F,Distribution U>
inline ts::TreeData<F>
TS( const DistMatrix<F,U,STAR>& A )
{
    ts::TreeData<F> treeData;
    treeData.QR0 = A.LockedMatrix();
    QR( treeData.QR0, treeData.t0 );

    const Int p = mpi::CommSize( A.ColComm() );
    if( p != 1 )
    {
        ts::Reduce( A, treeData );
        if( A.ColRank() == 0 )
            QR( RootQR(A,treeData), RootPhases(A,treeData) );
    }
    return treeData;
}

template<typename F,Distribution U>
inline void
ExplicitTS( DistMatrix<F,U,STAR>& A, DistMatrix<F,STAR,STAR>& R )
{
    auto treeData = TS( A );
    R = ts::FormR( A, treeData );
    ts::FormQ( A, treeData );
}

} // namespace qr
} // namespace elem

#endif // ifndef ELEM_LAPACK_QR_TS_HPP
<commit_msg>Fixing a few details in TSQR<commit_after>/*
   Copyright (c) 2009-2013, Jack Poulson
   All rights reserved.

   This file is part of Elemental and is under the BSD 2-Clause License,
   which can be found in the LICENSE file in the root directory, or at
   http://opensource.org/licenses/BSD-2-Clause
*/
#pragma once
#ifndef ELEM_LAPACK_QR_TS_HPP
#define ELEM_LAPACK_QR_TS_HPP

#include "elemental/blas-like/level1/MakeTriangular.hpp"
#include "elemental/lapack-like/ExpandPackedReflectors.hpp"
#include "elemental/lapack-like/QR.hpp"

namespace elem {
namespace qr {

template<typename F>
struct TreeData
{
    Matrix<F> QR0, t0;
    std::vector<Matrix<F>> QRList;
    std::vector<Matrix<F>> tList;

    TreeData( Int numStages=0 )
    : QRList(numStages), tList(numStages)
    { }

    TreeData( TreeData<F>&& treeData )
    : QR0(std::move(treeData.QR0)),
      t0(std::move(treeData.t0)),
      QRList(std::move(treeData.QRList)),
      tList(std::move(treeData.tList))
    { }

    TreeData<F>& operator=( TreeData<F>&& treeData )
    {
        QR0 = std::move(treeData.QR0);
        t0 = std::move(treeData.t0);
        QRList = std::move(treeData.QRList);
        tList = std::move(treeData.tList);
        return *this;
    }
};

namespace ts {

template<typename F,Distribution U>
inline void
Reduce( const DistMatrix<F,U,STAR>& A, TreeData<F>& treeData )
{
#ifndef RELEASE
    CallStackEntry cse("qr::ts::Reduce");
#endif
    const Int m =  A.Height();
    const Int n = A.Width();
    const mpi::Comm colComm = A.ColComm();
    const Int p = mpi::CommSize( colComm );
    if( p == 1 )
        return;
    const Int rank = mpi::CommRank( colComm );
    if( m < p*n )
        LogicError("TSQR currently assumes height >= width*numProcesses");
    if( !PowerOfTwo(p) )
        LogicError("TSQR currently requires power-of-two number of processes");
    const Int logp = Log2(p);
    auto lastZ = LockedView( treeData.QR0, 0, 0, n, n );
    treeData.QRList.resize( logp );
    treeData.tList.resize( logp );

    // Run the binary tree reduction
    Matrix<F> ZTop(n,n,n), ZBot(n,n,n);
    for( Int stage=0; stage<logp; ++stage )
    {
        // Pack, then send and receive n x n matrices
        const Int partner = Unsigned(rank) ^ (Unsigned(1)<<stage);
        const bool top = rank < partner;
        if( top )
        {
            ZTop = lastZ;
            MakeTriangular( UPPER, ZTop );
            mpi::Recv( ZBot.Buffer(), n*n, partner, colComm );
        }
        else
        {
            ZBot = lastZ;
            MakeTriangular( UPPER, ZBot );
            mpi::Send( ZBot.LockedBuffer(), n*n, partner, colComm );
            break;
        }

        auto& Q = treeData.QRList[stage];
        auto& t = treeData.tList[stage];
        Q.ResizeTo( 2*n, n, 2*n );
        t.ResizeTo( n, 1 );
        auto QTop = View( Q, 0, 0, n, n );
        auto QBot = View( Q, n, 0, n, n );
        QTop = ZTop;
        QBot = ZBot;

        // Note that the last QR is not performed by this routine, as many
        // higher-level routines, such as TS-SVT, are simplified if the final
        // small matrix is left alone.
        if( stage < logp-1 )
        {
            // TODO: Exploit double-triangular structure
            QR( Q, t );
            lastZ = LockedView( Q, 0, 0, n, n );
        }
    }
}

template<typename F,Distribution U>
inline Matrix<F>&
RootQR( const DistMatrix<F,U,STAR>& A, TreeData<F>& treeData )
{
    const Int p = mpi::CommSize( A.ColComm() );
    const Int rank = mpi::CommRank( A.ColComm() );
    if( rank != 0 )
        LogicError("This process does not have access to the root QR");
    if( p == 1 )
        return treeData.QR0;
    else
        return treeData.QRList.back();
}

template<typename F,Distribution U>
inline const Matrix<F>&
RootQR( const DistMatrix<F,U,STAR>& A, const TreeData<F>& treeData )
{
    const Int p = mpi::CommSize( A.ColComm() );
    const Int rank = mpi::CommRank( A.ColComm() );
    if( rank != 0 )
        LogicError("This process does not have access to the root QR");
    if( p == 1 )
        return treeData.QR0;
    else
        return treeData.QRList.back();
}

template<typename F,Distribution U>
inline Matrix<F>&
RootPhases( const DistMatrix<F,U,STAR>& A, TreeData<F>& treeData )
{
    const Int p = mpi::CommSize( A.ColComm() );
    const Int rank = mpi::CommRank( A.ColComm() );
    if( rank != 0 )
        LogicError("This process does not have access to the root phases");
    if( p == 1 )
        return treeData.t0;
    else
        return treeData.tList.back();
}

template<typename F,Distribution U>
inline const Matrix<F>&
RootPhases( const DistMatrix<F,U,STAR>& A, const TreeData<F>& treeData )
{
    const Int p = mpi::CommSize( A.ColComm() );
    const Int rank = mpi::CommRank( A.ColComm() );
    if( rank != 0 )
        LogicError("This process does not have access to the root phases");
    if( p == 1 )
        return treeData.t0;
    else
        return treeData.tList.back();
}

template<typename F,Distribution U>
inline void
Scatter( DistMatrix<F,U,STAR>& A, const TreeData<F>& treeData )
{
#ifndef RELEASE
    CallStackEntry cse("qr::ts::Scatter");
#endif
    const Int m =  A.Height();
    const Int n = A.Width();
    const mpi::Comm colComm = A.ColComm();
    const Int p = mpi::CommSize( colComm );
    if( p == 1 )
        return;
    const Int rank = mpi::CommRank( colComm );
    if( m < p*n )
        LogicError("TSQR currently assumes height >= width*numProcesses");
    if( !PowerOfTwo(p) )
        LogicError("TSQR currently requires power-of-two number of processes");
    const Int logp = Log2(p);

    // Run the binary tree scatter
    Matrix<F> Z(2*n,n,2*n), ZHalf(n,n,n);
    if( rank == 0 )
        Z = RootQR( A, treeData );
    auto ZTop = View( Z, 0, 0, n, n );
    auto ZBot = View( Z, n, 0, n, n );
    for( Int revStage=0; revStage<logp; ++revStage )
    {
        const Int stage = (logp-1)-revStage;
        // Skip this stage if the first stage bits of our rank are not zero
        if( stage>0 && (Unsigned(rank) & ((Unsigned(1)<<stage)-1)) )
            continue;

        const Int partner = rank ^ (1u<<stage);
        const bool top = rank < partner;
        if( top )
        {
            if( stage < logp-1 )
            {
                // Multiply by the current Q
                ZTop = ZHalf;
                MakeZeros( ZBot );
                // TODO: Exploit sparsity?
                ApplyQ
                ( LEFT, NORMAL,
                  treeData.QRList[stage], treeData.tList[stage], Z );
            }
            // Send bottom-half to partner and keep top half
            ZHalf = ZBot;
            mpi::Send( ZHalf.LockedBuffer(), n*n, partner, colComm );
            ZHalf = ZTop;
        }
        else
        {
            // Recv top half from partner
            mpi::Recv( ZHalf.Buffer(), n*n, partner, colComm );
        }
    }

    // Apply the initial Q
    MakeZeros( A.Matrix() );
    auto ATop = View( A.Matrix(), 0, 0, n, n );
    ATop = ZHalf;
    // TODO: Exploit sparsity
    ApplyQ( LEFT, NORMAL, treeData.QR0, treeData.t0, A.Matrix() );
}

template<typename F,Distribution U>
inline DistMatrix<F,STAR,STAR>
FormR( const DistMatrix<F,U,STAR>& A, const TreeData<F>& treeData )
{
    const Grid& g = A.Grid();
    DistMatrix<F,CIRC,CIRC> RRoot(g);
    if( A.ColRank() == 0 )
    {
        const Int n = A.Width();
        auto RTop = LockedView( RootQR(A,treeData), 0, 0, n, n );
        RRoot.CopyFromRoot( RTop );
        MakeTriangular( UPPER, RRoot );
    }
    else
        RRoot.CopyFromNonRoot();
    DistMatrix<F,STAR,STAR> R(g);
    R = RRoot;
    return R;
}

// NOTE: This is destructive
template<typename F,Distribution U>
inline void
FormQ( DistMatrix<F,U,STAR>& A, TreeData<F>& treeData )
{
    const Int p = mpi::CommSize( A.ColComm() );
    if( p == 1 )
    {
        A.Matrix() = treeData.QR0;
        ExpandPackedReflectors
        ( LOWER, VERTICAL, UNCONJUGATED, 0,
          A.Matrix(), RootPhases(A,treeData) );
    }
    else
    {
        if( A.ColRank() == 0 )
            ExpandPackedReflectors
            ( LOWER, VERTICAL, UNCONJUGATED, 0,
              RootQR(A,treeData), RootPhases(A,treeData) );
        Scatter( A, treeData );
    }
}

} // namespace ts

template<typename F,Distribution U>
inline TreeData<F>
TS( const DistMatrix<F,U,STAR>& A )
{
    TreeData<F> treeData;
    treeData.QR0 = A.LockedMatrix();
    QR( treeData.QR0, treeData.t0 );

    const Int p = mpi::CommSize( A.ColComm() );
    if( p != 1 )
    {
        ts::Reduce( A, treeData );
        if( A.ColRank() == 0 )
            QR( ts::RootQR(A,treeData), ts::RootPhases(A,treeData) );
    }
    return treeData;
}

template<typename F,Distribution U>
inline void
ExplicitTS( DistMatrix<F,U,STAR>& A, DistMatrix<F,STAR,STAR>& R )
{
    auto treeData = TS( A );
    R = ts::FormR( A, treeData );
    ts::FormQ( A, treeData );
}

} // namespace qr
} // namespace elem

#endif // ifndef ELEM_LAPACK_QR_TS_HPP
<|endoftext|>


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

///
/// @file exp_omi_setup.C
/// @brief Contains the explorer OMI setup
///
// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: Memory

#include <fapi2.H>
#include <generic/memory/lib/utils/c_str.H>
#include <lib/exp_attribute_accessors_manual.H>
#include <lib/omi/exp_omi_utils.H>
#include <lib/workarounds/exp_omi_workarounds.H>
#include <lib/i2c/exp_i2c.H>
#include <generic/memory/mss_git_data_helper.H>
#include <generic/memory/lib/mss_generic_attribute_getters.H>
#include <generic/memory/lib/mss_generic_system_attribute_getters.H>

extern "C"
{

    ///
    /// @brief Setup the OCMB for enterprise and half-DIMM modes as desired
    /// @param[in] i_target the OCMB target to operate on
    /// @return FAPI2_RC_SUCCESS iff ok
    ///
    fapi2::ReturnCode exp_omi_setup( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
    {
        mss::display_git_commit_info("exp_omi_setup");

        // Declares variables
        fapi2::buffer<uint64_t> l_data;
        fapi2::buffer<uint64_t> dlx_config1_data;
        uint8_t l_edpl_disable = 0;
        bool l_is_enterprise = false;
        bool l_is_half_dimm = false;
        bool l_workaround_required = false;
        std::vector<uint8_t> l_boot_config_data;
        uint8_t l_dl_layer_boot_mode = fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_DL_LAYER_BOOT_MODE_NON_DL_TRAINING;

        // Gets the data setup
        FAPI_TRY(mss::exp::omi::train::setup_fw_boot_config(i_target, l_boot_config_data));

        // Sanity check: set dl_layer_boot_mode to NON DL TRAINING (0b00 == default)
        FAPI_TRY(mss::exp::i2c::boot_cfg::set_dl_layer_boot_mode( i_target, l_boot_config_data, l_dl_layer_boot_mode ));

        // Issues the command and checks for completion
        // Note: This does not kick off OMI training
        FAPI_TRY(mss::exp::i2c::boot_config(i_target, l_boot_config_data));

        // Gets the configuration information from attributes
        FAPI_TRY(mss::enterprise_mode(i_target, l_is_enterprise));
        FAPI_TRY(mss::half_dimm_mode(i_target, l_is_half_dimm));
        FAPI_TRY(mss::attr::get_mss_omi_edpl_disable(l_edpl_disable));

        // Prints out the data
        FAPI_INF("%s is %s enterprise mode, and %s-DIMM mode", mss::c_str(i_target), l_is_enterprise ? "" : "non",
                 l_is_half_dimm ? "half" : "full");

        // Sets up the register
        mss::exp::omi::set_enterprise_set_bit(l_data, l_is_enterprise);
        mss::exp::omi::set_half_dimm_mode(l_data, l_is_half_dimm);

        // Writes the data to the register
        FAPI_TRY(mss::exp::omi::write_enterprise_config(i_target, l_data));

        // Checks that the chip is configured correctly
        FAPI_TRY(mss::exp::omi::read_enterprise_config(i_target, l_data));
        FAPI_TRY(mss::exp::omi::check_enterprise_mode(i_target, l_is_enterprise, l_data));

        // Set the EDPL according the attribute
        FAPI_TRY(mss::exp::omi::read_dlx_config1(i_target, dlx_config1_data));
        mss::exp::omi::set_edpl_enable_bit(dlx_config1_data, l_edpl_disable);
        FAPI_TRY(mss::exp::omi::write_dlx_config1(i_target, dlx_config1_data));
        FAPI_INF("%s EDPL enable: ", mss::c_str(i_target), l_edpl_disable ? "false" : "true");

        // Run the workaround if it's needed
        FAPI_TRY(mss::exp::workarounds::omi::is_prbs_ocmb_required(i_target, l_workaround_required));

        if (l_workaround_required)
        {
            uint8_t l_dl_x4_backoff_en = 0;

            FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE, i_target, l_dl_x4_backoff_en),
                     "Error getting ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE");

            FAPI_TRY(mss::exp::workarounds::omi::prbs_ocmb(i_target, l_dl_x4_backoff_en));
        }

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

///
/// @file exp_omi_setup.C
/// @brief Contains the explorer OMI setup
///
// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: Memory

#include <fapi2.H>
#include <generic/memory/lib/utils/c_str.H>
#include <lib/exp_attribute_accessors_manual.H>
#include <lib/omi/exp_omi_utils.H>
#include <lib/workarounds/exp_omi_workarounds.H>
#include <lib/i2c/exp_i2c.H>
#include <generic/memory/mss_git_data_helper.H>
#include <generic/memory/lib/mss_generic_attribute_getters.H>
#include <generic/memory/lib/mss_generic_system_attribute_getters.H>

extern "C"
{

    ///
    /// @brief Setup the OCMB for enterprise and half-DIMM modes as desired
    /// @param[in] i_target the OCMB target to operate on
    /// @return FAPI2_RC_SUCCESS iff ok
    ///
    fapi2::ReturnCode exp_omi_setup( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
    {
        mss::display_git_commit_info("exp_omi_setup");

        // Declares variables
        fapi2::buffer<uint64_t> l_data;
        fapi2::buffer<uint64_t> dlx_config1_data;
        uint8_t l_edpl_disable = 0;
        bool l_is_enterprise = false;
        bool l_is_half_dimm = false;
        bool l_workaround_required = false;
        std::vector<uint8_t> l_boot_config_data;
        uint8_t l_dl_layer_boot_mode = fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_DL_LAYER_BOOT_MODE_NON_DL_TRAINING;

        // Gets the data setup
        FAPI_TRY(mss::exp::omi::train::setup_fw_boot_config(i_target, l_boot_config_data));

        // Sanity check: set dl_layer_boot_mode to NON DL TRAINING (0b00 == default)
        FAPI_TRY(mss::exp::i2c::boot_cfg::set_dl_layer_boot_mode( i_target, l_boot_config_data, l_dl_layer_boot_mode ));

        // Issues the command and checks for completion
        // Note: This does not kick off OMI training
        FAPI_TRY(mss::exp::i2c::boot_config(i_target, l_boot_config_data));

        // Gets the configuration information from attributes
        FAPI_TRY(mss::enterprise_mode(i_target, l_is_enterprise));
        FAPI_TRY(mss::half_dimm_mode(i_target, l_is_half_dimm));
        FAPI_TRY(mss::attr::get_mss_omi_edpl_disable(l_edpl_disable));

        // Prints out the data
        FAPI_INF("%s is %s enterprise mode, and %s-DIMM mode", mss::c_str(i_target), l_is_enterprise ? "" : "non",
                 l_is_half_dimm ? "half" : "full");

        // Sets up the register
        mss::exp::omi::set_enterprise_set_bit(l_data, l_is_enterprise);
        mss::exp::omi::set_half_dimm_mode(l_data, l_is_half_dimm);

        // Writes the data to the register
        FAPI_TRY(mss::exp::omi::write_enterprise_config(i_target, l_data));

        // Checks that the chip is configured correctly
        FAPI_TRY(mss::exp::omi::read_enterprise_config(i_target, l_data));
        FAPI_TRY(mss::exp::omi::check_enterprise_mode(i_target, l_is_enterprise, l_data));

        // Set the EDPL according the attribute
        FAPI_TRY(mss::exp::omi::read_dlx_config1(i_target, dlx_config1_data));
        mss::exp::omi::set_edpl_enable_bit(dlx_config1_data, l_edpl_disable);
        FAPI_TRY(mss::exp::omi::write_dlx_config1(i_target, dlx_config1_data));
        FAPI_INF("%s EDPL enable: %s", mss::c_str(i_target), (l_edpl_disable ? "false" : "true"));

        // Run the workaround if it's needed
        FAPI_TRY(mss::exp::workarounds::omi::is_prbs_ocmb_required(i_target, l_workaround_required));

        if (l_workaround_required)
        {
            uint8_t l_dl_x4_backoff_en = 0;

            FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE, i_target, l_dl_x4_backoff_en),
                     "Error getting ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE");

            FAPI_TRY(mss::exp::workarounds::omi::prbs_ocmb(i_target, l_dl_x4_backoff_en));
        }

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


<commit_before>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
Copyright (c) 2008 Aristid Breitkreuz, Ruediger Sonderfeld

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.
*/

#ifndef FLUSSPFERD_FUNCTION_ADAPTER_HPP
#define FLUSSPFERD_FUNCTION_ADAPTER_HPP

#include "convert.hpp"
#include "call_context.hpp"
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/function.hpp>

namespace flusspferd {

namespace detail {

template<typename T>
struct is_native_object_type {
  typedef typename boost::remove_reference<T>::type T2;
  typedef typename boost::remove_pointer<T2>::type native_object_type;

  typedef typename boost::is_convertible<T2, native_object_base>::type type;
};

template<typename T, typename Condition = void>
struct ptr_to_native_object_type {
  static T get(native_object_base *self_native) {
    return self_native;
  }
};

template<typename T>
struct ptr_to_native_object_type<
    T, typename boost::enable_if<typename boost::is_pointer<T>::type>::type>
{
  static T get(native_object_base *self_native) {
    return *self_native;
  }
};

native_object_base *
get_native_object_parameter(call_context &x, std::size_t &offset) {
  native_object_base *p = x.self_native;

  if (p)
    return p;

  convert<native_object_base *>::from_value from_value;

  p = from_value.perform(x.arg[offset++]);

  return p;
}

template<
  typename T,
  typename R = typename T::result_type,
  std::size_t A = T::arity,
  typename Condition = void>
struct function_adapter;

template<typename T, typename R>
struct function_adapter<T, R, 0> {
  typename convert<R>::to_value to_value;

  void action(T const &function, call_context &x) {
    x.result = to_value.perform(function());
  }
};

template<typename T>
struct function_adapter<T, void, 0> {
  void action(T const &function, call_context &) {
    function();
  }
};

template<typename T, typename R>
struct function_adapter<
  T, R, 1,
  typename boost::enable_if<
    typename is_native_object_type<typename T::arg1_type>::type
  >::type
>
{
  typename convert<R>::to_value to_value;

  typedef typename T::arg1_type arg1_type;

  void action(T const &function, call_context &x) {
    std::size_t offset = 0;
    native_object_base *obj = get_native_object_parameter(x, offset);
    arg1_type arg1 = ptr_to_native_object_type<arg1_type>::get(obj);
    x.result = to_value.perform(function(arg1));
  }
};

template<typename T>
struct function_adapter<
  T, void, 1,
  typename boost::enable_if<
    typename is_native_object_type<typename T::arg1_type>::type
  >::type
>
{
  typedef typename T::arg1_type arg1_type;

  void action(T const &function, call_context &x) {
    std::size_t offset = 0;
    native_object_base *obj = get_native_object_parameter(x, offset);
    arg1_type arg1 = ptr_to_native_object_type<arg1_type>::get(obj);
    function(arg1);
  }
};

template<typename T, typename R>
struct function_adapter<
  T, R, 1,
  typename boost::enable_if<
    typename boost::is_convertible<typename T::arg1_type, object>::type
  >::type
>
{
  typename convert<R>::to_value to_value;

  void action(T const &function, call_context &x) {
    x.result = to_value.perform(function(x.self));
  }
};

template<typename T>
struct function_adapter<
  T, void, 1,
  typename boost::enable_if<
    typename boost::is_convertible<typename T::arg1_type, object>::type
  >::type
>
{
  void action(T const &function, call_context &x) {
    function(x.self);
  }
};

template<typename T, typename R, typename C>
struct function_adapter<T, R, 1, C> {
  typename convert<R>::to_value to_value;

  typedef typename T::arg1_type arg1_type;

  typename convert<arg1_type>::from_value arg1_from_value;

  void action(T const &function, call_context &x) {
    x.result = to_value.perform(function(arg1_from_value.perform(x.arg[0])));
  }
};

template<typename T, typename C>
struct function_adapter<T, void, 1, C> {
  typedef typename T::arg1_type arg1_type;

  typename convert<arg1_type>::from_value arg1_from_value;

  void action(T const &function, call_context &x) {
    function(arg1_from_value.perform(x.arg[0]));
  }
};

}

template<typename T>
class function_adapter {
public:
  typedef T spec_type;
  typedef boost::function<spec_type> function_type;

  function_adapter(function_type const &function)
    : function(function)
  {}

  void operator() (call_context &x) {
    detail::function_adapter<function_type> function_adapter_implementation;
    function_adapter_implementation.action(function, x);
  }

private:
  function_type function;
};

}

#endif
<commit_msg>macro abstractions<commit_after>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
Copyright (c) 2008 Aristid Breitkreuz, Ruediger Sonderfeld

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.
*/

#ifndef FLUSSPFERD_FUNCTION_ADAPTER_HPP
#define FLUSSPFERD_FUNCTION_ADAPTER_HPP

#if 1
#include "convert.hpp"
#include "call_context.hpp"
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/function.hpp>
#endif
#include <boost/preprocessor.hpp>

namespace flusspferd {

namespace detail {

template<typename T>
struct is_native_object_type {
  typedef typename boost::remove_reference<T>::type T2;
  typedef typename boost::remove_pointer<T2>::type native_object_type;

  typedef typename boost::is_convertible<T2, native_object_base>::type type;
};

template<typename T, typename Condition = void>
struct ptr_to_native_object_type {
  static T get(native_object_base *self_native) {
    return self_native;
  }
};

template<typename T>
struct ptr_to_native_object_type<
    T, typename boost::enable_if<typename boost::is_pointer<T>::type>::type>
{
  static T get(native_object_base *self_native) {
    return *self_native;
  }
};

native_object_base *
get_native_object_parameter(call_context &x, std::size_t &offset) {
  native_object_base *p = x.self_native;

  if (p)
    return p;

  convert<native_object_base *>::from_value from_value;

  p = from_value.perform(x.arg[offset++]);

  return p;
}

template<
  typename T,
  typename R = typename T::result_type,
  std::size_t A = T::arity,
  typename Condition = void>
struct function_adapter;

template<typename T, typename R>
struct function_adapter<T, R, 0> {
  typename convert<R>::to_value to_value;

  void action(T const &function, call_context &x) {
    x.result = to_value.perform(function());
  }
};

template<typename T>
struct function_adapter<T, void, 0> {
  void action(T const &function, call_context &) {
    function();
  }
};

template<typename T, typename R>
struct function_adapter<
  T, R, 1,
  typename boost::enable_if<
    typename is_native_object_type<typename T::arg1_type>::type
  >::type
>
{
  typename convert<R>::to_value to_value;

  typedef typename T::arg1_type arg1_type;

  void action(T const &function, call_context &x) {
    std::size_t offset = 0;
    native_object_base *obj = get_native_object_parameter(x, offset);
    arg1_type arg1 = ptr_to_native_object_type<arg1_type>::get(obj);
    x.result = to_value.perform(function(arg1));
  }
};

template<typename T>
struct function_adapter<
  T, void, 1,
  typename boost::enable_if<
    typename is_native_object_type<typename T::arg1_type>::type
  >::type
>
{
  typedef typename T::arg1_type arg1_type;

  void action(T const &function, call_context &x) {
    std::size_t offset = 0;
    native_object_base *obj = get_native_object_parameter(x, offset);
    arg1_type arg1 = ptr_to_native_object_type<arg1_type>::get(obj);
    function(arg1);
  }
};

template<typename T, typename R>
struct function_adapter<
  T, R, 1,
  typename boost::enable_if<
    typename boost::is_convertible<typename T::arg1_type, object>::type
  >::type
>
{
  typename convert<R>::to_value to_value;

  void action(T const &function, call_context &x) {
    x.result = to_value.perform(function(x.self));
  }
};

template<typename T>
struct function_adapter<
  T, void, 1,
  typename boost::enable_if<
    typename boost::is_convertible<typename T::arg1_type, object>::type
  >::type
>
{
  void action(T const &function, call_context &x) {
    function(x.self);
  }
};

#define FLUSSPFERD_DECLARE_ARG_CONVERTER(z, i, T) \
  typename convert<typename T::BOOST_PP_CAT(BOOST_PP_CAT(arg, i), _type)>::from_value \
  BOOST_PP_CAT(BOOST_PP_CAT(arg, i), _from_value); \
  /**/

#define FLUSSPFERD_DECLARE_ARG_CONVERTERS(n, T) \
  BOOST_PP_REPEAT_FROM_TO( \
    1, \
    BOOST_PP_INC(n), \
    FLUSSPFERD_DECLARE_ARG_CONVERTER, \
    T) \
  /**/

#define FLUSSPFERD_CONVERT_ARG(z, i, x) \
  BOOST_PP_COMMA_IF(BOOST_PP_GREATER(i, 1)) \
  BOOST_PP_CAT(BOOST_PP_CAT(arg, i), _from_value) \
  .perform((x).arg[BOOST_PP_DEC(i)]) \
  /**/

#define FLUSSPFERD_CONVERT_ARGS(n, x) \
  BOOST_PP_REPEAT_FROM_TO( \
    1, \
    BOOST_PP_INC(n), \
    FLUSSPFERD_CONVERT_ARG, \
    x) \
  /**/

template<typename T, typename R, typename C>
struct function_adapter<T, R, 1, C> {
  typename convert<R>::to_value to_value;

  FLUSSPFERD_DECLARE_ARG_CONVERTERS(1, T)

  void action(T const &function, call_context &x) {
    x.result = to_value.perform(FLUSSPFERD_CONVERT_ARGS(1, x));
  }
};

template<typename T, typename C>
struct function_adapter<T, void, 1, C> {
  FLUSSPFERD_DECLARE_ARG_CONVERTERS(1, T)

  void action(T const &function, call_context &x) {
    function(FLUSSPFERD_CONVERT_ARGS(1, x));
  }
};

}

template<typename T>
class function_adapter {
public:
  typedef T spec_type;
  typedef boost::function<spec_type> function_type;

  function_adapter(function_type const &function)
    : function(function)
  {}

  void operator() (call_context &x) {
    detail::function_adapter<function_type> function_adapter_implementation;
    function_adapter_implementation.action(function, x);
  }

private:
  function_type function;
};

}

#endif
<|endoftext|>