<commit_before>#ifndef ARABICA_DOM_CONF_TEST_HPP
#define ARABICA_DOM_CONF_TEST_HPP

#include "../CppUnit/framework/TestCase.h"
#include "../CppUnit/framework/TestSuite.h"
#include "../CppUnit/framework/TestCaller.h"

#include <DOM/Simple/DOMImplementation.hpp>

#ifdef ARABICA_WINDOWS
const std::string PATH_PREFIX="../tests/DOM/conformance/files/";
#else
#include "test_path.hpp"
const std::string PATH_PREFIX=test_path;
#endif

template<class string_type, class string_adaptor>
class DOMTestCase : public TestCase
{
public:
  typedef typename Arabica::DOM::Document<string_type, string_adaptor> Document;
  typedef typename Arabica::DOM::Node<string_type, string_adaptor> Node;
  typedef typename Arabica::DOM::NodeList<string_type, string_adaptor> NodeList;
  typedef typename Arabica::DOM::NamedNodeMap<string_type, string_adaptor> NamedNodeMap;

  typedef string_adaptor SA;

  DOMTestCase(std::string name) : TestCase(name)
  {
  } // DOMTestCase

  virtual void runTest() = 0;
  virtual std::string getTargetURI() const = 0;

protected:

  std::string getContentType() const
  {
    return "";
  } // getContentType

  void preload(const std::string& /*contentType*/, const std::string& /*docURI*/, bool /*willBeModified*/) const
  {
  } // preload

  template<class T>
  bool equals(const T& lhs, const T& rhs) const { return lhs == rhs; }

  Document load(const std::string& docURI, bool /*willBeModified*/)
  {
    std::string filename = PATH_PREFIX + docURI + ".xml";

    Arabica::SAX::InputSource<string_type, string_adaptor> is(SA::construct_from_utf8(filename.c_str()));
    Arabica::SAX2DOM::Parser<string_type, string_adaptor> parser;
    parser.parse(is);

    Document d = parser.getDocument();
    if(d == 0)
      assertImplementation(false, "Could not load", -1, filename);

    //d.normalize();
    return d;
  } // load

  void assertEquals(int expected, int actual, int lineNo, const char* fileName)
  {
    TestCase::assertEquals((long)expected, (long)actual, lineNo, fileName);
  } // assertEquals
  void assertEquals(const char* expected, const string_type& actual, int lineNo, const char* fileName)
  {
    if(SA::construct_from_utf8(expected) != actual)
      assertImplementation (false, notEqualsMessage(expected, SA::asStdString(actual)), lineNo, fileName);
  } // assertEquals
  void assertEquals(const string_type& expected, const string_type& actual, int lineNo, const char* fileName)
  {
    if(expected != actual)
      assertImplementation (false, notEqualsMessage(SA::asStdString(expected), SA::asStdString(actual)), lineNo, fileName);
  } // assertEquals
  void assertEquals(const std::vector<string_type>& expected, const std::vector<string_type>& actual, int lineNo, const char* fileName)
  {
    std::string e = serialise_vector(expected);
    std::string a = serialise_vector(actual);
    if(e != a)
      assertImplementation (false, notEqualsMessage(e, a), lineNo, fileName);
  } // assertEquals
  void assertSame(const Node& lhs, const Node& rhs, int lineNo, const char* fileName)
  {
    if(lhs != rhs)
      assertImplementation(false, "Nodes should be the same", lineNo, fileName);
  } // assertSame

  void assertSize(int size, const NodeList& l, int lineNo, const char* fileName)
  {
    assertEquals(size, l.getLength(), lineNo, fileName);
  } // assertSize
  void assertSize(int size, const NamedNodeMap& l, int lineNo, const char* fileName)
  {
    assertEquals(size, l.getLength(), lineNo, fileName);
  } // assertSize

  bool isNull(const string_type& actual) { return SA::empty(actual); }
  bool isNull(const Node& actual) { return (actual == 0); }
  bool notNull(const string_type& actual) { return !isNull(actual); }
  bool notNull(const Node& actual) { return !isNull(actual); }

  void assertNull(const string_type& actual, int lineNo, const char* fileName)
  {
    if(!SA::empty(actual))
      assertImplementation(false, "String should be empty", lineNo, fileName);
  } // assertNull
  void assertNull(const Node& actual, int lineNo, const char* fileName)
  {
    if(actual != 0)
      assertImplementation(false, "Node should be null", lineNo, fileName);
  } // assertNull
  void assertNull(const NamedNodeMap& actual, int lineNo, const char* fileName)
  {
    if(actual != 0)
      assertImplementation(false, "NamedNodeMap should be empty", lineNo, fileName);
  } // assertNotNull
  void assertNotNull(const Node& actual, int lineNo, const char* fileName)
  {
    if(actual == 0)
      assertImplementation(false, "Node should not be null", lineNo, fileName);
  } // assertNull
  void assertNotNull(const NamedNodeMap& actual, int lineNo, const char* fileName)
  {
    if(actual == 0)
      assertImplementation(false, "NamedNodeMap should not be empty", lineNo, fileName);
  } // assertNotNull
  void skipIfNull(const Node& actual)
  {
    if(actual == 0)
      throw SkipException(getTargetURI());
  } // skipIfNull
  template<typename T>
  void skipIfNot(const Node& actual)
  {
     bool ok = false;
     try {
       T t = (T)actual;
       ok = true;
     }
     catch(const std::bad_cast&) {
     }
     if(!ok)
       throw SkipException(getTargetURI());
  } // skipIfNot
  void assertURIEquals(const char* /*dummy*/,
                       const char* /*scheme*/,
                       const char* /*path*/,
                       const char* /*host*/,
                       const char* /*file*/,
                       const char* /*name*/,
                       const char* /*query*/,
                       const char* /*fragment*/,
                       bool /*isAbsolute*/,
                       const string_type& /*actual*/)
  {
    assertImplementation(false, "Haven't implemented assertURIEquals yet", -1, getTargetURI());
  } // assertURIEquals

  bool equals(const char* expected, const string_type& actual)
  {
    return (SA::construct_from_utf8(expected) == actual);
  } // equals

  void fail(const char* msg, int lineNo, const char* fileName)
  {
    assertImplementation(false, msg, lineNo, fileName);
  } // fail

private:
  std::string serialise_vector(std::vector<string_type> v)
  {
    std::sort(v.begin(), v.end());
    std::string s;
    typedef typename std::vector<string_type>::const_iterator const_iterator;
    for(const_iterator a = v.begin(), e = v.end(); a != e; ++a)
      s += SA::asStdString(*a);
    return s;
  } // serialise_vector
};

#endif
<commit_msg>better error handling when loading docs<commit_after>#ifndef ARABICA_DOM_CONF_TEST_HPP
#define ARABICA_DOM_CONF_TEST_HPP

#include "../CppUnit/framework/TestCase.h"
#include "../CppUnit/framework/TestSuite.h"
#include "../CppUnit/framework/TestCaller.h"

#include <DOM/Simple/DOMImplementation.hpp>

#ifdef ARABICA_WINDOWS
const std::string PATH_PREFIX="../tests/DOM/conformance/files/";
#else
#include "test_path.hpp"
const std::string PATH_PREFIX=test_path;
#endif

template<class string_type, class string_adaptor>
class DOMTestCase : public TestCase
{
public:
  typedef typename Arabica::DOM::Document<string_type, string_adaptor> Document;
  typedef typename Arabica::DOM::Node<string_type, string_adaptor> Node;
  typedef typename Arabica::DOM::NodeList<string_type, string_adaptor> NodeList;
  typedef typename Arabica::DOM::NamedNodeMap<string_type, string_adaptor> NamedNodeMap;

  typedef string_adaptor SA;

  DOMTestCase(std::string name) : TestCase(name)
  {
  } // DOMTestCase

  virtual void runTest() = 0;
  virtual std::string getTargetURI() const = 0;

protected:

  std::string getContentType() const
  {
    return "";
  } // getContentType

  void preload(const std::string& /*contentType*/, const std::string& /*docURI*/, bool /*willBeModified*/) const
  {
  } // preload

  template<class T>
  bool equals(const T& lhs, const T& rhs) const { return lhs == rhs; }

  Document load(const std::string& docURI, bool /*willBeModified*/)
  {
    std::string filename = PATH_PREFIX + docURI + ".xml";

    Arabica::SAX::InputSource<string_type, string_adaptor> is(SA::construct_from_utf8(filename.c_str()));
    Arabica::SAX2DOM::Parser<string_type, string_adaptor> parser;
    Arabica::SAX::CatchErrorHandler<std::string> eh;
    parser.setErrorHandler(eh);
    parser.parse(is);

    Document d = parser.getDocument();
    if(d == 0)
      assertImplementation(false, "Could not load : " + eh.errors(), -1, filename);

    //d.normalize();
    return d;
  } // load

  void assertEquals(int expected, int actual, int lineNo, const char* fileName)
  {
    TestCase::assertEquals((long)expected, (long)actual, lineNo, fileName);
  } // assertEquals
  void assertEquals(const char* expected, const string_type& actual, int lineNo, const char* fileName)
  {
    if(SA::construct_from_utf8(expected) != actual)
      assertImplementation (false, notEqualsMessage(expected, SA::asStdString(actual)), lineNo, fileName);
  } // assertEquals
  void assertEquals(const string_type& expected, const string_type& actual, int lineNo, const char* fileName)
  {
    if(expected != actual)
      assertImplementation (false, notEqualsMessage(SA::asStdString(expected), SA::asStdString(actual)), lineNo, fileName);
  } // assertEquals
  void assertEquals(const std::vector<string_type>& expected, const std::vector<string_type>& actual, int lineNo, const char* fileName)
  {
    std::string e = serialise_vector(expected);
    std::string a = serialise_vector(actual);
    if(e != a)
      assertImplementation (false, notEqualsMessage(e, a), lineNo, fileName);
  } // assertEquals
  void assertSame(const Node& lhs, const Node& rhs, int lineNo, const char* fileName)
  {
    if(lhs != rhs)
      assertImplementation(false, "Nodes should be the same", lineNo, fileName);
  } // assertSame

  void assertSize(int size, const NodeList& l, int lineNo, const char* fileName)
  {
    assertEquals(size, l.getLength(), lineNo, fileName);
  } // assertSize
  void assertSize(int size, const NamedNodeMap& l, int lineNo, const char* fileName)
  {
    assertEquals(size, l.getLength(), lineNo, fileName);
  } // assertSize

  bool isNull(const string_type& actual) { return SA::empty(actual); }
  bool isNull(const Node& actual) { return (actual == 0); }
  bool notNull(const string_type& actual) { return !isNull(actual); }
  bool notNull(const Node& actual) { return !isNull(actual); }

  void assertNull(const string_type& actual, int lineNo, const char* fileName)
  {
    if(!SA::empty(actual))
      assertImplementation(false, "String should be empty", lineNo, fileName);
  } // assertNull
  void assertNull(const Node& actual, int lineNo, const char* fileName)
  {
    if(actual != 0)
      assertImplementation(false, "Node should be null", lineNo, fileName);
  } // assertNull
  void assertNull(const NamedNodeMap& actual, int lineNo, const char* fileName)
  {
    if(actual != 0)
      assertImplementation(false, "NamedNodeMap should be empty", lineNo, fileName);
  } // assertNotNull
  void assertNotNull(const Node& actual, int lineNo, const char* fileName)
  {
    if(actual == 0)
      assertImplementation(false, "Node should not be null", lineNo, fileName);
  } // assertNull
  void assertNotNull(const NamedNodeMap& actual, int lineNo, const char* fileName)
  {
    if(actual == 0)
      assertImplementation(false, "NamedNodeMap should not be empty", lineNo, fileName);
  } // assertNotNull
  void skipIfNull(const Node& actual)
  {
    if(actual == 0)
      throw SkipException(getTargetURI());
  } // skipIfNull
  template<typename T>
  void skipIfNot(const Node& actual)
  {
     bool ok = false;
     try {
       T t = (T)actual;
       ok = true;
     }
     catch(const std::bad_cast&) {
     }
     if(!ok)
       throw SkipException(getTargetURI());
  } // skipIfNot
  void assertURIEquals(const char* /*dummy*/,
                       const char* /*scheme*/,
                       const char* /*path*/,
                       const char* /*host*/,
                       const char* /*file*/,
                       const char* /*name*/,
                       const char* /*query*/,
                       const char* /*fragment*/,
                       bool /*isAbsolute*/,
                       const string_type& /*actual*/)
  {
    assertImplementation(false, "Haven't implemented assertURIEquals yet", -1, getTargetURI());
  } // assertURIEquals

  bool equals(const char* expected, const string_type& actual)
  {
    return (SA::construct_from_utf8(expected) == actual);
  } // equals

  void fail(const char* msg, int lineNo, const char* fileName)
  {
    assertImplementation(false, msg, lineNo, fileName);
  } // fail

private:
  std::string serialise_vector(std::vector<string_type> v)
  {
    std::sort(v.begin(), v.end());
    std::string s;
    typedef typename std::vector<string_type>::const_iterator const_iterator;
    for(const_iterator a = v.begin(), e = v.end(); a != e; ++a)
      s += SA::asStdString(*a);
    return s;
  } // serialise_vector
};

#endif
<|endoftext|>


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "CFGMutation.h"

namespace cfg {

void CFGMutation::flush() {
  auto ii = InstructionIterable(m_cfg);
  for (auto it = ii.begin(); !it.is_end();) {
    auto c = m_changes.find(it->insn);
    if (c == m_changes.end()) {
      // No change anchored at this instruction.
      ++it;
      continue;
    }

    auto& change = c->second;
    change.apply(m_cfg, it);

    // The anchor can be encountered again.  Erase the change to avoid it being
    // applied again.
    m_changes.erase(c);
  }

  // The effect of one change can erase the anchor for another.  The changes
  // left behind are the ones whose anchors were removed. They will never be
  // applied so clear them.
  m_changes.clear();
}

void CFGMutation::ChangeSet::apply(ControlFlowGraph& cfg,
                                   InstructionIterator& it) {
  // Save in case of iterator invalidation.
  Block* b = it.block();

  bool invalidated = false;
  switch (m_where) {
  case CFGMutation::Insert::Before:
    invalidated = cfg.insert_before(it, m_instructions);
    break;
  case CFGMutation::Insert::After:
    invalidated = cfg.insert_after(it, m_instructions);
    break;
  case CFGMutation::Insert::Replacing: {
    // The target will be invalidated by the replacement, increment the iterator
    // in preparation.
    auto target = it++;

    if (target->insn->has_move_result_any() &&
        cfg.move_result_of(target) == it) {
      // The iterator is now sitting over the target's move-result, which is
      // also going to be invalidated, increment again.
      ++it;
    }

    invalidated = cfg.replace_insns(target, m_instructions);
    break;
  }
  }

  if (invalidated) {
    // move iterator to the end of the last iterator's block to avoid missing
    // any instructions.
    it = b->to_cfg_instruction_iterator(b->end());
  }
}

} // namespace cfg
<commit_msg>Fix end iterator dereference in CFGMutation<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "CFGMutation.h"

namespace cfg {

void CFGMutation::flush() {
  auto ii = InstructionIterable(m_cfg);
  for (auto it = ii.begin(); !it.is_end();) {
    auto c = m_changes.find(it->insn);
    if (c == m_changes.end()) {
      // No change anchored at this instruction.
      ++it;
      continue;
    }

    auto& change = c->second;
    change.apply(m_cfg, it);

    // The anchor can be encountered again.  Erase the change to avoid it being
    // applied again.
    m_changes.erase(c);
  }

  // The effect of one change can erase the anchor for another.  The changes
  // left behind are the ones whose anchors were removed. They will never be
  // applied so clear them.
  m_changes.clear();
}

void CFGMutation::ChangeSet::apply(ControlFlowGraph& cfg,
                                   InstructionIterator& it) {
  // Save in case of iterator invalidation.
  Block* b = it.block();

  bool invalidated = false;
  switch (m_where) {
  case CFGMutation::Insert::Before:
    invalidated = cfg.insert_before(it, m_instructions);
    break;
  case CFGMutation::Insert::After:
    invalidated = cfg.insert_after(it, m_instructions);
    break;
  case CFGMutation::Insert::Replacing: {
    // The target will be invalidated by the replacement, increment the iterator
    // in preparation.
    auto target = it++;

    if (target->insn->has_move_result_any() && !it.is_end() &&
        cfg.move_result_of(target) == it) {
      // The iterator is now sitting over the target's move-result, which is
      // also going to be invalidated, increment again.
      ++it;
    }

    invalidated = cfg.replace_insns(target, m_instructions);
    break;
  }
  }

  if (invalidated) {
    // move iterator to the end of the last iterator's block to avoid missing
    // any instructions.
    it = b->to_cfg_instruction_iterator(b->end());
  }
}

} // namespace cfg
<|endoftext|>


<commit_before>//include <tclap/CmdLine.h>
#include <boost/program_options/errors.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/positional_options.hpp>
#include <boost/program_options/value_semantic.hpp>
#include <boost/program_options/variables_map.hpp>
#include <ctype.h>
#include <execinfo.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>

#include "bin_file.hpp"
#include "prenexusrenderer.hpp"
#include "renderer.hpp"
#include "version.hpp"

using std::cerr;
using std::cout;
using std::endl;
using std::invalid_argument;
using std::string;
using std::stringstream;
using std::vector;
namespace po = boost::program_options;

typedef uint32_t event_t;

struct Config{
  bool byte_swap;
  bool show_data;
  bool show_line_num;
  bool multi_file;
  bool sum_data;
  bool sum_block;
  bool is_event;
  bool get_pix_range;
  vector<size_t> integrate;
};

static const size_t BLOCK_SIZE=1024;
static const event_t ERROR=0x80000000;
static const string DEFAULT_TYPE="char";

static string::size_type count_occur(const string &str, const string &ch){
  string::size_type count = 0;
  string::size_type index = 0;

  // infinite loop to make sure that the entire string is parsed.
#ifdef _MSC_VER
  for(;;) {
#else
  while(true) {
#endif
      index = str.find(ch,index+1);
      if(index==string::npos)
        {
          break;
        }
      count++;
    }
  return count;
}

static bool my_isnotdigit(char c){
  return !isdigit(c);
}

static int str_to_int(const string &str){
  if(str.substr(0,1)=="-")
    return -1*str_to_int(str.substr(1,str.size()));

  string::const_iterator it = str.begin();
  it = std::find_if(it,str.end(),my_isnotdigit);

  if(it!=str.end())
    throw invalid_argument("str_to_int(string) argument is not an integer");

  return atol(str.c_str());
}

extern vector<string> split(const string &source,const string &split)
{
  string::size_type number=count_occur(source,split);
  if(number==0)
    {
      vector<string> result;
      result.push_back(source);
      return result;
    }

  vector<string> result;
  string::size_type start=0;
  string::size_type stop=0;
  string inner;
#ifdef _MSC_VER
  for(;;) {
#else
    while(true) {
#endif
      stop=source.find(split,start);
      if(stop==string::npos)
        {
          result.push_back(source.substr(start));
          break;
        }
      else
        {
          result.push_back(source.substr(start,stop-start));
          start=stop+split.size();
        }
    }
  return result;
}

template <typename NumT>
string thing_to_str(const NumT thing) {
  std::stringstream s;
  s << thing;
  return s.str();
}

template <typename NumT>
string thing_to_str(const vector<NumT> &thing) {
  std::stringstream s;
  size_t length = thing.size();
  for ( size_t i = 0 ; i < length ; ++i ){
    s << thing[i] << " ";
  }
  return s.str();
}

string pixid_str(const size_t pixid, const vector<size_t> &bounds) {
  size_t rank = bounds.size();
  if (rank<=0) {
    return "";
  }
  size_t max_index=1;
  for (size_t i = 0 ; i<rank ; ++i ){
    max_index*=bounds[i];
  }
  if(pixid>max_index) {
    std::stringstream s;
    s << "Pixel id outside of known bounds: " << pixid << ">" << max_index;
    throw std::runtime_error(s.str());
  }
  size_t my_id = pixid;
  vector<size_t> indices(bounds.size());
  for (size_t i = 0 ; i < rank-1 ; ++i ) {
    indices[i] = my_id / bounds[i+1];
    my_id = my_id - indices[i] * bounds[i+1];
  }
  indices[rank-1] = my_id;

  return thing_to_str(indices);
}

void handler() {
  void *trace_elems[20];
  int trace_elem_count(backtrace(trace_elems, 20));
  char **stack_syms(backtrace_symbols(trace_elems, trace_elem_count));
  for (int i = 0; i < trace_elem_count; ++i) {
    std::cout << stack_syms[i] << "\n";
  }
  free(stack_syms);

  exit(1);
}

/**
 * The main entry point for the program.
 */
int main(int argc, char** argv)
{
  std::set_terminate(handler);

  // ---------- Declare the supported options.
  po::options_description generic_options("Generic options");
  generic_options.add_options()
    ("help,h", "Produce this help message.")
    ("version,v", "Print version string.")
    ;

  stringstream typesHelp;
  typesHelp << "Set the type of the data. Allowed values are: " << render::getKnownDataDescr() << ", " << prenexus::getKnownDataDescr();
  po::options_description config_options("Configuration");
  config_options.add_options()
    ("type,t", po::value<string>()->default_value(DEFAULT_TYPE), typesHelp.str().c_str())
    ("offset", po::value<size_t>()->default_value(0), "Skip to this position (in bytes) in the file.")
    ("length", po::value<size_t>()->default_value(0), "Number of items to read (NOT in bytes). Zero means read to end of file.")
    ("records", po::value<size_t>()->default_value(1), "Number of items to print per line")
    ("byteswap", "Perform byte swapping on the data")
    ("quiet,q", "Do not print out values")
    ("lines", "show line numbers")
    ;

  po::options_description hidden_options;
  hidden_options.add_options()
    ("filename", po::value< vector<string> >(), "input files")
    ;

  // all options available on the command line
  po::options_description cmdline_options;
  cmdline_options.add(generic_options).add(config_options).add(hidden_options);

  // all options visible to the user
  po::options_description visible_options("Allowed options");
  visible_options.add(generic_options).add(config_options);

  // ---------- parse the command line
  po::positional_options_description p;
  p.add("filename", -1);
  po::variables_map vm;
  po::store(po::command_line_parser(argc, argv).options(cmdline_options)
	    .positional(p).run(), vm);
  po::notify(vm);

  // ---------- get everything out of the options
  // work with generic options
  if (vm.count("help")) {
    cout << "Usage: " << argv[0] << " [options] <filenames>" << endl;
    cout << endl;

    cout << "Source code located at http://github.com/peterfpeterson/morebin" << endl;
    cout << endl;

    cout << visible_options << endl;
    cout << endl;

    cout << "Notes on complex types:" << endl;
    cout << "  The following types are printed in colums (in order)" << endl;
    cout <<  endl;
    cout << "  event" << endl;
    cout << "\ttof(uint32_t) Time of flight." << endl;
    cout << "\tpid(uint32_t) Pixel identifier as published by the DAS/DAE/DAQ." << endl;
    cout << "  oldpulseid" << endl;
    cout << "\ttime(uint32_t,uint32_t) Time of the pulse" << endl;
    cout << "\tevent_index(uint64_t)   The index of the first event for this pulse." << endl;
    cout << "  pulseid" << endl;
    cout << "\ttime(uint32_t,uint32_t) Time of the pulse" << endl;
    cout << "\tevent_index(uint64_t)   The index of the first event for this pulse." << endl;
    cout << "\tpCurrent(double)        The proton charge for the pulse." << endl;
    cout << "  rtdl" << endl;
    cout << "\ttime(uint32_t,uint32_t) Time of the pulse" << endl;
    cout << "\tpulseType(uint32_t)" << endl;
    cout << "\tvetoStatus(uint32_t)" << endl;
    cout << "\tpCurrent(uint32_t)      The proton charge for the pulse." << endl;
    cout << "\tspare(uint32_t)" << endl;
    return 0;
  }
  if (vm.count("version")) {
    cout << "morebin version " << VERSION << " built " << DATE << endl;
    cout << endl;
    cout << "http://github.com/peterfpeterson/morebin/";
    if (VERSION.find("SNAPSHOT") == string::npos)
      cout << "tree/v" << VERSION;
    cout << endl;
    return 0;
  }

  // config options
  size_t offset = 0;
  if (vm.count("offset"))
    offset = vm["offset"].as<size_t>();
  size_t length = 0;
  if (vm.count("length"))
    length = vm["length"].as<size_t>();
  size_t numItemsPerLine = 1;
  if (vm.count("records"))
    numItemsPerLine = vm["records"].as<size_t>();
  bool byteswap = (vm.count("byteswap") > 0);
  bool quiet = (vm.count("quiet") > 0);
  string dataType = DEFAULT_TYPE;
  if (vm.count("type"))
    dataType = vm["type"].as<string>();
  bool showLines = (vm.count("lines") > 0);

  // hidden options
  vector<string> files;
  if (vm.count("filename"))
  {
    files = vm["filename"].as< vector<string> >();
  }
  else
  {
    cerr << "ERROR: failed to supply <filename>" << endl;
    //cmd.getOutput()->usage(cmd);
    return -1;
  }

  // ---------- push through the list of files
  try {
    bool multiFile = (files.size() > 1);
    render::Renderer * renderer = NULL;
    if (render::hasDataDescr(dataType)) {
      renderer = new render::Renderer();
      renderer->setDataDescr(dataType);
    } else if (prenexus::hasDataDescr(dataType)) {
      renderer = new prenexus::PrenexusRenderer();
      renderer->setDataDescr(dataType);
    } else {
      std::cout << "Unknown type \"" << dataType << "\". Allowed values are: "
      		<< render::getKnownDataDescr() << ", "
		<< prenexus::getKnownDataDescr() << std::endl;
      return -1;
    }
    renderer->quiet(quiet);
    renderer->showLines(showLines);
    renderer->numItemsPerLine(numItemsPerLine);

    for (std::size_t i = 0; i < files.size(); i++) {
      BinFile file(files[i]);
      file.setByteSwap(byteswap);
      if (multiFile) {
	cout << "******************************" << endl;
	cout << "* " << files[i] << " size:" << file.size_in_bytes() << endl;
	cout << "******************************" << endl;
      }
      renderer->showData(file, offset, length);
    }

    delete renderer;
  } catch(std::runtime_error &e) {
    cerr << "RUNTIME ERROR:" << e.what() << endl;
    return -1;
  }

  return 0;
}
<commit_msg>Fix coverity issues<commit_after>//include <tclap/CmdLine.h>
#include <boost/program_options/errors.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/positional_options.hpp>
#include <boost/program_options/value_semantic.hpp>
#include <boost/program_options/variables_map.hpp>
#include <ctype.h>
#include <execinfo.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>

#include "bin_file.hpp"
#include "prenexusrenderer.hpp"
#include "renderer.hpp"
#include "version.hpp"

using std::cerr;
using std::cout;
using std::endl;
using std::invalid_argument;
using std::string;
using std::stringstream;
using std::vector;
namespace po = boost::program_options;

typedef uint32_t event_t;

struct Config{
  bool byte_swap;
  bool show_data;
  bool show_line_num;
  bool multi_file;
  bool sum_data;
  bool sum_block;
  bool is_event;
  bool get_pix_range;
  vector<size_t> integrate;
};

static const size_t BLOCK_SIZE=1024;
static const event_t ERROR=0x80000000;
static const string DEFAULT_TYPE="char";

static string::size_type count_occur(const string &str, const string &ch){
  string::size_type count = 0;
  string::size_type index = 0;

  // infinite loop to make sure that the entire string is parsed.
#ifdef _MSC_VER
  for(;;) {
#else
  while(true) {
#endif
      index = str.find(ch,index+1);
      if(index==string::npos)
        {
          break;
        }
      count++;
    }
  return count;
}

static bool my_isnotdigit(char c){
  return !isdigit(c);
}

static int str_to_int(const string &str){
  if(str.substr(0,1)=="-")
    return -1*str_to_int(str.substr(1,str.size()));

  string::const_iterator it = str.begin();
  it = std::find_if(it,str.end(),my_isnotdigit);

  if(it!=str.end())
    throw invalid_argument("str_to_int(string) argument is not an integer");

  return atol(str.c_str());
}

extern vector<string> split(const string &source,const string &split)
{
  string::size_type number=count_occur(source,split);
  if(number==0)
    {
      vector<string> result;
      result.push_back(source);
      return result;
    }

  vector<string> result;
  string::size_type start=0;
  string::size_type stop=0;
  string inner;
#ifdef _MSC_VER
  for(;;) {
#else
    while(true) {
#endif
      stop=source.find(split,start);
      if(stop==string::npos)
        {
          result.push_back(source.substr(start));
          break;
        }
      else
        {
          result.push_back(source.substr(start,stop-start));
          start=stop+split.size();
        }
    }
  return result;
}

template <typename NumT>
string thing_to_str(const NumT thing) {
  std::stringstream s;
  s << thing;
  return s.str();
}

template <typename NumT>
string thing_to_str(const vector<NumT> &thing) {
  std::stringstream s;
  size_t length = thing.size();
  for ( size_t i = 0 ; i < length ; ++i ){
    s << thing[i] << " ";
  }
  return s.str();
}

string pixid_str(const size_t pixid, const vector<size_t> &bounds) {
  size_t rank = bounds.size();
  if (rank<=0) {
    return "";
  }
  size_t max_index=1;
  for (size_t i = 0 ; i<rank ; ++i ){
    max_index*=bounds[i];
  }
  if(pixid>max_index) {
    std::stringstream s;
    s << "Pixel id outside of known bounds: " << pixid << ">" << max_index;
    throw std::runtime_error(s.str());
  }
  size_t my_id = pixid;
  vector<size_t> indices(bounds.size());
  for (size_t i = 0 ; i < rank-1 ; ++i ) {
    indices[i] = my_id / bounds[i+1];
    my_id = my_id - indices[i] * bounds[i+1];
  }
  indices[rank-1] = my_id;

  return thing_to_str(indices);
}

void handler() {
  void *trace_elems[20];
  int trace_elem_count(backtrace(trace_elems, 20));
  char **stack_syms(backtrace_symbols(trace_elems, trace_elem_count));
  for (int i = 0; i < trace_elem_count; ++i) {
    std::cout << stack_syms[i] << "\n";
  }
  free(stack_syms);

  exit(1);
}

/**
 * The main entry point for the program.
 */
int main(int argc, char** argv)
{
  std::set_terminate(handler);

  // ---------- Declare the supported options.
  po::options_description generic_options("Generic options");
  generic_options.add_options()
    ("help,h", "Produce this help message.")
    ("version,v", "Print version string.")
    ;

  stringstream typesHelp;
  typesHelp << "Set the type of the data. Allowed values are: " << render::getKnownDataDescr() << ", " << prenexus::getKnownDataDescr();
  po::options_description config_options("Configuration");
  try {
  config_options.add_options()
    ("type,t", po::value<string>()->default_value(DEFAULT_TYPE), typesHelp.str().c_str())
    ("offset", po::value<size_t>()->default_value(0), "Skip to this position (in bytes) in the file.")
    ("length", po::value<size_t>()->default_value(0), "Number of items to read (NOT in bytes). Zero means read to end of file.")
    ("records", po::value<size_t>()->default_value(1), "Number of items to print per line")
    ("byteswap", "Perform byte swapping on the data")
    ("quiet,q", "Do not print out values")
    ("lines", "show line numbers")
    ;
  } catch (boost::bad_lexical_cast &e) {
    cerr << "Failed to initialize command line parser: " << e.what() << endl;
    return -1;
  }

  po::options_description hidden_options;
  hidden_options.add_options()
    ("filename", po::value< vector<string> >(), "input files")
    ;

  // all options available on the command line
  po::options_description cmdline_options;
  cmdline_options.add(generic_options).add(config_options).add(hidden_options);

  // all options visible to the user
  po::options_description visible_options("Allowed options");
  visible_options.add(generic_options).add(config_options);

  // ---------- parse the command line
  po::positional_options_description p;
  p.add("filename", -1);
  po::variables_map vm;
  po::store(po::command_line_parser(argc, argv).options(cmdline_options)
	    .positional(p).run(), vm);
  po::notify(vm);

  // ---------- get everything out of the options
  // work with generic options
  if (vm.count("help")) {
    cout << "Usage: " << argv[0] << " [options] <filenames>" << endl;
    cout << endl;

    cout << "Source code located at http://github.com/peterfpeterson/morebin" << endl;
    cout << endl;

    cout << visible_options << endl;
    cout << endl;

    cout << "Notes on complex types:" << endl;
    cout << "  The following types are printed in colums (in order)" << endl;
    cout <<  endl;
    cout << "  event" << endl;
    cout << "\ttof(uint32_t) Time of flight." << endl;
    cout << "\tpid(uint32_t) Pixel identifier as published by the DAS/DAE/DAQ." << endl;
    cout << "  oldpulseid" << endl;
    cout << "\ttime(uint32_t,uint32_t) Time of the pulse" << endl;
    cout << "\tevent_index(uint64_t)   The index of the first event for this pulse." << endl;
    cout << "  pulseid" << endl;
    cout << "\ttime(uint32_t,uint32_t) Time of the pulse" << endl;
    cout << "\tevent_index(uint64_t)   The index of the first event for this pulse." << endl;
    cout << "\tpCurrent(double)        The proton charge for the pulse." << endl;
    cout << "  rtdl" << endl;
    cout << "\ttime(uint32_t,uint32_t) Time of the pulse" << endl;
    cout << "\tpulseType(uint32_t)" << endl;
    cout << "\tvetoStatus(uint32_t)" << endl;
    cout << "\tpCurrent(uint32_t)      The proton charge for the pulse." << endl;
    cout << "\tspare(uint32_t)" << endl;
    return 0;
  }
  if (vm.count("version")) {
    cout << "morebin version " << VERSION << " built " << DATE << endl;
    cout << endl;
    cout << "http://github.com/peterfpeterson/morebin/";
    if (VERSION.find("SNAPSHOT") == string::npos)
      cout << "tree/v" << VERSION;
    cout << endl;
    return 0;
  }

  // config options
  size_t offset = 0;
  if (vm.count("offset"))
    offset = vm["offset"].as<size_t>();
  size_t length = 0;
  if (vm.count("length"))
    length = vm["length"].as<size_t>();
  size_t numItemsPerLine = 1;
  if (vm.count("records"))
    numItemsPerLine = vm["records"].as<size_t>();
  bool byteswap = (vm.count("byteswap") > 0);
  bool quiet = (vm.count("quiet") > 0);
  string dataType = DEFAULT_TYPE;
  if (vm.count("type"))
    dataType = vm["type"].as<string>();
  bool showLines = (vm.count("lines") > 0);

  // hidden options
  vector<string> files;
  if (vm.count("filename"))
  {
    try {
      files = vm["filename"].as<vector<string>>();
    } catch (boost::bad_any_cast &e) {
      cerr << "While parsing command line options: " << e.what() << endl;
      return -1;
    }
  }
  else
  {
    cerr << "ERROR: failed to supply <filename>" << endl;
    //cmd.getOutput()->usage(cmd);
    return -1;
  }

  // ---------- push through the list of files
  try {
    bool multiFile = (files.size() > 1);
    render::Renderer * renderer = NULL;
    if (render::hasDataDescr(dataType)) {
      renderer = new render::Renderer();
      renderer->setDataDescr(dataType);
    } else if (prenexus::hasDataDescr(dataType)) {
      renderer = new prenexus::PrenexusRenderer();
      renderer->setDataDescr(dataType);
    } else {
      std::cout << "Unknown type \"" << dataType << "\". Allowed values are: "
      		<< render::getKnownDataDescr() << ", "
		<< prenexus::getKnownDataDescr() << std::endl;
      return -1;
    }
    renderer->quiet(quiet);
    renderer->showLines(showLines);
    renderer->numItemsPerLine(numItemsPerLine);

    for (std::size_t i = 0; i < files.size(); i++) {
      BinFile file(files[i]);
      file.setByteSwap(byteswap);
      if (multiFile) {
	cout << "******************************" << endl;
	cout << "* " << files[i] << " size:" << file.size_in_bytes() << endl;
	cout << "******************************" << endl;
      }
      renderer->showData(file, offset, length);
    }

    delete renderer;
  } catch(std::runtime_error &e) {
    cerr << "RUNTIME ERROR:" << e.what() << endl;
    return -1;
  }

  return 0;
}
<|endoftext|>


<commit_before>/*
Copyright libCellML Contributors

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 <iostream>
#include <libcellml>

/*
 * The tests in this file are here to catch any branches of code that
 * are not picked up by the main tests testing the API of the library
 */
TEST(Coverage, import)
{
    const std::string id = "id";
    libcellml::ImportSource i;
    libcellml::ImportSource im;

    i.setId(id);

    im = std::move(i);

    EXPECT_EQ(id, im.getId());
}

TEST(Coverage, printer)
{
    libcellml::Printer p;
    libcellml::Printer pm;

    libcellml::ErrorPtr error = std::make_shared<libcellml::Error>();

    p.addError(error);

    pm = std::move(p);

    EXPECT_EQ(size_t(1), pm.errorCount());
}

TEST(Coverage, units)
{
    const std::string n = "dimensionless";
    libcellml::Units u;
    libcellml::Units um;

    u.setName("dimensionless");

    um = std::move(u);

    EXPECT_EQ(n, um.getName());
}

TEST(Coverage, when)
{
    const std::string id = "id";
    libcellml::When w;
    libcellml::When wm;

    w.setId(id);

    wm = std::move(w);

    EXPECT_EQ(id, wm.getId());
}

TEST(Coverage, prefixToString)
{
    libcellml::Model m;
    libcellml::Printer printer;

    std::vector<std::string> prefixString =
        {"atto",
         "centi",
         "deca",
         "deci",
         "exa",
         "femto",
         "giga",
         "hecto",
         "kilo",
         "mega",
         "micro",
         "milli",
         "nano",
         "peta",
         "pico",
         "tera",
         "yocto",
         "yotta",
         "zepto",
         "zetta"};
    std::vector<libcellml::Prefix> prefixEnum =
        {libcellml::Prefix::ATTO,
         libcellml::Prefix::CENTI,
         libcellml::Prefix::DECA,
         libcellml::Prefix::DECI,
         libcellml::Prefix::EXA,
         libcellml::Prefix::FEMTO,
         libcellml::Prefix::GIGA,
         libcellml::Prefix::HECTO,
         libcellml::Prefix::KILO,
         libcellml::Prefix::MEGA,
         libcellml::Prefix::MICRO,
         libcellml::Prefix::MILLI,
         libcellml::Prefix::NANO,
         libcellml::Prefix::PETA,
         libcellml::Prefix::PICO,
         libcellml::Prefix::TERA,
         libcellml::Prefix::YOCTO,
         libcellml::Prefix::YOTTA,
         libcellml::Prefix::ZEPTO,
         libcellml::Prefix::ZETTA};
    for (std::vector<std::string>::size_type i = 0; i != prefixString.size(); ++i) {
        libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();
        u->setName("abcdefg");
        u->addUnit("empty", prefixEnum[i]);

        m.addUnits(u);

        const std::string a = printer.printModel(m);
        std::size_t found = a.find(prefixString[i]);
        EXPECT_NE(std::string::npos, found);
        m.removeAllUnits();
    }
}

TEST(Coverage, variable)
{
    const std::string e = "<variable units=\"dimensionless\" initial_value=\"1\" interface=\"public\"/>\n";
    libcellml::Variable v;
    libcellml::Variable vm;
    libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();

    v.setInitialValue(1.0);
    v.setInterfaceType("public");
    u->setName("dimensionless");
    v.setUnits(u);

    vm = std::move(v);

    // Copy constructor
    libcellml::Variable vc(vm);

    libcellml::Printer printer;
    const std::string a = printer.printVariable(vc);
    EXPECT_EQ(e, a);
}

TEST(Coverage, component)
{
    const std::string n = "name";
    const std::string e =
        "<component name=\"name\">\n"
        "  <variable/>\n"
        "  <1+1=2>\n"
        "</component>\n";
    const std::string math = "<1+1=2>\n";

    libcellml::ComponentPtr c = std::make_shared<libcellml::Component>();
    libcellml::ComponentPtr cm;
    libcellml::VariablePtr v = std::make_shared<libcellml::Variable>();

    c->setName(n);
    c->addVariable(v);
    c->setMath(math);

    libcellml::Printer printer;
    std::string a = printer.printComponent(c);
    EXPECT_EQ(e, a);

    cm = std::move(c);
    a = printer.printComponent(cm);
    EXPECT_EQ(e, a);

    // Move constructor, assignment operator and swap method
    std::vector<libcellml::Component> vec;
    vec.emplace_back();

    libcellml::Component rc;
    libcellml::Component ao;

    rc.setName(n);

    ao = rc;

    EXPECT_EQ(n, ao.getName());
}

TEST(Coverage, error)
{
    libcellml::ErrorPtr err = std::make_shared<libcellml::Error>();
    libcellml::Error e;
    libcellml::Error em;
    const std::string description = "test";

    e.setDescription(description);
    e.setKind(libcellml::Error::Kind::XML);

    em = std::move(e);
    // Copy constructor
    libcellml::Error ec(em);

    EXPECT_EQ(description, ec.getDescription());
    EXPECT_EQ(libcellml::Error::Kind::XML, ec.getKind());
}

TEST(Coverage, model)
{
    // Move constructor, assignment operator and swap method
    std::vector<libcellml::Model> vec;
    vec.emplace_back();

    libcellml::Model rm;
    libcellml::Model ao;

    ao = rm;
}
<commit_msg>Coverage tests: removed the prefixToString test, which adds nothing in terms of coverage.<commit_after>/*
Copyright libCellML Contributors

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 <iostream>
#include <libcellml>

/*
 * The tests in this file are here to catch any branches of code that
 * are not picked up by the main tests testing the API of the library
 */
TEST(Coverage, import)
{
    const std::string id = "id";
    libcellml::ImportSource i;
    libcellml::ImportSource im;

    i.setId(id);

    im = std::move(i);

    EXPECT_EQ(id, im.getId());
}

TEST(Coverage, printer)
{
    libcellml::Printer p;
    libcellml::Printer pm;

    libcellml::ErrorPtr error = std::make_shared<libcellml::Error>();

    p.addError(error);

    pm = std::move(p);

    EXPECT_EQ(size_t(1), pm.errorCount());
}

TEST(Coverage, units)
{
    const std::string n = "dimensionless";
    libcellml::Units u;
    libcellml::Units um;

    u.setName("dimensionless");

    um = std::move(u);

    EXPECT_EQ(n, um.getName());
}

TEST(Coverage, when)
{
    const std::string id = "id";
    libcellml::When w;
    libcellml::When wm;

    w.setId(id);

    wm = std::move(w);

    EXPECT_EQ(id, wm.getId());
}

TEST(Coverage, variable)
{
    const std::string e = "<variable units=\"dimensionless\" initial_value=\"1\" interface=\"public\"/>\n";
    libcellml::Variable v;
    libcellml::Variable vm;
    libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();

    v.setInitialValue(1.0);
    v.setInterfaceType("public");
    u->setName("dimensionless");
    v.setUnits(u);

    vm = std::move(v);

    // Copy constructor
    libcellml::Variable vc(vm);

    libcellml::Printer printer;
    const std::string a = printer.printVariable(vc);
    EXPECT_EQ(e, a);
}

TEST(Coverage, component)
{
    const std::string n = "name";
    const std::string e =
        "<component name=\"name\">\n"
        "  <variable/>\n"
        "  <1+1=2>\n"
        "</component>\n";
    const std::string math = "<1+1=2>\n";

    libcellml::ComponentPtr c = std::make_shared<libcellml::Component>();
    libcellml::ComponentPtr cm;
    libcellml::VariablePtr v = std::make_shared<libcellml::Variable>();

    c->setName(n);
    c->addVariable(v);
    c->setMath(math);

    libcellml::Printer printer;
    std::string a = printer.printComponent(c);
    EXPECT_EQ(e, a);

    cm = std::move(c);
    a = printer.printComponent(cm);
    EXPECT_EQ(e, a);

    // Move constructor, assignment operator and swap method
    std::vector<libcellml::Component> vec;
    vec.emplace_back();

    libcellml::Component rc;
    libcellml::Component ao;

    rc.setName(n);

    ao = rc;

    EXPECT_EQ(n, ao.getName());
}

TEST(Coverage, error)
{
    libcellml::ErrorPtr err = std::make_shared<libcellml::Error>();
    libcellml::Error e;
    libcellml::Error em;
    const std::string description = "test";

    e.setDescription(description);
    e.setKind(libcellml::Error::Kind::XML);

    em = std::move(e);
    // Copy constructor
    libcellml::Error ec(em);

    EXPECT_EQ(description, ec.getDescription());
    EXPECT_EQ(libcellml::Error::Kind::XML, ec.getKind());
}

TEST(Coverage, model)
{
    // Move constructor, assignment operator and swap method
    std::vector<libcellml::Model> vec;
    vec.emplace_back();

    libcellml::Model rm;
    libcellml::Model ao;

    ao = rm;
}
<|endoftext|>


<commit_before>// Copyright (C) 2012 Rhys Ulerich
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#include "ar.hpp"

#include <algorithm>
#include <cstdlib>
#include <limits>
#include <iterator>
#include <vector>

#include <octave/oct.h>

/** @file
 * A GNU Octave wrapper estimating the best AR(p) model given signal input.
 * Compare \ref arsel.cpp.
 */

// Compile-time defaults in the code also appearing in the help message
#define DEFAULT_SUBMEAN  true
#define DEFAULT_MAXORDER 512
#define STRINGIFY(x) STRINGIFY_HELPER(x)
#define STRINGIFY_HELPER(x) #x

DEFUN_DLD(
    arsel, args, nargout,
    "\t[A, mu, sigma2eps, eff_sigma2x, Neff, T0] = arsel (d, submean, maxorder)\n"
    "\tAutomatically fit an autoregressive model to an input signal.\n"
    "\t\n"
    "\tUse ar::burg_method followed by ar::best_model<CIC<Burg<MeanHandling > >\n"
    "\tto obtain the most likely autoregressive process for input signal d.\n"
    "\tThe sample mean of d will be subtracted whenever submean is true.\n"
    "\tModel orders zero through min(size(d), maxorder) will be considered.\n"
    "\t\n"
    "\tThe filter()-ready process parameters are returned in A, the sample mean\n"
    "\tin mu, and the innovation variance \\sigma^2_\\epsilon in sigma2eps.\n"
    "\tGiven the observed autocorrelation structure, a decorrelation time T0 is\n"
    "\tcomputed and used to estimate the effective signal variance eff_sigma2x.\n"
    "\tThe number of effectively independent samples is returned in Neff.\n"
    "\t\n"
    "\tOne may simulate N samples from the fitted process by afterwards calling:\n"
    "\t\n"
    "\t\tx = mu + filter([1], A, sqrt(sigma2eps)*randn(N,1));\n"
    "\t\n"
    "\tWhen not supplied, submean defaults to " STRINGIFY(DEFAULT_SUBMEAN) ".\n"
    "\tWhen not supplied, maxorder defaults to " STRINGIFY(DEFAULT_MAXORDER) ".\n"
)
{
    std::size_t maxorder = DEFAULT_MAXORDER;
    bool        submean  = DEFAULT_SUBMEAN;
    RowVector   data;
    switch (args.length())  // Cases deliberately fall through
    {
        case 3:
            maxorder = args(2).ulong_value();
        case 2:
            submean = args(1).bool_value();
        case 1:
            data = args(0).row_vector_value();
            break;
        default:
            error("Invalid call to arsel.  Correct usage is: ");
        case 0:
            print_usage();
            return octave_value();
    }

    // How much data will we be processing?
    const size_t N = data.dims().numel();
    if (!N) {
        error("arsel: input signal d must have nonzero length");
        return octave_value();
    }

    // Use burg_method to estimate a hierarchy of AR models from input data
    double mu;
    std::vector<double> params, sigma2e, gain, autocor;
    params .reserve(maxorder*(maxorder + 1)/2);
    sigma2e.reserve(maxorder + 1);
    gain   .reserve(maxorder + 1);
    autocor.reserve(maxorder + 1);
    ar::burg_method(data.fortran_vec(), data.fortran_vec() + N,
                    mu, maxorder,
                    std::back_inserter(params),
                    std::back_inserter(sigma2e),
                    std::back_inserter(gain),
                    std::back_inserter(autocor),
                    submean, /* output hierarchy? */ true);

    // Keep only best model according to CIC accounting for subtract_mean.
    if (submean) {
        ar::best_model<ar::CIC<ar::Burg<ar::mean_subtracted> > >(
                N, params, sigma2e, gain, autocor);
    } else {
        ar::best_model<ar::CIC<ar::Burg<ar::mean_retained> > >(
                N, params, sigma2e, gain, autocor);
    }

    // Compute decorrelation time from the estimated autocorrelation model
    double T0 = std::numeric_limits<double>::quiet_NaN();
    if (nargout > 2) {
        ar::predictor<double> p = ar::autocorrelation(
                params.begin(), params.end(), gain[0], autocor.begin());
        T0 = ar::decorrelation_time(N, p, /* abs(rho) */ true);
    }

    // Prepare autoregressive process parameters for Octave's filter function
    RowVector A(params.size() + 1, /* leading one */ 1);
    std::copy(params.begin(), params.end(), A.fortran_vec() + 1);

    // Prepare output: [A, mu, sigma2eps, eff_sigma2x, T0]
    octave_value_list retval;
    switch (nargout)  // Cases deliberately fall through
    {
        default:
            warning("arsel: too many output values requested");
        case 6:
            retval.prepend(T0);
        case 5:
            retval.prepend(N / T0);
        case 4:
            retval.prepend((N*gain[0]*sigma2e[0]) / (N - T0));
        case 3:
            retval.prepend(sigma2e[0]);
        case 2:
            retval.prepend(mu);
        case 1:
            retval.prepend(A);
            break;
        case 0:
            warning("arsel: no output values requested");
    }

    // Return results iff no errors were detected
    return error_state ? octave_value_list() : retval;
}
<commit_msg>clean up docstring in Octfile<commit_after>// Copyright (C) 2012 Rhys Ulerich
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#include "ar.hpp"

#include <algorithm>
#include <cstdlib>
#include <limits>
#include <iterator>
#include <vector>

#include <octave/oct.h>

/** @file
 * A GNU Octave wrapper estimating the best AR(p) model given signal input.
 * Compare \ref arsel.cpp.
 */

// Compile-time defaults in the code also appearing in the help message
#define DEFAULT_SUBMEAN  true
#define DEFAULT_MAXORDER 512
#define STRINGIFY(x) STRINGIFY_HELPER(x)
#define STRINGIFY_HELPER(x) #x

DEFUN_DLD(
    arsel, args, nargout,
    "\t[A, mu, sigma2eps, eff_sigma2x, Neff, T0] = arsel (d, submean, maxorder)\n"
    "\tAutomatically fit an autoregressive model to an input signal.\n"
    "\t\n"
    "\tUse ar::burg_method followed by ar::best_model<CIC<Burg<MeanHandling > >\n"
    "\tto obtain the most likely autoregressive process for input signal d.\n"
    "\tThe sample mean of d will be subtracted whenever submean is true.\n"
    "\tModel orders zero through min(size(d), maxorder) will be considered.\n"
    "\t\n"
    "\tThe filter()-ready process parameters are returned in A, the sample mean\n"
    "\tin mu, and the innovation variance \\sigma^2_\\epsilon in sigma2eps.\n"
    "\tGiven the observed autocorrelation structure, a decorrelation time T0 is\n"
    "\tcomputed and used to estimate the effective signal variance eff_sigma2x.\n"
    "\tThe number of effectively independent samples is returned in Neff.\n"
    "\t\n"
    "\tOne may simulate N samples from the fitted process by calling:\n"
    "\t\n"
    "\t\tx = mu + filter([1], A, sqrt(sigma2eps)*randn(N,1));\n"
    "\t\n"
    "\tWhen not supplied, submean defaults to " STRINGIFY(DEFAULT_SUBMEAN) ".\n"
    "\tWhen not supplied, maxorder defaults to " STRINGIFY(DEFAULT_MAXORDER) ".\n"
)
{
    std::size_t maxorder = DEFAULT_MAXORDER;
    bool        submean  = DEFAULT_SUBMEAN;
    RowVector   data;
    switch (args.length())  // Cases deliberately fall through
    {
        case 3:
            maxorder = args(2).ulong_value();
        case 2:
            submean = args(1).bool_value();
        case 1:
            data = args(0).row_vector_value();
            break;
        default:
            error("Invalid call to arsel.  Correct usage is: ");
        case 0:
            print_usage();
            return octave_value();
    }

    // How much data will we be processing?
    const size_t N = data.dims().numel();
    if (!N) {
        error("arsel: input signal d must have nonzero length");
        return octave_value();
    }

    // Use burg_method to estimate a hierarchy of AR models from input data
    double mu;
    std::vector<double> params, sigma2e, gain, autocor;
    params .reserve(maxorder*(maxorder + 1)/2);
    sigma2e.reserve(maxorder + 1);
    gain   .reserve(maxorder + 1);
    autocor.reserve(maxorder + 1);
    ar::burg_method(data.fortran_vec(), data.fortran_vec() + N,
                    mu, maxorder,
                    std::back_inserter(params),
                    std::back_inserter(sigma2e),
                    std::back_inserter(gain),
                    std::back_inserter(autocor),
                    submean, /* output hierarchy? */ true);

    // Keep only best model according to CIC accounting for subtract_mean.
    if (submean) {
        ar::best_model<ar::CIC<ar::Burg<ar::mean_subtracted> > >(
                N, params, sigma2e, gain, autocor);
    } else {
        ar::best_model<ar::CIC<ar::Burg<ar::mean_retained> > >(
                N, params, sigma2e, gain, autocor);
    }

    // Compute decorrelation time from the estimated autocorrelation model
    double T0 = std::numeric_limits<double>::quiet_NaN();
    if (nargout > 2) {
        ar::predictor<double> p = ar::autocorrelation(
                params.begin(), params.end(), gain[0], autocor.begin());
        T0 = ar::decorrelation_time(N, p, /* abs(rho) */ true);
    }

    // Prepare autoregressive process parameters for Octave's filter function
    RowVector A(params.size() + 1, /* leading one */ 1);
    std::copy(params.begin(), params.end(), A.fortran_vec() + 1);

    // Prepare output: [A, mu, sigma2eps, eff_sigma2x, T0]
    octave_value_list retval;
    switch (nargout)  // Cases deliberately fall through
    {
        default:
            warning("arsel: too many output values requested");
        case 6:
            retval.prepend(T0);
        case 5:
            retval.prepend(N / T0);
        case 4:
            retval.prepend((N*gain[0]*sigma2e[0]) / (N - T0));
        case 3:
            retval.prepend(sigma2e[0]);
        case 2:
            retval.prepend(mu);
        case 1:
            retval.prepend(A);
            break;
        case 0:
            warning("arsel: no output values requested");
    }

    // Return results iff no errors were detected
    return error_state ? octave_value_list() : retval;
}
<|endoftext|>


<commit_before>#include "gtest/gtest.h"
#include "Rand.h"

TEST(RandTest, RandNotAlwaysZero)
{
	Rand r1;
	int bit_sum = 0;
	int iters = 1000;

	for(int i = 0; i < iters; i++)
	{
		bit_sum += r1.randbit();
	}
	EXPECT_LT(0, bit_sum);
}

TEST(RandTest, RandNotAlwaysOne)
{
	Rand r1;
	int bit_sum = 0;
	int iters = 1000;

	for(int i = 0; i < iters; i++)
	{
		bit_sum += r1.randbit();
	}
	EXPECT_GT(iters, bit_sum);
}

TEST(RandTest, HalfBitsAreOne)
{
	Rand r1;
	int iters = 10000;
	int bit_sum = 0;

	for(int i = 0; i < iters; i++)
	{
		bit_sum += r1.randbit();
	}

	//Give ourselves a range to allow +/- the exact mean
	int low = iters * 2 / 5;
	int high = iters * 3 / 5;

	EXPECT_LE(low, bit_sum);
	EXPECT_GE(high, bit_sum);
}

TEST(RandTest, SameSeedsAreEqual)
{
	Rand r1(0xACE01u);
	Rand r2(0xACE01u);

	int iters = 10000;
	int equal = 1;

	for(int i = 0; i < iters; i++)
	{
		equal &= r1.randbit() == r2.randbit();
	}

	EXPECT_EQ(1, equal);
}

TEST(RandTest, DifferentSeedsAreNotEqual)
{
	Rand r1(0xACE01u);
	Rand r2(0x10ECAu);

	int iters = 10000;
	int equal = 1;

	for(int i = 0; i < iters; i++)
	{
		equal &= r1.randbit() == r2.randbit();
	}

	EXPECT_NE(1, equal);
}

TEST(RandTest, GetNBits)
{
	Rand r1;

	int iters = 1000;

	for(int i = 0; i < iters; i++)
	{
		ASSERT_GE(0xFF, r1.randn(8));
	}
}

TEST(RandTest, RandNNotAlwaysZero)
{
	Rand r1;
	int bit_sum = 0;
	int iters = 1000;

	for(int i = 0; i < iters; i++)
	{
		bit_sum += r1.randn(8);
	}
	EXPECT_LT(0, bit_sum);
}

TEST(RandTest, RandNNotAlwaysMax)
{
	Rand r1;
	int bit_sum = 0;
	int iters = 1000;

	for(int i = 0; i < iters; i++)
	{
		bit_sum += r1.randn(8);
	}
	EXPECT_GT(iters * 0xFF, bit_sum);
}

TEST(RandTest, 8BitsEqual)
{
	Rand r1(0xACE01u);
	Rand r2(0xACE01u);

	int iters = 1000;

	for(int i = 0; i < iters; i++)
	{
		ASSERT_EQ(r1.rand8(), r2.randn(8));
	}
}

TEST(RandTest, 16BitsEqual)
{
	Rand r1(0xACE01u);
	Rand r2(0xACE01u);

	int iters = 1000;

	for(int i = 0; i < iters; i++)
	{
		ASSERT_EQ(r1.rand16(), r2.randn(16));
	}
}

TEST(RandTest, 32BitsEqual)
{
	Rand r1(0xACE01u);
	Rand r2(0xACE01u);

	int iters = 1000;

	for(int i = 0; i < iters; i++)
	{
		ASSERT_EQ(r1.rand32(), r2.randn(32));
	}
}

TEST(RandTest, RandIntIsInclusive)
{
	Rand r1;
	int foo[6] = {false};
	int iters = 1000;

	for(int i = 0; i < iters; i++)
	{
		foo[r1.randint(1,6)-1] = true;
	}

	for(int i = 0; i < 6; i++)
	{
		EXPECT_TRUE(foo[i]);
	}
}

int main(int argc, char **argv)
{
	::testing::InitGoogleTest(&argc, argv);
	return RUN_ALL_TESTS();
}
<commit_msg>New unit test for overloaded Rand::randint(max) method<commit_after>#include "gtest/gtest.h"
#include "Rand.h"

TEST(RandTest, RandNotAlwaysZero)
{
	Rand r1;
	int bit_sum = 0;
	int iters = 1000;

	for(int i = 0; i < iters; i++)
	{
		bit_sum += r1.randbit();
	}
	EXPECT_LT(0, bit_sum);
}

TEST(RandTest, RandNotAlwaysOne)
{
	Rand r1;
	int bit_sum = 0;
	int iters = 1000;

	for(int i = 0; i < iters; i++)
	{
		bit_sum += r1.randbit();
	}
	EXPECT_GT(iters, bit_sum);
}

TEST(RandTest, HalfBitsAreOne)
{
	Rand r1;
	int iters = 10000;
	int bit_sum = 0;

	for(int i = 0; i < iters; i++)
	{
		bit_sum += r1.randbit();
	}

	//Give ourselves a range to allow +/- the exact mean
	int low = iters * 2 / 5;
	int high = iters * 3 / 5;

	EXPECT_LE(low, bit_sum);
	EXPECT_GE(high, bit_sum);
}

TEST(RandTest, SameSeedsAreEqual)
{
	Rand r1(0xACE01u);
	Rand r2(0xACE01u);

	int iters = 10000;
	int equal = 1;

	for(int i = 0; i < iters; i++)
	{
		equal &= r1.randbit() == r2.randbit();
	}

	EXPECT_EQ(1, equal);
}

TEST(RandTest, DifferentSeedsAreNotEqual)
{
	Rand r1(0xACE01u);
	Rand r2(0x10ECAu);

	int iters = 10000;
	int equal = 1;

	for(int i = 0; i < iters; i++)
	{
		equal &= r1.randbit() == r2.randbit();
	}

	EXPECT_NE(1, equal);
}

TEST(RandTest, GetNBits)
{
	Rand r1;

	int iters = 1000;

	for(int i = 0; i < iters; i++)
	{
		ASSERT_GE(0xFF, r1.randn(8));
	}
}

TEST(RandTest, RandNNotAlwaysZero)
{
	Rand r1;
	int bit_sum = 0;
	int iters = 1000;

	for(int i = 0; i < iters; i++)
	{
		bit_sum += r1.randn(8);
	}
	EXPECT_LT(0, bit_sum);
}

TEST(RandTest, RandNNotAlwaysMax)
{
	Rand r1;
	int bit_sum = 0;
	int iters = 1000;

	for(int i = 0; i < iters; i++)
	{
		bit_sum += r1.randn(8);
	}
	EXPECT_GT(iters * 0xFF, bit_sum);
}

TEST(RandTest, 8BitsEqual)
{
	Rand r1(0xACE01u);
	Rand r2(0xACE01u);

	int iters = 1000;

	for(int i = 0; i < iters; i++)
	{
		ASSERT_EQ(r1.rand8(), r2.randn(8));
	}
}

TEST(RandTest, 16BitsEqual)
{
	Rand r1(0xACE01u);
	Rand r2(0xACE01u);

	int iters = 1000;

	for(int i = 0; i < iters; i++)
	{
		ASSERT_EQ(r1.rand16(), r2.randn(16));
	}
}

TEST(RandTest, 32BitsEqual)
{
	Rand r1(0xACE01u);
	Rand r2(0xACE01u);

	int iters = 1000;

	for(int i = 0; i < iters; i++)
	{
		ASSERT_EQ(r1.rand32(), r2.randn(32));
	}
}

TEST(RandTest, RandIntIsInclusive)
{
	Rand r1;
	int foo[6] = {false};
	int iters = 1000;

	for(int i = 0; i < iters; i++)
	{
		foo[r1.randint(1,6)-1] = true;
	}

	for(int i = 0; i < 6; i++)
	{
		EXPECT_TRUE(foo[i]);
	}
}

TEST(RandTest, OverloadedRandIntReturnsZeroToMax)
{
	Rand r1;
	int foo[6] = {false};
	int iters = 1000;

	for(int i = 0; i < iters; i++)
	{
		foo[r1.randint(5)] = true;
	}

	for(int i = 0; i < 6; i++)
	{
		EXPECT_TRUE(foo[i]);
	}
}

int main(int argc, char **argv)
{
	::testing::InitGoogleTest(&argc, argv);
	return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * YEXTEND: Help for YARA users.
 * This file is part of yextend.
 *
 * Copyright (c) 2014-2017, Bayshore Networks, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 * the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
 * following disclaimer.
 *
 * 2. 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.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
 * products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>

#include "bzl.h"

#include <iostream>
using namespace std;

BZlibInflator_t::BZlibInflator_t(){

    bzStreamEnd = false;
    total = 0;

    bz.bzalloc =NULL;
    bz.bzfree = NULL;
    bz.opaque = NULL;

    int u = BZ2_bzDecompressInit(&bz, 0, 0);

    bzError = (u != BZ_OK);

    bzsingle_result.size = 2048;
    bzsingle_result.used = 0;
    bzsingle_result.data = (uint8_t*) malloc (bzsingle_result.size);
    bzsingle_result.data[0] = 0;

}

BZlibInflator_t::~BZlibInflator_t(){

    BZ2_bzDecompressEnd(&bz);

    if(bzsingle_result.data)
        free(bzsingle_result.data);

}

void BZlibInflator_t::bzdecomp(uint8_t* buf, size_t sz){

    if(bzError || bzStreamEnd || !buf || !sz){
        return;
    }

    if((bzsingle_result.size - bzsingle_result.used) < (sz*2)){

        bzsingle_result.size += (sz * 2);
		bzsingle_result.data = (uint8_t*) realloc (bzsingle_result.data, bzsingle_result.size);

		if (!bzsingle_result.data) {
			bzError = true;
			return;
		}
	}

    bz.next_in = (char*)buf;
	bz.avail_in = sz;
	bz.next_out = (char*)(bzsingle_result.data + bzsingle_result.used);
	bz.avail_out = bzsingle_result.size - bzsingle_result.used - 1;

	if (!bz.avail_out) {
		bzError = true;
		return;
	}

	size_t outsize = bz.avail_out;

    int r = BZ2_bzDecompress(&bz);

    if (r == BZ_OK) {
		bzsingle_result.used += (outsize - bz.avail_out);
		assert (bzsingle_result.used < bzsingle_result.size);
		bzsingle_result.data [bzsingle_result.used] = 0;
		total = bzsingle_result.used;

		if (bz.avail_in || !bz.avail_out) {

            bzdecomp(buf + sz - bz.avail_in, bz.avail_in);
		}
	}
    else if(r == BZ_STREAM_END){

        bzsingle_result.used += (outsize - bz.avail_out);
		assert (bzsingle_result.used < bzsingle_result.size);
		bzsingle_result.data [bzsingle_result.used] = 0;
		total = bzsingle_result.used;
		bzStreamEnd = true;
    }
    else {
		bzError = true;
	}

}

<commit_msg>function headers<commit_after>/*****************************************************************************
 *
 * YEXTEND: Help for YARA users.
 * This file is part of yextend.
 *
 * Copyright (c) 2014-2017, Bayshore Networks, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 * the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
 * following disclaimer.
 *
 * 2. 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.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
 * products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>

#include "bzl.h"

#include <iostream>
using namespace std;

/******************************
BZlibInflator_t::BZlibInflator_t
******************************/

BZlibInflator_t::BZlibInflator_t(){

    bzStreamEnd = false;
    total = 0;

    bz.bzalloc =NULL;
    bz.bzfree = NULL;
    bz.opaque = NULL;

    int u = BZ2_bzDecompressInit(&bz, 0, 0);

    bzError = (u != BZ_OK);

    bzsingle_result.size = 2048;
    bzsingle_result.used = 0;
    bzsingle_result.data = (uint8_t*) malloc (bzsingle_result.size);
    bzsingle_result.data[0] = 0;

}

/*******************************
BZlibInflator_t::~BZlibInflator_t
*******************************/

BZlibInflator_t::~BZlibInflator_t(){

    BZ2_bzDecompressEnd(&bz);

    if(bzsingle_result.data)
        free(bzsingle_result.data);

}

/**********************
BZlibInflator_t::bzdecomp
**********************/

void BZlibInflator_t::bzdecomp(uint8_t* buf, size_t sz){

    if(bzError || bzStreamEnd || !buf || !sz){
        return;
    }

    if((bzsingle_result.size - bzsingle_result.used) < (sz*2)){

        bzsingle_result.size += (sz * 2);
		bzsingle_result.data = (uint8_t*) realloc (bzsingle_result.data, bzsingle_result.size);

		if (!bzsingle_result.data) {
			bzError = true;
			return;
		}
	}

    bz.next_in = (char*)buf;
	bz.avail_in = sz;
	bz.next_out = (char*)(bzsingle_result.data + bzsingle_result.used);
	bz.avail_out = bzsingle_result.size - bzsingle_result.used - 1;

	if (!bz.avail_out) {
		bzError = true;
		return;
	}

	size_t outsize = bz.avail_out;

    int r = BZ2_bzDecompress(&bz);

    if (r == BZ_OK) {
		bzsingle_result.used += (outsize - bz.avail_out);
		assert (bzsingle_result.used < bzsingle_result.size);
		bzsingle_result.data [bzsingle_result.used] = 0;
		total = bzsingle_result.used;

		if (bz.avail_in || !bz.avail_out) {

            bzdecomp(buf + sz - bz.avail_in, bz.avail_in);
		}
	}
    else if(r == BZ_STREAM_END){

        bzsingle_result.used += (outsize - bz.avail_out);
		assert (bzsingle_result.used < bzsingle_result.size);
		bzsingle_result.data [bzsingle_result.used] = 0;
		total = bzsingle_result.used;
		bzStreamEnd = true;
    }
    else {
		bzError = true;
	}

}

<|endoftext|>


<commit_before>/// Implementation of the Number-Theoretical Transform in GF(P) Galois field
#include <iostream>
#include <algorithm>
#include <stdint.h>

typedef uint32_t ElementT;        // data items type, 32-bit unsigned integer for GF(P) computations with P>65536
typedef uint64_t DoubleElementT;  // twice wider type to hold intermediate results

// Reverse-binary reindexing
template <typename T>
void scramble (T* data, size_t nn)
{
    size_t n, mmax, m, j, istep, i;

    n = nn<<1;
    j=1;
    for (i=1; i<n; i+=2) {
        if (j>i) {
            std::swap(data[j-1], data[i-1]);
            std::swap(data[j], data[i]);
        }
        m = nn;
        while (m>=2 && j>m) {
            j -= m;
            m >>= 1;
        }
        j += m;
    };
}

template <ElementT P>
ElementT GF_Add (ElementT X, ElementT Y)
{
    ElementT res = X + Y;
    return (res>=P || res<X)? res-P : res;
}

template <ElementT P>
ElementT GF_Sub (ElementT X, ElementT Y)
{
    ElementT res = X - Y;
    return res<=X? res : res+P;
}

template <ElementT P>
ElementT GF_Mul (ElementT X, ElementT Y)
{
    return ElementT( (DoubleElementT(X)*Y) % P);
}

template <size_t N, typename T, T P>
class DanielsonLanczos {
   DanielsonLanczos<N/2,T,P> next;
public:
   void apply(T* data, T root) {
      T root_sqr = GF_Mul<P> (root, root);  // first root of power N of 1
      if (N>8192) {
          #pragma omp task
          next.apply (data,   root_sqr);
          #pragma omp task
          next.apply (data+N, root_sqr);
          #pragma omp taskwait
      } else {
          next.apply (data,   root_sqr);
          next.apply (data+N, root_sqr);
      }

      T root_i = root;   // first root of power 2N of 1
      for (size_t i=0; i<N; i++) {
        T temp    = GF_Mul<P> (root_i, data[i+N]);
        data[i+N] = GF_Sub<P> (data[i], temp);
        data[i]   = GF_Add<P> (data[i], temp);
        root_i    = GF_Mul<P> (root_i, root);  // next root of power 2N of 1
      }
   }
};

template<typename T, T P>
class DanielsonLanczos<0,T,P> {
public:
   void apply(T* data, T root) { }
};

template <size_t Exp, typename T, T P>
class NTT {
   enum { N = 1<<Exp };
   DanielsonLanczos<N,T,P> recursion;
public:
   void ntt(T* data) {
      T root = 1557;                      // init 'root' with root of 1 of power 2**20 in GF(0xFFF00001)
      for (int i=20; --i>Exp; )
          root = GF_Mul<P> (root, root);  // find root of 1 of power 2N
      scramble(data,N);
      recursion.apply(data,root);
   }
};

// Find first root of 1 of power 2**N
template <typename T, T P>
void FindRoot (int N)
{
    for (T i=2; i<P; i++)
    {
        T q = i;
        for (int j=0; j<N; j++)
        {
            if (q==1)  goto next;
            q = GF_Mul<P> (q,q);
        }
        if (q==1)
        {
            std::cout << i << "\n";
            break;
        }
next:;
    }
}

int main()
{
    const ElementT P = 0xFFF00001;
    // FindRoot<ElementT,P>(20);  // prints 1557

    ElementT *data = new ElementT[1<<20];
    for (int i=0; i<(1<<20); i++)
        data[i] = i;
    NTT<19,ElementT,P> transformer;
    #pragma omp parallel num_threads(16)
    #pragma omp single
    for (int i=0; i<100; i++)
        transformer.ntt(data);
    return 0;
}
<commit_msg>NTT: Alternative GF_Mul implementation for 32-bit CPUs, SIMD and GPUs<commit_after>/// Implementation of the Number-Theoretical Transform in GF(P) Galois field
#include <iostream>
#include <algorithm>
#include <stdint.h>

#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__)
#define MY_CPU_AMD64
#endif

#if defined(MY_CPU_AMD64) || defined(_M_IA64)
#define MY_CPU_64BIT
#endif

typedef uint32_t ElementT;        // data items type, 32-bit unsigned integer for GF(P) computations with P>65536
typedef uint64_t DoubleElementT;  // twice wider type to hold intermediate results

// Reverse-binary reindexing
template <typename T>
void scramble (T* data, size_t nn)
{
    size_t n, mmax, m, j, istep, i;

    n = nn<<1;
    j=1;
    for (i=1; i<n; i+=2) {
        if (j>i) {
            std::swap(data[j-1], data[i-1]);
            std::swap(data[j], data[i]);
        }
        m = nn;
        while (m>=2 && j>m) {
            j -= m;
            m >>= 1;
        }
        j += m;
    };
}

template <ElementT P>
ElementT GF_Add (ElementT X, ElementT Y)
{
    ElementT res = X + Y;
    return (res>=P || res<X)? res-P : res;
}

template <ElementT P>
ElementT GF_Sub (ElementT X, ElementT Y)
{
    ElementT res = X - Y;
    return res<=X? res : res+P;
}

template <ElementT P>
ElementT GF_Mul1 (ElementT X, ElementT Y)
{
    return ElementT( (DoubleElementT(X)*Y) % P);
}

template <ElementT P>
ElementT GF_Mul2 (ElementT X, ElementT Y)
{
    const ElementT invP32 = ElementT(((DoubleElementT(1)<<63) / P) << 1) + 1;
//    const ElementT invP32 = DoubleElementT(invP32a)*P > DoubleElementT(invP32a+1)*P? invP32a : invP32a+1;
    DoubleElementT res = DoubleElementT(X)*Y;
    ElementT res32 = ElementT(res >> 32);
    res -= (res32 + ((DoubleElementT(res32)*invP32) >> 32)) * P;
/*
static ElementT maxdiv = 0;
ElementT div = res/P;
if (maxdiv < div)
{
  maxdiv = div;
  std::cout << std::hex << X << " * " << Y << " = " << res << " ("  << div << "), " << invP32 << "\n";
}
*/
    return ElementT(res>=2*DoubleElementT(P)? res-2*P : (res>=P? res-P : res));
}

// GF_Mul1 is optimized for 64-bit CPUs
#ifdef MY_CPU_64BIT
#define GF_Mul GF_Mul1
#else
#define GF_Mul GF_Mul2
#endif

template <size_t N, typename T, T P>
class DanielsonLanczos {
   DanielsonLanczos<N/2,T,P> next;
public:
   void apply(T* data, T root) {
      T root_sqr = GF_Mul<P> (root, root);  // first root of power N of 1
      if (N>8192) {
          #pragma omp task
          next.apply (data,   root_sqr);
          #pragma omp task
          next.apply (data+N, root_sqr);
          #pragma omp taskwait
      } else {
          next.apply (data,   root_sqr);
          next.apply (data+N, root_sqr);
      }

      T root_i = root;   // first root of power 2N of 1
      for (size_t i=0; i<N; i++) {
        T temp    = GF_Mul<P> (root_i, data[i+N]);
        data[i+N] = GF_Sub<P> (data[i], temp);
        data[i]   = GF_Add<P> (data[i], temp);
        root_i    = GF_Mul<P> (root_i, root);  // next root of power 2N of 1
      }
   }
};

template<typename T, T P>
class DanielsonLanczos<0,T,P> {
public:
   void apply(T* data, T root) { }
};

template <size_t Exp, typename T, T P>
class NTT {
   enum { N = 1<<Exp };
   DanielsonLanczos<N,T,P> recursion;
public:
   void ntt(T* data) {
      T root = 1557;                      // init 'root' with root of 1 of power 2**20 in GF(0xFFF00001)
      for (int i=20; --i>Exp; )
          root = GF_Mul<P> (root, root);  // find root of 1 of power 2N
      scramble(data,N);
      recursion.apply(data,root);
   }
};

// Find first root of 1 of power 2**N
template <typename T, T P>
void FindRoot (int N)
{
    for (T i=2; i<P; i++)
    {
        T q = i;
        for (int j=0; j<N; j++)
        {
            if (q==1)  goto next;
            q = GF_Mul<P> (q,q);
        }
        if (q==1)
        {
            std::cout << i << "\n";
            break;
        }
next:;
    }
}

// Test the GF_Mul2 correctness
template <ElementT P>
void Test_GF_Mul2()
{
    int n = 0;
    for (ElementT i=P; --i; )
    {
        std::cout << std::hex << "\r" << i << "...";
        for (ElementT j=i; --j; )
            if (GF_Mul1<P> (i,j)  !=  GF_Mul2<P> (i,j))
            {
                std::cout << std::hex << "\r" << i << "*" << j << "=" << GF_Mul1<P> (i,j) << " != " << GF_Mul2<P> (i,j) << "\n" ;
                if (++n>10) return;
            }
    }
}

int main()
{
    const ElementT P = 0xFFF00001;
    // Test_GF_Mul2<P>();
    // FindRoot<ElementT,P>(20);  // prints 1557

    ElementT *data = new ElementT[1<<20];
    for (int i=0; i<(1<<20); i++)
        data[i] = i;
    NTT<19,ElementT,P> transformer;
    #pragma omp parallel num_threads(16)
    #pragma omp single
    for (int i=0; i<100; i++)
        transformer.ntt(data);
    return 0;
}
<|endoftext|>