<commit_before>/******************************************************************************
 *
 *  Copyright 2008 Szymon Tomasz Stefanek <pragma@kvirc.net>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 *******************************************************************************/

#include "messagelistview/core/aggregation.h"

#include <QDataStream>

#include <klocale.h>

namespace KMail
{

namespace MessageListView
{

namespace Core
{

static const int gAggregationCurrentVersion = 0x1009; // increase if you add new fields of change the meaning of some

Aggregation::Aggregation(
      const QString &name,
      const QString &description,
      Grouping grouping,
      GroupExpandPolicy groupExpandPolicy,
      Threading threading,
      ThreadLeader threadLeader,
      ThreadExpandPolicy threadExpandPolicy,
      FillViewStrategy fillViewStrategy
    )
  : OptionSet( name, description ),
    mGrouping( grouping ),
    mGroupExpandPolicy( groupExpandPolicy ),
    mThreading( threading ),
    mThreadLeader( threadLeader ),
    mThreadExpandPolicy( threadExpandPolicy ),
    mFillViewStrategy( fillViewStrategy )
{
}

Aggregation::Aggregation(
      const Aggregation &opt
    )
  : OptionSet( opt ),
    mGrouping( opt.mGrouping ),
    mGroupExpandPolicy( opt.mGroupExpandPolicy ),
    mThreading( opt.mThreading ),
    mThreadLeader( opt.mThreadLeader ),
    mThreadExpandPolicy( opt.mThreadExpandPolicy ),
    mFillViewStrategy( opt.mFillViewStrategy )
{
}

Aggregation::Aggregation()
  : OptionSet(),
    mGrouping( NoGrouping ),
    mGroupExpandPolicy( NeverExpandGroups ),
    mThreading( NoThreading ),
    mThreadLeader( TopmostMessage ),
    mThreadExpandPolicy( NeverExpandThreads ),
    mFillViewStrategy( FavorInteractivity )
{
}

bool Aggregation::load( QDataStream &stream )
{
  int val;

  stream >> val;
  if ( val != gAggregationCurrentVersion )
    return false; // b0rken (invalid version)

  stream >> val;
  mGrouping = (Grouping)val;
  switch( mGrouping )
  {
    case NoGrouping:
    case GroupByDate:
    case GroupByDateRange:
    case GroupBySenderOrReceiver:
    case GroupBySender:
    case GroupByReceiver:
      // ok
    break;
    default:
      // b0rken
      return false;
    break;
  };

  stream >> val; // Formerly contained group sorting
  stream >> val; // Formerly contained group sorting direction

  stream >> val;
  mGroupExpandPolicy = (GroupExpandPolicy)val;
  switch( mGroupExpandPolicy )
  {
    case NeverExpandGroups:
    case ExpandRecentGroups:
    case AlwaysExpandGroups:
      // ok
    break;
    default:
      // b0rken
      return false;
    break;
  };

  stream >> val;
  mThreading = (Threading)val;
  switch( mThreading )
  {
    case NoThreading:
    case PerfectOnly:
    case PerfectAndReferences:
    case PerfectReferencesAndSubject:
      // ok
    break;
    default:
      // b0rken
      return false;
    break;
  }

  stream >> val;
  mThreadLeader = (ThreadLeader)val;
  switch( mThreadLeader )
  {
    case MostRecentMessage:
    case TopmostMessage:
      // ok
      // FIXME: Should check that thread leaders setting matches grouping and threading settings.
    break;
    default:
      // b0rken
      return false;
    break;
  }

  stream >> val;
  mThreadExpandPolicy = (ThreadExpandPolicy)val;
  switch( mThreadExpandPolicy )
  {
    case NeverExpandThreads:
    case ExpandThreadsWithNewMessages:
    case ExpandThreadsWithUnreadMessages:
    case ExpandThreadsWithUnreadOrImportantMessages:
    case AlwaysExpandThreads:
      // ok
    break;
    default:
      // b0rken
      return false;
    break;
  }

  stream >> val; // Formely contained message sorting
  stream >> val; // Formely contained message sort direction

  stream >> val;
  mFillViewStrategy = (FillViewStrategy)val;
  switch( mFillViewStrategy )
  {
    case FavorSpeed:
    case FavorInteractivity:
    case BatchNoInteractivity:
      // ok
    break;
    default:
      // b0rken
      return false;
    break;
  }

  return true;
}

void Aggregation::save( QDataStream &stream ) const
{
  stream << (int)gAggregationCurrentVersion;
  stream << (int)mGrouping;
  stream << 0; // Formerly group sorting
  stream << 0; // Formerly group sort direction
  stream << (int)mGroupExpandPolicy;
  stream << (int)mThreading;
  stream << (int)mThreadLeader;
  stream << (int)mThreadExpandPolicy;
  stream << 0; // Formerly message sorting
  stream << 0; // Formerly message sort direction
  stream << (int)mFillViewStrategy;
}

QList< QPair< QString, int > > Aggregation::enumerateGroupingOptions()
{
  QList< QPair< QString, int > > ret;
  ret.append( QPair< QString, int >( i18nc( "No grouping of messages", "None" ), NoGrouping ) );
  ret.append( QPair< QString, int >( i18n( "By Exact Date (of Thread Leaders)" ), GroupByDate ) );
  ret.append( QPair< QString, int >( i18n( "By Smart Date Ranges (of Thread Leaders)" ), GroupByDateRange ) );
  ret.append( QPair< QString, int >( i18n( "By Smart Sender/Receiver" ), GroupBySenderOrReceiver ) );
  ret.append( QPair< QString, int >( i18n( "By Sender" ), GroupBySender ) );
  ret.append( QPair< QString, int >( i18n( "By Receiver" ), GroupBySender ) );
  return ret;
}

QList< QPair< QString, int > > Aggregation::enumerateGroupExpandPolicyOptions( Grouping g )
{
  QList< QPair< QString, int > > ret;
  if ( g == NoGrouping )
    return ret;
  ret.append( QPair< QString, int >( i18n( "Never Expand Groups" ), NeverExpandGroups ) );
  if ( ( g == GroupByDate ) || ( g == GroupByDateRange ) )
    ret.append( QPair< QString, int >( i18n( "Expand Recent Groups" ), ExpandRecentGroups ) );
  ret.append( QPair< QString, int >( i18n( "Always Expand Groups" ), AlwaysExpandGroups ) );
  return ret;
}

QList< QPair< QString, int > > Aggregation::enumerateThreadingOptions()
{
  QList< QPair< QString, int > > ret;
  ret.append( QPair< QString, int >( i18nc( "No threading of messages", "None" ), NoThreading ) );
  ret.append( QPair< QString, int >( i18n( "Perfect Only" ), PerfectOnly ) );
  ret.append( QPair< QString, int >( i18n( "Perfect and by References" ), PerfectAndReferences ) );
  ret.append( QPair< QString, int >( i18n( "Perfect, by References and by Subject" ), PerfectReferencesAndSubject ) );
  return ret;
}

QList< QPair< QString, int > > Aggregation::enumerateThreadLeaderOptions( Grouping g, Threading t )
{
  QList< QPair< QString, int > > ret;
  if ( t == NoThreading )
    return ret;
  ret.append( QPair< QString, int >( i18n( "Topmost Message" ), TopmostMessage ) );
  if ( ( g != GroupByDate ) && ( g != GroupByDateRange ) )
    return ret;
  ret.append( QPair< QString, int >( i18n( "Most Recent Message" ), MostRecentMessage ) );
  return ret;
}

QList< QPair< QString, int > > Aggregation::enumerateThreadExpandPolicyOptions( Threading t )
{
  QList< QPair< QString, int > > ret;
  if ( t == NoThreading )
    return ret;
  ret.append( QPair< QString, int >( i18n( "Never Expand Threads" ), NeverExpandThreads ) );
  ret.append( QPair< QString, int >( i18n( "Expand Threads With New Messages" ), ExpandThreadsWithNewMessages ) );
  ret.append( QPair< QString, int >( i18n( "Expand Threads With Unread Messages" ), ExpandThreadsWithUnreadMessages ) );
  ret.append( QPair< QString, int >( i18n( "Expand Threads With Unread or Important Messages" ), ExpandThreadsWithUnreadOrImportantMessages ) );
  ret.append( QPair< QString, int >( i18n( "Always Expand Threads" ), AlwaysExpandThreads ) );
  return ret;
}

QList< QPair< QString, int > > Aggregation::enumerateFillViewStrategyOptions()
{
  QList< QPair< QString, int > > ret;
  ret.append( QPair< QString, int >( i18n( "Favor Interactivity" ), FavorInteractivity ) );
  ret.append( QPair< QString, int >( i18n( "Favor Speed" ), FavorSpeed ) );
  ret.append( QPair< QString, int >( i18n( "Batch Job (No Interactivity)" ), BatchNoInteractivity ) );
  return ret;
}

} // namespace Core

} // namespace MessageListView

} // namespace KMail
<commit_msg>BUG: 204193<commit_after>/******************************************************************************
 *
 *  Copyright 2008 Szymon Tomasz Stefanek <pragma@kvirc.net>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 *******************************************************************************/

#include "messagelistview/core/aggregation.h"

#include <QDataStream>

#include <klocale.h>

namespace KMail
{

namespace MessageListView
{

namespace Core
{

static const int gAggregationCurrentVersion = 0x1009; // increase if you add new fields of change the meaning of some

Aggregation::Aggregation(
      const QString &name,
      const QString &description,
      Grouping grouping,
      GroupExpandPolicy groupExpandPolicy,
      Threading threading,
      ThreadLeader threadLeader,
      ThreadExpandPolicy threadExpandPolicy,
      FillViewStrategy fillViewStrategy
    )
  : OptionSet( name, description ),
    mGrouping( grouping ),
    mGroupExpandPolicy( groupExpandPolicy ),
    mThreading( threading ),
    mThreadLeader( threadLeader ),
    mThreadExpandPolicy( threadExpandPolicy ),
    mFillViewStrategy( fillViewStrategy )
{
}

Aggregation::Aggregation(
      const Aggregation &opt
    )
  : OptionSet( opt ),
    mGrouping( opt.mGrouping ),
    mGroupExpandPolicy( opt.mGroupExpandPolicy ),
    mThreading( opt.mThreading ),
    mThreadLeader( opt.mThreadLeader ),
    mThreadExpandPolicy( opt.mThreadExpandPolicy ),
    mFillViewStrategy( opt.mFillViewStrategy )
{
}

Aggregation::Aggregation()
  : OptionSet(),
    mGrouping( NoGrouping ),
    mGroupExpandPolicy( NeverExpandGroups ),
    mThreading( NoThreading ),
    mThreadLeader( TopmostMessage ),
    mThreadExpandPolicy( NeverExpandThreads ),
    mFillViewStrategy( FavorInteractivity )
{
}

bool Aggregation::load( QDataStream &stream )
{
  int val;

  stream >> val;
  if ( val != gAggregationCurrentVersion )
    return false; // b0rken (invalid version)

  stream >> val;
  mGrouping = (Grouping)val;
  switch( mGrouping )
  {
    case NoGrouping:
    case GroupByDate:
    case GroupByDateRange:
    case GroupBySenderOrReceiver:
    case GroupBySender:
    case GroupByReceiver:
      // ok
    break;
    default:
      // b0rken
      return false;
    break;
  };

  stream >> val; // Formerly contained group sorting
  stream >> val; // Formerly contained group sorting direction

  stream >> val;
  mGroupExpandPolicy = (GroupExpandPolicy)val;
  switch( mGroupExpandPolicy )
  {
    case NeverExpandGroups:
    case ExpandRecentGroups:
    case AlwaysExpandGroups:
      // ok
    break;
    default:
      // b0rken
      return false;
    break;
  };

  stream >> val;
  mThreading = (Threading)val;
  switch( mThreading )
  {
    case NoThreading:
    case PerfectOnly:
    case PerfectAndReferences:
    case PerfectReferencesAndSubject:
      // ok
    break;
    default:
      // b0rken
      return false;
    break;
  }

  stream >> val;
  mThreadLeader = (ThreadLeader)val;
  switch( mThreadLeader )
  {
    case MostRecentMessage:
    case TopmostMessage:
      // ok
      // FIXME: Should check that thread leaders setting matches grouping and threading settings.
    break;
    default:
      // b0rken
      return false;
    break;
  }

  stream >> val;
  mThreadExpandPolicy = (ThreadExpandPolicy)val;
  switch( mThreadExpandPolicy )
  {
    case NeverExpandThreads:
    case ExpandThreadsWithNewMessages:
    case ExpandThreadsWithUnreadMessages:
    case ExpandThreadsWithUnreadOrImportantMessages:
    case AlwaysExpandThreads:
      // ok
    break;
    default:
      // b0rken
      return false;
    break;
  }

  stream >> val; // Formely contained message sorting
  stream >> val; // Formely contained message sort direction

  stream >> val;
  mFillViewStrategy = (FillViewStrategy)val;
  switch( mFillViewStrategy )
  {
    case FavorSpeed:
    case FavorInteractivity:
    case BatchNoInteractivity:
      // ok
    break;
    default:
      // b0rken
      return false;
    break;
  }

  return true;
}

void Aggregation::save( QDataStream &stream ) const
{
  stream << (int)gAggregationCurrentVersion;
  stream << (int)mGrouping;
  stream << 0; // Formerly group sorting
  stream << 0; // Formerly group sort direction
  stream << (int)mGroupExpandPolicy;
  stream << (int)mThreading;
  stream << (int)mThreadLeader;
  stream << (int)mThreadExpandPolicy;
  stream << 0; // Formerly message sorting
  stream << 0; // Formerly message sort direction
  stream << (int)mFillViewStrategy;
}

QList< QPair< QString, int > > Aggregation::enumerateGroupingOptions()
{
  QList< QPair< QString, int > > ret;
  ret.append( QPair< QString, int >( i18nc( "No grouping of messages", "None" ), NoGrouping ) );
  ret.append( QPair< QString, int >( i18n( "By Exact Date (of Thread Leaders)" ), GroupByDate ) );
  ret.append( QPair< QString, int >( i18n( "By Smart Date Ranges (of Thread Leaders)" ), GroupByDateRange ) );
  ret.append( QPair< QString, int >( i18n( "By Smart Sender/Receiver" ), GroupBySenderOrReceiver ) );
  ret.append( QPair< QString, int >( i18n( "By Sender" ), GroupBySender ) );
  ret.append( QPair< QString, int >( i18n( "By Receiver" ), GroupByReceiver ) );
  return ret;
}

QList< QPair< QString, int > > Aggregation::enumerateGroupExpandPolicyOptions( Grouping g )
{
  QList< QPair< QString, int > > ret;
  if ( g == NoGrouping )
    return ret;
  ret.append( QPair< QString, int >( i18n( "Never Expand Groups" ), NeverExpandGroups ) );
  if ( ( g == GroupByDate ) || ( g == GroupByDateRange ) )
    ret.append( QPair< QString, int >( i18n( "Expand Recent Groups" ), ExpandRecentGroups ) );
  ret.append( QPair< QString, int >( i18n( "Always Expand Groups" ), AlwaysExpandGroups ) );
  return ret;
}

QList< QPair< QString, int > > Aggregation::enumerateThreadingOptions()
{
  QList< QPair< QString, int > > ret;
  ret.append( QPair< QString, int >( i18nc( "No threading of messages", "None" ), NoThreading ) );
  ret.append( QPair< QString, int >( i18n( "Perfect Only" ), PerfectOnly ) );
  ret.append( QPair< QString, int >( i18n( "Perfect and by References" ), PerfectAndReferences ) );
  ret.append( QPair< QString, int >( i18n( "Perfect, by References and by Subject" ), PerfectReferencesAndSubject ) );
  return ret;
}

QList< QPair< QString, int > > Aggregation::enumerateThreadLeaderOptions( Grouping g, Threading t )
{
  QList< QPair< QString, int > > ret;
  if ( t == NoThreading )
    return ret;
  ret.append( QPair< QString, int >( i18n( "Topmost Message" ), TopmostMessage ) );
  if ( ( g != GroupByDate ) && ( g != GroupByDateRange ) )
    return ret;
  ret.append( QPair< QString, int >( i18n( "Most Recent Message" ), MostRecentMessage ) );
  return ret;
}

QList< QPair< QString, int > > Aggregation::enumerateThreadExpandPolicyOptions( Threading t )
{
  QList< QPair< QString, int > > ret;
  if ( t == NoThreading )
    return ret;
  ret.append( QPair< QString, int >( i18n( "Never Expand Threads" ), NeverExpandThreads ) );
  ret.append( QPair< QString, int >( i18n( "Expand Threads With New Messages" ), ExpandThreadsWithNewMessages ) );
  ret.append( QPair< QString, int >( i18n( "Expand Threads With Unread Messages" ), ExpandThreadsWithUnreadMessages ) );
  ret.append( QPair< QString, int >( i18n( "Expand Threads With Unread or Important Messages" ), ExpandThreadsWithUnreadOrImportantMessages ) );
  ret.append( QPair< QString, int >( i18n( "Always Expand Threads" ), AlwaysExpandThreads ) );
  return ret;
}

QList< QPair< QString, int > > Aggregation::enumerateFillViewStrategyOptions()
{
  QList< QPair< QString, int > > ret;
  ret.append( QPair< QString, int >( i18n( "Favor Interactivity" ), FavorInteractivity ) );
  ret.append( QPair< QString, int >( i18n( "Favor Speed" ), FavorSpeed ) );
  ret.append( QPair< QString, int >( i18n( "Batch Job (No Interactivity)" ), BatchNoInteractivity ) );
  return ret;
}

} // namespace Core

} // namespace MessageListView

} // namespace KMail
<|endoftext|>


<commit_before>/***************************************************************************
        konsolekalendarexports.cpp  -  description
           -------------------
    begin                : Sun May 25 2003
    copyright            : (C) 2003 by Tuukka Pasanen
    copyright            : (C) 2003 by Allen Winter
    email                : illuusio@mailcity.com
 ***************************************************************************/

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

#include <stdlib.h>
#include <iostream>

#include <qdatetime.h>

#include <kdebug.h>
#include <klocale.h>

#include <libkcal/calendarlocal.h>
#include <libkcal/calendar.h>
#include <libkcal/event.h>
#include <libkcal/htmlexport.h>

#include "konsolekalendarexports.h"

using namespace KCal;
using namespace std;

KonsoleKalendarExports::KonsoleKalendarExports( KonsoleKalendarVariables *variables )
{
  m_variables = variables;
  m_firstEntry = true;
}

KonsoleKalendarExports::~KonsoleKalendarExports()
{
}

bool KonsoleKalendarExports::exportAsTxt( QTextStream *ts, Event *event ){

  if( m_firstEntry == true ||
      m_lastDate.day() != event->dtStart().date().day() ||
      m_lastDate.month() != event->dtStart().date().month() ||
      m_lastDate.year() != event->dtStart().date().year() ){

    m_firstEntry=false;
    int len = event->dtStartStr().length();
    QString date = event->dtStartStr();
    date.truncate( len - 5 );
    *ts << I18N_NOOP("Date:") << "\t" <<  date.local8Bit() << endl;
    m_lastDate = event->dtStart().date();

  }

  if ( !event->doesFloat() ) {
    *ts << "\t";
    *ts <<  event->dtStartStr().remove(0, (event->dtStartStr().find(' ', 0, false) + 1) ).local8Bit();
    *ts << " - ";
    *ts << event->dtEndStr().remove(0, (event->dtEndStr().find(' ', 0, false) + 1) ).local8Bit();
  }

  *ts << endl << I18N_NOOP("Summary:") << endl;
  *ts << "\t" << event->summary().local8Bit() << endl;
  *ts << I18N_NOOP("Description:") << endl;
  if( !event->description().isEmpty() ) {
    *ts << "\t" << event->description().local8Bit() << endl;
  } else {
    *ts << "\t" << I18N_NOOP("(no description available)") << endl;
  }
  *ts << I18N_NOOP("UID:") << endl;
  *ts << "\t" << event->uid().local8Bit() << endl;
  *ts << "----------------------------------" << endl;

  return true;
}

bool KonsoleKalendarExports::exportAsCSV( QTextStream *ts, Event *event ){

// startdate,starttime,enddate,endtime,summary,description,UID

  QString delim = ",";  //one day maybe the delim character can be an option??

  if ( !event->doesFloat() ) {
    *ts <<          event->dtStart().date().toString("yyyy:M:d");
    *ts << delim << event->dtStart().time().toString("hh:mm");
    *ts << delim << event->dtEnd().date().toString("yyyy:M:d");
    *ts << delim << event->dtEnd().time().toString("hh:mm");
  } else {
    *ts << ",,,";
  }

  *ts << delim << event->summary().local8Bit();
  *ts << delim << event->description().local8Bit();
  *ts << delim << event->uid().local8Bit();
  *ts << endl;

  return true;
}

// Old function for printing out as keyword:<tab>value
//bool KonsoleKalendarExports::exportAsCSV( QTextStream *ts, Event *event ){
//
//  if ( !event->doesFloat() ) {
//    *ts <<  event->dtStartStr().remove(0, (event->dtStartStr().find(' ', 0, false) + 1) ).local8Bit();
//    *ts << "\t";
//    *ts << event->dtEndStr().remove(0, (event->dtEndStr().find(' ', 0, false) + 1) ).local8Bit();
// }
//
//  *ts << "\t" << I18N_NOOP("Summary:");
//  *ts << "\t\"" << event->summary().local8Bit() << "\"";
//  *ts << "\t" << I18N_NOOP("Description:");
//  *ts << "\t\"" << event->description().local8Bit() << "\"";
//  *ts << "\t" << I18N_NOOP("UID:");
//  *ts << "\t" << event->uid().local8Bit() << endl;
//
//  return true;
//}
<commit_msg>BUG Fix: why can't I concentrate today?  Another tweak for CSVexport<commit_after>/***************************************************************************
        konsolekalendarexports.cpp  -  description
           -------------------
    begin                : Sun May 25 2003
    copyright            : (C) 2003 by Tuukka Pasanen
    copyright            : (C) 2003 by Allen Winter
    email                : illuusio@mailcity.com
 ***************************************************************************/

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

#include <stdlib.h>
#include <iostream>

#include <qdatetime.h>

#include <kdebug.h>
#include <klocale.h>

#include <libkcal/calendarlocal.h>
#include <libkcal/calendar.h>
#include <libkcal/event.h>
#include <libkcal/htmlexport.h>

#include "konsolekalendarexports.h"

using namespace KCal;
using namespace std;

KonsoleKalendarExports::KonsoleKalendarExports( KonsoleKalendarVariables *variables )
{
  m_variables = variables;
  m_firstEntry = true;
}

KonsoleKalendarExports::~KonsoleKalendarExports()
{
}

bool KonsoleKalendarExports::exportAsTxt( QTextStream *ts, Event *event ){

  if( m_firstEntry == true ||
      m_lastDate.day() != event->dtStart().date().day() ||
      m_lastDate.month() != event->dtStart().date().month() ||
      m_lastDate.year() != event->dtStart().date().year() ){

    m_firstEntry=false;
    int len = event->dtStartStr().length();
    QString date = event->dtStartStr();
    date.truncate( len - 5 );
    *ts << I18N_NOOP("Date:") << "\t" <<  date.local8Bit() << endl;
    m_lastDate = event->dtStart().date();

  }

  if ( !event->doesFloat() ) {
    *ts << "\t";
    *ts <<  event->dtStartStr().remove(0, (event->dtStartStr().find(' ', 0, false) + 1) ).local8Bit();
    *ts << " - ";
    *ts << event->dtEndStr().remove(0, (event->dtEndStr().find(' ', 0, false) + 1) ).local8Bit();
  }

  *ts << endl << I18N_NOOP("Summary:") << endl;
  *ts << "\t" << event->summary().local8Bit() << endl;
  *ts << I18N_NOOP("Description:") << endl;
  if( !event->description().isEmpty() ) {
    *ts << "\t" << event->description().local8Bit() << endl;
  } else {
    *ts << "\t" << I18N_NOOP("(no description available)") << endl;
  }
  *ts << I18N_NOOP("UID:") << endl;
  *ts << "\t" << event->uid().local8Bit() << endl;
  *ts << "----------------------------------" << endl;

  return true;
}

bool KonsoleKalendarExports::exportAsCSV( QTextStream *ts, Event *event ){

// startdate,starttime,enddate,endtime,summary,description,UID

  QString delim = ",";  //one day maybe the delim character can be an option??

  if ( !event->doesFloat() ) {
    *ts <<          event->dtStart().date().toString("yyyy-M-d");
    *ts << delim << event->dtStart().time().toString("hh:mm");
    *ts << delim << event->dtEnd().date().toString("yyyy-M-d");
    *ts << delim << event->dtEnd().time().toString("hh:mm");
  } else {
    *ts << ",,,";
  }

  *ts << delim << event->summary().local8Bit();
  *ts << delim << event->description().local8Bit();
  *ts << delim << event->uid().local8Bit();
  *ts << endl;

  return true;
}

// Old function for printing out as keyword:<tab>value
//bool KonsoleKalendarExports::exportAsCSV( QTextStream *ts, Event *event ){
//
//  if ( !event->doesFloat() ) {
//    *ts <<  event->dtStartStr().remove(0, (event->dtStartStr().find(' ', 0, false) + 1) ).local8Bit();
//    *ts << "\t";
//    *ts << event->dtEndStr().remove(0, (event->dtEndStr().find(' ', 0, false) + 1) ).local8Bit();
// }
//
//  *ts << "\t" << I18N_NOOP("Summary:");
//  *ts << "\t\"" << event->summary().local8Bit() << "\"";
//  *ts << "\t" << I18N_NOOP("Description:");
//  *ts << "\t\"" << event->description().local8Bit() << "\"";
//  *ts << "\t" << I18N_NOOP("UID:");
//  *ts << "\t" << event->uid().local8Bit() << endl;
//
//  return true;
//}
<|endoftext|>


<commit_before>/* testhhrecord.cc			KPilot
**
** Copyright (C) 2007 by Bertjan Broeksema <b.broeksema@kdemail.net>
** Copyright (C) 2007 by Jason "vanRijn" Kasper <vr@movingparts.net>
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 of the License, or
** (at your option) any later version.
**
** This 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
** MA 02110-1301, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/

#include "testhhrecord.h"
#include "testrecord.h"

#include "options.h"

TestHHRecord::TestHHRecord( const QStringList& fields, const QString &id )
	: HHRecord( 0L, CSL1( "Unfiled" ) ), fId( id ), fFields( fields ), fModified( false )
		, fDeleted( false ), fArchived( false )
{
}

TestHHRecord::TestHHRecord( const TestHHRecord *other )
	: HHRecord( 0L, CSL1( "Unfiled" ) )
{
	fId = other->id();
	fFields = other->fields();

	QStringListIterator it(fFields);

	while( it.hasNext() )
	{
		QString field = it.next();

		setValue( field, other->value( field ) );
	}

	fModified = other->isModified();
	fDeleted = other->isDeleted();
	fArchived = other->isArchived();;
}

TestHHRecord::TestHHRecord( const TestRecord *other )
	: HHRecord( 0L, CSL1( "Unfiled" ) )
{
	fId = other->id();
	fFields = other->fields();

	QStringListIterator it(fFields);

	while( it.hasNext() )
	{
		QString field = it.next();

		setValue( field, other->value( field ) );
	}

	fModified = other->isModified();
	fDeleted = other->isDeleted();
	fArchived = false;
}

void TestHHRecord::setArchived()
{
	setDeleted();
	fArchived = true;
}

void TestHHRecord::setDeleted()
{
	fDeleted = true;
}

void TestHHRecord::setModified()
{
	fModified = true;
}

const QString TestHHRecord::id() const
{
	return fId;
}

void TestHHRecord::setId( const QString &id )
{
	fId = id;
}

QVariant TestHHRecord::value( const QString &field ) const
{
	return fValues.value( field );
}

bool TestHHRecord::setValue( const QString &field, const QVariant &value )
{
	fValues.insert( field, value );
	fModified = true;
	return true;
}

bool TestHHRecord::isModified() const
{
	return fModified || isDeleted();
}

bool TestHHRecord::isDeleted() const
{
	return fDeleted;
}

void TestHHRecord::synced()
{
	fDeleted = false;
	fModified = false;
}

QString TestHHRecord::toString() const
{
	QString representation = fId + CSL1( " [" );
	QStringListIterator it(fFields);

	while( it.hasNext() )
	{
		QString field = it.next();

		representation += CSL1( " " );
		representation += field;
		representation += CSL1( "=\"" );
		representation += fValues.value( field ).toString();
		representation += CSL1( "\"" );
	}

	representation += CSL1( " ]" );

	return representation;
}

const QStringList TestHHRecord::fields() const
{
	return fFields;
}

TestHHRecord* TestHHRecord::duplicate() const
{
	return new TestHHRecord( this );
}

bool TestHHRecord::equal( const Record *rec ) const
{
	if( const TestRecord *other = dynamic_cast<const TestRecord*>( rec ) )
	{
		QStringList fields = other->fields();
		QStringListIterator it(fields);

		bool allEqual = true;

		while( it.hasNext() )
		{
			QString field = it.next();

			allEqual = allEqual && ( fValues.value( field ) == other->value( field ) );
		}

		return allEqual && (fields == fFields);
	}
	else if( const TestHHRecord *other = dynamic_cast<const TestHHRecord*>( rec ) )
	{
		QStringList fields = other->fields();
		QStringListIterator it(fields);

		bool allEqual = true;

		while( it.hasNext() )
		{
			QString field = it.next();

			allEqual = allEqual && ( fValues.value( field ) == other->value( field ) );
		}

		return allEqual && (fields == fFields);
	}

	return false;
}
<commit_msg>Create a pilotRecord in the the TestHHRecord to avoid seg faults when the conduit tries to set the category.<commit_after>/* testhhrecord.cc			KPilot
**
** Copyright (C) 2007 by Bertjan Broeksema <b.broeksema@kdemail.net>
** Copyright (C) 2007 by Jason "vanRijn" Kasper <vr@movingparts.net>
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 of the License, or
** (at your option) any later version.
**
** This 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
** MA 02110-1301, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/

#include "testhhrecord.h"
#include "testrecord.h"

#include "options.h"
#include "pilotRecord.h"

TestHHRecord::TestHHRecord( const QStringList& fields, const QString &id )
	: HHRecord( 0L, CSL1( "Unfiled" ) ), fId( id ), fFields( fields ), fModified( false )
		, fDeleted( false ), fArchived( false )
{
	pi_buffer_t *buf = pi_buffer_new( QString( "" ).size() );
	Pilot::toPilot( QString(""), buf->data, 0 );

	fRecord = new PilotRecord( buf, 0, 0, 0);
	fRecord->setCategory( 0 );
}

TestHHRecord::TestHHRecord( const TestHHRecord *other )
	: HHRecord( 0L, CSL1( "Unfiled" ) )
{
	fId = other->id();
	fFields = other->fields();

	QStringListIterator it(fFields);

	while( it.hasNext() )
	{
		QString field = it.next();

		setValue( field, other->value( field ) );
	}

	fModified = other->isModified();
	fDeleted = other->isDeleted();
	fArchived = other->isArchived();;
}

TestHHRecord::TestHHRecord( const TestRecord *other )
	: HHRecord( 0L, CSL1( "Unfiled" ) )
{
	fId = other->id();
	fFields = other->fields();

	QStringListIterator it(fFields);

	while( it.hasNext() )
	{
		QString field = it.next();

		setValue( field, other->value( field ) );
	}

	fModified = other->isModified();
	fDeleted = other->isDeleted();
	fArchived = false;
}

void TestHHRecord::setArchived()
{
	setDeleted();
	fArchived = true;
}

void TestHHRecord::setDeleted()
{
	fDeleted = true;
}

void TestHHRecord::setModified()
{
	fModified = true;
}

const QString TestHHRecord::id() const
{
	return fId;
}

void TestHHRecord::setId( const QString &id )
{
	fId = id;
}

QVariant TestHHRecord::value( const QString &field ) const
{
	return fValues.value( field );
}

bool TestHHRecord::setValue( const QString &field, const QVariant &value )
{
	fValues.insert( field, value );
	fModified = true;
	return true;
}

bool TestHHRecord::isModified() const
{
	return fModified || isDeleted();
}

bool TestHHRecord::isDeleted() const
{
	return fDeleted;
}

void TestHHRecord::synced()
{
	fDeleted = false;
	fModified = false;
}

QString TestHHRecord::toString() const
{
	QString representation = fId + CSL1( " [" );
	QStringListIterator it(fFields);

	while( it.hasNext() )
	{
		QString field = it.next();

		representation += CSL1( " " );
		representation += field;
		representation += CSL1( "=\"" );
		representation += fValues.value( field ).toString();
		representation += CSL1( "\"" );
	}

	representation += CSL1( " ]" );

	return representation;
}

const QStringList TestHHRecord::fields() const
{
	return fFields;
}

TestHHRecord* TestHHRecord::duplicate() const
{
	return new TestHHRecord( this );
}

bool TestHHRecord::equal( const Record *rec ) const
{
	if( const TestRecord *other = dynamic_cast<const TestRecord*>( rec ) )
	{
		QStringList fields = other->fields();
		QStringListIterator it(fields);

		bool allEqual = true;

		while( it.hasNext() )
		{
			QString field = it.next();

			allEqual = allEqual && ( fValues.value( field ) == other->value( field ) );
		}

		return allEqual && (fields == fFields);
	}
	else if( const TestHHRecord *other = dynamic_cast<const TestHHRecord*>( rec ) )
	{
		QStringList fields = other->fields();
		QStringListIterator it(fields);

		bool allEqual = true;

		while( it.hasNext() )
		{
			QString field = it.next();

			allEqual = allEqual && ( fValues.value( field ) == other->value( field ) );
		}

		return allEqual && (fields == fFields);
	}

	return false;
}
<|endoftext|>


<commit_before>// Author: Jingyue

#include <cstdio>
#include <set>
using namespace std;

#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

#include "common/PointerAnalysis.h"
using namespace rcs;

#include "dyn-aa/LogRecord.h"
#include "dyn-aa/IntervalTree.h"
using namespace dyn_aa;

namespace dyn_aa {
struct DynamicPointerAnalysis: public ModulePass, public PointerAnalysis {
  static char ID;

  DynamicPointerAnalysis(): ModulePass(ID) {}
  virtual bool runOnModule(Module &M);
  virtual void getAnalysisUsage(AnalysisUsage &AU) const;

  virtual void getAllPointers(ValueList &Pointers);
  virtual bool getPointees(const Value *Pointer, ValueList &Pointees);

 private:
  void processAddrTakenDecl(const AddrTakenDeclLogRecord &Record);
  void processTopLevelPointTo(const TopLevelPointToLogRecord &Record);
  void processAddrTakenPointTo(const AddrTakenPointToLogRecord &Record);
  // Returns the value ID of <Addr>'s allocator.
  // Possible allocators include malloc function calls, AllocaInsts, and
  // global variables.
  Value *lookupAddress(void *Addr) const;

  // Stores all addr-taken declarations.
  IntervalTree AddrTakenDecls;
  // Use DenseSet instead of vector, because they are usually lots of
  // duplicated edges.
  DenseMap<const Value *, ValueSet> PointTos;
};
}

static RegisterPass<DynamicPointerAnalysis> X("dyn-pa",
                                              "Build the point-to graph from "
                                              "the point-to log",
                                              false,
                                              true);
static RegisterAnalysisGroup<PointerAnalysis> Y(X);

static cl::opt<string> LogFileName("log-file",
                                   cl::desc("Point-to log file generated by "
                                            "running the instrumented program"),
                                   cl::init(""));

char DynamicPointerAnalysis::ID = 0;

bool DynamicPointerAnalysis::runOnModule(Module &M) {
  LogRecordType RecordType;
  int numRecords = 0;
  int numAddrTakenDecls = 0;
  int numAddrTakenPointTos = 0;
  int numTopLevelPointTos = 0;

  FILE *LogFile = fopen(LogFileName.c_str(), "rb");
  while (fread(&RecordType, sizeof RecordType, 1, LogFile) == 1) {
    if (numRecords % 1000000 == 0)
      errs() << "Processed " << numRecords << " records\n";
    ++numRecords;
    switch (RecordType) {
      case AddrTakenDecl:
        {
          ++numAddrTakenDecls;
          AddrTakenDeclLogRecord Record;
          assert(fread(&Record, sizeof Record, 1, LogFile) == 1);
          processAddrTakenDecl(Record);
        }
        break;
      case TopLevelPointTo:
        {
          ++numTopLevelPointTos;
          TopLevelPointToLogRecord Record;
          assert(fread(&Record, sizeof Record, 1, LogFile) == 1);
          processTopLevelPointTo(Record);
        }
        break;
      case AddrTakenPointTo:
        {
          ++numAddrTakenPointTos;
          AddrTakenPointToLogRecord Record;
          assert(fread(&Record, sizeof Record, 1, LogFile) == 1);
          processAddrTakenPointTo(Record);
        }
        break;
      default:
        fprintf(stderr, "RecordType = %d\n", RecordType);
        assert(false && "Unknown record type");
    }
  }

  errs() << "Processed " << numRecords << " records\n";
  errs() << "# of addr-taken decls = " << numAddrTakenDecls << "\n";
  errs() << "# of addr-taken point-tos = " << numAddrTakenPointTos << "\n";
  errs() << "# of top-level point-tos = " << numTopLevelPointTos << "\n";

  return false;
}

void DynamicPointerAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesAll();
  AU.addRequired<IDAssigner>();
}

void DynamicPointerAnalysis::processAddrTakenDecl(
    const AddrTakenDeclLogRecord &Record) {
  IDAssigner &IDA = getAnalysis<IDAssigner>();

  Value *Allocator = IDA.getValue(Record.AllocatedBy);
  assert(Allocator);

  unsigned long Start = (unsigned long)Record.Address;
  Interval I(Start, Start + Record.Bound);
  pair<IntervalTree::iterator, IntervalTree::iterator> ER =
      AddrTakenDecls.equal_range(I);
  AddrTakenDecls.erase(ER.first, ER.second);
  AddrTakenDecls.insert(make_pair(I, Allocator));
}

void DynamicPointerAnalysis::processTopLevelPointTo(
    const TopLevelPointToLogRecord &Record) {
  IDAssigner &IDA = getAnalysis<IDAssigner>();

  Value *Pointer = IDA.getValue(Record.PointerValueID);
  Value *Pointee = lookupAddress(Record.PointeeAddress);
  assert(Pointer);
  if (Pointee)
    PointTos[Pointer].insert(Pointee);
}

void DynamicPointerAnalysis::processAddrTakenPointTo(
    const AddrTakenPointToLogRecord &Record) {
  Value *Pointer = lookupAddress(Record.PointerAddress);
  Value *Pointee = lookupAddress(Record.PointeeAddress);
  assert(Pointer);
  if (Pointee)
    PointTos[Pointer].insert(Pointee);
}

Value *DynamicPointerAnalysis::lookupAddress(void *Addr) const {
  Interval I((unsigned long)Addr, (unsigned long)Addr + 1);
  IntervalTree::const_iterator Pos = AddrTakenDecls.find(I);
  if (Pos == AddrTakenDecls.end())
    return NULL;
  return Pos->second;
}

bool DynamicPointerAnalysis::getPointees(const Value *Pointer,
                                         ValueList &Pointees) {
  Pointees.clear();
  DenseMap<const Value *, ValueSet>::iterator I = PointTos.find(Pointer);
  if (I == PointTos.end())
    return false;

  Pointees.insert(Pointees.end(), I->second.begin(), I->second.end());
  return true;
}

void DynamicPointerAnalysis::getAllPointers(ValueList &Pointers) {
  for (DenseMap<const Value *, ValueSet>::iterator I = PointTos.begin();
       I != PointTos.end(); ++I) {
    Pointers.push_back(const_cast<Value *>(I->first));
  }
}
<commit_msg>allow AddrTakenDecls have NULL values<commit_after>// Author: Jingyue

#include <cstdio>
#include <set>
using namespace std;

#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

#include "common/PointerAnalysis.h"
using namespace rcs;

#include "dyn-aa/LogRecord.h"
#include "dyn-aa/IntervalTree.h"
using namespace dyn_aa;

namespace dyn_aa {
struct DynamicPointerAnalysis: public ModulePass, public PointerAnalysis {
  static char ID;

  DynamicPointerAnalysis(): ModulePass(ID) {}
  virtual bool runOnModule(Module &M);
  virtual void getAnalysisUsage(AnalysisUsage &AU) const;

  virtual void getAllPointers(ValueList &Pointers);
  virtual bool getPointees(const Value *Pointer, ValueList &Pointees);

 private:
  void processAddrTakenDecl(const AddrTakenDeclLogRecord &Record);
  void processTopLevelPointTo(const TopLevelPointToLogRecord &Record);
  void processAddrTakenPointTo(const AddrTakenPointToLogRecord &Record);
  // Returns the value ID of <Addr>'s allocator.
  // Possible allocators include malloc function calls, AllocaInsts, and
  // global variables.
  Value *lookupAddress(void *Addr) const;

  // Stores all addr-taken declarations.
  IntervalTree AddrTakenDecls;
  // Use DenseSet instead of vector, because they are usually lots of
  // duplicated edges.
  DenseMap<const Value *, ValueSet> PointTos;
};
}

static RegisterPass<DynamicPointerAnalysis> X("dyn-pa",
                                              "Build the point-to graph from "
                                              "the point-to log",
                                              false,
                                              true);
static RegisterAnalysisGroup<PointerAnalysis> Y(X);

static cl::opt<string> LogFileName("log-file",
                                   cl::desc("Point-to log file generated by "
                                            "running the instrumented program"),
                                   cl::init(""));

char DynamicPointerAnalysis::ID = 0;

bool DynamicPointerAnalysis::runOnModule(Module &M) {
  LogRecordType RecordType;
  int numRecords = 0;
  int numAddrTakenDecls = 0;
  int numAddrTakenPointTos = 0;
  int numTopLevelPointTos = 0;

  FILE *LogFile = fopen(LogFileName.c_str(), "rb");
  while (fread(&RecordType, sizeof RecordType, 1, LogFile) == 1) {
    if (numRecords % 1000000 == 0)
      errs() << "Processed " << numRecords << " records\n";
    ++numRecords;
    switch (RecordType) {
      case AddrTakenDecl:
        {
          ++numAddrTakenDecls;
          AddrTakenDeclLogRecord Record;
          assert(fread(&Record, sizeof Record, 1, LogFile) == 1);
          processAddrTakenDecl(Record);
        }
        break;
      case TopLevelPointTo:
        {
          ++numTopLevelPointTos;
          TopLevelPointToLogRecord Record;
          assert(fread(&Record, sizeof Record, 1, LogFile) == 1);
          processTopLevelPointTo(Record);
        }
        break;
      case AddrTakenPointTo:
        {
          ++numAddrTakenPointTos;
          AddrTakenPointToLogRecord Record;
          assert(fread(&Record, sizeof Record, 1, LogFile) == 1);
          processAddrTakenPointTo(Record);
        }
        break;
      default:
        fprintf(stderr, "RecordType = %d\n", RecordType);
        assert(false && "Unknown record type");
    }
  }

  errs() << "Processed " << numRecords << " records\n";
  errs() << "# of addr-taken decls = " << numAddrTakenDecls << "\n";
  errs() << "# of addr-taken point-tos = " << numAddrTakenPointTos << "\n";
  errs() << "# of top-level point-tos = " << numTopLevelPointTos << "\n";

  return false;
}

void DynamicPointerAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesAll();
  AU.addRequired<IDAssigner>();
}

void DynamicPointerAnalysis::processAddrTakenDecl(
    const AddrTakenDeclLogRecord &Record) {
  IDAssigner &IDA = getAnalysis<IDAssigner>();

  Value *Allocator = NULL;
  if (Record.AllocatedBy != IDAssigner::INVALID_ID)
    Allocator = IDA.getValue(Record.AllocatedBy);
  // Allocator may be NULL.
  // In that case, the memory block is allocated by an external instruction.
  // e.g. main arguments.

  unsigned long Start = (unsigned long)Record.Address;
  Interval I(Start, Start + Record.Bound);
  pair<IntervalTree::iterator, IntervalTree::iterator> ER =
      AddrTakenDecls.equal_range(I);
  AddrTakenDecls.erase(ER.first, ER.second);
  AddrTakenDecls.insert(make_pair(I, Allocator));
}

void DynamicPointerAnalysis::processTopLevelPointTo(
    const TopLevelPointToLogRecord &Record) {
  IDAssigner &IDA = getAnalysis<IDAssigner>();

  Value *Pointer = IDA.getValue(Record.PointerValueID);
  Value *Pointee = lookupAddress(Record.PointeeAddress);
  assert(Pointer);
  if (Pointee)
    PointTos[Pointer].insert(Pointee);
}

void DynamicPointerAnalysis::processAddrTakenPointTo(
    const AddrTakenPointToLogRecord &Record) {
  Value *Pointer = lookupAddress(Record.PointerAddress);
  Value *Pointee = lookupAddress(Record.PointeeAddress);
  assert(Pointer);
  if (Pointee)
    PointTos[Pointer].insert(Pointee);
}

Value *DynamicPointerAnalysis::lookupAddress(void *Addr) const {
  Interval I((unsigned long)Addr, (unsigned long)Addr + 1);
  IntervalTree::const_iterator Pos = AddrTakenDecls.find(I);
  if (Pos == AddrTakenDecls.end())
    return NULL;
  return Pos->second;
}

bool DynamicPointerAnalysis::getPointees(const Value *Pointer,
                                         ValueList &Pointees) {
  Pointees.clear();
  DenseMap<const Value *, ValueSet>::iterator I = PointTos.find(Pointer);
  if (I == PointTos.end())
    return false;

  Pointees.insert(Pointees.end(), I->second.begin(), I->second.end());
  return true;
}

void DynamicPointerAnalysis::getAllPointers(ValueList &Pointers) {
  for (DenseMap<const Value *, ValueSet>::iterator I = PointTos.begin();
       I != PointTos.end(); ++I) {
    Pointers.push_back(const_cast<Value *>(I->first));
  }
}
<|endoftext|>


<commit_before>//
// Copyright 2013-2014, Bradley A. Grantham
//
// 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 <cstdio>
#include <cstdlib>
#include <string>
#include <map>
#include <limits>
#include <algorithm>
#include <vector>
#include <unistd.h>

#define GLFW_INCLUDE_GLCOREARB
#include <GLFW/glfw3.h>

#include "vectormath.h"
#include "geometry.h"
#include "manipulator.h"

#include "drawable.h"
#include "builtin_loader.h"
#include "trisrc_loader.h"

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

static manipulator *gSceneManip;
static manipulator *gObjectManip;
static manipulator *gCurrentManip = NULL;

static bool gDrawWireframe = false;
static bool gStreamFrames = false;

static int gWindowWidth;
static int gWindowHeight;

static double gMotionReported = false;
static double gOldMouseX, gOldMouseY;
static int gButtonPressed = -1;

// XXX Allow these to be set by options
bool gVerbose = true;

std::vector<Drawable::sptr> gObjects;

float gFOV = 45;

struct Light
{
    vec4f position;
    vec4f color;
    Light(const vec4f& position_, const vec4f color_) :
        position(position_),
        color(color_)
    {}
};

struct Environment
{
    mat4f projection;
    mat4f modelview;
    std::vector<Light> lights; // only one supported at present

    Environment(const mat4f& projection_, const mat4f& modelview_, const std::vector<Light>& lights_) :
        projection(projection_),
        modelview(modelview_),
        lights(lights_)
    {}
};

struct DisplayInfo
{
    mat4f modelview;
    GLuint program;

    DisplayInfo(const mat4f& modelview_, GLuint program_) :
        modelview(modelview_),
        program(program_)
    {}

    struct Comparator
    {
        bool operator() (const DisplayInfo& d1, const DisplayInfo& d2) const
        {
            for(int i = 0; i < 16; i++) {
                if(d1.modelview.m_v[i] < d2.modelview.m_v[i])
                    return true;
                if(d1.modelview.m_v[i] < d2.modelview.m_v[i])
                    return false;
            }
            if(d1.program < d2.program)
                return true;
            if(d1.program < d2.program)
                return false;
            return false;
        }
    };

};
typedef std::map<DisplayInfo, std::vector<Drawable::sptr>, DisplayInfo::Comparator> DisplayList;

struct Node
{
    typedef boost::shared_ptr<Node> sptr;
    box bounds; // Later can cull
    virtual void Visit(const Environment& env, DisplayList& displaylist) = 0;

    Node(const box& bounds_) :
        bounds(bounds_)
    {}
};

struct Shape : public Node
{
    typedef boost::shared_ptr<Shape> sptr;
    Drawable::sptr drawable;
    virtual void Visit(const Environment& env, DisplayList& displaylist);
    Shape(const Drawable::sptr& drawable_) :
        Node(drawable->bounds),
        drawable(drawable_)
    {}
};

void Shape::Visit(const Environment& env, DisplayList& displaylist)
{
    displaylist[DisplayInfo(env.modelview, drawable->GetProgram())].push_back(drawable);
}

box TransformedBounds(const mat4f& transform, std::vector<Node::sptr> children)
{
    box b;

    for(auto it = children.begin(); it != children.end(); it++)
        b.extend((*it)->bounds * transform);

    return b;
}

struct Group : public Node
{
    typedef boost::shared_ptr<Group> sptr;
    mat4f transform;
    std::vector<Node::sptr> children;

    virtual void Visit(const Environment& env, DisplayList& displaylist);
    Group(const mat4f& transform_, std::vector<Node::sptr> children_) :
        Node(TransformedBounds(transform_, children_)),
        transform(transform_),
        children(children_)
    {}
};

void Group::Visit(const Environment& env, DisplayList& displaylist)
{
    mat4f newtransform = transform * env.modelview;
    Environment env2(env.projection, newtransform, env.lights);
    for(auto it = children.begin(); it != children.end(); it++)
        (*it)->Visit(env2, displaylist);
}

void DrawScene()
{
    float nearClip, farClip;

    /* XXX - need to create new box from all subordinate boxes */
    nearClip = - gSceneManip->m_translation[2] - gSceneManip->m_reference_size;
    farClip = - gSceneManip->m_translation[2] + gSceneManip->m_reference_size;
    if(nearClip < 0.1 * gSceneManip->m_reference_size)
	nearClip = 0.1 * gSceneManip->m_reference_size;
    if(farClip < 0.2 * gSceneManip->m_reference_size)
	nearClip = 0.2 * gSceneManip->m_reference_size;

    float frustumLeft, frustumRight, frustumBottom, frustumTop;
    frustumTop = tanf(gFOV / 180.0 * 3.14159 / 2) * nearClip;
    frustumBottom = -frustumTop;
    frustumRight = frustumTop * gWindowWidth / gWindowHeight;
    frustumLeft = -frustumRight;
    mat4f projection = mat4f::frustum(frustumLeft, frustumRight, frustumBottom, frustumTop, nearClip, farClip);

    Light light(vec4f(.577, .577, .577, 0), vec4f(1, 1, 1, 1));

    GLuint prevprogram;
    for(auto it = gObjects.begin(); it != gObjects.end(); it++) {
        Drawable::sptr ob(*it);
        GLuint program = ob->GetProgram();
        if(program != prevprogram)
        {
            glUseProgram(program);
            EnvironmentUniforms envu = ob->GetEnvironmentUniforms();
            glUniformMatrix4fv(envu.projection, 1, GL_FALSE, projection.m_v);
            CheckOpenGL(__FILE__, __LINE__);

            glUniform4fv(envu.lightPosition, 1, light.position.m_v);
            glUniform4fv(envu.lightColor, 1, light.color.m_v);
            CheckOpenGL(__FILE__, __LINE__);

            /* draw floor, draw shadow, etc */

            // XXX same object matrix for all objects
            mat4f modelview = gObjectManip->m_matrix * gSceneManip->m_matrix;
            mat4f modelview_normal = modelview;
            // XXX should not invert every time; parallel normal matrix math path?
            modelview_normal.transpose();
            modelview_normal.invert();
            glUniformMatrix4fv(envu.modelview, 1, GL_FALSE, modelview.m_v);
            glUniformMatrix4fv(envu.modelviewNormal, 1, GL_FALSE, modelview_normal.m_v);

            prevprogram = program;
        }
        ob->Draw(0, gDrawWireframe);
    }
}

void InitializeGL()
{
    CheckOpenGL(__FILE__, __LINE__);
    glClearColor(.25, .25, .25, 0);

    glEnable(GL_DEPTH_TEST);
    // glEnable(GL_CULL_FACE);
    glDisable(GL_CULL_FACE);

    CheckOpenGL(__FILE__, __LINE__);
}

void TeardownGL()
{
}

static void InitializeScene(std::vector<Drawable::sptr>& objects)
{
    box bounds;
    for(auto it = objects.begin(); it != objects.end(); it++) {
        Drawable::sptr ob(*it);

        bounds.extend(ob->bounds);
    }
    gSceneManip = new manipulator(bounds, gFOV / 180.0 * 3.14159);

    gObjectManip = new manipulator();
    gObjectManip->calculate_matrix();

    gCurrentManip = gSceneManip;
}

static void ErrorCallback(int error, const char* description)
{
    fprintf(stderr, "GLFW: %s\n", description);
}

static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
{
    if(action == GLFW_PRESS) {
        switch(key) {
            case 'W':
                gDrawWireframe = !gDrawWireframe;
                break;

            case 'R':
                gCurrentManip->m_mode = manipulator::ROTATE;
                break;

            case 'O':
                gCurrentManip->m_mode = manipulator::ROLL;
                break;

            case 'X':
                gCurrentManip->m_mode = manipulator::SCROLL;
                break;

            case 'Z':
                gCurrentManip->m_mode = manipulator::DOLLY;
                break;

            case '1':
                gCurrentManip = gSceneManip;
                break;

            case '2':
                gCurrentManip = gObjectManip;
                break;

            case 'Q': case '\033':
                glfwSetWindowShouldClose(window, GL_TRUE);
                break;
        }
    }
}

static void ResizeCallback(GLFWwindow *window, int x, int y)
{
    glfwGetFramebufferSize(window, &gWindowWidth, &gWindowHeight);
    glViewport(0, 0, gWindowWidth, gWindowHeight);
}

static void ButtonCallback(GLFWwindow *window, int b, int action, int mods)
{
    double x, y;
    glfwGetCursorPos(window, &x, &y);

    if(b == GLFW_MOUSE_BUTTON_1 && action == GLFW_PRESS) {
        gButtonPressed = 1;
	gOldMouseX = x;
	gOldMouseY = y;
    } else {
        gButtonPressed = -1;
    }
}

static void MotionCallback(GLFWwindow *window, double x, double y)
{
    // glfw/glfw#103
    // If no motion has been reported yet, we catch the first motion
    // reported and store the current location
    if(!gMotionReported) {
        gMotionReported = true;
        gOldMouseX = x;
        gOldMouseY = y;
    }

    double dx, dy;

    dx = x - gOldMouseX;
    dy = y - gOldMouseY;

    gOldMouseX = x;
    gOldMouseY = y;

    if(gButtonPressed == 1) {
        gCurrentManip->move(dx / gWindowWidth, dy / gWindowHeight);
        if(gCurrentManip == gSceneManip)
            gObjectManip->set_frame(gSceneManip->m_matrix);
    }
}

static void ScrollCallback(GLFWwindow *window, double dx, double dy)
{
    gCurrentManip->move(dx / gWindowWidth, dy / gWindowHeight);
    if(gCurrentManip == gSceneManip)
        gObjectManip->set_frame(gSceneManip->m_matrix);
}

static void DrawFrame(GLFWwindow *window)
{
    CheckOpenGL(__FILE__, __LINE__);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    CheckOpenGL(__FILE__, __LINE__);

    DrawScene();

    CheckOpenGL(__FILE__, __LINE__);
}

bool LoadScene(const std::string& filename, std::vector<Drawable::sptr>& objects)
{
    int index = filename.find_last_of(".");
    std::string extension = filename.substr(index + 1);

    if(extension == "builtin") {
        return BuiltinLoader::Load(filename, objects);
    } else if(extension == "trisrc") {
        return TriSrcLoader::Load(filename, objects);
    } else {
        return false;
    }
}

int main(int argc, char **argv)
{
    const char *progname = argv[0];
    if(argc < 2) {
        fprintf(stderr, "usage: %s filename # e.g. \"%s 64gon.builtin\"\n", progname, progname);
        exit(EXIT_FAILURE);
    }

    const char *scene_filename = argv[1];

    GLFWwindow* window;

    glfwSetErrorCallback(ErrorCallback);

    if(!glfwInit())
        exit(EXIT_FAILURE);

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    glfwWindowHint(GLFW_SAMPLES, 4);
    window = glfwCreateWindow(gWindowWidth = 512, gWindowHeight = 512, "Spin", NULL, NULL);
    if (!window) {
        glfwTerminate();
        fprintf(stdout, "Couldn't open main window\n");
        exit(EXIT_FAILURE);
    }

    glfwMakeContextCurrent(window);

    InitializeGL();
    if(!LoadScene(scene_filename, gObjects)) {
        fprintf(stderr, "couldn't load scene from %s\n", scene_filename);
        exit(EXIT_FAILURE);
    }
    InitializeScene(gObjects);

    if(gVerbose) {
        printf("GL_RENDERER: %s\n", glGetString(GL_RENDERER));
        printf("GL_VERSION: %s\n", glGetString(GL_VERSION));
    }

    glfwSetKeyCallback(window, KeyCallback);
    glfwSetMouseButtonCallback(window, ButtonCallback);
    glfwSetCursorPosCallback(window, MotionCallback);
    glfwSetScrollCallback(window, ScrollCallback);
    glfwSetFramebufferSizeCallback(window, ResizeCallback);
    glfwSetWindowRefreshCallback(window, DrawFrame);

    while (!glfwWindowShouldClose(window)) {

        DrawFrame(window);

        glfwSwapBuffers(window);

        if(gStreamFrames)
            glfwPollEvents();
        else
            glfwWaitEvents();
    }

    glfwTerminate();
}
<commit_msg>remove gObjectManip<commit_after>//
// Copyright 2013-2014, Bradley A. Grantham
//
// 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 <cstdio>
#include <cstdlib>
#include <string>
#include <map>
#include <limits>
#include <algorithm>
#include <vector>
#include <unistd.h>

#define GLFW_INCLUDE_GLCOREARB
#include <GLFW/glfw3.h>

#include "vectormath.h"
#include "geometry.h"
#include "manipulator.h"

#include "drawable.h"
#include "builtin_loader.h"
#include "trisrc_loader.h"

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

static manipulator *gSceneManip;
static manipulator *gCurrentManip = NULL;

static bool gDrawWireframe = false;
static bool gStreamFrames = false;

static int gWindowWidth;
static int gWindowHeight;

static double gMotionReported = false;
static double gOldMouseX, gOldMouseY;
static int gButtonPressed = -1;

// XXX Allow these to be set by options
bool gVerbose = true;

std::vector<Drawable::sptr> gObjects;

float gFOV = 45;

struct Light
{
    vec4f position;
    vec4f color;
    Light(const vec4f& position_, const vec4f color_) :
        position(position_),
        color(color_)
    {}
};

struct Environment
{
    mat4f projection;
    mat4f modelview;
    std::vector<Light> lights; // only one supported at present

    Environment(const mat4f& projection_, const mat4f& modelview_, const std::vector<Light>& lights_) :
        projection(projection_),
        modelview(modelview_),
        lights(lights_)
    {}
};

struct DisplayInfo
{
    mat4f modelview;
    GLuint program;

    DisplayInfo(const mat4f& modelview_, GLuint program_) :
        modelview(modelview_),
        program(program_)
    {}

    struct Comparator
    {
        bool operator() (const DisplayInfo& d1, const DisplayInfo& d2) const
        {
            for(int i = 0; i < 16; i++) {
                if(d1.modelview.m_v[i] < d2.modelview.m_v[i])
                    return true;
                if(d1.modelview.m_v[i] < d2.modelview.m_v[i])
                    return false;
            }
            if(d1.program < d2.program)
                return true;
            if(d1.program < d2.program)
                return false;
            return false;
        }
    };

};
typedef std::map<DisplayInfo, std::vector<Drawable::sptr>, DisplayInfo::Comparator> DisplayList;

struct Node
{
    typedef boost::shared_ptr<Node> sptr;
    box bounds; // Later can cull
    virtual void Visit(const Environment& env, DisplayList& displaylist) = 0;

    Node(const box& bounds_) :
        bounds(bounds_)
    {}
};

struct Shape : public Node
{
    typedef boost::shared_ptr<Shape> sptr;
    Drawable::sptr drawable;
    virtual void Visit(const Environment& env, DisplayList& displaylist);
    Shape(const Drawable::sptr& drawable_) :
        Node(drawable->bounds),
        drawable(drawable_)
    {}
};

void Shape::Visit(const Environment& env, DisplayList& displaylist)
{
    displaylist[DisplayInfo(env.modelview, drawable->GetProgram())].push_back(drawable);
}

box TransformedBounds(const mat4f& transform, std::vector<Node::sptr> children)
{
    box b;

    for(auto it = children.begin(); it != children.end(); it++)
        b.extend((*it)->bounds * transform);

    return b;
}

struct Group : public Node
{
    typedef boost::shared_ptr<Group> sptr;
    mat4f transform;
    std::vector<Node::sptr> children;

    virtual void Visit(const Environment& env, DisplayList& displaylist);
    Group(const mat4f& transform_, std::vector<Node::sptr> children_) :
        Node(TransformedBounds(transform_, children_)),
        transform(transform_),
        children(children_)
    {}
};

void Group::Visit(const Environment& env, DisplayList& displaylist)
{
    mat4f newtransform = transform * env.modelview;
    Environment env2(env.projection, newtransform, env.lights);
    for(auto it = children.begin(); it != children.end(); it++)
        (*it)->Visit(env2, displaylist);
}

void DrawScene()
{
    float nearClip, farClip;

    /* XXX - need to create new box from all subordinate boxes */
    nearClip = - gSceneManip->m_translation[2] - gSceneManip->m_reference_size;
    farClip = - gSceneManip->m_translation[2] + gSceneManip->m_reference_size;
    if(nearClip < 0.1 * gSceneManip->m_reference_size)
	nearClip = 0.1 * gSceneManip->m_reference_size;
    if(farClip < 0.2 * gSceneManip->m_reference_size)
	nearClip = 0.2 * gSceneManip->m_reference_size;

    float frustumLeft, frustumRight, frustumBottom, frustumTop;
    frustumTop = tanf(gFOV / 180.0 * 3.14159 / 2) * nearClip;
    frustumBottom = -frustumTop;
    frustumRight = frustumTop * gWindowWidth / gWindowHeight;
    frustumLeft = -frustumRight;
    mat4f projection = mat4f::frustum(frustumLeft, frustumRight, frustumBottom, frustumTop, nearClip, farClip);

    Light light(vec4f(.577, .577, .577, 0), vec4f(1, 1, 1, 1));

    GLuint prevprogram;
    for(auto it = gObjects.begin(); it != gObjects.end(); it++) {
        Drawable::sptr ob(*it);
        GLuint program = ob->GetProgram();
        if(program != prevprogram)
        {
            glUseProgram(program);
            EnvironmentUniforms envu = ob->GetEnvironmentUniforms();
            glUniformMatrix4fv(envu.projection, 1, GL_FALSE, projection.m_v);
            CheckOpenGL(__FILE__, __LINE__);

            glUniform4fv(envu.lightPosition, 1, light.position.m_v);
            glUniform4fv(envu.lightColor, 1, light.color.m_v);
            CheckOpenGL(__FILE__, __LINE__);

            /* draw floor, draw shadow, etc */

            // XXX same object matrix for all objects
            mat4f modelview = gSceneManip->m_matrix;

            mat4f modelview_normal = modelview;
            // XXX should not invert every time
            // XXX parallel normal matrix math path?
            modelview_normal.transpose();
            modelview_normal.invert();

            glUniformMatrix4fv(envu.modelview, 1, GL_FALSE, modelview.m_v);
            glUniformMatrix4fv(envu.modelviewNormal, 1, GL_FALSE, modelview_normal.m_v);

            prevprogram = program;
        }
        ob->Draw(0, gDrawWireframe);
    }
}

void InitializeGL()
{
    CheckOpenGL(__FILE__, __LINE__);
    glClearColor(.25, .25, .25, 0);

    glEnable(GL_DEPTH_TEST);
    // glEnable(GL_CULL_FACE);
    glDisable(GL_CULL_FACE);

    CheckOpenGL(__FILE__, __LINE__);
}

void TeardownGL()
{
}

static void InitializeScene(std::vector<Drawable::sptr>& objects)
{
    box bounds;
    for(auto it = objects.begin(); it != objects.end(); it++) {
        Drawable::sptr ob(*it);

        bounds.extend(ob->bounds);
    }
    gSceneManip = new manipulator(bounds, gFOV / 180.0 * 3.14159);

    gCurrentManip = gSceneManip;
}

static void ErrorCallback(int error, const char* description)
{
    fprintf(stderr, "GLFW: %s\n", description);
}

static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
{
    if(action == GLFW_PRESS) {
        switch(key) {
            case 'W':
                gDrawWireframe = !gDrawWireframe;
                break;

            case 'R':
                gCurrentManip->m_mode = manipulator::ROTATE;
                break;

            case 'O':
                gCurrentManip->m_mode = manipulator::ROLL;
                break;

            case 'X':
                gCurrentManip->m_mode = manipulator::SCROLL;
                break;

            case 'Z':
                gCurrentManip->m_mode = manipulator::DOLLY;
                break;

            case 'Q': case '\033':
                glfwSetWindowShouldClose(window, GL_TRUE);
                break;
        }
    }
}

static void ResizeCallback(GLFWwindow *window, int x, int y)
{
    glfwGetFramebufferSize(window, &gWindowWidth, &gWindowHeight);
    glViewport(0, 0, gWindowWidth, gWindowHeight);
}

static void ButtonCallback(GLFWwindow *window, int b, int action, int mods)
{
    double x, y;
    glfwGetCursorPos(window, &x, &y);

    if(b == GLFW_MOUSE_BUTTON_1 && action == GLFW_PRESS) {
        gButtonPressed = 1;
	gOldMouseX = x;
	gOldMouseY = y;
    } else {
        gButtonPressed = -1;
    }
}

static void MotionCallback(GLFWwindow *window, double x, double y)
{
    // glfw/glfw#103
    // If no motion has been reported yet, we catch the first motion
    // reported and store the current location
    if(!gMotionReported) {
        gMotionReported = true;
        gOldMouseX = x;
        gOldMouseY = y;
    }

    double dx, dy;

    dx = x - gOldMouseX;
    dy = y - gOldMouseY;

    gOldMouseX = x;
    gOldMouseY = y;

    if(gButtonPressed == 1) {
        gCurrentManip->move(dx / gWindowWidth, dy / gWindowHeight);
    }
}

static void ScrollCallback(GLFWwindow *window, double dx, double dy)
{
    gCurrentManip->move(dx / gWindowWidth, dy / gWindowHeight);
}

static void DrawFrame(GLFWwindow *window)
{
    CheckOpenGL(__FILE__, __LINE__);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    CheckOpenGL(__FILE__, __LINE__);

    DrawScene();

    CheckOpenGL(__FILE__, __LINE__);
}

bool LoadScene(const std::string& filename, std::vector<Drawable::sptr>& objects)
{
    int index = filename.find_last_of(".");
    std::string extension = filename.substr(index + 1);

    if(extension == "builtin") {
        return BuiltinLoader::Load(filename, objects);
    } else if(extension == "trisrc") {
        return TriSrcLoader::Load(filename, objects);
    } else {
        return false;
    }
}

int main(int argc, char **argv)
{
    const char *progname = argv[0];
    if(argc < 2) {
        fprintf(stderr, "usage: %s filename # e.g. \"%s 64gon.builtin\"\n", progname, progname);
        exit(EXIT_FAILURE);
    }

    const char *scene_filename = argv[1];

    GLFWwindow* window;

    glfwSetErrorCallback(ErrorCallback);

    if(!glfwInit())
        exit(EXIT_FAILURE);

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    glfwWindowHint(GLFW_SAMPLES, 4);
    window = glfwCreateWindow(gWindowWidth = 512, gWindowHeight = 512, "Spin", NULL, NULL);
    if (!window) {
        glfwTerminate();
        fprintf(stdout, "Couldn't open main window\n");
        exit(EXIT_FAILURE);
    }

    glfwMakeContextCurrent(window);

    InitializeGL();
    if(!LoadScene(scene_filename, gObjects)) {
        fprintf(stderr, "couldn't load scene from %s\n", scene_filename);
        exit(EXIT_FAILURE);
    }
    InitializeScene(gObjects);

    if(gVerbose) {
        printf("GL_RENDERER: %s\n", glGetString(GL_RENDERER));
        printf("GL_VERSION: %s\n", glGetString(GL_VERSION));
    }

    glfwSetKeyCallback(window, KeyCallback);
    glfwSetMouseButtonCallback(window, ButtonCallback);
    glfwSetCursorPosCallback(window, MotionCallback);
    glfwSetScrollCallback(window, ScrollCallback);
    glfwSetFramebufferSizeCallback(window, ResizeCallback);
    glfwSetWindowRefreshCallback(window, DrawFrame);

    while (!glfwWindowShouldClose(window)) {

        DrawFrame(window);

        glfwSwapBuffers(window);

        if(gStreamFrames)
            glfwPollEvents();
        else
            glfwWaitEvents();
    }

    glfwTerminate();
}
<|endoftext|>


<commit_before>/**
 * \file
 * \brief priorityTestPhases object declaration
 *
 * \author Copyright (C) 2014-2016 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \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 TEST_PRIORITYTESTPHASES_HPP_
#define TEST_PRIORITYTESTPHASES_HPP_

#include <array>

namespace distortos
{

namespace test
{

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

/// number of test threads
constexpr size_t totalThreads {10};

/// number of test phases
constexpr size_t totalPhases {8};

/// max priority used in test phases
constexpr uint8_t maxPhasePriority {UINT8_MAX};

/*---------------------------------------------------------------------------------------------------------------------+
| global types
+---------------------------------------------------------------------------------------------------------------------*/

/// parameters of test thread - priority, sequence point
using ThreadParameters = std::pair<uint8_t, uint8_t>;

/// description of test phase - reference to array with ThreadParameters, sequence of indexes for this array
using TestPhase = std::pair<const std::array<ThreadParameters, totalThreads>&, std::array<uint8_t, totalThreads>>;

/*---------------------------------------------------------------------------------------------------------------------+
| global objects
+---------------------------------------------------------------------------------------------------------------------*/

/// array with test phases
extern const std::array<TestPhase, totalPhases> priorityTestPhases;

}	// namespace test

}	// namespace distortos

#endif	// TEST_PRIORITYTESTPHASES_HPP_
<commit_msg>Reduce maxPhasePriority value in priorityTestPhases<commit_after>/**
 * \file
 * \brief priorityTestPhases object declaration
 *
 * \author Copyright (C) 2014-2016 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \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 TEST_PRIORITYTESTPHASES_HPP_
#define TEST_PRIORITYTESTPHASES_HPP_

#include <array>

namespace distortos
{

namespace test
{

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

/// number of test threads
constexpr size_t totalThreads {10};

/// number of test phases
constexpr size_t totalPhases {8};

/// max priority used in test phases
constexpr uint8_t maxPhasePriority {UINT8_MAX - 1};

/*---------------------------------------------------------------------------------------------------------------------+
| global types
+---------------------------------------------------------------------------------------------------------------------*/

/// parameters of test thread - priority, sequence point
using ThreadParameters = std::pair<uint8_t, uint8_t>;

/// description of test phase - reference to array with ThreadParameters, sequence of indexes for this array
using TestPhase = std::pair<const std::array<ThreadParameters, totalThreads>&, std::array<uint8_t, totalThreads>>;

/*---------------------------------------------------------------------------------------------------------------------+
| global objects
+---------------------------------------------------------------------------------------------------------------------*/

/// array with test phases
extern const std::array<TestPhase, totalPhases> priorityTestPhases;

}	// namespace test

}	// namespace distortos

#endif	// TEST_PRIORITYTESTPHASES_HPP_
<|endoftext|>


<commit_before>// Copyright (C) 2010-2013 Joshua Boyce.
// See the file COPYING for copying permission.

#include <memory>
#include <string>
#include <vector>
#include <sstream>
#include <iostream>

#include <hadesmem/detail/warning_disable_prefix.hpp>
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <hadesmem/detail/warning_disable_suffix.hpp>

#include <windows.h>

#include <hadesmem/call.hpp>
#include <hadesmem/error.hpp>
#include <hadesmem/config.hpp>
#include <hadesmem/module.hpp>
#include <hadesmem/process.hpp>
#include <hadesmem/injector.hpp>
#include <hadesmem/detail/self_path.hpp>
#include <hadesmem/detail/initialize.hpp>

// TODO: Add support for for passing args, work dir, etc to CreateAndInject.
// e.g. exe-arg0, exe-arg1, exe-arg2, ..., exe-argN?

namespace
{

std::wstring PtrToString(void const* const ptr)
{
  std::wostringstream str;
  str.imbue(std::locale::classic());
  str << std::hex << reinterpret_cast<DWORD_PTR>(ptr);
  return str.str();
}

}

int main(int argc, char* /*argv*/[])
{
  try
  {
    hadesmem::detail::InitializeAll();

    std::cout << "HadesMem Injector\n";

    boost::program_options::options_description opts_desc(
      "General options");
    opts_desc.add_options()
      ("help", "produce help message")
      ("pid", boost::program_options::value<DWORD>(), "process id")
      ("module", boost::program_options::wvalue<std::wstring>(), "module path")
      ("path-resolution", "perform path resolution")
      ("export", boost::program_options::value<std::string>(), "export name")
      ("free", "unload module")
      ("add-path", "add module dir to serach order")
      ("run", boost::program_options::wvalue<std::wstring>(), "process path")
      ;

    std::vector<std::wstring> const args = boost::program_options::
      split_winmain(GetCommandLine());
    boost::program_options::variables_map var_map;
    boost::program_options::store(boost::program_options::wcommand_line_parser(
      args).options(opts_desc).run(), var_map);
    boost::program_options::notify(var_map);

    if (var_map.count("help") || argc == 1)
    {
      std::cout << '\n' << opts_desc << '\n';
      return 1;
    }

    if (!var_map.count("module"))
    {
      std::cerr << "\nError! Module path must be specified.\n";
      return 1;
    }

    bool const has_pid = (var_map.count("pid") != 0);
    bool const create_proc = (var_map.count("run") != 0);
    if ((has_pid && create_proc) || (!has_pid && !create_proc))
    {
      std::cerr << "\nError! A process ID or an executable path must be "
        "specified.\n";
      return 1;
    }

    bool const inject = (var_map.count("free") == 0);
    if (!inject && create_proc)
    {
      std::cerr << "\nError! Modules can only be unloaded from running "
        "targets.\n";
      return 1;
    }

    std::wstring const module_path = var_map["module"].as<std::wstring>();
    bool const path_resolution = var_map.count("path-resolution") != 0;
    bool const add_path = var_map.count("add-path") != 0;

    int flags = hadesmem::InjectFlags::kNone;
    if (path_resolution)
    {
      flags |= hadesmem::InjectFlags::kPathResolution;
    }
    if (add_path)
    {
      flags |= hadesmem::InjectFlags::kAddToSearchOrder;
    }

    if (has_pid)
    {
      try
      {
        hadesmem::GetSeDebugPrivilege();

        std::wcout << "\nAcquired SeDebugPrivilege.\n";
      }
      catch (std::exception const& /*e*/)
      {
        std::wcout << "\nFailed to acquire SeDebugPrivilege.\n";
      }

      DWORD const pid = var_map["pid"].as<DWORD>();

      hadesmem::Process const process(pid);

      HMODULE module = nullptr;

      if (inject)
      {
        module = hadesmem::InjectDll(process, module_path, flags);

        std::wcout << "\nSuccessfully injected module at base address " <<
          PtrToString(module) << ".\n";
      }
      else
      {
        boost::filesystem::path path_real(module_path);
        if (path_resolution && path_real.is_relative())
        {
          path_real = boost::filesystem::absolute(path_real,
            hadesmem::detail::GetSelfDirPath());
        }
        path_real.make_preferred();

        hadesmem::Module const remote_module(process, path_real.native());
        module = remote_module.GetHandle();
      }

      if (var_map.count("export"))
      {
        std::string const export_name = var_map["export"].as<std::string>();
        auto const export_ret = hadesmem::CallExport(process, module,
          export_name);

        std::wcout << "\nSuccessfully called module export.\n";
        std::wcout << "Return: " << export_ret.GetReturnValue() << ".\n";
        std::wcout << "LastError: " << export_ret.GetLastError() << ".\n";
      }

      if (!inject)
      {
        hadesmem::FreeDll(process, module);

        std::wcout << "\nSuccessfully freed module at base address " <<
          PtrToString(module) << ".\n";
      }
    }
    else
    {
      std::wstring const exe_path = var_map["run"].as<std::wstring>();
      std::string const export_name = var_map.count("export") ?
        var_map["export"].as<std::string>() : "";
      hadesmem::CreateAndInjectData const inject_data =
        hadesmem::CreateAndInject(
        exe_path,
        L"",
        std::vector<std::wstring>::iterator(),
        std::vector<std::wstring>::iterator(),
        module_path,
        export_name,
        flags);

      std::wcout << "\nSuccessfully created target.\n";
      std::wcout << "Process ID: " << inject_data.GetProcess() << ".\n";
      std::wcout << "Module Base: " << PtrToString(inject_data.GetModule())
        << ".\n";
      std::wcout << "Export Return: " << inject_data.GetExportRet() << ".\n";
      std::wcout << "Export LastError: " << inject_data.GetExportLastError()
        << ".\n";
    }

    return 0;
  }
  catch (std::exception const& e)
  {
    std::cerr << "\nError!\n";
    std::cerr << boost::diagnostic_information(e) << '\n';

    return 1;
  }
}
<commit_msg>* Fix bug in Inject.<commit_after>// Copyright (C) 2010-2013 Joshua Boyce.
// See the file COPYING for copying permission.

#include <memory>
#include <string>
#include <vector>
#include <sstream>
#include <iostream>

#include <hadesmem/detail/warning_disable_prefix.hpp>
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <hadesmem/detail/warning_disable_suffix.hpp>

#include <windows.h>

#include <hadesmem/call.hpp>
#include <hadesmem/error.hpp>
#include <hadesmem/config.hpp>
#include <hadesmem/module.hpp>
#include <hadesmem/process.hpp>
#include <hadesmem/injector.hpp>
#include <hadesmem/detail/self_path.hpp>
#include <hadesmem/detail/initialize.hpp>

// TODO: Add support for for passing args, work dir, etc to CreateAndInject.
// e.g. exe-arg0, exe-arg1, exe-arg2, ..., exe-argN?

namespace
{

std::wstring PtrToString(void const* const ptr)
{
  std::wostringstream str;
  str.imbue(std::locale::classic());
  str << std::hex << reinterpret_cast<DWORD_PTR>(ptr);
  return str.str();
}

}

int main(int argc, char* /*argv*/[])
{
  try
  {
    hadesmem::detail::InitializeAll();

    std::cout << "HadesMem Injector\n";

    boost::program_options::options_description opts_desc(
      "General options");
    opts_desc.add_options()
      ("help", "produce help message")
      ("pid", boost::program_options::value<DWORD>(), "process id")
      ("module", boost::program_options::wvalue<std::wstring>(), "module path")
      ("path-resolution", "perform path resolution")
      ("export", boost::program_options::value<std::string>(), "export name")
      ("free", "unload module")
      ("add-path", "add module dir to serach order")
      ("run", boost::program_options::wvalue<std::wstring>(), "process path")
      ;

    std::vector<std::wstring> const args = boost::program_options::
      split_winmain(GetCommandLine());
    boost::program_options::variables_map var_map;
    boost::program_options::store(boost::program_options::wcommand_line_parser(
      args).options(opts_desc).run(), var_map);
    boost::program_options::notify(var_map);

    if (var_map.count("help") || argc == 1)
    {
      std::cout << '\n' << opts_desc << '\n';
      return 1;
    }

    if (!var_map.count("module"))
    {
      std::cerr << "\nError! Module path must be specified.\n";
      return 1;
    }

    bool const has_pid = (var_map.count("pid") != 0);
    bool const create_proc = (var_map.count("run") != 0);
    if ((has_pid && create_proc) || (!has_pid && !create_proc))
    {
      std::cerr << "\nError! A process ID or an executable path must be "
        "specified.\n";
      return 1;
    }

    bool const inject = (var_map.count("free") == 0);
    if (!inject && create_proc)
    {
      std::cerr << "\nError! Modules can only be unloaded from running "
        "targets.\n";
      return 1;
    }

    std::wstring const module_path = var_map["module"].as<std::wstring>();
    bool const path_resolution = var_map.count("path-resolution") != 0;
    bool const add_path = var_map.count("add-path") != 0;

    int flags = hadesmem::InjectFlags::kNone;
    if (path_resolution)
    {
      flags |= hadesmem::InjectFlags::kPathResolution;
    }
    if (add_path)
    {
      flags |= hadesmem::InjectFlags::kAddToSearchOrder;
    }

    if (has_pid)
    {
      try
      {
        hadesmem::GetSeDebugPrivilege();

        std::wcout << "\nAcquired SeDebugPrivilege.\n";
      }
      catch (std::exception const& /*e*/)
      {
        std::wcout << "\nFailed to acquire SeDebugPrivilege.\n";
      }

      DWORD const pid = var_map["pid"].as<DWORD>();

      hadesmem::Process const process(pid);

      HMODULE module = nullptr;

      if (inject)
      {
        module = hadesmem::InjectDll(process, module_path, flags);

        std::wcout << "\nSuccessfully injected module at base address " <<
          PtrToString(module) << ".\n";
      }
      else
      {
        boost::filesystem::path path_real(module_path);
        if (path_resolution && path_real.is_relative())
        {
          path_real = boost::filesystem::absolute(path_real,
            hadesmem::detail::GetSelfDirPath());
        }
        path_real.make_preferred();

        hadesmem::Module const remote_module(process, path_real.native());
        module = remote_module.GetHandle();
      }

      if (var_map.count("export"))
      {
        std::string const export_name = var_map["export"].as<std::string>();
        auto const export_ret = hadesmem::CallExport(process, module,
          export_name);

        std::wcout << "\nSuccessfully called module export.\n";
        std::wcout << "Return: " << export_ret.GetReturnValue() << ".\n";
        std::wcout << "LastError: " << export_ret.GetLastError() << ".\n";
      }

      if (!inject)
      {
        hadesmem::FreeDll(process, module);

        std::wcout << "\nSuccessfully freed module at base address " <<
          PtrToString(module) << ".\n";
      }
    }
    else
    {
      std::vector<std::wstring> args;
      std::wstring const exe_path = var_map["run"].as<std::wstring>();
      std::string const export_name = var_map.count("export") ?
        var_map["export"].as<std::string>() : "";
      hadesmem::CreateAndInjectData const inject_data =
        hadesmem::CreateAndInject(
        exe_path,
        L"",
        std::begin(args),
        std::end(args),
        module_path,
        export_name,
        flags);

      std::wcout << "\nSuccessfully created target.\n";
      std::wcout << "Process ID: " << inject_data.GetProcess() << ".\n";
      std::wcout << "Module Base: " << PtrToString(inject_data.GetModule())
        << ".\n";
      std::wcout << "Export Return: " << inject_data.GetExportRet() << ".\n";
      std::wcout << "Export LastError: " << inject_data.GetExportLastError()
        << ".\n";
    }

    return 0;
  }
  catch (std::exception const& e)
  {
    std::cerr << "\nError!\n";
    std::cerr << boost::diagnostic_information(e) << '\n';

    return 1;
  }
}
<|endoftext|>


<commit_before>// Licensed under the Apache License, Version 2.0.
// Author: Jin Qing (http://blog.csdn.net/jq0123)
// Dynamic singleton helper for manager class.
// See struct manager::dyn_singleton_helper in
//  "(A dynamic) Singleton using weak_ptr and shared_ptr"
//  http://boost.2283326.n4.nabble.com/A-dynamic-Singleton-using-weak-ptr-and-shared-ptr-td2581447.html

#include <rpcz/manager.hpp>

namespace rpcz {

manager::dyn_singleton_helper::manager_weak_ptr
    manager::dyn_singleton_helper::mgr_wptr;
boost::recursive_mutex
    manager::dyn_singleton_helper::mgr_wptr_mtx;

bool manager::dyn_singleton_helper::mgr_exists = false;
boost::recursive_mutex manager::dyn_singleton_helper::mgr_exists_mtx;
boost::condition_variable_any manager::dyn_singleton_helper::cond;

struct manager::dyn_singleton_deleter {
  void operator()(manager* p) {
    BOOST_ASSERT(p);
    delete p;
    manager::dyn_singleton_helper::finish_destruction();
  }
};

void manager::dyn_singleton_helper::start_construction()
{
  boost::recursive_mutex::scoped_lock lock(mgr_exists_mtx);
  while (mgr_exists) {
    cond.wait(lock);
  }
  mgr_exists = true;
}

void manager::dyn_singleton_helper::finish_destruction()
{
  boost::recursive_mutex::scoped_lock lock(mgr_exists_mtx);
  mgr_exists = false;
  cond.notify_one();
}

manager_ptr manager::dyn_singleton_helper::make_manager_ptr() {
  // Syncronise Initialization:
  boost::recursive_mutex::scoped_lock lock(
      dyn_singleton_helper::mgr_wptr_mtx);
  // Acquire singleton pointer:
  manager_ptr p = dyn_singleton_helper::mgr_wptr.lock();
  if (p) return p;

  start_construction();  // blocking until previous object finished destruction.
  p.reset(new manager(), manager::dyn_singleton_deleter());  // shared_ptr
  mgr_wptr = p;
  return p;
}

}  // namespace rpcz
<commit_msg>cleanup in singleton helper<commit_after>// Licensed under the Apache License, Version 2.0.
// Author: Jin Qing (http://blog.csdn.net/jq0123)
// Dynamic singleton helper for manager class.
// See struct manager::dyn_singleton_helper in
//  "(A dynamic) Singleton using weak_ptr and shared_ptr"
//  http://boost.2283326.n4.nabble.com/A-dynamic-Singleton-using-weak-ptr-and-shared-ptr-td2581447.html

#include <rpcz/manager.hpp>

namespace rpcz {

manager::dyn_singleton_helper::manager_weak_ptr
    manager::dyn_singleton_helper::mgr_wptr;
boost::recursive_mutex
    manager::dyn_singleton_helper::mgr_wptr_mtx;

bool manager::dyn_singleton_helper::mgr_exists = false;
boost::recursive_mutex manager::dyn_singleton_helper::mgr_exists_mtx;
boost::condition_variable_any manager::dyn_singleton_helper::cond;

struct manager::dyn_singleton_deleter {
  void operator()(manager* p) {
    BOOST_ASSERT(p);
    delete p;
    dyn_singleton_helper::finish_destruction();
  }
};

void manager::dyn_singleton_helper::start_construction()
{
  boost::recursive_mutex::scoped_lock lock(mgr_exists_mtx);
  while (mgr_exists) {
    cond.wait(lock);
  }
  mgr_exists = true;
}

void manager::dyn_singleton_helper::finish_destruction()
{
  boost::recursive_mutex::scoped_lock lock(mgr_exists_mtx);
  mgr_exists = false;
  cond.notify_one();
}

manager_ptr manager::dyn_singleton_helper::make_manager_ptr() {
  // Syncronise Initialization:
  boost::recursive_mutex::scoped_lock lock(mgr_wptr_mtx);
  // Acquire singleton pointer:
  manager_ptr p = mgr_wptr.lock();
  if (p) return p;

  start_construction();  // blocking until previous object finished destruction.
  p.reset(new manager(), manager::dyn_singleton_deleter());  // shared_ptr
  mgr_wptr = p;
  return p;
}

}  // namespace rpcz
<|endoftext|>