<commit_before>/*
  This file is part of KDE Kontact.

  Copyright (C) 2003 Cornelius Schumacher <schumacher@kde.org>

  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; see the file COPYING.  If not, write to
  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.
 */

#include <qptrlist.h>
#include <qwidgetstack.h>
#include <qsignal.h>
#include <qobjectlist.h>
#include <qlabel.h>
#include <qpainter.h>
#include <qbitmap.h>
#include <qfontmetrics.h>
#include <qsignalmapper.h>
#include <qstyle.h>
#include <qframe.h>
#include <qdrawutil.h>

#include <kpopupmenu.h>
#include <kapplication.h>
#include <klocale.h>
#include <kiconloader.h>
#include <sidebarextension.h>

#include <kdebug.h>

#include "mainwindow.h"

#include "plugin.h"

#include "prefs.h"
#include "iconsidepane.h"

namespace Kontact
{

//ugly wrapper class for adding an operator< to the Plugin class

class PluginProxy
{
public:
  PluginProxy()
    : m_plugin( 0 )
  { }

  PluginProxy( Plugin * plugin )
    : m_plugin( plugin )
  { }

  PluginProxy & operator=( Plugin * plugin )
  {
    m_plugin = plugin;
    return *this;
  }

  bool operator<( PluginProxy & rhs ) const
  {
    return m_plugin->weight() < rhs.m_plugin->weight();
  }

  Plugin * plugin() const
  {
    return m_plugin;
  }

private:
  Plugin * m_plugin;
};
} //namespace

using namespace Kontact;

EntryItem::EntryItem( Navigator *parent, Kontact::Plugin *plugin )
  : QListBoxItem( parent ),
    mPlugin( plugin )
{
  reloadPixmap();
  setCustomHighlighting( true );
  setText( plugin->title() );
}

EntryItem::~EntryItem()
{
}

void EntryItem::reloadPixmap()
{
  int size = (int)navigator()->viewMode();
  if (size != 0)
    mPixmap = KGlobal::iconLoader()->loadIcon( mPlugin->icon(),
  KIcon::Desktop, size );
  else
    mPixmap = QPixmap();
}

Navigator* EntryItem::navigator() const
{
  return static_cast<Navigator*>(listBox());
}

int EntryItem::width( const QListBox *listbox) const
{
  int w;
  if ( text().isEmpty() )
    w = mPixmap.width();
  else
    w = QMAX( (int)navigator()->viewMode(), listbox->fontMetrics().width( text() ) );

  return w + 36;
}

int EntryItem::height( const QListBox *listbox) const
{
  int h;
  if ( text().isEmpty() )
    h =  mPixmap.height();
  else
    h = (int)navigator()->viewMode() + listbox->fontMetrics().lineSpacing();

  return h + 4;
}

void EntryItem::paint( QPainter *p )
{
  reloadPixmap();

  QListBox *box = listBox();
  int w = box->viewport()->width();
  int y = 2;

  if ( !mPixmap.isNull() ) {
    int x = ( w - mPixmap.width() ) / 2;
    p->drawPixmap( x, y, mPixmap );
  }

  QColor save;
  if ( isCurrent() || isSelected() ) {
    save = p->pen().color();
    p->setPen(listBox()->colorGroup().brightText());
  }

  if ( !text().isEmpty() ) {
    QFontMetrics fm = p->fontMetrics();
    y += mPixmap.height() + fm.height() - fm.descent();
    int x = ( w - fm.width( text() ) ) / 2;
    p->drawText( x, y, text() );
  }
  // draw sunken
  if ( isCurrent() || isSelected() ) {
    p->setPen(save);
    QColorGroup group = box->colorGroup();
    group.setColor( QColorGroup::Dark, Qt::black );
    qDrawShadePanel( p, 1, 0, w - 2, height( box ),
                     group, true, 1, 0 );
  }
}

Navigator::Navigator( SidePaneBase *parent, const char *name)
  : KListBox( parent, name ), mSidePane( parent )
{
  mViewMode = sizeIntToEnum( Prefs::self()->sidePaneIconSize() );
  setSelectionMode( KListBox::Single );
  viewport()->setBackgroundMode( PaletteMid );
  setHScrollBarMode( QScrollView::AlwaysOff );
  setAcceptDrops( true );

  connect( this, SIGNAL( selectionChanged( QListBoxItem * ) ),
           SLOT( slotExecuted( QListBoxItem * ) ) );

  connect( this, SIGNAL( rightButtonPressed( QListBoxItem *, const QPoint& ) ),
           SLOT( slotShowRMBMenu( QListBoxItem *, const QPoint& ) ) );

  mMapper = new QSignalMapper( this );
  connect( mMapper, SIGNAL( mapped( int ) ), SLOT( shortCutSelected( int ) ) );
}

QSize Navigator::sizeHint() const
{
  return QSize( 100, 100 );
}

void Navigator::setSelected( QListBoxItem *i, bool sel )
{
  // Reimplemented to avoid the immediate activation of
  // the item. might turn out it doesn't work, we check that
  // an confirm from MainWindow::selectPlugin()
  if (sel) {
    EntryItem *entry = static_cast<EntryItem *>( i );
    emit pluginActivated( entry->plugin() );
  }
}

void Navigator::updatePlugins( QValueList<Kontact::Plugin*> plugins_ )
{
  QValueList<Kontact::PluginProxy> plugins;
  QValueList<Kontact::Plugin*>::ConstIterator end_ = plugins_.end();
  QValueList<Kontact::Plugin*>::ConstIterator it_ = plugins_.begin();
  for ( ; it_ != end_; ++it_ )
    plugins += PluginProxy( *it_ );

  clear();

  mActions.setAutoDelete( true );
  mActions.clear();
  mActions.setAutoDelete( false );

  int counter = 0;
  int minWidth = 0;
  qBubbleSort( plugins );
  QValueList<Kontact::PluginProxy>::ConstIterator end = plugins.end();
  QValueList<Kontact::PluginProxy>::ConstIterator it = plugins.begin();
  for ( ; it != end; ++it ) {
    Kontact::Plugin *plugin = ( *it ).plugin();
    if ( !plugin->showInSideBar() )
      continue;

    EntryItem *item = new EntryItem( this, plugin );

    if ( item->width( this ) > minWidth )
      minWidth = item->width( this );

    QString name = QString( "CTRL+%1" ).arg( counter + 1 );
    KAction *action = new KAction( plugin->title(), KShortcut( name ),
                                   mMapper, SLOT( map() ),
                                   mSidePane->actionCollection(), name.latin1() );
    mMapper->setMapping( action, counter );
    counter++;
  }

  parentWidget()->setFixedWidth( minWidth );
}

void Navigator::dragEnterEvent( QDragEnterEvent *event )
{
  kdDebug(5600) << "Navigator::dragEnterEvent()" << endl;

  dragMoveEvent( event );
}

void Navigator::dragMoveEvent( QDragMoveEvent *event )
{
  kdDebug(5600) << "Navigator::dragEnterEvent()" << endl;

  kdDebug(5600) << "  Format: " << event->format() << endl;

  QListBoxItem *item = itemAt( event->pos() );

  if ( !item ) {
    event->accept( false );
    return;
  }

  EntryItem *entry = static_cast<EntryItem *>( item );

  kdDebug(5600) << "  PLUGIN: " << entry->plugin()->identifier() << endl;

  event->accept( entry->plugin()->canDecodeDrag( event ) );
}

void Navigator::dropEvent( QDropEvent *event )
{
  kdDebug(5600) << "Navigator::dropEvent()" << endl;

  QListBoxItem *item = itemAt( event->pos() );

  if ( !item ) {
    return;
  }

  EntryItem *entry = static_cast<EntryItem *>( item );

  kdDebug(5600) << "  PLUGIN: " << entry->plugin()->identifier() << endl;

  entry->plugin()->processDropEvent( event );
}

void Navigator::resizeEvent( QResizeEvent *event )
{
  QListBox::resizeEvent( event );
  triggerUpdate( true );
}

void Navigator::slotExecuted( QListBoxItem *item )
{
  if ( !item ) return;

  EntryItem *entry = static_cast<EntryItem *>( item );

  emit pluginActivated( entry->plugin() );
}

IconViewMode Navigator::sizeIntToEnum(int size) const
{
  switch ( size ) {
    case int(LargeIcons):
      return LargeIcons;
      break;
    case int(NormalIcons):
      return NormalIcons;
      break;
    case int(SmallIcons):
      return SmallIcons;
      break;
    case int(TextOnly):
      return TextOnly;
      break;
    default:
      // Stick with sane values
      return NormalIcons;
      kdDebug() << "View mode not implemented!" << endl;
      break;
  }

}

void Navigator::slotShowRMBMenu( QListBoxItem *, const QPoint& pos )
{
  KPopupMenu menu;
  menu.insertTitle( i18n("Icon Size") );
  menu.insertItem( i18n("Large"), (int)LargeIcons );
  menu.insertItem( i18n("Nomal "), (int)NormalIcons );
  menu.insertItem( i18n("Small"), (int)SmallIcons );
  menu.insertItem( i18n("Text Only"), (int)TextOnly );
  int choice = menu.exec( pos );

  mViewMode = sizeIntToEnum(choice);
  Prefs::self()->setSidePaneIconSize( choice );

  triggerUpdate( true );
}

void Navigator::shortCutSelected( int pos )
{
  setCurrentItem( pos );
}

IconSidePane::IconSidePane( Core *core, QWidget *parent, const char *name )
  : SidePaneBase( core, parent, name )
{
  mNavigator = new Navigator( this );
  connect( mNavigator, SIGNAL( pluginActivated( Kontact::Plugin * ) ),
           SIGNAL( pluginSelected( Kontact::Plugin * ) ) );

  setAcceptDrops( true );
}

IconSidePane::~IconSidePane()
{
}

void IconSidePane::updatePlugins()
{
  mNavigator->updatePlugins( core()->pluginList() );
}

void IconSidePane::selectPlugin( Kontact::Plugin *plugin )
{
  bool blocked = signalsBlocked();
  blockSignals( true );

  uint i;
  for ( i = 0; i < mNavigator->count(); ++i ) {
    EntryItem *item = static_cast<EntryItem *>( mNavigator->item( i ) );
    if ( item->plugin() == plugin ) {
      mNavigator->setCurrentItem( i );
      break;
    }
  }

  blockSignals( blocked );
}

void IconSidePane::selectPlugin( const QString &name )
{
  bool blocked = signalsBlocked();
  blockSignals( true );

  uint i;
  for ( i = 0; i < mNavigator->count(); ++i ) {
    EntryItem *item = static_cast<EntryItem *>( mNavigator->item( i ) );
    if ( item->plugin()->identifier() == name ) {
      mNavigator->setCurrentItem( i );
      break;
    }
  }

  blockSignals( blocked );
}

#include "iconsidepane.moc"

// vim: sw=2 sts=2 et tw=80
<commit_msg>CVS_SILENT typo<commit_after>/*
  This file is part of KDE Kontact.

  Copyright (C) 2003 Cornelius Schumacher <schumacher@kde.org>

  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; see the file COPYING.  If not, write to
  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.
 */

#include <qptrlist.h>
#include <qwidgetstack.h>
#include <qsignal.h>
#include <qobjectlist.h>
#include <qlabel.h>
#include <qpainter.h>
#include <qbitmap.h>
#include <qfontmetrics.h>
#include <qsignalmapper.h>
#include <qstyle.h>
#include <qframe.h>
#include <qdrawutil.h>

#include <kpopupmenu.h>
#include <kapplication.h>
#include <klocale.h>
#include <kiconloader.h>
#include <sidebarextension.h>

#include <kdebug.h>

#include "mainwindow.h"

#include "plugin.h"

#include "prefs.h"
#include "iconsidepane.h"

namespace Kontact
{

//ugly wrapper class for adding an operator< to the Plugin class

class PluginProxy
{
public:
  PluginProxy()
    : m_plugin( 0 )
  { }

  PluginProxy( Plugin * plugin )
    : m_plugin( plugin )
  { }

  PluginProxy & operator=( Plugin * plugin )
  {
    m_plugin = plugin;
    return *this;
  }

  bool operator<( PluginProxy & rhs ) const
  {
    return m_plugin->weight() < rhs.m_plugin->weight();
  }

  Plugin * plugin() const
  {
    return m_plugin;
  }

private:
  Plugin * m_plugin;
};
} //namespace

using namespace Kontact;

EntryItem::EntryItem( Navigator *parent, Kontact::Plugin *plugin )
  : QListBoxItem( parent ),
    mPlugin( plugin )
{
  reloadPixmap();
  setCustomHighlighting( true );
  setText( plugin->title() );
}

EntryItem::~EntryItem()
{
}

void EntryItem::reloadPixmap()
{
  int size = (int)navigator()->viewMode();
  if (size != 0)
    mPixmap = KGlobal::iconLoader()->loadIcon( mPlugin->icon(),
  KIcon::Desktop, size );
  else
    mPixmap = QPixmap();
}

Navigator* EntryItem::navigator() const
{
  return static_cast<Navigator*>(listBox());
}

int EntryItem::width( const QListBox *listbox) const
{
  int w;
  if ( text().isEmpty() )
    w = mPixmap.width();
  else
    w = QMAX( (int)navigator()->viewMode(), listbox->fontMetrics().width( text() ) );

  return w + 36;
}

int EntryItem::height( const QListBox *listbox) const
{
  int h;
  if ( text().isEmpty() )
    h =  mPixmap.height();
  else
    h = (int)navigator()->viewMode() + listbox->fontMetrics().lineSpacing();

  return h + 4;
}

void EntryItem::paint( QPainter *p )
{
  reloadPixmap();

  QListBox *box = listBox();
  int w = box->viewport()->width();
  int y = 2;

  if ( !mPixmap.isNull() ) {
    int x = ( w - mPixmap.width() ) / 2;
    p->drawPixmap( x, y, mPixmap );
  }

  QColor save;
  if ( isCurrent() || isSelected() ) {
    save = p->pen().color();
    p->setPen(listBox()->colorGroup().brightText());
  }

  if ( !text().isEmpty() ) {
    QFontMetrics fm = p->fontMetrics();
    y += mPixmap.height() + fm.height() - fm.descent();
    int x = ( w - fm.width( text() ) ) / 2;
    p->drawText( x, y, text() );
  }
  // draw sunken
  if ( isCurrent() || isSelected() ) {
    p->setPen(save);
    QColorGroup group = box->colorGroup();
    group.setColor( QColorGroup::Dark, Qt::black );
    qDrawShadePanel( p, 1, 0, w - 2, height( box ),
                     group, true, 1, 0 );
  }
}

Navigator::Navigator( SidePaneBase *parent, const char *name)
  : KListBox( parent, name ), mSidePane( parent )
{
  mViewMode = sizeIntToEnum( Prefs::self()->sidePaneIconSize() );
  setSelectionMode( KListBox::Single );
  viewport()->setBackgroundMode( PaletteMid );
  setHScrollBarMode( QScrollView::AlwaysOff );
  setAcceptDrops( true );

  connect( this, SIGNAL( selectionChanged( QListBoxItem * ) ),
           SLOT( slotExecuted( QListBoxItem * ) ) );

  connect( this, SIGNAL( rightButtonPressed( QListBoxItem *, const QPoint& ) ),
           SLOT( slotShowRMBMenu( QListBoxItem *, const QPoint& ) ) );

  mMapper = new QSignalMapper( this );
  connect( mMapper, SIGNAL( mapped( int ) ), SLOT( shortCutSelected( int ) ) );
}

QSize Navigator::sizeHint() const
{
  return QSize( 100, 100 );
}

void Navigator::setSelected( QListBoxItem *i, bool sel )
{
  // Reimplemented to avoid the immediate activation of
  // the item. might turn out it doesn't work, we check that
  // an confirm from MainWindow::selectPlugin()
  if (sel) {
    EntryItem *entry = static_cast<EntryItem *>( i );
    emit pluginActivated( entry->plugin() );
  }
}

void Navigator::updatePlugins( QValueList<Kontact::Plugin*> plugins_ )
{
  QValueList<Kontact::PluginProxy> plugins;
  QValueList<Kontact::Plugin*>::ConstIterator end_ = plugins_.end();
  QValueList<Kontact::Plugin*>::ConstIterator it_ = plugins_.begin();
  for ( ; it_ != end_; ++it_ )
    plugins += PluginProxy( *it_ );

  clear();

  mActions.setAutoDelete( true );
  mActions.clear();
  mActions.setAutoDelete( false );

  int counter = 0;
  int minWidth = 0;
  qBubbleSort( plugins );
  QValueList<Kontact::PluginProxy>::ConstIterator end = plugins.end();
  QValueList<Kontact::PluginProxy>::ConstIterator it = plugins.begin();
  for ( ; it != end; ++it ) {
    Kontact::Plugin *plugin = ( *it ).plugin();
    if ( !plugin->showInSideBar() )
      continue;

    EntryItem *item = new EntryItem( this, plugin );

    if ( item->width( this ) > minWidth )
      minWidth = item->width( this );

    QString name = QString( "CTRL+%1" ).arg( counter + 1 );
    KAction *action = new KAction( plugin->title(), KShortcut( name ),
                                   mMapper, SLOT( map() ),
                                   mSidePane->actionCollection(), name.latin1() );
    mMapper->setMapping( action, counter );
    counter++;
  }

  parentWidget()->setFixedWidth( minWidth );
}

void Navigator::dragEnterEvent( QDragEnterEvent *event )
{
  kdDebug(5600) << "Navigator::dragEnterEvent()" << endl;

  dragMoveEvent( event );
}

void Navigator::dragMoveEvent( QDragMoveEvent *event )
{
  kdDebug(5600) << "Navigator::dragEnterEvent()" << endl;

  kdDebug(5600) << "  Format: " << event->format() << endl;

  QListBoxItem *item = itemAt( event->pos() );

  if ( !item ) {
    event->accept( false );
    return;
  }

  EntryItem *entry = static_cast<EntryItem *>( item );

  kdDebug(5600) << "  PLUGIN: " << entry->plugin()->identifier() << endl;

  event->accept( entry->plugin()->canDecodeDrag( event ) );
}

void Navigator::dropEvent( QDropEvent *event )
{
  kdDebug(5600) << "Navigator::dropEvent()" << endl;

  QListBoxItem *item = itemAt( event->pos() );

  if ( !item ) {
    return;
  }

  EntryItem *entry = static_cast<EntryItem *>( item );

  kdDebug(5600) << "  PLUGIN: " << entry->plugin()->identifier() << endl;

  entry->plugin()->processDropEvent( event );
}

void Navigator::resizeEvent( QResizeEvent *event )
{
  QListBox::resizeEvent( event );
  triggerUpdate( true );
}

void Navigator::slotExecuted( QListBoxItem *item )
{
  if ( !item ) return;

  EntryItem *entry = static_cast<EntryItem *>( item );

  emit pluginActivated( entry->plugin() );
}

IconViewMode Navigator::sizeIntToEnum(int size) const
{
  switch ( size ) {
    case int(LargeIcons):
      return LargeIcons;
      break;
    case int(NormalIcons):
      return NormalIcons;
      break;
    case int(SmallIcons):
      return SmallIcons;
      break;
    case int(TextOnly):
      return TextOnly;
      break;
    default:
      // Stick with sane values
      return NormalIcons;
      kdDebug() << "View mode not implemented!" << endl;
      break;
  }

}

void Navigator::slotShowRMBMenu( QListBoxItem *, const QPoint& pos )
{
  KPopupMenu menu;
  menu.insertTitle( i18n("Icon Size") );
  menu.insertItem( i18n("Large"), (int)LargeIcons );
  menu.insertItem( i18n("Normal "), (int)NormalIcons );
  menu.insertItem( i18n("Small"), (int)SmallIcons );
  menu.insertItem( i18n("Text Only"), (int)TextOnly );
  int choice = menu.exec( pos );

  mViewMode = sizeIntToEnum(choice);
  Prefs::self()->setSidePaneIconSize( choice );

  triggerUpdate( true );
}

void Navigator::shortCutSelected( int pos )
{
  setCurrentItem( pos );
}

IconSidePane::IconSidePane( Core *core, QWidget *parent, const char *name )
  : SidePaneBase( core, parent, name )
{
  mNavigator = new Navigator( this );
  connect( mNavigator, SIGNAL( pluginActivated( Kontact::Plugin * ) ),
           SIGNAL( pluginSelected( Kontact::Plugin * ) ) );

  setAcceptDrops( true );
}

IconSidePane::~IconSidePane()
{
}

void IconSidePane::updatePlugins()
{
  mNavigator->updatePlugins( core()->pluginList() );
}

void IconSidePane::selectPlugin( Kontact::Plugin *plugin )
{
  bool blocked = signalsBlocked();
  blockSignals( true );

  uint i;
  for ( i = 0; i < mNavigator->count(); ++i ) {
    EntryItem *item = static_cast<EntryItem *>( mNavigator->item( i ) );
    if ( item->plugin() == plugin ) {
      mNavigator->setCurrentItem( i );
      break;
    }
  }

  blockSignals( blocked );
}

void IconSidePane::selectPlugin( const QString &name )
{
  bool blocked = signalsBlocked();
  blockSignals( true );

  uint i;
  for ( i = 0; i < mNavigator->count(); ++i ) {
    EntryItem *item = static_cast<EntryItem *>( mNavigator->item( i ) );
    if ( item->plugin()->identifier() == name ) {
      mNavigator->setCurrentItem( i );
      break;
    }
  }

  blockSignals( blocked );
}

#include "iconsidepane.moc"

// vim: sw=2 sts=2 et tw=80
<|endoftext|>


<commit_before>// InteractiveNotifications.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "InteractiveNotifications.h"
#include <NotificationActivationCallback.h>

#include <Shellapi.h>
#include <string>
#include <iostream>
#include <SDKDDKVer.h>
#include <Windows.h>
#include <Psapi.h>
#include <strsafe.h>
#include <ShObjIdl.h>
#include <Shlobj.h>
#include <Pathcch.h>
#include <propvarutil.h>
#include <propkey.h>
#include <wchar.h>
#include <wrl.h>
#include <wrl\wrappers\corewrappers.h>
#include <windows.ui.notifications.h>

// Correct flow
// RegisterAppForNotificationSupport()
// RegisterActivator()

//  Name:     System.AppUserModel.ToastActivatorCLSID -- PKEY_AppUserModel_ToastActivatorCLSID
//  Type:     Guid -- VT_CLSID
//  FormatID: {9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}, 26
//
//  Used to CoCreate an INotificationActivationCallback interface to notify about toast activations.
EXTERN_C const PROPERTYKEY DECLSPEC_SELECTANY PKEY_AppUserModel_ToastActivatorCLSID = { { 0x9F4C2855, 0x9F79, 0x4B39,{ 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3 } }, 26 };

using namespace ABI::Windows::Data::Xml::Dom;
using namespace ABI::Windows::UI::Notifications;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;

struct CoTaskMemStringTraits
{
	typedef PWSTR Type;

	inline static bool Close(_In_ Type h) throw() { ::CoTaskMemFree(h); return true; }

	inline static Type GetInvalidValue() throw() { return nullptr; }
};
typedef HandleT<CoTaskMemStringTraits> CoTaskMemString;

const wchar_t Shortcut[] = LR"(Microsoft\Windows\Start Menu\Slack.lnk)";

#define __CSID "F4B2D0CA-5D93-41CF-9A4C-721782B3246F"

// For the app to be activated from Action Center, it needs to provide a COM server to be called
// when the notification is activated.  The CLSID of the object needs to be registered with the
// OS via its shortcut so that it knows who to call later.
class DECLSPEC_UUID(__CSID) NotificationActivator WrlSealed WrlFinal
: public RuntimeClass < RuntimeClassFlags<ClassicCom>,
	INotificationActivationCallback >
{
public:
	virtual HRESULT STDMETHODCALLTYPE Activate(
		_In_ LPCWSTR appUserModelId,
		_In_ LPCWSTR invokedArgs,
		_In_reads_(dataCount) const NOTIFICATION_USER_INPUT_DATA* data,
		ULONG dataCount) override
	{
		std::string args;

		for (int i = 0; i < dataCount; i++) {
			LPCWSTR lvalue = data[i].Value;
			LPCWSTR lkey = data[i].Key;

			std::wstring wvalue(lvalue);
			std::wstring wkey(lkey);

			std::string value(wvalue.begin(), wvalue.end());
			std::string key(wkey.begin(), wkey.end());

			args = args + "\"key\":\"" + key + "\"";
			args = args + ",\"value\":\"" + value + "\"";
		}

		std::string escapedArgs = "";
		for (char ch : args) {
			switch (ch) {
			case ' ': escapedArgs += "%20"; break;
			case '&': escapedArgs += "^&"; break;
			case '\\': escapedArgs += "^\\"; break;
			case '<': escapedArgs += "^<"; break;
			case '>': escapedArgs += "^>"; break;
			case '|': escapedArgs += "^|"; break;
			case '^': escapedArgs += "^^"; break;
			case '"': escapedArgs += "^\""; break;
			default: escapedArgs += ch; break;
			}
		}

		std::wstring wToastArgs(invokedArgs);
		std::string toastArgs(wToastArgs.begin(), wToastArgs.end());

		// CMD needs stuff escaped, so we'll do that here
		std::string escapedToastArgs = "";
		for (char ch : toastArgs) {
			switch (ch) {
			case ' ': escapedToastArgs += "%20"; break;
			case '&': escapedToastArgs += "^&"; break;
			case '\\': escapedToastArgs += "^\\"; break;
			case '<': escapedToastArgs += "^<"; break;
			case '>': escapedToastArgs += "^>"; break;
			case '|': escapedToastArgs += "^|"; break;
			case '^': escapedToastArgs += "^^"; break;
			case '"': escapedToastArgs += "^\""; break;
			default: escapedToastArgs += ch; break;
			}
		}

		std::string cmdLine = "start slack://" + escapedToastArgs + "^&userData={" + escapedArgs + "}";
		system(cmdLine.c_str());

		return HRESULT();
	}
};
CoCreatableClass(NotificationActivator);

namespace InteractiveNotifications
{
	INTERACTIVENOTIFICATIONS_API HRESULT RegisterAppForNotificationSupport(PCWSTR shortcut, PCWSTR appId)
	{
		CoTaskMemString appData;
		auto hr = ::SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, nullptr, appData.GetAddressOf());

		if (SUCCEEDED(hr))
		{
			wchar_t shortcutPath[MAX_PATH];
			// Todo: Don't hardcode the path
			hr = ::PathCchCombine(shortcutPath, ARRAYSIZE(shortcutPath), appData.Get(), shortcut);

			if (SUCCEEDED(hr))
			{
				DWORD attributes = ::GetFileAttributes(shortcutPath);
				bool fileExists = attributes < 0xFFFFFFF;

				if (!fileExists)
				{
					// Todo: This is probably the wrong path bc Squirrel
					wchar_t exePath[MAX_PATH];
					DWORD charWritten = ::GetModuleFileName(nullptr, exePath, ARRAYSIZE(exePath));
					hr = charWritten > 0 ? S_OK : HRESULT_FROM_WIN32(::GetLastError());

					if (SUCCEEDED(hr))
					{
						hr = InstallShortcut(shortcutPath, exePath, appId);
						if (SUCCEEDED(hr))
						{
							hr = RegisterComServer(exePath);
						}
					}
				}
			}
		}
		return hr;
	}

	_Use_decl_annotations_
	INTERACTIVENOTIFICATIONS_API HRESULT InstallShortcut(PCWSTR shortcutPath, PCWSTR exePath, PCWSTR appId)
	{
		ComPtr<IShellLink> shellLink;
		HRESULT hr = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shellLink));

		if (!SUCCEEDED(hr)) return hr;
		hr = shellLink->SetPath(exePath);

		if (!SUCCEEDED(hr)) return hr;
		ComPtr<IPropertyStore> propertyStore;
		hr = shellLink.As(&propertyStore);

		if (!SUCCEEDED(hr)) return hr;
		PROPVARIANT propVar;
		propVar.vt = VT_LPWSTR;
		propVar.pwszVal = const_cast<PWSTR>(appId); // for _In_ scenarios, we don't need a copy
		hr = propertyStore->SetValue(PKEY_AppUserModel_ID, propVar);

		if (!SUCCEEDED(hr)) return hr;
		propVar.vt = VT_CLSID;
		propVar.puuid = const_cast<CLSID*>(&__uuidof(NotificationActivator));
		hr = propertyStore->SetValue(PKEY_AppUserModel_ToastActivatorCLSID, propVar);

		if (!SUCCEEDED(hr)) return hr;
		hr = propertyStore->Commit();

		if (!SUCCEEDED(hr)) return hr;
		ComPtr<IPersistFile> persistFile;
		hr = shellLink.As(&persistFile);

		if (!SUCCEEDED(hr)) return hr;
		hr = persistFile->Save(shortcutPath, TRUE);

		return hr;
	}

	_Use_decl_annotations_
	INTERACTIVENOTIFICATIONS_API HRESULT RegisterComServer(PCWSTR exePath)
	{
		// We don't need to worry about overflow here as ::GetModuleFileName won't
		// return anything bigger than the max file system path (much fewer than max of DWORD).
		DWORD dataSize = static_cast<DWORD>((::wcslen(exePath) + 1) * sizeof(WCHAR));
		auto key = LR"(SOFTWARE\Classes\CLSID\{F4B2D0CA-5D93-41CF-9A4C-721782B3246F}\LocalServer32)";

		return HRESULT_FROM_WIN32(::RegSetKeyValue(
			HKEY_CURRENT_USER,
			key,
			nullptr,
			REG_SZ,
			reinterpret_cast<const BYTE*>(exePath),
			dataSize));
	}

	_Use_decl_annotations_
	INTERACTIVENOTIFICATIONS_API HRESULT RegisterActivator()
	{
		// Module<OutOfProc> needs a callback registered before it can be used.
		// Since we don't care about when it shuts down, we'll pass an empty lambda here.
		// If we need to clean up, do it here (we probably don't have to)
		Module<OutOfProc>::Create([] {});

		// If a local server process only hosts the COM object then COM expects
		// the COM server host to shutdown when the references drop to zero.
		// Since the user might still be using the program after activating the notification,
		// we don't want to shutdown immediately.  Incrementing the object count tells COM that
		// we aren't done yet.
		Module<OutOfProc>::GetModule().IncrementObjectCount();

		return Module<OutOfProc>::GetModule().RegisterObjects();
	}

	_Use_decl_annotations_
	INTERACTIVENOTIFICATIONS_API void UnregisterActivator()
	{
		Module<OutOfProc>::GetModule().UnregisterObjects();
		Module<OutOfProc>::GetModule().DecrementObjectCount();
	}
}

extern "C"
{
	__declspec(dllexport) void CRegisterForNotificationSupport(PCWSTR shortcut, PCWSTR appId)
	{
		InteractiveNotifications::RegisterAppForNotificationSupport(shortcut, appId);
	}

	__declspec(dllexport) void CRegisterActivator()
	{
		InteractiveNotifications::RegisterActivator();
	}

	__declspec(dllexport) void CUnregisterActivator()
	{
		InteractiveNotifications::UnregisterActivator();
	}
}<commit_msg>:wrench: And even more fixes<commit_after>// InteractiveNotifications.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "InteractiveNotifications.h"
#include <NotificationActivationCallback.h>

#include <Shellapi.h>
#include <string>
#include <iostream>
#include <SDKDDKVer.h>
#include <Windows.h>
#include <Psapi.h>
#include <strsafe.h>
#include <ShObjIdl.h>
#include <Shlobj.h>
#include <Pathcch.h>
#include <propvarutil.h>
#include <propkey.h>
#include <wchar.h>
#include <wrl.h>
#include <wrl\wrappers\corewrappers.h>
#include <windows.ui.notifications.h>

// Correct flow
// RegisterAppForNotificationSupport()
// RegisterActivator()

//  Name:     System.AppUserModel.ToastActivatorCLSID -- PKEY_AppUserModel_ToastActivatorCLSID
//  Type:     Guid -- VT_CLSID
//  FormatID: {9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}, 26
//
//  Used to CoCreate an INotificationActivationCallback interface to notify about toast activations.
EXTERN_C const PROPERTYKEY DECLSPEC_SELECTANY PKEY_AppUserModel_ToastActivatorCLSID = { { 0x9F4C2855, 0x9F79, 0x4B39,{ 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3 } }, 26 };

using namespace ABI::Windows::Data::Xml::Dom;
using namespace ABI::Windows::UI::Notifications;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;

struct CoTaskMemStringTraits
{
	typedef PWSTR Type;

	inline static bool Close(_In_ Type h) throw() { ::CoTaskMemFree(h); return true; }

	inline static Type GetInvalidValue() throw() { return nullptr; }
};
typedef HandleT<CoTaskMemStringTraits> CoTaskMemString;

const wchar_t Shortcut[] = LR"(Microsoft\Windows\Start Menu\Slack.lnk)";

#define __CSID "F4B2D0CA-5D93-41CF-9A4C-721782B3246F"

// For the app to be activated from Action Center, it needs to provide a COM server to be called
// when the notification is activated.  The CLSID of the object needs to be registered with the
// OS via its shortcut so that it knows who to call later.
class DECLSPEC_UUID(__CSID) NotificationActivator WrlSealed WrlFinal
: public RuntimeClass < RuntimeClassFlags<ClassicCom>,
	INotificationActivationCallback >
{
public:
	virtual HRESULT STDMETHODCALLTYPE Activate(
		_In_ LPCWSTR appUserModelId,
		_In_ LPCWSTR invokedArgs,
		_In_reads_(dataCount) const NOTIFICATION_USER_INPUT_DATA* data,
		ULONG dataCount) override
	{
		std::string args;

		for (int i = 0; i < dataCount; i++) {
			LPCWSTR lvalue = data[i].Value;
			LPCWSTR lkey = data[i].Key;

			std::wstring wvalue(lvalue);
			std::wstring wkey(lkey);

			std::string value(wvalue.begin(), wvalue.end());
			std::string key(wkey.begin(), wkey.end());

			args = args + "\"key\":\"" + key + "\"";
			args = args + ",\"value\":\"" + value + "\"";
		}

		std::string escapedArgs = "";
		for (char ch : args) {
			switch (ch) {
			case ' ': escapedArgs += "%20"; break;
			case '&': escapedArgs += "^&"; break;
			case '\\': escapedArgs += "^\\"; break;
			case '<': escapedArgs += "^<"; break;
			case '>': escapedArgs += "^>"; break;
			case '|': escapedArgs += "^|"; break;
			case '^': escapedArgs += "^^"; break;
			case '"': escapedArgs += "^%22"; break;
			default: escapedArgs += ch; break;
			}
		}

		std::wstring wToastArgs(invokedArgs);
		std::string toastArgs(wToastArgs.begin(), wToastArgs.end());

		// CMD needs stuff escaped, so we'll do that here
		std::string escapedToastArgs = "";
		for (char ch : toastArgs) {
			switch (ch) {
			case ' ': escapedToastArgs += "%20"; break;
			case '&': escapedToastArgs += "^&"; break;
			case '\\': escapedToastArgs += "^\\"; break;
			case '<': escapedToastArgs += "^<"; break;
			case '>': escapedToastArgs += "^>"; break;
			case '|': escapedToastArgs += "^|"; break;
			case '^': escapedToastArgs += "^^"; break;
			case '"': escapedToastArgs += "%22"; break;
			default: escapedToastArgs += ch; break;
			}
		}

		std::string cmdLine = "start slack://" + escapedToastArgs + "^&userData={" + escapedArgs + "}";
		system(cmdLine.c_str());

		return HRESULT();
	}
};
CoCreatableClass(NotificationActivator);

namespace InteractiveNotifications
{
	INTERACTIVENOTIFICATIONS_API HRESULT RegisterAppForNotificationSupport(PCWSTR shortcut, PCWSTR appId)
	{
		CoTaskMemString appData;
		auto hr = ::SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, nullptr, appData.GetAddressOf());

		if (SUCCEEDED(hr))
		{
			wchar_t shortcutPath[MAX_PATH];
			// Todo: Don't hardcode the path
			hr = ::PathCchCombine(shortcutPath, ARRAYSIZE(shortcutPath), appData.Get(), shortcut);

			if (SUCCEEDED(hr))
			{
				DWORD attributes = ::GetFileAttributes(shortcutPath);
				bool fileExists = attributes < 0xFFFFFFF;

				if (!fileExists)
				{
					// Todo: This is probably the wrong path bc Squirrel
					wchar_t exePath[MAX_PATH];
					DWORD charWritten = ::GetModuleFileName(nullptr, exePath, ARRAYSIZE(exePath));
					hr = charWritten > 0 ? S_OK : HRESULT_FROM_WIN32(::GetLastError());

					if (SUCCEEDED(hr))
					{
						hr = InstallShortcut(shortcutPath, exePath, appId);
						if (SUCCEEDED(hr))
						{
							hr = RegisterComServer(exePath);
						}
					}
				}
			}
		}
		return hr;
	}

	_Use_decl_annotations_
	INTERACTIVENOTIFICATIONS_API HRESULT InstallShortcut(PCWSTR shortcutPath, PCWSTR exePath, PCWSTR appId)
	{
		ComPtr<IShellLink> shellLink;
		HRESULT hr = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shellLink));

		if (!SUCCEEDED(hr)) return hr;
		hr = shellLink->SetPath(exePath);

		if (!SUCCEEDED(hr)) return hr;
		ComPtr<IPropertyStore> propertyStore;
		hr = shellLink.As(&propertyStore);

		if (!SUCCEEDED(hr)) return hr;
		PROPVARIANT propVar;
		propVar.vt = VT_LPWSTR;
		propVar.pwszVal = const_cast<PWSTR>(appId); // for _In_ scenarios, we don't need a copy
		hr = propertyStore->SetValue(PKEY_AppUserModel_ID, propVar);

		if (!SUCCEEDED(hr)) return hr;
		propVar.vt = VT_CLSID;
		propVar.puuid = const_cast<CLSID*>(&__uuidof(NotificationActivator));
		hr = propertyStore->SetValue(PKEY_AppUserModel_ToastActivatorCLSID, propVar);

		if (!SUCCEEDED(hr)) return hr;
		hr = propertyStore->Commit();

		if (!SUCCEEDED(hr)) return hr;
		ComPtr<IPersistFile> persistFile;
		hr = shellLink.As(&persistFile);

		if (!SUCCEEDED(hr)) return hr;
		hr = persistFile->Save(shortcutPath, TRUE);

		return hr;
	}

	_Use_decl_annotations_
	INTERACTIVENOTIFICATIONS_API HRESULT RegisterComServer(PCWSTR exePath)
	{
		// We don't need to worry about overflow here as ::GetModuleFileName won't
		// return anything bigger than the max file system path (much fewer than max of DWORD).
		DWORD dataSize = static_cast<DWORD>((::wcslen(exePath) + 1) * sizeof(WCHAR));
		auto key = LR"(SOFTWARE\Classes\CLSID\{F4B2D0CA-5D93-41CF-9A4C-721782B3246F}\LocalServer32)";

		return HRESULT_FROM_WIN32(::RegSetKeyValue(
			HKEY_CURRENT_USER,
			key,
			nullptr,
			REG_SZ,
			reinterpret_cast<const BYTE*>(exePath),
			dataSize));
	}

	_Use_decl_annotations_
	INTERACTIVENOTIFICATIONS_API HRESULT RegisterActivator()
	{
		// Module<OutOfProc> needs a callback registered before it can be used.
		// Since we don't care about when it shuts down, we'll pass an empty lambda here.
		// If we need to clean up, do it here (we probably don't have to)
		Module<OutOfProc>::Create([] {});

		// If a local server process only hosts the COM object then COM expects
		// the COM server host to shutdown when the references drop to zero.
		// Since the user might still be using the program after activating the notification,
		// we don't want to shutdown immediately.  Incrementing the object count tells COM that
		// we aren't done yet.
		Module<OutOfProc>::GetModule().IncrementObjectCount();

		return Module<OutOfProc>::GetModule().RegisterObjects();
	}

	_Use_decl_annotations_
	INTERACTIVENOTIFICATIONS_API void UnregisterActivator()
	{
		Module<OutOfProc>::GetModule().UnregisterObjects();
		Module<OutOfProc>::GetModule().DecrementObjectCount();
	}
}

extern "C"
{
	__declspec(dllexport) void CRegisterForNotificationSupport(PCWSTR shortcut, PCWSTR appId)
	{
		InteractiveNotifications::RegisterAppForNotificationSupport(shortcut, appId);
	}

	__declspec(dllexport) void CRegisterActivator()
	{
		InteractiveNotifications::RegisterActivator();
	}

	__declspec(dllexport) void CUnregisterActivator()
	{
		InteractiveNotifications::UnregisterActivator();
	}
}<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Library
  Module:    STLRead.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

This file is part of the Visualization Library. No part of this file or its
contents may be copied, reproduced or altered in any way without the express
written consent of the authors.

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994

=========================================================================*/
#include <ctype.h>
#include "STLRead.hh"
#include "ByteSwap.hh"

#define ASCII 0
#define BINARY 1

void vlSTLReader::Execute()
{
  FILE *fp;
  vlFloatPoints *newPts;
  vlCellArray *newPolys;
//
// Initialize
//
  this->Initialize();

  if ((fp = fopen(this->Filename, "r")) == NULL)
    {
    fprintf(stderr, "%s: file %s not found\n", this->GetClassName(), this->Filename);
      return;
    }

  newPts = new vlFloatPoints(5000,10000);
  newPolys = new vlCellArray(10000,20000);

//
// Depending upon file type, read differently
//
  if ( this->GetSTLFileType(fp) == ASCII )
    {
    if ( this->ReadASCIISTL(fp,newPts,newPolys) ) return;
    }
  else
    {
    if ( this->ReadBinarySTL(fp,newPts,newPolys) ) return;
    }

  vlDebugMacro(<< "Read " << newPts->NumberOfPoints() << " points\n");
  vlDebugMacro(<< "Read " << newPolys->GetNumberOfCells() << " triangles\n");
//
// Since we sized the dynamic arrays arbitrarily to begin with
// need to resize them to fit data
//
  newPts->Squeeze();
  newPolys->Squeeze();
//
// Update ourselves
//
  this->SetPoints(newPts);
  this->SetPolys(newPolys);
}

int vlSTLReader::ReadBinarySTL(FILE *fp, vlFloatPoints *newPts, vlCellArray *newPolys)
{
  int i, numTris, pts[3];
  unsigned long   ulint;
  unsigned short  ibuff2;
  char    header[81];
  vlByteSwap swap;
  typedef struct  {float  n[3], v1[3], v2[3], v3[3];} facet_t;
  facet_t facet;

  vlDebugMacro(<< " Reading BINARY STL file\n");
//
//  File is read to obtain raw information as well as bounding box
//
  fread (header, 1, 80, fp);
  fread (&ulint, 1, 4, fp);
  swap.Swap4 (&ulint);
  if ( (numTris = (int) ulint) <= 0 )
    {
    vlErrorMacro(<< "Bad binary STL file\n");
    return 1;
    }

  for (i=0; fread(&facet,48,1,fp) && i<numTris; i++)
    {
    fread(&ibuff2,2,1,fp); /* read extra junk */

    swap.Swap4 (facet.n);
    swap.Swap4 (facet.n+1);
    swap.Swap4 (facet.n+2);

    swap.Swap4 (facet.v1);
    swap.Swap4 (facet.v1+1);
    swap.Swap4 (facet.v1+2);
    pts[0] = newPts->InsertNextPoint(facet.v1);

    swap.Swap4 (facet.v2);
    swap.Swap4 (facet.v2+1);
    swap.Swap4 (facet.v2+2);
    pts[1] = newPts->InsertNextPoint(facet.v2);

    swap.Swap4 (facet.v3);
    swap.Swap4 (facet.v3+1);
    swap.Swap4 (facet.v3+2);
    pts[2] = newPts->InsertNextPoint(facet.v3);

    newPolys->InsertNextCell(3,pts);

    if (this->Debug && (i % 5000) == 0 && i != 0 )
      fprintf (stderr,"%s: triangle #%d\n", this->GetClassName(), i);
    }

  return 0;
}

int vlSTLReader::ReadASCIISTL(FILE *fp, vlFloatPoints *newPts, vlCellArray *newPolys)
{
  char line[256];
  int i;
  float x[3];
  int pts[3];

  vlDebugMacro(<< " Reading ASCII STL file\n");
//
//  Ingest header and junk to get to first vertex
//
  fgets (line, 255, fp);
/*
 *  Go into loop, reading  facet normal and vertices
 */
  while (fscanf(fp,"%*s %*s %f %f %f\n", x, x+1, x+2)!=EOF)
    {
    fgets (line, 255, fp);
    fscanf (fp, "%*s %f %f %f\n", x,x+1,x+2);
    pts[0] = newPts->InsertNextPoint(x);
    fscanf (fp, "%*s %f %f %f\n", x,x+1,x+2);
    pts[1] = newPts->InsertNextPoint(x);
    fscanf (fp, "%*s %f %f %f\n", x,x+1,x+2);
    pts[2] = newPts->InsertNextPoint(x);
    fgets (line, 255, fp); /* end loop */
    fgets (line, 255, fp); /* end facet */

    newPolys->InsertNextCell(3,pts);

    if (this->Debug && ((newPolys->GetNumberOfCells() % 5000) == 0) )
      fprintf (stderr,"%s: triangle #%d\n", this->GetClassName(), newPolys->GetNumberOfCells());
    }

  return 0;
}

int vlSTLReader::GetSTLFileType(FILE *fp)
{
  char header[256];
  int type, i;
//
//  Read a little from the file to figure what type it is.
//
  fgets (header, 255, fp); /* first line is always ascii */
  fgets (header, 18, fp);
  for (i=0, type=ASCII; i<17 && type == ASCII; i++) // don't test \0
    if ( ! isprint(header[i]) )
      type = BINARY;
//
// Reset file for reading
//
  rewind (fp);
  return type;
}

void vlSTLReader::PrintSelf(ostream& os, vlIndent indent)
{
  if (this->ShouldIPrint(vlSTLReader::GetClassName()))
    {
    vlPolySource::PrintSelf(os,indent);

    os << indent << "Filename: " << this->Filename << "\n";
    }
}
<commit_msg>ENH: More robust reading of binary files.<commit_after>/*=========================================================================

  Program:   Visualization Library
  Module:    STLRead.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

This file is part of the Visualization Library. No part of this file or its
contents may be copied, reproduced or altered in any way without the express
written consent of the authors.

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994

=========================================================================*/
#include <ctype.h>
#include "STLRead.hh"
#include "ByteSwap.hh"

#define ASCII 0
#define BINARY 1

void vlSTLReader::Execute()
{
  FILE *fp;
  vlFloatPoints *newPts;
  vlCellArray *newPolys;
//
// Initialize
//
  this->Initialize();

  if ((fp = fopen(this->Filename, "r")) == NULL)
    {
    vlErrorMacro(<< "File " << this->Filename << " not found\n");
    return;
    }

  newPts = new vlFloatPoints(5000,10000);
  newPolys = new vlCellArray(10000,20000);

//
// Depending upon file type, read differently
//
  if ( this->GetSTLFileType(fp) == ASCII )
    {
    if ( this->ReadASCIISTL(fp,newPts,newPolys) ) return;
    }
  else
    {
    if ( this->ReadBinarySTL(fp,newPts,newPolys) ) return;
    }

  vlDebugMacro(<< "Read " << newPts->NumberOfPoints() << " points\n");
  vlDebugMacro(<< "Read " << newPolys->GetNumberOfCells() << " triangles\n");
//
// Since we sized the dynamic arrays arbitrarily to begin with
// need to resize them to fit data
//
  newPts->Squeeze();
  newPolys->Squeeze();
//
// Update ourselves
//
  this->SetPoints(newPts);
  this->SetPolys(newPolys);
}

int vlSTLReader::ReadBinarySTL(FILE *fp, vlFloatPoints *newPts, vlCellArray *newPolys)
{
  int i, numTris, pts[3];
  unsigned long   ulint;
  unsigned short  ibuff2;
  char    header[81];
  vlByteSwap swap;
  typedef struct  {float  n[3], v1[3], v2[3], v3[3];} facet_t;
  facet_t facet;

  vlDebugMacro(<< " Reading BINARY STL file\n");
//
//  File is read to obtain raw information as well as bounding box
//
  fread (header, 1, 80, fp);
  fread (&ulint, 1, 4, fp);
  swap.Swap4 (&ulint);
//
// Many .stl files contain bogus count.  Hence we will ignore and read
//   until end of file.
//
  if ( (numTris = (int) ulint) <= 0 )
    {
    vlDebugMacro(<< "Bad binary count (" << numTris << ")\n");
    }

  while ( fread(&facet,48,1,fp) > 0 )
    {
    fread(&ibuff2,2,1,fp); /* read extra junk */

    swap.Swap4 (facet.n);
    swap.Swap4 (facet.n+1);
    swap.Swap4 (facet.n+2);

    swap.Swap4 (facet.v1);
    swap.Swap4 (facet.v1+1);
    swap.Swap4 (facet.v1+2);
    pts[0] = newPts->InsertNextPoint(facet.v1);

    swap.Swap4 (facet.v2);
    swap.Swap4 (facet.v2+1);
    swap.Swap4 (facet.v2+2);
    pts[1] = newPts->InsertNextPoint(facet.v2);

    swap.Swap4 (facet.v3);
    swap.Swap4 (facet.v3+1);
    swap.Swap4 (facet.v3+2);
    pts[2] = newPts->InsertNextPoint(facet.v3);

    newPolys->InsertNextCell(3,pts);

    if (this->Debug && (i % 5000) == 0 && i != 0 )
      fprintf (stderr,"%s: triangle #%d\n", this->GetClassName(), i);
    }

  return 0;
}

int vlSTLReader::ReadASCIISTL(FILE *fp, vlFloatPoints *newPts, vlCellArray *newPolys)
{
  char line[256];
  int i;
  float x[3];
  int pts[3];

  vlDebugMacro(<< " Reading ASCII STL file\n");
//
//  Ingest header and junk to get to first vertex
//
  fgets (line, 255, fp);
/*
 *  Go into loop, reading  facet normal and vertices
 */
  while (fscanf(fp,"%*s %*s %f %f %f\n", x, x+1, x+2)!=EOF)
    {
    fgets (line, 255, fp);
    fscanf (fp, "%*s %f %f %f\n", x,x+1,x+2);
    pts[0] = newPts->InsertNextPoint(x);
    fscanf (fp, "%*s %f %f %f\n", x,x+1,x+2);
    pts[1] = newPts->InsertNextPoint(x);
    fscanf (fp, "%*s %f %f %f\n", x,x+1,x+2);
    pts[2] = newPts->InsertNextPoint(x);
    fgets (line, 255, fp); /* end loop */
    fgets (line, 255, fp); /* end facet */

    newPolys->InsertNextCell(3,pts);

    if (this->Debug && ((newPolys->GetNumberOfCells() % 5000) == 0) )
      fprintf (stderr,"%s: triangle #%d\n", this->GetClassName(), newPolys->GetNumberOfCells());
    }

  return 0;
}

int vlSTLReader::GetSTLFileType(FILE *fp)
{
  char header[256];
  int type, i;
//
//  Read a little from the file to figure what type it is.
//
  fgets (header, 255, fp); /* first line is always ascii */
  fgets (header, 18, fp);
  for (i=0, type=ASCII; i<17 && type == ASCII; i++) // don't test \0
    if ( ! isprint(header[i]) )
      type = BINARY;
//
// Reset file for reading
//
  rewind (fp);
  return type;
}

void vlSTLReader::PrintSelf(ostream& os, vlIndent indent)
{
  if (this->ShouldIPrint(vlSTLReader::GetClassName()))
    {
    vlPolySource::PrintSelf(os,indent);

    os << indent << "Filename: " << this->Filename << "\n";
    }
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkRGBToVectorAdaptImageFilterTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif
/**
 *
 *  This program illustrates the AdaptImageFilter
 *
 *  The example shows how an Accessor can be used to
 *  convert an RGBPixel image to an image that has
 *  vector pixel type.
 *
 *  This allows to access an RGB image a an image of vectors.
 *
 */

#include <itkAdaptImageFilter.h>
#include <itkImageRegionIteratorWithIndex.h>
#include <itkRGBPixel.h>
#include <itkRGBToVectorPixelAccessor.h>

#include <vnl/vnl_sample.h>

//-------------------------
//
//   Main code
//
//-------------------------
int itkRGBToVectorAdaptImageFilterTest(int, char* [] ) {

  //-------------------------------------
  //     Typedefs for convenience
  //-------------------------------------
  typedef itk::RGBPixel< float >                  RGBPixelType;
  typedef itk::Image< RGBPixelType,   2 >         RGBImageType;

  typedef itk::ImageRegionIteratorWithIndex< RGBImageType >  myRGBIteratorType;

  typedef itk::Accessor::RGBToVectorPixelAccessor<float>    AccessorType;

  typedef AccessorType::ExternalType              VectorPixelType;

  typedef itk::Image< VectorPixelType,   2 >      myImageType;

  typedef itk::ImageRegionIteratorWithIndex< myImageType >  myVectorIteratorType;

  RGBImageType::SizeType size;
  size[0] = 2;
  size[1] = 2;

  RGBImageType::IndexType index;
  index[0] = 0;
  index[1] = 0;

  RGBImageType::RegionType region;
  region.SetIndex( index );
  region.SetSize(  size  );

  RGBImageType::Pointer myImage = RGBImageType::New();

  myImage->SetRegions( region );
  myImage->Allocate();

  myRGBIteratorType  it1( myImage, myImage->GetRequestedRegion() );

  // Value to initialize the pixels
  RGBImageType::PixelType color;

  // Initializing all the pixel in the image
  it1.GoToBegin();
  while( !it1.IsAtEnd() )
    {
    color.Set( (float) vnl_sample_uniform(0.0, 1.0),
               (float) vnl_sample_uniform(0.0, 1.0),
               (float) vnl_sample_uniform(0.0, 1.0) );
    it1.Set(color);
    ++it1;
    }

  // Reading the values to verify the image content
  std::cout << "--- Initial image --- " << std::endl;
  it1.GoToBegin();
  while( !it1.IsAtEnd() )
    {
    const RGBImageType::PixelType c( it1.Get() );
    std::cout << c.GetRed()   << "  ";
    std::cout << c.GetGreen() << "  ";
    std::cout << c.GetBlue()  << std::endl;
    ++it1;
    }

  bool passed = true;

  // Convert to a Vector image
  typedef itk::AdaptImageFilter< RGBImageType,
                                 myImageType,
                                 AccessorType   >  AdaptFilterType;

  AdaptFilterType::Pointer  adaptImageToVector = AdaptFilterType::New();

  adaptImageToVector->SetInput(myImage);
  adaptImageToVector->UpdateLargestPossibleRegion();

  myVectorIteratorType  it(
            adaptImageToVector->GetOutput(),
            adaptImageToVector->GetOutput()->GetRequestedRegion() );

  std::cout << "--- Read Vector values --- " << std::endl;

  it.GoToBegin();
  it1.GoToBegin();
  while( !it.IsAtEnd() )
  {
  std::cout << it.Get()   << std::endl;
  VectorPixelType v =   it.Get();
  RGBPixelType    c =  it1.Get();

  if ( v[0] != c.GetRed()   ||
       v[1] != c.GetGreen() ||
       v[2] != c.GetBlue()     )
    {
    std::cerr << "Vector pixel = " << v << std::endl;
    std::cerr << "does not match " << std::endl;
    std::cerr << "RGB    pixel = " << c << std::endl;
    passed = false;
    break;
    }

  ++it;
  ++it1;
  }

  std::cout << std::endl;
  if (passed)
    {
    std::cout << "AdaptImageFilterTest passed" << std::endl;
    return EXIT_SUCCESS;
    }
  else
    {
    std::cout << "AdaptImageFilterTest passed" << std::endl;
    return EXIT_FAILURE;
    }
}

<commit_msg>ENH: just a little more info if we fail.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkRGBToVectorAdaptImageFilterTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif
/**
 *
 *  This program illustrates the AdaptImageFilter
 *
 *  The example shows how an Accessor can be used to
 *  convert an RGBPixel image to an image that has
 *  vector pixel type.
 *
 *  This allows to access an RGB image a an image of vectors.
 *
 */

#include <itkAdaptImageFilter.h>
#include <itkImageRegionIteratorWithIndex.h>
#include <itkRGBPixel.h>
#include <itkRGBToVectorPixelAccessor.h>

#include <vnl/vnl_sample.h>

//-------------------------
//
//   Main code
//
//-------------------------
int itkRGBToVectorAdaptImageFilterTest(int, char* [] ) {

  //-------------------------------------
  //     Typedefs for convenience
  //-------------------------------------
  typedef itk::RGBPixel< float >                  RGBPixelType;
  typedef itk::Image< RGBPixelType,   2 >         RGBImageType;

  typedef itk::ImageRegionIteratorWithIndex< RGBImageType >  myRGBIteratorType;

  typedef itk::Accessor::RGBToVectorPixelAccessor<float>    AccessorType;

  typedef AccessorType::ExternalType              VectorPixelType;

  typedef itk::Image< VectorPixelType,   2 >      myImageType;

  typedef itk::ImageRegionIteratorWithIndex< myImageType >  myVectorIteratorType;

  RGBImageType::SizeType size;
  size[0] = 2;
  size[1] = 2;

  RGBImageType::IndexType index;
  index[0] = 0;
  index[1] = 0;

  RGBImageType::RegionType region;
  region.SetIndex( index );
  region.SetSize(  size  );

  RGBImageType::Pointer myImage = RGBImageType::New();

  myImage->SetRegions( region );
  myImage->Allocate();

  myRGBIteratorType  it1( myImage, myImage->GetRequestedRegion() );

  // Value to initialize the pixels
  RGBImageType::PixelType color;

  // Initializing all the pixel in the image
  it1.GoToBegin();
  while( !it1.IsAtEnd() )
    {
    color.Set( (float) vnl_sample_uniform(0.0, 1.0),
               (float) vnl_sample_uniform(0.0, 1.0),
               (float) vnl_sample_uniform(0.0, 1.0) );
    it1.Set(color);
    ++it1;
    }

  // Reading the values to verify the image content
  std::cout << "--- Initial image --- " << std::endl;
  it1.GoToBegin();
  while( !it1.IsAtEnd() )
    {
    const RGBImageType::PixelType c( it1.Get() );
    std::cout << c.GetRed()   << "  ";
    std::cout << c.GetGreen() << "  ";
    std::cout << c.GetBlue()  << std::endl;
    ++it1;
    }

  bool passed = true;

  // Convert to a Vector image
  typedef itk::AdaptImageFilter< RGBImageType,
                                 myImageType,
                                 AccessorType   >  AdaptFilterType;

  AdaptFilterType::Pointer  adaptImageToVector = AdaptFilterType::New();

  adaptImageToVector->SetInput(myImage);
  adaptImageToVector->UpdateLargestPossibleRegion();

  myVectorIteratorType  it(
            adaptImageToVector->GetOutput(),
            adaptImageToVector->GetOutput()->GetRequestedRegion() );

  std::cout << "--- Read Vector values --- " << std::endl;

  it.GoToBegin();
  it1.GoToBegin();
  while( !it.IsAtEnd() )
  {
  std::cout << it.Get()   << std::endl;
  VectorPixelType v =   it.Get();
  RGBPixelType    c =  it1.Get();

  if ( v[0] != c.GetRed()   ||
       v[1] != c.GetGreen() ||
       v[2] != c.GetBlue()     )
    {
    std::cerr << "Vector pixel = " << v << std::endl;
    std::cerr << "does not match " << std::endl;
    std::cerr << "RGB    pixel = " << c << std::endl;
    std::cerr << "myImage->GetRequestedRegion()" << myImage->GetRequestedRegion() << std::endl;
    std::cerr << "adaptImageToVector->GetRequestedRegion()" << adaptImageToVector->GetOutput()->GetRequestedRegion() << std::endl;
    passed = false;
    break;
    }

  ++it;
  ++it1;
  }

  std::cout << std::endl;
  if (passed)
    {
    std::cout << "AdaptImageFilterTest passed" << std::endl;
    return EXIT_SUCCESS;
    }
  else
    {
    std::cout << "AdaptImageFilterTest passed" << std::endl;
    return EXIT_FAILURE;
    }
}

<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkNeighborhoodOperatorImageFunctionTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include <stdio.h>

#include "itkNeighborhoodOperatorImageFunction.h"

#include "itkImage.h"
#include "itkGaussianOperator.h"

int itkNeighborhoodOperatorImageFunctionTest(int, char* [] )
{

  const unsigned int Dimension = 3;
  typedef float  PixelType;
  typedef itk::Image< PixelType, Dimension > ImageType;
  typedef itk::GaussianOperator<PixelType,3>      NeighborhoodOperatorType;
  typedef itk::NeighborhoodOperatorImageFunction< ImageType,double> FunctionType;

  // Create and allocate the image
  ImageType::Pointer      image = ImageType::New();
  ImageType::SizeType     size;
  ImageType::IndexType    start;
  ImageType::RegionType   region;

  size[0] = 50;
  size[1] = 50;
  size[2] = 50;

  start.Fill( 0 );

  region.SetIndex( start );
  region.SetSize( size );

  image->SetRegions( region );
  image->Allocate();

  ImageType::PixelType initialValue = 27;
  image->FillBuffer( initialValue );

  FunctionType::Pointer function = FunctionType::New();
  function->SetInputImage( image );

  NeighborhoodOperatorType* oper= new NeighborhoodOperatorType;
  oper->CreateToRadius(3);

  function->SetOperator(*oper);

  itk::Index<3>    index;
  index.Fill(25);

  FunctionType::OutputType  Blur;

  Blur = function->EvaluateAtIndex( index );

  // since the input image is constant
  // the should be equal to the initial value
  if( vnl_math_abs( initialValue - Blur ) > 10e-7 )
    {
    std::cerr << "Error in Blur computation" << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "[PASSED] " << std::endl;
  return EXIT_SUCCESS;

}

<commit_msg>ERR: memory leak.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkNeighborhoodOperatorImageFunctionTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include <stdio.h>

#include "itkNeighborhoodOperatorImageFunction.h"

#include "itkImage.h"
#include "itkGaussianOperator.h"

int itkNeighborhoodOperatorImageFunctionTest(int, char* [] )
{

  const unsigned int Dimension = 3;
  typedef float  PixelType;
  typedef itk::Image< PixelType, Dimension > ImageType;
  typedef itk::GaussianOperator<PixelType,3>      NeighborhoodOperatorType;
  typedef itk::NeighborhoodOperatorImageFunction< ImageType,double> FunctionType;

  // Create and allocate the image
  ImageType::Pointer      image = ImageType::New();
  ImageType::SizeType     size;
  ImageType::IndexType    start;
  ImageType::RegionType   region;

  size[0] = 50;
  size[1] = 50;
  size[2] = 50;

  start.Fill( 0 );

  region.SetIndex( start );
  region.SetSize( size );

  image->SetRegions( region );
  image->Allocate();

  ImageType::PixelType initialValue = 27;
  image->FillBuffer( initialValue );

  FunctionType::Pointer function = FunctionType::New();
  function->SetInputImage( image );

  NeighborhoodOperatorType* oper= new NeighborhoodOperatorType;
  oper->CreateToRadius(3);

  function->SetOperator(*oper);
  delete oper;

  itk::Index<3>    index;
  index.Fill(25);

  FunctionType::OutputType  Blur;

  Blur = function->EvaluateAtIndex( index );

  // since the input image is constant
  // the should be equal to the initial value
  if( vnl_math_abs( initialValue - Blur ) > 10e-7 )
    {
    std::cerr << "Error in Blur computation" << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "[PASSED] " << std::endl;
  return EXIT_SUCCESS;

}

<|endoftext|>


<commit_before>/*
*   Copyright (c) 2010-2014, MIT Probabilistic Computing Project
*
*   Lead Developers: Dan Lovell and Jay Baxter
*   Authors: Dan Lovell, Baxter Eaves, Jay Baxter, Vikash Mansinghka
*   Research Leads: Vikash Mansinghka, Patrick Shafto
*
*   Licensed under the Apache License, Version 2.0 (the "License");
*   you may not use this file except in compliance with the License.
*   You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*   Unless required by applicable law or agreed to in writing, software
*   distributed under the License is distributed on an "AS IS" BASIS,
*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*   See the License for the specific language governing permissions and
*   limitations under the License.
*/
#include <iostream>
//
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>
//
#include "State.h"
#include "utils.h"
#include "constants.h"
//
typedef boost::numeric::ublas::matrix<double> matrixD;
using namespace std;

int n_iterations = 10;
string filename = "T.csv";

// passing in a State is dangerous, if you don't pass in a reference, memory will be deallocated
// and bugs/segfaults will occur
void print_state_summary(const State& s) {
    cout << "s.num_views: " << s.get_num_views() << endl;
    for (int j = 0; j < s.get_num_views(); j++) {
        cout << "view " << j;
        cout << " row_paritition_model_counts: " << s.get_row_partition_model_counts_i(
                 j) << endl;
    }
    cout << "s.column_crp_score: " << s.get_column_crp_score();
    cout << "; s.data_score: " << s.get_data_score();
    cout << "; s.score: " << s.get_marginal_logp();
    cout << endl;
    return;
}

int main(int argc, char** argv) {
    cout << endl << "test_state: Hello World!" << endl;

    // load some data
    matrixD data;
    LoadData(filename, data);
    cout << "data is: " << data << endl;
    int num_rows = data.size1();
    int num_cols = data.size2();

    // create the objects to test
    vector<int> global_row_indices = create_sequence(data.size1());
    vector<int> global_column_indices = create_sequence(data.size2());
    vector<string> global_col_types;
    vector<int> global_col_multinomial_counts;
    for (int i = 0; i < global_column_indices.size(); i++) {
        global_col_types.push_back(CONTINUOUS_DATATYPE);
        global_col_multinomial_counts.push_back(0);
    }
    State s = State(data, global_col_types,
                    global_col_multinomial_counts,
                    global_row_indices,
                    global_column_indices);

    cout << "start X_D" << endl << s.get_X_D() << endl;
    // cout << "State:" << endl << s << endl;

    vector<int> empty_int_v;
    for (int i = 0; i < n_iterations; i++) {
        cout << "transition #: " << i << endl;
        s.transition_column_crp_alpha();
        s.transition_column_hyperparameters(empty_int_v);
        s.transition_row_partition_hyperparameters(empty_int_v);
        s.transition_features(data, empty_int_v);
        s.transition_row_partition_assignments(data, empty_int_v);
        // s.transition(data);
        print_state_summary(s);
    }

    // cout << "FINAL STATE" << endl;
    // cout << s << endl;
    cout << "end X_D" << endl << s.get_X_D() << endl;

    cout << endl << "test_state: Goodbye World!" << endl;
}
<commit_msg>Avoid copying State in test_state.cpp.<commit_after>/*
*   Copyright (c) 2010-2014, MIT Probabilistic Computing Project
*
*   Lead Developers: Dan Lovell and Jay Baxter
*   Authors: Dan Lovell, Baxter Eaves, Jay Baxter, Vikash Mansinghka
*   Research Leads: Vikash Mansinghka, Patrick Shafto
*
*   Licensed under the Apache License, Version 2.0 (the "License");
*   you may not use this file except in compliance with the License.
*   You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*   Unless required by applicable law or agreed to in writing, software
*   distributed under the License is distributed on an "AS IS" BASIS,
*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*   See the License for the specific language governing permissions and
*   limitations under the License.
*/
#include <iostream>
//
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>
//
#include "State.h"
#include "utils.h"
#include "constants.h"
//
typedef boost::numeric::ublas::matrix<double> matrixD;
using namespace std;

int n_iterations = 10;
string filename = "T.csv";

// passing in a State is dangerous, if you don't pass in a reference, memory will be deallocated
// and bugs/segfaults will occur
void print_state_summary(const State& s) {
    cout << "s.num_views: " << s.get_num_views() << endl;
    for (int j = 0; j < s.get_num_views(); j++) {
        cout << "view " << j;
        cout << " row_paritition_model_counts: " << s.get_row_partition_model_counts_i(
                 j) << endl;
    }
    cout << "s.column_crp_score: " << s.get_column_crp_score();
    cout << "; s.data_score: " << s.get_data_score();
    cout << "; s.score: " << s.get_marginal_logp();
    cout << endl;
    return;
}

int main(int argc, char** argv) {
    cout << endl << "test_state: Hello World!" << endl;

    // load some data
    matrixD data;
    LoadData(filename, data);
    cout << "data is: " << data << endl;
    int num_rows = data.size1();
    int num_cols = data.size2();

    // create the objects to test
    vector<int> global_row_indices = create_sequence(data.size1());
    vector<int> global_column_indices = create_sequence(data.size2());
    vector<string> global_col_types;
    vector<int> global_col_multinomial_counts;
    for (int i = 0; i < global_column_indices.size(); i++) {
        global_col_types.push_back(CONTINUOUS_DATATYPE);
        global_col_multinomial_counts.push_back(0);
    }
    State s(data, global_col_types,
                    global_col_multinomial_counts,
                    global_row_indices,
                    global_column_indices);

    cout << "start X_D" << endl << s.get_X_D() << endl;
    // cout << "State:" << endl << s << endl;

    vector<int> empty_int_v;
    for (int i = 0; i < n_iterations; i++) {
        cout << "transition #: " << i << endl;
        s.transition_column_crp_alpha();
        s.transition_column_hyperparameters(empty_int_v);
        s.transition_row_partition_hyperparameters(empty_int_v);
        s.transition_features(data, empty_int_v);
        s.transition_row_partition_assignments(data, empty_int_v);
        // s.transition(data);
        print_state_summary(s);
    }

    // cout << "FINAL STATE" << endl;
    // cout << s << endl;
    cout << "end X_D" << endl << s.get_X_D() << endl;

    cout << endl << "test_state: Goodbye World!" << endl;
}
<|endoftext|>


<commit_before><commit_msg>Missing const<commit_after><|endoftext|>


<commit_before>//===--- ClassHierarchyAnalysis.cpp - Class hierarchy analysis ------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/SILOptimizer/Analysis/ClassHierarchyAnalysis.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/ASTWalker.h"
#include "swift/AST/Module.h"
#include "swift/SIL/SILInstruction.h"
#include "swift/SIL/SILValue.h"
#include "swift/SIL/SILModule.h"

using namespace swift;

namespace {
/// A helper class to collect all nominal type declarations.
class NominalTypeWalker: public ASTWalker {
  ClassHierarchyAnalysis::ProtocolImplementations &ProtocolImplementationsCache;
public:
  NominalTypeWalker(ClassHierarchyAnalysis::ProtocolImplementations
                        &ProtocolImplementationsCache)
    :ProtocolImplementationsCache(ProtocolImplementationsCache) {
  }

  virtual bool walkToDeclPre(Decl *D) {
    auto *NTD = dyn_cast<NominalTypeDecl>(D);
    if (!NTD)
      return true;
    auto Protocols = NTD->getAllProtocols();
    // We are only interested in types implementing protocols.
    if (!Protocols.empty()) {
      for (auto &Protocol : Protocols) {
        auto &K = ProtocolImplementationsCache[Protocol];
        K.push_back(NTD);
      }
    }
    return true;
  }
};
}

void ClassHierarchyAnalysis::init() {
  // Process all types implementing protocols.
  SmallVector<Decl *, 32> Decls;
  // TODO: It would be better if we could get all declarations
  // from a given module, not only the top-level ones.
  M->getSwiftModule()->getTopLevelDecls(Decls);

  NominalTypeWalker Walker(ProtocolImplementationsCache);
  for (auto *D: Decls) {
    D->walk(Walker);
  }

  // For each class declaration in our V-table list:
  for (auto &VT : M->getVTableList()) {
    ClassDecl *C = VT.getClass();
    // Ignore classes that are at the top of the class hierarchy:
    if (!C->hasSuperclass())
      continue;

    // Add the superclass to the list of inherited classes.
    ClassDecl *Super = C->getSuperclass()->getClassOrBoundGenericClass();
    auto &K = DirectSubclassesCache[Super];
    assert(std::find(K.begin(), K.end(), C) == K.end() &&
           "Class vector must be unique");
    K.push_back(C);
  }
}

/// \brief Get all subclasses of a given class.
/// Does not include any direct subclasses of given base class.
///
/// \p Base class, whose direct subclasses are to be excluded
/// \p Current class, whose direct and indirect subclasses are
///    to be collected.
/// \p IndirectSubs placeholder for collected results
void ClassHierarchyAnalysis::getIndirectSubClasses(ClassDecl *Cur,
                                                   ClassList &IndirectSubs) {
  unsigned Idx = IndirectSubs.size();

  if (!hasKnownDirectSubclasses(Cur))
    return;

  // Produce a set of all indirect subclasses in a
  // breadth-first order;

  // First add subclasses of direct subclasses.
  for (auto C : getDirectSubClasses(Cur)) {
    // Get direct subclasses
    if (!hasKnownDirectSubclasses(C))
      continue;
    auto &DirectSubclasses = getDirectSubClasses(C);
    // Remember all direct subclasses of the current one.
    for (auto S : DirectSubclasses) {
      IndirectSubs.push_back(S);
    }
  }

  // Then recursively add direct subclasses of already
  // added subclasses.
  while (Idx != IndirectSubs.size()) {
    auto C = IndirectSubs[Idx++];
    // Get direct subclasses
    if (!hasKnownDirectSubclasses(C))
      continue;
    auto &DirectSubclasses = getDirectSubClasses(C);
    // Remember all direct subclasses of the current one.
    for (auto S : DirectSubclasses) {
      IndirectSubs.push_back(S);
    }
  }
}

ClassHierarchyAnalysis::~ClassHierarchyAnalysis() {}
<commit_msg>[Analysis] Adjust inline documentation in ClassHierarchyAnalysis.cpp<commit_after>//===--- ClassHierarchyAnalysis.cpp - Class hierarchy analysis ------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/SILOptimizer/Analysis/ClassHierarchyAnalysis.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/ASTWalker.h"
#include "swift/AST/Module.h"
#include "swift/SIL/SILInstruction.h"
#include "swift/SIL/SILValue.h"
#include "swift/SIL/SILModule.h"

using namespace swift;

namespace {
/// A helper class to collect all nominal type declarations.
class NominalTypeWalker: public ASTWalker {
  ClassHierarchyAnalysis::ProtocolImplementations &ProtocolImplementationsCache;
public:
  NominalTypeWalker(ClassHierarchyAnalysis::ProtocolImplementations
                        &ProtocolImplementationsCache)
    :ProtocolImplementationsCache(ProtocolImplementationsCache) {
  }

  virtual bool walkToDeclPre(Decl *D) {
    auto *NTD = dyn_cast<NominalTypeDecl>(D);
    if (!NTD)
      return true;
    auto Protocols = NTD->getAllProtocols();
    // We are only interested in types implementing protocols.
    if (!Protocols.empty()) {
      for (auto &Protocol : Protocols) {
        auto &K = ProtocolImplementationsCache[Protocol];
        K.push_back(NTD);
      }
    }
    return true;
  }
};
}

void ClassHierarchyAnalysis::init() {
  // Process all types implementing protocols.
  SmallVector<Decl *, 32> Decls;
  // TODO: It would be better if we could get all declarations
  // from a given module, not only the top-level ones.
  M->getSwiftModule()->getTopLevelDecls(Decls);

  NominalTypeWalker Walker(ProtocolImplementationsCache);
  for (auto *D: Decls) {
    D->walk(Walker);
  }

  // For each class declaration in our V-table list:
  for (auto &VT : M->getVTableList()) {
    ClassDecl *C = VT.getClass();
    // Ignore classes that are at the top of the class hierarchy:
    if (!C->hasSuperclass())
      continue;

    // Add the superclass to the list of inherited classes.
    ClassDecl *Super = C->getSuperclass()->getClassOrBoundGenericClass();
    auto &K = DirectSubclassesCache[Super];
    assert(std::find(K.begin(), K.end(), C) == K.end() &&
           "Class vector must be unique");
    K.push_back(C);
  }
}

/// \brief Get all subclasses of a given class.
///
/// \p Current class, whose direct and indirect subclasses are
///    to be collected.
/// \p IndirectSubs placeholder for collected results
void ClassHierarchyAnalysis::getIndirectSubClasses(ClassDecl *Cur,
                                                   ClassList &IndirectSubs) {
  unsigned Idx = IndirectSubs.size();

  if (!hasKnownDirectSubclasses(Cur))
    return;

  // Produce a set of all indirect subclasses in a
  // breadth-first order;

  // First add subclasses of direct subclasses.
  for (auto C : getDirectSubClasses(Cur)) {
    // Get direct subclasses
    if (!hasKnownDirectSubclasses(C))
      continue;
    auto &DirectSubclasses = getDirectSubClasses(C);
    // Remember all direct subclasses of the current one.
    for (auto S : DirectSubclasses) {
      IndirectSubs.push_back(S);
    }
  }

  // Then recursively add direct subclasses of already
  // added subclasses.
  while (Idx != IndirectSubs.size()) {
    auto C = IndirectSubs[Idx++];
    // Get direct subclasses
    if (!hasKnownDirectSubclasses(C))
      continue;
    auto &DirectSubclasses = getDirectSubClasses(C);
    // Remember all direct subclasses of the current one.
    for (auto S : DirectSubclasses) {
      IndirectSubs.push_back(S);
    }
  }
}

ClassHierarchyAnalysis::~ClassHierarchyAnalysis() {}
<|endoftext|>


<commit_before>/**
 * \file
 * \brief Definitions of clocks for STM32L0
 *
 * \author Copyright (C) 2017 Cezary Gapinski cezary.gapinski@gmail.com
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#ifndef SOURCE_CHIP_STM32_STM32L0_INCLUDE_DISTORTOS_CHIP_CLOCKS_HPP_
#define SOURCE_CHIP_STM32_STM32L0_INCLUDE_DISTORTOS_CHIP_CLOCKS_HPP_

#include "distortos/distortosConfiguration.h"

#include <cstdint>

namespace distortos
{

namespace chip
{

/*---------------------------------------------------------------------------------------------------------------------+
| global constants
+---------------------------------------------------------------------------------------------------------------------*/

/// allowed values for MSI frequency, Hz
/// [0] - range 0 around 65.536 kHz
/// [1] - range 1 around 131.072 kHz
/// [2] - range 2 around 262.144 kHz
/// [3] - range 3 around 524.288 kHz
/// [4] - range 4 around 1.048 MHz
/// [5] - range 5 around 2.097 MHz
/// [6] - range 6 around 4.194 MHz
constexpr uint32_t msiFrequencies[7]
{
		65536,
		131072,
		262144,
		524288,
		1048000,
		2097000,
		4194000,
};

/// HSI16 clock frequency, Hz
constexpr uint32_t hsi16Frequency {16000000};

/// minimum allowed value for PLL VCO input frequency, Hz
constexpr uint32_t minPllInFrequency {2000000};

/// maximum allowed value for PLL VCO input frequency, Hz
constexpr uint32_t maxPllInFrequency {24000000};

/// minimum allowed value for PLL output frequency, Hz
constexpr uint32_t minPllOutFrequency {1500000};

/// maximum allowed values for PLL output frequency, Hz
/// [0] - voltage scale 1
/// [1] - voltage scale 2
/// [2] - voltage scale 3
constexpr uint32_t maxPllOutFrequencies[3]
{
		960000000,
		480000000,
		240000000,
};

/// maximum allowed APB1 (low speed) frequency, Hz
constexpr uint32_t maxApb1Frequency {32000000};

/// maximum allowed APB2 (high speed) frequency, Hz
constexpr uint32_t maxApb2Frequency {32000000};

#ifdef CONFIG_CHIP_STM32L0_STANDARD_CLOCK_CONFIGURATION_ENABLE

/// voltage scale index for \a maxPllOutFrequencies array (maxPllOutFrequencies[voltageScaleIndex])
constexpr uint8_t voltageScaleIndex {CONFIG_CHIP_STM32L0_PWR_VOLTAGE_SCALE_MODE - 1};

/// maximum allowed value for PLL output frequency, Hz
constexpr uint32_t maxPllOutFrequency {maxPllOutFrequencies[voltageScaleIndex]};

#if defined(CONFIG_CHIP_STM32L0_RCC_MSI_ENABLE)
/// voltage scale index for \a msiFrequencies array (maxPllOutFrequencies[msiRangeIndex])
constexpr uint8_t msiRangeIndex {CONFIG_CHIP_STM32L0_RCC_MSIRANGE};

/// allowed value for MSI frequency, Hz
constexpr uint32_t msiFrequency {msiFrequencies[msiRangeIndex]};

#endif	// defined(CONFIG_CHIP_STM32L0_RCC_MSI_ENABLE)

#ifdef CONFIG_CHIP_STM32L0_RCC_PLL_ENABLE

/// PLL input frequency, Hz
#if defined(CONFIG_CHIP_STM32L0_RCC_PLLSRC_HSI16)
constexpr uint32_t pllInFrequency {hsi16Frequency};
#elif defined(CONFIG_CHIP_STM32L0_RCC_PLLSRC_HSE)
constexpr uint32_t pllInFrequency {CONFIG_CHIP_STM32L0_RCC_HSE_FREQUENCY};
#endif	// defined(CONFIG_CHIP_STM32L0_RCC_PLLSRC_HSE)

static_assert(minPllInFrequency <= pllInFrequency && pllInFrequency <= maxPllInFrequency,
		"Invalid PLL input frequency!");

/// PLL output frequency, Hz
constexpr uint32_t pllOutFrequency {(pllInFrequency * CONFIG_CHIP_STM32L0_RCC_PLLMUL) / CONFIG_CHIP_STM32L0_RCC_PLLDIV};

static_assert(minPllOutFrequency <= pllOutFrequency && pllOutFrequency <= maxPllOutFrequency,
		"Invalid PLL output frequency!");

#endif	// def CONFIG_CHIP_STM32L0_RCC_PLL_ENABLE

/// SYSCLK frequency, Hz
#if defined(CONFIG_CHIP_STM32L0_RCC_SYSCLK_MSI)
constexpr uint32_t sysclkFrequency {msiFrequency};
#elif defined(CONFIG_CHIP_STM32L0_RCC_SYSCLK_HSI16)
constexpr uint32_t sysclkFrequency {hsi16Frequency};
#elif defined(CONFIG_CHIP_STM32L0_RCC_SYSCLK_HSE)
constexpr uint32_t sysclkFrequency {CONFIG_CHIP_STM32L0_RCC_HSE_FREQUENCY};
#elif defined(CONFIG_CHIP_STM32L0_RCC_SYSCLK_PLL)
constexpr uint32_t sysclkFrequency {pllOutFrequency};
#else
#error "All SYSCLK sources disabled!"
#endif	// defined(CONFIG_CHIP_STM32L0_RCC_SYSCLK_PLL)

#else	// !def CONFIG_CHIP_STM32L0_STANDARD_CLOCK_CONFIGURATION_ENABLE

/// SYSCLK frequency, Hz
constexpr uint32_t sysclkFrequency {CONFIG_CHIP_STM32L0_RCC_SYSCLK_FREQUENCY};

#endif	// !def CONFIG_CHIP_STM32L0_STANDARD_CLOCK_CONFIGURATION_ENABLE

/// AHB frequency, Hz
constexpr uint32_t ahbFrequency {sysclkFrequency / CONFIG_CHIP_STM32L0_RCC_HPRE};

/// APB1 frequency, Hz
constexpr uint32_t apb1Frequency {ahbFrequency / CONFIG_CHIP_STM32L0_RCC_PPRE1};

static_assert(apb1Frequency <= maxApb1Frequency, "Invalid APB1 (low speed) frequency!");

/// APB2 frequency, Hz
constexpr uint32_t apb2Frequency {ahbFrequency / CONFIG_CHIP_STM32L0_RCC_PPRE2};

static_assert(apb2Frequency <= maxApb2Frequency, "Invalid APB2 (high speed) frequency!");

}	// namespace chip

}	// namespace distortos

#endif	// SOURCE_CHIP_STM32_STM32L0_INCLUDE_DISTORTOS_CHIP_CLOCKS_HPP_
<commit_msg>Simplify comment for msiFrequencies[] in clocks.hpp for STM32L0<commit_after>/**
 * \file
 * \brief Definitions of clocks for STM32L0
 *
 * \author Copyright (C) 2017 Cezary Gapinski cezary.gapinski@gmail.com
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#ifndef SOURCE_CHIP_STM32_STM32L0_INCLUDE_DISTORTOS_CHIP_CLOCKS_HPP_
#define SOURCE_CHIP_STM32_STM32L0_INCLUDE_DISTORTOS_CHIP_CLOCKS_HPP_

#include "distortos/distortosConfiguration.h"

#include <cstdint>

namespace distortos
{

namespace chip
{

/*---------------------------------------------------------------------------------------------------------------------+
| global constants
+---------------------------------------------------------------------------------------------------------------------*/

/// MSI frequencies, Hz
/// [0] - range 0
/// [1] - range 1
/// [2] - range 2
/// [3] - range 3
/// [4] - range 4
/// [5] - range 5
/// [6] - range 6
constexpr uint32_t msiFrequencies[7]
{
		65536,
		131072,
		262144,
		524288,
		1048000,
		2097000,
		4194000,
};

/// HSI16 clock frequency, Hz
constexpr uint32_t hsi16Frequency {16000000};

/// minimum allowed value for PLL VCO input frequency, Hz
constexpr uint32_t minPllInFrequency {2000000};

/// maximum allowed value for PLL VCO input frequency, Hz
constexpr uint32_t maxPllInFrequency {24000000};

/// minimum allowed value for PLL output frequency, Hz
constexpr uint32_t minPllOutFrequency {1500000};

/// maximum allowed values for PLL output frequency, Hz
/// [0] - voltage scale 1
/// [1] - voltage scale 2
/// [2] - voltage scale 3
constexpr uint32_t maxPllOutFrequencies[3]
{
		960000000,
		480000000,
		240000000,
};

/// maximum allowed APB1 (low speed) frequency, Hz
constexpr uint32_t maxApb1Frequency {32000000};

/// maximum allowed APB2 (high speed) frequency, Hz
constexpr uint32_t maxApb2Frequency {32000000};

#ifdef CONFIG_CHIP_STM32L0_STANDARD_CLOCK_CONFIGURATION_ENABLE

/// voltage scale index for \a maxPllOutFrequencies array (maxPllOutFrequencies[voltageScaleIndex])
constexpr uint8_t voltageScaleIndex {CONFIG_CHIP_STM32L0_PWR_VOLTAGE_SCALE_MODE - 1};

/// maximum allowed value for PLL output frequency, Hz
constexpr uint32_t maxPllOutFrequency {maxPllOutFrequencies[voltageScaleIndex]};

#if defined(CONFIG_CHIP_STM32L0_RCC_MSI_ENABLE)
/// voltage scale index for \a msiFrequencies array (maxPllOutFrequencies[msiRangeIndex])
constexpr uint8_t msiRangeIndex {CONFIG_CHIP_STM32L0_RCC_MSIRANGE};

/// allowed value for MSI frequency, Hz
constexpr uint32_t msiFrequency {msiFrequencies[msiRangeIndex]};

#endif	// defined(CONFIG_CHIP_STM32L0_RCC_MSI_ENABLE)

#ifdef CONFIG_CHIP_STM32L0_RCC_PLL_ENABLE

/// PLL input frequency, Hz
#if defined(CONFIG_CHIP_STM32L0_RCC_PLLSRC_HSI16)
constexpr uint32_t pllInFrequency {hsi16Frequency};
#elif defined(CONFIG_CHIP_STM32L0_RCC_PLLSRC_HSE)
constexpr uint32_t pllInFrequency {CONFIG_CHIP_STM32L0_RCC_HSE_FREQUENCY};
#endif	// defined(CONFIG_CHIP_STM32L0_RCC_PLLSRC_HSE)

static_assert(minPllInFrequency <= pllInFrequency && pllInFrequency <= maxPllInFrequency,
		"Invalid PLL input frequency!");

/// PLL output frequency, Hz
constexpr uint32_t pllOutFrequency {(pllInFrequency * CONFIG_CHIP_STM32L0_RCC_PLLMUL) / CONFIG_CHIP_STM32L0_RCC_PLLDIV};

static_assert(minPllOutFrequency <= pllOutFrequency && pllOutFrequency <= maxPllOutFrequency,
		"Invalid PLL output frequency!");

#endif	// def CONFIG_CHIP_STM32L0_RCC_PLL_ENABLE

/// SYSCLK frequency, Hz
#if defined(CONFIG_CHIP_STM32L0_RCC_SYSCLK_MSI)
constexpr uint32_t sysclkFrequency {msiFrequency};
#elif defined(CONFIG_CHIP_STM32L0_RCC_SYSCLK_HSI16)
constexpr uint32_t sysclkFrequency {hsi16Frequency};
#elif defined(CONFIG_CHIP_STM32L0_RCC_SYSCLK_HSE)
constexpr uint32_t sysclkFrequency {CONFIG_CHIP_STM32L0_RCC_HSE_FREQUENCY};
#elif defined(CONFIG_CHIP_STM32L0_RCC_SYSCLK_PLL)
constexpr uint32_t sysclkFrequency {pllOutFrequency};
#else
#error "All SYSCLK sources disabled!"
#endif	// defined(CONFIG_CHIP_STM32L0_RCC_SYSCLK_PLL)

#else	// !def CONFIG_CHIP_STM32L0_STANDARD_CLOCK_CONFIGURATION_ENABLE

/// SYSCLK frequency, Hz
constexpr uint32_t sysclkFrequency {CONFIG_CHIP_STM32L0_RCC_SYSCLK_FREQUENCY};

#endif	// !def CONFIG_CHIP_STM32L0_STANDARD_CLOCK_CONFIGURATION_ENABLE

/// AHB frequency, Hz
constexpr uint32_t ahbFrequency {sysclkFrequency / CONFIG_CHIP_STM32L0_RCC_HPRE};

/// APB1 frequency, Hz
constexpr uint32_t apb1Frequency {ahbFrequency / CONFIG_CHIP_STM32L0_RCC_PPRE1};

static_assert(apb1Frequency <= maxApb1Frequency, "Invalid APB1 (low speed) frequency!");

/// APB2 frequency, Hz
constexpr uint32_t apb2Frequency {ahbFrequency / CONFIG_CHIP_STM32L0_RCC_PPRE2};

static_assert(apb2Frequency <= maxApb2Frequency, "Invalid APB2 (high speed) frequency!");

}	// namespace chip

}	// namespace distortos

#endif	// SOURCE_CHIP_STM32_STM32L0_INCLUDE_DISTORTOS_CHIP_CLOCKS_HPP_
<|endoftext|>


<commit_before>//===- AnalysisOrderChecker - Print callbacks called ------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This checker prints callbacks that are called during analysis.
// This is required to ensure that callbacks are fired in order
// and do not duplicate or get lost.
// Feel free to extend this checker with any callback you need to check.
//
//===----------------------------------------------------------------------===//

#include "ClangSACheckers.h"
#include "clang/AST/ExprCXX.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"

using namespace clang;
using namespace ento;

namespace {

class AnalysisOrderChecker
    : public Checker<check::PreStmt<CastExpr>,
                     check::PostStmt<CastExpr>,
                     check::PreStmt<ArraySubscriptExpr>,
                     check::PostStmt<ArraySubscriptExpr>,
                     check::PreStmt<CXXNewExpr>,
                     check::PostStmt<CXXNewExpr>,
                     check::PreCall,
                     check::PostCall,
                     check::NewAllocator,
                     check::Bind,
                     check::RegionChanges,
                     check::LiveSymbols> {

  bool isCallbackEnabled(AnalyzerOptions &Opts, StringRef CallbackName) const {
    return Opts.getBooleanOption("*", false, this) ||
        Opts.getBooleanOption(CallbackName, false, this);
  }

  bool isCallbackEnabled(CheckerContext &C, StringRef CallbackName) const {
    AnalyzerOptions &Opts = C.getAnalysisManager().getAnalyzerOptions();
    return isCallbackEnabled(Opts, CallbackName);
  }

  bool isCallbackEnabled(ProgramStateRef State, StringRef CallbackName) const {
    AnalyzerOptions &Opts = State->getStateManager().getOwningEngine()
                                 ->getAnalysisManager().getAnalyzerOptions();
    return isCallbackEnabled(Opts, CallbackName);
  }

public:
  void checkPreStmt(const CastExpr *CE, CheckerContext &C) const {
    if (isCallbackEnabled(C, "PreStmtCastExpr"))
      llvm::errs() << "PreStmt<CastExpr> (Kind : " << CE->getCastKindName()
                   << ")\n";
  }

  void checkPostStmt(const CastExpr *CE, CheckerContext &C) const {
    if (isCallbackEnabled(C, "PostStmtCastExpr"))
      llvm::errs() << "PostStmt<CastExpr> (Kind : " << CE->getCastKindName()
                   << ")\n";
  }

  void checkPreStmt(const ArraySubscriptExpr *SubExpr,
                    CheckerContext &C) const {
    if (isCallbackEnabled(C, "PreStmtArraySubscriptExpr"))
      llvm::errs() << "PreStmt<ArraySubscriptExpr>\n";
  }

  void checkPostStmt(const ArraySubscriptExpr *SubExpr,
                     CheckerContext &C) const {
    if (isCallbackEnabled(C, "PostStmtArraySubscriptExpr"))
      llvm::errs() << "PostStmt<ArraySubscriptExpr>\n";
  }

  void checkPreStmt(const CXXNewExpr *NE, CheckerContext &C) const {
    if (isCallbackEnabled(C, "PreStmtCXXNewExpr"))
      llvm::errs() << "PreStmt<CXXNewExpr>\n";
  }

  void checkPostStmt(const CXXNewExpr *NE, CheckerContext &C) const {
    if (isCallbackEnabled(C, "PostStmtCXXNewExpr"))
      llvm::errs() << "PostStmt<CXXNewExpr>\n";
  }

  void checkPreCall(const CallEvent &Call, CheckerContext &C) const {
    if (isCallbackEnabled(C, "PreCall")) {
      llvm::errs() << "PreCall";
      if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(Call.getDecl()))
        llvm::errs() << " (" << ND->getQualifiedNameAsString() << ')';
      llvm::errs() << '\n';
    }
  }

  void checkPostCall(const CallEvent &Call, CheckerContext &C) const {
    if (isCallbackEnabled(C, "PostCall")) {
      llvm::errs() << "PostCall";
      if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(Call.getDecl()))
        llvm::errs() << " (" << ND->getQualifiedNameAsString() << ')';
      llvm::errs() << '\n';
    }
  }

  void checkNewAllocator(const CXXNewExpr *CNE, SVal Target,
                         CheckerContext &C) const {
    if (isCallbackEnabled(C, "NewAllocator"))
      llvm::errs() << "NewAllocator\n";
  }

  void checkBind(SVal Loc, SVal Val, const Stmt *S, CheckerContext &C) const {
    if (isCallbackEnabled(C, "Bind"))
      llvm::errs() << "Bind\n";
  }

  void checkLiveSymbols(ProgramStateRef State, SymbolReaper &SymReaper) const {
    if (isCallbackEnabled(State, "LiveSymbols"))
      llvm::errs() << "LiveSymbols\n";
  }

  ProgramStateRef
  checkRegionChanges(ProgramStateRef State,
                     const InvalidatedSymbols *Invalidated,
                     ArrayRef<const MemRegion *> ExplicitRegions,
                     ArrayRef<const MemRegion *> Regions,
                     const LocationContext *LCtx, const CallEvent *Call) const {
    if (isCallbackEnabled(State, "RegionChanges"))
      llvm::errs() << "RegionChanges\n";
    return State;
  }
};
} // end anonymous namespace

//===----------------------------------------------------------------------===//
// Registration.
//===----------------------------------------------------------------------===//

void ento::registerAnalysisOrderChecker(CheckerManager &mgr) {
  mgr.registerChecker<AnalysisOrderChecker>();
}
<commit_msg>[analyzer] Add missing pre-post-statement callbacks for OffsetOfExpr.<commit_after>//===- AnalysisOrderChecker - Print callbacks called ------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This checker prints callbacks that are called during analysis.
// This is required to ensure that callbacks are fired in order
// and do not duplicate or get lost.
// Feel free to extend this checker with any callback you need to check.
//
//===----------------------------------------------------------------------===//

#include "ClangSACheckers.h"
#include "clang/AST/ExprCXX.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"

using namespace clang;
using namespace ento;

namespace {

class AnalysisOrderChecker
    : public Checker<check::PreStmt<CastExpr>,
                     check::PostStmt<CastExpr>,
                     check::PreStmt<ArraySubscriptExpr>,
                     check::PostStmt<ArraySubscriptExpr>,
                     check::PreStmt<CXXNewExpr>,
                     check::PostStmt<CXXNewExpr>,
                     check::PreStmt<OffsetOfExpr>,
                     check::PostStmt<OffsetOfExpr>,
                     check::PreCall,
                     check::PostCall,
                     check::NewAllocator,
                     check::Bind,
                     check::RegionChanges,
                     check::LiveSymbols> {

  bool isCallbackEnabled(AnalyzerOptions &Opts, StringRef CallbackName) const {
    return Opts.getBooleanOption("*", false, this) ||
        Opts.getBooleanOption(CallbackName, false, this);
  }

  bool isCallbackEnabled(CheckerContext &C, StringRef CallbackName) const {
    AnalyzerOptions &Opts = C.getAnalysisManager().getAnalyzerOptions();
    return isCallbackEnabled(Opts, CallbackName);
  }

  bool isCallbackEnabled(ProgramStateRef State, StringRef CallbackName) const {
    AnalyzerOptions &Opts = State->getStateManager().getOwningEngine()
                                 ->getAnalysisManager().getAnalyzerOptions();
    return isCallbackEnabled(Opts, CallbackName);
  }

public:
  void checkPreStmt(const CastExpr *CE, CheckerContext &C) const {
    if (isCallbackEnabled(C, "PreStmtCastExpr"))
      llvm::errs() << "PreStmt<CastExpr> (Kind : " << CE->getCastKindName()
                   << ")\n";
  }

  void checkPostStmt(const CastExpr *CE, CheckerContext &C) const {
    if (isCallbackEnabled(C, "PostStmtCastExpr"))
      llvm::errs() << "PostStmt<CastExpr> (Kind : " << CE->getCastKindName()
                   << ")\n";
  }

  void checkPreStmt(const ArraySubscriptExpr *SubExpr,
                    CheckerContext &C) const {
    if (isCallbackEnabled(C, "PreStmtArraySubscriptExpr"))
      llvm::errs() << "PreStmt<ArraySubscriptExpr>\n";
  }

  void checkPostStmt(const ArraySubscriptExpr *SubExpr,
                     CheckerContext &C) const {
    if (isCallbackEnabled(C, "PostStmtArraySubscriptExpr"))
      llvm::errs() << "PostStmt<ArraySubscriptExpr>\n";
  }

  void checkPreStmt(const CXXNewExpr *NE, CheckerContext &C) const {
    if (isCallbackEnabled(C, "PreStmtCXXNewExpr"))
      llvm::errs() << "PreStmt<CXXNewExpr>\n";
  }

  void checkPostStmt(const CXXNewExpr *NE, CheckerContext &C) const {
    if (isCallbackEnabled(C, "PostStmtCXXNewExpr"))
      llvm::errs() << "PostStmt<CXXNewExpr>\n";
  }

  void checkPreStmt(const OffsetOfExpr *OOE, CheckerContext &C) const {
    if (isCallbackEnabled(C, "PreStmtOffsetOfExpr"))
      llvm::errs() << "PreStmt<OffsetOfExpr>\n";
  }

  void checkPostStmt(const OffsetOfExpr *OOE, CheckerContext &C) const {
    if (isCallbackEnabled(C, "PostStmtOffsetOfExpr"))
      llvm::errs() << "PostStmt<OffsetOfExpr>\n";
  }

  void checkPreCall(const CallEvent &Call, CheckerContext &C) const {
    if (isCallbackEnabled(C, "PreCall")) {
      llvm::errs() << "PreCall";
      if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(Call.getDecl()))
        llvm::errs() << " (" << ND->getQualifiedNameAsString() << ')';
      llvm::errs() << '\n';
    }
  }

  void checkPostCall(const CallEvent &Call, CheckerContext &C) const {
    if (isCallbackEnabled(C, "PostCall")) {
      llvm::errs() << "PostCall";
      if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(Call.getDecl()))
        llvm::errs() << " (" << ND->getQualifiedNameAsString() << ')';
      llvm::errs() << '\n';
    }
  }

  void checkNewAllocator(const CXXNewExpr *CNE, SVal Target,
                         CheckerContext &C) const {
    if (isCallbackEnabled(C, "NewAllocator"))
      llvm::errs() << "NewAllocator\n";
  }

  void checkBind(SVal Loc, SVal Val, const Stmt *S, CheckerContext &C) const {
    if (isCallbackEnabled(C, "Bind"))
      llvm::errs() << "Bind\n";
  }

  void checkLiveSymbols(ProgramStateRef State, SymbolReaper &SymReaper) const {
    if (isCallbackEnabled(State, "LiveSymbols"))
      llvm::errs() << "LiveSymbols\n";
  }

  ProgramStateRef
  checkRegionChanges(ProgramStateRef State,
                     const InvalidatedSymbols *Invalidated,
                     ArrayRef<const MemRegion *> ExplicitRegions,
                     ArrayRef<const MemRegion *> Regions,
                     const LocationContext *LCtx, const CallEvent *Call) const {
    if (isCallbackEnabled(State, "RegionChanges"))
      llvm::errs() << "RegionChanges\n";
    return State;
  }
};
} // end anonymous namespace

//===----------------------------------------------------------------------===//
// Registration.
//===----------------------------------------------------------------------===//

void ento::registerAnalysisOrderChecker(CheckerManager &mgr) {
  mgr.registerChecker<AnalysisOrderChecker>();
}
<|endoftext|>