<commit_before>//===-- MipsInstrInfo.cpp - Mips Instruction Information ------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the Mips implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//

#include "MipsInstrInfo.h"
#include "InstPrinter/MipsInstPrinter.h"
#include "MipsAnalyzeImmediate.h"
#include "MipsMachineFunction.h"
#include "MipsTargetMachine.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"

#define GET_INSTRINFO_CTOR
#include "MipsGenInstrInfo.inc"

using namespace llvm;

MipsInstrInfo::MipsInstrInfo(MipsTargetMachine &tm, unsigned UncondBr)
  : MipsGenInstrInfo(Mips::ADJCALLSTACKDOWN, Mips::ADJCALLSTACKUP),
    TM(tm), UncondBrOpc(UncondBr) {}

const MipsInstrInfo *MipsInstrInfo::create(MipsTargetMachine &TM) {
  if (TM.getSubtargetImpl()->inMips16Mode())
    return llvm::createMips16InstrInfo(TM);

  return llvm::createMipsSEInstrInfo(TM);
}

bool MipsInstrInfo::isZeroImm(const MachineOperand &op) const {
  return op.isImm() && op.getImm() == 0;
}

/// insertNoop - If data hazard condition is found insert the target nop
/// instruction.
void MipsInstrInfo::
insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const
{
  DebugLoc DL;
  BuildMI(MBB, MI, DL, get(Mips::NOP));
}

MachineMemOperand *MipsInstrInfo::GetMemOperand(MachineBasicBlock &MBB, int FI,
                                                unsigned Flag) const {
  MachineFunction &MF = *MBB.getParent();
  MachineFrameInfo &MFI = *MF.getFrameInfo();
  unsigned Align = MFI.getObjectAlignment(FI);

  return MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FI), Flag,
                                 MFI.getObjectSize(FI), Align);
}

MachineInstr*
MipsInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx,
                                        uint64_t Offset, const MDNode *MDPtr,
                                        DebugLoc DL) const {
  MachineInstrBuilder MIB = BuildMI(MF, DL, get(Mips::DBG_VALUE))
    .addFrameIndex(FrameIx).addImm(0).addImm(Offset).addMetadata(MDPtr);
  return &*MIB;
}

//===----------------------------------------------------------------------===//
// Branch Analysis
//===----------------------------------------------------------------------===//

void MipsInstrInfo::AnalyzeCondBr(const MachineInstr *Inst, unsigned Opc,
                                  MachineBasicBlock *&BB,
                                  SmallVectorImpl<MachineOperand> &Cond) const {
  assert(GetAnalyzableBrOpc(Opc) && "Not an analyzable branch");
  int NumOp = Inst->getNumExplicitOperands();

  // for both int and fp branches, the last explicit operand is the
  // MBB.
  BB = Inst->getOperand(NumOp-1).getMBB();
  Cond.push_back(MachineOperand::CreateImm(Opc));

  for (int i=0; i<NumOp-1; i++)
    Cond.push_back(Inst->getOperand(i));
}

bool MipsInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
                                  MachineBasicBlock *&TBB,
                                  MachineBasicBlock *&FBB,
                                  SmallVectorImpl<MachineOperand> &Cond,
                                  bool AllowModify) const {
  SmallVector<MachineInstr*, 2> BranchInstrs;
  BranchType BT = AnalyzeBranch(MBB, TBB, FBB, Cond, AllowModify, BranchInstrs);

  return (BT == BT_None) || (BT == BT_Indirect);
}

void MipsInstrInfo::BuildCondBr(MachineBasicBlock &MBB,
                                MachineBasicBlock *TBB, DebugLoc DL,
                                const SmallVectorImpl<MachineOperand>& Cond)
  const {
  unsigned Opc = Cond[0].getImm();
  const MCInstrDesc &MCID = get(Opc);
  MachineInstrBuilder MIB = BuildMI(&MBB, DL, MCID);

  for (unsigned i = 1; i < Cond.size(); ++i) {
    if (Cond[i].isReg())
      MIB.addReg(Cond[i].getReg());
    else if (Cond[i].isImm())
      MIB.addImm(Cond[i].getImm());
    else
       assert(true && "Cannot copy operand");
  }
  MIB.addMBB(TBB);
}

unsigned MipsInstrInfo::
InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
             MachineBasicBlock *FBB,
             const SmallVectorImpl<MachineOperand> &Cond,
             DebugLoc DL) const {
  // Shouldn't be a fall through.
  assert(TBB && "InsertBranch must not be told to insert a fallthrough");

  // # of condition operands:
  //  Unconditional branches: 0
  //  Floating point branches: 1 (opc)
  //  Int BranchZero: 2 (opc, reg)
  //  Int Branch: 3 (opc, reg0, reg1)
  assert((Cond.size() <= 3) &&
         "# of Mips branch conditions must be <= 3!");

  // Two-way Conditional branch.
  if (FBB) {
    BuildCondBr(MBB, TBB, DL, Cond);
    BuildMI(&MBB, DL, get(UncondBrOpc)).addMBB(FBB);
    return 2;
  }

  // One way branch.
  // Unconditional branch.
  if (Cond.empty())
    BuildMI(&MBB, DL, get(UncondBrOpc)).addMBB(TBB);
  else // Conditional branch.
    BuildCondBr(MBB, TBB, DL, Cond);
  return 1;
}

unsigned MipsInstrInfo::
RemoveBranch(MachineBasicBlock &MBB) const
{
  MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend();
  MachineBasicBlock::reverse_iterator FirstBr;
  unsigned removed;

  // Skip all the debug instructions.
  while (I != REnd && I->isDebugValue())
    ++I;

  FirstBr = I;

  // Up to 2 branches are removed.
  // Note that indirect branches are not removed.
  for(removed = 0; I != REnd && removed < 2; ++I, ++removed)
    if (!GetAnalyzableBrOpc(I->getOpcode()))
      break;

  MBB.erase(I.base(), FirstBr.base());

  return removed;
}

/// ReverseBranchCondition - Return the inverse opcode of the
/// specified Branch instruction.
bool MipsInstrInfo::
ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const
{
  assert( (Cond.size() && Cond.size() <= 3) &&
          "Invalid Mips branch condition!");
  Cond[0].setImm(GetOppositeBranchOpc(Cond[0].getImm()));
  return false;
}

MipsInstrInfo::BranchType MipsInstrInfo::
AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
              MachineBasicBlock *&FBB, SmallVectorImpl<MachineOperand> &Cond,
              bool AllowModify,
              SmallVectorImpl<MachineInstr*> &BranchInstrs) const {

  MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend();

  // Skip all the debug instructions.
  while (I != REnd && I->isDebugValue())
    ++I;

  if (I == REnd || !isUnpredicatedTerminator(&*I)) {
    // This block ends with no branches (it just falls through to its succ).
    // Leave TBB/FBB null.
    TBB = FBB = NULL;
    return BT_NoBranch;
  }

  MachineInstr *LastInst = &*I;
  unsigned LastOpc = LastInst->getOpcode();
  BranchInstrs.push_back(LastInst);

  // Not an analyzable branch (e.g., indirect jump).
  if (!GetAnalyzableBrOpc(LastOpc))
    return LastInst->isIndirectBranch() ? BT_Indirect : BT_None;

  // Get the second to last instruction in the block.
  unsigned SecondLastOpc = 0;
  MachineInstr *SecondLastInst = NULL;

  if (++I != REnd) {
    SecondLastInst = &*I;
    SecondLastOpc = GetAnalyzableBrOpc(SecondLastInst->getOpcode());

    // Not an analyzable branch (must be an indirect jump).
    if (isUnpredicatedTerminator(SecondLastInst) && !SecondLastOpc)
      return BT_None;
  }

  BranchInstrs.insert(BranchInstrs.begin(), SecondLastInst);

  // If there is only one terminator instruction, process it.
  if (!SecondLastOpc) {
    // Unconditional branch
    if (LastOpc == UncondBrOpc) {
      TBB = LastInst->getOperand(0).getMBB();
      return BT_Uncond;
    }

    // Conditional branch
    AnalyzeCondBr(LastInst, LastOpc, TBB, Cond);
    return BT_Cond;
  }

  // If we reached here, there are two branches.
  // If there are three terminators, we don't know what sort of block this is.
  if (++I != REnd && isUnpredicatedTerminator(&*I))
    return BT_None;

  // If second to last instruction is an unconditional branch,
  // analyze it and remove the last instruction.
  if (SecondLastOpc == UncondBrOpc) {
    // Return if the last instruction cannot be removed.
    if (!AllowModify)
      return BT_None;

    TBB = SecondLastInst->getOperand(0).getMBB();
    LastInst->eraseFromParent();
    BranchInstrs.pop_back();
    return BT_Uncond;
  }

  // Conditional branch followed by an unconditional branch.
  // The last one must be unconditional.
  if (LastOpc != UncondBrOpc)
    return BT_None;

  AnalyzeCondBr(SecondLastInst, SecondLastOpc, TBB, Cond);
  FBB = LastInst->getOperand(0).getMBB();

  return BT_CondUncond;
}

/// Return the number of bytes of code the specified instruction may be.
unsigned MipsInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
  switch (MI->getOpcode()) {
  default:
    return MI->getDesc().getSize();
  case  TargetOpcode::INLINEASM: {       // Inline Asm: Variable size.
    const MachineFunction *MF = MI->getParent()->getParent();
    const char *AsmStr = MI->getOperand(0).getSymbolName();
    return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
  }
  }
}
<commit_msg>[mips] Do not add SecondLastInst to list BranchInstrs if there is only one terminator.<commit_after>//===-- MipsInstrInfo.cpp - Mips Instruction Information ------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the Mips implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//

#include "MipsInstrInfo.h"
#include "InstPrinter/MipsInstPrinter.h"
#include "MipsAnalyzeImmediate.h"
#include "MipsMachineFunction.h"
#include "MipsTargetMachine.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"

#define GET_INSTRINFO_CTOR
#include "MipsGenInstrInfo.inc"

using namespace llvm;

MipsInstrInfo::MipsInstrInfo(MipsTargetMachine &tm, unsigned UncondBr)
  : MipsGenInstrInfo(Mips::ADJCALLSTACKDOWN, Mips::ADJCALLSTACKUP),
    TM(tm), UncondBrOpc(UncondBr) {}

const MipsInstrInfo *MipsInstrInfo::create(MipsTargetMachine &TM) {
  if (TM.getSubtargetImpl()->inMips16Mode())
    return llvm::createMips16InstrInfo(TM);

  return llvm::createMipsSEInstrInfo(TM);
}

bool MipsInstrInfo::isZeroImm(const MachineOperand &op) const {
  return op.isImm() && op.getImm() == 0;
}

/// insertNoop - If data hazard condition is found insert the target nop
/// instruction.
void MipsInstrInfo::
insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const
{
  DebugLoc DL;
  BuildMI(MBB, MI, DL, get(Mips::NOP));
}

MachineMemOperand *MipsInstrInfo::GetMemOperand(MachineBasicBlock &MBB, int FI,
                                                unsigned Flag) const {
  MachineFunction &MF = *MBB.getParent();
  MachineFrameInfo &MFI = *MF.getFrameInfo();
  unsigned Align = MFI.getObjectAlignment(FI);

  return MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FI), Flag,
                                 MFI.getObjectSize(FI), Align);
}

MachineInstr*
MipsInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx,
                                        uint64_t Offset, const MDNode *MDPtr,
                                        DebugLoc DL) const {
  MachineInstrBuilder MIB = BuildMI(MF, DL, get(Mips::DBG_VALUE))
    .addFrameIndex(FrameIx).addImm(0).addImm(Offset).addMetadata(MDPtr);
  return &*MIB;
}

//===----------------------------------------------------------------------===//
// Branch Analysis
//===----------------------------------------------------------------------===//

void MipsInstrInfo::AnalyzeCondBr(const MachineInstr *Inst, unsigned Opc,
                                  MachineBasicBlock *&BB,
                                  SmallVectorImpl<MachineOperand> &Cond) const {
  assert(GetAnalyzableBrOpc(Opc) && "Not an analyzable branch");
  int NumOp = Inst->getNumExplicitOperands();

  // for both int and fp branches, the last explicit operand is the
  // MBB.
  BB = Inst->getOperand(NumOp-1).getMBB();
  Cond.push_back(MachineOperand::CreateImm(Opc));

  for (int i=0; i<NumOp-1; i++)
    Cond.push_back(Inst->getOperand(i));
}

bool MipsInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
                                  MachineBasicBlock *&TBB,
                                  MachineBasicBlock *&FBB,
                                  SmallVectorImpl<MachineOperand> &Cond,
                                  bool AllowModify) const {
  SmallVector<MachineInstr*, 2> BranchInstrs;
  BranchType BT = AnalyzeBranch(MBB, TBB, FBB, Cond, AllowModify, BranchInstrs);

  return (BT == BT_None) || (BT == BT_Indirect);
}

void MipsInstrInfo::BuildCondBr(MachineBasicBlock &MBB,
                                MachineBasicBlock *TBB, DebugLoc DL,
                                const SmallVectorImpl<MachineOperand>& Cond)
  const {
  unsigned Opc = Cond[0].getImm();
  const MCInstrDesc &MCID = get(Opc);
  MachineInstrBuilder MIB = BuildMI(&MBB, DL, MCID);

  for (unsigned i = 1; i < Cond.size(); ++i) {
    if (Cond[i].isReg())
      MIB.addReg(Cond[i].getReg());
    else if (Cond[i].isImm())
      MIB.addImm(Cond[i].getImm());
    else
       assert(true && "Cannot copy operand");
  }
  MIB.addMBB(TBB);
}

unsigned MipsInstrInfo::
InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
             MachineBasicBlock *FBB,
             const SmallVectorImpl<MachineOperand> &Cond,
             DebugLoc DL) const {
  // Shouldn't be a fall through.
  assert(TBB && "InsertBranch must not be told to insert a fallthrough");

  // # of condition operands:
  //  Unconditional branches: 0
  //  Floating point branches: 1 (opc)
  //  Int BranchZero: 2 (opc, reg)
  //  Int Branch: 3 (opc, reg0, reg1)
  assert((Cond.size() <= 3) &&
         "# of Mips branch conditions must be <= 3!");

  // Two-way Conditional branch.
  if (FBB) {
    BuildCondBr(MBB, TBB, DL, Cond);
    BuildMI(&MBB, DL, get(UncondBrOpc)).addMBB(FBB);
    return 2;
  }

  // One way branch.
  // Unconditional branch.
  if (Cond.empty())
    BuildMI(&MBB, DL, get(UncondBrOpc)).addMBB(TBB);
  else // Conditional branch.
    BuildCondBr(MBB, TBB, DL, Cond);
  return 1;
}

unsigned MipsInstrInfo::
RemoveBranch(MachineBasicBlock &MBB) const
{
  MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend();
  MachineBasicBlock::reverse_iterator FirstBr;
  unsigned removed;

  // Skip all the debug instructions.
  while (I != REnd && I->isDebugValue())
    ++I;

  FirstBr = I;

  // Up to 2 branches are removed.
  // Note that indirect branches are not removed.
  for(removed = 0; I != REnd && removed < 2; ++I, ++removed)
    if (!GetAnalyzableBrOpc(I->getOpcode()))
      break;

  MBB.erase(I.base(), FirstBr.base());

  return removed;
}

/// ReverseBranchCondition - Return the inverse opcode of the
/// specified Branch instruction.
bool MipsInstrInfo::
ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const
{
  assert( (Cond.size() && Cond.size() <= 3) &&
          "Invalid Mips branch condition!");
  Cond[0].setImm(GetOppositeBranchOpc(Cond[0].getImm()));
  return false;
}

MipsInstrInfo::BranchType MipsInstrInfo::
AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
              MachineBasicBlock *&FBB, SmallVectorImpl<MachineOperand> &Cond,
              bool AllowModify,
              SmallVectorImpl<MachineInstr*> &BranchInstrs) const {

  MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend();

  // Skip all the debug instructions.
  while (I != REnd && I->isDebugValue())
    ++I;

  if (I == REnd || !isUnpredicatedTerminator(&*I)) {
    // This block ends with no branches (it just falls through to its succ).
    // Leave TBB/FBB null.
    TBB = FBB = NULL;
    return BT_NoBranch;
  }

  MachineInstr *LastInst = &*I;
  unsigned LastOpc = LastInst->getOpcode();
  BranchInstrs.push_back(LastInst);

  // Not an analyzable branch (e.g., indirect jump).
  if (!GetAnalyzableBrOpc(LastOpc))
    return LastInst->isIndirectBranch() ? BT_Indirect : BT_None;

  // Get the second to last instruction in the block.
  unsigned SecondLastOpc = 0;
  MachineInstr *SecondLastInst = NULL;

  if (++I != REnd) {
    SecondLastInst = &*I;
    SecondLastOpc = GetAnalyzableBrOpc(SecondLastInst->getOpcode());

    // Not an analyzable branch (must be an indirect jump).
    if (isUnpredicatedTerminator(SecondLastInst) && !SecondLastOpc)
      return BT_None;
  }

  // If there is only one terminator instruction, process it.
  if (!SecondLastOpc) {
    // Unconditional branch
    if (LastOpc == UncondBrOpc) {
      TBB = LastInst->getOperand(0).getMBB();
      return BT_Uncond;
    }

    // Conditional branch
    AnalyzeCondBr(LastInst, LastOpc, TBB, Cond);
    return BT_Cond;
  }

  // If we reached here, there are two branches.
  // If there are three terminators, we don't know what sort of block this is.
  if (++I != REnd && isUnpredicatedTerminator(&*I))
    return BT_None;

  BranchInstrs.insert(BranchInstrs.begin(), SecondLastInst);

  // If second to last instruction is an unconditional branch,
  // analyze it and remove the last instruction.
  if (SecondLastOpc == UncondBrOpc) {
    // Return if the last instruction cannot be removed.
    if (!AllowModify)
      return BT_None;

    TBB = SecondLastInst->getOperand(0).getMBB();
    LastInst->eraseFromParent();
    BranchInstrs.pop_back();
    return BT_Uncond;
  }

  // Conditional branch followed by an unconditional branch.
  // The last one must be unconditional.
  if (LastOpc != UncondBrOpc)
    return BT_None;

  AnalyzeCondBr(SecondLastInst, SecondLastOpc, TBB, Cond);
  FBB = LastInst->getOperand(0).getMBB();

  return BT_CondUncond;
}

/// Return the number of bytes of code the specified instruction may be.
unsigned MipsInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
  switch (MI->getOpcode()) {
  default:
    return MI->getDesc().getSize();
  case  TargetOpcode::INLINEASM: {       // Inline Asm: Variable size.
    const MachineFunction *MF = MI->getParent()->getParent();
    const char *AsmStr = MI->getOperand(0).getSymbolName();
    return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
  }
  }
}
<|endoftext|>


<commit_before>//===-- X86ISelPattern.cpp - A pattern matching inst selector for X86 -----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines a pattern matching instruction selector for X86.
//
//  FIXME: we could allocate one big array of unsigneds to use as the backing
//         store for all of the nodes costs arrays.
//
//===----------------------------------------------------------------------===//

/// NOTE: This whole selector is completely disabled.  This is only retained
/// for historical interest and future work.  It will probably change
/// substantially in the future.
#if 0

#include "X86.h"
#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/DerivedTypes.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/SSARegMap.h"
#include "X86RegisterInfo.h"
#include <iostream>

// Include the generated instruction selector...
#include "X86GenInstrSelector.inc"
using namespace llvm;

namespace {
  struct ISel : public FunctionPass, SelectionDAGTargetBuilder {
    TargetMachine &TM;
    ISel(TargetMachine &tm) : TM(tm) {}
    int VarArgsFrameIndex;              // FrameIndex for start of varargs area

    bool runOnFunction(Function &Fn) {
      MachineFunction &MF = MachineFunction::construct(&Fn, TM);
      SelectionDAG DAG(MF, TM, *this);

      std::cerr << "\n\n\n=== "
                << DAG.getMachineFunction().getFunction()->getName() << "\n";

      DAG.dump();
      X86ISel(DAG).generateCode();
      std::cerr << "\n\n\n";
      return true;
    }

  public:  // Implementation of the SelectionDAGTargetBuilder class...
    /// expandArguments - Add nodes to the DAG to indicate how to load arguments
    /// off of the X86 stack.
    void expandArguments(SelectionDAG &SD);
    void expandCall(SelectionDAG &SD, CallInst &CI);
  };
}

void ISel::expandArguments(SelectionDAG &SD) {

  // Add DAG nodes to load the arguments...  On entry to a function on the X86,
  // the stack frame looks like this:
  //
  // [ESP] -- return address
  // [ESP + 4] -- first argument (leftmost lexically)
  // [ESP + 8] -- second argument, if first argument is four bytes in size
  //    ...
  //
  MachineFunction &F = SD.getMachineFunction();
  MachineFrameInfo *MFI = F.getFrameInfo();
  const Function &Fn = *F.getFunction();

  unsigned ArgOffset = 0;   // Frame mechanisms handle retaddr slot
  for (Function::const_aiterator I = Fn.abegin(), E = Fn.aend(); I != E; ++I) {
    MVT::ValueType ObjectVT = SD.getValueType(I->getType());
    unsigned ArgIncrement = 4;
    unsigned ObjSize;
    switch (ObjectVT) {
    default: assert(0 && "Unhandled argument type!");
    case MVT::i8:  ObjSize = 1;                break;
    case MVT::i16: ObjSize = 2;                break;
    case MVT::i32: ObjSize = 4;                break;
    case MVT::i64: ObjSize = ArgIncrement = 8; break;
    case MVT::f32: ObjSize = 4;                break;
    case MVT::f64: ObjSize = ArgIncrement = 8; break;
    }
    // Create the frame index object for this incoming parameter...
    int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);

    // Create the SelectionDAG nodes corresponding to a load from this parameter
    SelectionDAGNode *FIN = new SelectionDAGNode(ISD::FrameIndex, MVT::i32);
    FIN->addValue(new ReducedValue_FrameIndex_i32(FI));

    SelectionDAGNode *Arg
      = new SelectionDAGNode(ISD::Load, ObjectVT, F.begin(), FIN);

    // Add the SelectionDAGNodes to the SelectionDAG... note that there is no
    // reason to add chain nodes here.  We know that no loads ore stores will
    // ever alias these loads, so we are free to perform the load at any time in
    // the function
    SD.addNode(FIN);
    SD.addNodeForValue(Arg, I);

    ArgOffset += ArgIncrement;   // Move on to the next argument...
  }

  // If the function takes variable number of arguments, make a frame index for
  // the start of the first vararg value... for expansion of llvm.va_start.
  if (Fn.getFunctionType()->isVarArg())
    VarArgsFrameIndex = MFI->CreateFixedObject(1, ArgOffset);
}

void ISel::expandCall(SelectionDAG &SD, CallInst &CI) {
  assert(0 && "ISel::expandCall not implemented!");
}

/// createX86PatternInstructionSelector - This pass converts an LLVM function
/// into a machine code representation using pattern matching and a machine
/// description file.
///
FunctionPass *llvm::createX86PatternInstructionSelector(TargetMachine &TM) {
  return new ISel(TM);
}

#endif
<commit_msg>This file is now dead.<commit_after><|endoftext|>


<commit_before>// $Id: quadrature_build.C,v 1.9 2006-03-22 19:26:33 roystgnr Exp $

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

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

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes

// Local includes
#include "quadrature_gauss.h"
#include "quadrature_jacobi.h"
#include "quadrature_simpson.h"
#include "quadrature_trap.h"

AutoPtr<QBase> QBase::build(const QuadratureType _qt,
			    const unsigned int _dim,
			    const Order _order)
{
  switch (_qt)
    {

    case QGAUSS:
      {

#ifdef DEBUG
	if (_order > FORTYTHIRD)
	  {
	    std::cout << "WARNING: Gauss quadrature implemented" << std::endl
		      << " up to FORTYTHIRD order." << std::endl;
	  }
#endif

	AutoPtr<QBase> ap(new QGauss(_dim, _order));
	return ap;
      }

    case QJACOBI_1_0:
      {

#ifdef DEBUG
	if (_order > TWENTYTHIRD)
	  {
	    std::cout << "WARNING: Jacobi(1,0) quadrature implemented" << std::endl
		      << " up to TWENTYTHIRD order." << std::endl;
	  }

	if (_dim > 1)
	  {
	    std::cout << "WARNING: Jacobi(1,0) quadrature implemented" << std::endl
		      << " in 1D only." << std::endl;
	  }
#endif

	AutoPtr<QBase> ap(new QJacobi(_dim, _order, 1, 0));
	return ap;
      }

    case QJACOBI_2_0:
      {

#ifdef DEBUG
	if (_order > TWENTYTHIRD)
	  {
	    std::cout << "WARNING: Jacobi(2,0) quadrature implemented" << std::endl
		      << " up to TWENTYTHIRD order." << std::endl;
	  }

	if (_dim > 1)
	  {
	    std::cout << "WARNING: Jacobi(2,0) quadrature implemented" << std::endl
		      << " in 1D only." << std::endl;
	  }
#endif

	AutoPtr<QBase> ap(new QJacobi(_dim, _order, 2, 0));
	return ap;
      }

    case QSIMPSON:
      {

#ifdef DEBUG
	if (_order > THIRD)
	  {
	    std::cout << "WARNING: Simpson rule provides only" << std::endl
		      << " THIRD order!" << std::endl;
	  }
#endif

	AutoPtr<QBase> ap(new QSimpson(_dim));
	return ap;
      }

    case QTRAP:
      {

#ifdef DEBUG
	if (_order > FIRST)
	  {
	    std::cout << "WARNING: Trapezoidal rule provides only" << std::endl
		      << " FIRST order!" << std::endl;
	  }
#endif

	AutoPtr<QBase> ap(new QTrap(_dim));
	return ap;
      }

    default:
      {
	std::cerr << "ERROR: Bad qt=" << _qt << std::endl;
	error();
      }
    }

  error();
  AutoPtr<QBase> ap(NULL);
  return ap;
}

<commit_msg>Added Clough option to QBase::build()<commit_after>// $Id: quadrature_build.C,v 1.10 2006-03-27 23:50:42 roystgnr Exp $

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

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

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes

// Local includes
#include "quadrature_clough.h"
#include "quadrature_gauss.h"
#include "quadrature_jacobi.h"
#include "quadrature_simpson.h"
#include "quadrature_trap.h"

AutoPtr<QBase> QBase::build(const QuadratureType _qt,
			    const unsigned int _dim,
			    const Order _order)
{
  switch (_qt)
    {

    case QCLOUGH:
      {
#ifdef DEBUG
	if (_order > TWENTYTHIRD)
	  {
	    std::cout << "WARNING: Clough quadrature implemented" << std::endl
		      << " up to TWENTYTHIRD order." << std::endl;
	  }
#endif

	AutoPtr<QBase> ap(new QClough(_dim, _order));
	return ap;
      }

    case QGAUSS:
      {

#ifdef DEBUG
	if (_order > FORTYTHIRD)
	  {
	    std::cout << "WARNING: Gauss quadrature implemented" << std::endl
		      << " up to FORTYTHIRD order." << std::endl;
	  }
#endif

	AutoPtr<QBase> ap(new QGauss(_dim, _order));
	return ap;
      }

    case QJACOBI_1_0:
      {

#ifdef DEBUG
	if (_order > TWENTYTHIRD)
	  {
	    std::cout << "WARNING: Jacobi(1,0) quadrature implemented" << std::endl
		      << " up to TWENTYTHIRD order." << std::endl;
	  }

	if (_dim > 1)
	  {
	    std::cout << "WARNING: Jacobi(1,0) quadrature implemented" << std::endl
		      << " in 1D only." << std::endl;
	  }
#endif

	AutoPtr<QBase> ap(new QJacobi(_dim, _order, 1, 0));
	return ap;
      }

    case QJACOBI_2_0:
      {

#ifdef DEBUG
	if (_order > TWENTYTHIRD)
	  {
	    std::cout << "WARNING: Jacobi(2,0) quadrature implemented" << std::endl
		      << " up to TWENTYTHIRD order." << std::endl;
	  }

	if (_dim > 1)
	  {
	    std::cout << "WARNING: Jacobi(2,0) quadrature implemented" << std::endl
		      << " in 1D only." << std::endl;
	  }
#endif

	AutoPtr<QBase> ap(new QJacobi(_dim, _order, 2, 0));
	return ap;
      }

    case QSIMPSON:
      {

#ifdef DEBUG
	if (_order > THIRD)
	  {
	    std::cout << "WARNING: Simpson rule provides only" << std::endl
		      << " THIRD order!" << std::endl;
	  }
#endif

	AutoPtr<QBase> ap(new QSimpson(_dim));
	return ap;
      }

    case QTRAP:
      {

#ifdef DEBUG
	if (_order > FIRST)
	  {
	    std::cout << "WARNING: Trapezoidal rule provides only" << std::endl
		      << " FIRST order!" << std::endl;
	  }
#endif

	AutoPtr<QBase> ap(new QTrap(_dim));
	return ap;
      }

    default:
      {
	std::cerr << "ERROR: Bad qt=" << _qt << std::endl;
	error();
      }
    }

  error();
  AutoPtr<QBase> ap(NULL);
  return ap;
}

<|endoftext|>


<commit_before>// Halide tutorial lesson 10: AOT compilation part 1

// This lesson demonstrates how to use Halide as an more traditional
// ahead-of-time (AOT) compiler.

// This lesson is split across two files. The first (this one), builds
// a Halide pipeline and compiles it to an object file and header. The
// second (lesson_10_aot_compilation_run.cpp), uses that object file
// to actually run the pipeline. This means that compiling this code
// is a multi-step process.

// On linux, you can compile and run it like so:
// g++ lesson_10*generate.cpp -g -std=c++11 -I ../include -L ../bin -lHalide -lpthread -ldl -o lesson_10_generate
// LD_LIBRARY_PATH=../bin ./lesson_10_generate
// g++ lesson_10*run.cpp lesson_10_halide.o -lpthread -o lesson_10_run
// ./lesson_10_run

// On os x:
// g++ lesson_10*generate.cpp -g -std=c++11 -I ../include -L ../bin -lHalide -o lesson_10_generate
// DYLD_LIBRARY_PATH=../bin ./lesson_10_generate
// g++ lesson_10*run.cpp lesson_10_halide.o -o lesson_10_run
// ./lesson_10_run

// The benefits of this approach are that the final program:
// - Doesn't do any jit compilation at runtime, so it's fast.
// - Doesn't depend on libHalide at all, so it's a small, easy-to-deploy binary.

// If you have the entire Halide source tree, you can also build it by
// running:
//    make tutorial_lesson_10_aot_compilation_run
// in a shell with the current directory at the top of the halide
// source tree.

#include "Halide.h"
#include <stdio.h>
using namespace Halide;

int main(int argc, char **argv) {

    // We'll define a simple one-stage pipeline:
    Func brighter;
    Var x, y;

    // The pipeline will depend on one scalar parameter.
    Param<uint8_t> offset;

    // And take one grayscale 8-bit input buffer. The first
    // constructor argument gives the type of a pixel, and the second
    // specifies the number of dimensions (not the number of
    // channels!). For a grayscale image this is two; for a color
    // image it's three. Currently, four dimensions is the maximum for
    // inputs and outputs.
    ImageParam input(type_of<uint8_t>(), 2);

    // If we were jit-compiling, these would just be an int and an
    // Image, but because we want to compile the pipeline once and
    // have it work for any value of the parameter, we need to make a
    // Param object, which can be used like an Expr, and an ImageParam
    // object, which can be used like an Image.

    // Define the Func.
    brighter(x, y) = input(x, y) + offset;

    // Schedule it.
    brighter.vectorize(x, 16).parallel(y);

    // This time, instead of calling brighter.realize(...), which
    // would compile and run the pipeline immediately, we'll call a
    // method that compiles the pipeline to a static library and header.
    //
    // For AOT-compiled code, we need to explicitly declare the
    // arguments to the routine. This routine takes two. Arguments are
    // usually Params or ImageParams.
    std::vector<Argument> args = {input, offset};
    brighter.compile_to_static_library("lesson_10_halide", args);

    // If you're using C++11, you can just say:
    // brighter.compile_to_static_library("lesson_10_halide", {input, offset});

    printf("Halide pipeline compiled, but not yet run.\n");

    // To continue this lesson, look in the file lesson_10_aot_compilation_run.cpp

    return 0;
}
<commit_msg>Fix comment in lesson 10<commit_after>// Halide tutorial lesson 10: AOT compilation part 1

// This lesson demonstrates how to use Halide as an more traditional
// ahead-of-time (AOT) compiler.

// This lesson is split across two files. The first (this one), builds
// a Halide pipeline and compiles it to an object file and header. The
// second (lesson_10_aot_compilation_run.cpp), uses that object file
// to actually run the pipeline. This means that compiling this code
// is a multi-step process.

// On linux, you can compile and run it like so:
// g++ lesson_10*generate.cpp -g -std=c++11 -I ../include -L ../bin -lHalide -lpthread -ldl -o lesson_10_generate
// LD_LIBRARY_PATH=../bin ./lesson_10_generate
// g++ lesson_10*run.cpp lesson_10_halide.o -lpthread -ldl -o lesson_10_run
// ./lesson_10_run

// On os x:
// g++ lesson_10*generate.cpp -g -std=c++11 -I ../include -L ../bin -lHalide -o lesson_10_generate
// DYLD_LIBRARY_PATH=../bin ./lesson_10_generate
// g++ lesson_10*run.cpp lesson_10_halide.o -o lesson_10_run
// ./lesson_10_run

// The benefits of this approach are that the final program:
// - Doesn't do any jit compilation at runtime, so it's fast.
// - Doesn't depend on libHalide at all, so it's a small, easy-to-deploy binary.

// If you have the entire Halide source tree, you can also build it by
// running:
//    make tutorial_lesson_10_aot_compilation_run
// in a shell with the current directory at the top of the halide
// source tree.

#include "Halide.h"
#include <stdio.h>
using namespace Halide;

int main(int argc, char **argv) {

    // We'll define a simple one-stage pipeline:
    Func brighter;
    Var x, y;

    // The pipeline will depend on one scalar parameter.
    Param<uint8_t> offset;

    // And take one grayscale 8-bit input buffer. The first
    // constructor argument gives the type of a pixel, and the second
    // specifies the number of dimensions (not the number of
    // channels!). For a grayscale image this is two; for a color
    // image it's three. Currently, four dimensions is the maximum for
    // inputs and outputs.
    ImageParam input(type_of<uint8_t>(), 2);

    // If we were jit-compiling, these would just be an int and an
    // Image, but because we want to compile the pipeline once and
    // have it work for any value of the parameter, we need to make a
    // Param object, which can be used like an Expr, and an ImageParam
    // object, which can be used like an Image.

    // Define the Func.
    brighter(x, y) = input(x, y) + offset;

    // Schedule it.
    brighter.vectorize(x, 16).parallel(y);

    // This time, instead of calling brighter.realize(...), which
    // would compile and run the pipeline immediately, we'll call a
    // method that compiles the pipeline to a static library and header.
    //
    // For AOT-compiled code, we need to explicitly declare the
    // arguments to the routine. This routine takes two. Arguments are
    // usually Params or ImageParams.
    std::vector<Argument> args = {input, offset};
    brighter.compile_to_static_library("lesson_10_halide", args);

    // If you're using C++11, you can just say:
    // brighter.compile_to_static_library("lesson_10_halide", {input, offset});

    printf("Halide pipeline compiled, but not yet run.\n");

    // To continue this lesson, look in the file lesson_10_aot_compilation_run.cpp

    return 0;
}
<|endoftext|>


<commit_before>/**
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 <netinet/tcp.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstdio>
#include <cerrno>
#include <netdb.h>
#include <iostream>
#include <string>

#include "io/validation.h"
#include "io/ClientSocket.h"

std::string Socket::HOSTNAME = Socket::getMyHostName(0);

Socket::Socket(const std::string &hostname, const uint16_t port,
		const uint16_t listeners = -1) :
		requested_hostname_(hostname), port_(port), addr_info_(0), socket_file_descriptor_(
				-1), socket_max_(0), listeners_(listeners), canonical_hostname_("") {
	logger_ = Logger::getLogger();
	FD_ZERO(&total_list_);
	FD_ZERO(&read_fds_);

}

Socket::Socket(const std::string &hostname, const uint16_t port) :
		::Socket(hostname, port, 0) {

}

Socket::Socket(const Socket &&other) :
		requested_hostname_(std::move(other.requested_hostname_)), port_(
				std::move(other.port_)), addr_info_(std::move(other.addr_info_)), socket_file_descriptor_(
				other.socket_file_descriptor_), socket_max_(
				other.socket_max_.load()), listeners_(other.listeners_), total_list_(
				other.total_list_), read_fds_(other.read_fds_), canonical_hostname_(
				std::move(other.canonical_hostname_)) {
	logger_ = Logger::getLogger();

}

Socket::~Socket() {
	closeStream();
}

void Socket::closeStream()
{
    if (0 != addr_info_) {
	    freeaddrinfo(addr_info_);
	    addr_info_=0;
    }

    if (socket_file_descriptor_ >= 0)
    {
	    close(socket_file_descriptor_);
	    socket_file_descriptor_ = -1;
    }
}

int8_t Socket::createConnection(const addrinfo *p) {
	if ((socket_file_descriptor_ = socket(p->ai_family, p->ai_socktype,
			p->ai_protocol)) == -1) {
		logger_->log_error("error while connecting to server socket");
		return -1;
	}

	setSocketOptions(socket_file_descriptor_);

	if (listeners_ > 0) {

		struct sockaddr_in *sa_loc = (struct sockaddr_in*) p->ai_addr;
		sa_loc->sin_family = AF_INET;
		sa_loc->sin_port = htons(port_);
		sa_loc->sin_addr.s_addr = htonl(INADDR_ANY);

		if (bind(socket_file_descriptor_, p->ai_addr, p->ai_addrlen) == -1) {
			logger_->log_error("Could not bind to socket", strerror(errno));
			return -1;
		}
	}
	{
	  if (listeners_ <=0 )
	  {
		struct sockaddr_in *sa_loc = (struct sockaddr_in*) p->ai_addr;
		sa_loc->sin_family = AF_INET;
		//sa_loc->sin_port = htons(port);
		sa_loc->sin_port = htons(port_);
		// use any address if you are connecting to the local machine for testing
		// otherwise we must use the requested hostname
		if (IsNullOrEmpty(requested_hostname_) || requested_hostname_=="localhost")
		  sa_loc->sin_addr.s_addr = htonl(INADDR_ANY);
		else
		  sa_loc->sin_addr.s_addr = inet_addr(requested_hostname_.c_str());
		if (connect(socket_file_descriptor_, p->ai_addr, p->ai_addrlen) == -1) {
			  close(socket_file_descriptor_);
				socket_file_descriptor_ = -1;
				logger_->log_warn("Could not connect to socket, error:%s", strerror(errno));
				return -1;

		}
	  }
	}

	// listen
	if (listeners_ > 0) {
		if (listen(socket_file_descriptor_, listeners_) == -1) {
			logger_->log_warn("attempted connection, saw %s", strerror(errno));
			return -1;
		}

	}
	// add the listener to the total set
	FD_SET(socket_file_descriptor_, &total_list_);
	socket_max_ = socket_file_descriptor_;
	return 0;
}

short Socket::initialize() {

	struct sockaddr_in servAddr;

	addrinfo hints = { sizeof(addrinfo) };
	memset(&hints, 0, sizeof hints); // make sure the struct is empty
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_CANONNAME;
	if (listeners_ > 0)
	    hints.ai_flags |= AI_PASSIVE;

	hints.ai_protocol = 0; /* any protocol */

	int errcode = getaddrinfo(requested_hostname_.c_str(), 0, &hints, &addr_info_);

	if (errcode != 0) {
		logger_->log_error("Saw error during getaddrinfo, error: %s",strerror(errno));
		return -1;
	}

	socket_file_descriptor_ = -1;

	auto p = addr_info_;
	for (; p != NULL; p = p->ai_next) {
		if (IsNullOrEmpty(canonical_hostname_)) {
			if (!IsNullOrEmpty(p) && !IsNullOrEmpty(p->ai_canonname))
				canonical_hostname_ = p->ai_canonname;
		}

		//we've successfully connected
		if (port_ > 0 && createConnection(p) >= 0)
		{
			return 0;
			break;
		}
	}

	return -1;

}

short Socket::select_descriptor(const uint16_t msec) {
	struct timeval tv;
	int retval;

	read_fds_ = total_list_;

	tv.tv_sec = msec / 1000;
	tv.tv_usec = (msec % 1000) * 1000;

	std::lock_guard<std::recursive_mutex> guard(selection_mutex_);

	if (msec > 0)
		retval = select(socket_max_ + 1, &read_fds_, NULL, NULL, &tv);
	else
		retval = select(socket_max_ + 1, &read_fds_, NULL, NULL, NULL);

	if (retval < 0) {
		logger_->log_error("Saw error during selection, error:%i %s",retval,strerror(errno));
		return retval;
	}

	for (int i = 0; i <= socket_max_; i++) {
		if (FD_ISSET(i, &read_fds_)) {

			if (i == socket_file_descriptor_) {
			  if (listeners_ > 0)
			  {
				struct sockaddr_storage remoteaddr; // client address
				socklen_t addrlen = sizeof remoteaddr;
				int newfd = accept(socket_file_descriptor_,
						(struct sockaddr *) &remoteaddr, &addrlen);
				FD_SET(newfd, &total_list_); // add to master set
				if (newfd > socket_max_) {    // keep track of the max
					socket_max_ = newfd;
				}
				return newfd;

			  }
			  else{
			    return socket_file_descriptor_;
			  }
				// we have a new connection
			} else {
				// data to be received on i
				return i;
			}
		}

	}

	return -1;
}

short Socket::setSocketOptions(const int sock) {
	int opt = 1;
	bool nagle_off = true;
#ifndef __MACH__
	if (nagle_off) {
		if (setsockopt(sock, SOL_TCP, TCP_NODELAY, (void *) &opt, sizeof(opt))
				< 0) {
			logger_->log_error("setsockopt() TCP_NODELAY failed");
			close(sock);
			return -1;
		}
		if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &opt,
						sizeof(opt)) < 0) {
			logger_->log_error("setsockopt() SO_REUSEADDR failed");
			close(sock);
			return -1;
		}
	}

	int sndsize = 256 * 1024;
	if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *) &sndsize,
					(int) sizeof(sndsize)) < 0) {
		logger_->log_error("setsockopt() SO_SNDBUF failed");
		close(sock);
		return -1;
	}

#else
	if (listeners_ > 0) {
		// lose the pesky "address already in use" error message
		if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &opt,
				sizeof(opt)) < 0) {
			logger_->log_error("setsockopt() SO_REUSEADDR failed");
			close(sock);
			return -1;
		}
	}
#endif
	return 0;
}

std::string Socket::getHostname() const {
	return canonical_hostname_;
}

int Socket::writeData(std::vector<uint8_t> &buf, int buflen) {

	if (buf.capacity() < buflen)
		return -1;
	return writeData((uint8_t*) &buf[0], buflen);
}

// data stream overrides

int Socket::writeData(uint8_t *value, int size) {

	int ret = 0, bytes = 0;

	while (bytes < size) {

		ret = send(socket_file_descriptor_, value + bytes, size - bytes, 0);
		//check for errors
		if (ret <= 0) {
			close(socket_file_descriptor_);
			logger_->log_error("Could not send to %d, error: %s",socket_file_descriptor_, strerror(errno));
			return ret;
		}
		bytes += ret;

	}

	if (ret)
		logger_->log_debug("Send data size %d over socket %d", size,
				socket_file_descriptor_);

	return bytes;

}

template<typename T>
inline std::vector<uint8_t> Socket::readBuffer(const T& t) {
	std::vector<uint8_t> buf;
	buf.resize(sizeof t);
	readData((uint8_t*) &buf[0], sizeof(t));
	return buf;
}

int Socket::write(uint64_t base_value, bool is_little_endian){

  return Serializable::write(base_value,this,is_little_endian);
}

int Socket::write(uint32_t base_value, bool is_little_endian){
  return Serializable::write(base_value,this,is_little_endian);
}

int Socket::write(uint16_t base_value, bool is_little_endian){
  return Serializable::write(base_value,this,is_little_endian);
}

int Socket::read(uint64_t &value, bool is_little_endian) {

	auto buf = readBuffer(value);

	if (is_little_endian) {
		value = ((uint64_t) buf[0] << 56) | ((uint64_t) (buf[1] & 255) << 48)
				| ((uint64_t) (buf[2] & 255) << 40)
				| ((uint64_t) (buf[3] & 255) << 32)
				| ((uint64_t) (buf[4] & 255) << 24)
				| ((uint64_t) (buf[5] & 255) << 16)
				| ((uint64_t) (buf[6] & 255) << 8)
				| ((uint64_t) (buf[7] & 255) << 0);
	} else {
		value = ((uint64_t) buf[0] << 0) | ((uint64_t) (buf[1] & 255) << 8)
				| ((uint64_t) (buf[2] & 255) << 16)
				| ((uint64_t) (buf[3] & 255) << 24)
				| ((uint64_t) (buf[4] & 255) << 32)
				| ((uint64_t) (buf[5] & 255) << 40)
				| ((uint64_t) (buf[6] & 255) << 48)
				| ((uint64_t) (buf[7] & 255) << 56);
	}
	return sizeof(value);
}

int Socket::read(uint32_t &value, bool is_little_endian) {

	auto buf = readBuffer(value);

	if (is_little_endian) {
		value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
	} else {
		value = buf[0] | buf[1] << 8 | buf[2] << 16 | buf[3] << 24;

	}

	return sizeof(value);
}

int Socket::read(uint16_t &value, bool is_little_endian) {

	auto buf = readBuffer(value);

	if (is_little_endian) {
		value = (buf[0] << 8) | buf[1];
	} else {
		value = buf[0] | buf[1] << 8;

	}
	return sizeof(value);
}

int Socket::readData(std::vector<uint8_t> &buf, int buflen) {

	if (buf.capacity() < buflen)
	{
	      buf.resize(buflen);
	}
	return readData((uint8_t*) &buf[0], buflen);
}

int Socket::readData(uint8_t *buf, int buflen) {

	int total_read = 0;
	while (buflen) {
		short fd = select_descriptor(1000);
		if (fd < 0) {

			logger_->log_info("fd close %i",buflen);
			close(socket_file_descriptor_);
			return -1;
		}

		int bytes_read = recv(fd, buf, buflen, 0);
		if (bytes_read <= 0) {
			if (bytes_read == 0)
				logger_->log_info("Other side hung up on %d", fd);
			else {
				logger_->log_error("Could not recv on %d, error: %s",fd, strerror(errno));
			}
			return -1;
		}

		buflen -= bytes_read;
		buf += bytes_read;
		total_read += bytes_read;
	}

	return total_read;
}
<commit_msg>MINIFI-235: Add curly braces per review<commit_after>/**
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 <netinet/tcp.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstdio>
#include <cerrno>
#include <netdb.h>
#include <iostream>
#include <string>

#include "io/validation.h"
#include "io/ClientSocket.h"

std::string Socket::HOSTNAME = Socket::getMyHostName(0);

Socket::Socket(const std::string &hostname, const uint16_t port,
		const uint16_t listeners = -1) :
		requested_hostname_(hostname), port_(port), addr_info_(0), socket_file_descriptor_(
				-1), socket_max_(0), listeners_(listeners), canonical_hostname_("") {
	logger_ = Logger::getLogger();
	FD_ZERO(&total_list_);
	FD_ZERO(&read_fds_);

}

Socket::Socket(const std::string &hostname, const uint16_t port) :
		::Socket(hostname, port, 0) {

}

Socket::Socket(const Socket &&other) :
		requested_hostname_(std::move(other.requested_hostname_)), port_(
				std::move(other.port_)), addr_info_(std::move(other.addr_info_)), socket_file_descriptor_(
				other.socket_file_descriptor_), socket_max_(
				other.socket_max_.load()), listeners_(other.listeners_), total_list_(
				other.total_list_), read_fds_(other.read_fds_), canonical_hostname_(
				std::move(other.canonical_hostname_)) {
	logger_ = Logger::getLogger();

}

Socket::~Socket() {
	closeStream();
}

void Socket::closeStream()
{
    if (0 != addr_info_) {
	    freeaddrinfo(addr_info_);
	    addr_info_=0;
    }

    if (socket_file_descriptor_ >= 0)
    {
	    close(socket_file_descriptor_);
	    socket_file_descriptor_ = -1;
    }
}

int8_t Socket::createConnection(const addrinfo *p) {
	if ((socket_file_descriptor_ = socket(p->ai_family, p->ai_socktype,
			p->ai_protocol)) == -1) {
		logger_->log_error("error while connecting to server socket");
		return -1;
	}

	setSocketOptions(socket_file_descriptor_);

	if (listeners_ > 0) {

		struct sockaddr_in *sa_loc = (struct sockaddr_in*) p->ai_addr;
		sa_loc->sin_family = AF_INET;
		sa_loc->sin_port = htons(port_);
		sa_loc->sin_addr.s_addr = htonl(INADDR_ANY);

		if (bind(socket_file_descriptor_, p->ai_addr, p->ai_addrlen) == -1) {
			logger_->log_error("Could not bind to socket", strerror(errno));
			return -1;
		}
	}
	{
	  if (listeners_ <=0 )
	  {
		struct sockaddr_in *sa_loc = (struct sockaddr_in*) p->ai_addr;
		sa_loc->sin_family = AF_INET;
		//sa_loc->sin_port = htons(port);
		sa_loc->sin_port = htons(port_);
		// use any address if you are connecting to the local machine for testing
		// otherwise we must use the requested hostname
		if (IsNullOrEmpty(requested_hostname_) || requested_hostname_=="localhost")
		{
		  sa_loc->sin_addr.s_addr = htonl(INADDR_ANY);
		}
		else
		{
		  sa_loc->sin_addr.s_addr = inet_addr(requested_hostname_.c_str());
		}
		if (connect(socket_file_descriptor_, p->ai_addr, p->ai_addrlen) == -1) {
			  close(socket_file_descriptor_);
				socket_file_descriptor_ = -1;
				logger_->log_warn("Could not connect to socket, error:%s", strerror(errno));
				return -1;

		}
	  }
	}

	// listen
	if (listeners_ > 0) {
		if (listen(socket_file_descriptor_, listeners_) == -1) {
			logger_->log_warn("attempted connection, saw %s", strerror(errno));
			return -1;
		}

	}
	// add the listener to the total set
	FD_SET(socket_file_descriptor_, &total_list_);
	socket_max_ = socket_file_descriptor_;
	return 0;
}

short Socket::initialize() {

	struct sockaddr_in servAddr;

	addrinfo hints = { sizeof(addrinfo) };
	memset(&hints, 0, sizeof hints); // make sure the struct is empty
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_CANONNAME;
	if (listeners_ > 0)
	    hints.ai_flags |= AI_PASSIVE;

	hints.ai_protocol = 0; /* any protocol */

	int errcode = getaddrinfo(requested_hostname_.c_str(), 0, &hints, &addr_info_);

	if (errcode != 0) {
		logger_->log_error("Saw error during getaddrinfo, error: %s",strerror(errno));
		return -1;
	}

	socket_file_descriptor_ = -1;

	auto p = addr_info_;
	for (; p != NULL; p = p->ai_next) {
		if (IsNullOrEmpty(canonical_hostname_)) {
			if (!IsNullOrEmpty(p) && !IsNullOrEmpty(p->ai_canonname))
				canonical_hostname_ = p->ai_canonname;
		}

		//we've successfully connected
		if (port_ > 0 && createConnection(p) >= 0)
		{
			return 0;
			break;
		}
	}

	return -1;

}

short Socket::select_descriptor(const uint16_t msec) {
	struct timeval tv;
	int retval;

	read_fds_ = total_list_;

	tv.tv_sec = msec / 1000;
	tv.tv_usec = (msec % 1000) * 1000;

	std::lock_guard<std::recursive_mutex> guard(selection_mutex_);

	if (msec > 0)
		retval = select(socket_max_ + 1, &read_fds_, NULL, NULL, &tv);
	else
		retval = select(socket_max_ + 1, &read_fds_, NULL, NULL, NULL);

	if (retval < 0) {
		logger_->log_error("Saw error during selection, error:%i %s",retval,strerror(errno));
		return retval;
	}

	for (int i = 0; i <= socket_max_; i++) {
		if (FD_ISSET(i, &read_fds_)) {

			if (i == socket_file_descriptor_) {
			  if (listeners_ > 0)
			  {
				struct sockaddr_storage remoteaddr; // client address
				socklen_t addrlen = sizeof remoteaddr;
				int newfd = accept(socket_file_descriptor_,
						(struct sockaddr *) &remoteaddr, &addrlen);
				FD_SET(newfd, &total_list_); // add to master set
				if (newfd > socket_max_) {    // keep track of the max
					socket_max_ = newfd;
				}
				return newfd;

			  }
			  else{
			    return socket_file_descriptor_;
			  }
				// we have a new connection
			} else {
				// data to be received on i
				return i;
			}
		}

	}

	return -1;
}

short Socket::setSocketOptions(const int sock) {
	int opt = 1;
	bool nagle_off = true;
#ifndef __MACH__
	if (nagle_off) {
		if (setsockopt(sock, SOL_TCP, TCP_NODELAY, (void *) &opt, sizeof(opt))
				< 0) {
			logger_->log_error("setsockopt() TCP_NODELAY failed");
			close(sock);
			return -1;
		}
		if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &opt,
						sizeof(opt)) < 0) {
			logger_->log_error("setsockopt() SO_REUSEADDR failed");
			close(sock);
			return -1;
		}
	}

	int sndsize = 256 * 1024;
	if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *) &sndsize,
					(int) sizeof(sndsize)) < 0) {
		logger_->log_error("setsockopt() SO_SNDBUF failed");
		close(sock);
		return -1;
	}

#else
	if (listeners_ > 0) {
		// lose the pesky "address already in use" error message
		if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &opt,
				sizeof(opt)) < 0) {
			logger_->log_error("setsockopt() SO_REUSEADDR failed");
			close(sock);
			return -1;
		}
	}
#endif
	return 0;
}

std::string Socket::getHostname() const {
	return canonical_hostname_;
}

int Socket::writeData(std::vector<uint8_t> &buf, int buflen) {

	if (buf.capacity() < buflen)
		return -1;
	return writeData((uint8_t*) &buf[0], buflen);
}

// data stream overrides

int Socket::writeData(uint8_t *value, int size) {

	int ret = 0, bytes = 0;

	while (bytes < size) {

		ret = send(socket_file_descriptor_, value + bytes, size - bytes, 0);
		//check for errors
		if (ret <= 0) {
			close(socket_file_descriptor_);
			logger_->log_error("Could not send to %d, error: %s",socket_file_descriptor_, strerror(errno));
			return ret;
		}
		bytes += ret;

	}

	if (ret)
		logger_->log_debug("Send data size %d over socket %d", size,
				socket_file_descriptor_);

	return bytes;

}

template<typename T>
inline std::vector<uint8_t> Socket::readBuffer(const T& t) {
	std::vector<uint8_t> buf;
	buf.resize(sizeof t);
	readData((uint8_t*) &buf[0], sizeof(t));
	return buf;
}

int Socket::write(uint64_t base_value, bool is_little_endian){

  return Serializable::write(base_value,this,is_little_endian);
}

int Socket::write(uint32_t base_value, bool is_little_endian){
  return Serializable::write(base_value,this,is_little_endian);
}

int Socket::write(uint16_t base_value, bool is_little_endian){
  return Serializable::write(base_value,this,is_little_endian);
}

int Socket::read(uint64_t &value, bool is_little_endian) {

	auto buf = readBuffer(value);

	if (is_little_endian) {
		value = ((uint64_t) buf[0] << 56) | ((uint64_t) (buf[1] & 255) << 48)
				| ((uint64_t) (buf[2] & 255) << 40)
				| ((uint64_t) (buf[3] & 255) << 32)
				| ((uint64_t) (buf[4] & 255) << 24)
				| ((uint64_t) (buf[5] & 255) << 16)
				| ((uint64_t) (buf[6] & 255) << 8)
				| ((uint64_t) (buf[7] & 255) << 0);
	} else {
		value = ((uint64_t) buf[0] << 0) | ((uint64_t) (buf[1] & 255) << 8)
				| ((uint64_t) (buf[2] & 255) << 16)
				| ((uint64_t) (buf[3] & 255) << 24)
				| ((uint64_t) (buf[4] & 255) << 32)
				| ((uint64_t) (buf[5] & 255) << 40)
				| ((uint64_t) (buf[6] & 255) << 48)
				| ((uint64_t) (buf[7] & 255) << 56);
	}
	return sizeof(value);
}

int Socket::read(uint32_t &value, bool is_little_endian) {

	auto buf = readBuffer(value);

	if (is_little_endian) {
		value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
	} else {
		value = buf[0] | buf[1] << 8 | buf[2] << 16 | buf[3] << 24;

	}

	return sizeof(value);
}

int Socket::read(uint16_t &value, bool is_little_endian) {

	auto buf = readBuffer(value);

	if (is_little_endian) {
		value = (buf[0] << 8) | buf[1];
	} else {
		value = buf[0] | buf[1] << 8;

	}
	return sizeof(value);
}

int Socket::readData(std::vector<uint8_t> &buf, int buflen) {

	if (buf.capacity() < buflen)
	{
	      buf.resize(buflen);
	}
	return readData((uint8_t*) &buf[0], buflen);
}

int Socket::readData(uint8_t *buf, int buflen) {

	int total_read = 0;
	while (buflen) {
		short fd = select_descriptor(1000);
		if (fd < 0) {

			logger_->log_info("fd close %i",buflen);
			close(socket_file_descriptor_);
			return -1;
		}

		int bytes_read = recv(fd, buf, buflen, 0);
		if (bytes_read <= 0) {
			if (bytes_read == 0)
				logger_->log_info("Other side hung up on %d", fd);
			else {
				logger_->log_error("Could not recv on %d, error: %s",fd, strerror(errno));
			}
			return -1;
		}

		buflen -= bytes_read;
		buf += bytes_read;
		total_read += bytes_read;
	}

	return total_read;
}
<|endoftext|>


<commit_before>/*
**
** Copyright (C) 2012 Aldebaran Robotics
*/

#include "src/metamethod_p.hpp"
#include <qimessaging/metamethod.hpp>

namespace qi {

  MetaMethod::MetaMethod()
  {
    _p = new MetaMethodPrivate();
  }

  MetaMethod::MetaMethod(const std::string &sig, const qi::Functor *functor)
  {
    _p = new MetaMethodPrivate(sig, functor);
  }

  MetaMethod::MetaMethod(const MetaMethod &other)
  {
    _p = new MetaMethodPrivate();
    *_p = *(other._p);
  }

  MetaMethod& MetaMethod::operator=(const MetaMethod &other)
  {
    _p = new MetaMethodPrivate();
    *_p = *(other._p);
    return (*this);
  }

  MetaMethod::~MetaMethod()
  {
    delete _p;
  }

  const std::string &MetaMethod::signature() const
  {
    return _p->signature();
  }

  const qi::Functor *MetaMethod::functor() const
  {
    return _p->_functor;
  }

  unsigned int       MetaMethod::index() const
  {
    return _p->index();
  }

};<commit_msg>metamethod: fix operator=<commit_after>/*
**
** Copyright (C) 2012 Aldebaran Robotics
*/

#include "src/metamethod_p.hpp"
#include <qimessaging/metamethod.hpp>

namespace qi {

  MetaMethod::MetaMethod()
    : _p(new MetaMethodPrivate())
  {
  }

  MetaMethod::MetaMethod(const std::string &sig, const qi::Functor *functor)
    : _p(new MetaMethodPrivate(sig, functor))
  {
  }

  MetaMethod::MetaMethod(const MetaMethod &other)
    : _p(new MetaMethodPrivate())
  {
    *_p = *(other._p);
  }

  MetaMethod& MetaMethod::operator=(const MetaMethod &other)
  {
    *_p = *(other._p);
    return (*this);
  }

  MetaMethod::~MetaMethod()
  {
    delete _p;
  }

  const std::string &MetaMethod::signature() const
  {
    return _p->signature();
  }

  const qi::Functor *MetaMethod::functor() const
  {
    return _p->_functor;
  }

  unsigned int       MetaMethod::index() const
  {
    return _p->index();
  }

};
<|endoftext|>


<commit_before>#include <robocup2Dsim/server/monitor.hpp>
#include <gtest/gtest.h>

namespace rse = robocup2Dsim::server;

TEST(clock_monitor_test, record_transmit_basic)
{
    rse::clock_monitor monitor(5);
    monitor.record_transmit();
    monitor.record_transmit();
    monitor.record_transmit();
    monitor.record_transmit();
    monitor.record_transmit();
    EXPECT_EQ(5, monitor.transmit_sample_size()) << "The number of recorded transmits is wrong";
    monitor.record_transmit();
    EXPECT_EQ(5, monitor.transmit_sample_size()) << "The number of recorded transmits is wrong";
    monitor.record_transmit();
    EXPECT_EQ(5, monitor.transmit_sample_size()) << "The number of recorded transmits is wrong";
}
<commit_msg>adding more test cases<commit_after>#include <robocup2Dsim/server/monitor.hpp>

#include <beam/internet/endpoint.hpp>
#include <gtest/gtest.h>

namespace bin = beam::internet;
namespace rse = robocup2Dsim::server;

TEST(clock_monitor_test, record_transmit_basic)
{
    rse::clock_monitor monitor(5);

    std::uint16_t seq1 = monitor.record_transmit();
    std::uint16_t seq2 = monitor.record_transmit();
    std::uint16_t seq3 = monitor.record_transmit();
    std::uint16_t seq4 = monitor.record_transmit();
    std::uint16_t seq5 = monitor.record_transmit();

    EXPECT_EQ(monitor.target_sample_size(), monitor.transmit_sample_size()) << "The number of recorded transmits is wrong";
    EXPECT_EQ(seq1 + 1, seq2) << "The sequence number is not increasing on next transmit";
    EXPECT_EQ(seq2 + 1, seq3) << "The sequence number is not increasing on next transmit";
    EXPECT_EQ(seq3 + 1, seq4) << "The sequence number is not increasing on next transmit";
    EXPECT_EQ(seq4 + 1, seq5) << "The sequence number is not increasing on next transmit";

    monitor.record_transmit();
    EXPECT_EQ(monitor.target_sample_size(), monitor.transmit_sample_size()) << "The number of recorded transmits is wrong";

    monitor.record_transmit();
    EXPECT_EQ(monitor.target_sample_size(), monitor.transmit_sample_size()) << "The number of recorded transmits is wrong";
}

TEST(clock_monitor_test, record_receive_basic)
{
    const bin::endpoint_id endpoint(99);
    rse::clock_monitor monitor(5);

    monitor.record_receive(endpoint, 1, std::chrono::steady_clock::now());
    monitor.record_receive(endpoint, 2, std::chrono::steady_clock::now());
    monitor.record_receive(endpoint, 3, std::chrono::steady_clock::now());
    monitor.record_receive(endpoint, 4, std::chrono::steady_clock::now());
    monitor.record_receive(endpoint, 5, std::chrono::steady_clock::now());

    EXPECT_EQ(monitor.target_sample_size(), monitor.receive_sample_size(endpoint)) << "The number of recorded receives is wrong";
    EXPECT_EQ(1, monitor.oldest_receive()) << "The oldest receive calculation is wrong";

    monitor.record_receive(endpoint, 6, std::chrono::steady_clock::now());
    EXPECT_EQ(monitor.target_sample_size(), monitor.receive_sample_size(endpoint)) << "The number of recorded receives is wrong";
    EXPECT_EQ(2, monitor.oldest_receive()) << "The oldest receive calculation is wrong";

    monitor.record_receive(endpoint, 7, std::chrono::steady_clock::now());
    EXPECT_EQ(monitor.target_sample_size(), monitor.receive_sample_size(endpoint)) << "The number of recorded receives is wrong";
    EXPECT_EQ(3, monitor.oldest_receive()) << "The oldest receive calculation is wrong";
}

TEST(clock_monitor_test, needed_sequence_kept_single_client)
{
    const bin::endpoint_id endpoint(99);
    rse::clock_monitor monitor(5);

    std::uint16_t seq1 = monitor.record_transmit();
    std::uint16_t seq2 = monitor.record_transmit();
    std::uint16_t seq3 = monitor.record_transmit();
    std::uint16_t seq4 = monitor.record_transmit();
    std::uint16_t seq5 = monitor.record_transmit();
    monitor.record_receive(endpoint, seq1, std::chrono::steady_clock::now());
    monitor.record_receive(endpoint, seq2, std::chrono::steady_clock::now());
    monitor.record_receive(endpoint, seq3, std::chrono::steady_clock::now());
    monitor.record_receive(endpoint, seq4, std::chrono::steady_clock::now());
    monitor.record_receive(endpoint, seq5, std::chrono::steady_clock::now());

    EXPECT_EQ(monitor.target_sample_size(), monitor.receive_sample_size(endpoint)) << "The number of recorded receives is wrong";
    EXPECT_EQ(seq1, monitor.oldest_receive()) << "The oldest receive calculation is wrong";

    std::uint16_t seq6 = monitor.record_transmit();
    EXPECT_EQ(monitor.target_sample_size() + 1, monitor.transmit_sample_size()) << "The number of recorded transmits is wrong";
    EXPECT_EQ(monitor.target_sample_size(), monitor.receive_sample_size(endpoint)) << "The number of recorded receives is wrong";
    EXPECT_EQ(seq1, monitor.oldest_receive()) << "The oldest receive calculation is wrong";

    std::uint16_t seq7 = monitor.record_transmit();
    EXPECT_EQ(monitor.target_sample_size() + 2, monitor.transmit_sample_size()) << "The number of recorded transmits is wrong";
    EXPECT_EQ(monitor.target_sample_size(), monitor.receive_sample_size(endpoint)) << "The number of recorded receives is wrong";
    EXPECT_EQ(seq1, monitor.oldest_receive()) << "The oldest receive calculation is wrong";

    monitor.record_receive(endpoint, seq6, std::chrono::steady_clock::now());
    EXPECT_EQ(monitor.target_sample_size() + 2, monitor.transmit_sample_size()) << "The number of recorded transmits is wrong";
    EXPECT_EQ(monitor.target_sample_size(), monitor.receive_sample_size(endpoint)) << "The number of recorded receives is wrong";
    EXPECT_EQ(seq2, monitor.oldest_receive()) << "The oldest receive calculation is wrong";

    monitor.record_receive(endpoint, seq7, std::chrono::steady_clock::now());
    EXPECT_EQ(monitor.target_sample_size() + 2, monitor.transmit_sample_size()) << "The number of recorded transmits is wrong";
    EXPECT_EQ(monitor.target_sample_size(), monitor.receive_sample_size(endpoint)) << "The number of recorded receives is wrong";
    EXPECT_EQ(seq3, monitor.oldest_receive()) << "The oldest receive calculation is wrong";

    std::uint16_t seq8 = monitor.record_transmit();
    EXPECT_EQ(seq7 + 1, seq8) << "Wrong next sequence number";
    EXPECT_EQ(monitor.target_sample_size() + 1, monitor.transmit_sample_size()) << "The number of recorded transmits is wrong";
    EXPECT_EQ(monitor.target_sample_size(), monitor.receive_sample_size(endpoint)) << "The number of recorded receives is wrong";
    EXPECT_EQ(seq3, monitor.oldest_receive()) << "The oldest receive calculation is wrong";
}
<|endoftext|>


<commit_before>
#include "config.h"
#define _XOPEN_SOURCE_EXTENDED 1
#include <locale.h>

#if defined HAVE_NCURSESW_CURSES_H
#  include <ncursesw/curses.h>
#elif defined HAVE_NCURSESW_H
#  include <ncursesw.h>
#elif defined HAVE_NCURSES_CURSES_H
#  include <ncurses/curses.h>
#elif defined HAVE_NCURSES_H
#  include <ncurses.h>
#elif defined HAVE_CURSES_H
#  include <curses.h>
#else
#  error "SysV or X/Open-compatible Curses header file required"
#endif

int main(int argc, char *argv[])
{
    setlocale(LC_ALL, "");

    WINDOW *stdscr = initscr();
    cbreak();
    char buf[1024];
    FILE *file = fopen(argv[1], "r");
    int row = 0;
    while (!feof(file)) {
        if (0 < fgets(buf, sizeof(buf), file)) {
            mvwaddstr(stdscr, row++, 0, buf);
        }
    }
    getch();
    endwin();
}
<commit_msg>[tests] fix an issue with the last commit<commit_after>
#include "config.h"
#define _XOPEN_SOURCE_EXTENDED 1
#include <locale.h>

#if defined HAVE_NCURSESW_CURSES_H
#  include <ncursesw/curses.h>
#elif defined HAVE_NCURSESW_H
#  include <ncursesw.h>
#elif defined HAVE_NCURSES_CURSES_H
#  include <ncurses/curses.h>
#elif defined HAVE_NCURSES_H
#  include <ncurses.h>
#elif defined HAVE_CURSES_H
#  include <curses.h>
#else
#  error "SysV or X/Open-compatible Curses header file required"
#endif

int main(int argc, char *argv[])
{
    setlocale(LC_ALL, "");

    WINDOW *stdscr = initscr();
    cbreak();
    char buf[1024];
    FILE *file = fopen(argv[1], "r");
    int row = 0;
    while (!feof(file)) {
        if (fgets(buf, sizeof(buf), file) != nullptr) {
            mvwaddstr(stdscr, row++, 0, buf);
        }
    }
    getch();
    endwin();
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012 Aldebaran Robotics. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the COPYING file.
 */
#include <almath/types/alpose2d.h>
#include <almath/tools/altrigonometry.h>
#include <gtest/gtest.h>

TEST(ALPose2DTest, basicOperator)
{
  AL::Math::Pose2D pPos2D  = AL::Math::Pose2D();
  AL::Math::Pose2D pPos2D1 = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);
  AL::Math::Pose2D pPos2D2 = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);

  // operator !=
  EXPECT_FALSE(pPos2D1 != pPos2D2);
  EXPECT_TRUE(pPos2D1 != AL::Math::Pose2D());

  // operator ==
  EXPECT_TRUE(pPos2D1 == pPos2D2);
  EXPECT_FALSE(pPos2D1 == AL::Math::Pose2D());

  // operator + (a+b)
  pPos2D1 = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);
  pPos2D2 = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);
  pPos2D = pPos2D1 + pPos2D2;
  EXPECT_TRUE(pPos2D.isNear(AL::Math::Pose2D(1.0f, -0.6f, 0.2f), 0.001f));

  // operator + (+a)
  pPos2D1 = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);
  pPos2D  = AL::Math::Pose2D();
  pPos2D = +pPos2D1;
  EXPECT_TRUE(pPos2D.isNear(AL::Math::Pose2D(0.5f, -0.3f, 0.1f), 0.001f));

  // operator +=
  pPos2D1 = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);
  pPos2D2 = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);
  pPos2D1 += pPos2D2;
  EXPECT_TRUE(pPos2D1.isNear(AL::Math::Pose2D(1.0f, -0.6f, 0.2f), 0.001f));

  pPos2D1 = AL::Math::Pose2D(1.0f, 0.7f, 0.5f);
  pPos2D2 = pPos2D1;
  pPos2D2 += pPos2D1;
  pPos2D1 += pPos2D1;
  EXPECT_TRUE(pPos2D2.isNear(pPos2D1));

  // operator - (a-b)
  pPos2D1 = AL::Math::Pose2D(0.5f, +0.3f, 0.1f);
  pPos2D2 = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);
  pPos2D = pPos2D2 - pPos2D1;
  EXPECT_TRUE(pPos2D.isNear(AL::Math::Pose2D(0.0f, -0.6f, 0.0f), 0.001f));

  // operator - (-a)
  pPos2D1 = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);
  pPos2D  = AL::Math::Pose2D();
  pPos2D  = - pPos2D1;
  EXPECT_TRUE(pPos2D.isNear(AL::Math::Pose2D(-0.5f, 0.3f, -0.1f), 0.001f));

  // operator -=
  pPos2D1 = AL::Math::Pose2D(0.6f, -0.4f, 0.2f);
  pPos2D2 = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);
  pPos2D1 -= pPos2D2;
  EXPECT_TRUE(pPos2D1.isNear(AL::Math::Pose2D(0.1f, -0.1f, 0.1f), 0.001f));

  // operator *
  pPos2D1 = AL::Math::Pose2D(1.0f, 0.0f, 0.0f);
  pPos2D2 = AL::Math::Pose2D(0.0f, 1.0f, 0.2f);
  pPos2D = pPos2D1*pPos2D2;
  EXPECT_TRUE(pPos2D.isNear(AL::Math::Pose2D(1.0f, 1.0f, 0.2f), 0.001f));

//  // operator *
//  pPos2D1 = AL::Math::Pose2D(-0.13027f, 0.348845f, 3.14151f);
//  pPos2D2 = AL::Math::Pose2D(0.1f, 0.0f, 0.0f);
//  pPos2D = pPos2D1*pPos2D2;
//  EXPECT_TRUE(pPos2D.isNear(AL::Math::Pose2D(-0.212624f, 0.349525f, 3.14155f), 0.001f));

  // operator *=
  pPos2D1 = AL::Math::Pose2D(1.0f, 0.0f, 0.0f);
  pPos2D2 = AL::Math::Pose2D(0.0f, 1.0f, 0.2f);
  pPos2D1 *= pPos2D2;
  EXPECT_TRUE(pPos2D1.isNear(AL::Math::Pose2D(1.0f, 1.0f, 0.2f), 0.001f));

  pPos2D1 = AL::Math::Pose2D(1.0f, 0.7f, 0.5f);
  pPos2D2 = pPos2D1;
  pPos2D2 *= pPos2D1;
  pPos2D1 *= pPos2D1;
  EXPECT_TRUE(pPos2D2.isNear(pPos2D1));
}

TEST(ALPose2DTest, isNear)
{
  AL::Math::Pose2D pPos2D = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);

  EXPECT_TRUE(pPos2D.isNear(AL::Math::Pose2D(0.5f, -0.3f, 0.1f), 0.0001f));
  EXPECT_FALSE(pPos2D.isNear(AL::Math::Pose2D(0.4f, -0.3f, 0.1f), 0.0001f));
  EXPECT_FALSE(pPos2D.isNear(AL::Math::Pose2D(0.5f, -0.4f, 0.1f), 0.0001f));
  EXPECT_FALSE(pPos2D.isNear(AL::Math::Pose2D(0.5f, -0.3f, 0.2f), 0.0001f));
}

TEST(ALPose2DTest, distance)
{
  AL::Math::Pose2D pPos2D = AL::Math::Pose2D(1.0f, 2.0f, 3.0f);
  EXPECT_NEAR(pPos2D.distance(AL::Math::Pose2D(1.0f, 1.0f, 1.0f)), 1.0f, 0.0001f);
}

TEST(ALPose2DTest, distanceSquared)
{
  AL::Math::Pose2D pPos2D = AL::Math::Pose2D(1.0f, 2.0f, 3.0f);
  EXPECT_NEAR(pPos2D.distanceSquared(AL::Math::Pose2D(0.0f, 0.0f, 0.0f)), 5.0f, 0.0001f);
}

TEST(ALPose2DTest, pose2DInverse)
{
  AL::Math::Pose2D pPose2D = AL::Math::Pose2D(0.1f, -0.1f, -0.5f);
  AL::Math::Pose2D pResult = AL::Math::Pose2D(-0.135701f, 0.0398157f, 0.5f);
  AL::Math::Pose2D pInverse = pPose2D.inverse();
  EXPECT_TRUE(pInverse.isNear(pResult, 0.0001f));
  EXPECT_TRUE((pInverse*pPose2D).isNear(AL::Math::Pose2D(), 0.0001f));

  pInverse = AL::Math::Pose2D();
  pInverse = AL::Math::pose2DInverse(pPose2D);
  EXPECT_TRUE(pInverse.isNear(pResult, 0.0001f));
  EXPECT_TRUE((pInverse*pPose2D).isNear(AL::Math::Pose2D(), 0.0001f));

  pInverse = AL::Math::Pose2D();
  AL::Math::pose2DInverse(pPose2D, pInverse);
  EXPECT_TRUE(pInverse.isNear(pResult, 0.0001f));
  EXPECT_TRUE((pInverse*pPose2D).isNear(AL::Math::Pose2D(), 0.0001f));
}

TEST(ALPose2DTest, pose2dInvertInPlace)
{
  // We use pose2dInverse, previously tested
  AL::Math::Pose2D pIn = AL::Math::Pose2D(0.2f, -2.1f, 35.0*AL::Math::TO_RAD);
  AL::Math::Pose2D pCopy = pIn;
  AL::Math::Pose2D pInverse = AL::Math::pose2DInverse(pIn);

  AL::Math::pose2dInvertInPlace(pIn);

  EXPECT_TRUE(pIn.isNear(pInverse, 0.0001f));
  EXPECT_TRUE((pIn*pCopy).isNear(AL::Math::Pose2D(), 0.0001f));
}

TEST(ALPose2DTest, pose2dDiff)
{
  // We use pose2dInverse, previously tested
  //inverse(pPos1)*pPos2
  AL::Math::Pose2D pPos1   = AL::Math::Pose2D(0.2f, -2.1f, 35.0*AL::Math::TO_RAD);
  AL::Math::Pose2D pPos2   = pPos1;
  AL::Math::Pose2D pResult = AL::Math::pose2dDiff(pPos2, pPos1);

  EXPECT_TRUE(pResult.isNear(AL::Math::Pose2D(), 0.0001f));

  pPos1   = AL::Math::Pose2D(0.2f, -2.1f, 35.0*AL::Math::TO_RAD);
  pPos2   = AL::Math::Pose2D(-1.2f, 0.1f, -10.0*AL::Math::TO_RAD);
  pResult = AL::Math::pose2dDiff(pPos1, pPos2);

  AL::Math::Pose2D pExpected = AL::Math::pose2DInverse(pPos1)*pPos2;
  EXPECT_TRUE(pResult.isNear(pExpected, 0.0001f));
}

TEST(ALPose2DTest, diff)
{
  // We use pose2dInverse, previously tested
  //inverse(pPos1)*pPos2
  AL::Math::Pose2D pPos1   = AL::Math::Pose2D(0.2f, -2.1f, 35.0*AL::Math::TO_RAD);
  AL::Math::Pose2D pPos2   = pPos1;
  AL::Math::Pose2D pResult = pPos1.diff(pPos2);

  EXPECT_TRUE(pResult.isNear(AL::Math::Pose2D(), 0.0001f));

  pPos1   = AL::Math::Pose2D(0.2f, -2.1f, 35.0*AL::Math::TO_RAD);
  pPos2   = AL::Math::Pose2D(-1.2f, 0.1f, -10.0*AL::Math::TO_RAD);
  pResult = pPos1.diff(pPos2);

  AL::Math::Pose2D pExpected = AL::Math::pose2DInverse(pPos1)*pPos2;
  EXPECT_TRUE(pResult.isNear(pExpected, 0.0001f));
}

TEST(ALPose2DTest, pinv)
{
  // We use pose2dInverse, previously tested
  //inverse(pPos1)*pPos2
  AL::Math::Pose2D pPos1   = AL::Math::Pose2D(0.2f, -2.1f, 35.0*AL::Math::TO_RAD);
  AL::Math::Pose2D pPos2   = AL::Math::pinv(pPos1);
  AL::Math::Pose2D pResult = pPos2*pPos1;
  EXPECT_TRUE(pResult.isNear(AL::Math::Pose2D(), 0.0001f));

  pPos1     = AL::Math::Pose2D(0.2f, -2.1f, 35.0*AL::Math::TO_RAD);
  pResult   = AL::Math::pinv(pPos1);
  AL::Math::Pose2D pExpected = AL::Math::pose2DInverse(pPos1);

  EXPECT_TRUE(pResult.isNear(pExpected, 0.0001f));
}
<commit_msg>ALMATH: fix warning<commit_after>/*
 * Copyright (c) 2012 Aldebaran Robotics. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the COPYING file.
 */
#include <almath/types/alpose2d.h>
#include <almath/tools/altrigonometry.h>
#include <gtest/gtest.h>

TEST(ALPose2DTest, basicOperator)
{
  AL::Math::Pose2D pPos2D  = AL::Math::Pose2D();
  AL::Math::Pose2D pPos2D1 = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);
  AL::Math::Pose2D pPos2D2 = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);

  // operator !=
  EXPECT_FALSE(pPos2D1 != pPos2D2);
  EXPECT_TRUE(pPos2D1 != AL::Math::Pose2D());

  // operator ==
  EXPECT_TRUE(pPos2D1 == pPos2D2);
  EXPECT_FALSE(pPos2D1 == AL::Math::Pose2D());

  // operator + (a+b)
  pPos2D1 = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);
  pPos2D2 = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);
  pPos2D = pPos2D1 + pPos2D2;
  EXPECT_TRUE(pPos2D.isNear(AL::Math::Pose2D(1.0f, -0.6f, 0.2f), 0.001f));

  // operator + (+a)
  pPos2D1 = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);
  pPos2D  = AL::Math::Pose2D();
  pPos2D = +pPos2D1;
  EXPECT_TRUE(pPos2D.isNear(AL::Math::Pose2D(0.5f, -0.3f, 0.1f), 0.001f));

  // operator +=
  pPos2D1 = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);
  pPos2D2 = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);
  pPos2D1 += pPos2D2;
  EXPECT_TRUE(pPos2D1.isNear(AL::Math::Pose2D(1.0f, -0.6f, 0.2f), 0.001f));

  pPos2D1 = AL::Math::Pose2D(1.0f, 0.7f, 0.5f);
  pPos2D2 = pPos2D1;
  pPos2D2 += pPos2D1;
  pPos2D1 += pPos2D1;
  EXPECT_TRUE(pPos2D2.isNear(pPos2D1));

  // operator - (a-b)
  pPos2D1 = AL::Math::Pose2D(0.5f, +0.3f, 0.1f);
  pPos2D2 = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);
  pPos2D = pPos2D2 - pPos2D1;
  EXPECT_TRUE(pPos2D.isNear(AL::Math::Pose2D(0.0f, -0.6f, 0.0f), 0.001f));

  // operator - (-a)
  pPos2D1 = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);
  pPos2D  = AL::Math::Pose2D();
  pPos2D  = - pPos2D1;
  EXPECT_TRUE(pPos2D.isNear(AL::Math::Pose2D(-0.5f, 0.3f, -0.1f), 0.001f));

  // operator -=
  pPos2D1 = AL::Math::Pose2D(0.6f, -0.4f, 0.2f);
  pPos2D2 = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);
  pPos2D1 -= pPos2D2;
  EXPECT_TRUE(pPos2D1.isNear(AL::Math::Pose2D(0.1f, -0.1f, 0.1f), 0.001f));

  // operator *
  pPos2D1 = AL::Math::Pose2D(1.0f, 0.0f, 0.0f);
  pPos2D2 = AL::Math::Pose2D(0.0f, 1.0f, 0.2f);
  pPos2D = pPos2D1*pPos2D2;
  EXPECT_TRUE(pPos2D.isNear(AL::Math::Pose2D(1.0f, 1.0f, 0.2f), 0.001f));

//  // operator *
//  pPos2D1 = AL::Math::Pose2D(-0.13027f, 0.348845f, 3.14151f);
//  pPos2D2 = AL::Math::Pose2D(0.1f, 0.0f, 0.0f);
//  pPos2D = pPos2D1*pPos2D2;
//  EXPECT_TRUE(pPos2D.isNear(AL::Math::Pose2D(-0.212624f, 0.349525f, 3.14155f), 0.001f));

  // operator *=
  pPos2D1 = AL::Math::Pose2D(1.0f, 0.0f, 0.0f);
  pPos2D2 = AL::Math::Pose2D(0.0f, 1.0f, 0.2f);
  pPos2D1 *= pPos2D2;
  EXPECT_TRUE(pPos2D1.isNear(AL::Math::Pose2D(1.0f, 1.0f, 0.2f), 0.001f));

  pPos2D1 = AL::Math::Pose2D(1.0f, 0.7f, 0.5f);
  pPos2D2 = pPos2D1;
  pPos2D2 *= pPos2D1;
  pPos2D1 *= pPos2D1;
  EXPECT_TRUE(pPos2D2.isNear(pPos2D1));
}

TEST(ALPose2DTest, isNear)
{
  AL::Math::Pose2D pPos2D = AL::Math::Pose2D(0.5f, -0.3f, 0.1f);

  EXPECT_TRUE(pPos2D.isNear(AL::Math::Pose2D(0.5f, -0.3f, 0.1f), 0.0001f));
  EXPECT_FALSE(pPos2D.isNear(AL::Math::Pose2D(0.4f, -0.3f, 0.1f), 0.0001f));
  EXPECT_FALSE(pPos2D.isNear(AL::Math::Pose2D(0.5f, -0.4f, 0.1f), 0.0001f));
  EXPECT_FALSE(pPos2D.isNear(AL::Math::Pose2D(0.5f, -0.3f, 0.2f), 0.0001f));
}

TEST(ALPose2DTest, distance)
{
  AL::Math::Pose2D pPos2D = AL::Math::Pose2D(1.0f, 2.0f, 3.0f);
  EXPECT_NEAR(pPos2D.distance(AL::Math::Pose2D(1.0f, 1.0f, 1.0f)), 1.0f, 0.0001f);
}

TEST(ALPose2DTest, distanceSquared)
{
  AL::Math::Pose2D pPos2D = AL::Math::Pose2D(1.0f, 2.0f, 3.0f);
  EXPECT_NEAR(pPos2D.distanceSquared(AL::Math::Pose2D(0.0f, 0.0f, 0.0f)), 5.0f, 0.0001f);
}

TEST(ALPose2DTest, pose2DInverse)
{
  AL::Math::Pose2D pPose2D = AL::Math::Pose2D(0.1f, -0.1f, -0.5f);
  AL::Math::Pose2D pResult = AL::Math::Pose2D(-0.135701f, 0.0398157f, 0.5f);
  AL::Math::Pose2D pInverse = pPose2D.inverse();
  EXPECT_TRUE(pInverse.isNear(pResult, 0.0001f));
  EXPECT_TRUE((pInverse*pPose2D).isNear(AL::Math::Pose2D(), 0.0001f));

  pInverse = AL::Math::Pose2D();
  pInverse = AL::Math::pose2DInverse(pPose2D);
  EXPECT_TRUE(pInverse.isNear(pResult, 0.0001f));
  EXPECT_TRUE((pInverse*pPose2D).isNear(AL::Math::Pose2D(), 0.0001f));

  pInverse = AL::Math::Pose2D();
  AL::Math::pose2DInverse(pPose2D, pInverse);
  EXPECT_TRUE(pInverse.isNear(pResult, 0.0001f));
  EXPECT_TRUE((pInverse*pPose2D).isNear(AL::Math::Pose2D(), 0.0001f));
}

TEST(ALPose2DTest, pose2dInvertInPlace)
{
  // We use pose2dInverse, previously tested
  AL::Math::Pose2D pIn = AL::Math::Pose2D(0.2f, -2.1f, 35.0f*AL::Math::TO_RAD);
  AL::Math::Pose2D pCopy = pIn;
  AL::Math::Pose2D pInverse = AL::Math::pose2DInverse(pIn);

  AL::Math::pose2dInvertInPlace(pIn);

  EXPECT_TRUE(pIn.isNear(pInverse, 0.0001f));
  EXPECT_TRUE((pIn*pCopy).isNear(AL::Math::Pose2D(), 0.0001f));
}

TEST(ALPose2DTest, pose2dDiff)
{
  // We use pose2dInverse, previously tested
  //inverse(pPos1)*pPos2
  AL::Math::Pose2D pPos1   = AL::Math::Pose2D(0.2f, -2.1f, 35.0f*AL::Math::TO_RAD);
  AL::Math::Pose2D pPos2   = pPos1;
  AL::Math::Pose2D pResult = AL::Math::pose2dDiff(pPos2, pPos1);

  EXPECT_TRUE(pResult.isNear(AL::Math::Pose2D(), 0.0001f));

  pPos1   = AL::Math::Pose2D(0.2f, -2.1f, 35.0f*AL::Math::TO_RAD);
  pPos2   = AL::Math::Pose2D(-1.2f, 0.1f, -10.0f*AL::Math::TO_RAD);
  pResult = AL::Math::pose2dDiff(pPos1, pPos2);

  AL::Math::Pose2D pExpected = AL::Math::pose2DInverse(pPos1)*pPos2;
  EXPECT_TRUE(pResult.isNear(pExpected, 0.0001f));
}

TEST(ALPose2DTest, diff)
{
  // We use pose2dInverse, previously tested
  //inverse(pPos1)*pPos2
  AL::Math::Pose2D pPos1   = AL::Math::Pose2D(0.2f, -2.1f, 35.0f*AL::Math::TO_RAD);
  AL::Math::Pose2D pPos2   = pPos1;
  AL::Math::Pose2D pResult = pPos1.diff(pPos2);

  EXPECT_TRUE(pResult.isNear(AL::Math::Pose2D(), 0.0001f));

  pPos1   = AL::Math::Pose2D(0.2f, -2.1f, 35.0f*AL::Math::TO_RAD);
  pPos2   = AL::Math::Pose2D(-1.2f, 0.1f, -10.0f*AL::Math::TO_RAD);
  pResult = pPos1.diff(pPos2);

  AL::Math::Pose2D pExpected = AL::Math::pose2DInverse(pPos1)*pPos2;
  EXPECT_TRUE(pResult.isNear(pExpected, 0.0001f));
}

TEST(ALPose2DTest, pinv)
{
  // We use pose2dInverse, previously tested
  //inverse(pPos1)*pPos2
  AL::Math::Pose2D pPos1   = AL::Math::Pose2D(0.2f, -2.1f, 35.0f*AL::Math::TO_RAD);
  AL::Math::Pose2D pPos2   = AL::Math::pinv(pPos1);
  AL::Math::Pose2D pResult = pPos2*pPos1;
  EXPECT_TRUE(pResult.isNear(AL::Math::Pose2D(), 0.0001f));

  pPos1     = AL::Math::Pose2D(0.2f, -2.1f, 35.0f*AL::Math::TO_RAD);
  pResult   = AL::Math::pinv(pPos1);
  AL::Math::Pose2D pExpected = AL::Math::pose2DInverse(pPos1);

  EXPECT_TRUE(pResult.isNear(pExpected, 0.0001f));
}
<|endoftext|>