<commit_before>#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>

bool socketError = false;
bool socketBlocking = false;

int DDV_OpenUnix(std::string adres, bool nonblock = false){
  int s = socket(PF_UNIX, SOCK_STREAM, 0);
  sockaddr_un addr;
  addr.sun_family = AF_UNIX;
  strncpy(addr.sun_path, adres.c_str(), adres.size()+1);
  int r = connect(s, (sockaddr*)&addr, sizeof(addr));
  if (r == 0){
    if (nonblock){
      int flags = fcntl(s, F_GETFL, 0);
      flags |= O_NONBLOCK;
      fcntl(s, F_SETFL, flags);
    }
    return s;
  }else{
    close(s);
    return 0;
  }
}

int DDV_Listen(int port){
  int s = socket(AF_INET, SOCK_STREAM, 0);

  int on = 1;
  setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
  struct sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_port = htons(port);//port 8888
  inet_pton(AF_INET, "0.0.0.0", &addr.sin_addr);//listen on all interfaces
  int ret = bind(s, (sockaddr*)&addr, sizeof(addr));//bind to all interfaces, chosen port
  if (ret == 0){
    ret = listen(s, 100);//start listening, backlog of 100 allowed
    if (ret == 0){
      return s;
    }else{
      printf("Listen failed! Error: %s\n", strerror(errno));
      close(s);
      return 0;
    }
  }else{
    printf("Binding failed! Error: %s\n", strerror(errno));
    close(s);
    return 0;
  }
}

int DDV_Accept(int sock, bool nonblock = false){
  int r = accept(sock, 0, 0);
  if ((r > 0) && nonblock){
    int flags = fcntl(r, F_GETFL, 0);
    flags |= O_NONBLOCK;
    fcntl(r, F_SETFL, flags);
  }
  return r;
}

bool DDV_write(void * buffer, int todo, int sock){
  int sofar = 0;
  socketBlocking = false;
  while (sofar != todo){
    int r = send(sock, (char*)buffer + sofar, todo-sofar, 0);
    if (r <= 0){
      switch (errno){
        case EWOULDBLOCK: socketBlocking = true; break;
        default:
          socketError = true;
          printf("Could not write! %s\n", strerror(errno));
          return false;
          break;
      }
    }
    sofar += r;
  }
  return true;
}

bool DDV_ready(int sock){
  char tmp;
  int preflags = fcntl(sock, F_GETFL, 0);
  int postflags = preflags | O_NONBLOCK;
  fcntl(sock, F_SETFL, postflags);
  int r = recv(sock, &tmp, 1, MSG_PEEK);
  fcntl(sock, F_SETFL, preflags);
  return (r == 1);
}

bool DDV_read(void * buffer, int todo, int sock){
  int sofar = 0;
  socketBlocking = false;
  while (sofar != todo){
    int r = recv(sock, (char*)buffer + sofar, todo-sofar, 0);
    if (r <= 0){
      switch (errno){
        case EWOULDBLOCK: socketBlocking = true; break;
        default:
          socketError = true;
          printf("Could not read! %s\n", strerror(errno));
          return false;
          break;
      }
    }
    sofar += r;
  }
  return true;
}

bool DDV_read(void * buffer, int width, int count, int sock){return DDV_read(buffer, width*count, sock);}
bool DDV_write(void * buffer, int width, int count, int sock){return DDV_write(buffer, width*count, sock);}

int DDV_iwrite(void * buffer, int todo, int sock){
  int r = send(sock, buffer, todo, 0);
  if (r < 0){
    switch (errno){
      case EWOULDBLOCK: break;
      default:
        socketError = true;
        printf("Could not write! %s\n", strerror(errno));
        return false;
        break;
    }
  }
  return r;
}

int DDV_iread(void * buffer, int todo, int sock){
  int r = recv(sock, buffer, todo, 0);
  if (r < 0){
    switch (errno){
      case EWOULDBLOCK: break;
      default:
        socketError = true;
        printf("Could not read! %s\n", strerror(errno));
        return false;
        break;
    }
  }
  return r;
}

<commit_msg>Gadver<commit_after>#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>

bool socketError = false;
bool socketBlocking = false;

int DDV_OpenUnix(std::string adres, bool nonblock = false){
  int s = socket(PF_UNIX, SOCK_STREAM, 0);
  sockaddr_un addr;
  addr.sun_family = AF_UNIX;
  strncpy(addr.sun_path, adres.c_str(), adres.size()+1);
  int r = connect(s, (sockaddr*)&addr, sizeof(addr));
  if (r == 0){
    if (nonblock){
      int flags = fcntl(s, F_GETFL, 0);
      flags |= O_NONBLOCK;
      fcntl(s, F_SETFL, flags);
    }
    return s;
  }else{
    close(s);
    return 0;
  }
}

int DDV_Listen(int port){
  int s = socket(AF_INET, SOCK_STREAM, 0);

  int on = 1;
  setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
  struct sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_port = htons(port);//port 8888
  inet_pton(AF_INET, "0.0.0.0", &addr.sin_addr);//listen on all interfaces
  int ret = bind(s, (sockaddr*)&addr, sizeof(addr));//bind to all interfaces, chosen port
  if (ret == 0){
    ret = listen(s, 100);//start listening, backlog of 100 allowed
    if (ret == 0){
      return s;
    }else{
      printf("Listen failed! Error: %s\n", strerror(errno));
      close(s);
      return 0;
    }
  }else{
    printf("Binding failed! Error: %s\n", strerror(errno));
    close(s);
    return 0;
  }
}

int DDV_Accept(int sock, bool nonblock = false){
  int r = accept(sock, 0, 0);
  if ((r > 0) && nonblock){
    int flags = fcntl(r, F_GETFL, 0);
    flags |= O_NONBLOCK;
    fcntl(r, F_SETFL, flags);
  }
  return r;
}

bool DDV_write(void * buffer, int todo, int sock){
  int sofar = 0;
  socketBlocking = false;
  while (sofar != todo){
    int r = send(sock, (char*)buffer + sofar, todo-sofar, 0);
    if (r <= 0){
      switch (errno){
        case EWOULDBLOCK: socketBlocking = true; break;
        default:
          socketError = true;
          printf("Could not write! %s\n", strerror(errno));
          return false;
          break;
      }
    }
    sofar += r;
  }
  return true;
}

bool DDV_ready(int sock){
  char tmp;
  int preflags = fcntl(sock, F_GETFL, 0);
  int postflags = preflags | O_NONBLOCK;
  fcntl(sock, F_SETFL, postflags);
  int r = recv(sock, &tmp, 1, MSG_PEEK);
  fcntl(sock, F_SETFL, preflags);
  if (r != 1){
    fprintf(stderr, "Er ging iets mis... %i\n", r);
  }
  return (r == 1);
}

bool DDV_read(void * buffer, int todo, int sock){
  int sofar = 0;
  socketBlocking = false;
  while (sofar != todo){
    int r = recv(sock, (char*)buffer + sofar, todo-sofar, 0);
    if (r <= 0){
      switch (errno){
        case EWOULDBLOCK: socketBlocking = true; break;
        default:
          socketError = true;
          printf("Could not read! %s\n", strerror(errno));
          return false;
          break;
      }
    }
    sofar += r;
  }
  return true;
}

bool DDV_read(void * buffer, int width, int count, int sock){return DDV_read(buffer, width*count, sock);}
bool DDV_write(void * buffer, int width, int count, int sock){return DDV_write(buffer, width*count, sock);}

int DDV_iwrite(void * buffer, int todo, int sock){
  int r = send(sock, buffer, todo, 0);
  if (r < 0){
    switch (errno){
      case EWOULDBLOCK: break;
      default:
        socketError = true;
        printf("Could not write! %s\n", strerror(errno));
        return false;
        break;
    }
  }
  return r;
}

int DDV_iread(void * buffer, int todo, int sock){
  int r = recv(sock, buffer, todo, 0);
  if (r < 0){
    switch (errno){
      case EWOULDBLOCK: break;
      default:
        socketError = true;
        printf("Could not read! %s\n", strerror(errno));
        return false;
        break;
    }
  }
  return r;
}

<|endoftext|>


<commit_before>// $Id: error_vector.C,v 1.11 2006-10-26 21:05:13 roystgnr Exp $

// The libMesh Finite Element Library.
// Copyright (C) 2002-2005  Benjamin S. Kirk, John W. Peterson

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This 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

// C++ includes
#include <limits>

// Local includes
#include "elem.h"
#include "error_vector.h"
#include "libmesh_logging.h"
#include "mesh_base.h"

#include "dof_map.h"
#include "equation_systems.h"
#include "explicit_system.h"
#include "mesh.h"
#include "numeric_vector.h"
#include "gmv_io.h"
#include "tecplot_io.h"

// ------------------------------------------------------------
// ErrorVector class member functions
ErrorVectorReal ErrorVector::minimum() const
{
  START_LOG ("minimum()", "ErrorVector");

  const unsigned int n = this->size();
  ErrorVectorReal min = std::numeric_limits<ErrorVectorReal>::max();

  for (unsigned int i=0; i<n; i++)
    {
      // Only positive (or zero) values in the error vector
      assert((*this)[i] >= 0.);
      if (this->is_active_elem(i))
        min = std::min (min, (*this)[i]);
    }
  STOP_LOG ("minimum()", "ErrorVector");

  // ErrorVectors are for positive values
  assert (min >= 0.);

  return min;
}

Real ErrorVector::mean() const
{
  START_LOG ("mean()", "ErrorVector");

  const unsigned int n = this->size();

  Real mean  = 0;
  unsigned int nnz = 0;

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	mean += ( static_cast<Real>((*this)[i]) - mean ) / (nnz + 1);

	nnz++;
      }

  STOP_LOG ("mean()", "ErrorVector");

  return mean;
}

Real ErrorVector::median()
{
  const unsigned int n   = this->size();

  if (n == 0)
    return 0.;

  // Build a StatisticsVector<ErrorVectorReal> containing
  // only our active entries and take its mean
  StatisticsVector<ErrorVectorReal> sv;

  sv.reserve (n);

  for (unsigned int i=0; i<n; i++)
    if(this->is_active_elem(i))
      sv.push_back((*this)[i]);

  return sv.median();
}

Real ErrorVector::median() const
{
  ErrorVector ev = (*this);

  return ev.median();
}

Real ErrorVector::variance(const Real mean) const
{
  const unsigned int n   = this->size();

  START_LOG ("variance()", "ErrorVector");

  Real variance = 0;
  unsigned int nnz = 0;

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	const Real delta = ( static_cast<Real>((*this)[i]) - mean );
	variance += (delta * delta - variance) / (nnz + 1);

	nnz++;
      }

  STOP_LOG ("variance()", "ErrorVector");

  return variance;
}

std::vector<unsigned int> ErrorVector::cut_below(Real cut) const
{
  START_LOG ("cut_below()", "ErrorVector");

  const unsigned int n = this->size();

  std::vector<unsigned int> cut_indices;
  cut_indices.reserve(n/2);  // Arbitrary

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	if ((*this)[i] < cut)
	  {
	    cut_indices.push_back(i);
	  }
      }

  STOP_LOG ("cut_below()", "ErrorVector");

  return cut_indices;
}

std::vector<unsigned int> ErrorVector::cut_above(Real cut) const
{
  START_LOG ("cut_above()", "ErrorVector");

  const unsigned int n   = this->size();

  std::vector<unsigned int> cut_indices;
  cut_indices.reserve(n/2);  // Arbitrary

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	if ((*this)[i] > cut)
	  {
	    cut_indices.push_back(i);
	  }
      }

  STOP_LOG ("cut_above()", "ErrorVector");

  return cut_indices;
}

bool ErrorVector::is_active_elem (unsigned int i) const
{
  assert (i < this->size());

  if (_mesh)
    {
      assert(_mesh->elem(i));
      return _mesh->elem(i)->active();
    }
  else
    return ((*this)[i] != 0.);
}

void ErrorVector::plot_error(std::string filename, Mesh& mesh) const
{
  EquationSystems temp_es (mesh);
  ExplicitSystem& error_system
    = temp_es.add_system<ExplicitSystem> ("Error");
  error_system.add_variable("e", CONSTANT, MONOMIAL);
  temp_es.init();

  const DofMap& error_dof_map = error_system.get_dof_map();

  MeshBase::const_element_iterator       el     =
    mesh.active_local_elements_begin();
  const MeshBase::const_element_iterator end_el =
    mesh.active_local_elements_end();
  std::vector<unsigned int> dof_indices;

  for ( ; el != end_el; ++el)
  {
    Elem* elem = *el;

    error_dof_map.dof_indices(elem, dof_indices);

    const unsigned int elem_id = elem->id();

    //0 for the monomial basis
    const unsigned int solution_index = dof_indices[0];
    // std::cout << "elem_number=" << elem_number << std::endl;
    assert ((*this)[elem_id] > 0.);
    error_system.solution->set(solution_index, (*this)[elem_id]);
  }

  if (filename.rfind(".gmv") < filename.size())
    {
      GMVIO(mesh).write_discontinuous_gmv(filename,
                                          temp_es, false);
    }
  else if (filename.rfind(".plt") < filename.size())
    {
      TecplotIO (mesh).write_equation_systems
        (filename, temp_es);
    }
  else
    {
      here();
      std::cerr << "Warning: ErrorVector::plot_error currently only"
                << " supports .gmv and .plt output;" << std::endl;
      std::cerr << "Could not recognize filename: " << filename
                << std::endl;
    }
}

<commit_msg>Fix "corrupting mesh DoFObjects" bug<commit_after>// $Id: error_vector.C,v 1.12 2006-10-26 22:19:16 roystgnr Exp $

// The libMesh Finite Element Library.
// Copyright (C) 2002-2005  Benjamin S. Kirk, John W. Peterson

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This 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

// C++ includes
#include <limits>

// Local includes
#include "elem.h"
#include "error_vector.h"
#include "libmesh_logging.h"
#include "mesh_base.h"

#include "dof_map.h"
#include "equation_systems.h"
#include "explicit_system.h"
#include "mesh.h"
#include "numeric_vector.h"
#include "gmv_io.h"
#include "tecplot_io.h"

// ------------------------------------------------------------
// ErrorVector class member functions
ErrorVectorReal ErrorVector::minimum() const
{
  START_LOG ("minimum()", "ErrorVector");

  const unsigned int n = this->size();
  ErrorVectorReal min = std::numeric_limits<ErrorVectorReal>::max();

  for (unsigned int i=0; i<n; i++)
    {
      // Only positive (or zero) values in the error vector
      assert((*this)[i] >= 0.);
      if (this->is_active_elem(i))
        min = std::min (min, (*this)[i]);
    }
  STOP_LOG ("minimum()", "ErrorVector");

  // ErrorVectors are for positive values
  assert (min >= 0.);

  return min;
}

Real ErrorVector::mean() const
{
  START_LOG ("mean()", "ErrorVector");

  const unsigned int n = this->size();

  Real mean  = 0;
  unsigned int nnz = 0;

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	mean += ( static_cast<Real>((*this)[i]) - mean ) / (nnz + 1);

	nnz++;
      }

  STOP_LOG ("mean()", "ErrorVector");

  return mean;
}

Real ErrorVector::median()
{
  const unsigned int n   = this->size();

  if (n == 0)
    return 0.;

  // Build a StatisticsVector<ErrorVectorReal> containing
  // only our active entries and take its mean
  StatisticsVector<ErrorVectorReal> sv;

  sv.reserve (n);

  for (unsigned int i=0; i<n; i++)
    if(this->is_active_elem(i))
      sv.push_back((*this)[i]);

  return sv.median();
}

Real ErrorVector::median() const
{
  ErrorVector ev = (*this);

  return ev.median();
}

Real ErrorVector::variance(const Real mean) const
{
  const unsigned int n   = this->size();

  START_LOG ("variance()", "ErrorVector");

  Real variance = 0;
  unsigned int nnz = 0;

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	const Real delta = ( static_cast<Real>((*this)[i]) - mean );
	variance += (delta * delta - variance) / (nnz + 1);

	nnz++;
      }

  STOP_LOG ("variance()", "ErrorVector");

  return variance;
}

std::vector<unsigned int> ErrorVector::cut_below(Real cut) const
{
  START_LOG ("cut_below()", "ErrorVector");

  const unsigned int n = this->size();

  std::vector<unsigned int> cut_indices;
  cut_indices.reserve(n/2);  // Arbitrary

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	if ((*this)[i] < cut)
	  {
	    cut_indices.push_back(i);
	  }
      }

  STOP_LOG ("cut_below()", "ErrorVector");

  return cut_indices;
}

std::vector<unsigned int> ErrorVector::cut_above(Real cut) const
{
  START_LOG ("cut_above()", "ErrorVector");

  const unsigned int n   = this->size();

  std::vector<unsigned int> cut_indices;
  cut_indices.reserve(n/2);  // Arbitrary

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	if ((*this)[i] > cut)
	  {
	    cut_indices.push_back(i);
	  }
      }

  STOP_LOG ("cut_above()", "ErrorVector");

  return cut_indices;
}

bool ErrorVector::is_active_elem (unsigned int i) const
{
  assert (i < this->size());

  if (_mesh)
    {
      assert(_mesh->elem(i));
      return _mesh->elem(i)->active();
    }
  else
    return ((*this)[i] != 0.);
}

void ErrorVector::plot_error(std::string filename, Mesh& oldmesh) const
{
  Mesh mesh(oldmesh);
  EquationSystems temp_es (mesh);
  ExplicitSystem& error_system
    = temp_es.add_system<ExplicitSystem> ("Error");
  error_system.add_variable("e", CONSTANT, MONOMIAL);
  temp_es.init();

  const DofMap& error_dof_map = error_system.get_dof_map();

  MeshBase::const_element_iterator       el     =
    mesh.active_local_elements_begin();
  const MeshBase::const_element_iterator end_el =
    mesh.active_local_elements_end();
  std::vector<unsigned int> dof_indices;

  for ( ; el != end_el; ++el)
  {
    Elem* elem = *el;

    error_dof_map.dof_indices(elem, dof_indices);

    const unsigned int elem_id = elem->id();

    //0 for the monomial basis
    const unsigned int solution_index = dof_indices[0];
    // std::cout << "elem_number=" << elem_number << std::endl;
    assert (elem_id < (*this).size());
    assert ((*this)[elem_id] > 0.);
    error_system.solution->set(solution_index, (*this)[elem_id]);
  }

  if (filename.rfind(".gmv") < filename.size())
    {
      GMVIO(mesh).write_discontinuous_gmv(filename,
                                          temp_es, false);
    }
  else if (filename.rfind(".plt") < filename.size())
    {
      TecplotIO (mesh).write_equation_systems
        (filename, temp_es);
    }
  else
    {
      here();
      std::cerr << "Warning: ErrorVector::plot_error currently only"
                << " supports .gmv and .plt output;" << std::endl;
      std::cerr << "Could not recognize filename: " << filename
                << std::endl;
    }
}

<|endoftext|>


<commit_before>/** \brief Utility for removing unreferenced authority records
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2017,2018 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <stdexcept>
#include <unordered_set>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include "FileUtil.h"
#include "Leader.h"
#include "MARC.h"
#include "RegexMatcher.h"
#include "StringUtil.h"
#include "util.h"

namespace {

[[noreturn]] void Usage() {
    std::cerr << "Usage: " << ::progname << " title_data authority_data filtered_authority_data\n";
    std::exit(EXIT_FAILURE);
}

void CollectGNDReferences(MARC::Reader * const marc_reader, std::unordered_set<std::string> * const gnd_numbers) {
    std::string err_msg;
    RegexMatcher * const matcher(RegexMatcher::RegexMatcherFactory("\x1F""0\\(DE-588\\)([^\x1F]+).*\x1F""2gnd",
                                                                   &err_msg));
    if (matcher == nullptr)
        logger->error("failed to compile a regex in CollectGNDReferences: " + err_msg);

    unsigned record_count(0);
    while (const MARC::Record record = marc_reader->read()) {
        ++record_count;

        for (const auto field : record) {
            if (matcher->matched(field.getContents()))
                gnd_numbers->emplace((*matcher)[1]);
        }
    }

    std::cout << "Extracted " << gnd_numbers->size() << " GND number(s) from " <<  record_count
              << " title record(s).\n";
}

std::string GetGNDNumber(const MARC::Record &record) {
    for (const auto &_035_field : record.getTagRange("035")) {
        const MARC::Subfields _035_subfields(_035_field.getSubfields());
        const std::string _035a_contents(_035_subfields.getFirstSubfieldWithCode('a'));
        if (StringUtil::StartsWith(_035a_contents, "(DE-588)"))
            return _035a_contents.substr(__builtin_strlen("(DE-588)"));
    }

    return "";
}

const std::string DROPPED_GND_LIST_FILE("/usr/local/var/log/tuefind/dropped_gnd_numbers.list");

void FilterAuthorityData(MARC::Reader * const marc_reader, MARC::Writer * const marc_writer,
                         const std::unordered_set<std::string> &gnd_numbers)
{
    std::unique_ptr<File> gnd_list_file(FileUtil::OpenOutputFileOrDie(DROPPED_GND_LIST_FILE));
    unsigned record_count(0), dropped_count(0), authority_records_without_gnd_numbers_count(0);
    while (const MARC::Record record = marc_reader->read()) {
        ++record_count;

        const std::string gnd_number(GetGNDNumber(record));
        if (not gnd_number.empty() and gnd_numbers.find(gnd_number) == gnd_numbers.cend()) {
            gnd_list_file->write(gnd_number + "\n");
            ++dropped_count;
            continue;
        }

        if (gnd_number.empty())
            ++authority_records_without_gnd_numbers_count;
        marc_writer->write(record);
    }

    std::cerr << "Read " << record_count << " authority record(s) of which " << dropped_count << " were dropped.\n";
    std::cerr << "Found and kept " << authority_records_without_gnd_numbers_count
              << " authority records w/o a GND number.\n";
}

} // unnamed namespace

int Main(int argc, char *argv[]) {
    ::progname = argv[0];

    if (argc != 4)
        Usage();

    std::unique_ptr<MARC::Reader> marc_title_reader(MARC::Reader::Factory(argv[1]));
    std::unique_ptr<MARC::Reader> marc_authority_reader(MARC::Reader::Factory(argv[2]));
    std::unique_ptr<MARC::Writer> marc_authority_writer(MARC::Writer::Factory(argv[3]));

    std::unordered_set<std::string> gnd_numbers;
    CollectGNDReferences(marc_title_reader.get(), &gnd_numbers);
    FilterAuthorityData(marc_authority_reader.get(), marc_authority_writer.get(), gnd_numbers);

    return EXIT_SUCCESS;
}
<commit_msg>Update remove_unused_authority_records.cc<commit_after>/** \brief Utility for removing unreferenced authority records
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2017,2018 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <stdexcept>
#include <unordered_set>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include "FileUtil.h"
#include "Leader.h"
#include "MARC.h"
#include "RegexMatcher.h"
#include "StringUtil.h"
#include "util.h"

namespace {

[[noreturn]] void Usage() {
    std::cerr << "Usage: " << ::progname << " title_data authority_data filtered_authority_data\n";
    std::exit(EXIT_FAILURE);
}

void CollectGNDReferences(MARC::Reader * const marc_reader, std::unordered_set<std::string> * const gnd_numbers) {
    std::string err_msg;
    RegexMatcher * const matcher(RegexMatcher::RegexMatcherFactory("\x1F""0\\(DE-588\\)([^\x1F]+).*\x1F""2gnd",
                                                                   &err_msg));
    if (matcher == nullptr)
        logger->error("failed to compile a regex in CollectGNDReferences: " + err_msg);

    unsigned record_count(0);
    while (const MARC::Record record = marc_reader->read()) {
        ++record_count;

        for (const auto &field : record) {
            if (matcher->matched(field.getContents()))
                gnd_numbers->emplace((*matcher)[1]);
        }
    }

    std::cout << "Extracted " << gnd_numbers->size() << " GND number(s) from " <<  record_count
              << " title record(s).\n";
}

std::string GetGNDNumber(const MARC::Record &record) {
    for (const auto &_035_field : record.getTagRange("035")) {
        const MARC::Subfields _035_subfields(_035_field.getSubfields());
        const std::string _035a_contents(_035_subfields.getFirstSubfieldWithCode('a'));
        if (StringUtil::StartsWith(_035a_contents, "(DE-588)"))
            return _035a_contents.substr(__builtin_strlen("(DE-588)"));
    }

    return "";
}

const std::string DROPPED_GND_LIST_FILE("/usr/local/var/log/tuefind/dropped_gnd_numbers.list");

void FilterAuthorityData(MARC::Reader * const marc_reader, MARC::Writer * const marc_writer,
                         const std::unordered_set<std::string> &gnd_numbers)
{
    std::unique_ptr<File> gnd_list_file(FileUtil::OpenOutputFileOrDie(DROPPED_GND_LIST_FILE));
    unsigned record_count(0), dropped_count(0), authority_records_without_gnd_numbers_count(0);
    while (const MARC::Record record = marc_reader->read()) {
        ++record_count;

        const std::string gnd_number(GetGNDNumber(record));
        if (not gnd_number.empty() and gnd_numbers.find(gnd_number) == gnd_numbers.cend()) {
            gnd_list_file->write(gnd_number + "\n");
            ++dropped_count;
            continue;
        }

        if (gnd_number.empty())
            ++authority_records_without_gnd_numbers_count;
        marc_writer->write(record);
    }

    std::cerr << "Read " << record_count << " authority record(s) of which " << dropped_count << " were dropped.\n";
    std::cerr << "Found and kept " << authority_records_without_gnd_numbers_count
              << " authority records w/o a GND number.\n";
}

} // unnamed namespace

int Main(int argc, char *argv[]) {
    ::progname = argv[0];

    if (argc != 4)
        Usage();

    std::unique_ptr<MARC::Reader> marc_title_reader(MARC::Reader::Factory(argv[1]));
    std::unique_ptr<MARC::Reader> marc_authority_reader(MARC::Reader::Factory(argv[2]));
    std::unique_ptr<MARC::Writer> marc_authority_writer(MARC::Writer::Factory(argv[3]));

    std::unordered_set<std::string> gnd_numbers;
    CollectGNDReferences(marc_title_reader.get(), &gnd_numbers);
    FilterAuthorityData(marc_authority_reader.get(), marc_authority_writer.get(), gnd_numbers);

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/** \brief Utility for removing unreferenced authority records
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2017 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <stdexcept>
#include <unordered_set>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include "FileUtil.h"
#include "Leader.h"
#include "MarcReader.h"
#include "MarcRecord.h"
#include "MarcWriter.h"
#include "RegexMatcher.h"
#include "StringUtil.h"
#include "util.h"

namespace {

void Usage() __attribute__((noreturn));

void Usage() {
    std::cerr << "Usage: " << ::progname << " title_data authority_data filtered_authority_data\n";
    std::exit(EXIT_FAILURE);
}

void CollectGNDReferences(MarcReader * const marc_reader, std::unordered_set<std::string> * const gnd_numbers) {
    std::string err_msg;
    RegexMatcher * const matcher(RegexMatcher::RegexMatcherFactory("\x1F""0\\(DE-588\\)([^\x1F]+).*\x1F""2gnd",
                                                                   &err_msg));
    if (matcher == nullptr)
        logger->error("failed to compile a regex in CollectGNDReferences: " + err_msg);

    unsigned record_count(0);
    while (const MarcRecord record = marc_reader->read()) {
        ++record_count;

        for (const auto field_contents : record) {
            if (matcher->matched(field_contents))
                gnd_numbers->emplace((*matcher)[1]);
        }
    }

    std::cout << "Extracted " << gnd_numbers->size() << " GND number(s) from " <<  record_count
              << " title record(s).\n";
}

std::string GetGNDNumber(const MarcRecord &record) {
    std::vector<size_t> _035_indices;
    record.getFieldIndices("035", &_035_indices);

    for (const auto index : _035_indices) {
        const Subfields _035_subfields(record.getFieldData(index));
        const std::string _035a_contents(_035_subfields.getFirstSubfieldValue('a'));
        if (StringUtil::StartsWith(_035a_contents, "(DE-588)"))
            return _035a_contents.substr(__builtin_strlen("(DE-588)"));
    }

    return "";
}

const std::string DROPPED_GND_LIST_FILE("/usr/local/var/log/tuefind/dropped_gnd_numbers.list");

void FilterAuthorityData(MarcReader * const marc_reader, MarcWriter * const marc_writer,
                         const std::unordered_set<std::string> &gnd_numbers)
{
    std::unique_ptr<File> gnd_list_file(FileUtil::OpenOutputFileOrDie(DROPPED_GND_LIST_FILE));
    unsigned record_count(0), dropped_count(0), authority_records_without_gnd_numbers_count(0);
    while (const MarcRecord record = marc_reader->read()) {
        ++record_count;

        const std::string gnd_number(GetGNDNumber(record));
        if (not gnd_number.empty() and gnd_numbers.find(gnd_number) == gnd_numbers.cend()) {
            gnd_list_file->write(gnd_number + "\n");
            ++dropped_count;
            continue;
        }

        if (gnd_number.empty())
            ++authority_records_without_gnd_numbers_count;
        marc_writer->write(record);
    }

    std::cerr << "Read " << record_count << " authority record(s) of which " << dropped_count << " were dropped.\n";
    std::cerr << "Found and kept " << authority_records_without_gnd_numbers_count
              << " authority records w/o a GND number.\n";
}

} // unnamed namespace

int main(int argc, char *argv[]) {
    ::progname = argv[0];

    if (argc != 4)
        Usage();

    try {
        std::unique_ptr<MarcReader> marc_title_reader(MarcReader::Factory(argv[1]));
        std::unique_ptr<MarcReader> marc_authority_reader(MarcReader::Factory(argv[2]));
        std::unique_ptr<MarcWriter> marc_authority_writer(MarcWriter::Factory(argv[3]));

        std::unordered_set<std::string> gnd_numbers;
        CollectGNDReferences(marc_title_reader.get(), &gnd_numbers);
        FilterAuthorityData(marc_authority_reader.get(), marc_authority_writer.get(), gnd_numbers);
    } catch (const std::exception &e) {
        logger->error("Caught exception: " + std::string(e.what()));
    }
}
<commit_msg>Converted to the new MARC API.<commit_after>/** \brief Utility for removing unreferenced authority records
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2017,2018 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <stdexcept>
#include <unordered_set>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include "FileUtil.h"
#include "Leader.h"
#include "MARC.h"
#include "RegexMatcher.h"
#include "StringUtil.h"
#include "util.h"

namespace {

[[noreturn]] void Usage() {
    std::cerr << "Usage: " << ::progname << " title_data authority_data filtered_authority_data\n";
    std::exit(EXIT_FAILURE);
}

void CollectGNDReferences(MARC::Reader * const marc_reader, std::unordered_set<std::string> * const gnd_numbers) {
    std::string err_msg;
    RegexMatcher * const matcher(RegexMatcher::RegexMatcherFactory("\x1F""0\\(DE-588\\)([^\x1F]+).*\x1F""2gnd",
                                                                   &err_msg));
    if (matcher == nullptr)
        logger->error("failed to compile a regex in CollectGNDReferences: " + err_msg);

    unsigned record_count(0);
    while (const MARC::Record record = marc_reader->read()) {
        ++record_count;

        for (const auto field : record) {
            if (matcher->matched(field.getContents()))
                gnd_numbers->emplace((*matcher)[1]);
        }
    }

    std::cout << "Extracted " << gnd_numbers->size() << " GND number(s) from " <<  record_count
              << " title record(s).\n";
}

std::string GetGNDNumber(const MARC::Record &record) {
    for (const auto &_035_field : record.getTagRange("035")) {
        const MARC::Subfields _035_subfields(_035_field.getSubfields());
        const std::string _035a_contents(_035_subfields.getFirstSubfieldWithCode('a'));
        if (StringUtil::StartsWith(_035a_contents, "(DE-588)"))
            return _035a_contents.substr(__builtin_strlen("(DE-588)"));
    }

    return "";
}

const std::string DROPPED_GND_LIST_FILE("/usr/local/var/log/tuefind/dropped_gnd_numbers.list");

void FilterAuthorityData(MARC::Reader * const marc_reader, MARC::Writer * const marc_writer,
                         const std::unordered_set<std::string> &gnd_numbers)
{
    std::unique_ptr<File> gnd_list_file(FileUtil::OpenOutputFileOrDie(DROPPED_GND_LIST_FILE));
    unsigned record_count(0), dropped_count(0), authority_records_without_gnd_numbers_count(0);
    while (const MARC::Record record = marc_reader->read()) {
        ++record_count;

        const std::string gnd_number(GetGNDNumber(record));
        if (not gnd_number.empty() and gnd_numbers.find(gnd_number) == gnd_numbers.cend()) {
            gnd_list_file->write(gnd_number + "\n");
            ++dropped_count;
            continue;
        }

        if (gnd_number.empty())
            ++authority_records_without_gnd_numbers_count;
        marc_writer->write(record);
    }

    std::cerr << "Read " << record_count << " authority record(s) of which " << dropped_count << " were dropped.\n";
    std::cerr << "Found and kept " << authority_records_without_gnd_numbers_count
              << " authority records w/o a GND number.\n";
}

} // unnamed namespace

int Main(int argc, char *argv[]) {
    ::progname = argv[0];

    if (argc != 4)
        Usage();

    std::unique_ptr<MARC::Reader> marc_title_reader(MARC::Reader::Factory(argv[1]));
    std::unique_ptr<MARC::Reader> marc_authority_reader(MARC::Reader::Factory(argv[2]));
    std::unique_ptr<MARC::Writer> marc_authority_writer(MARC::Writer::Factory(argv[3]));

    std::unordered_set<std::string> gnd_numbers;
    CollectGNDReferences(marc_title_reader.get(), &gnd_numbers);
    FilterAuthorityData(marc_authority_reader.get(), marc_authority_writer.get(), gnd_numbers);

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#ifndef BLOCKING_MESSAGE_QUEUE_HPP
#define BLOCKING_MESSAGE_QUEUE_HPP

#include "cppa/message.hpp"
#include "cppa/message_queue.hpp"
#include "cppa/util/singly_linked_list.hpp"
#include "cppa/util/single_reader_queue.hpp"
#include "cppa/detail/abstract_message_queue.hpp"

namespace cppa { namespace detail {

class intermediate;

// blocks if single_reader_queue blocks
class blocking_message_queue_impl : public message_queue
{

    struct queue_node
    {
        queue_node* next;
        message msg;
        queue_node(const message& from);
    };

    util::single_reader_queue<queue_node> m_queue;

 protected:

    typedef util::singly_linked_list<queue_node> queue_node_buffer;

    inline bool empty()
    {
        return m_queue.empty();
    }

    inline void restore_mailbox(queue_node_buffer& buffer)
    {
        if (!buffer.empty()) m_queue.push_front(std::move(buffer));
    }

    // conputes the next message, returns true if the computed message
    // was not ignored (e.g. because it's an exit message with reason = normal)
    bool dequeue_impl(message& storage);

    bool dequeue_impl(invoke_rules&, queue_node_buffer&);

 public:

    virtual void enqueue(const message& msg) /*override*/;
};

typedef abstract_message_queue<blocking_message_queue_impl>
        blocking_message_queue;

} } // namespace hamcast::detail

#endif // BLOCKING_MESSAGE_QUEUE_HPP
<commit_msg>removed useless forward declaration<commit_after>#ifndef BLOCKING_MESSAGE_QUEUE_HPP
#define BLOCKING_MESSAGE_QUEUE_HPP

#include "cppa/message.hpp"
#include "cppa/message_queue.hpp"
#include "cppa/util/singly_linked_list.hpp"
#include "cppa/util/single_reader_queue.hpp"
#include "cppa/detail/abstract_message_queue.hpp"

namespace cppa { namespace detail {

// blocks if single_reader_queue blocks
class blocking_message_queue_impl : public message_queue
{

    struct queue_node
    {
        queue_node* next;
        message msg;
        queue_node(const message& from);
    };

    util::single_reader_queue<queue_node> m_queue;

 protected:

    typedef util::singly_linked_list<queue_node> queue_node_buffer;

    inline bool empty()
    {
        return m_queue.empty();
    }

    inline void restore_mailbox(queue_node_buffer& buffer)
    {
        if (!buffer.empty()) m_queue.push_front(std::move(buffer));
    }

    // conputes the next message, returns true if the computed message
    // was not ignored (e.g. because it's an exit message with reason = normal)
    bool dequeue_impl(message& storage);

    bool dequeue_impl(invoke_rules&, queue_node_buffer&);

 public:

    virtual void enqueue(const message& msg) /*override*/;
};

typedef abstract_message_queue<blocking_message_queue_impl>
        blocking_message_queue;

} } // namespace hamcast::detail

#endif // BLOCKING_MESSAGE_QUEUE_HPP
<|endoftext|>


<commit_before>// commodconverter.cc
// Implements the CommodConverter class
#include "commodconverter.h"

namespace commodconverter {

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CommodConverter::CommodConverter(cyclus::Context* ctx)
    : cyclus::Facility(ctx) {
  cyclus::Warn<cyclus::EXPERIMENTAL_WARNING>("the CommodConverter is experimental.");
    };

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// pragmas

#pragma cyclus def schema commodconverter::CommodConverter

#pragma cyclus def annotations commodconverter::CommodConverter

#pragma cyclus def initinv commodconverter::CommodConverter

#pragma cyclus def snapshotinv commodconverter::CommodConverter

#pragma cyclus def infiletodb commodconverter::CommodConverter

#pragma cyclus def snapshot commodconverter::CommodConverter

#pragma cyclus def clone commodconverter::CommodConverter

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::InitFrom(CommodConverter* m) {

  #pragma cyclus impl initfromcopy commodconverter::CommodConverter

  cyclus::toolkit::CommodityProducer::Copy(m);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::InitFrom(cyclus::QueryableBackend* b){

  #pragma cyclus impl initfromdb commodconverter::CommodConverter

  using cyclus::toolkit::Commodity;
  Commodity commod = Commodity(out_commod);
  cyclus::toolkit::CommodityProducer::Add(commod);
  cyclus::toolkit::CommodityProducer::SetCapacity(commod, capacity);
  cyclus::toolkit::CommodityProducer::SetCost(commod, cost);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::EnterNotify() {
  Facility::EnterNotify();

  using cyclus::toolkit::Commodity;
  Commodity commod = Commodity(out_commod);
  cyclus::toolkit::CommodityProducer::Add(commod);
  cyclus::toolkit::CommodityProducer::SetCapacity(commod, capacity);
  cyclus::toolkit::CommodityProducer::SetCost(commod, cost);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
std::string CommodConverter::str() {
  std::stringstream ss;
  std::string ans;
  if (cyclus::toolkit::CommodityProducer::
      Produces(cyclus::toolkit::Commodity(out_commod_()))){
    ans = "yes";
  } else {
    ans = "no";
  }
  ss << cyclus::Facility::str();
  ss << " has facility parameters {" << "\n"
     << "     Input Commodity = " << in_commod_() << ",\n"
     << "     Output Commodity = " << out_commod_() << ",\n"
     << "     Process Time = " << process_time_() << ",\n"
     << "     Capacity = " << capacity_() << ",\n"
     << " commod producer members: " << " produces "
     << out_commod << "?:" << ans
     << " capacity: " << cyclus::toolkit::CommodityProducer::Capacity(out_commod_())
     << " cost: " << cyclus::toolkit::CommodityProducer::Cost(out_commod_())
     << "'}";
  return ss.str();
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::Tick() {
  LOG(cyclus::LEV_INFO3, "ComCnv") << prototype() << " is ticking {";

  if (current_capacity() > cyclus::eps()) {
    LOG(cyclus::LEV_INFO4, "ComCnv") << " has capacity for " << current_capacity()
                                       << " kg of " << in_commod
                                       << " recipe: " << in_recipe << ".";
  }

  LOG(cyclus::LEV_INFO3, "ComCnv") << "}";
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::Tock() {
  LOG(cyclus::LEV_INFO3, "ComCnv") << prototype() << " is tocking {";

  BeginProcessing_(); // place unprocessed inventory into processing

  if( ready() >= 0 || process_time_() == 0 ) {
    Convert_(capacity_()); // place processing into stocks
  }

  LOG(cyclus::LEV_INFO3, "ComCnv") << "}";
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
std::set<cyclus::RequestPortfolio<cyclus::Material>::Ptr>
CommodConverter::GetMatlRequests() {
  using cyclus::CapacityConstraint;
  using cyclus::Material;
  using cyclus::RequestPortfolio;
  using cyclus::Request;

  std::set<RequestPortfolio<Material>::Ptr> ports;

  RequestPortfolio<Material>::Ptr port(new RequestPortfolio<Material>());
  Material::Ptr mat = Request_();
  double amt = mat->quantity();

  if (amt > cyclus::eps()) {
    //CapacityConstraint<Material> cc(amt);
    //port->AddConstraint(cc);

    port->AddRequest(mat, this, in_commod_());

    ports.insert(port);
  }

  return ports;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::AcceptMatlTrades(
  const std::vector< std::pair<cyclus::Trade<cyclus::Material>,
  cyclus::Material::Ptr> >& responses) {
  std::vector< std::pair<cyclus::Trade<cyclus::Material>,
      cyclus::Material::Ptr> >::const_iterator it;
  for (it = responses.begin(); it != responses.end(); ++it) {
    AddMat_(it->second);
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
std::set<cyclus::BidPortfolio<cyclus::Material>::Ptr>
CommodConverter::GetMatlBids(cyclus::CommodMap<cyclus::Material>::type&
                          commod_requests) {
  using cyclus::BidPortfolio;
  using cyclus::Material;

  std::set<BidPortfolio<Material>::Ptr> ports;

  std::set<std::string>::const_iterator it;
  BidPortfolio<Material>::Ptr port = GetBids_(commod_requests,
                                              out_commod,
                                              &stocks);
  if (!port->bids().empty()) {
    ports.insert(port);
  }

  return ports;

}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::GetMatlTrades(
  const std::vector< cyclus::Trade<cyclus::Material> >& trades,
  std::vector<std::pair<cyclus::Trade<cyclus::Material>,
  cyclus::Material::Ptr> >& responses) {
  using cyclus::Material;
  using cyclus::Trade;

  // for each trade, respond
  std::vector< Trade<Material> >::const_iterator it;
  for (it = trades.begin(); it != trades.end(); ++it) {
    std::string commodity = it->request->commodity();
    //double qty = it->amt;
    double qty = stocks.quantity();
    // create a material pointer representing what you can offer
    Material::Ptr response = TradeResponse_(qty, &stocks);

    responses.push_back(std::make_pair(*it, response));
    LOG(cyclus::LEV_INFO5, "ComCnv") << prototype()
                                  << " just received an order"
                                  << " for " << it->amt
                                  << " of " << commodity;
  }

}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::AddMat_(cyclus::Material::Ptr mat) {
  // Here we do not check that the recipe matches the input recipe.

  LOG(cyclus::LEV_INFO5, "ComCnv") << prototype() << " is initially holding "
                                << inventory.quantity() << " total.";

  try {
    inventory.Push(mat);
  } catch (cyclus::Error& e) {
    e.msg(Agent::InformErrorMsg(e.msg()));
    throw e;
  }

  LOG(cyclus::LEV_INFO5, "ComCnv") << prototype() << " added " << mat->quantity()
                                << " of " << in_commod_()
                                << " to its inventory, which is holding "
                                << inventory.quantity() << " total.";

}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
cyclus::Material::Ptr CommodConverter::Request_() {
  double qty = std::max(0.0, current_capacity());
  LOG(cyclus::LEV_INFO5, "ComCnv") << prototype()
                                  << " just requested "
                                  << current_capacity()
                                  << " of commodity: " << in_commod
                                  << " with recipe: " << in_recipe;
  return cyclus::Material::CreateUntracked(qty,
                                        context()->GetRecipe(in_recipe));
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
cyclus::BidPortfolio<cyclus::Material>::Ptr CommodConverter::GetBids_(
    cyclus::CommodMap<cyclus::Material>::type& commod_requests,
    std::string commod,
    cyclus::toolkit::ResourceBuff* buffer) {
  using cyclus::Bid;
  using cyclus::BidPortfolio;
  using cyclus::CapacityConstraint;
  using cyclus::Composition;
  using cyclus::Converter;
  using cyclus::Material;
  using cyclus::Request;
  using cyclus::ResCast;
  using cyclus::toolkit::ResourceBuff;

  BidPortfolio<Material>::Ptr port(new BidPortfolio<Material>());

  if (commod_requests.count(commod) > 0 && buffer->quantity() > 0) {
    std::vector<Request<Material>*>& requests = commod_requests.at(commod);

    // get offer composition
    Material::Ptr back = ResCast<Material>(buffer->Pop(ResourceBuff::BACK));
    Composition::Ptr comp = back->comp();
    buffer->Push(back);

    std::vector<Request<Material>*>::iterator it;
    for (it = requests.begin(); it != requests.end(); ++it) {
      Request<Material>* req = *it;
      double qty = std::min(req->target()->quantity(), buffer->quantity());
      Material::Ptr offer = Material::CreateUntracked(qty, comp);
      port->AddBid(req, offer, this);
    }

    //CapacityConstraint<Material> cc(buffer->quantity());
    //port->AddConstraint(cc);
  }

  return port;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
cyclus::Material::Ptr CommodConverter::TradeResponse_(
    double qty,
    cyclus::toolkit::ResourceBuff* buffer) {
  using cyclus::Material;
  using cyclus::ResCast;

  std::vector<Material::Ptr> manifest;
  try {
    // pop amount from inventory and blob it into one material
    manifest = ResCast<Material>(buffer->PopQty(qty));
  } catch(cyclus::Error& e) {
    e.msg(Agent::InformErrorMsg(e.msg()));
    throw e;
  }

  Material::Ptr response = manifest[0];
  for (int i = 1; i < manifest.size(); i++) {
    response->Absorb(manifest[i]);
  }
  return response;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::BeginProcessing_(){
  if( inventory.count() > 0 ){
    try {
      processing[context()->time()].Push(inventory.Pop());
      LOG(cyclus::LEV_DEBUG2, "ComCnv") << "CommodConverter " << prototype()
                                      << " added resources to processing at t= "
                                      << context()->time();
    } catch (cyclus::Error& e) {
      e.msg(Agent::InformErrorMsg(e.msg()));
      throw e;
    }
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::Convert_(double cap){
  using cyclus::Material;
  using cyclus::ResCast;
  using cyclus::toolkit::ResourceBuff;
  using cyclus::toolkit::Manifest;

  int t = ready();
  if ( ProcessingAmt_(t) > 0 ){
    try {
      double to_pop = std::min(cap, processing[t].quantity());
      // pop appropriate amount of material from processing
      std::vector<Material::Ptr> to_conv =
        ResCast<Material>(processing[t].PopQty(to_pop));
      // if an out_recipe was provided, transmute it
      std::vector<Material::Ptr>::iterator mat;
      if( out_recipe == "" ){
        // if no out recipe, then no transmute needed
        stocks.PushAll(to_conv);
      } else {
        // transmute each mat
        for(mat=to_conv.begin(); mat!=to_conv.end(); ++mat) {
          (*mat)->Transmute(context()->GetRecipe(out_recipe));
          // put it in the stocks
          stocks.Push(*mat);
        }
      }
      AdvanceUnconverted_(t);
      LOG(cyclus::LEV_INFO1, "ComCnv") << "CommodConverter " << prototype()
                                        << " converted quantity : " << to_pop
                                        << " from " << in_commod
                                        << " to " << out_commod;
    } catch (cyclus::Error& e) {
      e.msg(Agent::InformErrorMsg(e.msg()));
      throw e;
    }
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double CommodConverter::ProcessingAmt_(int time) {
  using cyclus::toolkit::ResourceBuff;
  double to_ret = 0;
  std::map<int, ResourceBuff>::iterator proc = processing.find(time);
  if ( proc!=processing.end() &&
      proc->second.quantity() > 0 ) {
    to_ret = proc->second.quantity();
  }
  return to_ret;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::AdvanceUnconverted_(int time){
  using cyclus::Material;
  using cyclus::ResCast;

  double to_pop = ProcessingAmt_(time);
  if ( to_pop > 0 ) {
    try {
      std::vector<Material::Ptr> to_advance =
      ResCast<Material>(processing[time].PopQty(to_pop));
      processing[time+1].PushAll(to_advance);
    } catch (cyclus::Error& e) {
      e.msg(Agent::InformErrorMsg(e.msg()));
      throw e;
    }
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
extern "C" cyclus::Agent* ConstructCommodConverter(cyclus::Context* ctx) {
  return new CommodConverter(ctx);
}

} // namespace commodconverter
<commit_msg>fixed popqty seg fault when qty = 0<commit_after>// commodconverter.cc
// Implements the CommodConverter class
#include "commodconverter.h"

namespace commodconverter {

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CommodConverter::CommodConverter(cyclus::Context* ctx)
    : cyclus::Facility(ctx) {
  cyclus::Warn<cyclus::EXPERIMENTAL_WARNING>("the CommodConverter is experimental.");
    };

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// pragmas

#pragma cyclus def schema commodconverter::CommodConverter

#pragma cyclus def annotations commodconverter::CommodConverter

#pragma cyclus def initinv commodconverter::CommodConverter

#pragma cyclus def snapshotinv commodconverter::CommodConverter

#pragma cyclus def infiletodb commodconverter::CommodConverter

#pragma cyclus def snapshot commodconverter::CommodConverter

#pragma cyclus def clone commodconverter::CommodConverter

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::InitFrom(CommodConverter* m) {

  #pragma cyclus impl initfromcopy commodconverter::CommodConverter

  cyclus::toolkit::CommodityProducer::Copy(m);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::InitFrom(cyclus::QueryableBackend* b){

  #pragma cyclus impl initfromdb commodconverter::CommodConverter

  using cyclus::toolkit::Commodity;
  Commodity commod = Commodity(out_commod);
  cyclus::toolkit::CommodityProducer::Add(commod);
  cyclus::toolkit::CommodityProducer::SetCapacity(commod, capacity);
  cyclus::toolkit::CommodityProducer::SetCost(commod, cost);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::EnterNotify() {
  Facility::EnterNotify();

  using cyclus::toolkit::Commodity;
  Commodity commod = Commodity(out_commod);
  cyclus::toolkit::CommodityProducer::Add(commod);
  cyclus::toolkit::CommodityProducer::SetCapacity(commod, capacity);
  cyclus::toolkit::CommodityProducer::SetCost(commod, cost);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
std::string CommodConverter::str() {
  std::stringstream ss;
  std::string ans;
  if (cyclus::toolkit::CommodityProducer::
      Produces(cyclus::toolkit::Commodity(out_commod_()))){
    ans = "yes";
  } else {
    ans = "no";
  }
  ss << cyclus::Facility::str();
  ss << " has facility parameters {" << "\n"
     << "     Input Commodity = " << in_commod_() << ",\n"
     << "     Output Commodity = " << out_commod_() << ",\n"
     << "     Process Time = " << process_time_() << ",\n"
     << "     Capacity = " << capacity_() << ",\n"
     << " commod producer members: " << " produces "
     << out_commod << "?:" << ans
     << " capacity: " << cyclus::toolkit::CommodityProducer::Capacity(out_commod_())
     << " cost: " << cyclus::toolkit::CommodityProducer::Cost(out_commod_())
     << "'}";
  return ss.str();
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::Tick() {
  LOG(cyclus::LEV_INFO3, "ComCnv") << prototype() << " is ticking {";

  if (current_capacity() > cyclus::eps()) {
    LOG(cyclus::LEV_INFO4, "ComCnv") << " has capacity for " << current_capacity()
                                       << " kg of " << in_commod
                                       << " recipe: " << in_recipe << ".";
  }

  LOG(cyclus::LEV_INFO3, "ComCnv") << "}";
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::Tock() {
  LOG(cyclus::LEV_INFO3, "ComCnv") << prototype() << " is tocking {";

  BeginProcessing_(); // place unprocessed inventory into processing

  if( ready() >= 0 || process_time_() == 0 ) {
    Convert_(capacity_()); // place processing into stocks
  }

  LOG(cyclus::LEV_INFO3, "ComCnv") << "}";
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
std::set<cyclus::RequestPortfolio<cyclus::Material>::Ptr>
CommodConverter::GetMatlRequests() {
  using cyclus::CapacityConstraint;
  using cyclus::Material;
  using cyclus::RequestPortfolio;
  using cyclus::Request;

  std::set<RequestPortfolio<Material>::Ptr> ports;

  RequestPortfolio<Material>::Ptr port(new RequestPortfolio<Material>());
  Material::Ptr mat = Request_();
  double amt = mat->quantity();

  if (amt > cyclus::eps()) {
    //CapacityConstraint<Material> cc(amt);
    //port->AddConstraint(cc);

    port->AddRequest(mat, this, in_commod_());

    ports.insert(port);
  }

  return ports;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::AcceptMatlTrades(
  const std::vector< std::pair<cyclus::Trade<cyclus::Material>,
  cyclus::Material::Ptr> >& responses) {
  std::vector< std::pair<cyclus::Trade<cyclus::Material>,
      cyclus::Material::Ptr> >::const_iterator it;
  for (it = responses.begin(); it != responses.end(); ++it) {
    AddMat_(it->second);
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
std::set<cyclus::BidPortfolio<cyclus::Material>::Ptr>
CommodConverter::GetMatlBids(cyclus::CommodMap<cyclus::Material>::type&
                          commod_requests) {
  using cyclus::BidPortfolio;
  using cyclus::Material;

  std::set<BidPortfolio<Material>::Ptr> ports;

  std::set<std::string>::const_iterator it;
  BidPortfolio<Material>::Ptr port = GetBids_(commod_requests,
                                              out_commod,
                                              &stocks);
  if (!port->bids().empty()) {
    ports.insert(port);
  }

  return ports;

}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::GetMatlTrades(
  const std::vector< cyclus::Trade<cyclus::Material> >& trades,
  std::vector<std::pair<cyclus::Trade<cyclus::Material>,
  cyclus::Material::Ptr> >& responses) {
  using cyclus::Material;
  using cyclus::Trade;

  // for each trade, respond
  std::vector< Trade<Material> >::const_iterator it;
  for (it = trades.begin(); it != trades.end(); ++it) {
    std::string commodity = it->request->commodity();
    //double qty = it->amt;
    double qty = stocks.quantity();
    // create a material pointer representing what you can offer
    if ( qty > 0 ) {
      Material::Ptr response = TradeResponse_(qty, &stocks);
      responses.push_back(std::make_pair(*it, response));
    }
    LOG(cyclus::LEV_INFO5, "ComCnv") << prototype()
                                  << " just received an order"
                                  << " for " << it->amt
                                  << " of " << commodity;
  }

}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::AddMat_(cyclus::Material::Ptr mat) {
  // Here we do not check that the recipe matches the input recipe.

  LOG(cyclus::LEV_INFO5, "ComCnv") << prototype() << " is initially holding "
                                << inventory.quantity() << " total.";

  try {
    inventory.Push(mat);
  } catch (cyclus::Error& e) {
    e.msg(Agent::InformErrorMsg(e.msg()));
    throw e;
  }

  LOG(cyclus::LEV_INFO5, "ComCnv") << prototype() << " added " << mat->quantity()
                                << " of " << in_commod_()
                                << " to its inventory, which is holding "
                                << inventory.quantity() << " total.";

}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
cyclus::Material::Ptr CommodConverter::Request_() {
  double qty = std::max(0.0, current_capacity());
  LOG(cyclus::LEV_INFO5, "ComCnv") << prototype()
                                  << " just requested "
                                  << current_capacity()
                                  << " of commodity: " << in_commod
                                  << " with recipe: " << in_recipe;
  return cyclus::Material::CreateUntracked(qty,
                                        context()->GetRecipe(in_recipe));
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
cyclus::BidPortfolio<cyclus::Material>::Ptr CommodConverter::GetBids_(
    cyclus::CommodMap<cyclus::Material>::type& commod_requests,
    std::string commod,
    cyclus::toolkit::ResourceBuff* buffer) {
  using cyclus::Bid;
  using cyclus::BidPortfolio;
  using cyclus::CapacityConstraint;
  using cyclus::Composition;
  using cyclus::Converter;
  using cyclus::Material;
  using cyclus::Request;
  using cyclus::ResCast;
  using cyclus::toolkit::ResourceBuff;

  BidPortfolio<Material>::Ptr port(new BidPortfolio<Material>());

  if (commod_requests.count(commod) > 0 && buffer->quantity() > 0) {
    std::vector<Request<Material>*>& requests = commod_requests.at(commod);

    // get offer composition
    Material::Ptr back = ResCast<Material>(buffer->Pop(ResourceBuff::BACK));
    Composition::Ptr comp = back->comp();
    buffer->Push(back);

    std::vector<Request<Material>*>::iterator it;
    for (it = requests.begin(); it != requests.end(); ++it) {
      Request<Material>* req = *it;
      double qty = std::min(req->target()->quantity(), buffer->quantity());
      Material::Ptr offer = Material::CreateUntracked(qty, comp);
      port->AddBid(req, offer, this);
    }

    //CapacityConstraint<Material> cc(buffer->quantity());
    //port->AddConstraint(cc);
  }

  return port;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
cyclus::Material::Ptr CommodConverter::TradeResponse_(
    double qty,
    cyclus::toolkit::ResourceBuff* buffer) {
  using cyclus::Material;
  using cyclus::ResCast;

  std::vector<Material::Ptr> manifest;
  try {
    // pop amount from inventory and blob it into one material
    manifest = ResCast<Material>(buffer->PopQty(qty));
    Material::Ptr response = manifest[0];
    for (int i = 1; i < manifest.size(); i++) {
      response->Absorb(manifest[i]);
    }
    return response;
  } catch(cyclus::Error& e) {
    e.msg(Agent::InformErrorMsg(e.msg()));
    throw e;
  }

}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::BeginProcessing_(){
  if( inventory.count() > 0 ){
    try {
      processing[context()->time()].Push(inventory.Pop());
      LOG(cyclus::LEV_DEBUG2, "ComCnv") << "CommodConverter " << prototype()
                                      << " added resources to processing at t= "
                                      << context()->time();
    } catch (cyclus::Error& e) {
      e.msg(Agent::InformErrorMsg(e.msg()));
      throw e;
    }
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::Convert_(double cap){
  using cyclus::Material;
  using cyclus::ResCast;
  using cyclus::toolkit::ResourceBuff;
  using cyclus::toolkit::Manifest;

  int t = ready();
  if ( ProcessingAmt_(t) > 0 ){
    try {
      double to_pop = std::min(cap, processing[t].quantity());
      // pop appropriate amount of material from processing
      std::vector<Material::Ptr> to_conv =
        ResCast<Material>(processing[t].PopQty(to_pop));
      // if an out_recipe was provided, transmute it
      std::vector<Material::Ptr>::iterator mat;
      if( out_recipe == "" ){
        // if no out recipe, then no transmute needed
        stocks.PushAll(to_conv);
      } else {
        // transmute each mat
        for(mat=to_conv.begin(); mat!=to_conv.end(); ++mat) {
          (*mat)->Transmute(context()->GetRecipe(out_recipe));
          // put it in the stocks
          stocks.Push(*mat);
        }
      }
      AdvanceUnconverted_(t);
      LOG(cyclus::LEV_INFO1, "ComCnv") << "CommodConverter " << prototype()
                                        << " converted quantity : " << to_pop
                                        << " from " << in_commod
                                        << " to " << out_commod
                                        << " at t= " << context()->time();
    } catch (cyclus::Error& e) {
      e.msg(Agent::InformErrorMsg(e.msg()));
      throw e;
    }
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
double CommodConverter::ProcessingAmt_(int time) {
  using cyclus::toolkit::ResourceBuff;
  double to_ret = 0;
  std::map<int, ResourceBuff>::iterator proc = processing.find(time);
  if ( proc!=processing.end() &&
      proc->second.quantity() > 0 ) {
    to_ret = proc->second.quantity();
  }
  return to_ret;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CommodConverter::AdvanceUnconverted_(int time){
  using cyclus::Material;
  using cyclus::ResCast;

  double to_pop = ProcessingAmt_(time);
  if ( to_pop > 0 ) {
    try {
      std::vector<Material::Ptr> to_advance =
      ResCast<Material>(processing[time].PopQty(to_pop));
      processing[time+1].PushAll(to_advance);
    } catch (cyclus::Error& e) {
      e.msg(Agent::InformErrorMsg(e.msg()));
      throw e;
    }
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
extern "C" cyclus::Agent* ConstructCommodConverter(cyclus::Context* ctx) {
  return new CommodConverter(ctx);
}

} // namespace commodconverter
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the <organization> nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "CppUTest/TestHarness.h"

extern "C" {
	#include "CppUTestExt/MockSupport_c.h"
	#include "TestMockSupport_cCFile.h"
}

TEST_GROUP(MockSupport_c)
{
};

TEST(MockSupport_c, expectAndActualOneCall)
{
	mock_c()->expectOneCall("boo");
	mock_c()->actualCall("boo");
	mock_c()->checkExpectations();
}

TEST(MockSupport_c, expectAndActualParameters)
{
	mock_c()->expectOneCall("boo")->withIntParamaters("integer", 1)->withDoubleParameters("doube", 1.0)->
			withStringParameters("string", "string")->withPointerParameters("pointer", (void*) 1);
	mock_c()->actualCall("boo")->withIntParamaters("integer", 1)->withDoubleParameters("doube", 1.0)->
			withStringParameters("string", "string")->withPointerParameters("pointer", (void*) 1);
}

int typeNameIsEqual(void* object1, void* object2)
{
	return object1 == object2;

}

char* typeNameValueToString(void* object)
{
	return (char*) object;
}

TEST(MockSupport_c, expectAndActualParametersOnObject)
{
	mock_c()->installComparator("typeName", typeNameIsEqual, typeNameValueToString);
	mock_c()->expectOneCall("boo")->withParameterOfType("typeName", "name", (void*) 1);
	mock_c()->actualCall("boo")->withParameterOfType("typeName", "name", (void*) 1);
	mock_c()->removeAllComparators();
}

TEST(MockSupport_c, returnIntValue)
{
	mock_c()->expectOneCall("boo")->andReturnIntValue(10);
	LONGS_EQUAL(10, mock_c()->actualCall("boo")->returnValue().value.intValue);
	LONGS_EQUAL(MOCKVALUETYPE_INTEGER, mock_c()->returnValue().type);
}

TEST(MockSupport_c, returnDoubleValue)
{
	mock_c()->expectOneCall("boo")->andReturnDoubleValue(1.0);
	DOUBLES_EQUAL(1.0, mock_c()->actualCall("boo")->returnValue().value.doubleValue, 0.005);
	LONGS_EQUAL(MOCKVALUETYPE_DOUBLE, mock_c()->returnValue().type);
}

TEST(MockSupport_c, returnStringValue)
{
	mock_c()->expectOneCall("boo")->andReturnStringValue("hello world");
	STRCMP_EQUAL("hello world", mock_c()->actualCall("boo")->returnValue().value.stringValue);
	LONGS_EQUAL(MOCKVALUETYPE_STRING, mock_c()->returnValue().type);
}

TEST(MockSupport_c, returnPointerValue)
{
	mock_c()->expectOneCall("boo")->andReturnPointerValue((void*) 10);
	POINTERS_EQUAL((void*) 10, mock_c()->actualCall("boo")->returnValue().value.pointerValue);
	LONGS_EQUAL(MOCKVALUETYPE_POINTER, mock_c()->returnValue().type);
}

TEST(MockSupport_c, MockSupportWithScope)
{
	mock_scope_c("scope")->expectOneCall("boo");
	LONGS_EQUAL(0, mock_scope_c("other")->expectedCallsLeft());
	LONGS_EQUAL(1, mock_scope_c("scope")->expectedCallsLeft());
	mock_scope_c("scope")->actualCall("boo");
}

TEST(MockSupport_c, MockSupportSetIntData)
{
	mock_c()->setIntData("integer", 10);
	LONGS_EQUAL(10, mock_c()->getData("integer").value.intValue);
}

TEST(MockSupport_c, MockSupportSetDoubleData)
{
	mock_c()->setDoubleData("double", 1.0);
	DOUBLES_EQUAL(1.00, mock_c()->getData("double").value.doubleValue, 0.05);
}

TEST(MockSupport_c, MockSupportSetStringData)
{
	mock_c()->setStringData("string", "hello world");
	STRCMP_EQUAL("hello world", mock_c()->getData("string").value.stringValue);
}

TEST(MockSupport_c, MockSupportSetPointerData)
{
	mock_c()->setPointerData("pointer", (void*) 1);
	POINTERS_EQUAL((void*) 1, mock_c()->getData("pointer").value.pointerValue);
}

TEST(MockSupport_c, MockSupportSetDataObject)
{
	mock_c()->setDataObject("name", "type", (void*) 1);
	POINTERS_EQUAL((void*) 1, mock_c()->getData("name").value.objectValue);
}

TEST(MockSupport_c, WorksInCFile)
{
	all_mock_support_c_calls();
}
<commit_msg><commit_after>/*
 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the <organization> nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "CppUTest/TestHarness.h"

extern "C" {
	#include "CppUTest/TestHarness_c.h"
	#include "CppUTestExt/MockSupport_c.h"
	#include "TestMockSupport_cCFile.h"
}

TEST_GROUP(MockSupport_c)
{
};

TEST(MockSupport_c, expectAndActualOneCall)
{
	mock_c()->expectOneCall("boo");
	mock_c()->actualCall("boo");
	mock_c()->checkExpectations();
}

TEST(MockSupport_c, expectAndActualParameters)
{
	mock_c()->expectOneCall("boo")->withIntParamaters("integer", 1)->withDoubleParameters("doube", 1.0)->
			withStringParameters("string", "string")->withPointerParameters("pointer", (void*) 1);
	mock_c()->actualCall("boo")->withIntParamaters("integer", 1)->withDoubleParameters("doube", 1.0)->
			withStringParameters("string", "string")->withPointerParameters("pointer", (void*) 1);
}

int typeNameIsEqual(void* object1, void* object2)
{
	return object1 == object2;

}

char* typeNameValueToString(void* PUNUSED(object))
{
	return (char*) "valueToString";
}

TEST(MockSupport_c, expectAndActualParametersOnObject)
{
	mock_c()->installComparator("typeName", typeNameIsEqual, typeNameValueToString);
	mock_c()->expectOneCall("boo")->withParameterOfType("typeName", "name", (void*) 1);
	mock_c()->actualCall("boo")->withParameterOfType("typeName", "name", (void*) 1);
	mock_c()->checkExpectations();
	mock_c()->removeAllComparators();
}

TEST(MockSupport_c, returnIntValue)
{
	mock_c()->expectOneCall("boo")->andReturnIntValue(10);
	LONGS_EQUAL(10, mock_c()->actualCall("boo")->returnValue().value.intValue);
	LONGS_EQUAL(MOCKVALUETYPE_INTEGER, mock_c()->returnValue().type);
}

TEST(MockSupport_c, returnDoubleValue)
{
	mock_c()->expectOneCall("boo")->andReturnDoubleValue(1.0);
	DOUBLES_EQUAL(1.0, mock_c()->actualCall("boo")->returnValue().value.doubleValue, 0.005);
	LONGS_EQUAL(MOCKVALUETYPE_DOUBLE, mock_c()->returnValue().type);
}

TEST(MockSupport_c, returnStringValue)
{
	mock_c()->expectOneCall("boo")->andReturnStringValue("hello world");
	STRCMP_EQUAL("hello world", mock_c()->actualCall("boo")->returnValue().value.stringValue);
	LONGS_EQUAL(MOCKVALUETYPE_STRING, mock_c()->returnValue().type);
}

TEST(MockSupport_c, returnPointerValue)
{
	mock_c()->expectOneCall("boo")->andReturnPointerValue((void*) 10);
	POINTERS_EQUAL((void*) 10, mock_c()->actualCall("boo")->returnValue().value.pointerValue);
	LONGS_EQUAL(MOCKVALUETYPE_POINTER, mock_c()->returnValue().type);
}

TEST(MockSupport_c, MockSupportWithScope)
{
	mock_scope_c("scope")->expectOneCall("boo");
	LONGS_EQUAL(0, mock_scope_c("other")->expectedCallsLeft());
	LONGS_EQUAL(1, mock_scope_c("scope")->expectedCallsLeft());
	mock_scope_c("scope")->actualCall("boo");
}

TEST(MockSupport_c, MockSupportSetIntData)
{
	mock_c()->setIntData("integer", 10);
	LONGS_EQUAL(10, mock_c()->getData("integer").value.intValue);
}

TEST(MockSupport_c, MockSupportSetDoubleData)
{
	mock_c()->setDoubleData("double", 1.0);
	DOUBLES_EQUAL(1.00, mock_c()->getData("double").value.doubleValue, 0.05);
}

TEST(MockSupport_c, MockSupportSetStringData)
{
	mock_c()->setStringData("string", "hello world");
	STRCMP_EQUAL("hello world", mock_c()->getData("string").value.stringValue);
}

TEST(MockSupport_c, MockSupportSetPointerData)
{
	mock_c()->setPointerData("pointer", (void*) 1);
	POINTERS_EQUAL((void*) 1, mock_c()->getData("pointer").value.pointerValue);
}

TEST(MockSupport_c, MockSupportSetDataObject)
{
	mock_c()->setDataObject("name", "type", (void*) 1);
	POINTERS_EQUAL((void*) 1, mock_c()->getData("name").value.objectValue);
}

TEST(MockSupport_c, WorksInCFile)
{
	all_mock_support_c_calls();
}
<|endoftext|>