<commit_before>/* -*- mode: c++; c-basic-offset:4 -*-
    selftest/enginecheck.cpp

    This file is part of Kleopatra, the KDE keymanager
    Copyright (c) 2008 Klarälvdalens Datakonsult AB

    Kleopatra 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.

    Kleopatra 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

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include <config-kleopatra.h>

#include "enginecheck.h"

#include "implementation_p.h"

#include <gpgme++/global.h>
#include <gpgme++/engineinfo.h>
#include <gpgme++/error.h>

#include <gpg-error.h>

#include <KLocale>

#include <QFile>

#include <boost/shared_ptr.hpp>

#include <cassert>

using namespace Kleo;
using namespace Kleo::_detail;
using namespace GpgME;
using namespace boost;

static QString engine_name( GpgME::Engine eng ) {
    static const char * engines[] = {
        "gpg", "gpgsm", "gpgconf"
    };
    return QString::fromLatin1( engines[eng] );
}

static QString test_name( GpgME::Engine eng ) {
    static const char * names[] = {
        I18N_NOOP2( "@title", "GPG (OpenPGP Backend) installation" ),
        I18N_NOOP2( "@title", "GpgSM (S/MIME Backend) installation" ),
        I18N_NOOP2( "@title", "GpgConf (Configuration) installation" ),
    };
    return i18nc( "@title", names[eng] );
}

namespace {

    class EngineCheck : public SelfTestImplementation {
    public:
        explicit EngineCheck( GpgME::Engine eng )
            : SelfTestImplementation( test_name( eng ) )
        {
            runTest( eng );
        }

        void runTest( GpgME::Engine eng ) {
            const Error err = GpgME::checkEngine( eng );
            assert( !err.code() || err.code() == GPG_ERR_INV_ENGINE );

            m_passed = !err;

            if ( m_passed )
                return;

            m_explaination = i18nc("@info",
                                   "<para>A problem was detected with the <application>%1</application> backend.</para>",
                                   engine_name( eng ) );

            const EngineInfo ei = engineInfo( eng );
            if ( ei.isNull() ) {
                m_error = i18n("not supported");
                m_explaination += i18nc("@info",
                                        "<para>It seems that the <icode>gpgme</icode> library was compiled without "
                                        "support for this backend.</para>");
                m_proposedFix += i18nc("@info",
                                       "<para>Replace the <icode>gpgme</icode> library with a version compiled "
                                       "with <application>%1</application> support.",
                                       engine_name( eng ) );
            } else if ( ei.fileName() && !ei.version() ) {
                m_error = i18n("not properly installed");
                m_explaination += i18nc("@info",
                                        "<para>Backend <command>%1</command> is not installed properly.</para>" );
                m_proposedFix += i18nc( "@info",
                                        "<para>Please check the output of <command>%1 --version</command> manually.</para>",
                                        QFile::decodeName( ei.fileName() ) );
            } else if ( ei.fileName() && ei.version() && ei.requiredVersion() ) {
                m_error = i18n("too old");
                m_explaination += i18nc("@info",
                                        "<para>Backend <command>%1</command> is installed in version %2, "
                                        "but at least version %3 is required.",
                                        QFile::decodeName( ei.fileName() ),
                                        QString::fromUtf8( ei.version() ),
                                        QString::fromUtf8( ei.requiredVersion() ) );
                m_proposedFix += i18nc( "@info",
                                        "<para>Install <application>%1</application> version %2 or higher.</para>",
                                        engine_name( eng ), QString::fromUtf8( ei.requiredVersion() ) );
            } else {
                m_error = m_explaination = i18n("unknown problem");
                m_proposedFix += i18nc( "@info",
                                        "<para>Make sure <application>%1</application> is installed and "
                                        "in <envvar>PATH</envvar>.",
                                        engine_name( eng ) );
            }
        }

    };
}

shared_ptr<SelfTest> Kleo::makeGpgEngineCheckSelfTest() {
    return shared_ptr<SelfTest>( new EngineCheck( GpgME::GpgEngine ) );
}

shared_ptr<SelfTest> Kleo::makeGpgSmEngineCheckSelfTest() {
    return shared_ptr<SelfTest>( new EngineCheck( GpgME::GpgSMEngine ) );
}

shared_ptr<SelfTest> Kleo::makeGpgConfEngineCheckSelfTest() {
    return shared_ptr<SelfTest>( new EngineCheck( GpgME::GpgConfEngine ) );
}
<commit_msg>i18n fixes.<commit_after>/* -*- mode: c++; c-basic-offset:4 -*-
    selftest/enginecheck.cpp

    This file is part of Kleopatra, the KDE keymanager
    Copyright (c) 2008 Klarälvdalens Datakonsult AB

    Kleopatra 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.

    Kleopatra 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

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include <config-kleopatra.h>

#include "enginecheck.h"

#include "implementation_p.h"

#include <gpgme++/global.h>
#include <gpgme++/engineinfo.h>
#include <gpgme++/error.h>

#include <gpg-error.h>

#include <KLocale>

#include <QFile>

#include <boost/shared_ptr.hpp>

#include <cassert>

using namespace Kleo;
using namespace Kleo::_detail;
using namespace GpgME;
using namespace boost;

static QString engine_name( GpgME::Engine eng ) {
    static const char * engines[] = {
        "gpg", "gpgsm", "gpgconf"
    };
    return QString::fromLatin1( engines[eng] );
}

static QString test_name( GpgME::Engine eng ) {
    static const char * names[] = {
        I18N_NOOP2( "@title", "GPG (OpenPGP Backend) installation" ),
        I18N_NOOP2( "@title", "GpgSM (S/MIME Backend) installation" ),
        I18N_NOOP2( "@title", "GpgConf (Configuration) installation" ),
    };
    return i18nc( "@title", names[eng] );
}

namespace {

    class EngineCheck : public SelfTestImplementation {
    public:
        explicit EngineCheck( GpgME::Engine eng )
            : SelfTestImplementation( test_name( eng ) )
        {
            runTest( eng );
        }

        void runTest( GpgME::Engine eng ) {
            const Error err = GpgME::checkEngine( eng );
            assert( !err.code() || err.code() == GPG_ERR_INV_ENGINE );

            m_passed = !err;

            if ( m_passed )
                return;

            m_explaination = i18nc("@info",
                                   "<para>A problem was detected with the <application>%1</application> backend.</para>",
                                   engine_name( eng ) );

            const EngineInfo ei = engineInfo( eng );
            if ( ei.isNull() ) {
                m_error = i18n("not supported");
                m_explaination += i18nc("@info",
                                        "<para>It seems that the <icode>gpgme</icode> library was compiled without "
                                        "support for this backend.</para>");
                m_proposedFix += i18nc("@info",
                                       "<para>Replace the <icode>gpgme</icode> library with a version compiled "
                                       "with <application>%1</application> support.</para>",
                                       engine_name( eng ) );
            } else if ( ei.fileName() && !ei.version() ) {
                m_error = i18n("not properly installed");
                m_explaination += i18nc("@info",
                                        "<para>Backend <command>%1</command> is not installed properly.</para>",
                                        QFile::decodeName( ei.fileName() ) );
                m_proposedFix += i18nc( "@info",
                                        "<para>Please check the output of <command>%1 --version</command> manually.</para>",
                                        QFile::decodeName( ei.fileName() ) );
            } else if ( ei.fileName() && ei.version() && ei.requiredVersion() ) {
                m_error = i18n("too old");
                m_explaination += i18nc("@info",
                                        "<para>Backend <command>%1</command> is installed in version %2, "
                                        "but at least version %3 is required.</para>",
                                        QFile::decodeName( ei.fileName() ),
                                        QString::fromUtf8( ei.version() ),
                                        QString::fromUtf8( ei.requiredVersion() ) );
                m_proposedFix += i18nc( "@info",
                                        "<para>Install <application>%1</application> version %2 or higher.</para>",
                                        engine_name( eng ), QString::fromUtf8( ei.requiredVersion() ) );
            } else {
                m_error = m_explaination = i18n("unknown problem");
                m_proposedFix += i18nc( "@info",
                                        "<para>Make sure <application>%1</application> is installed and "
                                        "in <envar>PATH</envar>.</para>",
                                        engine_name( eng ) );
            }
        }

    };
}

shared_ptr<SelfTest> Kleo::makeGpgEngineCheckSelfTest() {
    return shared_ptr<SelfTest>( new EngineCheck( GpgME::GpgEngine ) );
}

shared_ptr<SelfTest> Kleo::makeGpgSmEngineCheckSelfTest() {
    return shared_ptr<SelfTest>( new EngineCheck( GpgME::GpgSMEngine ) );
}

shared_ptr<SelfTest> Kleo::makeGpgConfEngineCheckSelfTest() {
    return shared_ptr<SelfTest>( new EngineCheck( GpgME::GpgConfEngine ) );
}
<|endoftext|>


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

  Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org>
  Copyright (c) 2005 Rafal Rzepecki <divide@users.sourceforge.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 "koeventviewerdialog.h"
#include "koeventviewer.h"
#include <klocale.h>

KOEventViewerDialog::KOEventViewerDialog( QWidget *parent, bool compact )
  : KDialog( parent )
{
  setCaption( i18n( "Event Viewer" ) );
  setButtons( Ok | User1 | User2 );
  setModal( false );
  setButtonGuiItem( User1, KGuiItem( i18n( "Edit..." ) ) );
  setButtonGuiItem( User2, KGuiItem( i18n( "Show in Context" ) ) );
  mEventViewer = new KOEventViewer( this );
  setMainWidget( mEventViewer );

  // FIXME: Set a sensible size (based on the content?).
  if ( compact ) {
    setFixedSize( 240, 284 );
    move( 0, 15 );
  } else {
    setMinimumSize( 300, 200 );
    resize( 320, 300 );
  }
  connect( this, SIGNAL(finished()), this, SLOT(delayedDestruct()) );
  connect( this, SIGNAL( user1Clicked() ), mEventViewer,
           SLOT( editIncidence() ) );
  connect( this, SIGNAL( user2Clicked() ), mEventViewer,
           SLOT( showIncidenceContext() ) );
}

KOEventViewerDialog::~KOEventViewerDialog()
{
}

void KOEventViewerDialog::addText( const QString &text )
{
  mEventViewer->addText(text);
}

#include "koeventviewerdialog.moc"
<commit_msg>Backport: use close here<commit_after>/*
  This file is part of KOrganizer.

  Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org>
  Copyright (c) 2005 Rafal Rzepecki <divide@users.sourceforge.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 "koeventviewerdialog.h"
#include "koeventviewer.h"
#include <klocale.h>

KOEventViewerDialog::KOEventViewerDialog( QWidget *parent, bool compact )
  : KDialog( parent )
{
  setCaption( i18n( "Event Viewer" ) );
  setButtons( Close | User1 | User2 );
  setModal( false );
  setButtonGuiItem( User1, KGuiItem( i18n( "Edit..." ) ) );
  setButtonGuiItem( User2, KGuiItem( i18n( "Show in Context" ) ) );
  mEventViewer = new KOEventViewer( this );
  setMainWidget( mEventViewer );

  // FIXME: Set a sensible size (based on the content?).
  if ( compact ) {
    setFixedSize( 240, 284 );
    move( 0, 15 );
  } else {
    setMinimumSize( 300, 200 );
    resize( 320, 300 );
  }
  connect( this, SIGNAL(finished()), this, SLOT(delayedDestruct()) );
  connect( this, SIGNAL( user1Clicked() ), mEventViewer,
           SLOT( editIncidence() ) );
  connect( this, SIGNAL( user2Clicked() ), mEventViewer,
           SLOT( showIncidenceContext() ) );
}

KOEventViewerDialog::~KOEventViewerDialog()
{
}

void KOEventViewerDialog::addText( const QString &text )
{
  mEventViewer->addText(text);
}

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


<commit_before>/*
 * This file is part of telepathy-nepomuk-service
 *
 * Copyright (C) 2009-2011 Collabora Ltd. <info@collabora.co.uk>
 *   @author George Goldberg <george.goldberg@collabora.co.uk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "account.h"

#include <KDebug>

#include <TelepathyQt/ContactManager>
#include <TelepathyQt/PendingContacts>
#include <TelepathyQt/PendingOperation>
#include <TelepathyQt/PendingReady>

Account::Account(const Tp::AccountPtr &account, QObject *parent)
 : QObject(parent),
   m_account(account)
{
    // Do nothing here. Wait for init() to be called to allow
    // signal/slot connections to be set up first.
    kDebug() << "Account Constructed.";
}

void Account::init()
{
    // Connect to all the signals that indicate changes in properties we care about.
    connect(m_account.data(),
            SIGNAL(nicknameChanged(QString)),
            SLOT(onNicknameChanged(QString)));
    //    connect(m_account.data(),
    //            SIGNAL(avatarChanged(Tp::Avatar)),
    //            SLOT(onAvatarChanged(Tp::Avatar)));
    // ...... and any other properties we want to sync...
    connect(m_account.data(),
            SIGNAL(connectionChanged(Tp::ConnectionPtr)),
            SLOT(onConnectionChanged(Tp::ConnectionPtr)));

    connect(m_account.data(),
            SIGNAL(removed()),
            SLOT(onAccountRemoved()));

    QString protocolName = m_account->serviceName().isEmpty() ? m_account->protocolName() : m_account->serviceName();
    // Emit a signal to notify the storage that a new account has been constructed
    // FIXME: Some IM Accounts don't have an ID as such, e.g. Link-Local-XMPP.
    emit created(m_account->objectPath(),
                 m_account->parameters().value(QLatin1String("account")).toString(),
                 protocolName);

    // Simulate all the accounts properties being changed.
    onNicknameChanged(m_account->nickname());

    // Now that the storage stuff is done, simulate emission of all the account signals.
    onConnectionChanged(m_account->connection());
}

Account::~Account()
{
    kDebug();
}

void Account::shutdown()
{
    kDebug();

    // Emit a signal to say we were destroyed.
    emit accountDestroyed(m_account->objectPath());
}

void Account::onConnectionChanged(const Tp::ConnectionPtr &connection)
{
    if (! connection.isNull()) {

        m_connection = connection;

        // We need to destroy ourselves if the connection goes down.
        connect(m_connection.data(),
            SIGNAL(invalidated(Tp::DBusProxy*,QString,QString)),
            SLOT(deleteLater()));

        if (!m_connection->contactManager()) {
            kWarning() << "ContactManager is Null. Abort getting contacts.";
            return;
        }

        //add contacts as soon as the contact manager is ready.
        connect(m_connection->contactManager().data(),
                SIGNAL(stateChanged(Tp::ContactListState)),
                SLOT(onContactManagerStateChanged(Tp::ContactListState)));
        // Simulate a state change signal in case it is already ready.
        onContactManagerStateChanged(m_connection->contactManager()->state());

    } else {
        // Connection has gone down. Delete our pointer to it.
        m_connection.reset();
        kDebug() << "Connection closed:" << this;
    }
}

void Account::onContactManagerStateChanged(Tp::ContactListState state)
{
//    kDebug() << "contact manager state changed to " << state;

    if (state == Tp::ContactListStateSuccess)  {
        Tp::Contacts contacts = m_connection->contactManager()->allKnownContacts();

        emit initialContactsLoaded(m_account->objectPath(), contacts);

        // Create wrapper objects for all the Contacts.
        foreach (const Tp::ContactPtr &contact, contacts) {
            onNewContact(contact);
        }
//        kDebug() << "Loop over.";
    }
}

void Account::onNicknameChanged(const QString &nickname)
{
    emit nicknameChanged(m_account->objectPath(), nickname);
}

void Account::onAllKnownContactsChanged(const Tp::Contacts &added, const Tp::Contacts &removed)
{
    // For each added contact, let's check if we already have a Contact wrapper for it
    foreach (const Tp::ContactPtr &contact, added) {
        if (!m_contacts.contains(contact)) {
            // It's a brand new one
            onNewContact(contact);
        }
    }

    // If contacts are removed, we don't actually need to do anything!
    Q_UNUSED(removed);
}

void Account::onAccountRemoved()
{
    Tp::AccountPtr account(qobject_cast<Tp::Account*>(sender()));
    Q_ASSERT(account);

    kDebug() << "Account being removed";

    emit accountRemoved(account->objectPath());
}

void Account::onNewContact(const Tp::ContactPtr &contact)
{
    // Only create a new contact if one doesn't already exist.
    if (!m_contacts.contains(contact)) {

        m_contacts.append(contact);

        // Become ready asynchronously with the avatar data, since this may take some time and we
        // don't want to delay the rest of the contact's attributes being ready.
        // Fire and forget because we can't do anything even if this fails.
        contact->manager()->upgradeContacts(QList<Tp::ContactPtr>() << contact,
                                            Tp::Features() << Tp::Contact::FeatureAvatarData
                                                           << Tp::Contact::FeatureAvatarToken);

        // Connect to all its signals
        connect(contact.data(),
                SIGNAL(aliasChanged(QString)),
                SLOT(onContactAliasChanged()));
        connect(contact.data(),
                SIGNAL(addedToGroup(QString)),
                SLOT(onContactAddedToGroup()));
        connect(contact.data(),
                SIGNAL(removedFromGroup(QString)),
                SLOT(onContactRemovedFromGroup(QString)));
        connect(contact.data(),
                SIGNAL(avatarDataChanged(Tp::AvatarData)),
                SLOT(onContactAvatarChanged(Tp::AvatarData)));

        emit contactCreated(m_account->objectPath(), contact);
    }
}

void Account::onContactAddedToGroup()
{
    const Tp::ContactPtr contact(qobject_cast<Tp::Contact*>(sender()));
    Q_ASSERT(contact);

    onContactAddedToGroup(contact);
}

void Account::onContactAddedToGroup(const Tp::ContactPtr &contact)
{
    emit contactGroupsChanged(m_account->objectPath(), contact->id(), contact->groups());
}

void Account::onContactRemovedFromGroup(const QString &group)
{
    Q_UNUSED(group);
    const Tp::ContactPtr contact(qobject_cast<Tp::Contact*>(sender()));
    Q_ASSERT(contact);

    emit contactGroupsChanged(m_account->objectPath(), contact->id(), contact->groups());
}

void Account::onContactAliasChanged()
{
    const Tp::ContactPtr contact(qobject_cast<Tp::Contact*>(sender()));
    Q_ASSERT(contact);

    onContactAliasChanged(contact);
}

void Account::onContactAliasChanged(const Tp::ContactPtr &contact)
{
    emit contactAliasChanged(m_account->objectPath(), contact->id(), contact->alias());
}

void Account::onContactAvatarChanged(const Tp::AvatarData &avatar)
{
    const Tp::ContactPtr contact(qobject_cast<Tp::Contact*>(sender()));
    Q_ASSERT(contact);

    emit contactAvatarChanged(m_account->objectPath(), contact->id(), avatar);
}

#include "account.moc"
<commit_msg>Don't delete teh account when connection goes down<commit_after>/*
 * This file is part of telepathy-nepomuk-service
 *
 * Copyright (C) 2009-2011 Collabora Ltd. <info@collabora.co.uk>
 *   @author George Goldberg <george.goldberg@collabora.co.uk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "account.h"

#include <KDebug>

#include <TelepathyQt/ContactManager>
#include <TelepathyQt/PendingContacts>
#include <TelepathyQt/PendingOperation>
#include <TelepathyQt/PendingReady>

Account::Account(const Tp::AccountPtr &account, QObject *parent)
 : QObject(parent),
   m_account(account)
{
    // Do nothing here. Wait for init() to be called to allow
    // signal/slot connections to be set up first.
    kDebug() << "Account Constructed.";
}

void Account::init()
{
    // Connect to all the signals that indicate changes in properties we care about.
    connect(m_account.data(),
            SIGNAL(nicknameChanged(QString)),
            SLOT(onNicknameChanged(QString)));
    //    connect(m_account.data(),
    //            SIGNAL(avatarChanged(Tp::Avatar)),
    //            SLOT(onAvatarChanged(Tp::Avatar)));
    // ...... and any other properties we want to sync...
    connect(m_account.data(),
            SIGNAL(connectionChanged(Tp::ConnectionPtr)),
            SLOT(onConnectionChanged(Tp::ConnectionPtr)));

    connect(m_account.data(),
            SIGNAL(removed()),
            SLOT(onAccountRemoved()));

    QString protocolName = m_account->serviceName().isEmpty() ? m_account->protocolName() : m_account->serviceName();
    // Emit a signal to notify the storage that a new account has been constructed
    // FIXME: Some IM Accounts don't have an ID as such, e.g. Link-Local-XMPP.
    emit created(m_account->objectPath(),
                 m_account->parameters().value(QLatin1String("account")).toString(),
                 protocolName);

    // Simulate all the accounts properties being changed.
    onNicknameChanged(m_account->nickname());

    // Now that the storage stuff is done, simulate emission of all the account signals.
    onConnectionChanged(m_account->connection());
}

Account::~Account()
{
    kDebug();
}

void Account::shutdown()
{
    kDebug();

    // Emit a signal to say we were destroyed.
    emit accountDestroyed(m_account->objectPath());
}

void Account::onConnectionChanged(const Tp::ConnectionPtr &connection)
{
    if (! connection.isNull()) {

        m_connection = connection;

        if (!m_connection->contactManager()) {
            kWarning() << "ContactManager is Null. Abort getting contacts.";
            return;
        }

        //add contacts as soon as the contact manager is ready.
        connect(m_connection->contactManager().data(),
                SIGNAL(stateChanged(Tp::ContactListState)),
                SLOT(onContactManagerStateChanged(Tp::ContactListState)));
        // Simulate a state change signal in case it is already ready.
        onContactManagerStateChanged(m_connection->contactManager()->state());

    } else {
        // Connection has gone down. Delete our pointer to it.
        m_connection.reset();
        kDebug() << "Connection closed:" << this;
    }
}

void Account::onContactManagerStateChanged(Tp::ContactListState state)
{
//    kDebug() << "contact manager state changed to " << state;

    if (state == Tp::ContactListStateSuccess)  {
        Tp::Contacts contacts = m_connection->contactManager()->allKnownContacts();

        emit initialContactsLoaded(m_account->objectPath(), contacts);

        // Create wrapper objects for all the Contacts.
        foreach (const Tp::ContactPtr &contact, contacts) {
            onNewContact(contact);
        }
//        kDebug() << "Loop over.";
    }
}

void Account::onNicknameChanged(const QString &nickname)
{
    emit nicknameChanged(m_account->objectPath(), nickname);
}

void Account::onAllKnownContactsChanged(const Tp::Contacts &added, const Tp::Contacts &removed)
{
    // For each added contact, let's check if we already have a Contact wrapper for it
    foreach (const Tp::ContactPtr &contact, added) {
        if (!m_contacts.contains(contact)) {
            // It's a brand new one
            onNewContact(contact);
        }
    }

    // If contacts are removed, we don't actually need to do anything!
    Q_UNUSED(removed);
}

void Account::onAccountRemoved()
{
    Tp::AccountPtr account(qobject_cast<Tp::Account*>(sender()));
    Q_ASSERT(account);

    kDebug() << "Account being removed";

    emit accountRemoved(account->objectPath());
}

void Account::onNewContact(const Tp::ContactPtr &contact)
{
    // Only create a new contact if one doesn't already exist.
    if (!m_contacts.contains(contact)) {

        m_contacts.append(contact);

        // Become ready asynchronously with the avatar data, since this may take some time and we
        // don't want to delay the rest of the contact's attributes being ready.
        // Fire and forget because we can't do anything even if this fails.
        contact->manager()->upgradeContacts(QList<Tp::ContactPtr>() << contact,
                                            Tp::Features() << Tp::Contact::FeatureAvatarData
                                                           << Tp::Contact::FeatureAvatarToken);

        // Connect to all its signals
        connect(contact.data(),
                SIGNAL(aliasChanged(QString)),
                SLOT(onContactAliasChanged()));
        connect(contact.data(),
                SIGNAL(addedToGroup(QString)),
                SLOT(onContactAddedToGroup()));
        connect(contact.data(),
                SIGNAL(removedFromGroup(QString)),
                SLOT(onContactRemovedFromGroup(QString)));
        connect(contact.data(),
                SIGNAL(avatarDataChanged(Tp::AvatarData)),
                SLOT(onContactAvatarChanged(Tp::AvatarData)));

        emit contactCreated(m_account->objectPath(), contact);
    }
}

void Account::onContactAddedToGroup()
{
    const Tp::ContactPtr contact(qobject_cast<Tp::Contact*>(sender()));
    Q_ASSERT(contact);

    onContactAddedToGroup(contact);
}

void Account::onContactAddedToGroup(const Tp::ContactPtr &contact)
{
    emit contactGroupsChanged(m_account->objectPath(), contact->id(), contact->groups());
}

void Account::onContactRemovedFromGroup(const QString &group)
{
    Q_UNUSED(group);
    const Tp::ContactPtr contact(qobject_cast<Tp::Contact*>(sender()));
    Q_ASSERT(contact);

    emit contactGroupsChanged(m_account->objectPath(), contact->id(), contact->groups());
}

void Account::onContactAliasChanged()
{
    const Tp::ContactPtr contact(qobject_cast<Tp::Contact*>(sender()));
    Q_ASSERT(contact);

    onContactAliasChanged(contact);
}

void Account::onContactAliasChanged(const Tp::ContactPtr &contact)
{
    emit contactAliasChanged(m_account->objectPath(), contact->id(), contact->alias());
}

void Account::onContactAvatarChanged(const Tp::AvatarData &avatar)
{
    const Tp::ContactPtr contact(qobject_cast<Tp::Contact*>(sender()));
    Q_ASSERT(contact);

    emit contactAvatarChanged(m_account->objectPath(), contact->id(), avatar);
}

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


<commit_before>/*
Copyright (c) 2012 Carsten Burstedde, Donna Calhoun
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.

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

#ifndef AMR_UTILS_H
#define AMR_UTILS_H

#include "amr_options.h"
#include "forestclaw2d.h"

#include "amr_forestclaw.H"
#include "fclaw2d_typedefs.h"

#include "fclaw2d_capi.h"

/* Note: either we make this a C .h file, or we remove the extern "C". */

#ifdef __cplusplus
extern "C"
{
#if 0
}                               /* need this because indent is dumb */
#endif
#endif

// -----------------------------------------------------------------
// Check parms
// -----------------------------------------------------------------

void check_amr_parms (amr_options_t * gparms);

/* -----------------------------------------------------------------
   Initialize data
   ----------------------------------------------------------------- */
void init_domain_data (fclaw2d_domain_t * domain);
void init_block_data (fclaw2d_block_t * block);
void init_patch_data (fclaw2d_patch_t * patch);
void init_block_and_patch_data (fclaw2d_domain_t * domain);

void delete_domain_data (fclaw2d_domain_t * domain);
void delete_patch_data (fclaw2d_patch_t * patch);

/* -----------------------------------------------------------------
   Work with timers
   ----------------------------------------------------------------- */

/** Get current wall clock time in seconds.
 */
double fclaw2d_timer_wtime (void);
void fclaw2d_timer_init (fclaw2d_timer_t * timer);
void fclaw2d_timer_start (fclaw2d_timer_t * timer);
void fclaw2d_timer_stop (fclaw2d_timer_t * timer);

/* -----------------------------------------------------------------
   Return pointer to user data
   ---------------------------------------------------------------- */
fclaw2d_domain_data_t *get_domain_data (fclaw2d_domain_t * domain);
fclaw2d_block_data_t *get_block_data (fclaw2d_block_t * block);
fclaw2d_patch_data_t *get_patch_data (fclaw2d_patch_t * patch);

/* -----------------------------------------------------------------
   Set user data with user defined variables, etc.
   ----------------------------------------------------------------- */
void set_block_data (fclaw2d_block_t * block, const int mthbc[]);
void set_patch_data (fclaw2d_patch_t * patch, ClawPatch * cp);

void copy_domain_data (fclaw2d_domain_t * old_domain,
                       fclaw2d_domain_t * new_domain);

/* -----------------------------------------------------------------
   Link routines that don't have any other place to go...
   ----------------------------------------------------------------- */
void link_problem_setup (fclaw2d_domain_t * domain,
                         fclaw2d_problem_setup_t f_problem_setup);

#if 0                           /* moved into fclaw2d_capi.h */

/* -----------------------------------------------------------------
   Some helper functions that really do make things easier..
   ----------------------------------------------------------------- */
const amr_options_t *get_domain_parms (fclaw2d_domain_t * domain);
void set_domain_time (fclaw2d_domain_t * domain, double time);
double get_domain_time (fclaw2d_domain_t * domain);

// Misc. routines
int num_patches (fclaw2d_domain_t * domain, int level, int include_shadow);
int pow_int (int a, int n);

#endif

fclaw2d_domain_exchange_t *get_domain_exchange_data (fclaw2d_domain_t *
                                                     domain);
void set_domain_exchange_data (fclaw2d_domain_t * domain,
                               fclaw2d_domain_exchange_t * e);

#ifdef __cplusplus
#if 0
{                               /* need this because indent is dumb */
#endif
}
#endif

#endif
<commit_msg>Included header for fclaw2d_mpi_debug.c here<commit_after>/*
Copyright (c) 2012 Carsten Burstedde, Donna Calhoun
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.

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

#ifndef AMR_UTILS_H
#define AMR_UTILS_H

#include "amr_options.h"
#include "forestclaw2d.h"

#include "amr_forestclaw.H"
#include "fclaw2d_typedefs.h"

#include "fclaw2d_capi.h"

/* Note: either we make this a C .h file, or we remove the extern "C". */

#ifdef __cplusplus
extern "C"
{
#if 0
}                               /* need this because indent is dumb */
#endif
#endif

// -----------------------------------------------------------------
// Check parms
// -----------------------------------------------------------------

void check_amr_parms (amr_options_t * gparms);

/* -----------------------------------------------------------------
   Initialize data
   ----------------------------------------------------------------- */
void init_domain_data (fclaw2d_domain_t * domain);
void init_block_data (fclaw2d_block_t * block);
void init_patch_data (fclaw2d_patch_t * patch);
void init_block_and_patch_data (fclaw2d_domain_t * domain);

void delete_domain_data (fclaw2d_domain_t * domain);
void delete_patch_data (fclaw2d_patch_t * patch);

/* -----------------------------------------------------------------
   Work with timers
   ----------------------------------------------------------------- */

/** Get current wall clock time in seconds.
 */
double fclaw2d_timer_wtime (void);
void fclaw2d_timer_init (fclaw2d_timer_t * timer);
void fclaw2d_timer_start (fclaw2d_timer_t * timer);
void fclaw2d_timer_stop (fclaw2d_timer_t * timer);

/* -----------------------------------------------------------------
   Return pointer to user data
   ---------------------------------------------------------------- */
fclaw2d_domain_data_t *get_domain_data (fclaw2d_domain_t * domain);
fclaw2d_block_data_t *get_block_data (fclaw2d_block_t * block);
fclaw2d_patch_data_t *get_patch_data (fclaw2d_patch_t * patch);

/* -----------------------------------------------------------------
  Debug routines
   ---------------------------------------------------------------- */
void fclaw2d_mpi_debug();

/* -----------------------------------------------------------------
   Set user data with user defined variables, etc.
   ----------------------------------------------------------------- */
void set_block_data (fclaw2d_block_t * block, const int mthbc[]);
void set_patch_data (fclaw2d_patch_t * patch, ClawPatch * cp);

void copy_domain_data (fclaw2d_domain_t * old_domain,
                       fclaw2d_domain_t * new_domain);

/* -----------------------------------------------------------------
   Link routines that don't have any other place to go...
   ----------------------------------------------------------------- */
void link_problem_setup (fclaw2d_domain_t * domain,
                         fclaw2d_problem_setup_t f_problem_setup);

#if 0                           /* moved into fclaw2d_capi.h */

/* -----------------------------------------------------------------
   Some helper functions that really do make things easier..
   ----------------------------------------------------------------- */
const amr_options_t *get_domain_parms (fclaw2d_domain_t * domain);
void set_domain_time (fclaw2d_domain_t * domain, double time);
double get_domain_time (fclaw2d_domain_t * domain);

// Misc. routines
int num_patches (fclaw2d_domain_t * domain, int level, int include_shadow);
int pow_int (int a, int n);

#endif

fclaw2d_domain_exchange_t *get_domain_exchange_data (fclaw2d_domain_t *
                                                     domain);
void set_domain_exchange_data (fclaw2d_domain_t * domain,
                               fclaw2d_domain_exchange_t * e);

#ifdef __cplusplus
#if 0
{                               /* need this because indent is dumb */
#endif
}
#endif

#endif
<|endoftext|>


<commit_before>#include <base_64.hpp>
#include <utility>

namespace Base64 {

	//	Encoding table
	static const ASCIIChar encode []={
		'A','B','C','D','E','F','G','H',
		'I','J','K','L','M','N','O','P',
		'Q','R','S','T','U','V','W','X',
		'Y','Z','a','b','c','d','e','f',
		'g','h','i','j','k','l','m','n',
		'o','p','q','r','s','t','u','v',
		'w','x','y','z','0','1','2','3',
		'4','5','6','7','8','9','+','/'
	};
	static const ASCIIChar pad='=';

	String Encode (const Vector<Byte> & buffer) {

		auto begin=buffer.begin();
		auto end=buffer.end();

		//	This will be converted to
		//	a string and then returned
		Vector<CodePoint> cps;

		//	Iterate over entire input
		//	buffer
		while (begin!=end) {

			//	We need 24 bits for 4 base 64
			//	characters, they'll be stored
			//	in here
			UInt32 build=0;
			//	Keep track of the number of significant
			//	bytes for padding purposes
			Word significant=0;
			//	Extract 3 bytes (24 bits)
			for (Word i=0;i<3;++i) {

				//	Make room for the next byte
				build<<=BitsPerByte();

				//	Only add the next byte if
				//	there's a byte to extract
				if (begin!=end) {

					build|=*begin;

					//	Advance buffer pointer
					++begin;
					//	A byte from the buffer
					//	is significant
					++significant;

				}

			}

			Word printed=0;
			//	Print base 64 characters
			for (;printed<(significant+1);++printed) cps.Add(static_cast<CodePoint>(encode[(build>>(6*(3-printed)))&63]));
			//	Print padding (if necessary)
			for (;printed<4;++printed) cps.Add(static_cast<CodePoint>(pad));

		}

		return String(std::move(cps));

	}

}
<commit_msg>Base64 Encoder Improvement<commit_after>#include <base_64.hpp>
#include <utility>

namespace Base64 {

	//	Encoding table
	static const ASCIIChar encode []={
		'A','B','C','D','E','F','G','H',
		'I','J','K','L','M','N','O','P',
		'Q','R','S','T','U','V','W','X',
		'Y','Z','a','b','c','d','e','f',
		'g','h','i','j','k','l','m','n',
		'o','p','q','r','s','t','u','v',
		'w','x','y','z','0','1','2','3',
		'4','5','6','7','8','9','+','/'
	};
	static const ASCIIChar pad='=';

	String Encode (const Vector<Byte> & buffer) {

		//	Determine the number of code
		//	points it will take maximally
		//	to describe this buffer
		SafeWord len(buffer.Count()/3);
		if ((buffer.Count()%3)!=0) ++len;
		len*=4;

		//	This will be converted to
		//	a string and then returned
		Vector<CodePoint> cps(static_cast<Word>(len));

		auto begin=buffer.begin();
		auto end=buffer.end();

		//	Iterate over entire input
		//	buffer
		while (begin!=end) {

			//	We need 24 bits for 4 base 64
			//	characters, they'll be stored
			//	in here
			UInt32 build=0;
			//	Keep track of the number of significant
			//	bytes for padding purposes
			Word significant=0;
			//	Extract 3 bytes (24 bits)
			for (Word i=0;i<3;++i) {

				//	Make room for the next byte
				build<<=BitsPerByte();

				//	Only add the next byte if
				//	there's a byte to extract
				if (begin!=end) {

					build|=*begin;

					//	Advance buffer pointer
					++begin;
					//	A byte from the buffer
					//	is significant
					++significant;

				}

			}

			Word printed=0;
			//	Print base 64 characters
			for (;printed<(significant+1);++printed) cps.Add(static_cast<CodePoint>(encode[(build>>(6*(3-printed)))&63]));
			//	Print padding (if necessary)
			for (;printed<4;++printed) cps.Add(static_cast<CodePoint>(pad));

		}

		return String(std::move(cps));

	}

}
<|endoftext|>


<commit_before>/*
 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 * This code has been modified under the terms listed below and is made
 * available under the same terms.
 */

/*
 *	Copyright (c) 1990-1994 The Regents of the University of California.
 *	Copyright (c) 1994-1997 Sun Microsystems, Inc.
 *
 *	See the file "license.terms" for information on usage and redistribution
 *	of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 *	Copyright 2003-2004 George A Howlett.
 *
 *	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 <stdarg.h>

extern "C" {
#include "bltInt.h"
#include "bltConfig.h"
};

// State
const char* stateObjOption[] = {"normal", "active", "disabled", NULL};

// Point
static Tk_CustomOptionSetProc PointSetProc;
static Tk_CustomOptionGetProc PointGetProc;
Tk_ObjCustomOption pointObjOption =
  {
    "point", PointSetProc, PointGetProc, NULL, NULL, NULL
  };

static int PointSetProc(ClientData clientData, Tcl_Interp *interp,
			Tk_Window tkwin, Tcl_Obj** objPtr, char* widgRec,
			int offset, char* save, int flags)
{
  XPoint* pointPtr = (XPoint*)(widgRec + offset);
  int x, y;

  if (Blt_GetXY(interp, tkwin, Tcl_GetString(*objPtr), &x, &y) != TCL_OK)
    return TCL_ERROR;

  pointPtr->x = x;
  pointPtr->y = y;

  return TCL_OK;
};

static Tcl_Obj* PointGetProc(ClientData clientData, Tk_Window tkwin,
			     char *widgRec, int offset)
{
  XPoint* pointPtr = (XPoint*)(widgRec + offset);

  if ((pointPtr->x != -SHRT_MAX) && (pointPtr->y != -SHRT_MAX)) {
    char string[200];
    sprintf_s(string, 200, "@%d,%d", pointPtr->x, pointPtr->y);
    return Tcl_NewStringObj(string, -1);
  }
  else
    return Tcl_NewStringObj("", -1);
};

// Dashes
static Tk_CustomOptionSetProc DashesSetProc;
static Tk_CustomOptionGetProc DashesGetProc;
Tk_ObjCustomOption dashesObjOption =
  {
    "dashes", DashesSetProc, DashesGetProc, NULL, NULL, NULL
  };

static int DashesSetProc(ClientData clientData, Tcl_Interp *interp,
			 Tk_Window tkwin, Tcl_Obj** objPtr, char* widgRec,
			 int offset, char* save, int flags)
{
  Blt_Dashes* dashesPtr = (Blt_Dashes*)(widgRec + offset);

  int length;
  const char* string = Tcl_GetStringFromObj(*objPtr, &length);
  if (!string) {
    dashesPtr->values[0] = 0;
    return TCL_OK;
  }

  if (!string[0])
    dashesPtr->values[0] = 0;
  else if (!strncmp(string, "dot", length)) {
    /* 1 */
    dashesPtr->values[0] = 1;
    dashesPtr->values[1] = 0;
  }
  else if (!strncmp(string, "dash", length)) {
    /* 5 2 */
    dashesPtr->values[0] = 5;
    dashesPtr->values[1] = 2;
    dashesPtr->values[2] = 0;
  }
  else if (!strncmp(string, "dashdot", length)) {
    /* 2 4 2 */
    dashesPtr->values[0] = 2;
    dashesPtr->values[1] = 4;
    dashesPtr->values[2] = 2;
    dashesPtr->values[3] = 0;
  }
  else if (!strncmp(string, "dashdotdot", length)) {
    /* 2 4 2 2 */
    dashesPtr->values[0] = 2;
    dashesPtr->values[1] = 4;
    dashesPtr->values[2] = 2;
    dashesPtr->values[3] = 2;
    dashesPtr->values[4] = 0;
  }
  else {
    int objc;
    Tcl_Obj** objv;
    if (Tcl_ListObjGetElements(interp, *objPtr, &objc, &objv) != TCL_OK)
      return TCL_ERROR;

    if (objc > 11) {	/* This is the postscript limit */
      Tcl_AppendResult(interp, "too many values in dash list \"",
		       string, "\"", (char *)NULL);
      return TCL_ERROR;
    }

    int ii;
    for (ii=0; ii<objc; ii++) {
      int value;
      if (Tcl_GetIntFromObj(interp, objv[ii], &value) != TCL_OK)
	return TCL_ERROR;

      /*
       * Backward compatibility:
       * Allow list of 0 to turn off dashes
       */
      if ((value == 0) && (objc == 1))
	break;

      if ((value < 1) || (value > 255)) {
	Tcl_AppendResult(interp, "dash value \"",
			 Tcl_GetString(objv[ii]), "\" is out of range",
			 (char *)NULL);
	return TCL_ERROR;
      }
      dashesPtr->values[ii] = (unsigned char)value;
    }

    // Make sure the array ends with a NUL byte
    dashesPtr->values[ii] = 0;
  }

  return TCL_OK;
};

static Tcl_Obj* DashesGetProc(ClientData clientData, Tk_Window tkwin,
			     char *widgRec, int offset)
{
  Blt_Dashes* dashesPtr = (Blt_Dashes*)(widgRec + offset);

  // count how many
  int cnt =0;
  while (dashesPtr->values[cnt])
    cnt++;

  if (!cnt)
    return Tcl_NewListObj(0, (Tcl_Obj**)NULL);

  Tcl_Obj** ll = (Tcl_Obj**)calloc(cnt, sizeof(Tcl_Obj*));
  for (int ii=0; ii<cnt; ii++)
    ll[ii] = Tcl_NewIntObj(dashesPtr->values[ii]);
  Tcl_Obj* listObjPtr = Tcl_NewListObj(cnt, ll);
  free(ll);

  return listObjPtr;
};

// List
static Tk_CustomOptionSetProc ListSetProc;
static Tk_CustomOptionGetProc ListGetProc;
Tk_ObjCustomOption listObjOption =
  {
    "list", ListSetProc, ListGetProc, NULL, NULL, NULL
  };

static int ListSetProc(ClientData clientData, Tcl_Interp *interp,
		       Tk_Window tkwin, Tcl_Obj** objPtr, char* widgRec,
		       int offset, char* save, int flags)
{
  const char*** listPtr = (const char***)(widgRec + offset);

  const char** argv;
  int argc;
  if (Tcl_SplitList(interp, Tcl_GetString(*objPtr), &argc, &argv) != TCL_OK)
    return TCL_ERROR;

  if (*listPtr) {
    Tcl_Free(*(char**)listPtr);
    *listPtr = NULL;
  }
  *listPtr = argv;

  return TCL_OK;
};

static Tcl_Obj* ListGetProc(ClientData clientData, Tk_Window tkwin,
			    char *widgRec, int offset)
{
  const char*** listPtr = (const char***)(widgRec + offset);

  // count how many
  int cnt=0;
  for (const char** p = *listPtr; *p != NULL; p++,cnt++) {}
  if (!cnt)
    return Tcl_NewListObj(0, (Tcl_Obj**)NULL);

  Tcl_Obj** ll = (Tcl_Obj**)calloc(cnt, sizeof(Tcl_Obj*));
  for (int ii=0; ii<cnt; ii++)
    ll[ii] = Tcl_NewStringObj(*listPtr[ii], -1);
  Tcl_Obj* listObjPtr = Tcl_NewListObj(cnt, ll);
  free(ll);

  return listObjPtr;
};
<commit_msg>*** empty log message ***<commit_after>/*
 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 * This code has been modified under the terms listed below and is made
 * available under the same terms.
 */

/*
 *	Copyright (c) 1990-1994 The Regents of the University of California.
 *	Copyright (c) 1994-1997 Sun Microsystems, Inc.
 *
 *	See the file "license.terms" for information on usage and redistribution
 *	of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 *	Copyright 2003-2004 George A Howlett.
 *
 *	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 <stdarg.h>

extern "C" {
#include "bltInt.h"
#include "bltConfig.h"
};

// State
const char* stateObjOption[] = {"normal", "active", "disabled", NULL};

// Point
static Tk_CustomOptionSetProc PointSetProc;
static Tk_CustomOptionGetProc PointGetProc;
Tk_ObjCustomOption pointObjOption =
  {
    "point", PointSetProc, PointGetProc, NULL, NULL, NULL
  };

static int PointSetProc(ClientData clientData, Tcl_Interp *interp,
			Tk_Window tkwin, Tcl_Obj** objPtr, char* widgRec,
			int offset, char* save, int flags)
{
  XPoint* pointPtr = (XPoint*)(widgRec + offset);
  int x, y;

  if (Blt_GetXY(interp, tkwin, Tcl_GetString(*objPtr), &x, &y) != TCL_OK)
    return TCL_ERROR;

  pointPtr->x = x;
  pointPtr->y = y;

  return TCL_OK;
};

static Tcl_Obj* PointGetProc(ClientData clientData, Tk_Window tkwin,
			     char *widgRec, int offset)
{
  XPoint* pointPtr = (XPoint*)(widgRec + offset);

  if ((pointPtr->x != -SHRT_MAX) && (pointPtr->y != -SHRT_MAX)) {
    char string[200];
    sprintf_s(string, 200, "@%d,%d", pointPtr->x, pointPtr->y);
    return Tcl_NewStringObj(string, -1);
  }
  else
    return Tcl_NewStringObj("", -1);
};

// Dashes
static Tk_CustomOptionSetProc DashesSetProc;
static Tk_CustomOptionGetProc DashesGetProc;
Tk_ObjCustomOption dashesObjOption =
  {
    "dashes", DashesSetProc, DashesGetProc, NULL, NULL, NULL
  };

static int DashesSetProc(ClientData clientData, Tcl_Interp *interp,
			 Tk_Window tkwin, Tcl_Obj** objPtr, char* widgRec,
			 int offset, char* save, int flags)
{
  Blt_Dashes* dashesPtr = (Blt_Dashes*)(widgRec + offset);

  int length;
  const char* string = Tcl_GetStringFromObj(*objPtr, &length);
  if (!string) {
    dashesPtr->values[0] = 0;
    return TCL_OK;
  }

  if (!string[0])
    dashesPtr->values[0] = 0;
  else if (!strncmp(string, "dot", length)) {
    /* 1 */
    dashesPtr->values[0] = 1;
    dashesPtr->values[1] = 0;
  }
  else if (!strncmp(string, "dash", length)) {
    /* 5 2 */
    dashesPtr->values[0] = 5;
    dashesPtr->values[1] = 2;
    dashesPtr->values[2] = 0;
  }
  else if (!strncmp(string, "dashdot", length)) {
    /* 2 4 2 */
    dashesPtr->values[0] = 2;
    dashesPtr->values[1] = 4;
    dashesPtr->values[2] = 2;
    dashesPtr->values[3] = 0;
  }
  else if (!strncmp(string, "dashdotdot", length)) {
    /* 2 4 2 2 */
    dashesPtr->values[0] = 2;
    dashesPtr->values[1] = 4;
    dashesPtr->values[2] = 2;
    dashesPtr->values[3] = 2;
    dashesPtr->values[4] = 0;
  }
  else {
    int objc;
    Tcl_Obj** objv;
    if (Tcl_ListObjGetElements(interp, *objPtr, &objc, &objv) != TCL_OK)
      return TCL_ERROR;

    if (objc > 11) {	/* This is the postscript limit */
      Tcl_AppendResult(interp, "too many values in dash list \"",
		       string, "\"", (char *)NULL);
      return TCL_ERROR;
    }

    int ii;
    for (ii=0; ii<objc; ii++) {
      int value;
      if (Tcl_GetIntFromObj(interp, objv[ii], &value) != TCL_OK)
	return TCL_ERROR;

      /*
       * Backward compatibility:
       * Allow list of 0 to turn off dashes
       */
      if ((value == 0) && (objc == 1))
	break;

      if ((value < 1) || (value > 255)) {
	Tcl_AppendResult(interp, "dash value \"",
			 Tcl_GetString(objv[ii]), "\" is out of range",
			 (char *)NULL);
	return TCL_ERROR;
      }
      dashesPtr->values[ii] = (unsigned char)value;
    }

    // Make sure the array ends with a NUL byte
    dashesPtr->values[ii] = 0;
  }

  return TCL_OK;
};

static Tcl_Obj* DashesGetProc(ClientData clientData, Tk_Window tkwin,
			     char *widgRec, int offset)
{
  Blt_Dashes* dashesPtr = (Blt_Dashes*)(widgRec + offset);

  // count how many
  int cnt =0;
  while (dashesPtr->values[cnt])
    cnt++;

  if (!cnt)
    return Tcl_NewListObj(0, (Tcl_Obj**)NULL);

  Tcl_Obj** ll = (Tcl_Obj**)calloc(cnt, sizeof(Tcl_Obj*));
  for (int ii=0; ii<cnt; ii++)
    ll[ii] = Tcl_NewIntObj(dashesPtr->values[ii]);
  Tcl_Obj* listObjPtr = Tcl_NewListObj(cnt, ll);
  free(ll);

  return listObjPtr;
};

// List
static Tk_CustomOptionSetProc ListSetProc;
static Tk_CustomOptionGetProc ListGetProc;
static Tk_CustomOptionRestoreProc ListRestoreProc;
static Tk_CustomOptionFreeProc ListFreeProc;
Tk_ObjCustomOption listObjOption =
  {
    "list", ListSetProc, ListGetProc, ListRestoreProc, ListFreeProc, NULL
  };

static int ListSetProc(ClientData clientData, Tcl_Interp *interp,
		       Tk_Window tkwin, Tcl_Obj** objPtr, char* widgRec,
		       int offset, char* savePtr, int flags)
{
  const char*** listPtr = (const char***)(widgRec + offset);
  *(double*)savePtr = *(double*)listPtr;

  const char** argv;
  int argc;
  if (Tcl_SplitList(interp, Tcl_GetString(*objPtr), &argc, &argv) != TCL_OK)
    return TCL_ERROR;

  *listPtr = argv;

  return TCL_OK;
};

static Tcl_Obj* ListGetProc(ClientData clientData, Tk_Window tkwin,
			    char *widgRec, int offset)
{
  const char*** listPtr = (const char***)(widgRec + offset);

  // count how many
  int cnt=0;
  for (const char** p = *listPtr; *p != NULL; p++,cnt++) {}
  if (!cnt)
    return Tcl_NewListObj(0, (Tcl_Obj**)NULL);

  Tcl_Obj** ll = (Tcl_Obj**)calloc(cnt, sizeof(Tcl_Obj*));
  for (int ii=0; ii<cnt; ii++)
    ll[ii] = Tcl_NewStringObj(*listPtr[ii], -1);
  Tcl_Obj* listObjPtr = Tcl_NewListObj(cnt, ll);
  free(ll);

  return listObjPtr;
};

static void ListRestoreProc(ClientData clientData, Tk_Window tkwin,
			    char *ptr, char *savePtr)
{
  *(double*)ptr = *(double*)savePtr;
}

static void ListFreeProc(ClientData clientData, Tk_Window tkwin,
			 char *ptr)
{
  const char** argv = *(const char***)ptr;
  if (argv)
    Tcl_Free((char*)argv);
}

<|endoftext|>


<commit_before>/*
 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 * This code has been modified under the terms listed below and is made
 * available under the same terms.
 */

/*
 *	Copyright 1998 George A Howlett.
 *
 *	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 <stdlib.h>

#include <iostream>
#include <sstream>
#include <iomanip>
using namespace std;

#include "bltGrBind.h"

static Tk_EventProc BindProc;
typedef struct _Blt_BindTable BindTable;

#define REPICK_IN_PROGRESS (1<<0)
#define LEFT_GRABBED_ITEM  (1<<1)

static void BltDoEvent(BindTable* bindPtr, XEvent* eventPtr,
		       ClientData item, ClientData context)
{
  if (!bindPtr->tkwin || !bindPtr->bindingTable)
    return;

  if ((eventPtr->type == KeyPress) || (eventPtr->type == KeyRelease)) {
    item = bindPtr->focusItem;
    context = bindPtr->focusContext;
  }
  if (!item)
    return;

  int nTags;
  const char** tagArray = (*bindPtr->tagProc)(bindPtr, item, context, &nTags);
  Tk_BindEvent(bindPtr->bindingTable, eventPtr, bindPtr->tkwin, nTags,
	       (void**)tagArray);

  if (tagArray)
    delete [] tagArray;
}

static void PickCurrentItem(BindTable *bindPtr,	XEvent *eventPtr)
{
  // Check whether or not a button is down.  If so, we'll log entry and exit
  // into and out of the current item, but not entry into any other item.
  // This implements a form of grabbing equivalent to what the X server does
  // for windows.

  int buttonDown = (bindPtr->state & (Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask));
  if (!buttonDown)
    bindPtr->flags &= ~LEFT_GRABBED_ITEM;

  // Save information about this event in the widget.  The event in the
  // widget is used for two purposes:
  // 1. Event bindings: if the current item changes, fake events are
  //    generated to allow item-enter and item-leave bindings to trigger.
  // 2. Reselection: if the current item gets deleted, can use the
  //    saved event to find a new current item.
  // Translate MotionNotify events into EnterNotify events, since that's
  // what gets reported to item handlers.

  if (eventPtr != &bindPtr->pickEvent) {
    if ((eventPtr->type == MotionNotify) || (eventPtr->type == ButtonRelease)) {
      bindPtr->pickEvent.xcrossing.type = EnterNotify;
      bindPtr->pickEvent.xcrossing.serial = eventPtr->xmotion.serial;
      bindPtr->pickEvent.xcrossing.send_event =	eventPtr->xmotion.send_event;
      bindPtr->pickEvent.xcrossing.display = eventPtr->xmotion.display;
      bindPtr->pickEvent.xcrossing.window = eventPtr->xmotion.window;
      bindPtr->pickEvent.xcrossing.root = eventPtr->xmotion.root;
      bindPtr->pickEvent.xcrossing.subwindow = None;
      bindPtr->pickEvent.xcrossing.time = eventPtr->xmotion.time;
      bindPtr->pickEvent.xcrossing.x = eventPtr->xmotion.x;
      bindPtr->pickEvent.xcrossing.y = eventPtr->xmotion.y;
      bindPtr->pickEvent.xcrossing.x_root = eventPtr->xmotion.x_root;
      bindPtr->pickEvent.xcrossing.y_root = eventPtr->xmotion.y_root;
      bindPtr->pickEvent.xcrossing.mode = NotifyNormal;
      bindPtr->pickEvent.xcrossing.detail = NotifyNonlinear;
      bindPtr->pickEvent.xcrossing.same_screen = eventPtr->xmotion.same_screen;
      bindPtr->pickEvent.xcrossing.focus = False;
      bindPtr->pickEvent.xcrossing.state = eventPtr->xmotion.state;
    }
    else
      bindPtr->pickEvent = *eventPtr;

  }
  bindPtr->activePick = 1;

  // If this is a recursive call (there's already a partially completed call
  // pending on the stack; it's in the middle of processing a Leave event
  // handler for the old current item) then just return; the pending call
  // will do everything that's needed.
  if (bindPtr->flags & REPICK_IN_PROGRESS)
    return;

  // A LeaveNotify event automatically means that there's no current item,
  // so the check for closest item can be skipped.
  ClientData newContext =NULL;
  ClientData newItem =NULL;
  if (bindPtr->pickEvent.type != LeaveNotify) {
    int x = bindPtr->pickEvent.xcrossing.x;
    int y = bindPtr->pickEvent.xcrossing.y;
    newItem = (*bindPtr->pickProc)(bindPtr->clientData, x, y, &newContext);
  }

  // Nothing to do:  the current item hasn't changed.
  if (((newItem == bindPtr->currentItem) && (newContext == bindPtr->currentContext)) && ((bindPtr->flags & LEFT_GRABBED_ITEM) == 0))
    return;

  // Simulate a LeaveNotify event on the previous current item and an
  // EnterNotify event on the new current item.  Remove the "current" tag
  // from the previous current item and place it on the new current item.
  ClientData oldItem = bindPtr->currentItem;
  Tcl_Preserve(oldItem);
  Tcl_Preserve(newItem);

  if ((bindPtr->currentItem != NULL) && ((newItem != bindPtr->currentItem) || (newContext != bindPtr->currentContext)) && ((bindPtr->flags & LEFT_GRABBED_ITEM) == 0)) {
    XEvent event = bindPtr->pickEvent;
    event.type = LeaveNotify;

    // If the event's detail happens to be NotifyInferior the binding
    // mechanism will discard the event.  To be consistent, always use
    // NotifyAncestor.
    event.xcrossing.detail = NotifyAncestor;

    bindPtr->flags |= REPICK_IN_PROGRESS;
    BltDoEvent(bindPtr, &event, bindPtr->currentItem, bindPtr->currentContext);
    bindPtr->flags &= ~REPICK_IN_PROGRESS;

    // Note: during DoEvent above, it's possible that bindPtr->newItem got
    // reset to NULL because the item was deleted.
  }

  if (((newItem != bindPtr->currentItem) || (newContext != bindPtr->currentContext)) && (buttonDown)) {
    bindPtr->flags |= LEFT_GRABBED_ITEM;
    XEvent event = bindPtr->pickEvent;
    if ((newItem != bindPtr->newItem) ||
	(newContext != bindPtr->newContext)) {

      // Generate <Enter> and <Leave> events for objects during button
      // grabs. This isn't standard. But for example, it allows one to
      // provide balloon help on the individual entries of the Hierbox
      // widget.
      ClientData savedItem = bindPtr->currentItem;
      ClientData savedContext = bindPtr->currentContext;
      if (bindPtr->newItem != NULL) {
	event.type = LeaveNotify;
	event.xcrossing.detail = NotifyVirtual; // Ancestor
	bindPtr->currentItem = bindPtr->newItem;
	BltDoEvent(bindPtr, &event, bindPtr->newItem, bindPtr->newContext);
      }

      bindPtr->newItem = newItem;
      bindPtr->newContext = newContext;
      if (newItem != NULL) {
	event.type = EnterNotify;
	event.xcrossing.detail = NotifyVirtual; // Ancestor
	bindPtr->currentItem = newItem;
	BltDoEvent(bindPtr, &event, newItem, newContext);
      }

      bindPtr->currentItem = savedItem;
      bindPtr->currentContext = savedContext;
    }
    goto done;
  }

  // Special note:  it's possible that bindPtr->newItem == bindPtr->currentItem
  // here. This can happen, for example, if LEFT_GRABBED_ITEM was set.
  bindPtr->flags &= ~LEFT_GRABBED_ITEM;
  bindPtr->currentItem = bindPtr->newItem = newItem;
  bindPtr->currentContext = bindPtr->newContext = newContext;
  if (bindPtr->currentItem != NULL) {
    XEvent event;
    event = bindPtr->pickEvent;
    event.type = EnterNotify;
    event.xcrossing.detail = NotifyAncestor;
    BltDoEvent(bindPtr, &event, newItem, newContext);
  }

 done:
  Tcl_Release(newItem);
  Tcl_Release(oldItem);
}

static void BindProc(ClientData clientData, XEvent *eventPtr)
{
  // This code below keeps track of the current modifier state in
  // bindPtr->state.  This information is used to defer repicks of the
  // current item while buttons are down.

  BindTable *bindPtr = (BindTable*)clientData;

  Tcl_Preserve(bindPtr->clientData);

  switch (eventPtr->type) {
  case ButtonPress:
  case ButtonRelease:
    {
      int mask = 0;
      switch (eventPtr->xbutton.button) {
      case Button1:
	mask = Button1Mask;
	break;
      case Button2:
	mask = Button2Mask;
	break;
      case Button3:
	mask = Button3Mask;
	break;
      case Button4:
	mask = Button4Mask;
	break;
      case Button5:
	mask = Button5Mask;
	break;
      default:
	break;
      }

      // For button press events, repick the current item using the button
      // state before the event, then process the event.  For button release
      // events, first process the event, then repick the current item using
      // the button state *after* the event (the button has logically gone
      // up before we change the current item).

      if (eventPtr->type == ButtonPress) {

	// On a button press, first repick the current item using the
	// button state before the event, the process the event.
	bindPtr->state = eventPtr->xbutton.state;
	PickCurrentItem(bindPtr, eventPtr);
	bindPtr->state ^= mask;
	BltDoEvent(bindPtr, eventPtr, bindPtr->currentItem,
		   bindPtr->currentContext);
      }
      else {

	// Button release: first process the event, with the button still
	// considered to be down.  Then repick the current item under the
	// assumption that the button is no longer down.
	bindPtr->state = eventPtr->xbutton.state;
	BltDoEvent(bindPtr, eventPtr, bindPtr->currentItem,
		   bindPtr->currentContext);
	eventPtr->xbutton.state ^= mask;
	bindPtr->state = eventPtr->xbutton.state;
	PickCurrentItem(bindPtr, eventPtr);
	eventPtr->xbutton.state ^= mask;
      }
    }
    break;

  case EnterNotify:
  case LeaveNotify:
    bindPtr->state = eventPtr->xcrossing.state;
    PickCurrentItem(bindPtr, eventPtr);
    break;

  case MotionNotify:
    bindPtr->state = eventPtr->xmotion.state;
    PickCurrentItem(bindPtr, eventPtr);
    BltDoEvent(bindPtr, eventPtr, bindPtr->currentItem,
	       bindPtr->currentContext);
    break;

  case KeyPress:
  case KeyRelease:
    bindPtr->state = eventPtr->xkey.state;
    PickCurrentItem(bindPtr, eventPtr);
    BltDoEvent(bindPtr, eventPtr, bindPtr->currentItem,
	       bindPtr->currentContext);
    break;
  }

  Tcl_Release(bindPtr->clientData);
}

int Blt_ConfigureBindingsFromObj(Tcl_Interp* interp, BindTable *bindPtr,
				 ClientData item, int objc,
				 Tcl_Obj* const objv[])
{
  if (objc == 0) {
    Tk_GetAllBindings(interp, bindPtr->bindingTable, item);
    return TCL_OK;
  }

  const char *string = Tcl_GetString(objv[0]);
  if (objc == 1) {
    const char* command =
      Tk_GetBinding(interp, bindPtr->bindingTable, item, string);
    if (!command) {
      Tcl_ResetResult(interp);
      Tcl_AppendResult(interp, "invalid binding event \"", string, "\"", NULL);
      return TCL_ERROR;
    }
    Tcl_SetStringObj(Tcl_GetObjResult(interp), command, -1);
    return TCL_OK;
  }

  const char *seq = string;
  const char* command = Tcl_GetString(objv[1]);
  if (command[0] == '\0')
    return Tk_DeleteBinding(interp, bindPtr->bindingTable, item, seq);

  unsigned long mask;
  if (command[0] == '+')
    mask = Tk_CreateBinding(interp, bindPtr->bindingTable, item, seq,
			    command+1, 1);
  else
    mask = Tk_CreateBinding(interp, bindPtr->bindingTable, item, seq,
			    command, 0);
  if (!mask)
    return TCL_ERROR;

  if (mask & (unsigned) ~(ButtonMotionMask|Button1MotionMask
			  |Button2MotionMask|Button3MotionMask|Button4MotionMask
			  |Button5MotionMask|ButtonPressMask|ButtonReleaseMask
			  |EnterWindowMask|LeaveWindowMask|KeyPressMask
			  |KeyReleaseMask|PointerMotionMask|VirtualEventMask)) {
    Tk_DeleteBinding(interp, bindPtr->bindingTable, item, seq);
    Tcl_ResetResult(interp);
    Tcl_AppendResult(interp, "requested illegal events; ",
		     "only key, button, motion, enter, leave, and virtual ",
		     "events may be used", (char *)NULL);
    return TCL_ERROR;
  }

  return TCL_OK;
}

Blt_BindTable Blt_CreateBindingTable(Tcl_Interp* interp, Tk_Window tkwin,
				     ClientData clientData,
				     Blt_BindPickProc *pickProc,
				     Blt_BindTagProc *tagProc)
{
  BindTable *bindPtr = (BindTable*)calloc(1, sizeof(BindTable));
  bindPtr->bindingTable = Tk_CreateBindingTable(interp);
  bindPtr->clientData = clientData;
  bindPtr->tkwin = tkwin;
  bindPtr->pickProc = pickProc;
  bindPtr->tagProc = tagProc;
  unsigned int mask = (KeyPressMask | KeyReleaseMask | ButtonPressMask |
		       ButtonReleaseMask | EnterWindowMask | LeaveWindowMask |
		       PointerMotionMask);
  Tk_CreateEventHandler(tkwin, mask, BindProc, bindPtr);

  return bindPtr;
}

void Blt_DestroyBindingTable(BindTable *bindPtr)
{
  Tk_DeleteBindingTable(bindPtr->bindingTable);
  unsigned int mask = (KeyPressMask | KeyReleaseMask | ButtonPressMask |
		       ButtonReleaseMask | EnterWindowMask | LeaveWindowMask |
		       PointerMotionMask);
  Tk_DeleteEventHandler(bindPtr->tkwin, mask, BindProc, bindPtr);

  free(bindPtr);
  bindPtr = NULL;
}

void Blt_DeleteBindings(BindTable *bindPtr, ClientData object)
{
  Tk_DeleteAllBindings(bindPtr->bindingTable, object);

  // If this is the object currently picked, we need to repick one.
  if (bindPtr->currentItem == object) {
    bindPtr->currentItem = NULL;
    bindPtr->currentContext = NULL;
  }

  if (bindPtr->newItem == object) {
    bindPtr->newItem = NULL;
    bindPtr->newContext = NULL;
  }

  if (bindPtr->focusItem == object) {
    bindPtr->focusItem = NULL;
    bindPtr->focusContext = NULL;
  }
}
<commit_msg>*** empty log message ***<commit_after>/*
 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 * This code has been modified under the terms listed below and is made
 * available under the same terms.
 */

/*
 *	Copyright 1998 George A Howlett.
 *
 *	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 <stdlib.h>

#include <iostream>
#include <sstream>
#include <iomanip>
using namespace std;

#include "bltGrBind.h"

static Tk_EventProc BindProc;

#define REPICK_IN_PROGRESS (1<<0)
#define LEFT_GRABBED_ITEM  (1<<1)

static void BltDoEvent(Blt_BindTable bindPtr, XEvent* eventPtr,
		       ClientData item, ClientData context)
{
  if (!bindPtr->tkwin || !bindPtr->bindingTable)
    return;

  if ((eventPtr->type == KeyPress) || (eventPtr->type == KeyRelease)) {
    item = bindPtr->focusItem;
    context = bindPtr->focusContext;
  }
  if (!item)
    return;

  int nTags;
  const char** tagArray = (*bindPtr->tagProc)(bindPtr, item, context, &nTags);
  Tk_BindEvent(bindPtr->bindingTable, eventPtr, bindPtr->tkwin, nTags,
	       (void**)tagArray);

  if (tagArray)
    delete [] tagArray;
}

static void PickCurrentItem(Blt_BindTable bindPtr, XEvent *eventPtr)
{
  // Check whether or not a button is down.  If so, we'll log entry and exit
  // into and out of the current item, but not entry into any other item.
  // This implements a form of grabbing equivalent to what the X server does
  // for windows.

  int buttonDown = (bindPtr->state & (Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask));
  if (!buttonDown)
    bindPtr->flags &= ~LEFT_GRABBED_ITEM;

  // Save information about this event in the widget.  The event in the
  // widget is used for two purposes:
  // 1. Event bindings: if the current item changes, fake events are
  //    generated to allow item-enter and item-leave bindings to trigger.
  // 2. Reselection: if the current item gets deleted, can use the
  //    saved event to find a new current item.
  // Translate MotionNotify events into EnterNotify events, since that's
  // what gets reported to item handlers.

  if (eventPtr != &bindPtr->pickEvent) {
    if ((eventPtr->type == MotionNotify) || (eventPtr->type == ButtonRelease)) {
      bindPtr->pickEvent.xcrossing.type = EnterNotify;
      bindPtr->pickEvent.xcrossing.serial = eventPtr->xmotion.serial;
      bindPtr->pickEvent.xcrossing.send_event =	eventPtr->xmotion.send_event;
      bindPtr->pickEvent.xcrossing.display = eventPtr->xmotion.display;
      bindPtr->pickEvent.xcrossing.window = eventPtr->xmotion.window;
      bindPtr->pickEvent.xcrossing.root = eventPtr->xmotion.root;
      bindPtr->pickEvent.xcrossing.subwindow = None;
      bindPtr->pickEvent.xcrossing.time = eventPtr->xmotion.time;
      bindPtr->pickEvent.xcrossing.x = eventPtr->xmotion.x;
      bindPtr->pickEvent.xcrossing.y = eventPtr->xmotion.y;
      bindPtr->pickEvent.xcrossing.x_root = eventPtr->xmotion.x_root;
      bindPtr->pickEvent.xcrossing.y_root = eventPtr->xmotion.y_root;
      bindPtr->pickEvent.xcrossing.mode = NotifyNormal;
      bindPtr->pickEvent.xcrossing.detail = NotifyNonlinear;
      bindPtr->pickEvent.xcrossing.same_screen = eventPtr->xmotion.same_screen;
      bindPtr->pickEvent.xcrossing.focus = False;
      bindPtr->pickEvent.xcrossing.state = eventPtr->xmotion.state;
    }
    else
      bindPtr->pickEvent = *eventPtr;

  }
  bindPtr->activePick = 1;

  // If this is a recursive call (there's already a partially completed call
  // pending on the stack; it's in the middle of processing a Leave event
  // handler for the old current item) then just return; the pending call
  // will do everything that's needed.
  if (bindPtr->flags & REPICK_IN_PROGRESS)
    return;

  // A LeaveNotify event automatically means that there's no current item,
  // so the check for closest item can be skipped.
  ClientData newContext =NULL;
  ClientData newItem =NULL;
  if (bindPtr->pickEvent.type != LeaveNotify) {
    int x = bindPtr->pickEvent.xcrossing.x;
    int y = bindPtr->pickEvent.xcrossing.y;
    newItem = (*bindPtr->pickProc)(bindPtr->clientData, x, y, &newContext);
  }

  // Nothing to do:  the current item hasn't changed.
  if (((newItem == bindPtr->currentItem) && (newContext == bindPtr->currentContext)) && ((bindPtr->flags & LEFT_GRABBED_ITEM) == 0))
    return;

  // Simulate a LeaveNotify event on the previous current item and an
  // EnterNotify event on the new current item.  Remove the "current" tag
  // from the previous current item and place it on the new current item.
  ClientData oldItem = bindPtr->currentItem;
  Tcl_Preserve(oldItem);
  Tcl_Preserve(newItem);

  if ((bindPtr->currentItem != NULL) && ((newItem != bindPtr->currentItem) || (newContext != bindPtr->currentContext)) && ((bindPtr->flags & LEFT_GRABBED_ITEM) == 0)) {
    XEvent event = bindPtr->pickEvent;
    event.type = LeaveNotify;

    // If the event's detail happens to be NotifyInferior the binding
    // mechanism will discard the event.  To be consistent, always use
    // NotifyAncestor.
    event.xcrossing.detail = NotifyAncestor;

    bindPtr->flags |= REPICK_IN_PROGRESS;
    BltDoEvent(bindPtr, &event, bindPtr->currentItem, bindPtr->currentContext);
    bindPtr->flags &= ~REPICK_IN_PROGRESS;

    // Note: during DoEvent above, it's possible that bindPtr->newItem got
    // reset to NULL because the item was deleted.
  }

  if (((newItem != bindPtr->currentItem) || (newContext != bindPtr->currentContext)) && (buttonDown)) {
    bindPtr->flags |= LEFT_GRABBED_ITEM;
    XEvent event = bindPtr->pickEvent;
    if ((newItem != bindPtr->newItem) ||
	(newContext != bindPtr->newContext)) {

      // Generate <Enter> and <Leave> events for objects during button
      // grabs. This isn't standard. But for example, it allows one to
      // provide balloon help on the individual entries of the Hierbox
      // widget.
      ClientData savedItem = bindPtr->currentItem;
      ClientData savedContext = bindPtr->currentContext;
      if (bindPtr->newItem != NULL) {
	event.type = LeaveNotify;
	event.xcrossing.detail = NotifyVirtual; // Ancestor
	bindPtr->currentItem = bindPtr->newItem;
	BltDoEvent(bindPtr, &event, bindPtr->newItem, bindPtr->newContext);
      }

      bindPtr->newItem = newItem;
      bindPtr->newContext = newContext;
      if (newItem != NULL) {
	event.type = EnterNotify;
	event.xcrossing.detail = NotifyVirtual; // Ancestor
	bindPtr->currentItem = newItem;
	BltDoEvent(bindPtr, &event, newItem, newContext);
      }

      bindPtr->currentItem = savedItem;
      bindPtr->currentContext = savedContext;
    }
    goto done;
  }

  // Special note:  it's possible that bindPtr->newItem == bindPtr->currentItem
  // here. This can happen, for example, if LEFT_GRABBED_ITEM was set.
  bindPtr->flags &= ~LEFT_GRABBED_ITEM;
  bindPtr->currentItem = bindPtr->newItem = newItem;
  bindPtr->currentContext = bindPtr->newContext = newContext;
  if (bindPtr->currentItem != NULL) {
    XEvent event;
    event = bindPtr->pickEvent;
    event.type = EnterNotify;
    event.xcrossing.detail = NotifyAncestor;
    BltDoEvent(bindPtr, &event, newItem, newContext);
  }

 done:
  Tcl_Release(newItem);
  Tcl_Release(oldItem);
}

static void BindProc(ClientData clientData, XEvent *eventPtr)
{
  // This code below keeps track of the current modifier state in
  // bindPtr->state.  This information is used to defer repicks of the
  // current item while buttons are down.

  Blt_BindTable bindPtr = (Blt_BindTable)clientData;

  Tcl_Preserve(bindPtr->clientData);

  switch (eventPtr->type) {
  case ButtonPress:
  case ButtonRelease:
    {
      int mask = 0;
      switch (eventPtr->xbutton.button) {
      case Button1:
	mask = Button1Mask;
	break;
      case Button2:
	mask = Button2Mask;
	break;
      case Button3:
	mask = Button3Mask;
	break;
      case Button4:
	mask = Button4Mask;
	break;
      case Button5:
	mask = Button5Mask;
	break;
      default:
	break;
      }

      // For button press events, repick the current item using the button
      // state before the event, then process the event.  For button release
      // events, first process the event, then repick the current item using
      // the button state *after* the event (the button has logically gone
      // up before we change the current item).

      if (eventPtr->type == ButtonPress) {

	// On a button press, first repick the current item using the
	// button state before the event, the process the event.
	bindPtr->state = eventPtr->xbutton.state;
	PickCurrentItem(bindPtr, eventPtr);
	bindPtr->state ^= mask;
	BltDoEvent(bindPtr, eventPtr, bindPtr->currentItem,
		   bindPtr->currentContext);
      }
      else {

	// Button release: first process the event, with the button still
	// considered to be down.  Then repick the current item under the
	// assumption that the button is no longer down.
	bindPtr->state = eventPtr->xbutton.state;
	BltDoEvent(bindPtr, eventPtr, bindPtr->currentItem,
		   bindPtr->currentContext);
	eventPtr->xbutton.state ^= mask;
	bindPtr->state = eventPtr->xbutton.state;
	PickCurrentItem(bindPtr, eventPtr);
	eventPtr->xbutton.state ^= mask;
      }
    }
    break;

  case EnterNotify:
  case LeaveNotify:
    bindPtr->state = eventPtr->xcrossing.state;
    PickCurrentItem(bindPtr, eventPtr);
    break;

  case MotionNotify:
    bindPtr->state = eventPtr->xmotion.state;
    PickCurrentItem(bindPtr, eventPtr);
    BltDoEvent(bindPtr, eventPtr, bindPtr->currentItem,
	       bindPtr->currentContext);
    break;

  case KeyPress:
  case KeyRelease:
    bindPtr->state = eventPtr->xkey.state;
    PickCurrentItem(bindPtr, eventPtr);
    BltDoEvent(bindPtr, eventPtr, bindPtr->currentItem,
	       bindPtr->currentContext);
    break;
  }

  Tcl_Release(bindPtr->clientData);
}

int Blt_ConfigureBindingsFromObj(Tcl_Interp* interp, Blt_BindTable bindPtr,
				 ClientData item, int objc,
				 Tcl_Obj* const objv[])
{
  if (objc == 0) {
    Tk_GetAllBindings(interp, bindPtr->bindingTable, item);
    return TCL_OK;
  }

  const char *string = Tcl_GetString(objv[0]);
  if (objc == 1) {
    const char* command =
      Tk_GetBinding(interp, bindPtr->bindingTable, item, string);
    if (!command) {
      Tcl_ResetResult(interp);
      Tcl_AppendResult(interp, "invalid binding event \"", string, "\"", NULL);
      return TCL_ERROR;
    }
    Tcl_SetStringObj(Tcl_GetObjResult(interp), command, -1);
    return TCL_OK;
  }

  const char *seq = string;
  const char* command = Tcl_GetString(objv[1]);
  if (command[0] == '\0')
    return Tk_DeleteBinding(interp, bindPtr->bindingTable, item, seq);

  unsigned long mask;
  if (command[0] == '+')
    mask = Tk_CreateBinding(interp, bindPtr->bindingTable, item, seq,
			    command+1, 1);
  else
    mask = Tk_CreateBinding(interp, bindPtr->bindingTable, item, seq,
			    command, 0);
  if (!mask)
    return TCL_ERROR;

  if (mask & (unsigned) ~(ButtonMotionMask|Button1MotionMask
			  |Button2MotionMask|Button3MotionMask|Button4MotionMask
			  |Button5MotionMask|ButtonPressMask|ButtonReleaseMask
			  |EnterWindowMask|LeaveWindowMask|KeyPressMask
			  |KeyReleaseMask|PointerMotionMask|VirtualEventMask)) {
    Tk_DeleteBinding(interp, bindPtr->bindingTable, item, seq);
    Tcl_ResetResult(interp);
    Tcl_AppendResult(interp, "requested illegal events; ",
		     "only key, button, motion, enter, leave, and virtual ",
		     "events may be used", (char *)NULL);
    return TCL_ERROR;
  }

  return TCL_OK;
}

Blt_BindTable Blt_CreateBindingTable(Tcl_Interp* interp, Tk_Window tkwin,
				     ClientData clientData,
				     Blt_BindPickProc *pickProc,
				     Blt_BindTagProc *tagProc)
{
  Blt_BindTable bindPtr = (Blt_BindTable)calloc(1, sizeof(_Blt_BindTable));
  bindPtr->bindingTable = Tk_CreateBindingTable(interp);
  bindPtr->clientData = clientData;
  bindPtr->tkwin = tkwin;
  bindPtr->pickProc = pickProc;
  bindPtr->tagProc = tagProc;
  unsigned int mask = (KeyPressMask | KeyReleaseMask | ButtonPressMask |
		       ButtonReleaseMask | EnterWindowMask | LeaveWindowMask |
		       PointerMotionMask);
  Tk_CreateEventHandler(tkwin, mask, BindProc, bindPtr);

  return bindPtr;
}

void Blt_DestroyBindingTable(Blt_BindTable bindPtr)
{
  Tk_DeleteBindingTable(bindPtr->bindingTable);
  unsigned int mask = (KeyPressMask | KeyReleaseMask | ButtonPressMask |
		       ButtonReleaseMask | EnterWindowMask | LeaveWindowMask |
		       PointerMotionMask);
  Tk_DeleteEventHandler(bindPtr->tkwin, mask, BindProc, bindPtr);

  free(bindPtr);
  bindPtr = NULL;
}

void Blt_DeleteBindings(Blt_BindTable bindPtr, ClientData object)
{
  Tk_DeleteAllBindings(bindPtr->bindingTable, object);

  // If this is the object currently picked, we need to repick one.
  if (bindPtr->currentItem == object) {
    bindPtr->currentItem = NULL;
    bindPtr->currentContext = NULL;
  }

  if (bindPtr->newItem == object) {
    bindPtr->newItem = NULL;
    bindPtr->newContext = NULL;
  }

  if (bindPtr->focusItem == object) {
    bindPtr->focusItem = NULL;
    bindPtr->focusContext = NULL;
  }
}
<|endoftext|>


<commit_before>//===--- index-test.cpp - Indexing test bed -------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This utility may be invoked in the following manner:
//   index-test --help                - Output help info.
//   index-test [options]             - Read from stdin.
//   index-test [options] file        - Read from "file".
//   index-test [options] file1 file2 - Read these files.
//
//  Files must be AST files.
//
//===----------------------------------------------------------------------===//
//
//   -point-at  [file:column:line]
//       Point at a declaration/statement/expression. If no other operation is
//       specified, prints some info about it.
//
//===----------------------------------------------------------------------===//

#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/Utils.h"
#include "clang/Frontend/CommandLineSourceLoc.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Stmt.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Signals.h"
using namespace clang;

static llvm::cl::list<ParsedSourceLocation>
PointAtLocation("point-at", llvm::cl::Optional,
                 llvm::cl::value_desc("source-location"),
   llvm::cl::desc("Point at the given source location of the first AST file"));

static llvm::cl::opt<bool>
DisableFree("disable-free",
           llvm::cl::desc("Disable freeing of memory on exit"),
           llvm::cl::init(false));

static llvm::cl::list<std::string>
InputFilenames(llvm::cl::Positional, llvm::cl::desc("<input AST files>"));

int main(int argc, char **argv) {
  llvm::sys::PrintStackTraceOnErrorSignal();
  llvm::PrettyStackTraceProgram X(argc, argv);
  llvm::cl::ParseCommandLineOptions(argc, argv,
                     "LLVM 'Clang' Indexing Test Bed: http://clang.llvm.org\n");

  FileManager FileMgr;

  // If no input was specified, read from stdin.
  if (InputFilenames.empty())
    InputFilenames.push_back("-");

  // FIXME: Only the first AST file is used for now.

  const std::string &InFile = InputFilenames[0];

  std::string ErrMsg;
  llvm::OwningPtr<ASTUnit> AST;

  AST.reset(ASTUnit::LoadFromPCHFile(InFile, FileMgr, &ErrMsg));
  if (!AST) {
    llvm::errs() << "[" << InFile << "] Error: " << ErrMsg << '\n';
    return 1;
  }

  struct ASTPoint {
    Decl *D;
    Stmt *Node;
    ASTPoint() : D(0), Node(0) {}
  };

  ASTPoint Point;

  if (!PointAtLocation.empty()) {
    const std::string &Filename = PointAtLocation[0].FileName;
    const FileEntry *File = FileMgr.getFile(Filename);

    // Safety check. Using an out-of-date AST file will only lead to crashes
    // or incorrect results.
    // FIXME: Check all the source files that make up the AST file.
    const FileEntry *ASTFile = FileMgr.getFile(InFile);
    if (File->getModificationTime() > ASTFile->getModificationTime()) {
      llvm::errs() << "[" << InFile << "] Error: " <<
        "Pointing at a source file which was modified after creating "
        "the AST file\n";
      return 1;
    }

    if (File == 0) {
      llvm::errs() << "File '" << Filename << "' does not exist\n";
      return 1;
    }
    unsigned Line = PointAtLocation[0].Line;
    unsigned Col = PointAtLocation[0].Column;

    SourceLocation Loc = AST->getSourceManager().getLocation(File, Line, Col);
    if (Loc.isInvalid()) {
      llvm::errs() << "[" << InFile << "] Error: " <<
        "Couldn't resolve source location (invalid location)\n";
      return 1;
    }

    llvm::tie(Point.D, Point.Node) =
      ResolveLocationInAST(AST->getASTContext(), Loc);
    if (Point.D == 0) {
      llvm::errs() << "[" << InFile << "] Error: " <<
        "Couldn't resolve source location (no declaration found)\n";
      return 1;
    }
  }

  if (Point.D) {
    llvm::raw_ostream &OS = llvm::outs();
    assert(Point.D && "If no node was found we should have exited with error");
    OS << "Declaration node at point: " << Point.D->getDeclKindName() << " ";
    if (NamedDecl *ND = dyn_cast<NamedDecl>(Point.D))
      OS << ND->getNameAsString();
    OS << "\n";

    if (Point.Node) {
      OS << "Statement node at point: " << Point.Node->getStmtClassName()
         << " ";
      Point.Node->printPretty(OS, AST->getASTContext());
      OS << "\n";
    }
  }

  if (DisableFree)
    AST.take();

  // Managed static deconstruction. Useful for making things like
  // -time-passes usable.
  llvm::llvm_shutdown();

  return 0;
}
<commit_msg>Remove redundant leftover code.<commit_after>//===--- index-test.cpp - Indexing test bed -------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This utility may be invoked in the following manner:
//   index-test --help                - Output help info.
//   index-test [options]             - Read from stdin.
//   index-test [options] file        - Read from "file".
//   index-test [options] file1 file2 - Read these files.
//
//  Files must be AST files.
//
//===----------------------------------------------------------------------===//
//
//   -point-at  [file:column:line]
//       Point at a declaration/statement/expression. If no other operation is
//       specified, prints some info about it.
//
//===----------------------------------------------------------------------===//

#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/Utils.h"
#include "clang/Frontend/CommandLineSourceLoc.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Stmt.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Signals.h"
using namespace clang;

static llvm::cl::list<ParsedSourceLocation>
PointAtLocation("point-at", llvm::cl::Optional,
                 llvm::cl::value_desc("source-location"),
   llvm::cl::desc("Point at the given source location of the first AST file"));

static llvm::cl::opt<bool>
DisableFree("disable-free",
           llvm::cl::desc("Disable freeing of memory on exit"),
           llvm::cl::init(false));

static llvm::cl::list<std::string>
InputFilenames(llvm::cl::Positional, llvm::cl::desc("<input AST files>"));

int main(int argc, char **argv) {
  llvm::sys::PrintStackTraceOnErrorSignal();
  llvm::PrettyStackTraceProgram X(argc, argv);
  llvm::cl::ParseCommandLineOptions(argc, argv,
                     "LLVM 'Clang' Indexing Test Bed: http://clang.llvm.org\n");

  FileManager FileMgr;

  // If no input was specified, read from stdin.
  if (InputFilenames.empty())
    InputFilenames.push_back("-");

  // FIXME: Only the first AST file is used for now.

  const std::string &InFile = InputFilenames[0];

  std::string ErrMsg;
  llvm::OwningPtr<ASTUnit> AST;

  AST.reset(ASTUnit::LoadFromPCHFile(InFile, FileMgr, &ErrMsg));
  if (!AST) {
    llvm::errs() << "[" << InFile << "] Error: " << ErrMsg << '\n';
    return 1;
  }

  struct ASTPoint {
    Decl *D;
    Stmt *Node;
    ASTPoint() : D(0), Node(0) {}
  };

  ASTPoint Point;

  if (!PointAtLocation.empty()) {
    const std::string &Filename = PointAtLocation[0].FileName;
    const FileEntry *File = FileMgr.getFile(Filename);

    // Safety check. Using an out-of-date AST file will only lead to crashes
    // or incorrect results.
    // FIXME: Check all the source files that make up the AST file.
    const FileEntry *ASTFile = FileMgr.getFile(InFile);
    if (File->getModificationTime() > ASTFile->getModificationTime()) {
      llvm::errs() << "[" << InFile << "] Error: " <<
        "Pointing at a source file which was modified after creating "
        "the AST file\n";
      return 1;
    }

    if (File == 0) {
      llvm::errs() << "File '" << Filename << "' does not exist\n";
      return 1;
    }
    unsigned Line = PointAtLocation[0].Line;
    unsigned Col = PointAtLocation[0].Column;

    SourceLocation Loc = AST->getSourceManager().getLocation(File, Line, Col);
    if (Loc.isInvalid()) {
      llvm::errs() << "[" << InFile << "] Error: " <<
        "Couldn't resolve source location (invalid location)\n";
      return 1;
    }

    llvm::tie(Point.D, Point.Node) =
      ResolveLocationInAST(AST->getASTContext(), Loc);
    if (Point.D == 0) {
      llvm::errs() << "[" << InFile << "] Error: " <<
        "Couldn't resolve source location (no declaration found)\n";
      return 1;
    }
  }

  if (Point.D) {
    llvm::raw_ostream &OS = llvm::outs();
    OS << "Declaration node at point: " << Point.D->getDeclKindName() << " ";
    if (NamedDecl *ND = dyn_cast<NamedDecl>(Point.D))
      OS << ND->getNameAsString();
    OS << "\n";

    if (Point.Node) {
      OS << "Statement node at point: " << Point.Node->getStmtClassName()
         << " ";
      Point.Node->printPretty(OS, AST->getASTContext());
      OS << "\n";
    }
  }

  if (DisableFree)
    AST.take();

  // Managed static deconstruction. Useful for making things like
  // -time-passes usable.
  llvm::llvm_shutdown();

  return 0;
}
<|endoftext|>