<commit_before>//===- LazyRandomTypeCollection.cpp ---------------------------- *- C++--*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"

#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
#include "llvm/DebugInfo/CodeView/TypeName.h"
#include "llvm/DebugInfo/CodeView/TypeServerHandler.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"

using namespace llvm;
using namespace llvm::codeview;

static void error(Error &&EC) {
  assert(!static_cast<bool>(EC));
  if (EC)
    consumeError(std::move(EC));
}

LazyRandomTypeCollection::LazyRandomTypeCollection(uint32_t RecordCountHint)
    : LazyRandomTypeCollection(CVTypeArray(), RecordCountHint,
                               PartialOffsetArray()) {}

LazyRandomTypeCollection::LazyRandomTypeCollection(
    const CVTypeArray &Types, uint32_t RecordCountHint,
    PartialOffsetArray PartialOffsets)
    : NameStorage(Allocator), Database(RecordCountHint), Types(Types),
      DatabaseVisitor(Database), PartialOffsets(PartialOffsets) {
  KnownOffsets.resize(Database.capacity());
}

LazyRandomTypeCollection::LazyRandomTypeCollection(ArrayRef<uint8_t> Data,
                                                   uint32_t RecordCountHint)
    : LazyRandomTypeCollection(RecordCountHint) {
  reset(Data);
}

LazyRandomTypeCollection::LazyRandomTypeCollection(StringRef Data,
                                                   uint32_t RecordCountHint)
    : LazyRandomTypeCollection(
          makeArrayRef(Data.bytes_begin(), Data.bytes_end()), RecordCountHint) {
}

LazyRandomTypeCollection::LazyRandomTypeCollection(const CVTypeArray &Types,
                                                   uint32_t NumRecords)
    : LazyRandomTypeCollection(Types, NumRecords, PartialOffsetArray()) {}

void LazyRandomTypeCollection::reset(StringRef Data) {
  reset(makeArrayRef(Data.bytes_begin(), Data.bytes_end()));
}

void LazyRandomTypeCollection::reset(ArrayRef<uint8_t> Data) {
  PartialOffsets = PartialOffsetArray();

  BinaryStreamReader Reader(Data, support::little);
  error(Reader.readArray(Types, Reader.getLength()));

  KnownOffsets.resize(Database.capacity());
}

CVType LazyRandomTypeCollection::getType(TypeIndex Index) {
  error(ensureTypeExists(Index));
  return Database.getTypeRecord(Index);
}

StringRef LazyRandomTypeCollection::getTypeName(TypeIndex Index) {
  if (Index.isNoneType() || Index.isSimple())
    return TypeIndex::simpleTypeName(Index);

  uint32_t I = Index.toArrayIndex();
  if (I >= TypeNames.size())
    TypeNames.resize(I + 1);

  if (TypeNames[I].data() == nullptr) {
    StringRef Result = NameStorage.save(computeTypeName(*this, Index));
    TypeNames[I] = Result;
  }
  return TypeNames[I];
}

bool LazyRandomTypeCollection::contains(TypeIndex Index) {
  return Database.contains(Index);
}

uint32_t LazyRandomTypeCollection::size() { return Database.size(); }

uint32_t LazyRandomTypeCollection::capacity() { return Database.capacity(); }

Error LazyRandomTypeCollection::ensureTypeExists(TypeIndex TI) {
  if (!Database.contains(TI)) {
    if (auto EC = visitRangeForType(TI))
      return EC;
  }
  return Error::success();
}

Error LazyRandomTypeCollection::visitRangeForType(TypeIndex TI) {
  if (PartialOffsets.empty())
    return fullScanForType(TI);

  auto Next = std::upper_bound(PartialOffsets.begin(), PartialOffsets.end(), TI,
                               [](TypeIndex Value, const TypeIndexOffset &IO) {
                                 return Value < IO.Type;
                               });

  assert(Next != PartialOffsets.begin());
  auto Prev = std::prev(Next);

  TypeIndex TIB = Prev->Type;
  if (Database.contains(TIB)) {
    // They've asked us to fetch a type index, but the entry we found in the
    // partial offsets array has already been visited.  Since we visit an entire
    // block every time, that means this record should have been previously
    // discovered.  Ultimately, this means this is a request for a non-existant
    // type index.
    return make_error<CodeViewError>("Invalid type index");
  }

  TypeIndex TIE;
  if (Next == PartialOffsets.end()) {
    TIE = TypeIndex::fromArrayIndex(Database.capacity());
  } else {
    TIE = Next->Type;
  }

  if (auto EC = visitRange(TIB, Prev->Offset, TIE))
    return EC;
  return Error::success();
}

Optional<TypeIndex> LazyRandomTypeCollection::getFirst() {
  TypeIndex TI = TypeIndex::fromArrayIndex(0);
  if (auto EC = ensureTypeExists(TI)) {
    consumeError(std::move(EC));
    return None;
  }
  return TI;
}

Optional<TypeIndex> LazyRandomTypeCollection::getNext(TypeIndex Prev) {
  // We can't be sure how long this type stream is, given that the initial count
  // given to the constructor is just a hint.  So just try to make sure the next
  // record exists, and if anything goes wrong, we must be at the end.
  if (auto EC = ensureTypeExists(Prev + 1)) {
    consumeError(std::move(EC));
    return None;
  }

  return Prev + 1;
}

Error LazyRandomTypeCollection::fullScanForType(TypeIndex TI) {
  assert(PartialOffsets.empty());

  TypeIndex CurrentTI = TypeIndex::fromArrayIndex(0);
  uint32_t Offset = 0;
  auto Begin = Types.begin();

  if (!Database.empty()) {
    // In the case of type streams which we don't know the number of records of,
    // it's possible to search for a type index triggering a full scan, but then
    // later additional records are added since we didn't know how many there
    // would be until we did a full visitation, then you try to access the new
    // type triggering another full scan.  To avoid this, we assume that if the
    // database has some records, this must be what's going on.  So we ask the
    // database for the largest type index less than the one we're searching for
    // and only do the forward scan from there.
    auto Prev = Database.largestTypeIndexLessThan(TI);
    assert(Prev.hasValue() && "Empty database with valid types?");
    Offset = KnownOffsets[Prev->toArrayIndex()];
    CurrentTI = *Prev;
    ++CurrentTI;
    Begin = Types.at(Offset);
    ++Begin;
    Offset = Begin.offset();
  }

  auto End = Types.end();
  while (Begin != End) {
    if (auto EC = visitOneRecord(CurrentTI, Offset, *Begin))
      return EC;

    Offset += Begin.getRecordLength();
    ++Begin;
    ++CurrentTI;
  }
  if (CurrentTI <= TI) {
    return make_error<CodeViewError>("Type Index does not exist!");
  }
  return Error::success();
}

Error LazyRandomTypeCollection::visitRange(TypeIndex Begin,
                                           uint32_t BeginOffset,
                                           TypeIndex End) {

  auto RI = Types.at(BeginOffset);
  assert(RI != Types.end());

  while (Begin != End) {
    if (auto EC = visitOneRecord(Begin, BeginOffset, *RI))
      return EC;

    BeginOffset += RI.getRecordLength();
    ++Begin;
    ++RI;
  }

  return Error::success();
}

Error LazyRandomTypeCollection::visitOneRecord(TypeIndex TI, uint32_t Offset,
                                               CVType &Record) {
  assert(!Database.contains(TI));
  if (auto EC = codeview::visitTypeRecord(Record, TI, DatabaseVisitor))
    return EC;
  // Keep the KnownOffsets array the same size as the Database's capacity. Since
  // we don't always know how many records are in the type stream, we need to be
  // prepared for the database growing and receicing a type index that can't fit
  // in our current buffer.
  if (KnownOffsets.size() < Database.capacity())
    KnownOffsets.resize(Database.capacity());
  KnownOffsets[TI.toArrayIndex()] = Offset;
  return Error::success();
}
<commit_msg>Don't crash if a type record can't be found.<commit_after>//===- LazyRandomTypeCollection.cpp ---------------------------- *- C++--*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"

#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
#include "llvm/DebugInfo/CodeView/TypeName.h"
#include "llvm/DebugInfo/CodeView/TypeServerHandler.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"

using namespace llvm;
using namespace llvm::codeview;

static void error(Error &&EC) {
  assert(!static_cast<bool>(EC));
  if (EC)
    consumeError(std::move(EC));
}

LazyRandomTypeCollection::LazyRandomTypeCollection(uint32_t RecordCountHint)
    : LazyRandomTypeCollection(CVTypeArray(), RecordCountHint,
                               PartialOffsetArray()) {}

LazyRandomTypeCollection::LazyRandomTypeCollection(
    const CVTypeArray &Types, uint32_t RecordCountHint,
    PartialOffsetArray PartialOffsets)
    : NameStorage(Allocator), Database(RecordCountHint), Types(Types),
      DatabaseVisitor(Database), PartialOffsets(PartialOffsets) {
  KnownOffsets.resize(Database.capacity());
}

LazyRandomTypeCollection::LazyRandomTypeCollection(ArrayRef<uint8_t> Data,
                                                   uint32_t RecordCountHint)
    : LazyRandomTypeCollection(RecordCountHint) {
  reset(Data);
}

LazyRandomTypeCollection::LazyRandomTypeCollection(StringRef Data,
                                                   uint32_t RecordCountHint)
    : LazyRandomTypeCollection(
          makeArrayRef(Data.bytes_begin(), Data.bytes_end()), RecordCountHint) {
}

LazyRandomTypeCollection::LazyRandomTypeCollection(const CVTypeArray &Types,
                                                   uint32_t NumRecords)
    : LazyRandomTypeCollection(Types, NumRecords, PartialOffsetArray()) {}

void LazyRandomTypeCollection::reset(StringRef Data) {
  reset(makeArrayRef(Data.bytes_begin(), Data.bytes_end()));
}

void LazyRandomTypeCollection::reset(ArrayRef<uint8_t> Data) {
  PartialOffsets = PartialOffsetArray();

  BinaryStreamReader Reader(Data, support::little);
  error(Reader.readArray(Types, Reader.getLength()));

  KnownOffsets.resize(Database.capacity());
}

CVType LazyRandomTypeCollection::getType(TypeIndex Index) {
  error(ensureTypeExists(Index));
  return Database.getTypeRecord(Index);
}

StringRef LazyRandomTypeCollection::getTypeName(TypeIndex Index) {
  if (Index.isNoneType() || Index.isSimple())
    return TypeIndex::simpleTypeName(Index);

  // Try to make sure the type exists.  Even if it doesn't though, it may be
  // because we're dumping a symbol stream with no corresponding type stream
  // present, in which case we still want to be able to print <unknown UDT>
  // for the type names.
  if (auto EC = ensureTypeExists(Index)) {
    consumeError(std::move(EC));
    return "<unknown UDT>";
  }

  uint32_t I = Index.toArrayIndex();
  if (I >= TypeNames.size())
    TypeNames.resize(I + 1);

  if (TypeNames[I].data() == nullptr) {
    StringRef Result = NameStorage.save(computeTypeName(*this, Index));
    TypeNames[I] = Result;
  }
  return TypeNames[I];
}

bool LazyRandomTypeCollection::contains(TypeIndex Index) {
  return Database.contains(Index);
}

uint32_t LazyRandomTypeCollection::size() { return Database.size(); }

uint32_t LazyRandomTypeCollection::capacity() { return Database.capacity(); }

Error LazyRandomTypeCollection::ensureTypeExists(TypeIndex TI) {
  if (!Database.contains(TI)) {
    if (auto EC = visitRangeForType(TI))
      return EC;
  }
  return Error::success();
}

Error LazyRandomTypeCollection::visitRangeForType(TypeIndex TI) {
  if (PartialOffsets.empty())
    return fullScanForType(TI);

  auto Next = std::upper_bound(PartialOffsets.begin(), PartialOffsets.end(), TI,
                               [](TypeIndex Value, const TypeIndexOffset &IO) {
                                 return Value < IO.Type;
                               });

  assert(Next != PartialOffsets.begin());
  auto Prev = std::prev(Next);

  TypeIndex TIB = Prev->Type;
  if (Database.contains(TIB)) {
    // They've asked us to fetch a type index, but the entry we found in the
    // partial offsets array has already been visited.  Since we visit an entire
    // block every time, that means this record should have been previously
    // discovered.  Ultimately, this means this is a request for a non-existant
    // type index.
    return make_error<CodeViewError>("Invalid type index");
  }

  TypeIndex TIE;
  if (Next == PartialOffsets.end()) {
    TIE = TypeIndex::fromArrayIndex(Database.capacity());
  } else {
    TIE = Next->Type;
  }

  if (auto EC = visitRange(TIB, Prev->Offset, TIE))
    return EC;
  return Error::success();
}

Optional<TypeIndex> LazyRandomTypeCollection::getFirst() {
  TypeIndex TI = TypeIndex::fromArrayIndex(0);
  if (auto EC = ensureTypeExists(TI)) {
    consumeError(std::move(EC));
    return None;
  }
  return TI;
}

Optional<TypeIndex> LazyRandomTypeCollection::getNext(TypeIndex Prev) {
  // We can't be sure how long this type stream is, given that the initial count
  // given to the constructor is just a hint.  So just try to make sure the next
  // record exists, and if anything goes wrong, we must be at the end.
  if (auto EC = ensureTypeExists(Prev + 1)) {
    consumeError(std::move(EC));
    return None;
  }

  return Prev + 1;
}

Error LazyRandomTypeCollection::fullScanForType(TypeIndex TI) {
  assert(PartialOffsets.empty());

  TypeIndex CurrentTI = TypeIndex::fromArrayIndex(0);
  uint32_t Offset = 0;
  auto Begin = Types.begin();

  if (!Database.empty()) {
    // In the case of type streams which we don't know the number of records of,
    // it's possible to search for a type index triggering a full scan, but then
    // later additional records are added since we didn't know how many there
    // would be until we did a full visitation, then you try to access the new
    // type triggering another full scan.  To avoid this, we assume that if the
    // database has some records, this must be what's going on.  So we ask the
    // database for the largest type index less than the one we're searching for
    // and only do the forward scan from there.
    auto Prev = Database.largestTypeIndexLessThan(TI);
    assert(Prev.hasValue() && "Empty database with valid types?");
    Offset = KnownOffsets[Prev->toArrayIndex()];
    CurrentTI = *Prev;
    ++CurrentTI;
    Begin = Types.at(Offset);
    ++Begin;
    Offset = Begin.offset();
  }

  auto End = Types.end();
  while (Begin != End) {
    if (auto EC = visitOneRecord(CurrentTI, Offset, *Begin))
      return EC;

    Offset += Begin.getRecordLength();
    ++Begin;
    ++CurrentTI;
  }
  if (CurrentTI <= TI) {
    return make_error<CodeViewError>("Type Index does not exist!");
  }
  return Error::success();
}

Error LazyRandomTypeCollection::visitRange(TypeIndex Begin,
                                           uint32_t BeginOffset,
                                           TypeIndex End) {

  auto RI = Types.at(BeginOffset);
  assert(RI != Types.end());

  while (Begin != End) {
    if (auto EC = visitOneRecord(Begin, BeginOffset, *RI))
      return EC;

    BeginOffset += RI.getRecordLength();
    ++Begin;
    ++RI;
  }

  return Error::success();
}

Error LazyRandomTypeCollection::visitOneRecord(TypeIndex TI, uint32_t Offset,
                                               CVType &Record) {
  assert(!Database.contains(TI));
  if (auto EC = codeview::visitTypeRecord(Record, TI, DatabaseVisitor))
    return EC;
  // Keep the KnownOffsets array the same size as the Database's capacity. Since
  // we don't always know how many records are in the type stream, we need to be
  // prepared for the database growing and receicing a type index that can't fit
  // in our current buffer.
  if (KnownOffsets.size() < Database.capacity())
    KnownOffsets.resize(Database.capacity());
  KnownOffsets[TI.toArrayIndex()] = Offset;
  return Error::success();
}
<|endoftext|>


<commit_before>// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.

#include "parametersController.hpp"

#include <iostream>

template <typename T>
static bool readFromNode(cv::FileNode node, T& value)
{
    if(!node.isNone()) {
        node >> value;
        return true;
    }
    else
        return false;
}

static bool checkAssertion(bool value, const std::string& msg)
{
    if(!value)
        std::cerr << "Error: " << msg << std::endl;

    return value;
}

bool calib::parametersController::loadFromFile(const std::string &inputFileName)
{
    cv::FileStorage reader;
    reader.open(inputFileName, cv::FileStorage::READ);

    if(!reader.isOpened()) {
        std::cerr << "Warning: Unable to open " << inputFileName <<
                     " Application started with default advanced parameters" << std::endl;
        return true;
    }

    readFromNode(reader["charuco_dict"], mCapParams.charucoDictName);
    if (readFromNode(reader["charuco_square_lenght"], mCapParams.charucoSquareLength)) {
        std::cout << "DEPRECATION: Parameter 'charuco_square_lenght' has been deprecated (typo). Use 'charuco_square_length' instead." << std::endl;
    }
    readFromNode(reader["charuco_square_length"], mCapParams.charucoSquareLength);
    readFromNode(reader["charuco_marker_size"], mCapParams.charucoMarkerSize);
    readFromNode(reader["camera_resolution"], mCapParams.cameraResolution);
    readFromNode(reader["calibration_step"], mCapParams.calibrationStep);
    readFromNode(reader["max_frames_num"], mCapParams.maxFramesNum);
    readFromNode(reader["min_frames_num"], mCapParams.minFramesNum);
    readFromNode(reader["solver_eps"], mInternalParameters.solverEps);
    readFromNode(reader["solver_max_iters"], mInternalParameters.solverMaxIters);
    readFromNode(reader["fast_solver"], mInternalParameters.fastSolving);
    readFromNode(reader["frame_filter_conv_param"], mInternalParameters.filterAlpha);

    bool retValue =
            checkAssertion(mCapParams.charucoDictName >= 0, "Dict name must be >= 0") &&
            checkAssertion(mCapParams.charucoMarkerSize > 0, "Marker size must be positive") &&
            checkAssertion(mCapParams.charucoSquareLength > 0, "Square size must be positive") &&
            checkAssertion(mCapParams.minFramesNum > 1, "Minimal number of frames for calibration < 1") &&
            checkAssertion(mCapParams.calibrationStep > 0, "Calibration step must be positive") &&
            checkAssertion(mCapParams.maxFramesNum > mCapParams.minFramesNum, "maxFramesNum < minFramesNum") &&
            checkAssertion(mInternalParameters.solverEps > 0, "Solver precision must be positive") &&
            checkAssertion(mInternalParameters.solverMaxIters > 0, "Max solver iterations number must be positive") &&
            checkAssertion(mInternalParameters.filterAlpha >=0 && mInternalParameters.filterAlpha <=1 ,
                           "Frame filter convolution parameter must be in [0,1] interval") &&
            checkAssertion(mCapParams.cameraResolution.width > 0 && mCapParams.cameraResolution.height > 0,
                           "Wrong camera resolution values");

    reader.release();
    return retValue;
}

calib::parametersController::parametersController()
{
}

calib::captureParameters calib::parametersController::getCaptureParameters() const
{
    return mCapParams;
}

calib::internalParameters calib::parametersController::getInternalParameters() const
{
    return mInternalParameters;
}

bool calib::parametersController::loadFromParser(cv::CommandLineParser &parser)
{
    mCapParams.flipVertical = parser.get<bool>("flip");
    mCapParams.captureDelay = parser.get<float>("d");
    mCapParams.squareSize = parser.get<float>("sz");
    mCapParams.templDst = parser.get<float>("dst");
    mCapParams.saveFrames = parser.has("save_frames");
    mCapParams.zoom = parser.get<float>("zoom");

    if(!checkAssertion(mCapParams.squareSize > 0, "Distance between corners or circles must be positive"))
        return false;
    if(!checkAssertion(mCapParams.templDst > 0, "Distance between parts of dual template must be positive"))
        return false;

    if (parser.has("v")) {
        mCapParams.source = File;
        mCapParams.videoFileName = parser.get<std::string>("v");
    }
    else {
        mCapParams.source = Camera;
        mCapParams.camID = parser.get<int>("ci");
    }

    std::string templateType = parser.get<std::string>("t");

    if(templateType.find("circles", 0) == 0) {
        mCapParams.board = AcirclesGrid;
        mCapParams.boardSize = cv::Size(4, 11);
    }
    else if(templateType.find("chessboard", 0) == 0) {
        mCapParams.board = Chessboard;
        mCapParams.boardSize = cv::Size(7, 7);
    }
    else if(templateType.find("dualcircles", 0) == 0) {
        mCapParams.board = DoubleAcirclesGrid;
        mCapParams.boardSize = cv::Size(4, 11);
    }
    else if(templateType.find("charuco", 0) == 0) {
        mCapParams.board = chAruco;
        mCapParams.boardSize = cv::Size(6, 8);
        mCapParams.charucoDictName = 0;
        mCapParams.charucoSquareLength = 200;
        mCapParams.charucoMarkerSize = 100;
    }
    else {
        std::cerr << "Wrong template name\n";
        return false;
    }

    if(parser.has("w") && parser.has("h")) {
        mCapParams.boardSize = cv::Size(parser.get<int>("w"), parser.get<int>("h"));
        if(!checkAssertion(mCapParams.boardSize.width > 0 || mCapParams.boardSize.height > 0,
                           "Board size must be positive"))
            return false;
    }

    if(!checkAssertion(parser.get<std::string>("of").find(".xml") > 0,
                       "Wrong output file name: correct format is [name].xml"))
        return false;

    loadFromFile(parser.get<std::string>("pf"));
    return true;
}
<commit_msg>fix save_frames parameter<commit_after>// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.

#include "parametersController.hpp"

#include <iostream>

template <typename T>
static bool readFromNode(cv::FileNode node, T& value)
{
    if(!node.isNone()) {
        node >> value;
        return true;
    }
    else
        return false;
}

static bool checkAssertion(bool value, const std::string& msg)
{
    if(!value)
        std::cerr << "Error: " << msg << std::endl;

    return value;
}

bool calib::parametersController::loadFromFile(const std::string &inputFileName)
{
    cv::FileStorage reader;
    reader.open(inputFileName, cv::FileStorage::READ);

    if(!reader.isOpened()) {
        std::cerr << "Warning: Unable to open " << inputFileName <<
                     " Application started with default advanced parameters" << std::endl;
        return true;
    }

    readFromNode(reader["charuco_dict"], mCapParams.charucoDictName);
    if (readFromNode(reader["charuco_square_lenght"], mCapParams.charucoSquareLength)) {
        std::cout << "DEPRECATION: Parameter 'charuco_square_lenght' has been deprecated (typo). Use 'charuco_square_length' instead." << std::endl;
    }
    readFromNode(reader["charuco_square_length"], mCapParams.charucoSquareLength);
    readFromNode(reader["charuco_marker_size"], mCapParams.charucoMarkerSize);
    readFromNode(reader["camera_resolution"], mCapParams.cameraResolution);
    readFromNode(reader["calibration_step"], mCapParams.calibrationStep);
    readFromNode(reader["max_frames_num"], mCapParams.maxFramesNum);
    readFromNode(reader["min_frames_num"], mCapParams.minFramesNum);
    readFromNode(reader["solver_eps"], mInternalParameters.solverEps);
    readFromNode(reader["solver_max_iters"], mInternalParameters.solverMaxIters);
    readFromNode(reader["fast_solver"], mInternalParameters.fastSolving);
    readFromNode(reader["frame_filter_conv_param"], mInternalParameters.filterAlpha);

    bool retValue =
            checkAssertion(mCapParams.charucoDictName >= 0, "Dict name must be >= 0") &&
            checkAssertion(mCapParams.charucoMarkerSize > 0, "Marker size must be positive") &&
            checkAssertion(mCapParams.charucoSquareLength > 0, "Square size must be positive") &&
            checkAssertion(mCapParams.minFramesNum > 1, "Minimal number of frames for calibration < 1") &&
            checkAssertion(mCapParams.calibrationStep > 0, "Calibration step must be positive") &&
            checkAssertion(mCapParams.maxFramesNum > mCapParams.minFramesNum, "maxFramesNum < minFramesNum") &&
            checkAssertion(mInternalParameters.solverEps > 0, "Solver precision must be positive") &&
            checkAssertion(mInternalParameters.solverMaxIters > 0, "Max solver iterations number must be positive") &&
            checkAssertion(mInternalParameters.filterAlpha >=0 && mInternalParameters.filterAlpha <=1 ,
                           "Frame filter convolution parameter must be in [0,1] interval") &&
            checkAssertion(mCapParams.cameraResolution.width > 0 && mCapParams.cameraResolution.height > 0,
                           "Wrong camera resolution values");

    reader.release();
    return retValue;
}

calib::parametersController::parametersController()
{
}

calib::captureParameters calib::parametersController::getCaptureParameters() const
{
    return mCapParams;
}

calib::internalParameters calib::parametersController::getInternalParameters() const
{
    return mInternalParameters;
}

bool calib::parametersController::loadFromParser(cv::CommandLineParser &parser)
{
    mCapParams.flipVertical = parser.get<bool>("flip");
    mCapParams.captureDelay = parser.get<float>("d");
    mCapParams.squareSize = parser.get<float>("sz");
    mCapParams.templDst = parser.get<float>("dst");
    mCapParams.saveFrames = parser.get<bool>("save_frames");
    mCapParams.zoom = parser.get<float>("zoom");

    if(!checkAssertion(mCapParams.squareSize > 0, "Distance between corners or circles must be positive"))
        return false;
    if(!checkAssertion(mCapParams.templDst > 0, "Distance between parts of dual template must be positive"))
        return false;

    if (parser.has("v")) {
        mCapParams.source = File;
        mCapParams.videoFileName = parser.get<std::string>("v");
    }
    else {
        mCapParams.source = Camera;
        mCapParams.camID = parser.get<int>("ci");
    }

    std::string templateType = parser.get<std::string>("t");

    if(templateType.find("circles", 0) == 0) {
        mCapParams.board = AcirclesGrid;
        mCapParams.boardSize = cv::Size(4, 11);
    }
    else if(templateType.find("chessboard", 0) == 0) {
        mCapParams.board = Chessboard;
        mCapParams.boardSize = cv::Size(7, 7);
    }
    else if(templateType.find("dualcircles", 0) == 0) {
        mCapParams.board = DoubleAcirclesGrid;
        mCapParams.boardSize = cv::Size(4, 11);
    }
    else if(templateType.find("charuco", 0) == 0) {
        mCapParams.board = chAruco;
        mCapParams.boardSize = cv::Size(6, 8);
        mCapParams.charucoDictName = 0;
        mCapParams.charucoSquareLength = 200;
        mCapParams.charucoMarkerSize = 100;
    }
    else {
        std::cerr << "Wrong template name\n";
        return false;
    }

    if(parser.has("w") && parser.has("h")) {
        mCapParams.boardSize = cv::Size(parser.get<int>("w"), parser.get<int>("h"));
        if(!checkAssertion(mCapParams.boardSize.width > 0 || mCapParams.boardSize.height > 0,
                           "Board size must be positive"))
            return false;
    }

    if(!checkAssertion(parser.get<std::string>("of").find(".xml") > 0,
                       "Wrong output file name: correct format is [name].xml"))
        return false;

    loadFromFile(parser.get<std::string>("pf"));
    return true;
}
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (C) 2004 by Stanislav Karchebny                             *
 *   Stanislav.Karchebny@kdemail.net                                       *
 *                                                                         *
 *   Licensed under GPL.                                                   *
 ***************************************************************************/

#include "feed.h"
#include "feediconmanager.h"
#include "feedscollection.h"

#include <kurl.h>
#include <kdebug.h>
#include <kglobal.h>
#include <kstandarddirs.h>
#include <kiconloader.h>

#include <qtimer.h>
#include <qlistview.h>
#include <qdom.h>

using namespace Akregator;
using namespace RSS;

Feed::Feed(QListViewItem *i, FeedsCollection *coll)
    : FeedGroup(i, coll)
    , updateTitle(false)
    , articles()
    , m_fetchError(false)
    , m_fetchTries(0)
    , m_merged(false)
    , m_unread(0)
{
}

Feed::~Feed()
{
}

bool Feed::isGroup()
{
    return false;
}

QDomElement Feed::toXml( QDomElement parent, QDomDocument document )
{
    QDomElement el = document.createElement( "outline" );
    el.setAttribute( "text", title() );
    el.setAttribute( "title", title() );
    el.setAttribute( "xmlUrl", xmlUrl );
    el.setAttribute( "htmlUrl", htmlUrl );
    el.setAttribute( "description", description );
    el.setAttribute( "updateTitle", (updateTitle ? "true" : "false") );
    el.setAttribute( "type", "rss" ); // despite some additional fields, its still "rss" OPML
    el.setAttribute( "version", "RSS" );
    parent.appendChild( el );
    return el;
}

void Feed::dumpXmlData( QDomElement parent, QDomDocument doc )
{
    QDomElement channode = doc.createElement( "channel" );
    parent.appendChild(channode);
    QDomElement tnode = doc.createElement( "title" );
    QDomText t=doc.createTextNode( title() );
    tnode.appendChild(t);
    channode.appendChild(tnode);

    if (!htmlUrl.isEmpty())
    {
        QDomElement lnode = doc.createElement( "link" );
        QDomText ht=doc.createTextNode( htmlUrl );
        lnode.appendChild(ht);
        channode.appendChild(lnode);
    }

    // rss 2.0 requires channel description
    QDomElement dnode = doc.createElement( "description" );
    QDomText dt=doc.createTextNode( htmlUrl );
    dnode.appendChild(dt);
    channode.appendChild(dnode);

    ArticleSequence::ConstIterator it;
    ArticleSequence::ConstIterator en=articles.end();
    for (it = articles.begin(); it != en; ++it)
    {
        QDomElement enode = doc.createElement( "item" );
        (*it).dumpXmlData(enode, doc);
        channode.appendChild(enode);
    }

}

void Feed::markAllRead()
{
    ArticleSequence::Iterator it;
    ArticleSequence::Iterator en=articles.end();
    for (it = articles.begin(); it != en; ++it)
    {
        (*it).setStatus(MyArticle::Read);
    }
    m_unread=0;
}

void Feed::appendArticles(const Document &d, bool findDups)
{
//    kdDebug() << "appendArticles findDups=="<<findDups<< " isMerged=="<< m_merged<<endl;
    findDups=true;
    Article::List::ConstIterator it;
    Article::List::ConstIterator en = d.articles().end();
    //kdDebug() << "m_unread before appending articles=="<<m_unread<<endl;
    for (it = d.articles().begin(); it != en; ++it)
    {
        MyArticle mya(*it);
        if (findDups)
        {
            ArticleSequence::ConstIterator oo=articles.find(mya);
            if (oo == articles.end() )
            {
                if (m_merged)
                    mya.setStatus(MyArticle::New);
                else
                {
                    if (mya.status()==MyArticle::New)
                        mya.setStatus(MyArticle::Unread);
                }
                appendArticle(mya);
            }
            /*else{
            kdDebug() << "got dup!!"<<mya.title()<<endl;
            }*/
        }
        else
        {
            MyArticle mya(*it);
            if (!m_merged)
            {
                if (mya.status()==MyArticle::New)
                    mya.setStatus(MyArticle::Unread);
            }
            appendArticle(mya);
        }
    }
    //kdDebug() << "m_unread after appending articles=="<<m_unread<<endl;
}

void Feed::appendArticle(const MyArticle &a)
{
    if (a.status()!=MyArticle::Read)
        m_unread++;
    articles.append(a);
}

void Feed::fetch(bool followDiscovery)
{
    m_fetchError=false;
	m_followDiscovery=followDiscovery;
    m_fetchTries=0;

    // mark all new as unread
    ArticleSequence::Iterator it;
    ArticleSequence::Iterator en=articles.end();
    for (it = articles.begin(); it != en; ++it)
    {
        if ((*it).status()==MyArticle::New)
        {
            (*it).setStatus(MyArticle::Unread);
        }
    }

    tryFetch();
}

void Feed::tryFetch()
{
    Loader *loader = Loader::create( this, SLOT(fetchCompleted(Loader *, Document, Status)) );
    loader->loadFrom( xmlUrl, new FileRetriever );
    // TODO: note that we probably don't want to load the favicon here enventually..
    QTimer::singleShot( 1000, this, SLOT(loadFavicon()) );
    //loadFavicon();
}

void Feed::fetchCompleted(Loader *l, Document doc, Status status)
{
    // Note that Loader::~Loader() is private, so you cannot delete Loader instances.
    // You don't need to do that anyway since Loader instances delete themselves.

    if (status!= Success)
    {
        if (m_followDiscovery && (status==ParseError) && (m_fetchTries < 3) && 			(l->discoveredFeedURL().isValid()))
        {
            m_fetchTries++;
            xmlUrl=l->discoveredFeedURL().url();
            emit fetchDiscovery(this);
            tryFetch();
            return;
        }
        else
        {
            faviconChanged(xmlUrl, KGlobal::iconLoader()->loadIcon("cancel", KIcon::Small));
            m_fetchError=true;
            emit fetchError(this);
            return;
        }
    }

    m_fetchError=false;
    m_document=doc;
    kdDebug() << "Feed fetched successfully [" << m_document.title() << "]" << endl;

    if (image.isNull())
    {
        QString u=xmlUrl;
        QString imageFileName=KGlobal::dirs()->saveLocation("cache", "akregator/Media/")+u.replace("/", "_").replace(":", "_")+".png";
        image=QPixmap(imageFileName, "PNG");

        if (image.isNull())
        {
            if (m_document.image()) // if we aint got teh image
                                    // and the feed provides one, get it....
            {
                connect (m_document.image(), SIGNAL(gotPixmap(const QPixmap &)),
                                   this, SLOT(imageChanged(const QPixmap &)));
                m_document.image()->getPixmap();
            }
        }
    }

    if (updateTitle || title().isEmpty()) setTitle( m_document.title() );

    description = m_document.description();
    htmlUrl = m_document.link().url();

    //kdDebug() << "ismerged reprots:::"<<isMerged()<<endl;

    bool findDups=isMerged();
    appendArticles(m_document, findDups);

    emit fetched(this);
}

void Feed::loadFavicon()
{
    FeedIconManager::self()->loadIcon(xmlUrl);
    connect (FeedIconManager::self(), SIGNAL(iconChanged(const QString &, const QPixmap &)),
                                this, SLOT(faviconChanged(const QString &, const QPixmap &)));
}

void Feed::faviconChanged(const QString &url, const QPixmap &p)
{
    if (xmlUrl==url && !m_fetchError)
    {
        if (item())
            item()->setPixmap(0, p);
        favicon=p;
        emit(faviconLoaded(this)); // emit so that other sources can be updated.. not used right now
    }
}

void Feed::imageChanged(const QPixmap &p)
{
    image=p;
    QString u=xmlUrl;
    image.save(KGlobal::dirs()->saveLocation("cache", "akregator/Media/")+u.replace("/", "_").replace(":", "_")+".png","PNG");
    emit(imageLoaded(this));
}

// = ArticleSequence ===================================================== //

struct ArticleSequence::Private
{
   int dummy;
//   bool doSort :1;
};

ArticleSequence::ArticleSequence()
   : MyArticle::List()
   , d(new Private)
{
}

ArticleSequence::ArticleSequence(const ArticleSequence &other)
   : MyArticle::List(other)
   , d(new Private)
{
}

ArticleSequence::~ArticleSequence()
{
   delete d;
}

/*
    The reason to include insert/append/prepend code here is to:
    a) check if there's another record with the exactly same pubDate() present,
    b) if so, adjust this inserted item's clock off by one second to keep sorting sane,
    c) re-sort added items (if enabled).
    d) use MyArticle::fetchDate for sorting! ( defined by MyArticle::operator <() )
 */
ArticleSequence::iterator ArticleSequence::insert( iterator it, const MyArticle &x )
{
    return MyArticle::List::insert( it, x );
}

void ArticleSequence::insert( iterator it, size_type n, const MyArticle &x )
{
    MyArticle::List::insert( it, n, x );
}

ArticleSequence::iterator ArticleSequence::append( const MyArticle &x )
{
    return MyArticle::List::append( x );
}

ArticleSequence::iterator ArticleSequence::prepend( const MyArticle &x )
{
    return MyArticle::List::prepend( x );
}

/*
void ArticleSequence::doNotSort()
{
    d->doSort = false;
}

void ArticleSequence::sort()
{
    d->doSort = true;
//    qHeapSort( *this );
}
*/

#include "feed.moc"
<commit_msg>reset the feed favicon if it error'd last time fetching it.<commit_after>/***************************************************************************
 *   Copyright (C) 2004 by Stanislav Karchebny                             *
 *   Stanislav.Karchebny@kdemail.net                                       *
 *                                                                         *
 *   Licensed under GPL.                                                   *
 ***************************************************************************/

#include "feed.h"
#include "feediconmanager.h"
#include "feedscollection.h"

#include <kurl.h>
#include <kdebug.h>
#include <kglobal.h>
#include <kstandarddirs.h>
#include <kiconloader.h>

#include <qtimer.h>
#include <qlistview.h>
#include <qdom.h>

using namespace Akregator;
using namespace RSS;

Feed::Feed(QListViewItem *i, FeedsCollection *coll)
    : FeedGroup(i, coll)
    , updateTitle(false)
    , articles()
    , m_fetchError(false)
    , m_fetchTries(0)
    , m_merged(false)
    , m_unread(0)
{
}

Feed::~Feed()
{
}

bool Feed::isGroup()
{
    return false;
}

QDomElement Feed::toXml( QDomElement parent, QDomDocument document )
{
    QDomElement el = document.createElement( "outline" );
    el.setAttribute( "text", title() );
    el.setAttribute( "title", title() );
    el.setAttribute( "xmlUrl", xmlUrl );
    el.setAttribute( "htmlUrl", htmlUrl );
    el.setAttribute( "description", description );
    el.setAttribute( "updateTitle", (updateTitle ? "true" : "false") );
    el.setAttribute( "type", "rss" ); // despite some additional fields, its still "rss" OPML
    el.setAttribute( "version", "RSS" );
    parent.appendChild( el );
    return el;
}

void Feed::dumpXmlData( QDomElement parent, QDomDocument doc )
{
    QDomElement channode = doc.createElement( "channel" );
    parent.appendChild(channode);
    QDomElement tnode = doc.createElement( "title" );
    QDomText t=doc.createTextNode( title() );
    tnode.appendChild(t);
    channode.appendChild(tnode);

    if (!htmlUrl.isEmpty())
    {
        QDomElement lnode = doc.createElement( "link" );
        QDomText ht=doc.createTextNode( htmlUrl );
        lnode.appendChild(ht);
        channode.appendChild(lnode);
    }

    // rss 2.0 requires channel description
    QDomElement dnode = doc.createElement( "description" );
    QDomText dt=doc.createTextNode( htmlUrl );
    dnode.appendChild(dt);
    channode.appendChild(dnode);

    ArticleSequence::ConstIterator it;
    ArticleSequence::ConstIterator en=articles.end();
    for (it = articles.begin(); it != en; ++it)
    {
        QDomElement enode = doc.createElement( "item" );
        (*it).dumpXmlData(enode, doc);
        channode.appendChild(enode);
    }

}

void Feed::markAllRead()
{
    ArticleSequence::Iterator it;
    ArticleSequence::Iterator en=articles.end();
    for (it = articles.begin(); it != en; ++it)
    {
        (*it).setStatus(MyArticle::Read);
    }
    m_unread=0;
}

void Feed::appendArticles(const Document &d, bool findDups)
{
//    kdDebug() << "appendArticles findDups=="<<findDups<< " isMerged=="<< m_merged<<endl;
    findDups=true;
    Article::List::ConstIterator it;
    Article::List::ConstIterator en = d.articles().end();
    //kdDebug() << "m_unread before appending articles=="<<m_unread<<endl;
    for (it = d.articles().begin(); it != en; ++it)
    {
        MyArticle mya(*it);
        if (findDups)
        {
            ArticleSequence::ConstIterator oo=articles.find(mya);
            if (oo == articles.end() )
            {
                if (m_merged)
                    mya.setStatus(MyArticle::New);
                else
                {
                    if (mya.status()==MyArticle::New)
                        mya.setStatus(MyArticle::Unread);
                }
                appendArticle(mya);
            }
            /*else{
            kdDebug() << "got dup!!"<<mya.title()<<endl;
            }*/
        }
        else
        {
            MyArticle mya(*it);
            if (!m_merged)
            {
                if (mya.status()==MyArticle::New)
                    mya.setStatus(MyArticle::Unread);
            }
            appendArticle(mya);
        }
    }
    //kdDebug() << "m_unread after appending articles=="<<m_unread<<endl;
}

void Feed::appendArticle(const MyArticle &a)
{
    if (a.status()!=MyArticle::Read)
        m_unread++;
    articles.append(a);
}

void Feed::fetch(bool followDiscovery)
{
	m_followDiscovery=followDiscovery;
    m_fetchTries=0;

    // mark all new as unread
    ArticleSequence::Iterator it;
    ArticleSequence::Iterator en=articles.end();
    for (it = articles.begin(); it != en; ++it)
    {
        if ((*it).status()==MyArticle::New)
        {
            (*it).setStatus(MyArticle::Unread);
        }
    }

    tryFetch();
}

void Feed::tryFetch()
{
    if (item() && m_fetchError)
        item()->setPixmap(0, KGlobal::iconLoader()->loadIcon("txt", KIcon::Small));

    m_fetchError=false;

    Loader *loader = Loader::create( this, SLOT(fetchCompleted(Loader *, Document, Status)) );
    loader->loadFrom( xmlUrl, new FileRetriever );
    // TODO: note that we probably don't want to load the favicon here enventually..
    QTimer::singleShot( 1000, this, SLOT(loadFavicon()) );
    //loadFavicon();
}

void Feed::fetchCompleted(Loader *l, Document doc, Status status)
{
    // Note that Loader::~Loader() is private, so you cannot delete Loader instances.
    // You don't need to do that anyway since Loader instances delete themselves.

    if (status!= Success)
    {
        if (m_followDiscovery && (status==ParseError) && (m_fetchTries < 3) && 			(l->discoveredFeedURL().isValid()))
        {
            m_fetchTries++;
            xmlUrl=l->discoveredFeedURL().url();
            emit fetchDiscovery(this);
            tryFetch();
            return;
        }
        else
        {
            faviconChanged(xmlUrl, KGlobal::iconLoader()->loadIcon("cancel", KIcon::Small));
            m_fetchError=true;
            emit fetchError(this);
            return;
        }
    }

    m_fetchError=false;
    m_document=doc;
    //kdDebug() << "Feed fetched successfully [" << m_document.title() << "]" << endl;

    if (image.isNull())
    {
        QString u=xmlUrl;
        QString imageFileName=KGlobal::dirs()->saveLocation("cache", "akregator/Media/")+u.replace("/", "_").replace(":", "_")+".png";
        image=QPixmap(imageFileName, "PNG");

        if (image.isNull())
        {
            if (m_document.image()) // if we aint got teh image
                                    // and the feed provides one, get it....
            {
                connect (m_document.image(), SIGNAL(gotPixmap(const QPixmap &)),
                                   this, SLOT(imageChanged(const QPixmap &)));
                m_document.image()->getPixmap();
            }
        }
    }

    if (updateTitle || title().isEmpty()) setTitle( m_document.title() );

    description = m_document.description();
    htmlUrl = m_document.link().url();

    //kdDebug() << "ismerged reprots:::"<<isMerged()<<endl;

    bool findDups=isMerged();
    appendArticles(m_document, findDups);

    emit fetched(this);
}

void Feed::loadFavicon()
{
    FeedIconManager::self()->loadIcon(xmlUrl);
    connect (FeedIconManager::self(), SIGNAL(iconChanged(const QString &, const QPixmap &)),
                                this, SLOT(faviconChanged(const QString &, const QPixmap &)));
}

void Feed::faviconChanged(const QString &url, const QPixmap &p)
{
    if (xmlUrl==url && !m_fetchError)
    {
        if (item())
            item()->setPixmap(0, p);
        favicon=p;
        emit(faviconLoaded(this)); // emit so that other sources can be updated.. not used right now
    }
}

void Feed::imageChanged(const QPixmap &p)
{
    image=p;
    QString u=xmlUrl;
    image.save(KGlobal::dirs()->saveLocation("cache", "akregator/Media/")+u.replace("/", "_").replace(":", "_")+".png","PNG");
    emit(imageLoaded(this));
}

// = ArticleSequence ===================================================== //

struct ArticleSequence::Private
{
   int dummy;
//   bool doSort :1;
};

ArticleSequence::ArticleSequence()
   : MyArticle::List()
   , d(new Private)
{
}

ArticleSequence::ArticleSequence(const ArticleSequence &other)
   : MyArticle::List(other)
   , d(new Private)
{
}

ArticleSequence::~ArticleSequence()
{
   delete d;
}

/*
    The reason to include insert/append/prepend code here is to:
    a) check if there's another record with the exactly same pubDate() present,
    b) if so, adjust this inserted item's clock off by one second to keep sorting sane,
    c) re-sort added items (if enabled).
    d) use MyArticle::fetchDate for sorting! ( defined by MyArticle::operator <() )
 */
ArticleSequence::iterator ArticleSequence::insert( iterator it, const MyArticle &x )
{
    return MyArticle::List::insert( it, x );
}

void ArticleSequence::insert( iterator it, size_type n, const MyArticle &x )
{
    MyArticle::List::insert( it, n, x );
}

ArticleSequence::iterator ArticleSequence::append( const MyArticle &x )
{
    return MyArticle::List::append( x );
}

ArticleSequence::iterator ArticleSequence::prepend( const MyArticle &x )
{
    return MyArticle::List::prepend( x );
}

/*
void ArticleSequence::doNotSort()
{
    d->doSort = false;
}

void ArticleSequence::sort()
{
    d->doSort = true;
//    qHeapSort( *this );
}
*/

#include "feed.moc"
<|endoftext|>


<commit_before>#define BOOST_TEST_MODULE exscan

#include <boost/test/included/unit_test.hpp>
#include <mpl/mpl.hpp>

template<typename T>
struct add {
  T operator()(const T &a, const T &b) { return a + b; }
};

template<typename T>
bool exscan_func_test() {
  const mpl::communicator &comm_world = mpl::environment::comm_world();
  int N = comm_world.rank() + 1;
  T x{T(N)}, y{};
  comm_world.exscan(add<T>(), x, y);
  return comm_world.rank() == 0 ? true : y == T((N * N - N) / 2);
}

template<typename T>
bool exscan_op_test() {
  const mpl::communicator &comm_world = mpl::environment::comm_world();
  int N = comm_world.rank() + 1;
  T x{T(N)}, y{};
  comm_world.exscan(mpl::plus<T>(), x, y);
  return comm_world.rank() == 0 ? true : y == T((N * N - N) / 2);
}

template<typename T>
bool exscan_lambda_test() {
  const mpl::communicator &comm_world = mpl::environment::comm_world();
  int N = comm_world.rank() + 1;
  T x{T(N)}, y{};
  comm_world.exscan([](T a, T b) { return a + b; }, x, y);
  return comm_world.rank() == 0 ? true : y == T((N * N - N) / 2);
}

template<typename T>
bool exscan_inplace_func_test() {
  const mpl::communicator &comm_world = mpl::environment::comm_world();
  int N = comm_world.rank() + 1;
  T x{T(N)};
  comm_world.exscan(add<T>(), x);
  return comm_world.rank() == 0 ? true : x == T((N * N - N) / 2);
}

template<typename T>
bool exscan_inplace_op_test() {
  const mpl::communicator &comm_world = mpl::environment::comm_world();
  int N = comm_world.rank() + 1;
  T x{T(N)};
  comm_world.exscan(mpl::plus<T>(), x);
  return comm_world.rank() == 0 ? true : x == T((N * N - N) / 2);
}

template<typename T>
bool exscan_inplace_lambda_test() {
  const mpl::communicator &comm_world = mpl::environment::comm_world();
  int N = comm_world.rank() + 1;
  T x{T(N)};
  comm_world.exscan([](T a, T b) { return a + b; }, x);
  return comm_world.rank() == 0 ? true : x == T((N * N - N) / 2);
}

BOOST_AUTO_TEST_CASE(reduce) {
  BOOST_TEST(exscan_func_test<double>());
  BOOST_TEST(exscan_op_test<double>());
  BOOST_TEST(exscan_lambda_test<double>());
  BOOST_TEST(exscan_inplace_func_test<double>());
  BOOST_TEST(exscan_inplace_op_test<double>());
  BOOST_TEST(exscan_inplace_lambda_test<double>());
}
<commit_msg>simplify logical expression<commit_after>#define BOOST_TEST_MODULE exscan

#include <boost/test/included/unit_test.hpp>
#include <mpl/mpl.hpp>

template<typename T>
struct add {
  T operator()(const T &a, const T &b) { return a + b; }
};

template<typename T>
bool exscan_func_test() {
  const mpl::communicator &comm_world = mpl::environment::comm_world();
  int N = comm_world.rank() + 1;
  T x{T(N)}, y{};
  comm_world.exscan(add<T>(), x, y);
  return comm_world.rank() == 0 || y == T((N * N - N) / 2);
}

template<typename T>
bool exscan_op_test() {
  const mpl::communicator &comm_world = mpl::environment::comm_world();
  int N = comm_world.rank() + 1;
  T x{T(N)}, y{};
  comm_world.exscan(mpl::plus<T>(), x, y);
  return comm_world.rank() == 0 || y == T((N * N - N) / 2);
}

template<typename T>
bool exscan_lambda_test() {
  const mpl::communicator &comm_world = mpl::environment::comm_world();
  int N = comm_world.rank() + 1;
  T x{T(N)}, y{};
  comm_world.exscan([](T a, T b) { return a + b; }, x, y);
  return comm_world.rank() == 0 || y == T((N * N - N) / 2);
}

template<typename T>
bool exscan_inplace_func_test() {
  const mpl::communicator &comm_world = mpl::environment::comm_world();
  int N = comm_world.rank() + 1;
  T x{T(N)};
  comm_world.exscan(add<T>(), x);
  return comm_world.rank() == 0 || x == T((N * N - N) / 2);
}

template<typename T>
bool exscan_inplace_op_test() {
  const mpl::communicator &comm_world = mpl::environment::comm_world();
  int N = comm_world.rank() + 1;
  T x{T(N)};
  comm_world.exscan(mpl::plus<T>(), x);
  return comm_world.rank() == 0 || x == T((N * N - N) / 2);
}

template<typename T>
bool exscan_inplace_lambda_test() {
  const mpl::communicator &comm_world = mpl::environment::comm_world();
  int N = comm_world.rank() + 1;
  T x{T(N)};
  comm_world.exscan([](T a, T b) { return a + b; }, x);
  return comm_world.rank() == 0 || x == T((N * N - N) / 2);
}

BOOST_AUTO_TEST_CASE(reduce) {
  BOOST_TEST(exscan_func_test<double>());
  BOOST_TEST(exscan_op_test<double>());
  BOOST_TEST(exscan_lambda_test<double>());
  BOOST_TEST(exscan_inplace_func_test<double>());
  BOOST_TEST(exscan_inplace_op_test<double>());
  BOOST_TEST(exscan_inplace_lambda_test<double>());
}
<|endoftext|>


<commit_before>#include "Daemon.h"

#ifndef _WIN32

#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

#include "Log.h"
#include "util.h"

void handle_signal(int sig)
{
	switch (sig)
	{
	case SIGHUP:
		if (i2p::util::config::GetArg("daemon", 0) == 1)
		{
			static bool first=true;
			if (first)
			{
				first=false;
				return;
			}
		}
		LogPrint("Reloading config.");
		i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs);
		break;
	case SIGABRT:
	case SIGTERM:
	case SIGINT:
		Daemon.running = 0; // Exit loop
		break;
	}
}

namespace i2p
{
	namespace util
	{
		bool DaemonLinux::start()
		{
			if (isDaemon == 1)
			{
				pid_t pid;
				pid = fork();
				if (pid > 0) // parent
					::exit (EXIT_SUCCESS);

				if (pid < 0) // error
					return false;

				// child
				umask(0);
				int sid = setsid();
				if (sid < 0)
				{
					LogPrint("Error, could not create process group.");
					return false;
				}
				std::string d(i2p::util::filesystem::GetDataDir()); // make a copy
				chdir(d.c_str());

				// close stdin/stdout/stderr descriptors
				::close (0);
				::open ("/dev/null", O_RDWR);
				::close (1);
				::open ("/dev/null", O_RDWR);
				::close (2);
				::open ("/dev/null", O_RDWR);
			}

			// Pidfile
			pidfile = IsService () ? "/var/run" : i2p::util::filesystem::GetDataDir().string();
			pidfile.append("/i2pd.pid");
			pidFilehandle = open(pidfile.c_str(), O_RDWR | O_CREAT, 0600);
			if (pidFilehandle == -1)
			{
				LogPrint("Error, could not create pid file (", pidfile, ")\nIs an instance already running?");
				return false;
			}
			if (lockf(pidFilehandle, F_TLOCK, 0) == -1)
			{
				LogPrint("Error, could not lock pid file (", pidfile, ")\nIs an instance already running?");
				return false;
			}
			char pid[10];
			sprintf(pid, "%d\n", getpid());
			write(pidFilehandle, pid, strlen(pid));

			// Signal handler
			struct sigaction sa;
			sa.sa_handler = handle_signal;
			sigemptyset(&sa.sa_mask);
			sa.sa_flags = SA_RESTART;
			sigaction(SIGHUP, &sa, 0);
			sigaction(SIGABRT, &sa, 0);
			sigaction(SIGTERM, &sa, 0);
			sigaction(SIGINT, &sa, 0);

			return Daemon_Singleton::start();
		}

		bool DaemonLinux::stop()
		{
			close(pidFilehandle);
			unlink(pidfile.c_str());

			return Daemon_Singleton::stop();
		}

	}
}

#endif
<commit_msg>fixed build error<commit_after>#include "Daemon.h"

#ifndef _WIN32

#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

#include "Log.h"
#include "util.h"

void handle_signal(int sig)
{
	switch (sig)
	{
	case SIGHUP:
		if (i2p::util::config::GetArg("daemon", 0) == 1)
		{
			static bool first=true;
			if (first)
			{
				first=false;
				return;
			}
		}
		LogPrint("Reloading config.");
		i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs);
		break;
	case SIGABRT:
	case SIGTERM:
	case SIGINT:
		Daemon.running = 0; // Exit loop
		break;
	}
}

namespace i2p
{
	namespace util
	{
		bool DaemonLinux::start()
		{
			if (isDaemon == 1)
			{
				pid_t pid;
				pid = fork();
				if (pid > 0) // parent
					::exit (EXIT_SUCCESS);

				if (pid < 0) // error
					return false;

				// child
				umask(0);
				int sid = setsid();
				if (sid < 0)
				{
					LogPrint("Error, could not create process group.");
					return false;
				}
				std::string d(i2p::util::filesystem::GetDataDir().string ()); // make a copy
				chdir(d.c_str());

				// close stdin/stdout/stderr descriptors
				::close (0);
				::open ("/dev/null", O_RDWR);
				::close (1);
				::open ("/dev/null", O_RDWR);
				::close (2);
				::open ("/dev/null", O_RDWR);
			}

			// Pidfile
			pidfile = IsService () ? "/var/run" : i2p::util::filesystem::GetDataDir().string();
			pidfile.append("/i2pd.pid");
			pidFilehandle = open(pidfile.c_str(), O_RDWR | O_CREAT, 0600);
			if (pidFilehandle == -1)
			{
				LogPrint("Error, could not create pid file (", pidfile, ")\nIs an instance already running?");
				return false;
			}
			if (lockf(pidFilehandle, F_TLOCK, 0) == -1)
			{
				LogPrint("Error, could not lock pid file (", pidfile, ")\nIs an instance already running?");
				return false;
			}
			char pid[10];
			sprintf(pid, "%d\n", getpid());
			write(pidFilehandle, pid, strlen(pid));

			// Signal handler
			struct sigaction sa;
			sa.sa_handler = handle_signal;
			sigemptyset(&sa.sa_mask);
			sa.sa_flags = SA_RESTART;
			sigaction(SIGHUP, &sa, 0);
			sigaction(SIGABRT, &sa, 0);
			sigaction(SIGTERM, &sa, 0);
			sigaction(SIGINT, &sa, 0);

			return Daemon_Singleton::start();
		}

		bool DaemonLinux::stop()
		{
			close(pidFilehandle);
			unlink(pidfile.c_str());

			return Daemon_Singleton::stop();
		}

	}
}

#endif
<|endoftext|>


<commit_before>#include "Tesselate.hpp"

#include "ExPolygon.hpp"

#include <glu-libtess.h>

namespace Slic3r {

class GluTessWrapper {
public:
    GluTessWrapper() : m_tesselator(gluNewTess()) {
        // register callback functions
        gluTessCallback(m_tesselator, GLU_TESS_BEGIN_DATA,   (_GLUfuncptr)tessBeginCB);
        gluTessCallback(m_tesselator, GLU_TESS_END_DATA,     (_GLUfuncptr)tessEndCB);
        gluTessCallback(m_tesselator, GLU_TESS_ERROR_DATA,   (_GLUfuncptr)tessErrorCB);
        gluTessCallback(m_tesselator, GLU_TESS_VERTEX_DATA,  (_GLUfuncptr)tessVertexCB);
        gluTessCallback(m_tesselator, GLU_TESS_COMBINE_DATA, (_GLUfuncptr)tessCombineCB);
    }
    ~GluTessWrapper() {
        gluDeleteTess(m_tesselator);
    }

    Pointf3s tesselate(const ExPolygon &expoly, double z_, bool flipped_)
    {
        m_z = z_;
        m_flipped = flipped_;
        std::vector<GLdouble> coords;
        {
            size_t num_coords = expoly.contour.points.size();
            for (const Polygon &poly : expoly.holes)
                num_coords += poly.points.size();
            coords.reserve(num_coords * 3);
        }
        gluTessBeginPolygon(m_tesselator, (void*)this);
        gluTessBeginContour(m_tesselator);
        for (const Point &pt : expoly.contour.points) {
            coords.emplace_back(unscale<double>(pt[0]));
            coords.emplace_back(unscale<double>(pt[1]));
            coords.emplace_back(0.);
            gluTessVertex(m_tesselator, &coords[coords.size() - 3], &coords[coords.size() - 3]);
        }
        gluTessEndContour(m_tesselator);
        for (const Polygon &poly : expoly.holes) {
            gluTessBeginContour(m_tesselator);
            for (const Point &pt : poly.points) {
                coords.emplace_back(unscale<double>(pt[0]));
                coords.emplace_back(unscale<double>(pt[1]));
                coords.emplace_back(0.);
                gluTessVertex(m_tesselator, &coords[coords.size() - 3], &coords[coords.size() - 3]);
            }
            gluTessEndContour(m_tesselator);
        }
        gluTessEndPolygon(m_tesselator);
        m_output_triangles.clear();
        m_intersection_points.clear();
        return std::move(m_output_triangles);
    }

    Pointf3s tesselate(const ExPolygons &expolygons, double z_, bool flipped_)
    {
        m_z = z_;
        m_flipped = flipped_;
        std::vector<GLdouble> coords;
        {
            size_t num_coords = 0;
            for (const ExPolygon &expoly : expolygons) {
                size_t num_coords_this = expoly.contour.points.size();
                for (const Polygon &poly : expoly.holes)
                    num_coords_this += poly.points.size();
                num_coords = std::max(num_coords, num_coords_this);
            }
            coords.assign(num_coords * 3, 0);
        }
        for (const ExPolygon &expoly : expolygons) {
            gluTessBeginPolygon(m_tesselator, (void*)this);
            gluTessBeginContour(m_tesselator);
            size_t idx = 0;
            for (const Point &pt : expoly.contour.points) {
                coords[idx ++] = unscale<double>(pt[0]);
                coords[idx ++] = unscale<double>(pt[1]);
                coords[idx ++] = 0.;
                gluTessVertex(m_tesselator, &coords[idx - 3], &coords[idx - 3]);
            }
            gluTessEndContour(m_tesselator);
            for (const Polygon &poly : expoly.holes) {
                gluTessBeginContour(m_tesselator);
                for (const Point &pt : poly.points) {
                    coords[idx ++] = unscale<double>(pt[0]);
                    coords[idx ++] = unscale<double>(pt[1]);
                    coords[idx ++] = 0.;
                    gluTessVertex(m_tesselator, &coords[idx - 3], &coords[idx - 3]);
                }
                gluTessEndContour(m_tesselator);
            }
            gluTessEndPolygon(m_tesselator);
        }
        m_output_triangles.clear();
        m_intersection_points.clear();
        return std::move(m_output_triangles);
    }

private:
    static void tessBeginCB(GLenum which, void *polygonData)        { reinterpret_cast<GluTessWrapper*>(polygonData)->tessBegin(which); }
    static void tessEndCB(void *polygonData)                        { reinterpret_cast<GluTessWrapper*>(polygonData)->tessEnd(); }
    static void tessVertexCB(const GLvoid *data, void *polygonData) { reinterpret_cast<GluTessWrapper*>(polygonData)->tessVertex(data); }
    static void tessCombineCB(const GLdouble newVertex[3], const GLdouble *neighborVertex[4], const GLfloat neighborWeight[4], GLdouble **outData, void *polygonData)
                                                                    { reinterpret_cast<GluTessWrapper*>(polygonData)->tessCombine(newVertex, neighborVertex, neighborWeight, outData); }
    static void tessErrorCB(GLenum errorCode, void *polygonData)    { reinterpret_cast<GluTessWrapper*>(polygonData)->tessError(errorCode); }

    void tessBegin(GLenum which)
    {
        assert(which == GL_TRIANGLES || which == GL_TRIANGLE_FAN || which == GL_TRIANGLE_STRIP);
        m_primitive_type = which;
        m_num_points = 0;
    }

    void tessEnd()
    {
        m_num_points = 0;
    }

    void tessVertex(const GLvoid *data)
    {
        if (data == nullptr)
            return;
        const GLdouble *ptr = (const GLdouble*)data;
        ++ m_num_points;
        if (m_num_points == 1) {
            memcpy(m_pt0, ptr, sizeof(GLdouble) * 3);
        } else if (m_num_points == 2) {
            memcpy(m_pt1, ptr, sizeof(GLdouble) * 3);
        } else {
            bool flip = m_flipped;
            if (m_primitive_type == GL_TRIANGLE_STRIP && m_num_points == 4) {
                flip = !flip;
                m_num_points = 2;
            }
            m_output_triangles.emplace_back(m_pt0[0], m_pt0[1], m_z);
            if (flip) {
                m_output_triangles.emplace_back(ptr[0],   ptr[1],   m_z);
                m_output_triangles.emplace_back(m_pt1[0], m_pt1[1], m_z);
            } else {
                m_output_triangles.emplace_back(m_pt1[0], m_pt1[1], m_z);
                m_output_triangles.emplace_back(ptr[0],   ptr[1],   m_z);
            }
            if (m_primitive_type == GL_TRIANGLE_STRIP) {
                memcpy(m_pt0, m_pt1, sizeof(GLdouble) * 3);
                memcpy(m_pt1, ptr,   sizeof(GLdouble) * 3);
            } else if (m_primitive_type == GL_TRIANGLE_FAN) {
                memcpy(m_pt1, ptr,   sizeof(GLdouble) * 3);
            } else {
                assert(m_primitive_type == GL_TRIANGLES);
                assert(m_num_points == 3);
                m_num_points = 0;
            }
        }
    }

    void tessCombine(const GLdouble newVertex[3], const GLdouble *neighborVertex[4], const GLfloat neighborWeight[4], GLdouble **outData)
    {
        m_intersection_points.emplace_back(newVertex[0], newVertex[1], m_z);
        *outData = m_intersection_points.back().data();
    }

    static void tessError(GLenum errorCode)
    {
//        const GLubyte *errorStr;
//        errorStr = gluErrorString(errorCode);
//        printf("Error: %s\n", (const char*)errorStr);
    }

    // Instance owned over the life time of this wrapper.
    GLUtesselator  *m_tesselator;

    // Currently processed primitive type.
    GLenum          m_primitive_type;
    // Two last vertices received for m_primitive_type. Used for processing triangle strips, fans etc.
    GLdouble        m_pt0[3];
    GLdouble        m_pt1[3];
    // Number of points processed over m_primitive_type.
    int             m_num_points;
    // Triangles generated by the tesselator.
    Pointf3s        m_output_triangles;
    // Intersection points generated by tessCombine callback. There should be none if the input contour is not self intersecting.
    std::deque<Vec3d> m_intersection_points;
    // Fixed third coordinate.
    double          m_z;
    // Output triangles shall be flipped (normal points down).
    bool            m_flipped;
};

Pointf3s triangulate_expolygons_3df(const ExPolygon &poly, coordf_t z, bool flip)
{
    GluTessWrapper tess;
    return tess.tesselate(poly, z, flip);
}

Pointf3s triangulate_expolygons_3df(const ExPolygons &polys, coordf_t z, bool flip)
{
	GluTessWrapper tess;
    return tess.tesselate(polys, z, flip);
}

} // namespace Slic3r
<commit_msg>Fixed last buggy commit.<commit_after>#include "Tesselate.hpp"

#include "ExPolygon.hpp"

#include <glu-libtess.h>

namespace Slic3r {

class GluTessWrapper {
public:
    GluTessWrapper() : m_tesselator(gluNewTess()) {
        // register callback functions
        gluTessCallback(m_tesselator, GLU_TESS_BEGIN_DATA,   (_GLUfuncptr)tessBeginCB);
        gluTessCallback(m_tesselator, GLU_TESS_END_DATA,     (_GLUfuncptr)tessEndCB);
        gluTessCallback(m_tesselator, GLU_TESS_ERROR_DATA,   (_GLUfuncptr)tessErrorCB);
        gluTessCallback(m_tesselator, GLU_TESS_VERTEX_DATA,  (_GLUfuncptr)tessVertexCB);
        gluTessCallback(m_tesselator, GLU_TESS_COMBINE_DATA, (_GLUfuncptr)tessCombineCB);
    }
    ~GluTessWrapper() {
        gluDeleteTess(m_tesselator);
    }

    Pointf3s tesselate(const ExPolygon &expoly, double z_, bool flipped_)
    {
        m_z = z_;
        m_flipped = flipped_;
        m_output_triangles.clear();
        std::vector<GLdouble> coords;
        {
            size_t num_coords = expoly.contour.points.size();
            for (const Polygon &poly : expoly.holes)
                num_coords += poly.points.size();
            coords.reserve(num_coords * 3);
        }
        gluTessBeginPolygon(m_tesselator, (void*)this);
        gluTessBeginContour(m_tesselator);
        for (const Point &pt : expoly.contour.points) {
            coords.emplace_back(unscale<double>(pt[0]));
            coords.emplace_back(unscale<double>(pt[1]));
            coords.emplace_back(0.);
            gluTessVertex(m_tesselator, &coords[coords.size() - 3], &coords[coords.size() - 3]);
        }
        gluTessEndContour(m_tesselator);
        for (const Polygon &poly : expoly.holes) {
            gluTessBeginContour(m_tesselator);
            for (const Point &pt : poly.points) {
                coords.emplace_back(unscale<double>(pt[0]));
                coords.emplace_back(unscale<double>(pt[1]));
                coords.emplace_back(0.);
                gluTessVertex(m_tesselator, &coords[coords.size() - 3], &coords[coords.size() - 3]);
            }
            gluTessEndContour(m_tesselator);
        }
        gluTessEndPolygon(m_tesselator);
        m_intersection_points.clear();
        return std::move(m_output_triangles);
    }

    Pointf3s tesselate(const ExPolygons &expolygons, double z_, bool flipped_)
    {
        m_z = z_;
        m_flipped = flipped_;
        m_output_triangles.clear();
        std::vector<GLdouble> coords;
        {
            size_t num_coords = 0;
            for (const ExPolygon &expoly : expolygons) {
                size_t num_coords_this = expoly.contour.points.size();
                for (const Polygon &poly : expoly.holes)
                    num_coords_this += poly.points.size();
                num_coords = std::max(num_coords, num_coords_this);
            }
            coords.assign(num_coords * 3, 0);
        }
        for (const ExPolygon &expoly : expolygons) {
            gluTessBeginPolygon(m_tesselator, (void*)this);
            gluTessBeginContour(m_tesselator);
            size_t idx = 0;
            for (const Point &pt : expoly.contour.points) {
                coords[idx ++] = unscale<double>(pt[0]);
                coords[idx ++] = unscale<double>(pt[1]);
                coords[idx ++] = 0.;
                gluTessVertex(m_tesselator, &coords[idx - 3], &coords[idx - 3]);
            }
            gluTessEndContour(m_tesselator);
            for (const Polygon &poly : expoly.holes) {
                gluTessBeginContour(m_tesselator);
                for (const Point &pt : poly.points) {
                    coords[idx ++] = unscale<double>(pt[0]);
                    coords[idx ++] = unscale<double>(pt[1]);
                    coords[idx ++] = 0.;
                    gluTessVertex(m_tesselator, &coords[idx - 3], &coords[idx - 3]);
                }
                gluTessEndContour(m_tesselator);
            }
            gluTessEndPolygon(m_tesselator);
        }
        m_intersection_points.clear();
        return std::move(m_output_triangles);
    }

private:
    static void tessBeginCB(GLenum which, void *polygonData)        { reinterpret_cast<GluTessWrapper*>(polygonData)->tessBegin(which); }
    static void tessEndCB(void *polygonData)                        { reinterpret_cast<GluTessWrapper*>(polygonData)->tessEnd(); }
    static void tessVertexCB(const GLvoid *data, void *polygonData) { reinterpret_cast<GluTessWrapper*>(polygonData)->tessVertex(data); }
    static void tessCombineCB(const GLdouble newVertex[3], const GLdouble *neighborVertex[4], const GLfloat neighborWeight[4], GLdouble **outData, void *polygonData)
                                                                    { reinterpret_cast<GluTessWrapper*>(polygonData)->tessCombine(newVertex, neighborVertex, neighborWeight, outData); }
    static void tessErrorCB(GLenum errorCode, void *polygonData)    { reinterpret_cast<GluTessWrapper*>(polygonData)->tessError(errorCode); }

    void tessBegin(GLenum which)
    {
        assert(which == GL_TRIANGLES || which == GL_TRIANGLE_FAN || which == GL_TRIANGLE_STRIP);
        m_primitive_type = which;
        m_num_points = 0;
    }

    void tessEnd()
    {
        m_num_points = 0;
    }

    void tessVertex(const GLvoid *data)
    {
        if (data == nullptr)
            return;
        const GLdouble *ptr = (const GLdouble*)data;
        ++ m_num_points;
        if (m_num_points == 1) {
            memcpy(m_pt0, ptr, sizeof(GLdouble) * 3);
        } else if (m_num_points == 2) {
            memcpy(m_pt1, ptr, sizeof(GLdouble) * 3);
        } else {
            bool flip = m_flipped;
            if (m_primitive_type == GL_TRIANGLE_STRIP && m_num_points == 4) {
                flip = !flip;
                m_num_points = 2;
            }
            m_output_triangles.emplace_back(m_pt0[0], m_pt0[1], m_z);
            if (flip) {
                m_output_triangles.emplace_back(ptr[0],   ptr[1],   m_z);
                m_output_triangles.emplace_back(m_pt1[0], m_pt1[1], m_z);
            } else {
                m_output_triangles.emplace_back(m_pt1[0], m_pt1[1], m_z);
                m_output_triangles.emplace_back(ptr[0],   ptr[1],   m_z);
            }
            if (m_primitive_type == GL_TRIANGLE_STRIP) {
                memcpy(m_pt0, m_pt1, sizeof(GLdouble) * 3);
                memcpy(m_pt1, ptr,   sizeof(GLdouble) * 3);
            } else if (m_primitive_type == GL_TRIANGLE_FAN) {
                memcpy(m_pt1, ptr,   sizeof(GLdouble) * 3);
            } else {
                assert(m_primitive_type == GL_TRIANGLES);
                assert(m_num_points == 3);
                m_num_points = 0;
            }
        }
    }

    void tessCombine(const GLdouble newVertex[3], const GLdouble *neighborVertex[4], const GLfloat neighborWeight[4], GLdouble **outData)
    {
        m_intersection_points.emplace_back(newVertex[0], newVertex[1], m_z);
        *outData = m_intersection_points.back().data();
    }

    static void tessError(GLenum errorCode)
    {
//        const GLubyte *errorStr;
//        errorStr = gluErrorString(errorCode);
//        printf("Error: %s\n", (const char*)errorStr);
    }

    // Instance owned over the life time of this wrapper.
    GLUtesselator  *m_tesselator;

    // Currently processed primitive type.
    GLenum          m_primitive_type;
    // Two last vertices received for m_primitive_type. Used for processing triangle strips, fans etc.
    GLdouble        m_pt0[3];
    GLdouble        m_pt1[3];
    // Number of points processed over m_primitive_type.
    int             m_num_points;
    // Triangles generated by the tesselator.
    Pointf3s        m_output_triangles;
    // Intersection points generated by tessCombine callback. There should be none if the input contour is not self intersecting.
    std::deque<Vec3d> m_intersection_points;
    // Fixed third coordinate.
    double          m_z;
    // Output triangles shall be flipped (normal points down).
    bool            m_flipped;
};

Pointf3s triangulate_expolygons_3df(const ExPolygon &poly, coordf_t z, bool flip)
{
    GluTessWrapper tess;
    return tess.tesselate(poly, z, flip);
}

Pointf3s triangulate_expolygons_3df(const ExPolygons &polys, coordf_t z, bool flip)
{
	GluTessWrapper tess;
    return tess.tesselate(polys, z, flip);
}

} // namespace Slic3r
<|endoftext|>


<commit_before>//===-- sanitizer_atomic_test.cc ------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
//
//===----------------------------------------------------------------------===//
#include "sanitizer_common/sanitizer_atomic.h"
#include "gtest/gtest.h"

namespace __sanitizer {

template<typename T>
void CheckAtomicCompareExchange() {
  typedef typename T::Type Type;
  {
    Type old_val = 42;
    Type new_val = 24;
    Type var = old_val;
    EXPECT_TRUE(atomic_compare_exchange_strong((T*)&var, &old_val, new_val,
                                               memory_order_relaxed));
    EXPECT_FALSE(atomic_compare_exchange_strong((T*)&var, &old_val, new_val,
                                                memory_order_relaxed));
    EXPECT_EQ(new_val, old_val);
  }
  {
    Type old_val = 42;
    Type new_val = 24;
    Type var = old_val;
    EXPECT_TRUE(atomic_compare_exchange_weak((T*)&var, &old_val, new_val,
                                             memory_order_relaxed));
    EXPECT_FALSE(atomic_compare_exchange_weak((T*)&var, &old_val, new_val,
                                              memory_order_relaxed));
    EXPECT_EQ(new_val, old_val);
  }
}

TEST(SanitizerCommon, AtomicCompareExchangeTest) {
  CheckAtomicCompareExchange<atomic_uint8_t>();
  CheckAtomicCompareExchange<atomic_uint16_t>();
  CheckAtomicCompareExchange<atomic_uint32_t>();
  CheckAtomicCompareExchange<atomic_uint64_t>();
  CheckAtomicCompareExchange<atomic_uintptr_t>();
}

}  // namespace __sanitizer
<commit_msg>[Sanitizer] Disable atomic_test on Android, where it crashes Clang.<commit_after>//===-- sanitizer_atomic_test.cc ------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
//
//===----------------------------------------------------------------------===//
#include "sanitizer_common/sanitizer_atomic.h"
#include "gtest/gtest.h"

namespace __sanitizer {

// Clang crashes while compiling this test for Android:
// http://llvm.org/bugs/show_bug.cgi?id=15587
#if !SANITIZER_ANDROID
template<typename T>
void CheckAtomicCompareExchange() {
  typedef typename T::Type Type;
  {
    Type old_val = 42;
    Type new_val = 24;
    Type var = old_val;
    EXPECT_TRUE(atomic_compare_exchange_strong((T*)&var, &old_val, new_val,
                                               memory_order_relaxed));
    EXPECT_FALSE(atomic_compare_exchange_strong((T*)&var, &old_val, new_val,
                                                memory_order_relaxed));
    EXPECT_EQ(new_val, old_val);
  }
  {
    Type old_val = 42;
    Type new_val = 24;
    Type var = old_val;
    EXPECT_TRUE(atomic_compare_exchange_weak((T*)&var, &old_val, new_val,
                                             memory_order_relaxed));
    EXPECT_FALSE(atomic_compare_exchange_weak((T*)&var, &old_val, new_val,
                                              memory_order_relaxed));
    EXPECT_EQ(new_val, old_val);
  }
}

TEST(SanitizerCommon, AtomicCompareExchangeTest) {
  CheckAtomicCompareExchange<atomic_uint8_t>();
  CheckAtomicCompareExchange<atomic_uint16_t>();
  CheckAtomicCompareExchange<atomic_uint32_t>();
  CheckAtomicCompareExchange<atomic_uint64_t>();
  CheckAtomicCompareExchange<atomic_uintptr_t>();
}
#endif  //!SANITIZER_ANDROID

}  // namespace __sanitizer
<|endoftext|>


<commit_before>/*
*  Author(s):
*  - Chris  Kilner <ckilner@aldebaran-robotics.com>
*  - Cedric Gestes <gestes@aldebaran-robotics.com>
*
*  Copyright (C) 2010 Aldebaran Robotics
*/

#include "src/messaging/network/ip_address.hpp"
#include <boost/algorithm/string.hpp>

#ifdef _WIN32
#  include <windows.h>
#  include <winsock2.h>
#  include <iphlpapi.h>
#  include <Ws2tcpip.h>
#else
#  include <arpa/inet.h>
#  include <sys/socket.h>
#  include <netdb.h>
#  include <ifaddrs.h>
#  include <stdio.h>
#  include <stdlib.h>
#  include <unistd.h>
#endif

namespace qi {
namespace detail {

std::string getPrimaryPublicIPAddress()
{
  std::vector<std::string> ips = getIPAddresses();
  static const std::string ipLocalHost = "127.0.0.1";
  // todo: some logic to choose between good addresses
  for (unsigned int i = 0; i< ips.size(); i++)
  {
    if (ipLocalHost.compare(ips[i]) != 0)
      return ips[i];
  }
  return "";
}

bool isValidAddress(const std::string& userHostString,
  Address& outAddress)
{
  if (userHostString.empty())
    return false;

  std::vector<std::string> parts;
  boost::split(parts, userHostString, boost::is_any_of(":/"));

  if (parts.size() <= 2)
    parts.insert(parts.begin(), "tcp");

  if (parts.size() < 2 || parts.size() > 3)
    return false;

  if (parts[1].empty())
    return false;

  outAddress.transport = parts[0];
  outAddress.address = parts[1];

  if (parts.size() == 3)
  {
    outAddress.port = atoi(parts[2].c_str());
  }
  else
  {
    outAddress.port = 0;
    parts.push_back("0"); // hmmm
  }

  return isValidHostAndPort(outAddress.address, parts[2]);
}

bool isValidHostAndPort(const std::string& hostName, std::string& port)
{
  bool ret = true;
#ifdef _WIN32
  WSADATA WSAData;
  if(::WSAStartup(MAKEWORD(1, 0), &WSAData))
    ret = false;
#endif

  addrinfo req;
  memset(&req, 0, sizeof(req));
  req.ai_family = AF_INET;
  req.ai_socktype = SOCK_STREAM;
  req.ai_flags = AI_NUMERICSERV;
  addrinfo *res;

  if(getaddrinfo(hostName.c_str(), port.c_str(), &req, &res))
    ret = false; // lookup failed
  else
  {
    if (res == NULL)
      ret = false;
    else
      freeaddrinfo(res);
  }
#ifdef _WIN32
  WSACleanup();
#endif
  return ret;
}

std::vector<std::string> getIPAddresses()
{
  std::vector<std::string> ret;

#ifdef _WIN32
  // win version
  char szHostName[128] = "";

  WSADATA WSAData;
  if(::WSAStartup(MAKEWORD(1, 0), &WSAData))
    return ret;

  if(::gethostname(szHostName, sizeof(szHostName)))
    return ret;

  struct sockaddr_in socketAddress;
  struct hostent*    host = 0;

  host = ::gethostbyname(szHostName);
  if(!host)
    return ret;

  for(int i = 0; ((host->h_addr_list[i]) && (i < 10)); ++i)
  {
    memcpy(&socketAddress.sin_addr, host->h_addr_list[i], host->h_length);
    ret.push_back(inet_ntoa(socketAddress.sin_addr));
  }

  WSACleanup();
#else
  // linux version
  struct ifaddrs *ifaddr, *ifa;
  int family, s;
  char host[NI_MAXHOST];

  if (getifaddrs(&ifaddr) == -1)
    return ret;

  for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
  {
    if (ifa->ifa_addr == NULL)
      continue;
    family = ifa->ifa_addr->sa_family;

    // Don't include AF_INET6 for the moment
    if (family == AF_INET)
    {
      s = getnameinfo(ifa->ifa_addr,
        (family == AF_INET) ? sizeof(struct sockaddr_in) :
        sizeof(struct sockaddr_in6),
        host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);

      if (s != 0)
        break;
      ret.push_back(host);
    }
  }

  freeifaddrs(ifaddr);
#endif
  return ret;
}

} // namespace detail
} // namespace qi
<commit_msg>Fix transport handling in address<commit_after>/*
*  Author(s):
*  - Chris  Kilner <ckilner@aldebaran-robotics.com>
*  - Cedric Gestes <gestes@aldebaran-robotics.com>
*
*  Copyright (C) 2010 Aldebaran Robotics
*/

#include "src/messaging/network/ip_address.hpp"
#include <boost/algorithm/string.hpp>

#ifdef _WIN32
#  include <windows.h>
#  include <winsock2.h>
#  include <iphlpapi.h>
#  include <Ws2tcpip.h>
#else
#  include <arpa/inet.h>
#  include <sys/socket.h>
#  include <netdb.h>
#  include <ifaddrs.h>
#  include <stdio.h>
#  include <stdlib.h>
#  include <unistd.h>
#endif

namespace qi {
namespace detail {

std::string getPrimaryPublicIPAddress()
{
  std::vector<std::string> ips = getIPAddresses();
  static const std::string ipLocalHost = "127.0.0.1";
  // todo: some logic to choose between good addresses
  for (unsigned int i = 0; i< ips.size(); i++)
  {
    if (ipLocalHost.compare(ips[i]) != 0)
      return ips[i];
  }
  return "";
}

bool isValidAddress(const std::string& userHostString,
  Address& outAddress)
{
  if (userHostString.empty())
    return false;

  std::vector<std::string> parts;
  boost::split(parts, userHostString, boost::is_any_of(":/"));

  std::vector<std::string>::iterator i = parts.begin();
  while (i != parts.end())
  {
    if (i->empty())
      parts.erase(i);
    else
      ++i;
  }

  if (parts.size() <= 2)
    parts.insert(parts.begin(), "tcp");

  if (parts.size() < 2 || parts.size() > 3)
    return false;

  if (parts[1].empty())
    return false;

  outAddress.transport = parts[0];
  outAddress.address = parts[1];

  if (parts.size() == 3)
  {
    outAddress.port = atoi(parts[2].c_str());
  }
  else
  {
    outAddress.port = 0;
    parts.push_back("0"); // hmmm
  }

  return isValidHostAndPort(outAddress.address, parts[2]);
}

bool isValidHostAndPort(const std::string& hostName, std::string& port)
{
  bool ret = true;
#ifdef _WIN32
  WSADATA WSAData;
  if(::WSAStartup(MAKEWORD(1, 0), &WSAData))
    ret = false;
#endif

  addrinfo req;
  memset(&req, 0, sizeof(req));
  req.ai_family = AF_INET;
  req.ai_socktype = SOCK_STREAM;
  req.ai_flags = AI_NUMERICSERV;
  addrinfo *res;

  if(getaddrinfo(hostName.c_str(), port.c_str(), &req, &res))
    ret = false; // lookup failed
  else
  {
    if (res == NULL)
      ret = false;
    else
      freeaddrinfo(res);
  }
#ifdef _WIN32
  WSACleanup();
#endif
  return ret;
}

std::vector<std::string> getIPAddresses()
{
  std::vector<std::string> ret;

#ifdef _WIN32
  // win version
  char szHostName[128] = "";

  WSADATA WSAData;
  if(::WSAStartup(MAKEWORD(1, 0), &WSAData))
    return ret;

  if(::gethostname(szHostName, sizeof(szHostName)))
    return ret;

  struct sockaddr_in socketAddress;
  struct hostent*    host = 0;

  host = ::gethostbyname(szHostName);
  if(!host)
    return ret;

  for(int i = 0; ((host->h_addr_list[i]) && (i < 10)); ++i)
  {
    memcpy(&socketAddress.sin_addr, host->h_addr_list[i], host->h_length);
    ret.push_back(inet_ntoa(socketAddress.sin_addr));
  }

  WSACleanup();
#else
  // linux version
  struct ifaddrs *ifaddr, *ifa;
  int family, s;
  char host[NI_MAXHOST];

  if (getifaddrs(&ifaddr) == -1)
    return ret;

  for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
  {
    if (ifa->ifa_addr == NULL)
      continue;
    family = ifa->ifa_addr->sa_family;

    // Don't include AF_INET6 for the moment
    if (family == AF_INET)
    {
      s = getnameinfo(ifa->ifa_addr,
        (family == AF_INET) ? sizeof(struct sockaddr_in) :
        sizeof(struct sockaddr_in6),
        host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);

      if (s != 0)
        break;
      ret.push_back(host);
    }
  }

  freeifaddrs(ifaddr);
#endif
  return ret;
}

} // namespace detail
} // namespace qi
<|endoftext|>