<commit_before>/*****************************************************************************
* libVLC backend for the Phonon library                                     *
*                                                                           *
* Copyright (C) 2010 Casian Andrei <skeletk13@gmail.com>                    *
* Copyright (C) 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 "devicescan.h"

#ifdef HAVE_LIBV4L2
#include <linux/videodev2.h>
#include <libv4l2.h>
#include <fcntl.h>
#endif // HAVE_LIBV4L2

#include <QtCore/QDebug>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QDir>

QT_BEGIN_NAMESPACE

namespace Phonon {
namespace VLC {

bool scanDevices(QList<DeviceInfo> & devices)
{
    bool ret = true;

    #ifdef HAVE_LIBV4L2
    qDebug() << Q_FUNC_INFO << "Probing for v4l2 devices";
    ret &= scanDevicesV4L2(devices);
    #endif

    return ret;
}

#ifdef HAVE_LIBV4L2

typedef enum {
    IO_METHOD_AUTO,
    IO_METHOD_READ,
    IO_METHOD_MMAP,
    IO_METHOD_USERPTR,
} io_method;

struct demux_sys_t {
    char *psz_device;  /* Main device from MRL */
    int  i_fd;

    char *psz_requested_chroma;

    /* Video */
    io_method io;

    int i_cache;

    struct v4l2_capability dev_cap;

    int i_input;
    struct v4l2_input *p_inputs;
    int i_selected_input;

    int i_standard;
    struct v4l2_standard *p_standards;
    v4l2_std_id i_selected_standard_id;

    int i_audio;
    /* V4L2 devices cannot have more than 32 audio inputs */
    struct v4l2_audio p_audios[32];
    int i_selected_audio_input;

    int i_tuner;
    struct v4l2_tuner *p_tuners;

    int i_codec;
    struct v4l2_fmtdesc *p_codecs;

    struct buffer_t *p_buffers;
    unsigned int i_nbuffers;

    int i_width;
    int i_height;
    unsigned int i_aspect;
    float f_fps;            /* <= 0.0 mean to grab at full rate */
    int64_t i_video_pts;    /* only used when f_fps > 0 */
    int i_fourcc;
    uint32_t i_block_flags;

    /* es_out_id_t *p_es; */
    void *p_es;

    /* Tuner */
    int i_cur_tuner;
    int i_frequency;
    int i_audio_mode;

    /* Controls */
    char *psz_set_ctrls;

    /* */
    int (*pf_open)(const char *, int, ...);
    int (*pf_close)(int);
    int (*pf_dup)(int);
    int (*pf_ioctl)(int, unsigned long int, ...);
    ssize_t (*pf_read)(int, void *, size_t );
    void *(*pf_mmap)(void *, size_t, int, int, int, off_t);
    int (*pf_munmap)(void *, size_t);
    bool b_libv4l2;
};

/*
Tries to open a v4l device specified by devicePath, and queries it's capabilities.
Depending on the device capabilities, it is added to the capture device lists
*/
static bool probeDevice(QByteArray devicePath, QList<DeviceInfo> & devices)
{
    int i_index;
    int i_standard;
    int i_fd;

    struct demux_sys_t v4lDeviceInfo;
    memset(&v4lDeviceInfo, 0, sizeof(v4lDeviceInfo));

    // Open device
    if ((i_fd = v4l2_open(devicePath.constData(), O_RDWR)) < 0) {
        qCritical() << Q_FUNC_INFO << "Cannot open video device" << devicePath;
        if (i_fd >= 0)
            v4l2_close(i_fd);
        return false;
    }

    int libv4l2_fd;
    libv4l2_fd = v4l2_fd_open(i_fd, V4L2_ENABLE_ENUM_FMT_EMULATION);
    if (libv4l2_fd != -1)
        i_fd = libv4l2_fd;

    // Get device capabilites
    if (v4l2_ioctl(i_fd, VIDIOC_QUERYCAP, &v4lDeviceInfo.dev_cap) < 0) {
        qCritical() << Q_FUNC_INFO << "Cannot get video capabilities for" << devicePath;
        if (i_fd >= 0)
            v4l2_close(i_fd);
        return false;
    }

    DeviceInfo di("", devicePath);
    bool ok = false;

    // Create a device description if the device has either video or audio capabilities, or both
    if (v4lDeviceInfo.dev_cap.capabilities & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO)) {
        di.nameId = QByteArray((const char*) v4lDeviceInfo.dev_cap.card).trimmed();
        di.description = "Video For Linux 2 Video Device, using driver ";
        di.description.append(QByteArray((const char*) v4lDeviceInfo.dev_cap.driver).trimmed());
        di.deviceClass = DeviceInfo::V4L2;
        ok = true;
    }

    // Probe video inputs
    if (v4lDeviceInfo.dev_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
        qDebug() << "found video capture device" << devicePath;
        di.capabilities |= DeviceInfo::VideoCapture;
    }

    // Probe audio inputs
    if (v4lDeviceInfo.dev_cap.capabilities & V4L2_CAP_AUDIO) {
        qDebug() << "found audio capture device" << devicePath;
        di.capabilities |= DeviceInfo::AudioCapture;
    }

    if (ok)
        devices << di;

    if (i_fd >= 0)
        v4l2_close(i_fd);
    return true;
}

bool scanDevicesV4L2(QList<DeviceInfo> & devices)
{
    QDir deviceDir("/dev");
    if (!deviceDir.isReadable()) {
        qCritical() << Q_FUNC_INFO << "Unable to read /dev";
        return false;
    }

    // Search trough /dev/videoX for valid V4L devices
    QStringList nameFilters;
    nameFilters << "video*";
    deviceDir.setFilter(QDir::System);
    deviceDir.setNameFilters(nameFilters);

    QStringList devicePaths = deviceDir.entryList();
    foreach (QString dn, devicePaths) {
        dn = deviceDir.filePath(dn);

        // Get information about the device from V4L, and append it to the capture device lists
        probeDevice(dn.toLatin1(), devices);
    }

    return true;
}

#endif // HAVE_LIBV4L2

} // namespace VLC
} // namespace Phonon

QT_END_NAMESPACE

<commit_msg>Remove unused variables in device scan<commit_after>/*****************************************************************************
* libVLC backend for the Phonon library                                     *
*                                                                           *
* Copyright (C) 2010 Casian Andrei <skeletk13@gmail.com>                    *
* Copyright (C) 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 "devicescan.h"

#ifdef HAVE_LIBV4L2
#include <linux/videodev2.h>
#include <libv4l2.h>
#include <fcntl.h>
#endif // HAVE_LIBV4L2

#include <QtCore/QDebug>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QDir>

QT_BEGIN_NAMESPACE

namespace Phonon {
namespace VLC {

bool scanDevices(QList<DeviceInfo> & devices)
{
    bool ret = true;

    #ifdef HAVE_LIBV4L2
    qDebug() << Q_FUNC_INFO << "Probing for v4l2 devices";
    ret &= scanDevicesV4L2(devices);
    #endif

    return ret;
}

#ifdef HAVE_LIBV4L2

typedef enum {
    IO_METHOD_AUTO,
    IO_METHOD_READ,
    IO_METHOD_MMAP,
    IO_METHOD_USERPTR,
} io_method;

struct demux_sys_t {
    char *psz_device;  /* Main device from MRL */
    int  i_fd;

    char *psz_requested_chroma;

    /* Video */
    io_method io;

    int i_cache;

    struct v4l2_capability dev_cap;

    int i_input;
    struct v4l2_input *p_inputs;
    int i_selected_input;

    int i_standard;
    struct v4l2_standard *p_standards;
    v4l2_std_id i_selected_standard_id;

    int i_audio;
    /* V4L2 devices cannot have more than 32 audio inputs */
    struct v4l2_audio p_audios[32];
    int i_selected_audio_input;

    int i_tuner;
    struct v4l2_tuner *p_tuners;

    int i_codec;
    struct v4l2_fmtdesc *p_codecs;

    struct buffer_t *p_buffers;
    unsigned int i_nbuffers;

    int i_width;
    int i_height;
    unsigned int i_aspect;
    float f_fps;            /* <= 0.0 mean to grab at full rate */
    int64_t i_video_pts;    /* only used when f_fps > 0 */
    int i_fourcc;
    uint32_t i_block_flags;

    /* es_out_id_t *p_es; */
    void *p_es;

    /* Tuner */
    int i_cur_tuner;
    int i_frequency;
    int i_audio_mode;

    /* Controls */
    char *psz_set_ctrls;

    /* */
    int (*pf_open)(const char *, int, ...);
    int (*pf_close)(int);
    int (*pf_dup)(int);
    int (*pf_ioctl)(int, unsigned long int, ...);
    ssize_t (*pf_read)(int, void *, size_t );
    void *(*pf_mmap)(void *, size_t, int, int, int, off_t);
    int (*pf_munmap)(void *, size_t);
    bool b_libv4l2;
};

/*
Tries to open a v4l device specified by devicePath, and queries it's capabilities.
Depending on the device capabilities, it is added to the capture device lists
*/
static bool probeDevice(QByteArray devicePath, QList<DeviceInfo> & devices)
{
    int i_fd;

    struct demux_sys_t v4lDeviceInfo;
    memset(&v4lDeviceInfo, 0, sizeof(v4lDeviceInfo));

    // Open device
    if ((i_fd = v4l2_open(devicePath.constData(), O_RDWR)) < 0) {
        qCritical() << Q_FUNC_INFO << "Cannot open video device" << devicePath;
        if (i_fd >= 0)
            v4l2_close(i_fd);
        return false;
    }

    int libv4l2_fd;
    libv4l2_fd = v4l2_fd_open(i_fd, V4L2_ENABLE_ENUM_FMT_EMULATION);
    if (libv4l2_fd != -1)
        i_fd = libv4l2_fd;

    // Get device capabilites
    if (v4l2_ioctl(i_fd, VIDIOC_QUERYCAP, &v4lDeviceInfo.dev_cap) < 0) {
        qCritical() << Q_FUNC_INFO << "Cannot get video capabilities for" << devicePath;
        if (i_fd >= 0)
            v4l2_close(i_fd);
        return false;
    }

    DeviceInfo di("", devicePath);
    bool ok = false;

    // Create a device description if the device has either video or audio capabilities, or both
    if (v4lDeviceInfo.dev_cap.capabilities & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO)) {
        di.nameId = QByteArray((const char*) v4lDeviceInfo.dev_cap.card).trimmed();
        di.description = "Video For Linux 2 Video Device, using driver ";
        di.description.append(QByteArray((const char*) v4lDeviceInfo.dev_cap.driver).trimmed());
        di.deviceClass = DeviceInfo::V4L2;
        ok = true;
    }

    // Probe video inputs
    if (v4lDeviceInfo.dev_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
        qDebug() << "found video capture device" << devicePath;
        di.capabilities |= DeviceInfo::VideoCapture;
    }

    // Probe audio inputs
    if (v4lDeviceInfo.dev_cap.capabilities & V4L2_CAP_AUDIO) {
        qDebug() << "found audio capture device" << devicePath;
        di.capabilities |= DeviceInfo::AudioCapture;
    }

    if (ok)
        devices << di;

    if (i_fd >= 0)
        v4l2_close(i_fd);
    return true;
}

bool scanDevicesV4L2(QList<DeviceInfo> & devices)
{
    QDir deviceDir("/dev");
    if (!deviceDir.isReadable()) {
        qCritical() << Q_FUNC_INFO << "Unable to read /dev";
        return false;
    }

    // Search trough /dev/videoX for valid V4L devices
    QStringList nameFilters;
    nameFilters << "video*";
    deviceDir.setFilter(QDir::System);
    deviceDir.setNameFilters(nameFilters);

    QStringList devicePaths = deviceDir.entryList();
    foreach (QString dn, devicePaths) {
        dn = deviceDir.filePath(dn);

        // Get information about the device from V4L, and append it to the capture device lists
        probeDevice(dn.toLatin1(), devices);
    }

    return true;
}

#endif // HAVE_LIBV4L2

} // namespace VLC
} // namespace Phonon

QT_END_NAMESPACE

<|endoftext|>


<commit_before>//===- Miscompilation.cpp - Debug program miscompilations -----------------===//
//
// This file implements program miscompilation debugging support.
//
//===----------------------------------------------------------------------===//

#include "BugDriver.h"
#include "SystemUtils.h"
#include "llvm/Pass.h"
#include "llvm/Module.h"
#include "Support/CommandLine.h"

// Anonymous namespace to define command line options for miscompilation
// debugging.
//
namespace {
  // Output - The user can specify a file containing the expected output of the
  // program.  If this filename is set, it is used as the reference diff source,
  // otherwise the raw input run through an interpreter is used as the reference
  // source.
  //
  cl::opt<std::string>
  Output("output", cl::desc("Specify a reference program output "
			    "(for miscompilation detection)"));
}

/// debugMiscompilation - This method is used when the passes selected are not
/// crashing, but the generated output is semantically different from the
/// input.
///
bool BugDriver::debugMiscompilation() {
  std::cout << "*** Debugging miscompilation!\n";

  // Set up the execution environment, selecting a method to run LLVM bytecode.
  if (initializeExecutionEnvironment()) return true;

  // Run the raw input to see where we are coming from.  If a reference output
  // was specified, make sure that the raw output matches it.  If not, it's a
  // problem in the front-end or whatever produced the input code.
  //
  bool CreatedOutput = false;
  if (Output.empty()) {
    std::cout << "Generating reference output from raw program...";
    Output = executeProgram("bugpoint.reference.out");
    CreatedOutput = true;
    std::cout << " done!\n";
  } else if (diffProgram(Output)) {
    std::cout << "\n*** Input program does not match reference diff!\n"
	      << "    Must be problem with input source!\n";
    return false;  // Problem found
  }

  // Figure out which transformation is the first to miscompile the input
  // program.  We do a binary search here in case there are a large number of
  // passes involved.
  //
  unsigned LastGood = 0, LastBad = PassesToRun.size();
  while (LastGood != LastBad) {
    unsigned Mid = (LastBad+LastGood+1) / 2;
    std::vector<const PassInfo*> P(PassesToRun.begin(),
                                   PassesToRun.begin()+Mid);
    std::cout << "Checking to see if the first " << Mid << " passes are ok: ";

    std::string BytecodeResult;
    if (runPasses(P, BytecodeResult, false, true)) {
      std::cerr << ToolName << ": Error running this sequence of passes"
		<< " on the input program!\n";
      exit(1);
    }

    // Check to see if the finished program matches the reference output...
    if (diffProgram(Output, BytecodeResult)) {
      std::cout << "nope.\n";
      LastBad = Mid-1;    // Miscompilation detected!
    } else {
      std::cout << "yup.\n";
      LastGood = Mid;     // No miscompilation!
    }

    // We are now done with the optimized output... so remove it.
    removeFile(BytecodeResult);
  }

  // Make sure something was miscompiled...
  if (LastBad >= PassesToRun.size()) {
    std::cerr << "*** Optimized program matches reference output!  No problem "
	      << "detected...\nbugpoint can't help you with your problem!\n";
    return false;
  }

  // Calculate which pass it is that miscompiles...
  const PassInfo *ThePass = PassesToRun[LastBad];

  std::cout << "\n*** Found miscompiling pass '-" << ThePass->getPassArgument()
            << "': " << ThePass->getPassName() << "\n";

  if (LastGood != 0) {
    std::vector<const PassInfo*> P(PassesToRun.begin(),
                                   PassesToRun.begin()+LastGood);
    std::string Filename;
    std::cout << "Running good passes to get input for pass:";
    if (runPasses(P, Filename, false, true)) {
      std::cerr << "ERROR: Running the first " << LastGood
                << " passes crashed!\n";
      return true;
    }
    std::cout << " done!\n";

    // Assuming everything was successful, we now have a valid bytecode file in
    // OutputName.  Use it for "Program" Instead.
    delete Program;
    Program = ParseInputFile(Filename);

    // Delete the file now.
    removeFile(Filename);
  }

  bool Result = debugPassMiscompilation(ThePass, Output);

  if (CreatedOutput) removeFile(Output);
  return Result;
}

/// debugPassMiscompilation - This method is called when the specified pass
/// miscompiles Program as input.  It tries to reduce the testcase to something
/// that smaller that still miscompiles the program.  ReferenceOutput contains
/// the filename of the file containing the output we are to match.
///
bool BugDriver::debugPassMiscompilation(const PassInfo *Pass,
                                        const std::string &ReferenceOutput) {
  EmitProgressBytecode(Pass, "passinput");

  // Loop over all of the functions in the program, attempting to find one that
  // is being miscompiled.  We do this by extracting the function into a module,
  // running the "bad" optimization on that module, then linking it back into
  // the program.  If the program fails the diff, the function got misoptimized.
  //

  return false;
}
<commit_msg>Print where reference output goes<commit_after>//===- Miscompilation.cpp - Debug program miscompilations -----------------===//
//
// This file implements program miscompilation debugging support.
//
//===----------------------------------------------------------------------===//

#include "BugDriver.h"
#include "SystemUtils.h"
#include "llvm/Pass.h"
#include "llvm/Module.h"
#include "Support/CommandLine.h"

// Anonymous namespace to define command line options for miscompilation
// debugging.
//
namespace {
  // Output - The user can specify a file containing the expected output of the
  // program.  If this filename is set, it is used as the reference diff source,
  // otherwise the raw input run through an interpreter is used as the reference
  // source.
  //
  cl::opt<std::string>
  Output("output", cl::desc("Specify a reference program output "
			    "(for miscompilation detection)"));
}

/// debugMiscompilation - This method is used when the passes selected are not
/// crashing, but the generated output is semantically different from the
/// input.
///
bool BugDriver::debugMiscompilation() {
  std::cout << "*** Debugging miscompilation!\n";

  // Set up the execution environment, selecting a method to run LLVM bytecode.
  if (initializeExecutionEnvironment()) return true;

  // Run the raw input to see where we are coming from.  If a reference output
  // was specified, make sure that the raw output matches it.  If not, it's a
  // problem in the front-end or whatever produced the input code.
  //
  bool CreatedOutput = false;
  if (Output.empty()) {
    std::cout << "Generating reference output from raw program...";
    Output = executeProgram("bugpoint.reference.out");
    CreatedOutput = true;
    std::cout << " done! Reference output is: bugpoint.reference.out.\n";
  } else if (diffProgram(Output)) {
    std::cout << "\n*** Input program does not match reference diff!\n"
	      << "    Must be problem with input source!\n";
    return false;  // Problem found
  }

  // Figure out which transformation is the first to miscompile the input
  // program.  We do a binary search here in case there are a large number of
  // passes involved.
  //
  unsigned LastGood = 0, LastBad = PassesToRun.size();
  while (LastGood != LastBad) {
    unsigned Mid = (LastBad+LastGood+1) / 2;
    std::vector<const PassInfo*> P(PassesToRun.begin(),
                                   PassesToRun.begin()+Mid);
    std::cout << "Checking to see if the first " << Mid << " passes are ok: ";

    std::string BytecodeResult;
    if (runPasses(P, BytecodeResult, false, true)) {
      std::cerr << ToolName << ": Error running this sequence of passes"
		<< " on the input program!\n";
      exit(1);
    }

    // Check to see if the finished program matches the reference output...
    if (diffProgram(Output, BytecodeResult)) {
      std::cout << "nope.\n";
      LastBad = Mid-1;    // Miscompilation detected!
    } else {
      std::cout << "yup.\n";
      LastGood = Mid;     // No miscompilation!
    }

    // We are now done with the optimized output... so remove it.
    removeFile(BytecodeResult);
  }

  // Make sure something was miscompiled...
  if (LastBad >= PassesToRun.size()) {
    std::cerr << "*** Optimized program matches reference output!  No problem "
	      << "detected...\nbugpoint can't help you with your problem!\n";
    return false;
  }

  // Calculate which pass it is that miscompiles...
  const PassInfo *ThePass = PassesToRun[LastBad];

  std::cout << "\n*** Found miscompiling pass '-" << ThePass->getPassArgument()
            << "': " << ThePass->getPassName() << "\n";

  if (LastGood != 0) {
    std::vector<const PassInfo*> P(PassesToRun.begin(),
                                   PassesToRun.begin()+LastGood);
    std::string Filename;
    std::cout << "Running good passes to get input for pass:";
    if (runPasses(P, Filename, false, true)) {
      std::cerr << "ERROR: Running the first " << LastGood
                << " passes crashed!\n";
      return true;
    }
    std::cout << " done!\n";

    // Assuming everything was successful, we now have a valid bytecode file in
    // OutputName.  Use it for "Program" Instead.
    delete Program;
    Program = ParseInputFile(Filename);

    // Delete the file now.
    removeFile(Filename);
  }

  bool Result = debugPassMiscompilation(ThePass, Output);

  if (CreatedOutput) removeFile(Output);
  return Result;
}

/// debugPassMiscompilation - This method is called when the specified pass
/// miscompiles Program as input.  It tries to reduce the testcase to something
/// that smaller that still miscompiles the program.  ReferenceOutput contains
/// the filename of the file containing the output we are to match.
///
bool BugDriver::debugPassMiscompilation(const PassInfo *Pass,
                                        const std::string &ReferenceOutput) {
  EmitProgressBytecode(Pass, "passinput");

  // Loop over all of the functions in the program, attempting to find one that
  // is being miscompiled.  We do this by extracting the function into a module,
  // running the "bad" optimization on that module, then linking it back into
  // the program.  If the program fails the diff, the function got misoptimized.
  //

  return false;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <sstream>
#include <string>
#include "pegmatite.hh"
// This is very bad style, but it's okay for a short example...
using namespace std;
using namespace pegmatite;

/**
 * The AST namespace contains the abstract syntax tree for this grammar.
 */
namespace AST
{
/**
 * The base class for expressions in our language.
 */
class Expression : public ASTContainer
{
public:
	/**
	 * Evaluate this expression.  Returns a `double` representing the result of
	 * the evaluation.
	 */
	virtual double eval() const = 0;
	/**
	 * Print the node, at the specified indent depth.
	 */
	virtual void print(int depth = 0) const = 0;
	PEGMATITE_RTTI(Expression, ASTContainer);
};

/**
 * AST node representing a number.
 */
class Number : public Expression
{
public:
	/**
	 * Construct the numerical value from the text in the input range.
	 */
	virtual void construct(const pegmatite::InputRange &r, pegmatite::ASTStack &st)
	{
		stringstream stream;
		for (char c : r)
		{
			stream << c;
		}
		stream >> value;
	}

	virtual double eval() const
	{
		return value;
	}

	virtual void print(int depth) const
	{
		cout << string(depth, '\t') << value << endl;
	}

private:
	double value;
};

/**
 * Superclass for all of the binary expressions.  Contains pointers to the left
 * and right children.  Subclasses encode the operation type.
 */
class BinaryExpression : public Expression
{
protected:
	/**
	 * The pointers to the left and right nodes.  The `ASTPtr` class will
	 * automatically fill these in when this node is constructed, popping the
	 * two top values from the AST stack.
	 */
	ASTPtr<Expression> left, right;
public:

	virtual void print(int depth) const
	{
		left->print(depth);
		right->print(depth);
	}
};

/**
 * Add expression node.
 */
class AddExpression : public BinaryExpression
{
public:
	virtual double eval() const
	{
		return left->eval() + right->eval();
	}

	virtual void print(int depth) const
	{
		cout << string(depth, '\t') << "+" << endl;
		BinaryExpression::print(depth+1);
	}
};

/**
 * Subtract expression node.
 */
class SubtractExpression : public BinaryExpression
{
public:
	virtual double eval() const
	{
		return left->eval() - right->eval();
	}

	virtual void print(int depth) const
	{
		cout << string(depth, '\t') << "-" << endl;
		BinaryExpression::print(depth+1);
	}
};

/**
 * Multiply expression node.
 */
class MultiplyExpression : public BinaryExpression
{
public:
	virtual double eval() const
	{
		return left->eval() * right->eval();
	}

	virtual void print(int depth) const
	{
		cout << string(depth, '\t') << "*" << endl;
		BinaryExpression::print(depth+1);
	}
};

/**
 * Divide expression node.
 */
class DivideExpression : public BinaryExpression
{
public:
	virtual double eval() const
	{
		double ret = 0;
		double rval = right->eval();
		if (rval != 0)
		{
			ret = left->eval() / rval;
		}
		return ret;
	}

	virtual void print(int depth) const
	{
		cout << string(depth, '\t') << "/" << endl;
		BinaryExpression::print(depth+1);
	}
};
}

namespace Parser
{
/**
 * The (singleton) calculator grammar.
 */
struct CalculatorGrammar
{
	/**
	 * Only spaces are recognised as whitespace in this toy example.
	 */
	Rule ws     = " \t\n"_E;
	/**
	 * Digits are things in the range 0-9.
	 */
	Rule digits  = "[0-9]+"_R;
	/**
	 * Numbers are one or more digits, optionally followed by a decimal point,
	 * and one or more digits, optionally followed by an exponent (which may
	 * also be negative.
	 */
	Rule num    = digits >> -('.'_E >> digits >> -("eE"_S >> -("+-"_S) >> digits));
	/**
	 * Values are either numbers or expressions in brackets (highest precedence).
	 */
	Rule val    = num |  '(' >> expr >> ')';
	/**
	 * Multiply operations are values or multiply, or divide operations,
	 * followed by a multiply symbol, followed by a values, or multiply or
	 * divide operations.  The sides can never be add or subtract operations,
	 * because they have lower precedence and so can only be parents of
	 * multiply or divide operations (or children via parenthetical
	 * expressions), not direct children.
	 */
	Rule mul_op = mul >> '*' >> mul;
	/**
	 * Divide operations follow the same syntax as multiply.
	 */
	Rule div_op = mul >> '/' >> mul;
	/**
	 * Multiply-precedence operations are either multiply or divide operations,
	 * or simple values (numbers of parenthetical expressions).
	 */
	Rule mul    = mul_op | div_op | val;
	/**
	 * Add operations can have any expression on the left (including other add
	 * expressions), but only higher-precedence operations on the right.
	 */
	Rule add_op = expr >> '+' >> expr;
	/**
	 * Subtract operations follow the same structure as add.
	 */
	Rule sub_op = expr >> '-' >> expr;
	/**
	 * Expressions can be any of the other types.
	 */
	Rule expr   = add_op | sub_op | mul;

	/**
	 * Returns a singleton instance of this grammar.
	 */
	static const CalculatorGrammar& get()
	{
		static CalculatorGrammar g;
		return g;
	}
	private:
	/**
	 * Private constructor.  This class is immutable, and so only the `get()`
	 * method should be used to return the singleton instance.
	 */
	CalculatorGrammar() {};
};

/**
 * CalculatorParser, constructs an AST from an input string.
 */
class CalculatorParser : public ASTParserDelegate
{
	BindAST<AST::Number> num = CalculatorGrammar::get().num;
	BindAST<AST::AddExpression> add = CalculatorGrammar::get().add_op;
	BindAST<AST::SubtractExpression> sub = CalculatorGrammar::get().sub_op;
	BindAST<AST::MultiplyExpression> mul = CalculatorGrammar::get().mul_op;
	BindAST<AST::DivideExpression> div = CalculatorGrammar::get().div_op;
	public:
	const CalculatorGrammar &g = CalculatorGrammar::get();
};

}

int main()
{
	Parser::CalculatorParser p;
	for (;;)
	{
		string s;

		cout << "enter a math expression (+ - * /, floats, parentheses) or enter to exit:\n";
		getline(cin, s);
		if (s.empty()) break;

		//convert the string to input
		StringInput i(std::move(s));

		//parse
		ErrorList el;
		unique_ptr<AST::Expression> root = 0;
		p.parse(i, p.g.expr, p.g.ws, el, root);

		//on success
		if (root)
		{
			double v = root->eval();
			cout << "success\n";
			cout << "result = " << v << endl;
			cout << "parse tree:\n";
			root->print(0);
		}

		//on error
		else
		{
			cout << "errors: \n";
			for (auto &err : el)
			{
				cout << "line " << err.start.line << ", col " << err.finish.col << ": ";
				wcout << "syntax error" << endl;
			}
		}

		//next input
		cout << endl;
	}
	return 0;
}
<commit_msg>Update to the ErrorReporter APIs.<commit_after>#include <iostream>
#include <sstream>
#include <string>
#include "pegmatite.hh"
// This is very bad style, but it's okay for a short example...
using namespace std;
using namespace pegmatite;

/**
 * The AST namespace contains the abstract syntax tree for this grammar.
 */
namespace AST
{
/**
 * The base class for expressions in our language.
 */
class Expression : public ASTContainer
{
public:
	/**
	 * Evaluate this expression.  Returns a `double` representing the result of
	 * the evaluation.
	 */
	virtual double eval() const = 0;
	/**
	 * Print the node, at the specified indent depth.
	 */
	virtual void print(int depth = 0) const = 0;
	PEGMATITE_RTTI(Expression, ASTContainer);
};

/**
 * AST node representing a number.
 */
class Number : public Expression
{
public:
	/**
	 * Construct the numerical value from the text in the input range.
	 */
	virtual void construct(const pegmatite::InputRange &r, pegmatite::ASTStack &st)
	{
		stringstream stream;
		for (char c : r)
		{
			stream << c;
		}
		stream >> value;
	}

	virtual double eval() const
	{
		return value;
	}

	virtual void print(int depth) const
	{
		cout << string(depth, '\t') << value << endl;
	}

private:
	double value;
};

/**
 * Superclass for all of the binary expressions.  Contains pointers to the left
 * and right children.  Subclasses encode the operation type.
 */
class BinaryExpression : public Expression
{
protected:
	/**
	 * The pointers to the left and right nodes.  The `ASTPtr` class will
	 * automatically fill these in when this node is constructed, popping the
	 * two top values from the AST stack.
	 */
	ASTPtr<Expression> left, right;
public:

	virtual void print(int depth) const
	{
		left->print(depth);
		right->print(depth);
	}
};

/**
 * Add expression node.
 */
class AddExpression : public BinaryExpression
{
public:
	virtual double eval() const
	{
		return left->eval() + right->eval();
	}

	virtual void print(int depth) const
	{
		cout << string(depth, '\t') << "+" << endl;
		BinaryExpression::print(depth+1);
	}
};

/**
 * Subtract expression node.
 */
class SubtractExpression : public BinaryExpression
{
public:
	virtual double eval() const
	{
		return left->eval() - right->eval();
	}

	virtual void print(int depth) const
	{
		cout << string(depth, '\t') << "-" << endl;
		BinaryExpression::print(depth+1);
	}
};

/**
 * Multiply expression node.
 */
class MultiplyExpression : public BinaryExpression
{
public:
	virtual double eval() const
	{
		return left->eval() * right->eval();
	}

	virtual void print(int depth) const
	{
		cout << string(depth, '\t') << "*" << endl;
		BinaryExpression::print(depth+1);
	}
};

/**
 * Divide expression node.
 */
class DivideExpression : public BinaryExpression
{
public:
	virtual double eval() const
	{
		double ret = 0;
		double rval = right->eval();
		if (rval != 0)
		{
			ret = left->eval() / rval;
		}
		return ret;
	}

	virtual void print(int depth) const
	{
		cout << string(depth, '\t') << "/" << endl;
		BinaryExpression::print(depth+1);
	}
};
}

namespace Parser
{
/**
 * The (singleton) calculator grammar.
 */
struct CalculatorGrammar
{
	/**
	 * Only spaces are recognised as whitespace in this toy example.
	 */
	Rule ws     = " \t\n"_E;
	/**
	 * Digits are things in the range 0-9.
	 */
	Rule digits  = "[0-9]+"_R;
	/**
	 * Numbers are one or more digits, optionally followed by a decimal point,
	 * and one or more digits, optionally followed by an exponent (which may
	 * also be negative.
	 */
	Rule num    = digits >> -('.'_E >> digits >> -("eE"_S >> -("+-"_S) >> digits));
	/**
	 * Values are either numbers or expressions in brackets (highest precedence).
	 */
	Rule val    = num |  '(' >> expr >> ')';
	/**
	 * Multiply operations are values or multiply, or divide operations,
	 * followed by a multiply symbol, followed by a values, or multiply or
	 * divide operations.  The sides can never be add or subtract operations,
	 * because they have lower precedence and so can only be parents of
	 * multiply or divide operations (or children via parenthetical
	 * expressions), not direct children.
	 */
	Rule mul_op = mul >> '*' >> mul;
	/**
	 * Divide operations follow the same syntax as multiply.
	 */
	Rule div_op = mul >> '/' >> mul;
	/**
	 * Multiply-precedence operations are either multiply or divide operations,
	 * or simple values (numbers of parenthetical expressions).
	 */
	Rule mul    = mul_op | div_op | val;
	/**
	 * Add operations can have any expression on the left (including other add
	 * expressions), but only higher-precedence operations on the right.
	 */
	Rule add_op = expr >> '+' >> expr;
	/**
	 * Subtract operations follow the same structure as add.
	 */
	Rule sub_op = expr >> '-' >> expr;
	/**
	 * Expressions can be any of the other types.
	 */
	Rule expr   = add_op | sub_op | mul;

	/**
	 * Returns a singleton instance of this grammar.
	 */
	static const CalculatorGrammar& get()
	{
		static CalculatorGrammar g;
		return g;
	}
	private:
	/**
	 * Private constructor.  This class is immutable, and so only the `get()`
	 * method should be used to return the singleton instance.
	 */
	CalculatorGrammar() {};
};

/**
 * CalculatorParser, constructs an AST from an input string.
 */
class CalculatorParser : public ASTParserDelegate
{
	BindAST<AST::Number> num = CalculatorGrammar::get().num;
	BindAST<AST::AddExpression> add = CalculatorGrammar::get().add_op;
	BindAST<AST::SubtractExpression> sub = CalculatorGrammar::get().sub_op;
	BindAST<AST::MultiplyExpression> mul = CalculatorGrammar::get().mul_op;
	BindAST<AST::DivideExpression> div = CalculatorGrammar::get().div_op;
	public:
	const CalculatorGrammar &g = CalculatorGrammar::get();
};

}

int main()
{
	Parser::CalculatorParser p;
	for (;;)
	{
		string s;

		cout << "enter a math expression (+ - * /, floats, parentheses) or enter to exit:\n";
		getline(cin, s);
		if (s.empty()) break;

		//convert the string to input
		StringInput i(std::move(s));

		//parse
		ErrorReporter er = [](const InputRange &ir, const std::string &s)
		{
			cout << "line " << ir.start.line << ", col " << ir.finish.col << ": " << s;
		};
		unique_ptr<AST::Expression> root = 0;
		p.parse(i, p.g.expr, p.g.ws, er, root);

		//on success
		if (root)
		{
			double v = root->eval();
			cout << "success\n";
			cout << "result = " << v << endl;
			cout << "parse tree:\n";
			root->print(0);
		}

		//next input
		cout << endl;
	}
	return 0;
}
<|endoftext|>


<commit_before>/******************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2016-2018 Baldur Karlsson
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 ******************************************************************************/

#include "hooks/hooks.h"

#include <dlfcn.h>
#include <stddef.h>

void LibraryHooks::BeginHookRegistration()
{
  // nothing to do
}

void LibraryHooks::RegisterLibraryHook(char const *, FunctionLoadCallback cb)
{
  if(cb)
    RDCERR("Hooking on apple not complete - function load callback not implemented");
}

void LibraryHooks::IgnoreLibrary(const char *libraryName)
{
}

void LibraryHooks::EndHookRegistration()
{
}

bool LibraryHooks::Detect(const char *identifier)
{
  return dlsym(RTLD_DEFAULT, identifier) != NULL;
}

void LibraryHooks::RemoveHooks()
{
  RDCERR("Removing hooks is not possible on this platform");
}

// android only hooking functions, not used on apple
ScopedSuppressHooking::ScopedSuppressHooking()
{
}

ScopedSuppressHooking::~ScopedSuppressHooking()
{
}

void LibraryHooks::Refresh()
{
}<commit_msg>Implement missing stub on apple<commit_after>/******************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2016-2018 Baldur Karlsson
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 ******************************************************************************/

#include "hooks/hooks.h"

#include <dlfcn.h>
#include <stddef.h>

void LibraryHooks::BeginHookRegistration()
{
  // nothing to do
}

void LibraryHooks::RegisterFunctionHook(const char *libraryName, const FunctionHook &hook)
{
}

void LibraryHooks::RegisterLibraryHook(char const *, FunctionLoadCallback cb)
{
  if(cb)
    RDCERR("Hooking on apple not complete - function load callback not implemented");
}

void LibraryHooks::IgnoreLibrary(const char *libraryName)
{
}

void LibraryHooks::EndHookRegistration()
{
}

bool LibraryHooks::Detect(const char *identifier)
{
  return dlsym(RTLD_DEFAULT, identifier) != NULL;
}

void LibraryHooks::RemoveHooks()
{
  RDCERR("Removing hooks is not possible on this platform");
}

// android only hooking functions, not used on apple
ScopedSuppressHooking::ScopedSuppressHooking()
{
}

ScopedSuppressHooking::~ScopedSuppressHooking()
{
}

void LibraryHooks::Refresh()
{
}<|endoftext|>


<commit_before>
#include "floor_nav/SimTasksEnv.h"
#include <topic_tools/MuxSelect.h>
#include <boost/algorithm/string.hpp>

using namespace floor_nav;

SimTasksEnv::SimTasksEnv(ros::NodeHandle & n) : task_manager_lib::TaskEnvironment(n),
    paused(false), manualControl(true), joystick_topic("/teleop/twistCommand"), auto_topic("/mux/autoCommand"), base_frame("/bubbleRob"), reference_frame("/world")
{
    nh.getParam("joystick_topic",joystick_topic);
    nh.getParam("auto_topic",auto_topic);
    nh.getParam("base_frame",base_frame);
    nh.getParam("reference_frame",reference_frame);

    muxClient = nh.serviceClient<topic_tools::MuxSelect>("/mux/select");

    muxSub = nh.subscribe("/mux/selected",1,&SimTasksEnv::muxCallback,this);
    pointCloudSub = nh.subscribe("/vrep/depthSensor",1,&SimTasksEnv::pointCloudCallback,this);
    pointCloud2DSub = nh.subscribe("/vrep/hokuyoSensor",1,&SimTasksEnv::pointCloud2DCallback,this);
    laserscanSub = nh.subscribe("/scan",1,&SimTasksEnv::laserScanCallback,this);
    velPub = nh.advertise<geometry_msgs::Twist>(auto_topic,1);
}

void SimTasksEnv::setManualControl()
{
    topic_tools::MuxSelect select;
    select.request.topic = joystick_topic;
    if (!muxClient.call(select)) {
        ROS_ERROR("setManualControl: Failed to call service /mux/select");
    }
}

void SimTasksEnv::setComputerControl()
{
    topic_tools::MuxSelect select;
    select.request.topic = auto_topic;
    if (!muxClient.call(select)) {
        ROS_ERROR("setComputerControl: Failed to call service /mux/select");
    }
}

geometry_msgs::Pose2D SimTasksEnv::getPose2D() const {
    geometry_msgs::Pose2D pose;
    tf::StampedTransform transform;
    try{
        listener.lookupTransform(reference_frame,base_frame,
                ros::Time(0), transform);
    }
    catch (tf::TransformException ex){
        ROS_ERROR("%s",ex.what());
    }
    pose.theta = tf::getYaw(transform.getRotation());
    pose.x = transform.getOrigin().x();
    pose.y = transform.getOrigin().y();
    return pose;
}

geometry_msgs::Pose SimTasksEnv::getPose() const {
    geometry_msgs::Pose pose;
    tf::StampedTransform transform;
    try{
        listener.lookupTransform(reference_frame,base_frame,
                ros::Time(0), transform);
    }
    catch (tf::TransformException ex){
        ROS_ERROR("%s",ex.what());
    }
    tf::quaternionTFToMsg(transform.getRotation(),pose.orientation);
    tf::pointTFToMsg(transform.getOrigin(),pose.position);
    return pose;
}

geometry_msgs::PoseStamped SimTasksEnv::getPoseStamped() const {
    geometry_msgs::PoseStamped pose;
    tf::StampedTransform transform;
    try{
        listener.lookupTransform(reference_frame,base_frame,
                ros::Time(0), transform);
    }
    catch (tf::TransformException ex){
        ROS_ERROR("%s",ex.what());
    }
    tf::quaternionTFToMsg(transform.getRotation(),pose.pose.orientation);
    tf::pointTFToMsg(transform.getOrigin(),pose.pose.position);
    pose.header.stamp = transform.stamp_;
    return pose;
}

void SimTasksEnv::publishVelocity(double linear, double angular) {
    geometry_msgs::Twist cmd;
    if (paused) {
        cmd.linear.x = 0.;
        cmd.angular.z = 0.;
    } else {
        cmd.linear.x = linear;
        cmd.angular.z = angular;
    }
    velPub.publish(cmd);
}

void SimTasksEnv::muxCallback(const std_msgs::String::ConstPtr& msg) {
    if (msg->data == joystick_topic) {
        manualControl = true;
    } else if (msg->data == auto_topic) {
        manualControl = false;
    } else {
        ROS_ERROR("Received unknown mux selection: '%s'",msg->data.c_str());
    }
}

void SimTasksEnv::pointCloudCallback(const sensor_msgs::PointCloud2ConstPtr msg) {
    pcl::fromROSMsg(*msg, pointCloud);
}

void SimTasksEnv::pointCloud2DCallback(const sensor_msgs::PointCloud2ConstPtr msg) {
    pcl::fromROSMsg(*msg, pointCloud2D);
}

void SimTasksEnv::laserScanCallback(const sensor_msgs::LaserScanConstPtr msg) {
    pointCloud2D.resize(msg->ranges.size());
    for (size_t i=0;i<msg->ranges.size();i++) {
        pointCloud2D[i].x = msg->ranges[i]*cos(msg->angle_min + i*msg->angle_increment);
        pointCloud2D[i].y = msg->ranges[i]*sin(msg->angle_min + i*msg->angle_increment);
    }
}

<commit_msg>Added additional pubvel commands<commit_after>
#include "floor_nav/SimTasksEnv.h"
#include <topic_tools/MuxSelect.h>
#include <boost/algorithm/string.hpp>

using namespace floor_nav;

SimTasksEnv::SimTasksEnv(ros::NodeHandle & n) : task_manager_lib::TaskEnvironment(n),
    paused(false), manualControl(true), joystick_topic("/teleop/twistCommand"), auto_topic("/mux/autoCommand"), base_frame("/bubbleRob"), reference_frame("/world")
{
    nh.getParam("joystick_topic",joystick_topic);
    nh.getParam("auto_topic",auto_topic);
    nh.getParam("base_frame",base_frame);
    nh.getParam("reference_frame",reference_frame);

    muxClient = nh.serviceClient<topic_tools::MuxSelect>("/mux/select");

    muxSub = nh.subscribe("/mux/selected",1,&SimTasksEnv::muxCallback,this);
    pointCloudSub = nh.subscribe("/vrep/depthSensor",1,&SimTasksEnv::pointCloudCallback,this);
    pointCloud2DSub = nh.subscribe("/vrep/hokuyoSensor",1,&SimTasksEnv::pointCloud2DCallback,this);
    laserscanSub = nh.subscribe("/scan",1,&SimTasksEnv::laserScanCallback,this);
    velPub = nh.advertise<geometry_msgs::Twist>(auto_topic,1);
}

void SimTasksEnv::setManualControl()
{
    topic_tools::MuxSelect select;
    select.request.topic = joystick_topic;
    if (!muxClient.call(select)) {
        ROS_ERROR("setManualControl: Failed to call service /mux/select");
    }
}

void SimTasksEnv::setComputerControl()
{
    topic_tools::MuxSelect select;
    select.request.topic = auto_topic;
    if (!muxClient.call(select)) {
        ROS_ERROR("setComputerControl: Failed to call service /mux/select");
    }
}

geometry_msgs::Pose2D SimTasksEnv::getPose2D() const {
    geometry_msgs::Pose2D pose;
    tf::StampedTransform transform;
    try{
        listener.lookupTransform(reference_frame,base_frame,
                ros::Time(0), transform);
    }
    catch (tf::TransformException ex){
        ROS_ERROR("%s",ex.what());
    }
    pose.theta = tf::getYaw(transform.getRotation());
    pose.x = transform.getOrigin().x();
    pose.y = transform.getOrigin().y();
    return pose;
}

geometry_msgs::Pose SimTasksEnv::getPose() const {
    geometry_msgs::Pose pose;
    tf::StampedTransform transform;
    try{
        listener.lookupTransform(reference_frame,base_frame,
                ros::Time(0), transform);
    }
    catch (tf::TransformException ex){
        ROS_ERROR("%s",ex.what());
    }
    tf::quaternionTFToMsg(transform.getRotation(),pose.orientation);
    tf::pointTFToMsg(transform.getOrigin(),pose.position);
    return pose;
}

geometry_msgs::PoseStamped SimTasksEnv::getPoseStamped() const {
    geometry_msgs::PoseStamped pose;
    tf::StampedTransform transform;
    try{
        listener.lookupTransform(reference_frame,base_frame,
                ros::Time(0), transform);
    }
    catch (tf::TransformException ex){
        ROS_ERROR("%s",ex.what());
    }
    tf::quaternionTFToMsg(transform.getRotation(),pose.pose.orientation);
    tf::pointTFToMsg(transform.getOrigin(),pose.pose.position);
    pose.header.stamp = transform.stamp_;
    return pose;
}

void SimTasksEnv::publishVelocity(double linear, double angular) {
    geometry_msgs::Twist cmd;
    if (paused) {
        cmd.linear.x = 0.;
        cmd.angular.z = 0.;
    } else {
        cmd.linear.x = linear;
        cmd.angular.z = angular;
    }
    velPub.publish(cmd);
}

void SimTasksEnv::publishVelocity(double linear_x, double linear_y, double angular) {
    geometry_msgs::Twist cmd;
    if (paused) {
        cmd.linear.x = 0.;
        cmd.linear.y = 0.;
        cmd.angular.z = 0.;
    } else {
        cmd.linear.x = linear_x;
        cmd.linear.y = linear_y;
        cmd.angular.z = angular;
    }
    velPub.publish(cmd);
}

void SimTasksEnv::publishVelocity(const geometry_msgs::Twist & twist) {
    geometry_msgs::Twist cmd;
    if (paused) {
        cmd.linear.x = 0.;
        cmd.linear.y = 0.;
        cmd.angular.z = 0.;
    } else {
        cmd = twist;
    }
    velPub.publish(cmd);
}

void SimTasksEnv::muxCallback(const std_msgs::String::ConstPtr& msg) {
    if (msg->data == joystick_topic) {
        manualControl = true;
    } else if (msg->data == auto_topic) {
        manualControl = false;
    } else {
        ROS_ERROR("Received unknown mux selection: '%s'",msg->data.c_str());
    }
}

void SimTasksEnv::pointCloudCallback(const sensor_msgs::PointCloud2ConstPtr msg) {
    pcl::fromROSMsg(*msg, pointCloud);
}

void SimTasksEnv::pointCloud2DCallback(const sensor_msgs::PointCloud2ConstPtr msg) {
    pcl::fromROSMsg(*msg, pointCloud2D);
}

void SimTasksEnv::laserScanCallback(const sensor_msgs::LaserScanConstPtr msg) {
    pointCloud2D.resize(msg->ranges.size());
    for (size_t i=0;i<msg->ranges.size();i++) {
        pointCloud2D[i].x = msg->ranges[i]*cos(msg->angle_min + i*msg->angle_increment);
        pointCloud2D[i].y = msg->ranges[i]*sin(msg->angle_min + i*msg->angle_increment);
    }
}

<|endoftext|>


<commit_before>#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <getopt.h>
#include <atomic>
#include <signal.h>
#include <unistd.h>
#include <limits>

#include <zcm/zcm-cpp.hpp>

#include "zcm/json/json.h"

#include "util/TimeUtil.hpp"

using namespace std;

static atomic_int done {0};

static void usage(char * cmd)
{
    cerr << "usage: zcm-logplayer [options] [FILE]" << endl
         << "" << endl
         << "    Reads packets from an ZCM log file and publishes them to a " << endl
         << "    ZCM transport." << endl
         << "" << endl
         << "Options:" << endl
         << "" << endl
         << "  -s, --speed=NUM        Playback speed multiplier.  Default is 1." << endl
         << "  -u, --zcm-url=URL      Play logged messages on the specified ZCM URL." << endl
         << "  -o, --output=filename  Instead of broadcasting over zcm, log directly " << endl
         << "                         to a file. Enabling this, ignores the" << endl
         << "                         \"--speed\" option" << endl
         << "  -j, --jslp=filename    Use this jslp meta file. " << endl
         << "                         If unspecified, zcm-logplayer looks for a file " << endl
         << "                         with the same filename as the input log and " << endl
         << "                         a .jslp suffix" << endl
         << "  -v, --verbose          Print information about each packet." << endl
         << "  -h, --help             Shows some help text and exits." << endl
         << endl;
}

static void sighandler(int signal)
{
    done++;
    if (done == 3) exit(1);
}

struct Args
{
    double speed = 1.0;
    bool verbose = false;
    string zcmUrlOut = "";
    string filename = "";
    string jslpFilename = "";
    zcm::Json::Value jslpRoot;
    string outfile = "";

    bool init(int argc, char *argv[])
    {
        struct option long_opts[] = {
            { "help",          no_argument, 0, 'h' },
            { "output",  required_argument, 0, 'o' },
            { "speed",   required_argument, 0, 's' },
            { "zcm-url", required_argument, 0, 'u' },
            { "jslp",    required_argument, 0, 'j' },
            { "verbose",       no_argument, 0, 'v' },
            { 0, 0, 0, 0 }
        };

        int c;
        while ((c = getopt_long(argc, argv, "ho:s:u:j:v", long_opts, 0)) >= 0) {
            switch (c) {
                case 'o':      outfile = string(optarg);       break;
                case 's':        speed = strtod(optarg, NULL); break;
                case 'u':    zcmUrlOut = string(optarg);       break;
                case 'j': jslpFilename = string(optarg);       break;
                case 'v':      verbose = true;                 break;
                case 'h': usage(argv[0]); return true;
                default:  usage(argv[0]); return false;
            };
        }

        if (optind != argc - 1) {
            cerr << "Please specify a logfile" << endl;
            usage(argv[0]);
            return false;
        }

        filename = string(argv[optind]);

        ifstream jslpFile { jslpFilename == "" ? filename + ".jslp" : "" };
        if (jslpFile.good()) {
            zcm::Json::Reader reader;
            if (!reader.parse(jslpFile, jslpRoot, false)) {
                if (verbose) {
                    cerr << "Failed to parse jslp file " << endl;
                    cerr << reader.getFormattedErrorMessages() << endl;
                    return false;
                }
            }
            if (outfile != "") speed = 0;
            cerr << "Found jslp file. Filtering output." << endl;
        } else if (jslpFilename == "") {
            cerr << "No jslp file specified" << endl;
            if (outfile != "") {
                cerr << "Output file specified, but no jslp filter metafile found." << endl;
                return false;
            }
        } else {
            cerr << "Unable to find specified jslp file: " << jslpFilename << endl;
            return false;
        }

        if (speed == 0) speed = std::numeric_limits<decltype(speed)>::infinity();

        return true;
    }
};

struct LogPlayer
{
    Args args;
    zcm::LogFile *zcmIn  = nullptr;
    zcm::ZCM     *zcmOut = nullptr;
    zcm::LogFile *logOut = nullptr;

    string startMode = "";
    string startChan = "";
    uint64_t startDelayUs = 0;

    LogPlayer() { }

    ~LogPlayer()
    {
        if (logOut) { logOut->close(); delete logOut; }
        if (zcmIn)  { delete zcmIn;                   }
        if (zcmOut) { delete zcmOut;                  }
    }

    bool init(int argc, char *argv[])
    {
        if (!args.init(argc, argv))
            return false;

        zcmIn = new zcm::LogFile(args.filename, "r");
        if (!zcmIn->good()) {
            cerr << "Error: Failed to open '" << args.filename << "'" << endl;
            return false;
        }

        if (args.outfile == "") {
            zcmOut = new zcm::ZCM(args.zcmUrlOut);
            if (!zcmOut->good()) {
                cerr << "Error: Failed to create output ZCM" << endl;
                return false;
            }

            cout << "Using playback speed " << args.speed << endl;
        } else {
            logOut = new zcm::LogFile(args.outfile, "w");
            if (!logOut->good()) {
                cerr << "Error: Failed to create output log" << endl;
                return false;
            }
        }

        if (args.jslpRoot.isMember("START")) {
            if (!args.jslpRoot["START"].isMember("mode")) {
                cerr << "Start mode unspecified in jslp" << endl;
                return false;
            }
            startMode = args.jslpRoot["START"]["mode"].asString();
            if (startMode == "channel") {
                if (!args.jslpRoot["START"].isMember("channel")) {
                    cerr << "Start channel unspecified in jslp" << endl;
                    return false;
                }
                startChan = args.jslpRoot["START"]["channel"].asString();
            } else if (startMode == "us_delay") {
                if (!args.jslpRoot["START"].isMember("us")) {
                    cerr << "Start channel unspecified in jslp" << endl;
                    return false;
                }
                startDelayUs = args.jslpRoot["START"]["us"].asUInt64();
            } else {
                cerr << "Start mode unrecognized in jslp: " << startMode << endl;
                return false;
            }
        }

        return true;
    }

    void run()
    {
        uint64_t firstMsgUtime = UINT64_MAX;
        uint64_t lastMsgUtime = 0;
        uint64_t lastDispatchUtime = 0;
        bool startedPub = false;

        if (startMode == "") startedPub = true;

        while (!done) {
            const zcm::LogEvent* le = zcmIn->readNextEvent();
            if (!le) {
                done = true;
                continue;
            }

            uint64_t now = TimeUtil::utime();

            if (lastMsgUtime == 0)
                lastMsgUtime = le->timestamp;

            if (lastDispatchUtime == 0)
                lastDispatchUtime = now;

            if (firstMsgUtime == UINT64_MAX)
                firstMsgUtime = (uint64_t) le->timestamp;

            uint64_t localDiff = now - lastDispatchUtime;
            uint64_t logDiff = (uint64_t) le->timestamp - lastMsgUtime;
            uint64_t logDiffSpeed = logDiff / args.speed;
            uint64_t diff = logDiffSpeed > localDiff ? logDiffSpeed - localDiff
                                                     : 0;
            // TODO: this doesn't reproduce the input frequency perfectly but that is likely
            //       due to the difficulty of accurately timing events with the OS scheduler
            //       active. If it becomes an issue in the future, we could devote more time
            //       to improving the loop timing accuracy.
            //       Note that this inaccuracy does not apply if you are filting a log into
            //       a different log via a jslp file because the log times are preserved.
            //       Possible resource: http://www.tldp.org/HOWTO/IO-Port-Programming-4.html
            timespec delay;
            delay.tv_sec = (long int) diff / 1000000;
            delay.tv_nsec = (long int) (diff - (delay.tv_sec * 1000000)) * 1000;
            if (diff > 3) nanosleep(&delay, nullptr);

            if (startedPub == false) {
                if (startMode == "channel") {
                    if (le->channel == startChan)
                        startedPub = true;
                } else if (startMode == "us_delay") {
                    if ((uint64_t) le->timestamp > firstMsgUtime + startDelayUs)
                        startedPub = true;
                }
            }

            auto publish = [&](){
                if (args.verbose)
                    printf("%.3f Channel %-20s size %d\n", le->timestamp / 1e6,
                           le->channel.c_str(), le->datalen);

                if (args.outfile == "")
                    zcmOut->publish(le->channel, le->data, le->datalen);
                else
                    logOut->writeEvent(le);
            };

            if (startedPub) {
                if (args.jslpRoot.empty()) {
                    publish();
                } else if (args.jslpRoot.isMember("FILTER")) {
                    // RRR: some of these checks only need to be performed once,
                    //      not for every event. Maybe you could do the checks first
                    //      and form a different publish lambda function or something
                    //      (or maybe dump the information into a class / map that is more
                    //      efficient to dig through).
                    // RRR (Bendes) Why is this inefficient?
                    if (!args.jslpRoot["FILTER"].isMember("type")) {
                        cerr << "Filter \"type\" in jslp file unspecified" << endl;
                        done = true;
                        continue;
                    }
                    if (!args.jslpRoot["FILTER"].isMember("mode")) {
                        cerr << "Filter \"mode\" in jslp file unspecified" << endl;
                        done = true;
                        continue;
                    }

                    if (args.jslpRoot["FILTER"]["type"] == "channels") {
                        if (args.jslpRoot["FILTER"]["mode"] == "whitelist") {
                            if (args.jslpRoot["FILTER"]["channels"].isArray()) {
                                for (auto val : args.jslpRoot["FILTER"]["channels"])
                                    if (val == le->channel) publish();
                            } else if (args.jslpRoot["FILTER"]["channels"].isMember(le->channel))
                                publish();
                        } else if (args.jslpRoot["FILTER"]["mode"] == "blacklist") {
                            if (args.jslpRoot["FILTER"]["channels"].isArray()) {
                                bool found = false;
                                for (auto val : args.jslpRoot["FILTER"]["channels"])
                                    if (val == le->channel) found = true;
                                if (found == false) publish();
                            } else if (!args.jslpRoot["FILTER"]["channels"].isMember(le->channel))
                                publish();
                        } else if (args.jslpRoot["FILTER"]["mode"] == "specified") {
                            if (!args.jslpRoot["FILTER"]["channels"].isMember(le->channel)) {
                                cerr << "jslp file does not specify filtering behavior "
                                     << "for channel: " << le->channel << endl;
                                // RRR: not the only instance of this, but it would be
                                //      to have alternate return values for errors
                                //                                                     ^ nice?
                                // RRR (Bendes) Why? This is just exiting zcm-logplayer
                                done = true;
                                continue;
                            }
                            if (args.jslpRoot["FILTER"]["channels"][le->channel] == true)
                                publish();
                        } else {
                            cerr << "Filter \"mode\" unrecognized: "
                                 << args.jslpRoot["FILTER"]["mode"] << endl;
                            done = true;
                            continue;
                        }
                    } else {
                        cerr << "Filter \"type\" unrecognized: "
                             << args.jslpRoot["FILTER"]["type"] << endl;
                        done = true;
                        continue;
                    }
                }
            }

            lastDispatchUtime = TimeUtil::utime();
            lastMsgUtime = le->timestamp;
        }
    }
};

int main(int argc, char* argv[])
{
    LogPlayer lp;
    if (!lp.init(argc, argv)) return 1;

    // Register signal handlers
    signal(SIGINT, sighandler);
    signal(SIGQUIT, sighandler);
    signal(SIGTERM, sighandler);

    lp.run();

    cout << "zcm-logplayer done" << endl;

    return 0;
}
<commit_msg>Addressed review comments<commit_after>#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <getopt.h>
#include <atomic>
#include <signal.h>
#include <unistd.h>
#include <limits>
#include <unordered_map>

#include <zcm/zcm-cpp.hpp>

#include "zcm/json/json.h"

#include "util/TimeUtil.hpp"

using namespace std;

static atomic_int done {0};

static void usage(char * cmd)
{
    cerr << "usage: zcm-logplayer [options] [FILE]" << endl
         << "" << endl
         << "    Reads packets from an ZCM log file and publishes them to a " << endl
         << "    ZCM transport." << endl
         << "" << endl
         << "Options:" << endl
         << "" << endl
         << "  -s, --speed=NUM        Playback speed multiplier.  Default is 1." << endl
         << "  -u, --zcm-url=URL      Play logged messages on the specified ZCM URL." << endl
         << "  -o, --output=filename  Instead of broadcasting over zcm, log directly " << endl
         << "                         to a file. Enabling this, ignores the" << endl
         << "                         \"--speed\" option" << endl
         << "  -j, --jslp=filename    Use this jslp meta file. " << endl
         << "                         If unspecified, zcm-logplayer looks for a file " << endl
         << "                         with the same filename as the input log and " << endl
         << "                         a .jslp suffix" << endl
         << "  -v, --verbose          Print information about each packet." << endl
         << "  -h, --help             Shows some help text and exits." << endl
         << endl;
}

static void sighandler(int signal)
{
    done++;
    if (done == 3) exit(1);
}

struct Args
{
    double speed = 1.0;
    bool verbose = false;
    string zcmUrlOut = "";
    string filename = "";
    string jslpFilename = "";
    zcm::Json::Value jslpRoot;
    string outfile = "";

    bool init(int argc, char *argv[])
    {
        struct option long_opts[] = {
            { "help",          no_argument, 0, 'h' },
            { "output",  required_argument, 0, 'o' },
            { "speed",   required_argument, 0, 's' },
            { "zcm-url", required_argument, 0, 'u' },
            { "jslp",    required_argument, 0, 'j' },
            { "verbose",       no_argument, 0, 'v' },
            { 0, 0, 0, 0 }
        };

        int c;
        while ((c = getopt_long(argc, argv, "ho:s:u:j:v", long_opts, 0)) >= 0) {
            switch (c) {
                case 'o':      outfile = string(optarg);       break;
                case 's':        speed = strtod(optarg, NULL); break;
                case 'u':    zcmUrlOut = string(optarg);       break;
                case 'j': jslpFilename = string(optarg);       break;
                case 'v':      verbose = true;                 break;
                case 'h': usage(argv[0]); return true;
                default:  usage(argv[0]); return false;
            };
        }

        if (optind != argc - 1) {
            cerr << "Please specify a logfile" << endl;
            usage(argv[0]);
            return false;
        }

        filename = string(argv[optind]);

        ifstream jslpFile { jslpFilename == "" ? filename + ".jslp" : "" };
        if (jslpFile.good()) {
            zcm::Json::Reader reader;
            if (!reader.parse(jslpFile, jslpRoot, false)) {
                if (verbose) {
                    cerr << "Failed to parse jslp file " << endl;
                    cerr << reader.getFormattedErrorMessages() << endl;
                    return false;
                }
            }
            if (outfile != "") speed = 0;
            cerr << "Found jslp file. Filtering output." << endl;
        } else if (jslpFilename == "") {
            cerr << "No jslp file specified" << endl;
            if (outfile != "") {
                cerr << "Output file specified, but no jslp filter metafile found." << endl;
                return false;
            }
        } else {
            cerr << "Unable to find specified jslp file: " << jslpFilename << endl;
            return false;
        }

        if (speed == 0) speed = std::numeric_limits<decltype(speed)>::infinity();

        return true;
    }
};

struct LogPlayer
{
    Args args;
    zcm::LogFile *zcmIn  = nullptr;
    zcm::ZCM     *zcmOut = nullptr;
    zcm::LogFile *logOut = nullptr;

    string startMode = "";
    string startChan = "";
    uint64_t startDelayUs = 0;

    bool filtering;

    enum class FilterType { CHANNELS, NUM_TYPES };
    FilterType filterType;

    enum class FilterMode { WHITELIST, BLACKLIST, SPECIFIED, NUM_MODES };
    FilterMode filterMode;

    unordered_map<string, bool> channelMap;

    LogPlayer() { }

    ~LogPlayer()
    {
        if (logOut) { logOut->close(); delete logOut; }
        if (zcmIn)  { delete zcmIn;                   }
        if (zcmOut) { delete zcmOut;                  }
    }

    bool init(int argc, char *argv[])
    {
        if (!args.init(argc, argv))
            return false;

        zcmIn = new zcm::LogFile(args.filename, "r");
        if (!zcmIn->good()) {
            cerr << "Error: Failed to open '" << args.filename << "'" << endl;
            return false;
        }

        if (args.outfile == "") {
            zcmOut = new zcm::ZCM(args.zcmUrlOut);
            if (!zcmOut->good()) {
                cerr << "Error: Failed to create output ZCM" << endl;
                return false;
            }

            cout << "Using playback speed " << args.speed << endl;
        } else {
            logOut = new zcm::LogFile(args.outfile, "w");
            if (!logOut->good()) {
                cerr << "Error: Failed to create output log" << endl;
                return false;
            }
        }

        if (args.jslpRoot.isMember("START")) {
            if (!args.jslpRoot["START"].isMember("mode")) {
                cerr << "Start mode unspecified in jslp" << endl;
                return false;
            }
            startMode = args.jslpRoot["START"]["mode"].asString();
            if (startMode == "channel") {
                if (!args.jslpRoot["START"].isMember("channel")) {
                    cerr << "Start channel unspecified in jslp" << endl;
                    return false;
                }
                startChan = args.jslpRoot["START"]["channel"].asString();
            } else if (startMode == "us_delay") {
                if (!args.jslpRoot["START"].isMember("us")) {
                    cerr << "Start channel unspecified in jslp" << endl;
                    return false;
                }
                startDelayUs = args.jslpRoot["START"]["us"].asUInt64();
            } else {
                cerr << "Start mode unrecognized in jslp: " << startMode << endl;
                return false;
            }
        }

        filtering = args.jslpRoot.isMember("FILTER");
        if (filtering) {
            if (!args.jslpRoot["FILTER"].isMember("type")) {
                cerr << "Filter \"type\" in jslp file unspecified" << endl;
                return false;
            }
            if (!args.jslpRoot["FILTER"].isMember("mode")) {
                cerr << "Filter \"mode\" in jslp file unspecified" << endl;
                return false;
            }
        }

        if (args.jslpRoot["FILTER"]["type"] == "channels") {
            filterType = FilterType::CHANNELS;
        } else {
            cerr << "Filter \"mode\" unrecognized: "
                 << args.jslpRoot["FILTER"]["mode"] << endl;
            return false;
        }

        if (args.jslpRoot["FILTER"]["mode"] == "whitelist") {
            filterMode = FilterMode::WHITELIST;
        } else if (args.jslpRoot["FILTER"]["mode"] == "blacklist") {
            filterMode = FilterMode::BLACKLIST;
        } else if (args.jslpRoot["FILTER"]["mode"] == "specified") {
            filterMode = FilterMode::SPECIFIED;
        } else {
            cerr << "Filter \"type\" unrecognized: "
                 << args.jslpRoot["FILTER"]["type"] << endl;
            return false;
        }

        for (auto val : args.jslpRoot["FILTER"]["channels"]) {
            if (filterMode == FilterMode::SPECIFIED)
                channelMap[val.asString()] =
                    args.jslpRoot["FILTER"]["channels"][val.asString()].asBool();
            else
                channelMap[val.asString()] = true;
        }

        return true;
    }

    int run()
    {
        int err = 0;

        uint64_t firstMsgUtime = UINT64_MAX;
        uint64_t lastMsgUtime = 0;
        uint64_t lastDispatchUtime = 0;
        bool startedPub = false;

        if (startMode == "") startedPub = true;

        while (!done) {
            const zcm::LogEvent* le = zcmIn->readNextEvent();
            if (!le) {
                done = true;
                continue;
            }

            uint64_t now = TimeUtil::utime();

            if (lastMsgUtime == 0)
                lastMsgUtime = le->timestamp;

            if (lastDispatchUtime == 0)
                lastDispatchUtime = now;

            if (firstMsgUtime == UINT64_MAX)
                firstMsgUtime = (uint64_t) le->timestamp;

            uint64_t localDiff = now - lastDispatchUtime;
            uint64_t logDiff = (uint64_t) le->timestamp - lastMsgUtime;
            uint64_t logDiffSpeed = logDiff / args.speed;
            uint64_t diff = logDiffSpeed > localDiff ? logDiffSpeed - localDiff
                                                     : 0;
            // TODO: this doesn't reproduce the input frequency perfectly but that is likely
            //       due to the difficulty of accurately timing events with the OS scheduler
            //       active. If it becomes an issue in the future, we could devote more time
            //       to improving the loop timing accuracy.
            //       Note that this inaccuracy does not apply if you are filting a log into
            //       a different log via a jslp file because the log times are preserved.
            //       Possible resource: http://www.tldp.org/HOWTO/IO-Port-Programming-4.html
            timespec delay;
            delay.tv_sec = (long int) diff / 1000000;
            delay.tv_nsec = (long int) (diff - (delay.tv_sec * 1000000)) * 1000;
            if (diff > 3) nanosleep(&delay, nullptr);

            if (startedPub == false) {
                if (startMode == "channel") {
                    if (le->channel == startChan)
                        startedPub = true;
                } else if (startMode == "us_delay") {
                    if ((uint64_t) le->timestamp > firstMsgUtime + startDelayUs)
                        startedPub = true;
                }
            }

            auto publish = [&](){
                if (args.verbose)
                    printf("%.3f Channel %-20s size %d\n", le->timestamp / 1e6,
                           le->channel.c_str(), le->datalen);

                if (args.outfile == "")
                    zcmOut->publish(le->channel, le->data, le->datalen);
                else
                    logOut->writeEvent(le);
            };

            if (startedPub) {
                if (!filtering) {
                    publish();
                } else {
                    if (filterType == FilterType::CHANNELS) {
                        if (filterMode == FilterMode::WHITELIST) {
                            if (channelMap.count(le->channel) > 0) publish();
                        } else if (filterMode == FilterMode::BLACKLIST) {
                            if (channelMap.count(le->channel) == 0) publish();
                        } else if (filterMode == FilterMode::SPECIFIED) {
                            if (channelMap.count(le->channel) == 0) {
                                cerr << "jslp file does not specify filtering behavior "
                                     << "for channel: " << le->channel << endl;
                                done = true;
                                err = 1;
                                continue;
                            }
                            if (channelMap[le->channel]) publish();
                        } else {
                            assert(false && "Fatal error.");
                        }
                    } else {
                        assert(false && "Fatal error.");
                    }
                }
            }

            lastDispatchUtime = TimeUtil::utime();
            lastMsgUtime = le->timestamp;
        }

        return err;
    }
};

int main(int argc, char* argv[])
{
    LogPlayer lp;
    if (!lp.init(argc, argv)) return 1;

    // Register signal handlers
    signal(SIGINT, sighandler);
    signal(SIGQUIT, sighandler);
    signal(SIGTERM, sighandler);

    int ret = lp.run();

    cout << "zcm-logplayer done" << endl;

    return ret;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <fstream>

template <class iter>
void descend_sort(iter beg, iter end)
{
    std::sort(beg,end,std::greater<int>());
}

template <class iter>
void ascend_sort(iter beg, iter end)
{
    std::sort(beg,end);
}

template <class container>
long long int findSmallestScalerProduct(container x, container y)
{
    long long int zero = 0;

    if(x.size() != y.size())
    {
        std::cout << "Containers Are Not Same Length!\n";
        throw -1;
    }

    ascend_sort(x.begin(),x.end());
    descend_sort(y.begin(),y.end());

    return std::inner_product(x.begin(),x.end(),y.begin(),zero);
}

int main()
{
    std::ofstream outputfile("outputScalar.txt");
    std::vector<long long int> vec1, vec2;
    std::string fileName;
    int cases = 0;
    int cnt = 1;
    int vecLength = 0;
    long long int numb = 0;

    std::cout << "Enter Input File Name: ";
    getline(std::cin,fileName);

    std::ifstream streamIn;
    streamIn.open(fileName);

    if(!streamIn)
    {
        std::cout << "Error Opening File.\n";
        return -1;
    }

    streamIn >> cases;
    streamIn.ignore();

    while(!streamIn.fail() && cnt != cases+1)
    {
        streamIn >> vecLength;
        streamIn.ignore();
        for(int i = 0; i < vecLength; ++i)
        {
            streamIn >> numb;
            vec1.push_back(numb);
        }
        streamIn.ignore();
        for(int i = 0; i < vecLength; ++i)
        {
            streamIn >> numb;
            vec2.push_back(numb);
        }
        outputfile << "Case #" << cnt << ": " << findSmallestScalerProduct(vec1,vec2) << "\n";
        vec1.clear();
        vec2.clear();
        streamIn.ignore();
        ++cnt;
    }

    return 0;
}
<commit_msg>Update minimum_scalar_product.cpp<commit_after>#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <fstream>

template <class iter>
void descend_sort(iter beg, iter end)
{
    std::sort(beg,end,std::greater<int>());
}

template <class iter>
void ascend_sort(iter beg, iter end)
{
    std::sort(beg,end);
}

template <class container>
long long int findSmallestScalarProduct(container x, container y)
{
    long long int zero = 0;

    if(x.size() != y.size())
    {
        std::cout << "Containers Are Not Same Length!\n";
        throw -1;
    }

    ascend_sort(x.begin(),x.end());
    descend_sort(y.begin(),y.end());

    return std::inner_product(x.begin(),x.end(),y.begin(),zero);
}

int main()
{
    std::ofstream outputfile("outputScalar.txt");
    std::vector<long long int> vec1, vec2;
    std::string fileName;
    int cases = 0;
    int cnt = 1;
    int vecLength = 0;
    long long int numb = 0;

    std::cout << "Enter Input File Name: ";
    getline(std::cin,fileName);

    std::ifstream streamIn;
    streamIn.open(fileName);

    if(!streamIn)
    {
        std::cout << "Error Opening File.\n";
        return -1;
    }

    streamIn >> cases;
    streamIn.ignore();

    while(!streamIn.fail() && cnt != cases+1)
    {
        streamIn >> vecLength;
        streamIn.ignore();
        for(int i = 0; i < vecLength; ++i)
        {
            streamIn >> numb;
            vec1.push_back(numb);
        }
        streamIn.ignore();
        for(int i = 0; i < vecLength; ++i)
        {
            streamIn >> numb;
            vec2.push_back(numb);
        }
        outputfile << "Case #" << cnt << ": " << findSmallestScalerProduct(vec1,vec2) << "\n";
        vec1.clear();
        vec2.clear();
        streamIn.ignore();
        ++cnt;
    }

    return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2021 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/gpu/graphite/ContextUtils.h"

#include <string>
#include "include/private/SkSLString.h"
#include "include/private/SkUniquePaintParamsID.h"
#include "src/core/SkBlenderBase.h"
#include "src/core/SkKeyContext.h"
#include "src/core/SkPipelineData.h"
#include "src/core/SkShaderCodeDictionary.h"
#include "src/gpu/graphite/PaintParams.h"
#include "src/gpu/graphite/RecorderPriv.h"
#include "src/gpu/graphite/Renderer.h"
#include "src/gpu/graphite/ResourceProvider.h"
#include "src/gpu/graphite/UniformManager.h"

namespace skgpu::graphite {

std::tuple<SkUniquePaintParamsID, UniformDataCache::Index, TextureDataCache::Index>
ExtractPaintData(Recorder* recorder,
                 SkPipelineDataGatherer* gatherer,
                 SkPaintParamsKeyBuilder* builder,
                 const SkM44& dev2Local,
                 const PaintParams& p) {

    SkDEBUGCODE(gatherer->checkReset());
    SkDEBUGCODE(builder->checkReset());

    SkKeyContext keyContext(recorder, dev2Local);

    p.toKey(keyContext, builder, gatherer);

    auto dict = recorder->priv().resourceProvider()->shaderCodeDictionary();
    UniformDataCache* uniformDataCache = recorder->priv().uniformDataCache();
    TextureDataCache* textureDataCache = recorder->priv().textureDataCache();

    auto entry = dict->findOrCreate(builder);
    UniformDataCache::Index uniformIndex;
    if (gatherer->hasUniforms()) {
        uniformIndex = uniformDataCache->insert(gatherer->peekUniformData());
    }
    TextureDataCache::Index textureIndex;
    if (gatherer->hasTextures()) {
        textureIndex = textureDataCache->insert(gatherer->textureDataBlock());
    }

    gatherer->reset();

    return { entry->uniqueID(), uniformIndex, textureIndex };
}

std::tuple<UniformDataCache::Index, TextureDataCache::Index>
ExtractRenderStepData(UniformDataCache* geometryUniformDataCache,
                      TextureDataCache* textureDataCache,
                      SkPipelineDataGatherer* gatherer,
                      const RenderStep* step,
                      const DrawParams& params) {
    SkDEBUGCODE(gatherer->checkReset());

    step->writeUniformsAndTextures(params, gatherer);

    UniformDataCache::Index uIndex = geometryUniformDataCache->insert(gatherer->peekUniformData());

    TextureDataCache::Index textureIndex;
    if (step->hasTextures()) {
        textureIndex = textureDataCache->insert(gatherer->textureDataBlock());
    }

    gatherer->reset();

    return { uIndex, textureIndex };
}

namespace {
std::string get_uniform_header(int bufferID, const char* name) {
    std::string result;

    SkSL::String::appendf(&result, "layout (binding=%d) uniform %sUniforms {\n", bufferID, name);

    return result;
}

std::string get_uniforms(SkSpan<const SkUniform> uniforms, int* offset, int manglingSuffix) {
    std::string result;
    UniformOffsetCalculator offsetter(Layout::kMetal, *offset);

    for (const SkUniform& u : uniforms) {
        SkSL::String::appendf(&result, "    layout(offset=%zu) %s %s",
                              offsetter.calculateOffset(u.type(), u.count()),
                              SkSLTypeString(u.type()),
                              u.name());
        if (manglingSuffix >= 0) {
            result.append("_");
            result.append(std::to_string(manglingSuffix));
        }
        if (u.count()) {
            result.append("[");
            result.append(std::to_string(u.count()));
            result.append("]");
        }
        result.append(";\n");
    }

    *offset = offsetter.size();
    return result;
}
}  // anonymous namespace

std::string EmitPaintParamsUniforms(int bufferID,
                                    const char* name,
                                    const std::vector<SkPaintParamsKey::BlockReader>& readers,
                                    bool needsLocalCoords) {
    size_t numUniforms = 0;
    for (auto r : readers) {
        numUniforms += r.entry()->fUniforms.size();
    }

    if (!numUniforms) {
        return {};
    }

    int offset = 0;

    std::string result = get_uniform_header(bufferID, name);
    for (int i = 0; i < (int) readers.size(); ++i) {
        SkSL::String::appendf(&result,
                              "// %s\n",
                              readers[i].entry()->fName);
        result += get_uniforms(readers[i].entry()->fUniforms, &offset, i);
    }
    if (needsLocalCoords) {
        static constexpr SkUniform kDev2LocalUniform[] = {{ "dev2LocalUni", SkSLType::kFloat4x4 }};
        result += "// NeedsLocalCoords\n";
        result += get_uniforms(SkSpan<const SkUniform>(kDev2LocalUniform, 1), &offset, -1);
    }
    result.append("};\n\n");

    return result;
}

std::string EmitRenderStepUniforms(int bufferID, const char* name,
                                   SkSpan<const SkUniform> uniforms) {
    int offset = 0;

    std::string result = get_uniform_header(bufferID, name);
    result += get_uniforms(uniforms, &offset, -1);
    result.append("};\n\n");

    return result;
}

std::string EmitTexturesAndSamplers(const std::vector<SkPaintParamsKey::BlockReader>& readers,
                                    int* binding) {
    std::string result;
    for (int i = 0; i < (int) readers.size(); ++i) {
        auto texturesAndSamplers = readers[i].entry()->fTexturesAndSamplers;

        for (int j = 0; j < (int) texturesAndSamplers.size(); ++j) {
            const SkTextureAndSampler& t = texturesAndSamplers[j];
            SkSL::String::appendf(&result,
                                  "layout(binding=%d) uniform sampler2D %s_%d;\n",
                                  *binding, t.name(), i);
            (*binding)++;
        }
    }

    return result;
}

namespace {
std::string emit_attributes(SkSpan<const Attribute> vertexAttrs,
                            SkSpan<const Attribute> instanceAttrs) {
    std::string result;

    int attr = 0;
    auto add_attrs = [&](SkSpan<const Attribute> attrs) {
        for (auto a : attrs) {
            SkSL::String::appendf(&result, "    layout(location=%d) in ", attr++);
            result.append(SkSLTypeString(a.gpuType()));
            SkSL::String::appendf(&result, " %s;\n", a.name());
        }
    };

    if (!vertexAttrs.empty()) {
        result.append("// vertex attrs\n");
        add_attrs(vertexAttrs);
    }
    if (!instanceAttrs.empty()) {
        result.append("// instance attrs\n");
        add_attrs(instanceAttrs);
    }

    return result;
}
}  // anonymous namespace

std::string EmitVaryings(const RenderStep* step, const char* direction) {
    std::string result;

    int location = 0;
    for (auto v : step->varyings()) {
        SkSL::String::appendf(&result, "    layout(location=%d) %s ", location++, direction);
        result.append(SkSLTypeString(v.fType));
        SkSL::String::appendf(&result, " %s;\n", v.fName);
    }

    return result;
}

std::string GetSkSLVS(const GraphicsPipelineDesc& desc) {
    const RenderStep* step = desc.renderStep();
    // TODO: To more completely support end-to-end rendering, this will need to be updated so that
    // the RenderStep shader snippet can produce a device coord, a local coord, and depth.
    // If the paint combination doesn't need the local coord it can be ignored, otherwise we need
    // a varying for it. The fragment function's output will need to be updated to have a color and
    // the depth, or when there's no combination, just the depth. Lastly, we also should add the
    // static/intrinsic uniform binding point so that we can handle normalizing the device position
    // produced by the RenderStep automatically.

    // Fixed program header
    std::string sksl =
        "layout (binding=0) uniform intrinsicUniforms {\n"
        "    layout(offset=0) float4 rtAdjust;\n"
        "};\n"
        "\n";

    if (step->numVertexAttributes() > 0 || step->numInstanceAttributes() > 0) {
        sksl += emit_attributes(step->vertexAttributes(), step->instanceAttributes());
    }

    // Uniforms needed by RenderStep
    // The uniforms are mangled by having their index in 'fEntries' as a suffix (i.e., "_%d")
    // TODO: replace hard-coded bufferID with the backend's renderstep uniform-buffer index.
    if (step->numUniforms() > 0) {
        sksl += EmitRenderStepUniforms(1, "Step", step->uniforms());
    }

    // Varyings needed by RenderStep
    if (step->numVaryings() > 0) {
        sksl += EmitVaryings(step, "out");
    }

    // Vertex shader function declaration
    sksl += "void main() {\n";
    // Vertex shader body
    sksl += step->vertexSkSL();
    sksl += "sk_Position = float4(devPosition.xy * rtAdjust.xy + rtAdjust.zw, devPosition.zw);\n"
            "}\n";

    return sksl;
}

std::string GetSkSLFS(SkShaderCodeDictionary* dict,
                      SkRuntimeEffectDictionary* rteDict,
                      const GraphicsPipelineDesc& desc,
                      BlendInfo* blendInfo) {
    if (!desc.paintParamsID().isValid()) {
        // TODO: we should return the error shader code here
        return {};
    }

    SkShaderInfo shaderInfo(rteDict);

    dict->getShaderInfo(desc.paintParamsID(), &shaderInfo);
    *blendInfo = shaderInfo.blendInfo();

    std::string sksl;
    sksl += shaderInfo.toSkSL(desc.renderStep());

    return sksl;
}

} // namespace skgpu::graphite
<commit_msg>[graphite] Minor cleanup<commit_after>/*
 * Copyright 2021 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/gpu/graphite/ContextUtils.h"

#include <string>
#include "include/private/SkSLString.h"
#include "include/private/SkUniquePaintParamsID.h"
#include "src/core/SkBlenderBase.h"
#include "src/core/SkKeyContext.h"
#include "src/core/SkPipelineData.h"
#include "src/core/SkShaderCodeDictionary.h"
#include "src/gpu/graphite/PaintParams.h"
#include "src/gpu/graphite/RecorderPriv.h"
#include "src/gpu/graphite/Renderer.h"
#include "src/gpu/graphite/ResourceProvider.h"
#include "src/gpu/graphite/UniformManager.h"

namespace skgpu::graphite {

std::tuple<SkUniquePaintParamsID, UniformDataCache::Index, TextureDataCache::Index>
ExtractPaintData(Recorder* recorder,
                 SkPipelineDataGatherer* gatherer,
                 SkPaintParamsKeyBuilder* builder,
                 const SkM44& dev2Local,
                 const PaintParams& p) {

    SkDEBUGCODE(gatherer->checkReset());
    SkDEBUGCODE(builder->checkReset());

    SkKeyContext keyContext(recorder, dev2Local);

    p.toKey(keyContext, builder, gatherer);

    auto dict = recorder->priv().resourceProvider()->shaderCodeDictionary();
    UniformDataCache* uniformDataCache = recorder->priv().uniformDataCache();
    TextureDataCache* textureDataCache = recorder->priv().textureDataCache();

    auto entry = dict->findOrCreate(builder);
    UniformDataCache::Index uniformIndex;
    if (gatherer->hasUniforms()) {
        uniformIndex = uniformDataCache->insert(gatherer->peekUniformData());
    }
    TextureDataCache::Index textureIndex;
    if (gatherer->hasTextures()) {
        textureIndex = textureDataCache->insert(gatherer->textureDataBlock());
    }

    gatherer->reset();

    return { entry->uniqueID(), uniformIndex, textureIndex };
}

std::tuple<UniformDataCache::Index, TextureDataCache::Index>
ExtractRenderStepData(UniformDataCache* geometryUniformDataCache,
                      TextureDataCache* textureDataCache,
                      SkPipelineDataGatherer* gatherer,
                      const RenderStep* step,
                      const DrawParams& params) {
    SkDEBUGCODE(gatherer->checkReset());

    step->writeUniformsAndTextures(params, gatherer);

    UniformDataCache::Index uIndex = geometryUniformDataCache->insert(gatherer->peekUniformData());

    TextureDataCache::Index textureIndex;
    if (step->hasTextures()) {
        textureIndex = textureDataCache->insert(gatherer->textureDataBlock());
    }

    gatherer->reset();

    return { uIndex, textureIndex };
}

namespace {
std::string get_uniform_header(int bufferID, const char* name) {
    std::string result;

    SkSL::String::appendf(&result, "layout (binding=%d) uniform %sUniforms {\n", bufferID, name);

    return result;
}

std::string get_uniforms(SkSpan<const SkUniform> uniforms, int* offset, int manglingSuffix) {
    std::string result;
    UniformOffsetCalculator offsetter(Layout::kMetal, *offset);

    for (const SkUniform& u : uniforms) {
        SkSL::String::appendf(&result, "    layout(offset=%zu) %s %s",
                              offsetter.calculateOffset(u.type(), u.count()),
                              SkSLTypeString(u.type()),
                              u.name());
        if (manglingSuffix >= 0) {
            result.append("_");
            result.append(std::to_string(manglingSuffix));
        }
        if (u.count()) {
            result.append("[");
            result.append(std::to_string(u.count()));
            result.append("]");
        }
        result.append(";\n");
    }

    *offset = offsetter.size();
    return result;
}
}  // anonymous namespace

std::string EmitPaintParamsUniforms(int bufferID,
                                    const char* name,
                                    const std::vector<SkPaintParamsKey::BlockReader>& readers,
                                    bool needsLocalCoords) {
    size_t numUniforms = 0;
    for (auto r : readers) {
        numUniforms += r.entry()->fUniforms.size();
    }

    if (!numUniforms) {
        return {};
    }

    int offset = 0;

    std::string result = get_uniform_header(bufferID, name);
    for (int i = 0; i < (int) readers.size(); ++i) {
        SkSpan<const SkUniform> uniforms = readers[i].entry()->fUniforms;

        if (!uniforms.empty()) {
            SkSL::String::appendf(&result, "// %s uniforms\n", readers[i].entry()->fName);
            result += get_uniforms(uniforms, &offset, i);
        }
    }
    if (needsLocalCoords) {
        static constexpr SkUniform kDev2LocalUniform[] = {{ "dev2LocalUni", SkSLType::kFloat4x4 }};
        result += "// NeedsLocalCoords\n";
        result += get_uniforms(SkSpan<const SkUniform>(kDev2LocalUniform, 1), &offset, -1);
    }
    result.append("};\n\n");

    return result;
}

std::string EmitRenderStepUniforms(int bufferID, const char* name,
                                   SkSpan<const SkUniform> uniforms) {
    int offset = 0;

    std::string result = get_uniform_header(bufferID, name);
    result += get_uniforms(uniforms, &offset, -1);
    result.append("};\n\n");

    return result;
}

std::string EmitTexturesAndSamplers(const std::vector<SkPaintParamsKey::BlockReader>& readers,
                                    int* binding) {
    std::string result;
    for (int i = 0; i < (int) readers.size(); ++i) {
        SkSpan<const SkTextureAndSampler> samplers = readers[i].entry()->fTexturesAndSamplers;

        if (!samplers.empty()) {
            SkSL::String::appendf(&result, "// %s samplers\n", readers[i].entry()->fName);

            for (const SkTextureAndSampler& t : samplers) {
                SkSL::String::appendf(&result,
                                      "layout(binding=%d) uniform sampler2D %s_%d;\n",
                                      *binding, t.name(), i);
                (*binding)++;
            }
        }
    }

    return result;
}

namespace {
std::string emit_attributes(SkSpan<const Attribute> vertexAttrs,
                            SkSpan<const Attribute> instanceAttrs) {
    std::string result;

    int attr = 0;
    auto add_attrs = [&](SkSpan<const Attribute> attrs) {
        for (auto a : attrs) {
            SkSL::String::appendf(&result, "    layout(location=%d) in ", attr++);
            result.append(SkSLTypeString(a.gpuType()));
            SkSL::String::appendf(&result, " %s;\n", a.name());
        }
    };

    if (!vertexAttrs.empty()) {
        result.append("// vertex attrs\n");
        add_attrs(vertexAttrs);
    }
    if (!instanceAttrs.empty()) {
        result.append("// instance attrs\n");
        add_attrs(instanceAttrs);
    }

    return result;
}
}  // anonymous namespace

std::string EmitVaryings(const RenderStep* step, const char* direction) {
    std::string result;

    int location = 0;
    for (auto v : step->varyings()) {
        SkSL::String::appendf(&result, "    layout(location=%d) %s ", location++, direction);
        result.append(SkSLTypeString(v.fType));
        SkSL::String::appendf(&result, " %s;\n", v.fName);
    }

    return result;
}

std::string GetSkSLVS(const GraphicsPipelineDesc& desc) {
    const RenderStep* step = desc.renderStep();
    // TODO: To more completely support end-to-end rendering, this will need to be updated so that
    // the RenderStep shader snippet can produce a device coord, a local coord, and depth.
    // If the paint combination doesn't need the local coord it can be ignored, otherwise we need
    // a varying for it. The fragment function's output will need to be updated to have a color and
    // the depth, or when there's no combination, just the depth. Lastly, we also should add the
    // static/intrinsic uniform binding point so that we can handle normalizing the device position
    // produced by the RenderStep automatically.

    // Fixed program header
    std::string sksl =
        "layout (binding=0) uniform intrinsicUniforms {\n"
        "    layout(offset=0) float4 rtAdjust;\n"
        "};\n"
        "\n";

    if (step->numVertexAttributes() > 0 || step->numInstanceAttributes() > 0) {
        sksl += emit_attributes(step->vertexAttributes(), step->instanceAttributes());
    }

    // Uniforms needed by RenderStep
    // The uniforms are mangled by having their index in 'fEntries' as a suffix (i.e., "_%d")
    // TODO: replace hard-coded bufferID with the backend's renderstep uniform-buffer index.
    if (step->numUniforms() > 0) {
        sksl += EmitRenderStepUniforms(1, "Step", step->uniforms());
    }

    // Varyings needed by RenderStep
    if (step->numVaryings() > 0) {
        sksl += EmitVaryings(step, "out");
    }

    // Vertex shader function declaration
    sksl += "void main() {\n";
    // Vertex shader body
    sksl += step->vertexSkSL();
    sksl += "sk_Position = float4(devPosition.xy * rtAdjust.xy + rtAdjust.zw, devPosition.zw);\n"
            "}\n";

    return sksl;
}

std::string GetSkSLFS(SkShaderCodeDictionary* dict,
                      SkRuntimeEffectDictionary* rteDict,
                      const GraphicsPipelineDesc& desc,
                      BlendInfo* blendInfo) {
    if (!desc.paintParamsID().isValid()) {
        // TODO: we should return the error shader code here
        return {};
    }

    SkShaderInfo shaderInfo(rteDict);

    dict->getShaderInfo(desc.paintParamsID(), &shaderInfo);
    *blendInfo = shaderInfo.blendInfo();

    std::string sksl;
    sksl += shaderInfo.toSkSL(desc.renderStep());

    return sksl;
}

} // namespace skgpu::graphite
<|endoftext|>