<commit_before>/*****************************************************************************
 * libVLC backend for the Phonon library                                     *
 *                                                                           *
 * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com>               *
 * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com>                *
 * Copyright (C) 2009 Fathi Boudra <fabo@kde.org>                            *
 * Copyright (C) 2009-2010 vlc-phonon AUTHORS                                *
 *                                                                           *
 * 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 package; if not, write to the Free Software       *
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA *
 *****************************************************************************/

#include "videowidget.h"

#include "mediaobject.h"
#include "vlcmediaobject.h"

#include "vlcloader.h"

#include <QtGui/QWidget>
#include <QtGui/QApplication>
#include <QtGui/QDesktopWidget>
#include <QtCore/QtDebug>

namespace Phonon
{
namespace VLC {

/**
 * Constructs a new VideoWidget with the given parent. The video settings members
 * are set to their default values.
 */
VideoWidget::VideoWidget(QWidget *p_parent)
        : SinkNode(p_parent)
{
    p_video_widget = new Widget(p_parent, this);

    aspect_ratio = Phonon::VideoWidget::AspectRatioAuto;
    scale_mode = Phonon::VideoWidget::FitInView;

    b_filter_adjust_activated = false;
    f_brightness = 0.0;
    f_contrast = 0.0;
    f_hue = 0.0;
    f_saturation = 0.0;
}

VideoWidget::~VideoWidget()
{
}

/**
 * Connects the VideoWidget to a media object by setting the video widget
 * window system identifier of the media object to that of the owned private
 * video widget. It also connects the signal from the mediaObject regarding
 * a resize of the video.
 *
 * If the mediaObject was connected to another VideoWidget, the connection is
 * lost.
 *
 * \see VLCMediaObject
 * \param mediaObject What media object to connect to
 */
void VideoWidget::connectToMediaObject(PrivateMediaObject *mediaObject)
{
    SinkNode::connectToMediaObject(mediaObject);

    connect(mediaObject, SIGNAL(videoWidgetSizeChanged(int, int)),
            SLOT(videoWidgetSizeChanged(int, int)));

    //  mediaObject->setVideoWidgetId(p_video_widget->winId());
    mediaObject->setVideoWidget(p_video_widget);
}

/**
 * \return The aspect ratio previously set for the video widget
 */
Phonon::VideoWidget::AspectRatio VideoWidget::aspectRatio() const
{
    return aspect_ratio;
}

/**
 * Set the aspect ratio of the video.
 * VLC accepted formats are x:y (4:3, 16:9, etc...) expressing the global image aspect.
 */
void VideoWidget::setAspectRatio(Phonon::VideoWidget::AspectRatio aspect)
{
    // finish if no player
    if (!p_vlc_player)
        return;

    aspect_ratio = aspect;

    switch (aspect_ratio) {
    case Phonon::VideoWidget::AspectRatioAuto: // Let the decoder find the aspect ratio automatically from the media file (this is the default)
//        p_libvlc_video_set_aspect_ratio(p_vlc_current_media_player, "", vlc_exception);
        break;
    case Phonon::VideoWidget::AspectRatioWidget: // Fit the video into the widget making the aspect ratio depend solely on the size of the widget
        // This way the aspect ratio is freely resizeable by the user
//        p_libvlc_video_set_aspect_ratio(p_vlc_current_media_player, "", vlc_exception);
        break;
    case Phonon::VideoWidget::AspectRatio4_3:
//        p_libvlc_video_set_aspect_ratio(p_vlc_current_media_player, "4:3", vlc_exception);
        break;
    case Phonon::VideoWidget::AspectRatio16_9:
//        p_libvlc_video_set_aspect_ratio(p_vlc_current_media_player, "16:9", vlc_exception);
        break;
    default:
        qCritical() << __FUNCTION__ << "error: unsupported AspectRatio:" << (int) aspect_ratio;
    }
}

/**
 * \return The scale mode previously set for the video widget
 */
Phonon::VideoWidget::ScaleMode VideoWidget::scaleMode() const
{
    return scale_mode;
}

/**
 * Set how the video is scaled, keeping the aspect ratio into account when the video is resized.
 *
 * The ScaleMode enumeration describes how to treat aspect ratio during resizing of video.
 * \li Phonon::VideoWidget::FitInView - the video will be fitted to fill the view keeping aspect ratio
 * \li Phonon::VideoWidget::ScaleAndCrop - the video is scaled
 */
void VideoWidget::setScaleMode(Phonon::VideoWidget::ScaleMode scale)
{
    scale_mode = scale;
    switch (scale_mode) {
    case Phonon::VideoWidget::FitInView: // The video will be fitted to fill the view keeping aspect ratio
        break;
    case Phonon::VideoWidget::ScaleAndCrop: // The video is scaled
        break;
    default:
        qWarning() << __FUNCTION__ << "unknow Phonon::VideoWidget::ScaleMode:" << scale_mode;
    }
}

/**
 * \return The brightness previously set for the video widget
 */
qreal VideoWidget::brightness() const
{
    return f_brightness;
}

/**
 * Set the brightness of the video
 */
void VideoWidget::setBrightness(qreal brightness)
{
    f_brightness = brightness;

    // vlc takes brightness in range 0.0 - 2.0
    if (p_vlc_player) {
        if (!b_filter_adjust_activated) {
//            p_libvlc_video_filter_add(p_vlc_current_media_player, ADJUST, vlc_exception);
//            vlcExceptionRaised();
            b_filter_adjust_activated = true;
        }
//        p_libvlc_video_set_brightness(p_vlc_current_media_player, f_brightness + 1.0, vlc_exception);
//        vlcExceptionRaised();
    }
}

/**
 * \return The contrast previously set for the video widget
 */
qreal VideoWidget::contrast() const
{
    return f_contrast;
}

/**
 * Set the contrast of the video
 */
void VideoWidget::setContrast(qreal contrast)
{
    f_contrast = contrast;

    // vlc takes contrast in range 0.0 - 2.0
    float f_contrast = contrast;
    if (p_vlc_player) {
        if (!b_filter_adjust_activated) {
//            p_libvlc_video_filter_add(p_vlc_current_media_player, ADJUST, vlc_exception);
//            vlcExceptionRaised();
            b_filter_adjust_activated = true;
        }
//        p_libvlc_video_set_contrast(p_vlc_current_media_player, f_contrast + 1.0, vlc_exception);
//        vlcExceptionRaised();
    }
}

/**
 * \return The hue previously set for the video widget
 */
qreal VideoWidget::hue() const
{
    return f_hue;
}

/**
 * Set the hue of the video
 */
void VideoWidget::setHue(qreal hue)
{
    f_hue = hue;

    // vlc takes hue in range 0 - 360 in integer
    int i_hue = (f_hue + 1.0) * 180;
    if (p_vlc_player) {
        if (!b_filter_adjust_activated) {
//            p_libvlc_video_filter_add(p_vlc_current_media_player, ADJUST, vlc_exception);
//            vlcExceptionRaised();
            b_filter_adjust_activated = true;
        }
//        p_libvlc_video_set_hue(p_vlc_current_media_player, i_hue, vlc_exception);
//        vlcExceptionRaised();
    }

}

/**
 * \return The saturation previously set for the video widget
 */
qreal VideoWidget::saturation() const
{
    return f_saturation;
}

/**
 * Set the saturation of the video
 */
void VideoWidget::setSaturation(qreal saturation)
{
    f_saturation = saturation;

    // vlc takes brightness in range 0.0 - 3.0
    if (p_vlc_player) {
        if (!b_filter_adjust_activated) {
//            p_libvlc_video_filter_add(p_vlc_current_media_player, ADJUST, vlc_exception);
//            vlcExceptionRaised();
            b_filter_adjust_activated = true;
        }
//        p_libvlc_video_set_saturation(p_vlc_current_media_player, (f_saturation + 1.0) * 1.5, vlc_exception);
//        vlcExceptionRaised();
    }
}

/**
 * \return The owned widget that is used for the actual draw.
 */
Widget * VideoWidget::widget()
{
    return p_video_widget;
}

/**
 * Handles the change in the size of the video
 */
void VideoWidget::videoWidgetSizeChanged(int i_width, int i_height)
{
    qDebug() << __FUNCTION__ << "video width" << i_width << "height:" << i_height;

    // It resizes dynamically the widget and the main window
    // Note: I didn't find another way

    QSize videoSize(i_width, i_height);
    videoSize.boundedTo(QApplication::desktop()->availableGeometry().size());

    p_video_widget->hide();
    p_video_widget->setVideoSize(videoSize);
#ifdef Q_OS_WIN
    QWidget *p_parent = qobject_cast<QWidget *>(this->parent());
    QSize previousSize = p_parent->minimumSize();
    p_parent->setMinimumSize(videoSize);
#endif
    p_video_widget->show();
#ifdef Q_OS_WIN
    p_parent->setMinimumSize(previousSize);
#endif
}

}
} // Namespace Phonon::VLC
<commit_msg>fix header order<commit_after>/*****************************************************************************
 * libVLC backend for the Phonon library                                     *
 *                                                                           *
 * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com>               *
 * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com>                *
 * Copyright (C) 2009 Fathi Boudra <fabo@kde.org>                            *
 * Copyright (C) 2009-2010 vlc-phonon AUTHORS                                *
 *                                                                           *
 * 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 package; if not, write to the Free Software       *
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA *
 *****************************************************************************/

#include "videowidget.h"

#include <QtGui/QWidget>
#include <QtGui/QApplication>
#include <QtGui/QDesktopWidget>
#include <QtCore/QtDebug>

#include "mediaobject.h"
#include "vlcmediaobject.h"

#include "vlcloader.h"

namespace Phonon
{
namespace VLC {

/**
 * Constructs a new VideoWidget with the given parent. The video settings members
 * are set to their default values.
 */
VideoWidget::VideoWidget(QWidget *p_parent)
        : SinkNode(p_parent)
{
    p_video_widget = new Widget(p_parent, this);

    aspect_ratio = Phonon::VideoWidget::AspectRatioAuto;
    scale_mode = Phonon::VideoWidget::FitInView;

    b_filter_adjust_activated = false;
    f_brightness = 0.0;
    f_contrast = 0.0;
    f_hue = 0.0;
    f_saturation = 0.0;
}

VideoWidget::~VideoWidget()
{
}

/**
 * Connects the VideoWidget to a media object by setting the video widget
 * window system identifier of the media object to that of the owned private
 * video widget. It also connects the signal from the mediaObject regarding
 * a resize of the video.
 *
 * If the mediaObject was connected to another VideoWidget, the connection is
 * lost.
 *
 * \see VLCMediaObject
 * \param mediaObject What media object to connect to
 */
void VideoWidget::connectToMediaObject(PrivateMediaObject *mediaObject)
{
    SinkNode::connectToMediaObject(mediaObject);

    connect(mediaObject, SIGNAL(videoWidgetSizeChanged(int, int)),
            SLOT(videoWidgetSizeChanged(int, int)));

    //  mediaObject->setVideoWidgetId(p_video_widget->winId());
    mediaObject->setVideoWidget(p_video_widget);
}

/**
 * \return The aspect ratio previously set for the video widget
 */
Phonon::VideoWidget::AspectRatio VideoWidget::aspectRatio() const
{
    return aspect_ratio;
}

/**
 * Set the aspect ratio of the video.
 * VLC accepted formats are x:y (4:3, 16:9, etc...) expressing the global image aspect.
 */
void VideoWidget::setAspectRatio(Phonon::VideoWidget::AspectRatio aspect)
{
    // finish if no player
    if (!p_vlc_player)
        return;

    aspect_ratio = aspect;

    switch (aspect_ratio) {
    case Phonon::VideoWidget::AspectRatioAuto: // Let the decoder find the aspect ratio automatically from the media file (this is the default)
//        p_libvlc_video_set_aspect_ratio(p_vlc_current_media_player, "", vlc_exception);
        break;
    case Phonon::VideoWidget::AspectRatioWidget: // Fit the video into the widget making the aspect ratio depend solely on the size of the widget
        // This way the aspect ratio is freely resizeable by the user
//        p_libvlc_video_set_aspect_ratio(p_vlc_current_media_player, "", vlc_exception);
        break;
    case Phonon::VideoWidget::AspectRatio4_3:
//        p_libvlc_video_set_aspect_ratio(p_vlc_current_media_player, "4:3", vlc_exception);
        break;
    case Phonon::VideoWidget::AspectRatio16_9:
//        p_libvlc_video_set_aspect_ratio(p_vlc_current_media_player, "16:9", vlc_exception);
        break;
    default:
        qCritical() << __FUNCTION__ << "error: unsupported AspectRatio:" << (int) aspect_ratio;
    }
}

/**
 * \return The scale mode previously set for the video widget
 */
Phonon::VideoWidget::ScaleMode VideoWidget::scaleMode() const
{
    return scale_mode;
}

/**
 * Set how the video is scaled, keeping the aspect ratio into account when the video is resized.
 *
 * The ScaleMode enumeration describes how to treat aspect ratio during resizing of video.
 * \li Phonon::VideoWidget::FitInView - the video will be fitted to fill the view keeping aspect ratio
 * \li Phonon::VideoWidget::ScaleAndCrop - the video is scaled
 */
void VideoWidget::setScaleMode(Phonon::VideoWidget::ScaleMode scale)
{
    scale_mode = scale;
    switch (scale_mode) {
    case Phonon::VideoWidget::FitInView: // The video will be fitted to fill the view keeping aspect ratio
        break;
    case Phonon::VideoWidget::ScaleAndCrop: // The video is scaled
        break;
    default:
        qWarning() << __FUNCTION__ << "unknow Phonon::VideoWidget::ScaleMode:" << scale_mode;
    }
}

/**
 * \return The brightness previously set for the video widget
 */
qreal VideoWidget::brightness() const
{
    return f_brightness;
}

/**
 * Set the brightness of the video
 */
void VideoWidget::setBrightness(qreal brightness)
{
    f_brightness = brightness;

    // vlc takes brightness in range 0.0 - 2.0
    if (p_vlc_player) {
        if (!b_filter_adjust_activated) {
//            p_libvlc_video_filter_add(p_vlc_current_media_player, ADJUST, vlc_exception);
//            vlcExceptionRaised();
            b_filter_adjust_activated = true;
        }
//        p_libvlc_video_set_brightness(p_vlc_current_media_player, f_brightness + 1.0, vlc_exception);
//        vlcExceptionRaised();
    }
}

/**
 * \return The contrast previously set for the video widget
 */
qreal VideoWidget::contrast() const
{
    return f_contrast;
}

/**
 * Set the contrast of the video
 */
void VideoWidget::setContrast(qreal contrast)
{
    f_contrast = contrast;

    // vlc takes contrast in range 0.0 - 2.0
    float f_contrast = contrast;
    if (p_vlc_player) {
        if (!b_filter_adjust_activated) {
//            p_libvlc_video_filter_add(p_vlc_current_media_player, ADJUST, vlc_exception);
//            vlcExceptionRaised();
            b_filter_adjust_activated = true;
        }
//        p_libvlc_video_set_contrast(p_vlc_current_media_player, f_contrast + 1.0, vlc_exception);
//        vlcExceptionRaised();
    }
}

/**
 * \return The hue previously set for the video widget
 */
qreal VideoWidget::hue() const
{
    return f_hue;
}

/**
 * Set the hue of the video
 */
void VideoWidget::setHue(qreal hue)
{
    f_hue = hue;

    // vlc takes hue in range 0 - 360 in integer
    int i_hue = (f_hue + 1.0) * 180;
    if (p_vlc_player) {
        if (!b_filter_adjust_activated) {
//            p_libvlc_video_filter_add(p_vlc_current_media_player, ADJUST, vlc_exception);
//            vlcExceptionRaised();
            b_filter_adjust_activated = true;
        }
//        p_libvlc_video_set_hue(p_vlc_current_media_player, i_hue, vlc_exception);
//        vlcExceptionRaised();
    }

}

/**
 * \return The saturation previously set for the video widget
 */
qreal VideoWidget::saturation() const
{
    return f_saturation;
}

/**
 * Set the saturation of the video
 */
void VideoWidget::setSaturation(qreal saturation)
{
    f_saturation = saturation;

    // vlc takes brightness in range 0.0 - 3.0
    if (p_vlc_player) {
        if (!b_filter_adjust_activated) {
//            p_libvlc_video_filter_add(p_vlc_current_media_player, ADJUST, vlc_exception);
//            vlcExceptionRaised();
            b_filter_adjust_activated = true;
        }
//        p_libvlc_video_set_saturation(p_vlc_current_media_player, (f_saturation + 1.0) * 1.5, vlc_exception);
//        vlcExceptionRaised();
    }
}

/**
 * \return The owned widget that is used for the actual draw.
 */
Widget * VideoWidget::widget()
{
    return p_video_widget;
}

/**
 * Handles the change in the size of the video
 */
void VideoWidget::videoWidgetSizeChanged(int i_width, int i_height)
{
    qDebug() << __FUNCTION__ << "video width" << i_width << "height:" << i_height;

    // It resizes dynamically the widget and the main window
    // Note: I didn't find another way

    QSize videoSize(i_width, i_height);
    videoSize.boundedTo(QApplication::desktop()->availableGeometry().size());

    p_video_widget->hide();
    p_video_widget->setVideoSize(videoSize);
#ifdef Q_OS_WIN
    QWidget *p_parent = qobject_cast<QWidget *>(this->parent());
    QSize previousSize = p_parent->minimumSize();
    p_parent->setMinimumSize(videoSize);
#endif
    p_video_widget->show();
#ifdef Q_OS_WIN
    p_parent->setMinimumSize(previousSize);
#endif
}

}
} // Namespace Phonon::VLC
<|endoftext|>


<commit_before><commit_msg>mac: build fix.<commit_after><|endoftext|>


<commit_before>/*
 * PosixProcess.cpp
 *
 * Copyright (C) 2009-11 by RStudio, Inc.
 *
 * This program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include <core/system/Process.hpp>

// TODO: rename to AsyncChildProcess?

// TODO: consider whether onError should default to log and terminate

// TODO: wrapper for synchronous invocation

// TODO: address semantics of SIGCHLD:
//
//  - We've been calling reapChildren in SessionMain.cpp. this prevents
//    us from getting exit codes in the ChildProcessSupervisor! it appears
//    as if the semantics of system is to block SIGCHLD during execution
//    so we get away with it, however some other cases we might not be
//    (see pg. 345 of Advanced Unix Programming for more on this)
//
//  - Are the popen issues we've seen on the mac a result of the fact
//    that popen is not ignoring SIGCHLD on the mac? -- experiment
//
//  - Are the sweave/texi2dvi exit code issues we saw actually still
//    present if we do away with reapChildren? (we moved away from
//    ignoreChildExits to reapChildren however it may have been enough
//    to simply get rid of ignoreChildExits
//
//  - On the Mac R_system (in sysutils.c) uses a special cocoa run process
//    impl if useAqua is defined. Could it be that this implementation does
//    not block child signals which is why we couldn't get texi2dvi
//    exit codes?
//
//  - In server we need to reapChildren since we have session processes
//    which are exiting at random times (however we did have problems
//    with exit codes for PAM helper!). this simply may not be necessary
//    in session
//
//  - Furthermore, we may want to go with a more explicit method of
//    reaping the rsession processes so that we don't interfere with
//    the exit code handing for other scenarios.
//
// TODO: once we resolve the signal delivery issues could this
//       actually run on a background thread?

// PStreams 0.7.0
//
// The implementation of PosixChildProcess uses an embedded copy of the
// PStreams posix process control library. Links to the PStreams docs:
//
// http://pstreams.sourceforge.net/
// http://pstreams.sourceforge.net/doc/
// http://pstreams.sourceforge.net/faq.html
//
#include "pstreams-0.7.0/pstream.h"

#include <iostream>

#include <core/Error.hpp>
#include <core/Log.hpp>

#include "ChildProcess.hpp"

namespace core {
namespace system {

namespace {

void reportError(const Error& error)
{
   LOG_ERROR(error);
}

void reportIOError(const char* what, const ErrorLocation& location)
{
   Error error = systemError(boost::system::errc::io_error, location);
   if (what != NULL)
      error.addProperty("what", what);
   reportError(error);
}

void reportIOError(const ErrorLocation& location)
{
   reportIOError(NULL, location);
}

void readFromStream(redi::basic_pstream<char>& stream, std::string* pOutput)
{
   char ch;
   while (stream.readsome(&ch, 1) > 0)
      pOutput->append(1, ch);
}

Error checkStreamState(redi::basic_pstream<char>& stream,
                       bool *pFinished,
                       bool otherFinished)
{
   // defualt to no error
   Error error;

   // check for eof or error
   if (stream.eof())
   {
      *pFinished = true;
   }
   else if (stream.fail())
   {
      error = systemError(boost::system::errc::io_error, ERROR_LOCATION);
   }

   // clear any error bit if stderr is still pending
   if (!stream.good() && !otherFinished)
      stream.clear();

   // return error status
   return error;
}

} // anonymous namespace

struct ChildProcess::Impl
{
   Impl()
      : calledOnStarted_(false),
        finishedStdout_(false),
        finishedStderr_(false),
        exited_(false)
   {
   }

   redi::basic_pstreambuf<char>& rdbuf() { return *pstream_.rdbuf(); }

   redi::basic_pstream<char> pstream_;
   bool calledOnStarted_;
   bool finishedStdout_;
   bool finishedStderr_;
   bool exited_;
};

ChildProcess::ChildProcess(const std::string& cmd,
                           const std::vector<std::string>& args)
  : cmd_(cmd), args_(args), pImpl_(new Impl())
{
}

ChildProcess::~ChildProcess()
{
}

Error ChildProcess::run(const ProcessCallbacks& callbacks)
{
   // create set of args to pass (needs to include the cmd)
   std::vector<std::string> args;
   args.push_back(cmd_);
   args.insert(args.end(), args_.begin(), args_.end());

   // open the process
   pImpl_->pstream_.open(cmd_, args, redi::pstreambuf::pstdin |
                                     redi::pstreambuf::pstdout |
                                     redi::pstreambuf::pstderr);

   // return success if we are running
   if (pImpl_->pstream_.is_open())
   {
      callbacks_ = callbacks;
      return Success();
   }
   else
   {
      return systemError(pImpl_->rdbuf().error(), ERROR_LOCATION);
   }
}

Error ChildProcess::writeToStdin(const std::string& input, bool eof)
{
   try
   {
      // write and check for error
      pImpl_->pstream_ << input;
      if (pImpl_->pstream_.fail())
         return systemError(boost::system::errc::io_error, ERROR_LOCATION);

      // write eof if requested
      if (eof)
      {
         pImpl_->rdbuf().peof();

         if (pImpl_->pstream_.fail())
            return systemError(boost::system::errc::io_error, ERROR_LOCATION);
      }

      return Success();
   }
   catch(const std::ios_base::failure& e)
   {
      // we don't expect this to ever happen (since we haven't set the
      // exception flag on our io objects)
      Error error = systemError(boost::system::errc::io_error,
                                ERROR_LOCATION);
      error.addProperty("what", e.what());
      return error;
   }
}

void ChildProcess::poll()
{
   // check for output
   try
   {
      // call onStarted if we haven't yet
      if (!(pImpl_->calledOnStarted_))
      {
         if (callbacks_.onStarted)
            callbacks_.onStarted(*this);
         pImpl_->calledOnStarted_ = true;
      }

      // check stdout and fire event if we got output
      if (!pImpl_->finishedStdout_)
      {
         std::string out;
         readFromStream(pImpl_->pstream_.out(), &out);
         if (!out.empty() && callbacks_.onStdout)
            callbacks_.onStdout(*this, out);

         // check stream state
         Error error = checkStreamState(pImpl_->pstream_,
                                        &(pImpl_->finishedStdout_),
                                        pImpl_->finishedStderr_);
         if (error)
            reportError(error);
      }

      // check stderr and fire event if we got output
      if (!pImpl_->finishedStderr_)
      {
         std::string err;
         readFromStream(pImpl_->pstream_.err(), &err);
         if (!err.empty() && callbacks_.onStderr)
            callbacks_.onStderr(*this, err);

         // check stream state
         Error error = checkStreamState(pImpl_->pstream_,
                                        &(pImpl_->finishedStderr_),
                                        pImpl_->finishedStdout_);
         if (error)
            reportError(error);
      }

      // if both streams are finished then check for exited
      if (pImpl_->finishedStdout_ && pImpl_->finishedStderr_)
      {
         // Attempt to reap child. Note that this method specifies WNOHANG
         // so we don't block forever waiting for a process the exit. We may
         // not be able to reap the child due to EINTR, in that case we'll
         // just call exited again at the next polling interval. We may not
         // be able to reap the child due to ECHILD (reaped by a global
         // handler) in which case we'll allow the exit sequence to proceed
         // and simply pass -1 as the exit status. If we fail to reap the
         // the child for any other reason (there aren't actually any other
         // failure codes defined for waitpid) then we'll simply continue
         // calling exited in every polling interval (and this leak this
         // object). Note that we don't anticipate this ever occuring based
         // on our understanding of waitpid, PStreams, etc.
         if (pImpl_->rdbuf().exited() || (pImpl_->rdbuf().error() == ECHILD))
         {
            // close the stream (this won't block because we have
            // already established that the child is not running)
            pImpl_->pstream_.close();

            // fire exit event
            if (callbacks_.onExit)
            {
               // recover exit code
               int status = pImpl_->rdbuf().status();
               if (WIFEXITED(status))
                  status = WEXITSTATUS(status);

               // call onExit
               callbacks_.onExit(status);
            }

            // set exited_ flag so that our exited function always
            // returns the right value (even if we haven't been able
            // to successfully wait/reap the child)
            pImpl_->exited_ = true;
         }
      }
   }
   catch(const std::ios_base::failure& e)
   {
      // we don't expect this to ever happen (since we haven't set the
      // exception flag on our io objects)
      reportIOError(e.what(), ERROR_LOCATION);
   }
}

bool ChildProcess::exited()
{
   return pImpl_->exited_;
}

Error ChildProcess::terminate()
{
   // only send signal if the process is open
   if (!pImpl_->pstream_.is_open())
      return systemError(ESRCH, ERROR_LOCATION);

   // send signal
   if (pImpl_->rdbuf().kill(SIGTERM) != NULL)
      return Success();
   else
      return systemError(pImpl_->rdbuf().error(), ERROR_LOCATION);
}

} // namespace system
} // namespace core

<commit_msg>update process todo comments<commit_after>/*
 * PosixProcess.cpp
 *
 * Copyright (C) 2009-11 by RStudio, Inc.
 *
 * This program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include <core/system/Process.hpp>

// TODO: rename to AsyncChildProcess and AsyncProcessSupervisor?

// TODO: add docs on potential exitStatus values

// TODO: consider onRunning callback (for timeouts)

// TODO: consider whether onError should default to log and terminate

// TODO: wrapper for synchronous invocation

// TODO: address semantics of SIGCHLD:
//
//  - We've been calling reapChildren in SessionMain.cpp. this prevents
//    us from getting exit codes in the ChildProcessSupervisor! it appears
//    as if the semantics of system is to block SIGCHLD during execution
//    so we get away with it, however some other cases we might not be
//    (see pg. 345 of Advanced Unix Programming for more on this)
//
//  - Are the popen issues we've seen on the mac a result of the fact
//    that popen is not ignoring SIGCHLD on the mac? -- experiment
//
//  - Are the sweave/texi2dvi exit code issues we saw actually still
//    present if we do away with reapChildren? (we moved away from
//    ignoreChildExits to reapChildren however it may have been enough
//    to simply get rid of ignoreChildExits
//
//  - On the Mac R_system (in sysutils.c) uses a special cocoa run process
//    impl if useAqua is defined. Could it be that this implementation does
//    not block child signals which is why we couldn't get texi2dvi
//    exit codes?
//
//  - In server we need to reapChildren since we have session processes
//    which are exiting at random times (however we did have problems
//    with exit codes for PAM helper!). this simply may not be necessary
//    in session
//
//  - Furthermore, we may want to go with a more explicit method of
//    reaping the rsession processes so that we don't interfere with
//    the exit code handing for other scenarios.
//
// TODO: once we resolve the signal delivery issues could this
//       actually run on a background thread?

// PStreams 0.7.0
//
// The implementation of PosixChildProcess uses an embedded copy of the
// PStreams posix process control library. Links to the PStreams docs:
//
// http://pstreams.sourceforge.net/
// http://pstreams.sourceforge.net/doc/
// http://pstreams.sourceforge.net/faq.html
//
#include "pstreams-0.7.0/pstream.h"

#include <iostream>

#include <core/Error.hpp>
#include <core/Log.hpp>

#include "ChildProcess.hpp"

namespace core {
namespace system {

namespace {

void reportError(const Error& error)
{
   LOG_ERROR(error);
}

void reportIOError(const char* what, const ErrorLocation& location)
{
   Error error = systemError(boost::system::errc::io_error, location);
   if (what != NULL)
      error.addProperty("what", what);
   reportError(error);
}

void reportIOError(const ErrorLocation& location)
{
   reportIOError(NULL, location);
}

void readFromStream(redi::basic_pstream<char>& stream, std::string* pOutput)
{
   char ch;
   while (stream.readsome(&ch, 1) > 0)
      pOutput->append(1, ch);
}

Error checkStreamState(redi::basic_pstream<char>& stream,
                       bool *pFinished,
                       bool otherFinished)
{
   // defualt to no error
   Error error;

   // check for eof or error
   if (stream.eof())
   {
      *pFinished = true;
   }
   else if (stream.fail())
   {
      error = systemError(boost::system::errc::io_error, ERROR_LOCATION);
   }

   // clear any error bit if stderr is still pending
   if (!stream.good() && !otherFinished)
      stream.clear();

   // return error status
   return error;
}

} // anonymous namespace

struct ChildProcess::Impl
{
   Impl()
      : calledOnStarted_(false),
        finishedStdout_(false),
        finishedStderr_(false),
        exited_(false)
   {
   }

   redi::basic_pstreambuf<char>& rdbuf() { return *pstream_.rdbuf(); }

   redi::basic_pstream<char> pstream_;
   bool calledOnStarted_;
   bool finishedStdout_;
   bool finishedStderr_;
   bool exited_;
};

ChildProcess::ChildProcess(const std::string& cmd,
                           const std::vector<std::string>& args)
  : cmd_(cmd), args_(args), pImpl_(new Impl())
{
}

ChildProcess::~ChildProcess()
{
}

Error ChildProcess::run(const ProcessCallbacks& callbacks)
{
   // create set of args to pass (needs to include the cmd)
   std::vector<std::string> args;
   args.push_back(cmd_);
   args.insert(args.end(), args_.begin(), args_.end());

   // open the process
   pImpl_->pstream_.open(cmd_, args, redi::pstreambuf::pstdin |
                                     redi::pstreambuf::pstdout |
                                     redi::pstreambuf::pstderr);

   // return success if we are running
   if (pImpl_->pstream_.is_open())
   {
      callbacks_ = callbacks;
      return Success();
   }
   else
   {
      return systemError(pImpl_->rdbuf().error(), ERROR_LOCATION);
   }
}

Error ChildProcess::writeToStdin(const std::string& input, bool eof)
{
   try
   {
      // write and check for error
      pImpl_->pstream_ << input;
      if (pImpl_->pstream_.fail())
         return systemError(boost::system::errc::io_error, ERROR_LOCATION);

      // write eof if requested
      if (eof)
      {
         pImpl_->rdbuf().peof();

         if (pImpl_->pstream_.fail())
            return systemError(boost::system::errc::io_error, ERROR_LOCATION);
      }

      return Success();
   }
   catch(const std::ios_base::failure& e)
   {
      // we don't expect this to ever happen (since we haven't set the
      // exception flag on our io objects)
      Error error = systemError(boost::system::errc::io_error,
                                ERROR_LOCATION);
      error.addProperty("what", e.what());
      return error;
   }
}

void ChildProcess::poll()
{
   // check for output
   try
   {
      // call onStarted if we haven't yet
      if (!(pImpl_->calledOnStarted_))
      {
         if (callbacks_.onStarted)
            callbacks_.onStarted(*this);
         pImpl_->calledOnStarted_ = true;
      }

      // check stdout and fire event if we got output
      if (!pImpl_->finishedStdout_)
      {
         std::string out;
         readFromStream(pImpl_->pstream_.out(), &out);
         if (!out.empty() && callbacks_.onStdout)
            callbacks_.onStdout(*this, out);

         // check stream state
         Error error = checkStreamState(pImpl_->pstream_,
                                        &(pImpl_->finishedStdout_),
                                        pImpl_->finishedStderr_);
         if (error)
            reportError(error);
      }

      // check stderr and fire event if we got output
      if (!pImpl_->finishedStderr_)
      {
         std::string err;
         readFromStream(pImpl_->pstream_.err(), &err);
         if (!err.empty() && callbacks_.onStderr)
            callbacks_.onStderr(*this, err);

         // check stream state
         Error error = checkStreamState(pImpl_->pstream_,
                                        &(pImpl_->finishedStderr_),
                                        pImpl_->finishedStdout_);
         if (error)
            reportError(error);
      }

      // if both streams are finished then check for exited
      if (pImpl_->finishedStdout_ && pImpl_->finishedStderr_)
      {
         // Attempt to reap child. Note that this method specifies WNOHANG
         // so we don't block forever waiting for a process the exit. We may
         // not be able to reap the child due to EINTR, in that case we'll
         // just call exited again at the next polling interval. We may not
         // be able to reap the child due to ECHILD (reaped by a global
         // handler) in which case we'll allow the exit sequence to proceed
         // and simply pass -1 as the exit status. If we fail to reap the
         // the child for any other reason (there aren't actually any other
         // failure codes defined for waitpid) then we'll simply continue
         // calling exited in every polling interval (and this leak this
         // object). Note that we don't anticipate this ever occuring based
         // on our understanding of waitpid, PStreams, etc.
         if (pImpl_->rdbuf().exited() || (pImpl_->rdbuf().error() == ECHILD))
         {
            // close the stream (this won't block because we have
            // already established that the child is not running)
            pImpl_->pstream_.close();

            // fire exit event
            if (callbacks_.onExit)
            {
               // recover exit code
               int status = pImpl_->rdbuf().status();
               if (WIFEXITED(status))
                  status = WEXITSTATUS(status);

               // call onExit
               callbacks_.onExit(status);
            }

            // set exited_ flag so that our exited function always
            // returns the right value (even if we haven't been able
            // to successfully wait/reap the child)
            pImpl_->exited_ = true;
         }
      }
   }
   catch(const std::ios_base::failure& e)
   {
      // we don't expect this to ever happen (since we haven't set the
      // exception flag on our io objects)
      reportIOError(e.what(), ERROR_LOCATION);
   }
}

bool ChildProcess::exited()
{
   return pImpl_->exited_;
}

Error ChildProcess::terminate()
{
   // only send signal if the process is open
   if (!pImpl_->pstream_.is_open())
      return systemError(ESRCH, ERROR_LOCATION);

   // send signal
   if (pImpl_->rdbuf().kill(SIGTERM) != NULL)
      return Success();
   else
      return systemError(pImpl_->rdbuf().error(), ERROR_LOCATION);
}

} // namespace system
} // namespace core

<|endoftext|>


<commit_before>#include "builtin/string.hpp"

#include "capi/capi.hpp"
#include "capi/ruby.h"

using namespace rubinius;
using namespace rubinius::capi;

extern "C" {
  int rb_integer_pack(VALUE value, void *words, size_t numwords, size_t wordsize,
                      size_t nails, int flags)
  {
    if(nails != 0) {
      rb_raise(rb_eNotImpError, "non-zero bit padding is unsupported");
    }

    if(((flags & INTEGER_PACK_MSWORD_FIRST) != 0 &&
        (flags & INTEGER_PACK_LSBYTE_FIRST) != 0) ||
       ((flags & INTEGER_PACK_LSWORD_FIRST) != 0 &&
        (flags & INTEGER_PACK_MSBYTE_FIRST) != 0)) {
      rb_raise(rb_eNotImpError, "mixed byte and word ordering is unsupported");
    }

    value = rb_to_int(value);

    int numbytes = numwords * wordsize;
    memset(words, 0, numbytes);

    NativeMethodEnvironment* env = NativeMethodEnvironment::get();

    if(Fixnum* f = try_as<Fixnum>(env->get_object(value))) {
      native_int v = f->to_native();

      if(v == 0) return 0;

      if((numbytes >= FIXNUM_WIDTH / 8) &&
          ((flags & INTEGER_PACK_NATIVE_BYTE_ORDER) ||
#ifdef RBX_LITTLE_ENDIAN
          ((flags & INTEGER_PACK_LSWORD_FIRST) &&
          (flags & INTEGER_PACK_LSBYTE_FIRST))
#else
          ((flags & INTEGER_PACK_MSWORD_FIRST) &&
          (flags & INTEGER_PACK_MSBYTE_FIRST))
#endif
          ))
      {
        memcpy(words, &v, numbytes);
        return v < 0 ? -1 : 1;
      }
    }

    String* bytes = String::create(env->state(), Fixnum::from(numbytes));
    memset(bytes->byte_address(), 0, numbytes);

    VALUE result = rb_funcall(rb_mCAPI, rb_intern("rb_integer_pack"), 6,
        value, env->get_handle(bytes), INT2FIX(numwords), INT2FIX(wordsize),
        INT2FIX(nails), INT2FIX(flags));

    memcpy(words, bytes->byte_address(), numbytes);

    return FIX2INT(result);
  }
}
<commit_msg>Use size_t instead of int.<commit_after>#include "builtin/string.hpp"

#include "capi/capi.hpp"
#include "capi/ruby.h"

using namespace rubinius;
using namespace rubinius::capi;

extern "C" {
  int rb_integer_pack(VALUE value, void *words, size_t numwords, size_t wordsize,
                      size_t nails, int flags)
  {
    if(nails != 0) {
      rb_raise(rb_eNotImpError, "non-zero bit padding is unsupported");
    }

    if(((flags & INTEGER_PACK_MSWORD_FIRST) != 0 &&
        (flags & INTEGER_PACK_LSBYTE_FIRST) != 0) ||
       ((flags & INTEGER_PACK_LSWORD_FIRST) != 0 &&
        (flags & INTEGER_PACK_MSBYTE_FIRST) != 0)) {
      rb_raise(rb_eNotImpError, "mixed byte and word ordering is unsupported");
    }

    value = rb_to_int(value);

    size_t numbytes = numwords * wordsize;
    memset(words, 0, numbytes);

    NativeMethodEnvironment* env = NativeMethodEnvironment::get();

    if(Fixnum* f = try_as<Fixnum>(env->get_object(value))) {
      native_int v = f->to_native();

      if(v == 0) return 0;

      if((numbytes >= FIXNUM_WIDTH / 8) &&
          ((flags & INTEGER_PACK_NATIVE_BYTE_ORDER) ||
#ifdef RBX_LITTLE_ENDIAN
          ((flags & INTEGER_PACK_LSWORD_FIRST) &&
          (flags & INTEGER_PACK_LSBYTE_FIRST))
#else
          ((flags & INTEGER_PACK_MSWORD_FIRST) &&
          (flags & INTEGER_PACK_MSBYTE_FIRST))
#endif
          ))
      {
        memcpy(words, &v, numbytes);
        return v < 0 ? -1 : 1;
      }
    }

    String* bytes = String::create(env->state(), Fixnum::from(numbytes));
    memset(bytes->byte_address(), 0, numbytes);

    VALUE result = rb_funcall(rb_mCAPI, rb_intern("rb_integer_pack"), 6,
        value, env->get_handle(bytes), INT2FIX(numwords), INT2FIX(wordsize),
        INT2FIX(nails), INT2FIX(flags));

    memcpy(words, bytes->byte_address(), numbytes);

    return FIX2INT(result);
  }
}
<|endoftext|>


<commit_before>#include <string>
#include <deque>
#include <ctime>
#include <sstream>

#include "../../src/plugin_api.h"

#include "command.h"

#define PLUGIN_COMMAND_VERSION 1.1
const char CHATCMDPREFIX   = '/';
mineserver_pointer_struct* mineserver;

std::string dtos( double n )
{
  std::ostringstream result;
  result << n;
  return result.str();
}

std::deque<std::string> parseCmd(std::string cmd)
{
  int del;
  std::deque<std::string> temp;

  while(cmd.length() > 0)
  {
    while(cmd[0] == ' ')
    {
      cmd = cmd.substr(1);
    }

    del = cmd.find(' ');

    if(del > -1)
    {
      temp.push_back(cmd.substr(0, del));
      cmd = cmd.substr(del+1);
    }
    else
    {
      temp.push_back(cmd);
      break;
    }
  }

  if(temp.empty())
  {
    temp.push_back("empty");
  }
  return temp;
}

typedef void (*CommandCallback)(std::string nick, std::string, std::deque<std::string>);

struct Command
{
  std::deque<std::string> names;
  std::string arguments;
  std::string description;
  CommandCallback callback;
  Command(std::deque<std::string> _names, std::string _arguments, std::string _description, CommandCallback _callback)
    : names(_names),arguments(_arguments),description(_description),callback(_callback) {}
};

typedef std::map<std::string, Command*> CommandList;
CommandList m_Commands;

void registerCommand(Command* command)
{
  // Loop thru all the words for this command
  std::string currentWord;
  std::deque<std::string> words = command->names;
  while(!words.empty())
  {
    currentWord = words[0];
    words.pop_front();
    m_Commands[currentWord] = command;
  }
}

bool chatPreFunction(std::string user, std::string msg)
{
  if(msg.size() == 0)
  {
    return false;
  }

  char prefix = msg[0];

  mineserver->screen.log("Command Plugin got from "+user+": " + msg);

  if(prefix == CHATCMDPREFIX)
  {
    // Timestamp
    time_t rawTime = time(NULL);
    struct tm* Tm  = localtime(&rawTime);
    std::string timeStamp (asctime(Tm));
    timeStamp = timeStamp.substr(11, 5);

    std::deque<std::string> cmd = parseCmd(msg.substr(1));

    std::string command = cmd[0];
    cmd.pop_front();

    // User commands
    CommandList::iterator iter;
    if((iter = m_Commands.find(command)) != m_Commands.end())
    {
      iter->second->callback(user, command, cmd);
      return true;
    }
  }

  return false;
}

bool isValidItem(int id)
{
  if(id < 1)  // zero or negative items are all invalid
  {
    return false;
  }

  if(id > 91 && id < 256)  // these are undefined blocks and items
  {
    return false;
  }

  if(id == 2256 || id == 2257)  // records are special cased
  {
    return true;
  }

  if(id > 350)  // high items are invalid
  {
    return false;
  }

  return true;
}

int roundUpTo(int x, int nearest)
{
  return (((x + (nearest - 1)) / nearest) * nearest );
}

void giveItemsSelf(std::string user, std::string command, std::deque<std::string> args)
{
  if(args.size() == 1 || args.size() == 2)
  {
    int itemId = 0;

    //First check if item is a number
    itemId = atoi(args[0].c_str());

    // Check item validity
    if(isValidItem(itemId))
    {
      position_struct *player_pos = mineserver->user.getPosition(user);

      if(player_pos != NULL)
      {
        int itemCount = 1, itemStacks = 1;

        if(args.size() == 2)
        {
          itemCount = atoi(args[1].c_str());
          if(itemCount>1024) itemCount=1024;
          // If multiple stacks
          itemStacks = roundUpTo(itemCount, 64) / 64;
          itemCount  -= (itemStacks-1) * 64;
        }

        int amount = 64;
        for(int i = 0; i < itemStacks; i++)
        {
          // if last stack
          if(i == itemStacks - 1)
          {
            amount = itemCount;
          }

          mineserver->map.createPickupSpawn(player_pos->x,player_pos->y,player_pos->z,itemId,amount,0,user);
        }
      }
    }
    else
    {
      mineserver->chat.sendmsgTo(user, "Not a valid item");
    }
  }
  else
  {
    mineserver->chat.sendmsgTo(user, "Usage: /igive item [count]");
  }
}

void home(std::string user, std::string command, std::deque<std::string> args)
{
  mineserver->chat.sendmsgTo(user, "Teleported you home!");
  int x,y,z;
  mineserver->map.getSpawn(&x,&y,&z);
  mineserver->user.teleport(user,x, y + 2, z);
}

void setTime(std::string user, std::string command, std::deque<std::string> args)
{
  if(args.size() == 1)
  {
    std::string timeValue = args[0];

    // Check for time labels
    if(timeValue == "day" || timeValue == "morning")
    {
      timeValue = "24000";
    }
    else if (timeValue == "dawn")
    {
      timeValue = "22500";
    }
    else if (timeValue == "noon")
    {
      timeValue = "6000";
    }
    else if (timeValue == "dusk")
    {
      timeValue = "12000";
    }
    else if (timeValue == "night" || timeValue == "midnight")
    {
      timeValue = "18000";
    }

    mineserver->map.setTime(timeValue);

    mineserver->chat.sendmsgTo(user, "World time changed.");
  }
  else
  {
    mineserver->chat.sendmsgTo(user, "Usage: /settime time (time = 0-24000)");
  }
}

PLUGIN_API_EXPORT void command_init(mineserver_pointer_struct* mineserver_temp)
{
  mineserver = mineserver_temp;
  if (mineserver->plugin.getPluginVersion("command") > 0)
  {
    mineserver->screen.log("command is already loaded v." +dtos(mineserver->plugin.getPluginVersion("command")));
    return;
  }
  mineserver->screen.log("Loaded \"command\"!");

  mineserver->plugin.setPluginVersion("command", PLUGIN_COMMAND_VERSION);

  mineserver->callback.add_hook("ChatPre", (void *)chatPreFunction);

  registerCommand(new Command(parseCmd("igive i"), "<id/alias> [count]", "Gives self [count] pieces of <id/alias>. By default [count] = 1", giveItemsSelf));
  registerCommand(new Command(parseCmd("home"), "", "Teleport to map spawn location", home));
  registerCommand(new Command(parseCmd("settime"), "<time>", "Sets server time. (<time> = 0-24000, 0 & 24000 = day, ~15000 = night)", setTime));
}

PLUGIN_API_EXPORT void command_shutdown(void)
{
  if (mineserver->plugin.getPluginVersion("command") <= 0)
  {
    mineserver->screen.log("command is not loaded!");
    return;
  }

}

<commit_msg>plugintest/command.cpp fix<commit_after>/*
g++ -c command.cpp
g++ -shared command.o -o command.so

copy command.so to Mineserver bin directory.

*/

#include <string>
#include <deque>
#include <ctime>
#include <sstream>
#include <cstdlib>

#include "../../src/plugin_api.h"

#include "command.h"

#define PLUGIN_COMMAND_VERSION 1.1
const char CHATCMDPREFIX   = '/';
mineserver_pointer_struct* mineserver;

std::string dtos( double n )
{
  std::ostringstream result;
  result << n;
  return result.str();
}

std::deque<std::string> parseCmd(std::string cmd)
{
  int del;
  std::deque<std::string> temp;

  while(cmd.length() > 0)
  {
    while(cmd[0] == ' ')
    {
      cmd = cmd.substr(1);
    }

    del = cmd.find(' ');

    if(del > -1)
    {
      temp.push_back(cmd.substr(0, del));
      cmd = cmd.substr(del+1);
    }
    else
    {
      temp.push_back(cmd);
      break;
    }
  }

  if(temp.empty())
  {
    temp.push_back("empty");
  }
  return temp;
}

typedef void (*CommandCallback)(std::string nick, std::string, std::deque<std::string>);

struct Command
{
  std::deque<std::string> names;
  std::string arguments;
  std::string description;
  CommandCallback callback;
  Command(std::deque<std::string> _names, std::string _arguments, std::string _description, CommandCallback _callback)
    : names(_names),arguments(_arguments),description(_description),callback(_callback) {}
};

typedef std::map<std::string, Command*> CommandList;
CommandList m_Commands;

void registerCommand(Command* command)
{
  // Loop thru all the words for this command
  std::string currentWord;
  std::deque<std::string> words = command->names;
  while(!words.empty())
  {
    currentWord = words[0];
    words.pop_front();
    m_Commands[currentWord] = command;
  }
}

bool chatPreFunction(std::string user, std::string msg)
{
  if(msg.size() == 0)
  {
    return false;
  }

  char prefix = msg[0];

  mineserver->screen.log("Command Plugin got from "+user+": " + msg);

  if(prefix == CHATCMDPREFIX)
  {
    // Timestamp
    time_t rawTime = time(NULL);
    struct tm* Tm  = localtime(&rawTime);
    std::string timeStamp (asctime(Tm));
    timeStamp = timeStamp.substr(11, 5);

    std::deque<std::string> cmd = parseCmd(msg.substr(1));

    std::string command = cmd[0];
    cmd.pop_front();

    // User commands
    CommandList::iterator iter;
    if((iter = m_Commands.find(command)) != m_Commands.end())
    {
      iter->second->callback(user, command, cmd);
      return true;
    }
  }

  return false;
}

bool isValidItem(int id)
{
  if(id < 1)  // zero or negative items are all invalid
  {
    return false;
  }

  if(id > 91 && id < 256)  // these are undefined blocks and items
  {
    return false;
  }

  if(id == 2256 || id == 2257)  // records are special cased
  {
    return true;
  }

  if(id > 350)  // high items are invalid
  {
    return false;
  }

  return true;
}

int roundUpTo(int x, int nearest)
{
  return (((x + (nearest - 1)) / nearest) * nearest );
}

void giveItemsSelf(std::string user, std::string command, std::deque<std::string> args)
{
  if(args.size() == 1 || args.size() == 2)
  {
    int itemId = 0;

    //First check if item is a number
    itemId = atoi(args[0].c_str());

    // Check item validity
    if(isValidItem(itemId))
    {
      position_struct *player_pos = mineserver->user.getPosition(user);

      if(player_pos != NULL)
      {
        int itemCount = 1, itemStacks = 1;

        if(args.size() == 2)
        {
          itemCount = atoi(args[1].c_str());
          if(itemCount>1024) itemCount=1024;
          // If multiple stacks
          itemStacks = roundUpTo(itemCount, 64) / 64;
          itemCount  -= (itemStacks-1) * 64;
        }

        int amount = 64;
        for(int i = 0; i < itemStacks; i++)
        {
          // if last stack
          if(i == itemStacks - 1)
          {
            amount = itemCount;
          }

          mineserver->map.createPickupSpawn(player_pos->x,player_pos->y,player_pos->z,itemId,amount,0,user);
        }
      }
    }
    else
    {
      mineserver->chat.sendmsgTo(user, "Not a valid item");
    }
  }
  else
  {
    mineserver->chat.sendmsgTo(user, "Usage: /igive item [count]");
  }
}

void home(std::string user, std::string command, std::deque<std::string> args)
{
  mineserver->chat.sendmsgTo(user, "Teleported you home!");
  int x,y,z;
  mineserver->map.getSpawn(&x,&y,&z);
  mineserver->user.teleport(user,x, y + 2, z);
}

void setTime(std::string user, std::string command, std::deque<std::string> args)
{
  if(args.size() == 1)
  {
    std::string timeValue = args[0];

    // Check for time labels
    if(timeValue == "day" || timeValue == "morning")
    {
      timeValue = "24000";
    }
    else if (timeValue == "dawn")
    {
      timeValue = "22500";
    }
    else if (timeValue == "noon")
    {
      timeValue = "6000";
    }
    else if (timeValue == "dusk")
    {
      timeValue = "12000";
    }
    else if (timeValue == "night" || timeValue == "midnight")
    {
      timeValue = "18000";
    }

    mineserver->map.setTime(timeValue);

    mineserver->chat.sendmsgTo(user, "World time changed.");
  }
  else
  {
    mineserver->chat.sendmsgTo(user, "Usage: /settime time (time = 0-24000)");
  }
}

PLUGIN_API_EXPORT void command_init(mineserver_pointer_struct* mineserver_temp)
{
  mineserver = mineserver_temp;
  if (mineserver->plugin.getPluginVersion("command") > 0)
  {
    mineserver->screen.log("command is already loaded v." +dtos(mineserver->plugin.getPluginVersion("command")));
    return;
  }
  mineserver->screen.log("Loaded \"command\"!");

  mineserver->plugin.setPluginVersion("command", PLUGIN_COMMAND_VERSION);

  mineserver->callback.add_hook("ChatPre", (void *)chatPreFunction);

  registerCommand(new Command(parseCmd("igive i"), "<id/alias> [count]", "Gives self [count] pieces of <id/alias>. By default [count] = 1", giveItemsSelf));
  registerCommand(new Command(parseCmd("home"), "", "Teleport to map spawn location", home));
  registerCommand(new Command(parseCmd("settime"), "<time>", "Sets server time. (<time> = 0-24000, 0 & 24000 = day, ~15000 = night)", setTime));
}

PLUGIN_API_EXPORT void command_shutdown(void)
{
  if (mineserver->plugin.getPluginVersion("command") <= 0)
  {
    mineserver->screen.log("command is not loaded!");
    return;
  }

}

<|endoftext|>


<commit_before>/*
 * Main.cpp
 *
 * Copyright (C) 2009-12 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include <iostream>

#include <boost/test/minimal.hpp>

#include <core/Error.hpp>
#include <core/FilePath.hpp>
#include <core/Log.hpp>
#include <core/system/System.hpp>

#include <core/http/NamedPipeAsyncClient.hpp>
#include <core/http/NamedPipeBlockingClient.hpp>
#include <core/http/NamedPipeAsyncServer.hpp>

using namespace core ;

int test_main(int argc, char * argv[])
{
   try
   {
      // initialize log
      initializeSystemLog("coredev", core::system::kLogLevelWarning);

      // default connection retry profile
      http::ConnectionRetryProfile retryProfile(
                              boost::posix_time::seconds(10),
                              boost::posix_time::milliseconds(50));

      boost::asio::io_service ioService;
      http::NamedPipeAsyncClient client(ioService, "MyPipe", retryProfile);

      // client.request().assign(myRequest);

      // client.execute();

      http::Request request;
      http::Response response;
      Error error = http::sendRequest("MyPipe",
                                      request,
                                      retryProfile,
                                      &response);
      if (error)
         LOG_ERROR(error);

      http::NamedPipeAsyncServer asyncServer("RStudio");

      return EXIT_SUCCESS;
   }
   CATCH_UNEXPECTED_EXCEPTION

   // if we got this far we had an unexpected exception
   return EXIT_FAILURE ;
}

<commit_msg>add test code<commit_after>/*
 * Main.cpp
 *
 * Copyright (C) 2009-12 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include <iostream>

#include <boost/test/minimal.hpp>

#include <core/Error.hpp>
#include <core/FilePath.hpp>
#include <core/Log.hpp>
#include <core/Thread.hpp>
#include <core/system/System.hpp>

#include <core/http/Request.hpp>
#include <core/http/Response.hpp>

#include <core/http/NamedPipeAsyncClient.hpp>
#include <core/http/NamedPipeBlockingClient.hpp>
#include <core/http/NamedPipeAsyncServer.hpp>

using namespace core ;

const char * const kPipeName = "\\\\.\\pipe\\TestPipeName";

void handleRequest(const http::Request& request, http::Response* pResponse)
{
   std::cerr << request << std::endl;

   pResponse->setStatusCode(http::status::Ok);
   pResponse->setContentType("text/plain");
   pResponse->setBody("Hello client!");
}

int test_main(int argc, char * argv[])
{
   try
   {
      // setup log
      initializeSystemLog("coredev", core::system::kLogLevelWarning);

      // ignore sigpipe
      Error error = core::system::ignoreSignal(core::system::SigPipe);
      if (error)
         LOG_ERROR(error);

      // create server (runs on a background thread)
      http::NamedPipeAsyncServer asyncServer("RStudio");
      asyncServer.setBlockingDefaultHandler(handleRequest);
      error = asyncServer.init(kPipeName);
      if (error)
      {
         LOG_ERROR(error);
         return EXIT_FAILURE;
      }

      // run server
      error = asyncServer.run();
      if (error)
      {
         LOG_ERROR(error);
         return EXIT_FAILURE;
      }

      std::cerr << "trying request..." << std::endl;

      http::ConnectionRetryProfile retryProfile(
                              boost::posix_time::seconds(1),
                              boost::posix_time::milliseconds(50));

      http::Request request;
      request.setMethod("GET");
      request.setUri("/");
      request.setHeader("Accept", "*/*");
      request.setHeader("Connection", "close");

      http::Response response;
      error = http::sendRequest(kPipeName, request, retryProfile, &response);
      if (error)
         LOG_ERROR(error);

      std::cerr << response << std::endl;

      /*
      // create ioservice for client
      boost::asio::io_service ioService;

      boost::asio::io_service ioService;
      http::NamedPipeAsyncClient client(ioService, "MyPipe", retryProfile);
      client.request().assign(myRequest);
      client.execute();

      // run the io service
      boost::system::error_code ec;
      ioService.run(ec);
      if (ec)
      {
         LOG_ERROR(Error(ec, ERROR_LOCATION));
         return EXIT_FAILURE;
      }
      */

      // default connection retry profile
      /*
      http::ConnectionRetryProfile retryProfile(
                              boost::posix_time::seconds(10),
                              boost::posix_time::milliseconds(50));

      */

      return EXIT_SUCCESS;
   }
   CATCH_UNEXPECTED_EXCEPTION

   // if we got this far we had an unexpected exception
   return EXIT_FAILURE ;
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011-2012, 2016-2018, 2020 ARM Limited
 * Copyright (c) 2013 Advanced Micro Devices, Inc.
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __CPU_THREAD_CONTEXT_HH__
#define __CPU_THREAD_CONTEXT_HH__

#include <iostream>
#include <string>

#include "arch/generic/htm.hh"
#include "arch/generic/isa.hh"
#include "arch/pcstate.hh"
#include "arch/vecregs.hh"
#include "base/types.hh"
#include "config/the_isa.hh"
#include "cpu/pc_event.hh"
#include "cpu/reg_class.hh"

namespace gem5
{

// @todo: Figure out a more architecture independent way to obtain the ITB and
// DTB pointers.
namespace TheISA
{
    class Decoder;
}
class BaseCPU;
class BaseMMU;
class BaseTLB;
class CheckerCPU;
class Checkpoint;
class PortProxy;
class Process;
class System;
class Packet;
using PacketPtr = Packet *;

/**
 * ThreadContext is the external interface to all thread state for
 * anything outside of the CPU. It provides all accessor methods to
 * state that might be needed by external objects, ranging from
 * register values to things such as kernel stats. It is an abstract
 * base class; the CPU can create its own ThreadContext by
 * deriving from it.
 *
 * The ThreadContext is slightly different than the ExecContext.  The
 * ThreadContext provides access to an individual thread's state; an
 * ExecContext provides ISA access to the CPU (meaning it is
 * implicitly multithreaded on SMT systems).  Additionally the
 * ThreadState is an abstract class that exactly defines the
 * interface; the ExecContext is a more implicit interface that must
 * be implemented so that the ISA can access whatever state it needs.
 */
class ThreadContext : public PCEventScope
{
  protected:
    bool useForClone = false;

  public:

    bool getUseForClone() { return useForClone; }

    void setUseForClone(bool new_val) { useForClone = new_val; }

    enum Status
    {
        /// Running.  Instructions should be executed only when
        /// the context is in this state.
        Active,

        /// Temporarily inactive.  Entered while waiting for
        /// synchronization, etc.
        Suspended,

        /// Trying to exit and waiting for an event to completely exit.
        /// Entered when target executes an exit syscall.
        Halting,

        /// Permanently shut down.  Entered when target executes
        /// m5exit pseudo-instruction.  When all contexts enter
        /// this state, the simulation will terminate.
        Halted
    };

    virtual ~ThreadContext() { };

    virtual BaseCPU *getCpuPtr() = 0;

    virtual int cpuId() const = 0;

    virtual uint32_t socketId() const = 0;

    virtual int threadId() const = 0;

    virtual void setThreadId(int id) = 0;

    virtual ContextID contextId() const = 0;

    virtual void setContextId(ContextID id) = 0;

    virtual BaseMMU *getMMUPtr() = 0;

    virtual CheckerCPU *getCheckerCpuPtr() = 0;

    virtual BaseISA *getIsaPtr() = 0;

    virtual TheISA::Decoder *getDecoderPtr() = 0;

    virtual System *getSystemPtr() = 0;

    virtual void sendFunctional(PacketPtr pkt);

    virtual Process *getProcessPtr() = 0;

    virtual void setProcessPtr(Process *p) = 0;

    virtual Status status() const = 0;

    virtual void setStatus(Status new_status) = 0;

    /// Set the status to Active.
    virtual void activate() = 0;

    /// Set the status to Suspended.
    virtual void suspend() = 0;

    /// Set the status to Halted.
    virtual void halt() = 0;

    /// Quiesce thread context
    void quiesce();

    /// Quiesce, suspend, and schedule activate at resume
    void quiesceTick(Tick resume);

    virtual void takeOverFrom(ThreadContext *old_context) = 0;

    virtual void regStats(const std::string &name) {};

    virtual void scheduleInstCountEvent(Event *event, Tick count) = 0;
    virtual void descheduleInstCountEvent(Event *event) = 0;
    virtual Tick getCurrentInstCount() = 0;

    // Not necessarily the best location for these...
    // Having an extra function just to read these is obnoxious
    virtual Tick readLastActivate() = 0;
    virtual Tick readLastSuspend() = 0;

    virtual void copyArchRegs(ThreadContext *tc) = 0;

    virtual void clearArchRegs() = 0;

    //
    // New accessors for new decoder.
    //
    virtual RegVal readIntReg(RegIndex reg_idx) const = 0;

    virtual RegVal readFloatReg(RegIndex reg_idx) const = 0;

    virtual const TheISA::VecRegContainer&
        readVecReg(const RegId& reg) const = 0;
    virtual TheISA::VecRegContainer& getWritableVecReg(const RegId& reg) = 0;

    virtual RegVal readVecElem(const RegId& reg) const = 0;

    virtual const TheISA::VecPredRegContainer& readVecPredReg(
            const RegId& reg) const = 0;
    virtual TheISA::VecPredRegContainer& getWritableVecPredReg(
            const RegId& reg) = 0;

    virtual RegVal readCCReg(RegIndex reg_idx) const = 0;

    virtual void setIntReg(RegIndex reg_idx, RegVal val) = 0;

    virtual void setFloatReg(RegIndex reg_idx, RegVal val) = 0;

    virtual void setVecReg(const RegId& reg,
            const TheISA::VecRegContainer& val) = 0;

    virtual void setVecElem(const RegId& reg, RegVal val) = 0;

    virtual void setVecPredReg(const RegId& reg,
            const TheISA::VecPredRegContainer& val) = 0;

    virtual void setCCReg(RegIndex reg_idx, RegVal val) = 0;

    virtual TheISA::PCState pcState() const = 0;

    virtual void pcState(const TheISA::PCState &val) = 0;
    void pcState(Addr addr) { pcState(TheISA::PCState(addr)); }

    void
    setNPC(Addr val)
    {
        TheISA::PCState pc_state = pcState();
        pc_state.setNPC(val);
        pcState(pc_state);
    }

    virtual void pcStateNoRecord(const TheISA::PCState &val) = 0;

    virtual Addr instAddr() const = 0;

    virtual MicroPC microPC() const = 0;

    virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const = 0;

    virtual RegVal readMiscReg(RegIndex misc_reg) = 0;

    virtual void setMiscRegNoEffect(RegIndex misc_reg, RegVal val) = 0;

    virtual void setMiscReg(RegIndex misc_reg, RegVal val) = 0;

    virtual RegId flattenRegId(const RegId& reg_id) const = 0;

    // Also not necessarily the best location for these two.  Hopefully will go
    // away once we decide upon where st cond failures goes.
    virtual unsigned readStCondFailures() const = 0;

    virtual void setStCondFailures(unsigned sc_failures) = 0;

    // This function exits the thread context in the CPU and returns
    // 1 if the CPU has no more active threads (meaning it's OK to exit);
    // Used in syscall-emulation mode when a  thread calls the exit syscall.
    virtual int exit() { return 1; };

    /** function to compare two thread contexts (for debugging) */
    static void compare(ThreadContext *one, ThreadContext *two);

    /** @{ */
    /**
     * Flat register interfaces
     *
     * Some architectures have different registers visible in
     * different modes. Such architectures "flatten" a register (see
     * flattenRegId()) to map it into the
     * gem5 register file. This interface provides a flat interface to
     * the underlying register file, which allows for example
     * serialization code to access all registers.
     */

    virtual RegVal readIntRegFlat(RegIndex idx) const = 0;
    virtual void setIntRegFlat(RegIndex idx, RegVal val) = 0;

    virtual RegVal readFloatRegFlat(RegIndex idx) const = 0;
    virtual void setFloatRegFlat(RegIndex idx, RegVal val) = 0;

    virtual const TheISA::VecRegContainer&
        readVecRegFlat(RegIndex idx) const = 0;
    virtual TheISA::VecRegContainer& getWritableVecRegFlat(RegIndex idx) = 0;
    virtual void setVecRegFlat(RegIndex idx,
            const TheISA::VecRegContainer& val) = 0;

    virtual RegVal readVecElemFlat(RegIndex idx,
            const ElemIndex& elem_idx) const = 0;
    virtual void setVecElemFlat(RegIndex idx, const ElemIndex& elem_idx,
            RegVal val) = 0;

    virtual const TheISA::VecPredRegContainer &
        readVecPredRegFlat(RegIndex idx) const = 0;
    virtual TheISA::VecPredRegContainer& getWritableVecPredRegFlat(
            RegIndex idx) = 0;
    virtual void setVecPredRegFlat(RegIndex idx,
            const TheISA::VecPredRegContainer& val) = 0;

    virtual RegVal readCCRegFlat(RegIndex idx) const = 0;
    virtual void setCCRegFlat(RegIndex idx, RegVal val) = 0;
    /** @} */

    // hardware transactional memory
    virtual void htmAbortTransaction(uint64_t htm_uid,
                                     HtmFailureFaultCause cause) = 0;
    virtual BaseHTMCheckpointPtr& getHtmCheckpointPtr() = 0;
    virtual void setHtmCheckpointPtr(BaseHTMCheckpointPtr cpt) = 0;
};

/** @{ */
/**
 * Thread context serialization helpers
 *
 * These helper functions provide a way to the data in a
 * ThreadContext. They are provided as separate helper function since
 * implementing them as members of the ThreadContext interface would
 * be confusing when the ThreadContext is exported via a proxy.
 */

void serialize(const ThreadContext &tc, CheckpointOut &cp);
void unserialize(ThreadContext &tc, CheckpointIn &cp);

/** @} */

/**
 * Copy state between thread contexts in preparation for CPU handover.
 *
 * @note This method modifies the old thread contexts as well as the
 * new thread context. The old thread context will have its quiesce
 * event descheduled if it is scheduled and its status set to halted.
 *
 * @param new_tc Destination ThreadContext.
 * @param old_tc Source ThreadContext.
 */
void takeOverFrom(ThreadContext &new_tc, ThreadContext &old_tc);

} // namespace gem5

#endif
<commit_msg>cpu: Reimplement pcState(Addr) without using the PCState constructor.<commit_after>/*
 * Copyright (c) 2011-2012, 2016-2018, 2020 ARM Limited
 * Copyright (c) 2013 Advanced Micro Devices, Inc.
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __CPU_THREAD_CONTEXT_HH__
#define __CPU_THREAD_CONTEXT_HH__

#include <iostream>
#include <string>

#include "arch/generic/htm.hh"
#include "arch/generic/isa.hh"
#include "arch/pcstate.hh"
#include "arch/vecregs.hh"
#include "base/types.hh"
#include "config/the_isa.hh"
#include "cpu/pc_event.hh"
#include "cpu/reg_class.hh"

namespace gem5
{

// @todo: Figure out a more architecture independent way to obtain the ITB and
// DTB pointers.
namespace TheISA
{
    class Decoder;
}
class BaseCPU;
class BaseMMU;
class BaseTLB;
class CheckerCPU;
class Checkpoint;
class PortProxy;
class Process;
class System;
class Packet;
using PacketPtr = Packet *;

/**
 * ThreadContext is the external interface to all thread state for
 * anything outside of the CPU. It provides all accessor methods to
 * state that might be needed by external objects, ranging from
 * register values to things such as kernel stats. It is an abstract
 * base class; the CPU can create its own ThreadContext by
 * deriving from it.
 *
 * The ThreadContext is slightly different than the ExecContext.  The
 * ThreadContext provides access to an individual thread's state; an
 * ExecContext provides ISA access to the CPU (meaning it is
 * implicitly multithreaded on SMT systems).  Additionally the
 * ThreadState is an abstract class that exactly defines the
 * interface; the ExecContext is a more implicit interface that must
 * be implemented so that the ISA can access whatever state it needs.
 */
class ThreadContext : public PCEventScope
{
  protected:
    bool useForClone = false;

  public:

    bool getUseForClone() { return useForClone; }

    void setUseForClone(bool new_val) { useForClone = new_val; }

    enum Status
    {
        /// Running.  Instructions should be executed only when
        /// the context is in this state.
        Active,

        /// Temporarily inactive.  Entered while waiting for
        /// synchronization, etc.
        Suspended,

        /// Trying to exit and waiting for an event to completely exit.
        /// Entered when target executes an exit syscall.
        Halting,

        /// Permanently shut down.  Entered when target executes
        /// m5exit pseudo-instruction.  When all contexts enter
        /// this state, the simulation will terminate.
        Halted
    };

    virtual ~ThreadContext() { };

    virtual BaseCPU *getCpuPtr() = 0;

    virtual int cpuId() const = 0;

    virtual uint32_t socketId() const = 0;

    virtual int threadId() const = 0;

    virtual void setThreadId(int id) = 0;

    virtual ContextID contextId() const = 0;

    virtual void setContextId(ContextID id) = 0;

    virtual BaseMMU *getMMUPtr() = 0;

    virtual CheckerCPU *getCheckerCpuPtr() = 0;

    virtual BaseISA *getIsaPtr() = 0;

    virtual TheISA::Decoder *getDecoderPtr() = 0;

    virtual System *getSystemPtr() = 0;

    virtual void sendFunctional(PacketPtr pkt);

    virtual Process *getProcessPtr() = 0;

    virtual void setProcessPtr(Process *p) = 0;

    virtual Status status() const = 0;

    virtual void setStatus(Status new_status) = 0;

    /// Set the status to Active.
    virtual void activate() = 0;

    /// Set the status to Suspended.
    virtual void suspend() = 0;

    /// Set the status to Halted.
    virtual void halt() = 0;

    /// Quiesce thread context
    void quiesce();

    /// Quiesce, suspend, and schedule activate at resume
    void quiesceTick(Tick resume);

    virtual void takeOverFrom(ThreadContext *old_context) = 0;

    virtual void regStats(const std::string &name) {};

    virtual void scheduleInstCountEvent(Event *event, Tick count) = 0;
    virtual void descheduleInstCountEvent(Event *event) = 0;
    virtual Tick getCurrentInstCount() = 0;

    // Not necessarily the best location for these...
    // Having an extra function just to read these is obnoxious
    virtual Tick readLastActivate() = 0;
    virtual Tick readLastSuspend() = 0;

    virtual void copyArchRegs(ThreadContext *tc) = 0;

    virtual void clearArchRegs() = 0;

    //
    // New accessors for new decoder.
    //
    virtual RegVal readIntReg(RegIndex reg_idx) const = 0;

    virtual RegVal readFloatReg(RegIndex reg_idx) const = 0;

    virtual const TheISA::VecRegContainer&
        readVecReg(const RegId& reg) const = 0;
    virtual TheISA::VecRegContainer& getWritableVecReg(const RegId& reg) = 0;

    virtual RegVal readVecElem(const RegId& reg) const = 0;

    virtual const TheISA::VecPredRegContainer& readVecPredReg(
            const RegId& reg) const = 0;
    virtual TheISA::VecPredRegContainer& getWritableVecPredReg(
            const RegId& reg) = 0;

    virtual RegVal readCCReg(RegIndex reg_idx) const = 0;

    virtual void setIntReg(RegIndex reg_idx, RegVal val) = 0;

    virtual void setFloatReg(RegIndex reg_idx, RegVal val) = 0;

    virtual void setVecReg(const RegId& reg,
            const TheISA::VecRegContainer& val) = 0;

    virtual void setVecElem(const RegId& reg, RegVal val) = 0;

    virtual void setVecPredReg(const RegId& reg,
            const TheISA::VecPredRegContainer& val) = 0;

    virtual void setCCReg(RegIndex reg_idx, RegVal val) = 0;

    virtual TheISA::PCState pcState() const = 0;

    virtual void pcState(const TheISA::PCState &val) = 0;
    void
    pcState(Addr addr)
    {
        pcState(getIsaPtr()->newPCState(addr)->as<TheISA::PCState>());
    }

    void
    setNPC(Addr val)
    {
        TheISA::PCState pc_state = pcState();
        pc_state.setNPC(val);
        pcState(pc_state);
    }

    virtual void pcStateNoRecord(const TheISA::PCState &val) = 0;

    virtual Addr instAddr() const = 0;

    virtual MicroPC microPC() const = 0;

    virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const = 0;

    virtual RegVal readMiscReg(RegIndex misc_reg) = 0;

    virtual void setMiscRegNoEffect(RegIndex misc_reg, RegVal val) = 0;

    virtual void setMiscReg(RegIndex misc_reg, RegVal val) = 0;

    virtual RegId flattenRegId(const RegId& reg_id) const = 0;

    // Also not necessarily the best location for these two.  Hopefully will go
    // away once we decide upon where st cond failures goes.
    virtual unsigned readStCondFailures() const = 0;

    virtual void setStCondFailures(unsigned sc_failures) = 0;

    // This function exits the thread context in the CPU and returns
    // 1 if the CPU has no more active threads (meaning it's OK to exit);
    // Used in syscall-emulation mode when a  thread calls the exit syscall.
    virtual int exit() { return 1; };

    /** function to compare two thread contexts (for debugging) */
    static void compare(ThreadContext *one, ThreadContext *two);

    /** @{ */
    /**
     * Flat register interfaces
     *
     * Some architectures have different registers visible in
     * different modes. Such architectures "flatten" a register (see
     * flattenRegId()) to map it into the
     * gem5 register file. This interface provides a flat interface to
     * the underlying register file, which allows for example
     * serialization code to access all registers.
     */

    virtual RegVal readIntRegFlat(RegIndex idx) const = 0;
    virtual void setIntRegFlat(RegIndex idx, RegVal val) = 0;

    virtual RegVal readFloatRegFlat(RegIndex idx) const = 0;
    virtual void setFloatRegFlat(RegIndex idx, RegVal val) = 0;

    virtual const TheISA::VecRegContainer&
        readVecRegFlat(RegIndex idx) const = 0;
    virtual TheISA::VecRegContainer& getWritableVecRegFlat(RegIndex idx) = 0;
    virtual void setVecRegFlat(RegIndex idx,
            const TheISA::VecRegContainer& val) = 0;

    virtual RegVal readVecElemFlat(RegIndex idx,
            const ElemIndex& elem_idx) const = 0;
    virtual void setVecElemFlat(RegIndex idx, const ElemIndex& elem_idx,
            RegVal val) = 0;

    virtual const TheISA::VecPredRegContainer &
        readVecPredRegFlat(RegIndex idx) const = 0;
    virtual TheISA::VecPredRegContainer& getWritableVecPredRegFlat(
            RegIndex idx) = 0;
    virtual void setVecPredRegFlat(RegIndex idx,
            const TheISA::VecPredRegContainer& val) = 0;

    virtual RegVal readCCRegFlat(RegIndex idx) const = 0;
    virtual void setCCRegFlat(RegIndex idx, RegVal val) = 0;
    /** @} */

    // hardware transactional memory
    virtual void htmAbortTransaction(uint64_t htm_uid,
                                     HtmFailureFaultCause cause) = 0;
    virtual BaseHTMCheckpointPtr& getHtmCheckpointPtr() = 0;
    virtual void setHtmCheckpointPtr(BaseHTMCheckpointPtr cpt) = 0;
};

/** @{ */
/**
 * Thread context serialization helpers
 *
 * These helper functions provide a way to the data in a
 * ThreadContext. They are provided as separate helper function since
 * implementing them as members of the ThreadContext interface would
 * be confusing when the ThreadContext is exported via a proxy.
 */

void serialize(const ThreadContext &tc, CheckpointOut &cp);
void unserialize(ThreadContext &tc, CheckpointIn &cp);

/** @} */

/**
 * Copy state between thread contexts in preparation for CPU handover.
 *
 * @note This method modifies the old thread contexts as well as the
 * new thread context. The old thread context will have its quiesce
 * event descheduled if it is scheduled and its status set to halted.
 *
 * @param new_tc Destination ThreadContext.
 * @param old_tc Source ThreadContext.
 */
void takeOverFrom(ThreadContext &new_tc, ThreadContext &old_tc);

} // namespace gem5

#endif
<|endoftext|>


<commit_before>/****************************************************************/
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*          All contents are licensed under LGPL V2.1           */
/*             See LICENSE for full restrictions                */
/****************************************************************/
#include "MultiSoretDiffusion.h"
template<>
InputParameters validParams<SoretDiffusion>()
{
  InputParameters params = validParams<Kernel>();
  params.addClassDescription("Add Soret effect to Split formulation Cahn-Hilliard Kernel");
  params.addRequiredCoupledVar("T", "Temperature");
  params.addRequiredCoupledVar("c", "Concentration");
  #params.addRequiredParam<MaterialPropertyName>("diffname_1", "The diffusivity of Sn or Element 1 used with the kernel");
  #params.addRequiredParam<MaterialPropertyName>("diffname_2", "The diffusivity of Cu or Element 2 used with the kernel");
  #params.addParam<MaterialPropertyName>("Qname_1", "Qheat_1", "The material 1 name for the heat of transport");
  #params.addParam<MaterialPropertyName>("Qname_2", "Qheat_2", "The material 2 name for the heat of transport");
  params.addRequiredParam<MaterialPropertyName>("mob_thermotransport", "The mobility of thermotransport");
  return params;
}

MultiSoretDiffusion::MultiSoretDiffusion(const InputParameters & parameters) :
    Kernel(parameters),
    _T_var(coupled("T")),
    _T(coupledValue("T")),
    _grad_T(coupledGradient("T")),
    _c_var(coupled("c")),
    _Mq(getMaterialProperty<Real>("mob_thermotransport")),
    _kb(8.617343e-5) // Boltzmann constant in eV/K
{
}

Real
MultiSoretDiffusion::computeQpResidual()
{
  Real T_term = _Mc[_qp] / ( _T[_qp] [_qp]);
  return T_term * _grad_T[_qp] * _grad_test[_i][_qp];
}

Real
MultiSoretDiffusion::computeQpJacobian()
{
  if (_c_var == _var.number()) //Requires c jacobian
    return computeQpCJacobian();

  return 0.0;
}

Real
MultiSoretDiffusion::computeQpOffDiagJacobian(unsigned int jvar)
{
  if (_c_var == jvar) //Requires c jacobian
    return computeQpCJacobian();
  else if (_T_var == jvar) //Requires T jacobian
    return _D[_qp] * _Q[_qp] * _c[_qp] * _grad_test[_i][_qp] *
           (_grad_phi[_j][_qp]/(_kb * _T[_qp] * _T[_qp]) - 2.0 * _grad_T[_qp] * _phi[_j][_qp] / (_kb * _T[_qp] * _T[_qp] * _T[_qp]));

  return 0.0;
}

Real
MultiSoretDiffusion::computeQpCJacobian()
{
  //Calculate the Jacobian for the c variable
  return _D[_qp] * _Q[_qp] * _phi[_j][_qp] * _grad_T[_qp] / (_kb * _T[_qp] * _T[_qp]) * _grad_test[_i][_qp];
}

<commit_msg>Update MultiSorretDiffusion.C<commit_after>/****************************************************************/
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*          All contents are licensed under LGPL V2.1           */
/*             See LICENSE for full restrictions                */
/****************************************************************/
#include "MultiSoretDiffusion.h"
template<>
InputParameters validParams<SoretDiffusion>()
{
  InputParameters params = validParams<Kernel>();
  params.addClassDescription("Add Soret effect to Split formulation Cahn-Hilliard Kernel");
  params.addRequiredCoupledVar("T", "Temperature");
  params.addRequiredCoupledVar("c", "Concentration");
  #params.addParam<MaterialPropertyName>("mob_name", "L", "The mobility used with the kernel");
  params.addParam<MaterialPropertyName>("mob_thermotransport", "Mq","The mobility of thermotransport");
  return params;
}

MultiSoretDiffusion::MultiSoretDiffusion(const InputParameters & parameters) :
    Kernel(parameters),
    _T_var(coupled("T")),
    _T(coupledValue("T")),
    _grad_T(coupledGradient("T")),
    _c_var(coupled("c")),
    _Mq(getMaterialProperty<Real>("mob_thermotransport")),
    _kb(8.617343e-5) // Boltzmann constant in eV/K
{
}

Real
MultiSoretDiffusion::computeQpResidual()
{
  Real T_term = _Mc[_qp] / ( _T[_qp] [_qp]);
  return T_term * _grad_T[_qp] * _grad_test[_i][_qp];
}

Real
MultiSoretDiffusion::computeQpJacobian()
{
  if (_c_var == _var.number()) //Requires c jacobian
    return computeQpCJacobian();

  return 0.0;
}

Real
MultiSoretDiffusion::computeQpOffDiagJacobian(unsigned int jvar)
{
  if (_c_var == jvar) //Requires c jacobian
    return computeQpCJacobian();
  else if (_T_var == jvar) //Requires T jacobian
    return _D[_qp] * _Q[_qp] * _c[_qp] * _grad_test[_i][_qp] *
           (_grad_phi[_j][_qp]/(_kb * _T[_qp] * _T[_qp]) - 2.0 * _grad_T[_qp] * _phi[_j][_qp] / (_kb * _T[_qp] * _T[_qp] * _T[_qp]));

  return 0.0;
}

Real
MultiSoretDiffusion::computeQpCJacobian()
{
  //Calculate the Jacobian for the c variable
  return _D[_qp] * _Q[_qp] * _phi[_j][_qp] * _grad_T[_qp] / (_kb * _T[_qp] * _T[_qp]) * _grad_test[_i][_qp];
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: OOXMLParserState.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: obo $ $Date: 2008-01-10 11:58:53 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef INCLUDE_OOXML_PARSER_STATE_HXX
#define INCLUDE_OOXML_PARSER_STATE_HXX

#include <ooxml/OOXMLDocument.hxx>
#include "OOXMLPropertySetImpl.hxx"

namespace writerfilter {
namespace ooxml
{

class OOXMLParserState
{
    bool mbInSectionGroup;
    bool mbInParagraphGroup;
    bool mbInCharacterGroup;
    bool mbLastParagraphInSection;
    bool mbForwardEvents;
    unsigned int mnContexts;
    unsigned int mnHandle;
    OOXMLDocument * mpDocument;
    rtl::OUString msXNoteId;
    OOXMLPropertySet::Pointer_t mpCharacterProps;

public:
    typedef boost::shared_ptr<OOXMLParserState> Pointer_t;

    OOXMLParserState();
    virtual ~OOXMLParserState();

    bool isInSectionGroup() const;
    void setInSectionGroup(bool bInSectionGroup);

    void setLastParagraphInSection(bool bLastParagraphInSection);
    bool isLastParagraphInSection() const;

    bool isInParagraphGroup() const;
    void setInParagraphGroup(bool bInParagraphGroup);

    bool isInCharacterGroup() const;
    void setInCharacterGroup(bool bInCharacterGroup);

    void setForwardEvents(bool bForwardEvents);
    bool isForwardEvents() const;

    void incContextCount();
    const string getHandle() const;
    void setHandle();
    unsigned int getContextCount() const;

    void setDocument(OOXMLDocument * pDocument);
    OOXMLDocument * getDocument() const;

    void setXNoteId(const rtl::OUString & rId);
    const rtl::OUString & getXNoteId() const;

    void newCharacterProperty(const Id & rId, OOXMLValue::Pointer_t pVal);
    void resolveCharacterProperties(Stream & rStream);
    void setCharacterProperties(OOXMLPropertySet::Pointer_t pProps);

    string toString() const;
};

}}

#endif // INCLUDE_OOXML_PARSER_STATE_HXX
<commit_msg>INTEGRATION: CWS xmlfilter03_DEV300 (1.2.2); FILE MERGED 2008/02/26 13:08:25 hbrinkm 1.2.2.3: undone changes aimed for xmlfilter04 2008/02/25 09:59:33 hbrinkm 1.2.2.2: additionally use type of footnote/endnote to specify which footnote/endnote to use 2008/01/22 09:53:22 hbrinkm 1.2.2.1: table properties<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: OOXMLParserState.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: kz $ $Date: 2008-03-05 17:05:35 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef INCLUDE_OOXML_PARSER_STATE_HXX
#define INCLUDE_OOXML_PARSER_STATE_HXX

#include <ooxml/OOXMLDocument.hxx>
#include "OOXMLPropertySetImpl.hxx"

namespace writerfilter {
namespace ooxml
{

class OOXMLParserState
{
    bool mbInSectionGroup;
    bool mbInParagraphGroup;
    bool mbInCharacterGroup;
    bool mbLastParagraphInSection;
    bool mbForwardEvents;
    unsigned int mnContexts;
    unsigned int mnHandle;
    OOXMLDocument * mpDocument;
    rtl::OUString msXNoteId;
    OOXMLPropertySet::Pointer_t mpCharacterProps;
    OOXMLPropertySet::Pointer_t mpTableProps;

public:
    typedef boost::shared_ptr<OOXMLParserState> Pointer_t;

    OOXMLParserState();
    virtual ~OOXMLParserState();

    bool isInSectionGroup() const;
    void setInSectionGroup(bool bInSectionGroup);

    void setLastParagraphInSection(bool bLastParagraphInSection);
    bool isLastParagraphInSection() const;

    bool isInParagraphGroup() const;
    void setInParagraphGroup(bool bInParagraphGroup);

    bool isInCharacterGroup() const;
    void setInCharacterGroup(bool bInCharacterGroup);

    void setForwardEvents(bool bForwardEvents);
    bool isForwardEvents() const;

    void incContextCount();
    const string getHandle() const;
    void setHandle();
    unsigned int getContextCount() const;

    void setDocument(OOXMLDocument * pDocument);
    OOXMLDocument * getDocument() const;

    void setXNoteId(const rtl::OUString & rId);
    const rtl::OUString & getXNoteId() const;

    void newCharacterProperty(const Id & rId, OOXMLValue::Pointer_t pVal);
    void resolveCharacterProperties(Stream & rStream);
    void setCharacterProperties(OOXMLPropertySet::Pointer_t pProps);
    void resolveTableProperties(Stream & rStream);
    void setTableProperties(OOXMLPropertySet::Pointer_t pProps);

    string toString() const;
};

}}

#endif // INCLUDE_OOXML_PARSER_STATE_HXX
<|endoftext|>