<commit_before>/****************************************************************/
/*               DO NOT MODIFY THIS HEADER                      */
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*           (c) 2010 Battelle Energy Alliance, LLC             */
/*                   ALL RIGHTS RESERVED                        */
/*                                                              */
/*          Prepared by Battelle Energy Alliance, LLC           */
/*            Under Contract No. DE-AC07-05ID14517              */
/*            With the U. S. Department of Energy               */
/*                                                              */
/*            See COPYRIGHT for full restrictions               */
/****************************************************************/

#include "RestartableDataIO.h"
#include "MooseUtils.h"
#include "RestartableData.h"
#include "FEProblem.h"

#include <stdio.h>

RestartableDataIO::RestartableDataIO(FEProblem & fe_problem) :
    _fe_problem(fe_problem)
{
}

void
RestartableDataIO::writeRestartableData(std::string base_file_name)
{
  unsigned int n_threads = libMesh::n_threads();
  unsigned int n_procs = libMesh::n_processors();
  unsigned int proc_id = libMesh::processor_id();

  for(unsigned int tid=0; tid<n_threads; tid++)
  {
    std::map<std::string, RestartableDataValue *> restartable_data = _fe_problem._restartable_data[tid];

    if(restartable_data.size())
    {
      const unsigned int file_version = 1;

      std::ofstream out;

      std::ostringstream file_name_stream;
      file_name_stream << base_file_name;

      file_name_stream << "-" << proc_id;

      if(n_threads > 1)
        file_name_stream << "-" << tid;

      std::string file_name = file_name_stream.str();

      { // Write out header
        out.open(file_name.c_str(), std::ios::out | std::ios::binary);

        char id[2];

        // header
        id[0] = 'R';
        id[1] = 'D';

        out.write(id, 2);
        out.write((const char *)&file_version, sizeof(file_version));

        out.write((const char *)&n_procs, sizeof(n_procs));
        out.write((const char *)&n_threads, sizeof(n_threads));

        // number of RestartableData
        unsigned int n_data = restartable_data.size();
        out.write((const char *) &n_data, sizeof(n_data));

        // data names
        for(std::map<std::string, RestartableDataValue *>::iterator it = restartable_data.begin();
            it != restartable_data.end();
            ++it)
        {
          std::string name = it->second->name();
          out.write(name.c_str(), name.length() + 1); // trailing 0!
        }
      }
      {
        std::ostringstream data_blk;

        for(std::map<std::string, RestartableDataValue *>::iterator it = restartable_data.begin();
            it != restartable_data.end();
            ++it)
        {
          // std::cout<<"Storing "<<it->first<<std::endl;

          std::ostringstream data;
          it->second->store(data);

          // Store the size of the data then the data
          unsigned int data_size = data.tellp();
          data_blk.write((const char *) &data_size, sizeof(data_size));
          data_blk << data.str();
        }

        // Write out this proc's block size
        unsigned int data_blk_size = data_blk.tellp();
        out.write((const char *) &data_blk_size, sizeof(data_blk_size));

        // Write out the values
        out << data_blk.str();

        out.close();
      }
    }
  }
}

void
RestartableDataIO::readRestartableData(std::string base_file_name)
{
  unsigned int n_threads = libMesh::n_threads();
  unsigned int n_procs = libMesh::n_processors();
  unsigned int proc_id = libMesh::processor_id();

  std::vector<std::string> ignored_data;

  for(unsigned int tid=0; tid<n_threads; tid++)
  {
    std::map<std::string, RestartableDataValue *> restartable_data = _fe_problem._restartable_data[tid];

    if(restartable_data.size())
    {
      std::ostringstream file_name_stream;
      file_name_stream << base_file_name;

      file_name_stream << "-" << proc_id;

      if(n_threads > 1)
        file_name_stream << "-" << tid;

      std::string file_name = file_name_stream.str();

      MooseUtils::checkFileReadable(file_name);

      const unsigned int file_version = 1;

      std::ifstream in(file_name.c_str(), std::ios::in | std::ios::binary);

      // header
      char id[2];
      in.read(id, 2);

      unsigned int this_file_version;
      in.read((char *)&this_file_version, sizeof(this_file_version));

      unsigned int this_n_procs = 0;
      unsigned int this_n_threads = 0;

      in.read((char *)&this_n_procs, sizeof(this_n_procs));
      in.read((char *)&this_n_threads, sizeof(this_n_threads));

      // check the header
      if(id[0] != 'R' || id[1] != 'D')
        mooseError("Corrupted restartable data file!");

      // check the file version
      if(this_file_version > file_version)
        mooseError("Trying to restart from a newer file version - you need to update MOOSE");

      if(this_file_version < file_version)
        mooseError("Trying to restart from an older file version - you need to checkout an older version of MOOSE.");

      if(this_n_procs != n_procs)
        mooseError("Cannot restart using a different number of processors!");

      if(this_n_threads != n_threads)
        mooseError("Cannot restart using a different number of threads!");

      // number of data
      unsigned int n_data = 0;
      in.read((char *) &n_data, sizeof(n_data));

      // data names
      std::vector<std::string> data_names(n_data);

      for(unsigned int i=0; i < n_data; i++)
      {
        std::string data_name;
        char ch = 0;
        do {
          in.read(&ch, 1);
          if (ch != '\0')
            data_name += ch;
        } while (ch != '\0');
        data_names[i] = data_name;
      }

      // Grab this processor's block size
      unsigned int data_blk_size = 0;
      in.read((char *) &data_blk_size, sizeof(data_blk_size));

      for(unsigned int i=0; i < n_data; i++)
      {
        std::string current_name = data_names[i];

        unsigned int data_size = 0;
        in.read((char *) &data_size, sizeof(data_size));

        if(restartable_data.find(current_name) != restartable_data.end()) // Only restore values if they're currently being used
        {
          // std::cout<<"Loading "<<current_name<<std::endl;

          RestartableDataValue * current_data = restartable_data[current_name];
          current_data->load(in);
        }
        else
        {
          // Skip this piece of data
          in.seekg(data_size, std::ios_base::cur);
          ignored_data.push_back(current_name);
        }
      }

      in.close();
    }
  }

  if(ignored_data.size())
  {
    std::ostringstream names;

    for(unsigned int i=0; i<ignored_data.size(); i++)
      names << ignored_data[i] << "\n";

    mooseWarning("The following RestorableData was found in restart file but is being ignored:\n" << names.str());
  }
}
<commit_msg>Fix issue with displaced refs #1169<commit_after>/****************************************************************/
/*               DO NOT MODIFY THIS HEADER                      */
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*           (c) 2010 Battelle Energy Alliance, LLC             */
/*                   ALL RIGHTS RESERVED                        */
/*                                                              */
/*          Prepared by Battelle Energy Alliance, LLC           */
/*            Under Contract No. DE-AC07-05ID14517              */
/*            With the U. S. Department of Energy               */
/*                                                              */
/*            See COPYRIGHT for full restrictions               */
/****************************************************************/

#include "RestartableDataIO.h"
#include "MooseUtils.h"
#include "RestartableData.h"
#include "FEProblem.h"

#include <stdio.h>

RestartableDataIO::RestartableDataIO(FEProblem & fe_problem) :
    _fe_problem(fe_problem)
{
}

void
RestartableDataIO::writeRestartableData(std::string base_file_name)
{
  unsigned int n_threads = libMesh::n_threads();
  unsigned int n_procs = libMesh::n_processors();
  unsigned int proc_id = libMesh::processor_id();

  for(unsigned int tid=0; tid<n_threads; tid++)
  {
    const std::map<std::string, RestartableDataValue *> & restartable_data = _fe_problem._restartable_data[tid];

    if(restartable_data.size())
    {
      const unsigned int file_version = 1;

      std::ofstream out;

      std::ostringstream file_name_stream;
      file_name_stream << base_file_name;

      file_name_stream << "-" << proc_id;

      if(n_threads > 1)
        file_name_stream << "-" << tid;

      std::string file_name = file_name_stream.str();

      { // Write out header
        out.open(file_name.c_str(), std::ios::out | std::ios::binary);

        char id[2];

        // header
        id[0] = 'R';
        id[1] = 'D';

        out.write(id, 2);
        out.write((const char *)&file_version, sizeof(file_version));

        out.write((const char *)&n_procs, sizeof(n_procs));
        out.write((const char *)&n_threads, sizeof(n_threads));

        // number of RestartableData
        unsigned int n_data = restartable_data.size();
        out.write((const char *) &n_data, sizeof(n_data));

        // data names
        for(std::map<std::string, RestartableDataValue *>::const_iterator it = restartable_data.begin();
            it != restartable_data.end();
            ++it)
        {
          std::string name = it->first;
          out.write(name.c_str(), name.length() + 1); // trailing 0!
        }
      }
      {
        std::ostringstream data_blk;

        for(std::map<std::string, RestartableDataValue *>::const_iterator it = restartable_data.begin();
            it != restartable_data.end();
            ++it)
        {
          // std::cout<<"Storing "<<it->first<<std::endl;

          std::ostringstream data;
          it->second->store(data);

          // Store the size of the data then the data
          unsigned int data_size = data.tellp();
          data_blk.write((const char *) &data_size, sizeof(data_size));
          data_blk << data.str();
        }

        // Write out this proc's block size
        unsigned int data_blk_size = data_blk.tellp();
        out.write((const char *) &data_blk_size, sizeof(data_blk_size));

        // Write out the values
        out << data_blk.str();

        out.close();
      }
    }
  }
}

void
RestartableDataIO::readRestartableData(std::string base_file_name)
{
  unsigned int n_threads = libMesh::n_threads();
  unsigned int n_procs = libMesh::n_processors();
  unsigned int proc_id = libMesh::processor_id();

  std::vector<std::string> ignored_data;

  for(unsigned int tid=0; tid<n_threads; tid++)
  {
    std::map<std::string, RestartableDataValue *> restartable_data = _fe_problem._restartable_data[tid];

    if(restartable_data.size())
    {
      std::ostringstream file_name_stream;
      file_name_stream << base_file_name;

      file_name_stream << "-" << proc_id;

      if(n_threads > 1)
        file_name_stream << "-" << tid;

      std::string file_name = file_name_stream.str();

      MooseUtils::checkFileReadable(file_name);

      const unsigned int file_version = 1;

      std::ifstream in(file_name.c_str(), std::ios::in | std::ios::binary);

      // header
      char id[2];
      in.read(id, 2);

      unsigned int this_file_version;
      in.read((char *)&this_file_version, sizeof(this_file_version));

      unsigned int this_n_procs = 0;
      unsigned int this_n_threads = 0;

      in.read((char *)&this_n_procs, sizeof(this_n_procs));
      in.read((char *)&this_n_threads, sizeof(this_n_threads));

      // check the header
      if(id[0] != 'R' || id[1] != 'D')
        mooseError("Corrupted restartable data file!");

      // check the file version
      if(this_file_version > file_version)
        mooseError("Trying to restart from a newer file version - you need to update MOOSE");

      if(this_file_version < file_version)
        mooseError("Trying to restart from an older file version - you need to checkout an older version of MOOSE.");

      if(this_n_procs != n_procs)
        mooseError("Cannot restart using a different number of processors!");

      if(this_n_threads != n_threads)
        mooseError("Cannot restart using a different number of threads!");

      // number of data
      unsigned int n_data = 0;
      in.read((char *) &n_data, sizeof(n_data));

      // data names
      std::vector<std::string> data_names(n_data);

      for(unsigned int i=0; i < n_data; i++)
      {
        std::string data_name;
        char ch = 0;
        do {
          in.read(&ch, 1);
          if (ch != '\0')
            data_name += ch;
        } while (ch != '\0');
        data_names[i] = data_name;
      }

      // Grab this processor's block size
      unsigned int data_blk_size = 0;
      in.read((char *) &data_blk_size, sizeof(data_blk_size));

      for(unsigned int i=0; i < n_data; i++)
      {
        std::string current_name = data_names[i];

        unsigned int data_size = 0;
        in.read((char *) &data_size, sizeof(data_size));

        if(restartable_data.find(current_name) != restartable_data.end()) // Only restore values if they're currently being used
        {
          // std::cout<<"Loading "<<current_name<<std::endl;

          RestartableDataValue * current_data = restartable_data[current_name];
          current_data->load(in);
        }
        else
        {
          // Skip this piece of data
          in.seekg(data_size, std::ios_base::cur);
          ignored_data.push_back(current_name);
        }
      }

      in.close();
    }
  }

  if(ignored_data.size())
  {
    std::ostringstream names;

    for(unsigned int i=0; i<ignored_data.size(); i++)
      names << ignored_data[i] << "\n";

    mooseWarning("The following RestorableData was found in restart file but is being ignored:\n" << names.str());

  }
}
<|endoftext|>


<commit_before>#include "SkBenchmark.h"
#include "SkMatrix.h"
#include "SkRandom.h"
#include "SkString.h"

class MatrixBench : public SkBenchmark {
    SkString    fName;
    enum { N = 100000 };
public:
    MatrixBench(void* param, const char name[]) : INHERITED(param) {
        fName.printf("matrix_%s", name);
    }

    virtual void performTest() = 0;

protected:
    virtual int mulLoopCount() const { return 1; }

    virtual const char* onGetName() {
        return fName.c_str();
    }

    virtual void onDraw(SkCanvas* canvas) {
        int n = N * this->mulLoopCount();
        for (int i = 0; i < n; i++) {
            this->performTest();
        }
    }

private:
    typedef SkBenchmark INHERITED;
};

// we want to stop the compiler from eliminating code that it thinks is a no-op
// so we have a non-static global we increment, hoping that will convince the
// compiler to execute everything
int gMatrixBench_NonStaticGlobal;

#define always_do(pred)                     \
    do {                                    \
        if (pred) {                         \
            ++gMatrixBench_NonStaticGlobal; \
        }                                   \
    } while (0)

class EqualsMatrixBench : public MatrixBench {
public:
    EqualsMatrixBench(void* param) : INHERITED(param, "equals") {}
protected:
    virtual void performTest() {
        SkMatrix m0, m1, m2;

        m0.reset();
        m1.reset();
        m2.reset();
        always_do(m0 == m1);
        always_do(m1 == m2);
        always_do(m2 == m0);
        always_do(m0.getType());
        always_do(m1.getType());
        always_do(m2.getType());
    }
private:
    typedef MatrixBench INHERITED;
};

class ScaleMatrixBench : public MatrixBench {
public:
    ScaleMatrixBench(void* param) : INHERITED(param, "scale") {

        fM0.reset();
        fM1.setScale(fSX, fSY);
        fM2.setTranslate(fSX, fSY);
        fSX = fSY = SkFloatToScalar(1.5f);
    }
protected:
    virtual void performTest() {
        SkMatrix m;
        m = fM0; m.preScale(fSX, fSY);
        m = fM1; m.preScale(fSX, fSY);
        m = fM2; m.preScale(fSX, fSY);
    }
private:
    SkMatrix fM0, fM1, fM2;
    SkScalar fSX, fSY;
    typedef MatrixBench INHERITED;
};

// having unknown values in our arrays can throw off the timing a lot, perhaps
// handling NaN values is a lot slower. Anyway, this guy is just meant to put
// reasonable values in our arrays.
template <typename T> void init9(T array[9]) {
    SkRandom rand;
    for (int i = 0; i < 9; i++) {
        array[i] = rand.nextSScalar1();
    }
}

// Test the performance of setConcat() non-perspective case:
// using floating point precision only.
class FloatConcatMatrixBench : public MatrixBench {
public:
    FloatConcatMatrixBench(void* p) : INHERITED(p, "concat_floatfloat") {
        init9(mya);
        init9(myb);
        init9(myr);
    }
protected:
    virtual int mulLoopCount() const { return 4; }

    static inline void muladdmul(float a, float b, float c, float d,
                                   float* result) {
      *result = a * b + c * d;
    }
    virtual void performTest() {
        const float* a = mya;
        const float* b = myb;
        float* r = myr;
        muladdmul(a[0], b[0], a[1], b[3], &r[0]);
        muladdmul(a[0], b[1], a[1], b[4], &r[1]);
        muladdmul(a[0], b[2], a[1], b[5], &r[2]);
        r[2] += a[2];
        muladdmul(a[3], b[0], a[4], b[3], &r[3]);
        muladdmul(a[3], b[1], a[4], b[4], &r[4]);
        muladdmul(a[3], b[2], a[4], b[5], &r[5]);
        r[5] += a[5];
        r[6] = r[7] = 0.0f;
        r[8] = 1.0f;
    }
private:
    float mya [9];
    float myb [9];
    float myr [9];
    typedef MatrixBench INHERITED;
};

static inline float SkDoubleToFloat(double x) {
    return static_cast<float>(x);
}

// Test the performance of setConcat() non-perspective case:
// using floating point precision but casting up to float for
// intermediate results during computations.
class FloatDoubleConcatMatrixBench : public MatrixBench {
public:
    FloatDoubleConcatMatrixBench(void* p) : INHERITED(p, "concat_floatdouble") {
        init9(mya);
        init9(myb);
        init9(myr);
    }
protected:
    virtual int mulLoopCount() const { return 4; }

    static inline void muladdmul(float a, float b, float c, float d,
                                   float* result) {
      *result = SkDoubleToFloat((double)a * b + (double)c * d);
    }
    virtual void performTest() {
        const float* a = mya;
        const float* b = myb;
        float* r = myr;
        muladdmul(a[0], b[0], a[1], b[3], &r[0]);
        muladdmul(a[0], b[1], a[1], b[4], &r[1]);
        muladdmul(a[0], b[2], a[1], b[5], &r[2]);
        r[2] += a[2];
        muladdmul(a[3], b[0], a[4], b[3], &r[3]);
        muladdmul(a[3], b[1], a[4], b[4], &r[4]);
        muladdmul(a[3], b[2], a[4], b[5], &r[5]);
        r[5] += a[5];
        r[6] = r[7] = 0.0f;
        r[8] = 1.0f;
    }
private:
    float mya [9];
    float myb [9];
    float myr [9];
    typedef MatrixBench INHERITED;
};

// Test the performance of setConcat() non-perspective case:
// using double precision only.
class DoubleConcatMatrixBench : public MatrixBench {
public:
    DoubleConcatMatrixBench(void* p) : INHERITED(p, "concat_double") {
        init9(mya);
        init9(myb);
        init9(myr);
    }
protected:
    virtual int mulLoopCount() const { return 4; }

    static inline void muladdmul(double a, double b, double c, double d,
                                   double* result) {
      *result = a * b + c * d;
    }
    virtual void performTest() {
        const double* a = mya;
        const double* b = myb;
        double* r = myr;
        muladdmul(a[0], b[0], a[1], b[3], &r[0]);
        muladdmul(a[0], b[1], a[1], b[4], &r[1]);
        muladdmul(a[0], b[2], a[1], b[5], &r[2]);
        r[2] += a[2];
        muladdmul(a[3], b[0], a[4], b[3], &r[3]);
        muladdmul(a[3], b[1], a[4], b[4], &r[4]);
        muladdmul(a[3], b[2], a[4], b[5], &r[5]);
        r[5] += a[5];
        r[6] = r[7] = 0.0;
        r[8] = 1.0;
    }
private:
    double mya [9];
    double myb [9];
    double myr [9];
    typedef MatrixBench INHERITED;
};

static SkBenchmark* M0(void* p) { return new EqualsMatrixBench(p); }
static SkBenchmark* M1(void* p) { return new ScaleMatrixBench(p); }
static SkBenchmark* M2(void* p) { return new FloatConcatMatrixBench(p); }
static SkBenchmark* M3(void* p) { return new FloatDoubleConcatMatrixBench(p); }
static SkBenchmark* M4(void* p) { return new DoubleConcatMatrixBench(p); }

static BenchRegistry gReg0(M0);
static BenchRegistry gReg1(M1);
static BenchRegistry gReg2(M2);
static BenchRegistry gReg3(M3);
static BenchRegistry gReg4(M4);
<commit_msg>New benchmarks to determine performance of matrix-point multiplication for floating point vs. double matrices.<commit_after>#include "SkBenchmark.h"
#include "SkMatrix.h"
#include "SkRandom.h"
#include "SkString.h"

class MatrixBench : public SkBenchmark {
    SkString    fName;
    enum { N = 100000 };
public:
    MatrixBench(void* param, const char name[]) : INHERITED(param) {
        fName.printf("matrix_%s", name);
    }

    virtual void performTest() = 0;

protected:
    virtual int mulLoopCount() const { return 1; }

    virtual const char* onGetName() {
        return fName.c_str();
    }

    virtual void onDraw(SkCanvas* canvas) {
        int n = N * this->mulLoopCount();
        for (int i = 0; i < n; i++) {
            this->performTest();
        }
    }

private:
    typedef SkBenchmark INHERITED;
};

// we want to stop the compiler from eliminating code that it thinks is a no-op
// so we have a non-static global we increment, hoping that will convince the
// compiler to execute everything
int gMatrixBench_NonStaticGlobal;

#define always_do(pred)                     \
    do {                                    \
        if (pred) {                         \
            ++gMatrixBench_NonStaticGlobal; \
        }                                   \
    } while (0)

class EqualsMatrixBench : public MatrixBench {
public:
    EqualsMatrixBench(void* param) : INHERITED(param, "equals") {}
protected:
    virtual void performTest() {
        SkMatrix m0, m1, m2;

        m0.reset();
        m1.reset();
        m2.reset();
        always_do(m0 == m1);
        always_do(m1 == m2);
        always_do(m2 == m0);
        always_do(m0.getType());
        always_do(m1.getType());
        always_do(m2.getType());
    }
private:
    typedef MatrixBench INHERITED;
};

class ScaleMatrixBench : public MatrixBench {
public:
    ScaleMatrixBench(void* param) : INHERITED(param, "scale") {

        fM0.reset();
        fM1.setScale(fSX, fSY);
        fM2.setTranslate(fSX, fSY);
        fSX = fSY = SkFloatToScalar(1.5f);
    }
protected:
    virtual void performTest() {
        SkMatrix m;
        m = fM0; m.preScale(fSX, fSY);
        m = fM1; m.preScale(fSX, fSY);
        m = fM2; m.preScale(fSX, fSY);
    }
private:
    SkMatrix fM0, fM1, fM2;
    SkScalar fSX, fSY;
    typedef MatrixBench INHERITED;
};

// having unknown values in our arrays can throw off the timing a lot, perhaps
// handling NaN values is a lot slower. Anyway, this guy is just meant to put
// reasonable values in our arrays.
template <typename T> void init9(T array[9]) {
    SkRandom rand;
    for (int i = 0; i < 9; i++) {
        array[i] = rand.nextSScalar1();
    }
}

// Test the performance of setConcat() non-perspective case:
// using floating point precision only.
class FloatConcatMatrixBench : public MatrixBench {
public:
    FloatConcatMatrixBench(void* p) : INHERITED(p, "concat_floatfloat") {
        init9(mya);
        init9(myb);
        init9(myr);
    }
protected:
    virtual int mulLoopCount() const { return 4; }

    static inline void muladdmul(float a, float b, float c, float d,
                                   float* result) {
      *result = a * b + c * d;
    }
    virtual void performTest() {
        const float* a = mya;
        const float* b = myb;
        float* r = myr;
        muladdmul(a[0], b[0], a[1], b[3], &r[0]);
        muladdmul(a[0], b[1], a[1], b[4], &r[1]);
        muladdmul(a[0], b[2], a[1], b[5], &r[2]);
        r[2] += a[2];
        muladdmul(a[3], b[0], a[4], b[3], &r[3]);
        muladdmul(a[3], b[1], a[4], b[4], &r[4]);
        muladdmul(a[3], b[2], a[4], b[5], &r[5]);
        r[5] += a[5];
        r[6] = r[7] = 0.0f;
        r[8] = 1.0f;
    }
private:
    float mya [9];
    float myb [9];
    float myr [9];
    typedef MatrixBench INHERITED;
};

static inline float SkDoubleToFloat(double x) {
    return static_cast<float>(x);
}

// Test the performance of setConcat() non-perspective case:
// using floating point precision but casting up to float for
// intermediate results during computations.
class FloatDoubleConcatMatrixBench : public MatrixBench {
public:
    FloatDoubleConcatMatrixBench(void* p) : INHERITED(p, "concat_floatdouble") {
        init9(mya);
        init9(myb);
        init9(myr);
    }
protected:
    virtual int mulLoopCount() const { return 4; }

    static inline void muladdmul(float a, float b, float c, float d,
                                   float* result) {
      *result = SkDoubleToFloat((double)a * b + (double)c * d);
    }
    virtual void performTest() {
        const float* a = mya;
        const float* b = myb;
        float* r = myr;
        muladdmul(a[0], b[0], a[1], b[3], &r[0]);
        muladdmul(a[0], b[1], a[1], b[4], &r[1]);
        muladdmul(a[0], b[2], a[1], b[5], &r[2]);
        r[2] += a[2];
        muladdmul(a[3], b[0], a[4], b[3], &r[3]);
        muladdmul(a[3], b[1], a[4], b[4], &r[4]);
        muladdmul(a[3], b[2], a[4], b[5], &r[5]);
        r[5] += a[5];
        r[6] = r[7] = 0.0f;
        r[8] = 1.0f;
    }
private:
    float mya [9];
    float myb [9];
    float myr [9];
    typedef MatrixBench INHERITED;
};

// Test the performance of setConcat() non-perspective case:
// using double precision only.
class DoubleConcatMatrixBench : public MatrixBench {
public:
    DoubleConcatMatrixBench(void* p) : INHERITED(p, "concat_double") {
        init9(mya);
        init9(myb);
        init9(myr);
    }
protected:
    virtual int mulLoopCount() const { return 4; }

    static inline void muladdmul(double a, double b, double c, double d,
                                   double* result) {
      *result = a * b + c * d;
    }
    virtual void performTest() {
        const double* a = mya;
        const double* b = myb;
        double* r = myr;
        muladdmul(a[0], b[0], a[1], b[3], &r[0]);
        muladdmul(a[0], b[1], a[1], b[4], &r[1]);
        muladdmul(a[0], b[2], a[1], b[5], &r[2]);
        r[2] += a[2];
        muladdmul(a[3], b[0], a[4], b[3], &r[3]);
        muladdmul(a[3], b[1], a[4], b[4], &r[4]);
        muladdmul(a[3], b[2], a[4], b[5], &r[5]);
        r[5] += a[5];
        r[6] = r[7] = 0.0;
        r[8] = 1.0;
    }
private:
    double mya [9];
    double myb [9];
    double myr [9];
    typedef MatrixBench INHERITED;
};

#ifdef SK_SCALAR_IS_FLOAT
class ScaleTransMixedMatrixBench : public MatrixBench {
 public:
    ScaleTransMixedMatrixBench(void* p) : INHERITED(p, "scaletrans_mixed"), fCount (16) {
        fMatrix.setAll(fRandom.nextS(), fRandom.nextS(), fRandom.nextS(),
                       fRandom.nextS(), fRandom.nextS(), fRandom.nextS(),
                       fRandom.nextS(), fRandom.nextS(), fRandom.nextS());
        int i;
        for (i = 0; i < fCount; i++) {
            fSrc[i].fX = fRandom.nextS();
            fSrc[i].fY = fRandom.nextS();
            fDst[i].fX = fRandom.nextS();
            fDst[i].fY = fRandom.nextS();
        }
    }
 protected:
    virtual void performTest() {
        SkPoint* dst = fDst;
        const SkPoint* src = fSrc;
        int count = fCount;
        float mx = fMatrix[SkMatrix::kMScaleX];
        float my = fMatrix[SkMatrix::kMScaleY];
        float tx = fMatrix[SkMatrix::kMTransX];
        float ty = fMatrix[SkMatrix::kMTransY];
        do {
            dst->fY = SkScalarMulAdd(src->fY, my, ty);
            dst->fX = SkScalarMulAdd(src->fX, mx, tx);
            src += 1;
            dst += 1;
        } while (--count);
    }
 private:
    SkMatrix fMatrix;
    SkPoint fSrc [16];
    SkPoint fDst [16];
    int fCount;
    SkRandom fRandom;
    typedef MatrixBench INHERITED;
};

class ScaleTransDoubleMatrixBench : public MatrixBench {
 public:
    ScaleTransDoubleMatrixBench(void* p) : INHERITED(p, "scaletrans_double"), fCount (16) {
        init9(fMatrix);
        int i;
        for (i = 0; i < fCount; i++) {
            fSrc[i].fX = fRandom.nextS();
            fSrc[i].fY = fRandom.nextS();
            fDst[i].fX = fRandom.nextS();
            fDst[i].fY = fRandom.nextS();
        }
    }
 protected:
    virtual void performTest() {
        SkPoint* dst = fDst;
        const SkPoint* src = fSrc;
        int count = fCount;
        // As doubles, on Z600 Linux systems this is 2.5x as expensive as mixed mode
        float mx = fMatrix[SkMatrix::kMScaleX];
        float my = fMatrix[SkMatrix::kMScaleY];
        float tx = fMatrix[SkMatrix::kMTransX];
        float ty = fMatrix[SkMatrix::kMTransY];
        do {
            dst->fY = src->fY * my + ty;
            dst->fX = src->fX * mx + tx;
            src += 1;
            dst += 1;
        } while (--count);
    }
 private:
    double fMatrix [9];
    SkPoint fSrc [16];
    SkPoint fDst [16];
    int fCount;
    SkRandom fRandom;
    typedef MatrixBench INHERITED;
};
#endif

static SkBenchmark* M0(void* p) { return new EqualsMatrixBench(p); }
static SkBenchmark* M1(void* p) { return new ScaleMatrixBench(p); }
static SkBenchmark* M2(void* p) { return new FloatConcatMatrixBench(p); }
static SkBenchmark* M3(void* p) { return new FloatDoubleConcatMatrixBench(p); }
static SkBenchmark* M4(void* p) { return new DoubleConcatMatrixBench(p); }

static BenchRegistry gReg0(M0);
static BenchRegistry gReg1(M1);
static BenchRegistry gReg2(M2);
static BenchRegistry gReg3(M3);
static BenchRegistry gReg4(M4);

#ifdef SK_SCALAR_IS_FLOAT
static SkBenchmark* FlM0(void* p) { return new ScaleTransMixedMatrixBench(p); }
static SkBenchmark* FlM1(void* p) { return new ScaleTransDoubleMatrixBench(p); }
static BenchRegistry gFlReg5(FlM0);
static BenchRegistry gFlReg6(FlM1);
#endif
<|endoftext|>


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

#ifndef INCLUDED_BASEBMP_COLOR_HXX
#define INCLUDED_BASEBMP_COLOR_HXX

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif
#include <math.h>

namespace basebmp
{

class Color
{
private:
    sal_uInt32          mnColor;

public:
    typedef sal_uInt32  value_type;
    typedef sal_uInt8   component_type;

    Color() : mnColor(0) {}
    explicit Color( sal_uInt32 nVal ) : mnColor(nVal) {}
    Color( sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue ) :
        mnColor( ((sal_uInt32)nRed << 16) | ((sal_uInt32)nGreen << 8) | nBlue )
    {}

    void setRed( sal_uInt8 nRed ) { mnColor &= ~0x00FF0000UL; mnColor |= (sal_uInt32)nRed << 16; }
    void setGreen( sal_uInt8 nGreen ) { mnColor &= ~0x0000FF00UL; mnColor |= (sal_uInt32)nGreen << 8; }
    void setBlue( sal_uInt8 nBlue ) { mnColor &= ~0x000000FFUL; mnColor |= nBlue; }

    void setGrey( sal_uInt8 nGreyVal ) { mnColor = (sal_uInt32)nGreyVal << 16 | (sal_uInt32)nGreyVal << 8 | nGreyVal; }

    sal_uInt8 getRed() const   { return 0xFF & (sal_uInt8)(mnColor >> 16); }
    sal_uInt8 getGreen() const { return 0xFF & (sal_uInt8)(mnColor >> 8); }
    sal_uInt8 getBlue() const  { return 0xFF & (sal_uInt8)mnColor; }

    sal_uInt8 getGreyscale() const { return (sal_uInt8)((getBlue()*28UL +
                                                         getGreen()*151 +
                                                         getRed()*77) / 256); }

    sal_uInt32 toInt32() const { return mnColor; }

    bool  operator!() const { return mnColor == 0; }
    Color operator&( sal_uInt32 nMask ) const { return Color(mnColor & nMask); }
    Color operator^( Color col ) const { return Color(col.getRed()^getRed(),
                                                      col.getGreen()^getGreen(),
                                                      col.getBlue()^getBlue()); }
    Color operator-( Color col ) const { return Color((sal_uInt8)abs((int)getRed()-col.getRed()),
                                                      (sal_uInt8)abs((int)getGreen()-col.getGreen()),
                                                      (sal_uInt8)abs((int)getBlue()-col.getBlue())); }
    Color operator+( Color col ) const { return Color(getRed()+col.getRed(),
                                                      getGreen()+col.getGreen(),
                                                      getBlue()+col.getBlue()); }
    Color operator*( Color col ) const { return Color((sal_uInt8)((sal_uInt32)col.getRed()*getRed()/SAL_MAX_UINT8),
                                                      (sal_uInt8)((sal_uInt32)col.getGreen()*getGreen()/SAL_MAX_UINT8),
                                                      (sal_uInt8)((sal_uInt32)col.getBlue()*getBlue()/SAL_MAX_UINT8)); }
    Color operator*( sal_uInt8 n ) const { return Color((sal_uInt8)((sal_uInt32)n*getRed()/SAL_MAX_UINT8),
                                                        (sal_uInt8)((sal_uInt32)n*getGreen()/SAL_MAX_UINT8),
                                                        (sal_uInt8)((sal_uInt32)n*getBlue()/SAL_MAX_UINT8)); }
    Color operator*( double n ) const { return Color((sal_uInt8)(n*getRed()+.5),
                                                     (sal_uInt8)(n*getGreen()+.5),
                                                     (sal_uInt8)(n*getBlue()+.5)); }
    bool operator==( const Color& rhs ) const { return (getRed()==rhs.getRed() &&
                                                        getGreen()==rhs.getGreen() &&
                                                        getBlue()==rhs.getBlue()); }
    bool operator!=( const Color& rhs ) const { return !(*this==rhs); }
    double magnitude() const { return sqrt((double)getRed()*getRed()
                                           + getGreen()*getGreen()
                                           + getBlue()*getBlue()); }
};

} // namespace vigra

#endif /* INCLUDED_BASEBMP_COLOR_HXX */
<commit_msg>INTEGRATION: CWS presfixes09 (1.15.8); FILE MERGED 2006/10/20 14:43:49 thb 1.15.8.1: #142144# No more direct math.h includes - using rtl/math.hxx instead<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: color.hxx,v $
 *
 *  $Revision: 1.16 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-13 15:05:05 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef INCLUDED_BASEBMP_COLOR_HXX
#define INCLUDED_BASEBMP_COLOR_HXX

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif
#ifndef INCLUDED_RTL_MATH_HXX
#include <rtl/math.hxx>
#endif

namespace basebmp
{

class Color
{
private:
    sal_uInt32          mnColor;

public:
    typedef sal_uInt32  value_type;
    typedef sal_uInt8   component_type;

    Color() : mnColor(0) {}
    explicit Color( sal_uInt32 nVal ) : mnColor(nVal) {}
    Color( sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue ) :
        mnColor( ((sal_uInt32)nRed << 16) | ((sal_uInt32)nGreen << 8) | nBlue )
    {}

    void setRed( sal_uInt8 nRed ) { mnColor &= ~0x00FF0000UL; mnColor |= (sal_uInt32)nRed << 16; }
    void setGreen( sal_uInt8 nGreen ) { mnColor &= ~0x0000FF00UL; mnColor |= (sal_uInt32)nGreen << 8; }
    void setBlue( sal_uInt8 nBlue ) { mnColor &= ~0x000000FFUL; mnColor |= nBlue; }

    void setGrey( sal_uInt8 nGreyVal ) { mnColor = (sal_uInt32)nGreyVal << 16 | (sal_uInt32)nGreyVal << 8 | nGreyVal; }

    sal_uInt8 getRed() const   { return 0xFF & (sal_uInt8)(mnColor >> 16); }
    sal_uInt8 getGreen() const { return 0xFF & (sal_uInt8)(mnColor >> 8); }
    sal_uInt8 getBlue() const  { return 0xFF & (sal_uInt8)mnColor; }

    sal_uInt8 getGreyscale() const { return (sal_uInt8)((getBlue()*28UL +
                                                         getGreen()*151 +
                                                         getRed()*77) / 256); }

    sal_uInt32 toInt32() const { return mnColor; }

    bool  operator!() const { return mnColor == 0; }
    Color operator&( sal_uInt32 nMask ) const { return Color(mnColor & nMask); }
    Color operator^( Color col ) const { return Color(col.getRed()^getRed(),
                                                      col.getGreen()^getGreen(),
                                                      col.getBlue()^getBlue()); }
    Color operator-( Color col ) const { return Color((sal_uInt8)abs((int)getRed()-col.getRed()),
                                                      (sal_uInt8)abs((int)getGreen()-col.getGreen()),
                                                      (sal_uInt8)abs((int)getBlue()-col.getBlue())); }
    Color operator+( Color col ) const { return Color(getRed()+col.getRed(),
                                                      getGreen()+col.getGreen(),
                                                      getBlue()+col.getBlue()); }
    Color operator*( Color col ) const { return Color((sal_uInt8)((sal_uInt32)col.getRed()*getRed()/SAL_MAX_UINT8),
                                                      (sal_uInt8)((sal_uInt32)col.getGreen()*getGreen()/SAL_MAX_UINT8),
                                                      (sal_uInt8)((sal_uInt32)col.getBlue()*getBlue()/SAL_MAX_UINT8)); }
    Color operator*( sal_uInt8 n ) const { return Color((sal_uInt8)((sal_uInt32)n*getRed()/SAL_MAX_UINT8),
                                                        (sal_uInt8)((sal_uInt32)n*getGreen()/SAL_MAX_UINT8),
                                                        (sal_uInt8)((sal_uInt32)n*getBlue()/SAL_MAX_UINT8)); }
    Color operator*( double n ) const { return Color((sal_uInt8)(n*getRed()+.5),
                                                     (sal_uInt8)(n*getGreen()+.5),
                                                     (sal_uInt8)(n*getBlue()+.5)); }
    bool operator==( const Color& rhs ) const { return (getRed()==rhs.getRed() &&
                                                        getGreen()==rhs.getGreen() &&
                                                        getBlue()==rhs.getBlue()); }
    bool operator!=( const Color& rhs ) const { return !(*this==rhs); }
    double magnitude() const { return sqrt((double)getRed()*getRed()
                                           + getGreen()*getGreen()
                                           + getBlue()*getBlue()); }
};

} // namespace vigra

#endif /* INCLUDED_BASEBMP_COLOR_HXX */
<|endoftext|>


<commit_before>#include <unordered_map>

#include "MusicFile.h"
#include "MusicName.h"

namespace std
{
	// Hash specialization, since GCC doesn't support enum classes used as keys
	// in unordered_maps.
	template <>
	struct hash<MusicName>
	{
		size_t operator()(const MusicName &x) const
		{
			return static_cast<size_t>(x);
		}
	};
}

namespace
{
	// Each MusicName has a corresponding filename. Interestingly, it seems Arena
	// has separate XFM files for FM synth output devices (OPL, as on Adlib and
	// Sound Blaster before the AWE32), while the corresponding XMI files are for
	// MT-32, MPU-401, and other General MIDI devices.
	// - Dungeon1 uses the .XFM version because the .XMI version is a duplicate
	//   of Dungeon5.
	const std::unordered_map<MusicName, std::string> MusicFilenames =
	{
		{ MusicName::ArabCityEnter, "ARABCITY.XMI" },
		{ MusicName::ArabTownEnter, "ARABTOWN.XMI" },
		{ MusicName::ArabVillageEnter, "ARAB_VLG.XMI" },
		{ MusicName::CityEnter, "CITY.XMI" },
		{ MusicName::Combat, "COMBAT.XMI" },
		{ MusicName::Credits, "CREDITS.XMI" },
		{ MusicName::Dungeon1, "DUNGEON1.XFM" },
		{ MusicName::Dungeon2, "DUNGEON2.XMI" },
		{ MusicName::Dungeon3, "DUNGEON3.XMI" },
		{ MusicName::Dungeon4, "DUNGEON4.XMI" },
		{ MusicName::Dungeon5, "DUNGEON5.XMI" },
		{ MusicName::Equipment, "EQUIPMNT.XMI" },
		{ MusicName::Evil, "EVIL.XMI" },
		{ MusicName::EvilIntro, "EVLINTRO.XMI" },
		{ MusicName::Magic, "MAGIC_2.XMI" },
		{ MusicName::Night, "NIGHT.XMI" },
		{ MusicName::Overcast, "OVERCAST.XMI" },
		{ MusicName::OverSnow, "OVERSNOW.XMI" },
		{ MusicName::Palace, "PALACE.XMI" },
		{ MusicName::PercIntro, "PERCNTRO.XMI" },
		{ MusicName::Raining, "RAINING.XMI" },
		{ MusicName::Sheet, "SHEET.XMI" },
		{ MusicName::Sneaking, "SNEAKING.XMI" },
		{ MusicName::Snowing, "SNOWING.XMI" },
		{ MusicName::Square, "SQUARE.XMI" },
		{ MusicName::SunnyDay, "SUNNYDAY.XFM" },
		{ MusicName::Swimming, "SWIMMING.XMI" },
		{ MusicName::Tavern, "TAVERN.XMI" },
		{ MusicName::Temple, "TEMPLE.XMI" },
		{ MusicName::TownEnter, "TOWN.XMI" },
		{ MusicName::VillageEnter, "VILLAGE.XMI" },
		{ MusicName::Vision, "VISION.XMI" },
		{ MusicName::WinGame, "WINGAME.XMI" }
	};
}

const std::string &MusicFile::fromName(MusicName musicName)
{
	const std::string &filename = MusicFilenames.at(musicName);
	return filename;
}
<commit_msg>Changed OverSnow from XMI to XFM.<commit_after>#include <unordered_map>

#include "MusicFile.h"
#include "MusicName.h"

namespace std
{
	// Hash specialization, since GCC doesn't support enum classes used as keys
	// in unordered_maps.
	template <>
	struct hash<MusicName>
	{
		size_t operator()(const MusicName &x) const
		{
			return static_cast<size_t>(x);
		}
	};
}

namespace
{
	// Each MusicName has a corresponding filename. Interestingly, it seems Arena
	// has separate XFM files for FM synth output devices (OPL, as on Adlib and
	// Sound Blaster before the AWE32), while the corresponding XMI files are for
	// MT-32, MPU-401, and other General MIDI devices.
	// - Dungeon1 uses the .XFM version because the .XMI version is a duplicate
	//   of Dungeon5.
	const std::unordered_map<MusicName, std::string> MusicFilenames =
	{
		{ MusicName::ArabCityEnter, "ARABCITY.XMI" },
		{ MusicName::ArabTownEnter, "ARABTOWN.XMI" },
		{ MusicName::ArabVillageEnter, "ARAB_VLG.XMI" },
		{ MusicName::CityEnter, "CITY.XMI" },
		{ MusicName::Combat, "COMBAT.XMI" },
		{ MusicName::Credits, "CREDITS.XMI" },
		{ MusicName::Dungeon1, "DUNGEON1.XFM" },
		{ MusicName::Dungeon2, "DUNGEON2.XMI" },
		{ MusicName::Dungeon3, "DUNGEON3.XMI" },
		{ MusicName::Dungeon4, "DUNGEON4.XMI" },
		{ MusicName::Dungeon5, "DUNGEON5.XMI" },
		{ MusicName::Equipment, "EQUIPMNT.XMI" },
		{ MusicName::Evil, "EVIL.XMI" },
		{ MusicName::EvilIntro, "EVLINTRO.XMI" },
		{ MusicName::Magic, "MAGIC_2.XMI" },
		{ MusicName::Night, "NIGHT.XMI" },
		{ MusicName::Overcast, "OVERCAST.XMI" },
		{ MusicName::OverSnow, "OVERSNOW.XFM" },
		{ MusicName::Palace, "PALACE.XMI" },
		{ MusicName::PercIntro, "PERCNTRO.XMI" },
		{ MusicName::Raining, "RAINING.XMI" },
		{ MusicName::Sheet, "SHEET.XMI" },
		{ MusicName::Sneaking, "SNEAKING.XMI" },
		{ MusicName::Snowing, "SNOWING.XMI" },
		{ MusicName::Square, "SQUARE.XMI" },
		{ MusicName::SunnyDay, "SUNNYDAY.XFM" },
		{ MusicName::Swimming, "SWIMMING.XMI" },
		{ MusicName::Tavern, "TAVERN.XMI" },
		{ MusicName::Temple, "TEMPLE.XMI" },
		{ MusicName::TownEnter, "TOWN.XMI" },
		{ MusicName::VillageEnter, "VILLAGE.XMI" },
		{ MusicName::Vision, "VISION.XMI" },
		{ MusicName::WinGame, "WINGAME.XMI" }
	};
}

const std::string &MusicFile::fromName(MusicName musicName)
{
	const std::string &filename = MusicFilenames.at(musicName);
	return filename;
}
<|endoftext|>


<commit_before>//
//  lr_lalr_general.cpp
//  Parse
//
//  Created by Andrew Hunter on 02/05/2011.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#include <sstream>
#include <iostream>

#include "lr_lalr_general.h"

#include "Dfa/character_lexer.h"
#include "ContextFree/grammar.h"
#include "Lr/lalr_builder.h"
#include "Lr/parser.h"

using namespace std;
using namespace dfa;
using namespace contextfree;
using namespace lr;

static void dump(const item& it, const grammar& gram, const terminal_dictionary& dict) {
    if (it.type() == item::nonterminal) {
        wcerr << gram.name_for_nonterminal(it.symbol());
        wcerr << "(" << gram.identifier_for_item(it) << L")";
    } else if (it.type() == item::terminal) {
        wcerr << dict.name_for_symbol(it.symbol());
    } else if (it.type() == item::eoi) {
        wcerr << L"$";
        wcerr << "(" << gram.identifier_for_item(it) << L")";
    } else if (it.type() == item::empty) {
        wcerr << L"#";
        wcerr << "(" << gram.identifier_for_item(it) << L")";
    } else {
        wcerr << L"?";
        wcerr << "(" << gram.identifier_for_item(it) << L")";
    }
}

static void dump(const item_set& la, const grammar& gram, const terminal_dictionary& dict) {
    for (item_set::const_iterator it = la.begin(); it != la.end(); it++) {
        wcerr << L" ";
        dump(**it, gram, dict);
    }
}

static void dump(const rule& rule, const grammar& gram, const terminal_dictionary& dict) {
    wcerr << gram.identifier_for_rule(rule) << L": ";
    dump(*rule.nonterminal(), gram, dict);

    wcerr << L" ->";
    int pos;
    for (pos = 0; pos < rule.items().size(); pos++) {
        wcerr << L" ";
        dump(*rule.items()[pos], gram, dict);
    }
}

static void dump(const lr0_item& item, const item_set& la, const grammar& gram, const terminal_dictionary& dict) {
    wcerr << gram.identifier_for_rule(item.rule()) << L": ";
    dump(*item.rule()->nonterminal(), gram, dict);

    wcerr << L" ->";
    int pos;
    for (pos = 0; pos < item.rule()->items().size(); pos++) {
        if (pos == item.offset()) wcerr << L" *";
        wcerr << L" ";
        dump(*item.rule()->items()[pos], gram, dict);
    }
    if (pos == item.offset()) wcerr << L" *";

    wcerr << L",";
    dump(la, gram, dict);

    wcerr << L" [";
    if (item.offset() < item.rule()->items().size()) {
        dump(*item.rule()->items()[item.offset()], gram, dict);
        wcerr << L" >FIRST>";
        dump(gram.first(*item.rule()->items()[item.offset()]), gram, dict);
    }
    wcerr << L"]";
}

static void dump(const lr_action_set& actions, const grammar& gram, const terminal_dictionary& dict) {
    for (lr_action_set::const_iterator it = actions.begin(); it != actions.end(); it++) {
        wcerr << L"  ";
        switch ((*it)->type()) {
            case lr_action::act_accept:
                wcerr << L"ACCEPT ";
                break;
            case lr_action::act_reduce:
                wcerr << L"REDUCE ";
                break;
            case lr_action::act_shift:
                wcerr << L"SHIFT ";
                break;
            case lr_action::act_weakreduce:
                wcerr << L"WEAK REDUCE ";
                break;
            case lr_action::act_goto:
                wcerr << L"GOTO ";
                break;
            case lr_action::act_ignore:
                wcerr << L"IGNORE ";
                break;
        }
        dump(*(*it)->item(), gram, dict);

        if ((*it)->type() == lr_action::act_reduce || (*it)->type() == lr_action::act_weakreduce) {
            wcerr << L" on ";
            dump(*(*it)->rule(), gram, dict);
        } else {
            wcerr << L" -> " << (*it)->next_state();
        }
        wcerr << endl;
    }
}

/// \brief Dumps out a state machine to wcerr
static void dump_machine(const lalr_builder& builder) {
    item_set empty_set;
    empty_item empty;
    empty_set.insert(empty);
    const lalr_machine& machine = builder.machine();

    for (int stateId = 0; stateId < machine.count_states(); stateId++) {
        wcerr << L"STATE " << stateId << endl;

        const lalr_state& state = *machine.state_with_id(stateId);
        lr1_item_set closure;

        for (lalr_state::set_iterator nextItem = state.begin_kernel(); nextItem != state.end_kernel(); nextItem++) {
            int itemId = nextItem->second;
            const lr0_item& item = *state[itemId];
            wcerr << L"  ";
            dump(item, state.lookahead_for(itemId), machine.gram(), builder.terminals());
            wcerr << endl;

            if (item.offset() < item.rule()->items().size()) {
                lr1_item lr1(item, empty_set);
                item.rule()->items()[item.offset()]->closure(lr1, closure, machine.gram());
            }
        }

        if (!closure.empty()) {
            wcerr << endl;
            for (lr1_item_set::iterator closed = closure.begin(); closed != closure.end(); closed++) {
                wcerr << L"  ";
                dump(**closed, (*closed)->lookahead(), machine.gram(), builder.terminals());
                wcerr << endl;
            }
        }

        wcerr << endl;

        dump(builder.actions_for_state(stateId), builder.gram(), builder.terminals());

        wcerr << endl;
    }
}

void test_lalr_general::run_tests() {
    // Grammar specified in example 4.46 of the dragon book
    grammar             dragon446;
    terminal_dictionary terms;

    nonterminal sPrime(dragon446.id_for_nonterminal(L"S'"));
    nonterminal s(dragon446.id_for_nonterminal(L"S"));
    nonterminal l(dragon446.id_for_nonterminal(L"L"));
    nonterminal r(dragon446.id_for_nonterminal(L"R"));

    int equalsId    = terms.add_symbol(L"'='");
    int timesId     = terms.add_symbol(L"'*'");
    int idId        = terms.add_symbol(L"'i'");

    terminal equals(equalsId);
    terminal times(timesId);
    terminal id(idId);

    // S' -> S
    (dragon446 += sPrime) << s;

    // S -> L = R | R
    (dragon446 += s) << l << equals << r;
    (dragon446 += s) << r;

    // L -> * R | id
    (dragon446 += l) << times << r;
    (dragon446 += l) << id;

    // R -> L
    (dragon446 += r) << l;

    // Build this grammar
    lalr_builder builder(dragon446, terms);

    // S' defines the language
    builder.add_initial_state(s);
    builder.complete_parser();

    dump_machine(builder);

    // Assert some things about the machine (specified in the dragon book)
    report("num-states", builder.machine().count_states() == 10); // Figure 4.42: the result should have 10 states

    // Create a parser for this grammar
    simple_parser p(builder);
    character_lexer lex;

    typedef basic_string<int> symbol_string;
    typedef basic_stringstream<int> symbol_stringstream;

    symbol_string test1;
    symbol_string test2;

    test1 += idId;
    test2 += timesId;
    test2 += idId;
    test2 += equalsId;
    test2 += idId;

    symbol_stringstream stream1(test1);
    symbol_stringstream stream2(test2);

    simple_parser::state* parse1 = p.create_parser(new simple_parser_actions(lex.create_stream_from(stream1)));
    simple_parser::state* parse2 = p.create_parser(new simple_parser_actions(lex.create_stream_from(stream2)));

    // Test the parser
    report("accept1", parse1->parse());
    report("accept2", parse2->parse());

    delete parse1;
    delete parse2;

#if 0
    // Run the parser 50000 times
    for (int x=0; x<50000; x++) {
        stringstream stream2(test2);
        simple_parser::state* parse2 = p.create_parser(new simple_parser_actions(lex.create_stream_from(stream2)));

        parse2->parse();
        delete parse2;
    }

    // Build the parser 10000 times
    for (int x=0; x<10000; x++) {
        // Build this grammar
        lalr_builder builder(dragon446);

        // S' defines the language
        builder.add_initial_state(s);
        builder.complete_parser();
    }
#endif
}
<commit_msg>Added more tests, to detect if there are any duplicate states (there are, and that's why I think the generator is failing at the moment), or if there's a case where state ordering doesn't work (there isn't at present)<commit_after>//
//  lr_lalr_general.cpp
//  Parse
//
//  Created by Andrew Hunter on 02/05/2011.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#include <sstream>
#include <iostream>

#include "lr_lalr_general.h"

#include "Dfa/character_lexer.h"
#include "ContextFree/grammar.h"
#include "Lr/lalr_builder.h"
#include "Lr/parser.h"
#include "Language/formatter.h"

using namespace std;
using namespace dfa;
using namespace contextfree;
using namespace language;
using namespace lr;

static void dump(const item& it, const grammar& gram, const terminal_dictionary& dict) {
    if (it.type() == item::nonterminal) {
        wcerr << gram.name_for_nonterminal(it.symbol());
        wcerr << "(" << gram.identifier_for_item(it) << L")";
    } else if (it.type() == item::terminal) {
        wcerr << dict.name_for_symbol(it.symbol());
    } else if (it.type() == item::eoi) {
        wcerr << L"$";
        wcerr << "(" << gram.identifier_for_item(it) << L")";
    } else if (it.type() == item::empty) {
        wcerr << L"#";
        wcerr << "(" << gram.identifier_for_item(it) << L")";
    } else {
        wcerr << L"?";
        wcerr << "(" << gram.identifier_for_item(it) << L")";
    }
}

static void dump(const item_set& la, const grammar& gram, const terminal_dictionary& dict) {
    for (item_set::const_iterator it = la.begin(); it != la.end(); it++) {
        wcerr << L" ";
        dump(**it, gram, dict);
    }
}

static void dump(const rule& rule, const grammar& gram, const terminal_dictionary& dict) {
    wcerr << gram.identifier_for_rule(rule) << L": ";
    dump(*rule.nonterminal(), gram, dict);

    wcerr << L" ->";
    int pos;
    for (pos = 0; pos < rule.items().size(); pos++) {
        wcerr << L" ";
        dump(*rule.items()[pos], gram, dict);
    }
}

static void dump(const lr0_item& item, const item_set& la, const grammar& gram, const terminal_dictionary& dict) {
    wcerr << gram.identifier_for_rule(item.rule()) << L": ";
    dump(*item.rule()->nonterminal(), gram, dict);

    wcerr << L" ->";
    int pos;
    for (pos = 0; pos < item.rule()->items().size(); pos++) {
        if (pos == item.offset()) wcerr << L" *";
        wcerr << L" ";
        dump(*item.rule()->items()[pos], gram, dict);
    }
    if (pos == item.offset()) wcerr << L" *";

    wcerr << L",";
    dump(la, gram, dict);

    wcerr << L" [";
    if (item.offset() < item.rule()->items().size()) {
        dump(*item.rule()->items()[item.offset()], gram, dict);
        wcerr << L" >FIRST>";
        dump(gram.first(*item.rule()->items()[item.offset()]), gram, dict);
    }
    wcerr << L"]";
}

static void dump(const lr_action_set& actions, const grammar& gram, const terminal_dictionary& dict) {
    for (lr_action_set::const_iterator it = actions.begin(); it != actions.end(); it++) {
        wcerr << L"  ";
        switch ((*it)->type()) {
            case lr_action::act_accept:
                wcerr << L"ACCEPT ";
                break;
            case lr_action::act_reduce:
                wcerr << L"REDUCE ";
                break;
            case lr_action::act_shift:
                wcerr << L"SHIFT ";
                break;
            case lr_action::act_weakreduce:
                wcerr << L"WEAK REDUCE ";
                break;
            case lr_action::act_goto:
                wcerr << L"GOTO ";
                break;
            case lr_action::act_ignore:
                wcerr << L"IGNORE ";
                break;
        }
        dump(*(*it)->item(), gram, dict);

        if ((*it)->type() == lr_action::act_reduce || (*it)->type() == lr_action::act_weakreduce) {
            wcerr << L" on ";
            dump(*(*it)->rule(), gram, dict);
        } else {
            wcerr << L" -> " << (*it)->next_state();
        }
        wcerr << endl;
    }
}

/// \brief Dumps out a state machine to wcerr
static void dump_machine(const lalr_builder& builder) {
    item_set empty_set;
    empty_item empty;
    empty_set.insert(empty);
    const lalr_machine& machine = builder.machine();

    for (int stateId = 0; stateId < machine.count_states(); stateId++) {
        wcerr << L"STATE " << stateId << endl;

        const lalr_state& state = *machine.state_with_id(stateId);
        lr1_item_set closure;

        for (lalr_state::set_iterator nextItem = state.begin_kernel(); nextItem != state.end_kernel(); nextItem++) {
            int itemId = nextItem->second;
            const lr0_item& item = *state[itemId];
            wcerr << L"  ";
            dump(item, state.lookahead_for(itemId), machine.gram(), builder.terminals());
            wcerr << endl;

            if (item.offset() < item.rule()->items().size()) {
                lr1_item lr1(item, empty_set);
                item.rule()->items()[item.offset()]->closure(lr1, closure, machine.gram());
            }
        }

        if (!closure.empty()) {
            wcerr << endl;
            for (lr1_item_set::iterator closed = closure.begin(); closed != closure.end(); closed++) {
                wcerr << L"  ";
                dump(**closed, (*closed)->lookahead(), machine.gram(), builder.terminals());
                wcerr << endl;
            }
        }

        wcerr << endl;

        dump(builder.actions_for_state(stateId), builder.gram(), builder.terminals());

        wcerr << endl;
    }
}

static bool state_comparison_always_reversible(lalr_machine& m) {
    // If state X is less than state Y then state Y must not be less than state X
    for (int stateX = 0; stateX < m.count_states(); stateX++) {
        const lalr_state& stateXreal = *m.state_with_id(stateX);

        for (int stateY = 0; stateY < m.count_states(); stateY++) {
            const lalr_state& stateYreal = *m.state_with_id(stateY);

            if (stateXreal < stateYreal) {
                if (stateYreal < stateXreal) {
                    // DOH!
                    wcerr << stateX << L" is less than " << stateY << L" but is also greater than or equal to it!" << endl;
                    return false;
                }
            }
        }
    }

    return true;
}

static bool no_duplicate_states(lalr_machine& m) {
    // State X and state Y can only be the same if they have the same ID
    bool ok = true;

    for (int stateX = 0; stateX < m.count_states(); stateX++) {
        const lalr_state& stateXreal = *m.state_with_id(stateX);

        for (int stateY = 0; stateY < m.count_states(); stateY++) {
            const lalr_state& stateYreal = *m.state_with_id(stateY);

            if (stateXreal == stateYreal) {
                if (stateX != stateY) {
                    // DOH!
                    wcerr << stateX << L" is a duplicate of " << stateY << endl;
                    ok = false;
                }
            } else {
                if (stateX == stateY) {
                    // DOH!
                    wcerr << stateX << L" isn't equal to itself!" << endl;
                    ok = false;
                }
            }
        }
    }

    return ok;
}

void test_lalr_general::run_tests() {
    // Grammar specified in example 4.46 of the dragon book
    grammar             dragon446;
    terminal_dictionary terms;

    nonterminal sPrime(dragon446.id_for_nonterminal(L"S'"));
    nonterminal s(dragon446.id_for_nonterminal(L"S"));
    nonterminal l(dragon446.id_for_nonterminal(L"L"));
    nonterminal r(dragon446.id_for_nonterminal(L"R"));

    int equalsId    = terms.add_symbol(L"'='");
    int timesId     = terms.add_symbol(L"'*'");
    int idId        = terms.add_symbol(L"'i'");

    terminal equals(equalsId);
    terminal times(timesId);
    terminal id(idId);

    // S' -> S
    (dragon446 += sPrime) << s;

    // S -> L = R | R
    (dragon446 += s) << l << equals << r;
    (dragon446 += s) << r;

    // L -> * R | id
    (dragon446 += l) << times << r;
    (dragon446 += l) << id;

    // R -> L
    (dragon446 += r) << l;

    // Build this grammar
    lalr_builder builder(dragon446, terms);

    // S' defines the language
    builder.add_initial_state(s);
    builder.complete_parser();

    dump_machine(builder);

    // Assert some things about the machine (specified in the dragon book)
    report("num-states", builder.machine().count_states() == 10); // Figure 4.42: the result should have 10 states
    report("not-equal-simple", (*builder.machine().state_with_id(1)) != (*builder.machine().state_with_id(6)));
    report("no-duplicate-states", no_duplicate_states(builder.machine()));
    report("state-ordering-works", state_comparison_always_reversible(builder.machine()));

    wcerr << formatter::to_string(*builder.machine().state_with_id(1), dragon446, terms) << endl;
    wcerr << formatter::to_string(*builder.machine().state_with_id(6), dragon446, terms) << endl;

    // Create a parser for this grammar
    simple_parser p(builder);
    character_lexer lex;

    typedef basic_string<int> symbol_string;
    typedef basic_stringstream<int> symbol_stringstream;

    symbol_string test1;
    symbol_string test2;

    test1 += idId;
    test2 += timesId;
    test2 += idId;
    test2 += equalsId;
    test2 += idId;

    symbol_stringstream stream1(test1);
    symbol_stringstream stream2(test2);

    simple_parser::state* parse1 = p.create_parser(new simple_parser_actions(lex.create_stream_from(stream1)));
    simple_parser::state* parse2 = p.create_parser(new simple_parser_actions(lex.create_stream_from(stream2)));

    // Test the parser
    report("accept1", parse1->parse());
    report("accept2", parse2->parse());

    delete parse1;
    delete parse2;

#if 0
    // Run the parser 50000 times
    for (int x=0; x<50000; x++) {
        stringstream stream2(test2);
        simple_parser::state* parse2 = p.create_parser(new simple_parser_actions(lex.create_stream_from(stream2)));

        parse2->parse();
        delete parse2;
    }

    // Build the parser 10000 times
    for (int x=0; x<10000; x++) {
        // Build this grammar
        lalr_builder builder(dragon446);

        // S' defines the language
        builder.add_initial_state(s);
        builder.complete_parser();
    }
#endif
}
<|endoftext|>


<commit_before><commit_msg>missed one<commit_after><|endoftext|>


<commit_before>// Copyright 2017 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <gtest/gtest.h>

#include <stdexcept>

#include "rcl/expand_topic_name.h"
#include "rcl/validate_topic_name.h"
#include "rmw/validate_full_topic_name.h"
#include "rmw/validate_namespace.h"
#include "rmw/validate_node_name.h"

#include "rclcpp/exceptions.hpp"
#include "rclcpp/expand_topic_or_service_name.hpp"

#include "../mocking_utils/patch.hpp"
#include "../utils/rclcpp_gtest_macros.hpp"

/*
   Testing expand_topic_or_service_name.
 */
TEST(TestExpandTopicOrServiceName, normal) {
  using rclcpp::expand_topic_or_service_name;
  {
    ASSERT_EQ("/ns/chatter", expand_topic_or_service_name("chatter", "node", "/ns"));
  }
}

/*
   Testing exceptions of expand_topic_or_service_name.
 */
TEST(TestExpandTopicOrServiceName, exceptions) {
  using rclcpp::expand_topic_or_service_name;
  {
    ASSERT_THROW(
    {
      expand_topic_or_service_name("chatter", "invalid_node?", "/ns");
    }, rclcpp::exceptions::InvalidNodeNameError);
  }

  {
    ASSERT_THROW(
    {
      expand_topic_or_service_name("chatter", "node", "/invalid_ns?");
    }, rclcpp::exceptions::InvalidNamespaceError);
  }

  {
    ASSERT_THROW(
    {
      expand_topic_or_service_name("chatter/42invalid", "node", "/ns");
    }, rclcpp::exceptions::InvalidTopicNameError);
  }

  {
    ASSERT_THROW(
    {
      // this one will only fail on the "full" topic name validation check
      expand_topic_or_service_name("chatter/{ns}/invalid", "node", "/ns");
    }, rclcpp::exceptions::InvalidTopicNameError);
  }

  {
    ASSERT_THROW(
    {
      // is_service = true
      expand_topic_or_service_name("chatter/42invalid", "node", "/ns", true);
    }, rclcpp::exceptions::InvalidServiceNameError);
  }

  {
    ASSERT_THROW(
    {
      // is_service = true
      // this one will only fail on the "full" topic name validation check
      expand_topic_or_service_name("chatter/{ns}/invalid", "node", "/ns", true);
    }, rclcpp::exceptions::InvalidServiceNameError);
  }
}

// Required for mocking_utils below
MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcutils_allocator_t, ==)
MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcutils_allocator_t, !=)
MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcutils_allocator_t, <)
MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcutils_allocator_t, >)

TEST(TestExpandTopicOrServiceName, rcutils_string_map_init_fail_bad_alloc) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcutils_string_map_init, RCUTILS_RET_BAD_ALLOC);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    std::bad_alloc());
}

TEST(TestExpandTopicOrServiceName, rcutils_string_map_init_fail_other) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcutils_string_map_init, RCUTILS_RET_ERROR);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    std::runtime_error("error not set"));
}

TEST(TestExpandTopicOrServiceName, rcl_get_default_topic_name_substitution_fail) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_get_default_topic_name_substitutions, RCL_RET_ERROR);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    std::runtime_error("error not set"));
}

TEST(TestExpandTopicOrServiceName, rcl_get_default_topic_name_substitution_and_map_fini_fail) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_get_default_topic_name_substitutions, RCL_RET_ERROR);
  auto mock2 = mocking_utils::patch_and_return(
    "lib:rclcpp", rcutils_string_map_fini, RCUTILS_RET_ERROR);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    std::runtime_error("error not set"));
}

TEST(TestExpandTopicOrServiceName, rcutils_string_map_fini_fail_bad_alloc) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcutils_string_map_fini, RCUTILS_RET_ERROR);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    std::runtime_error("error not set"));
}

TEST(TestExpandTopicOrServiceName, rmw_valid_full_topic_name_fail_invalid_argument) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rmw_validate_full_topic_name, RMW_RET_INVALID_ARGUMENT);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    rclcpp::exceptions::RCLInvalidArgument(
      RCL_RET_INVALID_ARGUMENT, rcl_get_error_state(), "failed to validate full topic name"));
}

TEST(TestExpandTopicOrServiceName, rcl_expand_topic_name_fail) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_expand_topic_name, RCL_RET_TOPIC_NAME_INVALID);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    std::runtime_error("topic name unexpectedly valid"));
}

TEST(TestExpandTopicOrServiceName, rcl_validate_topic_name_fail) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_expand_topic_name, RCL_RET_TOPIC_NAME_INVALID);
  auto mock2 = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_validate_topic_name, RCL_RET_ERROR);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    rclcpp::exceptions::RCLError(
      RCL_RET_ERROR, rcl_get_error_state(), "failed to validate full topic name"));
}

TEST(TestExpandTopicOrServiceName, rmw_validate_node_name_fail_invalid_argument) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_expand_topic_name, RCL_RET_NODE_INVALID_NAME);
  auto mock2 = mocking_utils::patch_and_return(
    "lib:rclcpp", rmw_validate_node_name, RMW_RET_INVALID_ARGUMENT);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    rclcpp::exceptions::RCLInvalidArgument(
      RCL_RET_INVALID_ARGUMENT, rcl_get_error_state(), "failed to validate node name"));
}

TEST(TestExpandTopicOrServiceName, rmw_validate_node_name_fail_other) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_expand_topic_name, RCL_RET_NODE_INVALID_NAME);
  auto mock2 = mocking_utils::patch_and_return(
    "lib:rclcpp", rmw_validate_node_name, RMW_RET_ERROR);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    rclcpp::exceptions::RCLError(
      RCL_RET_ERROR, rcl_get_error_state(), "failed to validate node name"));
}

TEST(TestExpandTopicOrServiceName, rmw_validate_namespace_fail_invalid_argument) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_expand_topic_name, RCL_RET_NODE_INVALID_NAMESPACE);
  auto mock2 = mocking_utils::patch_and_return(
    "lib:rclcpp", rmw_validate_namespace, RMW_RET_INVALID_ARGUMENT);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    rclcpp::exceptions::RCLInvalidArgument(
      RCL_RET_INVALID_ARGUMENT, rcl_get_error_state(), "failed to validate namespace"));
}

TEST(TestExpandTopicOrServiceName, rmw_validate_namespace_fail_other) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_expand_topic_name, RCL_RET_NODE_INVALID_NAMESPACE);
  auto mock2 = mocking_utils::patch_and_return(
    "lib:rclcpp", rmw_validate_namespace, RMW_RET_ERROR);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    rclcpp::exceptions::RCLError(
      RCL_RET_ERROR, rcl_get_error_state(), "failed to validate namespace"));
}

TEST(TestExpandTopicOrServiceName, rcl_expand_topic_name_fail_other) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_expand_topic_name, RCL_RET_ERROR);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    rclcpp::exceptions::RCLError(RCL_RET_ERROR, rcl_get_error_state(), "error not set"));
}

TEST(TestExpandTopicOrServiceName, rmw_validate_full_topic_name_fail_other) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rmw_validate_full_topic_name, RMW_RET_ERROR);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    rclcpp::exceptions::RCLError(
      RCL_RET_ERROR, rcl_get_error_state(), "failed to validate full topic name"));
}
<commit_msg>Add in two more tests for expand_topic_or_service_name. (#1350)<commit_after>// Copyright 2017 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <gtest/gtest.h>

#include <stdexcept>

#include "rcl/expand_topic_name.h"
#include "rcl/validate_topic_name.h"
#include "rmw/validate_full_topic_name.h"
#include "rmw/validate_namespace.h"
#include "rmw/validate_node_name.h"

#include "rclcpp/exceptions.hpp"
#include "rclcpp/expand_topic_or_service_name.hpp"

#include "../mocking_utils/patch.hpp"
#include "../utils/rclcpp_gtest_macros.hpp"

/*
   Testing expand_topic_or_service_name.
 */
TEST(TestExpandTopicOrServiceName, normal) {
  using rclcpp::expand_topic_or_service_name;
  {
    ASSERT_EQ("/ns/chatter", expand_topic_or_service_name("chatter", "node", "/ns"));
  }
}

/*
   Testing exceptions of expand_topic_or_service_name.
 */
TEST(TestExpandTopicOrServiceName, exceptions) {
  using rclcpp::expand_topic_or_service_name;
  {
    ASSERT_THROW(
    {
      expand_topic_or_service_name("chatter", "invalid_node?", "/ns");
    }, rclcpp::exceptions::InvalidNodeNameError);
  }

  {
    ASSERT_THROW(
    {
      expand_topic_or_service_name("chatter", "node", "/invalid_ns?");
    }, rclcpp::exceptions::InvalidNamespaceError);
  }

  {
    ASSERT_THROW(
    {
      expand_topic_or_service_name("chatter/42invalid", "node", "/ns");
    }, rclcpp::exceptions::InvalidTopicNameError);
  }

  {
    ASSERT_THROW(
    {
      // this one will only fail on the "full" topic name validation check
      expand_topic_or_service_name("chatter/{ns}/invalid", "node", "/ns");
    }, rclcpp::exceptions::InvalidTopicNameError);
  }

  {
    ASSERT_THROW(
    {
      // is_service = true
      expand_topic_or_service_name("chatter/42invalid", "node", "/ns", true);
    }, rclcpp::exceptions::InvalidServiceNameError);
  }

  {
    ASSERT_THROW(
    {
      // is_service = true
      // this one will only fail on the "full" topic name validation check
      expand_topic_or_service_name("chatter/{ns}/invalid", "node", "/ns", true);
    }, rclcpp::exceptions::InvalidServiceNameError);
  }
}

// Required for mocking_utils below
MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcutils_allocator_t, ==)
MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcutils_allocator_t, !=)
MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcutils_allocator_t, <)
MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcutils_allocator_t, >)

TEST(TestExpandTopicOrServiceName, rcutils_string_map_init_fail_bad_alloc) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcutils_string_map_init, RCUTILS_RET_BAD_ALLOC);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    std::bad_alloc());
}

TEST(TestExpandTopicOrServiceName, rcutils_string_map_init_fail_other) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcutils_string_map_init, RCUTILS_RET_ERROR);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    std::runtime_error("error not set"));
}

TEST(TestExpandTopicOrServiceName, rcl_get_default_topic_name_substitution_fail) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_get_default_topic_name_substitutions, RCL_RET_ERROR);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    std::runtime_error("error not set"));
}

TEST(TestExpandTopicOrServiceName, rcl_get_default_topic_name_substitution_and_map_fini_fail) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_get_default_topic_name_substitutions, RCL_RET_ERROR);
  auto mock2 = mocking_utils::patch_and_return(
    "lib:rclcpp", rcutils_string_map_fini, RCUTILS_RET_ERROR);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    std::runtime_error("error not set"));
}

TEST(TestExpandTopicOrServiceName, rcutils_string_map_fini_fail_bad_alloc) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcutils_string_map_fini, RCUTILS_RET_ERROR);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    std::runtime_error("error not set"));
}

TEST(TestExpandTopicOrServiceName, rmw_valid_full_topic_name_fail_invalid_argument) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rmw_validate_full_topic_name, RMW_RET_INVALID_ARGUMENT);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    rclcpp::exceptions::RCLInvalidArgument(
      RCL_RET_INVALID_ARGUMENT, rcl_get_error_state(), "failed to validate full topic name"));
}

TEST(TestExpandTopicOrServiceName, rcl_expand_topic_name_fail) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_expand_topic_name, RCL_RET_TOPIC_NAME_INVALID);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    std::runtime_error("topic name unexpectedly valid"));
}

TEST(TestExpandTopicOrServiceName, rcl_validate_topic_name_fail) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_expand_topic_name, RCL_RET_TOPIC_NAME_INVALID);
  auto mock2 = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_validate_topic_name, RCL_RET_ERROR);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    rclcpp::exceptions::RCLError(
      RCL_RET_ERROR, rcl_get_error_state(), "failed to validate full topic name"));
}

TEST(TestExpandTopicOrServiceName, rmw_validate_node_name_fail_invalid_argument) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_expand_topic_name, RCL_RET_NODE_INVALID_NAME);
  auto mock2 = mocking_utils::patch_and_return(
    "lib:rclcpp", rmw_validate_node_name, RMW_RET_INVALID_ARGUMENT);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    rclcpp::exceptions::RCLInvalidArgument(
      RCL_RET_INVALID_ARGUMENT, rcl_get_error_state(), "failed to validate node name"));
}

TEST(TestExpandTopicOrServiceName, rmw_validate_node_name_fail_other) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_expand_topic_name, RCL_RET_NODE_INVALID_NAME);
  auto mock2 = mocking_utils::patch_and_return(
    "lib:rclcpp", rmw_validate_node_name, RMW_RET_ERROR);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    rclcpp::exceptions::RCLError(
      RCL_RET_ERROR, rcl_get_error_state(), "failed to validate node name"));
}

TEST(TestExpandTopicOrServiceName, rmw_validate_namespace_fail_invalid_argument) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_expand_topic_name, RCL_RET_NODE_INVALID_NAMESPACE);
  auto mock2 = mocking_utils::patch_and_return(
    "lib:rclcpp", rmw_validate_namespace, RMW_RET_INVALID_ARGUMENT);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    rclcpp::exceptions::RCLInvalidArgument(
      RCL_RET_INVALID_ARGUMENT, rcl_get_error_state(), "failed to validate namespace"));
}

TEST(TestExpandTopicOrServiceName, rmw_validate_namespace_fail_other) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_expand_topic_name, RCL_RET_NODE_INVALID_NAMESPACE);
  auto mock2 = mocking_utils::patch_and_return(
    "lib:rclcpp", rmw_validate_namespace, RMW_RET_ERROR);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    rclcpp::exceptions::RCLError(
      RCL_RET_ERROR, rcl_get_error_state(), "failed to validate namespace"));
}

TEST(TestExpandTopicOrServiceName, rcl_expand_topic_name_fail_other) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_expand_topic_name, RCL_RET_ERROR);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    rclcpp::exceptions::RCLError(RCL_RET_ERROR, rcl_get_error_state(), "error not set"));
}

TEST(TestExpandTopicOrServiceName, rcl_expand_topic_name_fail_invalid_node_name) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_expand_topic_name, RCL_RET_NODE_INVALID_NAME);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    std::runtime_error("invalid rcl node name but valid rmw node name"));
}

TEST(TestExpandTopicOrServiceName, rcl_expand_topic_name_fail_invalid_node_namespace) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rcl_expand_topic_name, RCL_RET_NODE_INVALID_NAMESPACE);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    std::runtime_error("invalid rcl namespace but valid rmw namespace"));
}

TEST(TestExpandTopicOrServiceName, rmw_validate_full_topic_name_fail_other) {
  auto mock = mocking_utils::patch_and_return(
    "lib:rclcpp", rmw_validate_full_topic_name, RMW_RET_ERROR);
  RCLCPP_EXPECT_THROW_EQ(
    rclcpp::expand_topic_or_service_name("chatter", "node", "/ns"),
    rclcpp::exceptions::RCLError(
      RCL_RET_ERROR, rcl_get_error_state(), "failed to validate full topic name"));
}
<|endoftext|>


<commit_before>#include "elem.hpp"

QComboBox *file_list() {
    QStringList string = QStringList() << "BINARY" << "MOTOROLA"
                                         << "AIFF" << "WAVE" << "MP3";
    QComboBox* combo = new QComboBox();
    combo->addItems(string);
    return combo;
}

QComboBox *track_list() {
    QStringList string = QStringList() << "AUDIO" << "CDG"
                                         << "MODE1/2048" << "MODE1/2352"
                                         << "MODE2/2336" << "MODE2/2352"
                                         << "CDI/2336" << "CDI/2352";
    QComboBox* combo = new QComboBox();
    combo->addItems(string);
    return combo;
}

QComboBox *genre_list() {
    QStringList string = QStringList() << "" << "GENRE1" << "GENRE2" << "GENRE3";
    QComboBox* combo = new QComboBox();
    combo->addItems(string);
    combo->setEditable(true);
    return combo;
}

QString GetFileName() {
    QString file_name = QFileDialog::getOpenFileName(0,"Name","cdda.wav","Audio File (*.wav *.flac *.ape)");
    int begin = file_name.lastIndexOf(QDir::separator());
    if (begin == -1)
        begin = 0;
    return file_name.mid(begin+1);
}

bool ParseMiddle(QString expstr, QString &var, QString line, int begin) {
    QRegExp regexp;
    QStringList list;
    regexp.setPattern(expstr);
    if (line.contains(regexp))
    {
        list = line.split(" ",QString::SkipEmptyParts);
        line = list.at(begin);
        for (int x = begin+1; x < list.size()-1; ++x)
            line += " " + list.at(x);
        list = line.split("\"",QString::SkipEmptyParts);
        var = list.at(0);
        return true;
    } else
        return false;
}

bool ParseLast(QString expstr, QString &var, QString line) {
    QRegExp regexp;
    QStringList list;
    regexp.setPattern(expstr);
    if (line.contains(regexp))
    {
        list = line.split(" ",QString::SkipEmptyParts);
        line = list.back();
        list = line.split("\"",QString::SkipEmptyParts);
        var = list.at(0);
        return true;
    } else
        return false;
}

bool ParseLast(QString expstr, QString &var, QString line, int begin) {
    QRegExp regexp;
    QStringList list;
    regexp.setPattern(expstr);
    if (line.contains(regexp))
    {
        list = line.split(" ",QString::SkipEmptyParts);
        line = list.at(begin);
        for (int x = begin+1; x < list.size(); ++x)
            line += " " + list.at(x);
        list = line.split("\"",QString::SkipEmptyParts);
        var = list.at(0);
        return true;
    } else
        return false;
}

bool MMSSFF_valid(QString line) {
    if (line.count() != 8)
        return false;
    QStringList list = line.split(":",QString::SkipEmptyParts);
    if (list.size() != 3)
        return false;
    bool ok = true;
    int time = 0;
    time = list.at(0).toInt(&ok);
    if ((ok)&&(time>=0)&&(time<=99)) {
        time = list.at(1).toInt(&ok);
        if ((ok)&&(time>=0)&&(time<=59)) {
            time = list.at(2).toInt(&ok);
            if ((ok)&&(time>=0)&&(time<=74)) {
                return true;
            }
        }
    }
    return false;
}

QString MMSSFF_sum(QString line1, QString line2, bool &ok) {
    ok = true;
    QString retstr = "00:00:00";
    QStringList list1;
    QStringList list2;
    int mm = 0, ss = 0, ff = 0;
    if ((MMSSFF_valid(line1))&&(MMSSFF_valid(line2))) {
        list1 = line1.split(":",QString::SkipEmptyParts);
        list2 = line2.split(":",QString::SkipEmptyParts);
        mm = list1.at(0).toInt() + list2.at(0).toInt();
        ss = list1.at(1).toInt() + list2.at(1).toInt();
        ff = list1.at(2).toInt() + list2.at(2).toInt();
        if (ff > 74) {
            ff = ff - 75;
            ss = ss + 1;
        }
        if (ss > 59) {
            ss = ss - 60;
            mm = mm + 1;
        }
        if (mm > 99)
            ok = false;
        else {
            retstr.clear();
            if (mm < 10)
                retstr += "0";
            retstr += QString::number(mm) + ":";
            if (ss < 10)
                retstr += "0";
            retstr += QString::number(ss) + ":";
            if (ff < 10)
                retstr += "0";
            retstr += QString::number(ff);
        }
    } else
        ok = false;
    return retstr;
}

QString MMSSFF_diff(QString line1, QString line2, bool &ok) {
    ok = true;
    QString retstr = "00:00:00";
    QStringList list1;
    QStringList list2;
    int mm = 0, ss = 0, ff = 0;
    if ((MMSSFF_valid(line1))&&(MMSSFF_valid(line2))) {
        list1 = line1.split(":",QString::SkipEmptyParts);
        list2 = line2.split(":",QString::SkipEmptyParts);
        mm = list1.at(0).toInt() - list2.at(0).toInt();
        ss = list1.at(1).toInt() - list2.at(1).toInt();
        ff = list1.at(2).toInt() - list2.at(2).toInt();
        if (ff < 0) {
            ff = 75 + ff;
            ss = ss - 1;
        }
        if (ss < 0) {
            ss = 60 + ss;
            mm = mm - 1;
        }
        if (mm < 0)
            ok = false;
        else {
            if (mm < 10)
                retstr = "0";
            retstr += QString::number(mm) + ":";
            if (ss < 10)
                retstr += "0";
            retstr += QString::number(ss) + ":";
            if (ff < 10)
                retstr += "0";
            retstr += QString::number(ff);
        }
    } else
        ok = false;
    return retstr;
}
<commit_msg>update genres list<commit_after>#include "elem.hpp"

QComboBox *file_list() {
    QStringList string = QStringList() << "BINARY" << "MOTOROLA"
                                         << "AIFF" << "WAVE" << "MP3";
    QComboBox* combo = new QComboBox();
    combo->addItems(string);
    return combo;
}

QComboBox *track_list() {
    QStringList string = QStringList() << "AUDIO" << "CDG"
                                         << "MODE1/2048" << "MODE1/2352"
                                         << "MODE2/2336" << "MODE2/2352"
                                         << "CDI/2336" << "CDI/2352";
    QComboBox* combo = new QComboBox();
    combo->addItems(string);
    return combo;
}

QComboBox *genre_list() {
    QStringList string = QStringList() << ""
                                       << "Blues"
                                       << "Classical"
                                       << "Country"
                                       << "Electronic"
                                       << "Folk"
                                       << "Funk"
                                       << "Hip-Hop"
                                       << "Jazz"
                                       << "Latin"
                                       << "New-Age"
                                       << "Pop"
                                       << "R&B"
                                       << "Reggae"
                                       << "Rock"
                                       << "Soundtrack";
    QComboBox* combo = new QComboBox();
    combo->addItems(string);
    combo->setEditable(true);
    return combo;
}

QString GetFileName() {
    QString file_name = QFileDialog::getOpenFileName(0,"Name","cdda.wav","Audio File (*.wav *.flac *.ape)");
    int begin = file_name.lastIndexOf(QDir::separator());
    if (begin == -1)
        begin = 0;
    return file_name.mid(begin+1);
}

bool ParseMiddle(QString expstr, QString &var, QString line, int begin) {
    QRegExp regexp;
    QStringList list;
    regexp.setPattern(expstr);
    if (line.contains(regexp))
    {
        list = line.split(" ",QString::SkipEmptyParts);
        line = list.at(begin);
        for (int x = begin+1; x < list.size()-1; ++x)
            line += " " + list.at(x);
        list = line.split("\"",QString::SkipEmptyParts);
        var = list.at(0);
        return true;
    } else
        return false;
}

bool ParseLast(QString expstr, QString &var, QString line) {
    QRegExp regexp;
    QStringList list;
    regexp.setPattern(expstr);
    if (line.contains(regexp))
    {
        list = line.split(" ",QString::SkipEmptyParts);
        line = list.back();
        list = line.split("\"",QString::SkipEmptyParts);
        var = list.at(0);
        return true;
    } else
        return false;
}

bool ParseLast(QString expstr, QString &var, QString line, int begin) {
    QRegExp regexp;
    QStringList list;
    regexp.setPattern(expstr);
    if (line.contains(regexp))
    {
        list = line.split(" ",QString::SkipEmptyParts);
        line = list.at(begin);
        for (int x = begin+1; x < list.size(); ++x)
            line += " " + list.at(x);
        list = line.split("\"",QString::SkipEmptyParts);
        var = list.at(0);
        return true;
    } else
        return false;
}

bool MMSSFF_valid(QString line) {
    if (line.count() != 8)
        return false;
    QStringList list = line.split(":",QString::SkipEmptyParts);
    if (list.size() != 3)
        return false;
    bool ok = true;
    int time = 0;
    time = list.at(0).toInt(&ok);
    if ((ok)&&(time>=0)&&(time<=99)) {
        time = list.at(1).toInt(&ok);
        if ((ok)&&(time>=0)&&(time<=59)) {
            time = list.at(2).toInt(&ok);
            if ((ok)&&(time>=0)&&(time<=74)) {
                return true;
            }
        }
    }
    return false;
}

QString MMSSFF_sum(QString line1, QString line2, bool &ok) {
    ok = true;
    QString retstr = "00:00:00";
    QStringList list1;
    QStringList list2;
    int mm = 0, ss = 0, ff = 0;
    if ((MMSSFF_valid(line1))&&(MMSSFF_valid(line2))) {
        list1 = line1.split(":",QString::SkipEmptyParts);
        list2 = line2.split(":",QString::SkipEmptyParts);
        mm = list1.at(0).toInt() + list2.at(0).toInt();
        ss = list1.at(1).toInt() + list2.at(1).toInt();
        ff = list1.at(2).toInt() + list2.at(2).toInt();
        if (ff > 74) {
            ff = ff - 75;
            ss = ss + 1;
        }
        if (ss > 59) {
            ss = ss - 60;
            mm = mm + 1;
        }
        if (mm > 99)
            ok = false;
        else {
            retstr.clear();
            if (mm < 10)
                retstr += "0";
            retstr += QString::number(mm) + ":";
            if (ss < 10)
                retstr += "0";
            retstr += QString::number(ss) + ":";
            if (ff < 10)
                retstr += "0";
            retstr += QString::number(ff);
        }
    } else
        ok = false;
    return retstr;
}

QString MMSSFF_diff(QString line1, QString line2, bool &ok) {
    ok = true;
    QString retstr = "00:00:00";
    QStringList list1;
    QStringList list2;
    int mm = 0, ss = 0, ff = 0;
    if ((MMSSFF_valid(line1))&&(MMSSFF_valid(line2))) {
        list1 = line1.split(":",QString::SkipEmptyParts);
        list2 = line2.split(":",QString::SkipEmptyParts);
        mm = list1.at(0).toInt() - list2.at(0).toInt();
        ss = list1.at(1).toInt() - list2.at(1).toInt();
        ff = list1.at(2).toInt() - list2.at(2).toInt();
        if (ff < 0) {
            ff = 75 + ff;
            ss = ss - 1;
        }
        if (ss < 0) {
            ss = 60 + ss;
            mm = mm - 1;
        }
        if (mm < 0)
            ok = false;
        else {
            if (mm < 10)
                retstr = "0";
            retstr += QString::number(mm) + ":";
            if (ss < 10)
                retstr += "0";
            retstr += QString::number(ss) + ":";
            if (ff < 10)
                retstr += "0";
            retstr += QString::number(ff);
        }
    } else
        ok = false;
    return retstr;
}
<|endoftext|>


<commit_before>#include <Benchmarks_adapters.hpp>

#include "OtherTranslationUnit.hpp"

class Benchmarks
{
public:
	typedef joint::TypeList<benchmarks::IBenchmarks>	JointInterfaces;

private:
	Joint_ModuleHandle   _module;

public:
	Benchmarks(Joint_ModuleHandle module)
		: _module(module)
	{ }

	~Benchmarks()
	{ }

	void NoParamsMethod() { }

	void MeasureNativeNoParams(int64_t n)
	{
		for (auto i = 0; i < n; ++i)
			NoParamsFunc();
	}

	void MeasureOutcomingNoParams(benchmarks::IInvokable_Ptr invokable, int64_t n)
	{
		for (auto i = 0; i < n; ++i)
			invokable->NoParamsMethod();
	}
};

extern "C"
{

#ifdef _MSC_VER
	__declspec(dllexport)
#endif
	Joint_ObjectHandle GetBenchmarks(Joint_ModuleHandle module)
	{ return joint::Export(joint::MakeComponent<joint::IObject, Benchmarks>(module, module)); }

}
<commit_msg>Added using namespace joint to Benchmarks.cpp<commit_after>#include <Benchmarks_adapters.hpp>

#include "OtherTranslationUnit.hpp"

using namespace joint;

class Benchmarks
{
public:
	typedef TypeList<benchmarks::IBenchmarks>	JointInterfaces;

private:
	Joint_ModuleHandle   _module;

public:
	Benchmarks(Joint_ModuleHandle module)
		: _module(module)
	{ }

	~Benchmarks()
	{ }

	void NoParamsMethod() { }

	void MeasureNativeNoParams(int64_t n)
	{
		for (auto i = 0; i < n; ++i)
			NoParamsFunc();
	}

	void MeasureOutcomingNoParams(benchmarks::IInvokable_Ptr invokable, int64_t n)
	{
		for (auto i = 0; i < n; ++i)
			invokable->NoParamsMethod();
	}
};

extern "C"
{

#ifdef _MSC_VER
	__declspec(dllexport)
#endif
	Joint_ObjectHandle GetBenchmarks(Joint_ModuleHandle module)
	{ return Export(MakeComponent<IObject, Benchmarks>(module, module)); }

}
<|endoftext|>