<commit_before>//===- SSAUpdater.cpp - Unstructured SSA Update Tool ----------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the SSAUpdater class.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Utils/SSAUpdater.h"
#include "llvm/Instructions.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

typedef DenseMap<BasicBlock*, TrackingVH<Value> > AvailableValsTy;
typedef std::vector<std::pair<BasicBlock*, TrackingVH<Value> > >
                IncomingPredInfoTy;

static AvailableValsTy &getAvailableVals(void *AV) {
  return *static_cast<AvailableValsTy*>(AV);
}

static IncomingPredInfoTy &getIncomingPredInfo(void *IPI) {
  return *static_cast<IncomingPredInfoTy*>(IPI);
}

SSAUpdater::SSAUpdater(SmallVectorImpl<PHINode*> *NewPHI)
  : AV(0), PrototypeValue(0), IPI(0), InsertedPHIs(NewPHI) {}

SSAUpdater::~SSAUpdater() {
  delete &getAvailableVals(AV);
  delete &getIncomingPredInfo(IPI);
}

/// Initialize - Reset this object to get ready for a new set of SSA
/// updates.  ProtoValue is the value used to name PHI nodes.
void SSAUpdater::Initialize(Value *ProtoValue) {
  if (AV == 0)
    AV = new AvailableValsTy();
  else
    getAvailableVals(AV).clear();

  if (IPI == 0)
    IPI = new IncomingPredInfoTy();
  else
    getIncomingPredInfo(IPI).clear();
  PrototypeValue = ProtoValue;
}

/// HasValueForBlock - Return true if the SSAUpdater already has a value for
/// the specified block.
bool SSAUpdater::HasValueForBlock(BasicBlock *BB) const {
  return getAvailableVals(AV).count(BB);
}

/// AddAvailableValue - Indicate that a rewritten value is available in the
/// specified block with the specified value.
void SSAUpdater::AddAvailableValue(BasicBlock *BB, Value *V) {
  assert(PrototypeValue != 0 && "Need to initialize SSAUpdater");
  assert(PrototypeValue->getType() == V->getType() &&
         "All rewritten values must have the same type");
  getAvailableVals(AV)[BB] = V;
}

/// GetValueAtEndOfBlock - Construct SSA form, materializing a value that is
/// live at the end of the specified block.
Value *SSAUpdater::GetValueAtEndOfBlock(BasicBlock *BB) {
  assert(getIncomingPredInfo(IPI).empty() && "Unexpected Internal State");
  Value *Res = GetValueAtEndOfBlockInternal(BB);
  assert(getIncomingPredInfo(IPI).empty() && "Unexpected Internal State");
  return Res;
}

/// GetValueInMiddleOfBlock - Construct SSA form, materializing a value that
/// is live in the middle of the specified block.
///
/// GetValueInMiddleOfBlock is the same as GetValueAtEndOfBlock except in one
/// important case: if there is a definition of the rewritten value after the
/// 'use' in BB.  Consider code like this:
///
///      X1 = ...
///   SomeBB:
///      use(X)
///      X2 = ...
///      br Cond, SomeBB, OutBB
///
/// In this case, there are two values (X1 and X2) added to the AvailableVals
/// set by the client of the rewriter, and those values are both live out of
/// their respective blocks.  However, the use of X happens in the *middle* of
/// a block.  Because of this, we need to insert a new PHI node in SomeBB to
/// merge the appropriate values, and this value isn't live out of the block.
///
Value *SSAUpdater::GetValueInMiddleOfBlock(BasicBlock *BB) {
  // If there is no definition of the renamed variable in this block, just use
  // GetValueAtEndOfBlock to do our work.
  if (!getAvailableVals(AV).count(BB))
    return GetValueAtEndOfBlock(BB);

  // Otherwise, we have the hard case.  Get the live-in values for each
  // predecessor.
  SmallVector<std::pair<BasicBlock*, Value*>, 8> PredValues;
  Value *SingularValue = 0;

  // We can get our predecessor info by walking the pred_iterator list, but it
  // is relatively slow.  If we already have PHI nodes in this block, walk one
  // of them to get the predecessor list instead.
  if (PHINode *SomePhi = dyn_cast<PHINode>(BB->begin())) {
    for (unsigned i = 0, e = SomePhi->getNumIncomingValues(); i != e; ++i) {
      BasicBlock *PredBB = SomePhi->getIncomingBlock(i);
      Value *PredVal = GetValueAtEndOfBlock(PredBB);
      PredValues.push_back(std::make_pair(PredBB, PredVal));

      // Compute SingularValue.
      if (i == 0)
        SingularValue = PredVal;
      else if (PredVal != SingularValue)
        SingularValue = 0;
    }
  } else {
    bool isFirstPred = true;
    for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
      BasicBlock *PredBB = *PI;
      Value *PredVal = GetValueAtEndOfBlock(PredBB);
      PredValues.push_back(std::make_pair(PredBB, PredVal));

      // Compute SingularValue.
      if (isFirstPred) {
        SingularValue = PredVal;
        isFirstPred = false;
      } else if (PredVal != SingularValue)
        SingularValue = 0;
    }
  }

  // If there are no predecessors, just return undef.
  if (PredValues.empty())
    return UndefValue::get(PrototypeValue->getType());

  // Otherwise, if all the merged values are the same, just use it.
  if (SingularValue != 0)
    return SingularValue;

  // Otherwise, we do need a PHI: check to see if we already have one available
  // in this block that produces the right value.
  if (isa<PHINode>(BB->begin())) {
    DenseMap<BasicBlock*, Value*> ValueMapping(PredValues.begin(),
                                               PredValues.end());
    PHINode *SomePHI;
    for (BasicBlock::iterator It = BB->begin();
         (SomePHI = dyn_cast<PHINode>(It)); ++It) {
      // Scan this phi to see if it is what we need.
      bool Equal = true;
      for (unsigned i = 0, e = SomePHI->getNumIncomingValues(); i != e; ++i)
        if (ValueMapping[SomePHI->getIncomingBlock(i)] !=
            SomePHI->getIncomingValue(i)) {
          Equal = false;
          break;
        }

      if (Equal)
        return SomePHI;
    }
  }

  // Ok, we have no way out, insert a new one now.
  PHINode *InsertedPHI = PHINode::Create(PrototypeValue->getType(),
                                         PrototypeValue->getName(),
                                         &BB->front());
  InsertedPHI->reserveOperandSpace(PredValues.size());

  // Fill in all the predecessors of the PHI.
  for (unsigned i = 0, e = PredValues.size(); i != e; ++i)
    InsertedPHI->addIncoming(PredValues[i].second, PredValues[i].first);

  // See if the PHI node can be merged to a single value.  This can happen in
  // loop cases when we get a PHI of itself and one other value.
  if (Value *ConstVal = InsertedPHI->hasConstantValue()) {
    InsertedPHI->eraseFromParent();
    return ConstVal;
  }

  // If the client wants to know about all new instructions, tell it.
  if (InsertedPHIs) InsertedPHIs->push_back(InsertedPHI);

  DEBUG(errs() << "  Inserted PHI: " << *InsertedPHI << "\n");
  return InsertedPHI;
}

/// RewriteUse - Rewrite a use of the symbolic value.  This handles PHI nodes,
/// which use their value in the corresponding predecessor.
void SSAUpdater::RewriteUse(Use &U) {
  Instruction *User = cast<Instruction>(U.getUser());

  Value *V;
  if (PHINode *UserPN = dyn_cast<PHINode>(User))
    V = GetValueAtEndOfBlock(UserPN->getIncomingBlock(U));
  else
    V = GetValueInMiddleOfBlock(User->getParent());

  U.set(V);
}

/// GetValueAtEndOfBlockInternal - Check to see if AvailableVals has an entry
/// for the specified BB and if so, return it.  If not, construct SSA form by
/// walking predecessors inserting PHI nodes as needed until we get to a block
/// where the value is available.
///
Value *SSAUpdater::GetValueAtEndOfBlockInternal(BasicBlock *BB) {
  AvailableValsTy &AvailableVals = getAvailableVals(AV);

  // Query AvailableVals by doing an insertion of null.
  std::pair<AvailableValsTy::iterator, bool> InsertRes =
  AvailableVals.insert(std::make_pair(BB, WeakVH()));

  // Handle the case when the insertion fails because we have already seen BB.
  if (!InsertRes.second) {
    // If the insertion failed, there are two cases.  The first case is that the
    // value is already available for the specified block.  If we get this, just
    // return the value.
    if (InsertRes.first->second != 0)
      return InsertRes.first->second;

    // Otherwise, if the value we find is null, then this is the value is not
    // known but it is being computed elsewhere in our recursion.  This means
    // that we have a cycle.  Handle this by inserting a PHI node and returning
    // it.  When we get back to the first instance of the recursion we will fill
    // in the PHI node.
    return InsertRes.first->second =
    PHINode::Create(PrototypeValue->getType(), PrototypeValue->getName(),
                    &BB->front());
  }

  // Okay, the value isn't in the map and we just inserted a null in the entry
  // to indicate that we're processing the block.  Since we have no idea what
  // value is in this block, we have to recurse through our predecessors.
  //
  // While we're walking our predecessors, we keep track of them in a vector,
  // then insert a PHI node in the end if we actually need one.  We could use a
  // smallvector here, but that would take a lot of stack space for every level
  // of the recursion, just use IncomingPredInfo as an explicit stack.
  IncomingPredInfoTy &IncomingPredInfo = getIncomingPredInfo(IPI);
  unsigned FirstPredInfoEntry = IncomingPredInfo.size();

  // As we're walking the predecessors, keep track of whether they are all
  // producing the same value.  If so, this value will capture it, if not, it
  // will get reset to null.  We distinguish the no-predecessor case explicitly
  // below.
  TrackingVH<Value> SingularValue;

  // We can get our predecessor info by walking the pred_iterator list, but it
  // is relatively slow.  If we already have PHI nodes in this block, walk one
  // of them to get the predecessor list instead.
  if (PHINode *SomePhi = dyn_cast<PHINode>(BB->begin())) {
    for (unsigned i = 0, e = SomePhi->getNumIncomingValues(); i != e; ++i) {
      BasicBlock *PredBB = SomePhi->getIncomingBlock(i);
      Value *PredVal = GetValueAtEndOfBlockInternal(PredBB);
      IncomingPredInfo.push_back(std::make_pair(PredBB, PredVal));

      // Compute SingularValue.
      if (i == 0)
        SingularValue = PredVal;
      else if (PredVal != SingularValue)
        SingularValue = 0;
    }
  } else {
    bool isFirstPred = true;
    for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
      BasicBlock *PredBB = *PI;
      Value *PredVal = GetValueAtEndOfBlockInternal(PredBB);
      IncomingPredInfo.push_back(std::make_pair(PredBB, PredVal));

      // Compute SingularValue.
      if (isFirstPred) {
        SingularValue = PredVal;
        isFirstPred = false;
      } else if (PredVal != SingularValue)
        SingularValue = 0;
    }
  }

  // If there are no predecessors, then we must have found an unreachable block
  // just return 'undef'.  Since there are no predecessors, InsertRes must not
  // be invalidated.
  if (IncomingPredInfo.size() == FirstPredInfoEntry)
    return InsertRes.first->second = UndefValue::get(PrototypeValue->getType());

  /// Look up BB's entry in AvailableVals.  'InsertRes' may be invalidated.  If
  /// this block is involved in a loop, a no-entry PHI node will have been
  /// inserted as InsertedVal.  Otherwise, we'll still have the null we inserted
  /// above.
  TrackingVH<Value> &InsertedVal = AvailableVals[BB];

  // If all the predecessor values are the same then we don't need to insert a
  // PHI.  This is the simple and common case.
  if (SingularValue) {
    // If a PHI node got inserted, replace it with the singlar value and delete
    // it.
    if (InsertedVal) {
      PHINode *OldVal = cast<PHINode>(InsertedVal);
      // Be careful about dead loops.  These RAUW's also update InsertedVal.
      if (InsertedVal != SingularValue)
        OldVal->replaceAllUsesWith(SingularValue);
      else
        OldVal->replaceAllUsesWith(UndefValue::get(InsertedVal->getType()));
      OldVal->eraseFromParent();
    } else {
      InsertedVal = SingularValue;
    }

    // Either path through the 'if' should have set insertedVal -> SingularVal.
    assert((InsertedVal == SingularValue || isa<UndefValue>(InsertedVal)) &&
           "RAUW didn't change InsertedVal to be SingularVal");

    // Drop the entries we added in IncomingPredInfo to restore the stack.
    IncomingPredInfo.erase(IncomingPredInfo.begin()+FirstPredInfoEntry,
                           IncomingPredInfo.end());
    return SingularValue;
  }

  // Otherwise, we do need a PHI: insert one now if we don't already have one.
  if (InsertedVal == 0)
    InsertedVal = PHINode::Create(PrototypeValue->getType(),
                                  PrototypeValue->getName(), &BB->front());

  PHINode *InsertedPHI = cast<PHINode>(InsertedVal);
  InsertedPHI->reserveOperandSpace(IncomingPredInfo.size()-FirstPredInfoEntry);

  // Fill in all the predecessors of the PHI.
  for (IncomingPredInfoTy::iterator I =
         IncomingPredInfo.begin()+FirstPredInfoEntry,
       E = IncomingPredInfo.end(); I != E; ++I)
    InsertedPHI->addIncoming(I->second, I->first);

  // Drop the entries we added in IncomingPredInfo to restore the stack.
  IncomingPredInfo.erase(IncomingPredInfo.begin()+FirstPredInfoEntry,
                         IncomingPredInfo.end());

  // See if the PHI node can be merged to a single value.  This can happen in
  // loop cases when we get a PHI of itself and one other value.
  if (Value *ConstVal = InsertedPHI->hasConstantValue()) {
    InsertedPHI->replaceAllUsesWith(ConstVal);
    InsertedPHI->eraseFromParent();
    InsertedVal = ConstVal;
  } else {
    DEBUG(errs() << "  Inserted PHI: " << *InsertedPHI << "\n");

    // If the client wants to know about all new instructions, tell it.
    if (InsertedPHIs) InsertedPHIs->push_back(InsertedPHI);
  }

  return InsertedVal;
}
<commit_msg>improve indentation avoid a pointless conversion from weakvh to trackingvh, no functionality change.<commit_after>//===- SSAUpdater.cpp - Unstructured SSA Update Tool ----------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the SSAUpdater class.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Utils/SSAUpdater.h"
#include "llvm/Instructions.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

typedef DenseMap<BasicBlock*, TrackingVH<Value> > AvailableValsTy;
typedef std::vector<std::pair<BasicBlock*, TrackingVH<Value> > >
                IncomingPredInfoTy;

static AvailableValsTy &getAvailableVals(void *AV) {
  return *static_cast<AvailableValsTy*>(AV);
}

static IncomingPredInfoTy &getIncomingPredInfo(void *IPI) {
  return *static_cast<IncomingPredInfoTy*>(IPI);
}

SSAUpdater::SSAUpdater(SmallVectorImpl<PHINode*> *NewPHI)
  : AV(0), PrototypeValue(0), IPI(0), InsertedPHIs(NewPHI) {}

SSAUpdater::~SSAUpdater() {
  delete &getAvailableVals(AV);
  delete &getIncomingPredInfo(IPI);
}

/// Initialize - Reset this object to get ready for a new set of SSA
/// updates.  ProtoValue is the value used to name PHI nodes.
void SSAUpdater::Initialize(Value *ProtoValue) {
  if (AV == 0)
    AV = new AvailableValsTy();
  else
    getAvailableVals(AV).clear();

  if (IPI == 0)
    IPI = new IncomingPredInfoTy();
  else
    getIncomingPredInfo(IPI).clear();
  PrototypeValue = ProtoValue;
}

/// HasValueForBlock - Return true if the SSAUpdater already has a value for
/// the specified block.
bool SSAUpdater::HasValueForBlock(BasicBlock *BB) const {
  return getAvailableVals(AV).count(BB);
}

/// AddAvailableValue - Indicate that a rewritten value is available in the
/// specified block with the specified value.
void SSAUpdater::AddAvailableValue(BasicBlock *BB, Value *V) {
  assert(PrototypeValue != 0 && "Need to initialize SSAUpdater");
  assert(PrototypeValue->getType() == V->getType() &&
         "All rewritten values must have the same type");
  getAvailableVals(AV)[BB] = V;
}

/// GetValueAtEndOfBlock - Construct SSA form, materializing a value that is
/// live at the end of the specified block.
Value *SSAUpdater::GetValueAtEndOfBlock(BasicBlock *BB) {
  assert(getIncomingPredInfo(IPI).empty() && "Unexpected Internal State");
  Value *Res = GetValueAtEndOfBlockInternal(BB);
  assert(getIncomingPredInfo(IPI).empty() && "Unexpected Internal State");
  return Res;
}

/// GetValueInMiddleOfBlock - Construct SSA form, materializing a value that
/// is live in the middle of the specified block.
///
/// GetValueInMiddleOfBlock is the same as GetValueAtEndOfBlock except in one
/// important case: if there is a definition of the rewritten value after the
/// 'use' in BB.  Consider code like this:
///
///      X1 = ...
///   SomeBB:
///      use(X)
///      X2 = ...
///      br Cond, SomeBB, OutBB
///
/// In this case, there are two values (X1 and X2) added to the AvailableVals
/// set by the client of the rewriter, and those values are both live out of
/// their respective blocks.  However, the use of X happens in the *middle* of
/// a block.  Because of this, we need to insert a new PHI node in SomeBB to
/// merge the appropriate values, and this value isn't live out of the block.
///
Value *SSAUpdater::GetValueInMiddleOfBlock(BasicBlock *BB) {
  // If there is no definition of the renamed variable in this block, just use
  // GetValueAtEndOfBlock to do our work.
  if (!getAvailableVals(AV).count(BB))
    return GetValueAtEndOfBlock(BB);

  // Otherwise, we have the hard case.  Get the live-in values for each
  // predecessor.
  SmallVector<std::pair<BasicBlock*, Value*>, 8> PredValues;
  Value *SingularValue = 0;

  // We can get our predecessor info by walking the pred_iterator list, but it
  // is relatively slow.  If we already have PHI nodes in this block, walk one
  // of them to get the predecessor list instead.
  if (PHINode *SomePhi = dyn_cast<PHINode>(BB->begin())) {
    for (unsigned i = 0, e = SomePhi->getNumIncomingValues(); i != e; ++i) {
      BasicBlock *PredBB = SomePhi->getIncomingBlock(i);
      Value *PredVal = GetValueAtEndOfBlock(PredBB);
      PredValues.push_back(std::make_pair(PredBB, PredVal));

      // Compute SingularValue.
      if (i == 0)
        SingularValue = PredVal;
      else if (PredVal != SingularValue)
        SingularValue = 0;
    }
  } else {
    bool isFirstPred = true;
    for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
      BasicBlock *PredBB = *PI;
      Value *PredVal = GetValueAtEndOfBlock(PredBB);
      PredValues.push_back(std::make_pair(PredBB, PredVal));

      // Compute SingularValue.
      if (isFirstPred) {
        SingularValue = PredVal;
        isFirstPred = false;
      } else if (PredVal != SingularValue)
        SingularValue = 0;
    }
  }

  // If there are no predecessors, just return undef.
  if (PredValues.empty())
    return UndefValue::get(PrototypeValue->getType());

  // Otherwise, if all the merged values are the same, just use it.
  if (SingularValue != 0)
    return SingularValue;

  // Otherwise, we do need a PHI: check to see if we already have one available
  // in this block that produces the right value.
  if (isa<PHINode>(BB->begin())) {
    DenseMap<BasicBlock*, Value*> ValueMapping(PredValues.begin(),
                                               PredValues.end());
    PHINode *SomePHI;
    for (BasicBlock::iterator It = BB->begin();
         (SomePHI = dyn_cast<PHINode>(It)); ++It) {
      // Scan this phi to see if it is what we need.
      bool Equal = true;
      for (unsigned i = 0, e = SomePHI->getNumIncomingValues(); i != e; ++i)
        if (ValueMapping[SomePHI->getIncomingBlock(i)] !=
            SomePHI->getIncomingValue(i)) {
          Equal = false;
          break;
        }

      if (Equal)
        return SomePHI;
    }
  }

  // Ok, we have no way out, insert a new one now.
  PHINode *InsertedPHI = PHINode::Create(PrototypeValue->getType(),
                                         PrototypeValue->getName(),
                                         &BB->front());
  InsertedPHI->reserveOperandSpace(PredValues.size());

  // Fill in all the predecessors of the PHI.
  for (unsigned i = 0, e = PredValues.size(); i != e; ++i)
    InsertedPHI->addIncoming(PredValues[i].second, PredValues[i].first);

  // See if the PHI node can be merged to a single value.  This can happen in
  // loop cases when we get a PHI of itself and one other value.
  if (Value *ConstVal = InsertedPHI->hasConstantValue()) {
    InsertedPHI->eraseFromParent();
    return ConstVal;
  }

  // If the client wants to know about all new instructions, tell it.
  if (InsertedPHIs) InsertedPHIs->push_back(InsertedPHI);

  DEBUG(errs() << "  Inserted PHI: " << *InsertedPHI << "\n");
  return InsertedPHI;
}

/// RewriteUse - Rewrite a use of the symbolic value.  This handles PHI nodes,
/// which use their value in the corresponding predecessor.
void SSAUpdater::RewriteUse(Use &U) {
  Instruction *User = cast<Instruction>(U.getUser());

  Value *V;
  if (PHINode *UserPN = dyn_cast<PHINode>(User))
    V = GetValueAtEndOfBlock(UserPN->getIncomingBlock(U));
  else
    V = GetValueInMiddleOfBlock(User->getParent());

  U.set(V);
}

/// GetValueAtEndOfBlockInternal - Check to see if AvailableVals has an entry
/// for the specified BB and if so, return it.  If not, construct SSA form by
/// walking predecessors inserting PHI nodes as needed until we get to a block
/// where the value is available.
///
Value *SSAUpdater::GetValueAtEndOfBlockInternal(BasicBlock *BB) {
  AvailableValsTy &AvailableVals = getAvailableVals(AV);

  // Query AvailableVals by doing an insertion of null.
  std::pair<AvailableValsTy::iterator, bool> InsertRes =
    AvailableVals.insert(std::make_pair(BB, TrackingVH<Value>()));

  // Handle the case when the insertion fails because we have already seen BB.
  if (!InsertRes.second) {
    // If the insertion failed, there are two cases.  The first case is that the
    // value is already available for the specified block.  If we get this, just
    // return the value.
    if (InsertRes.first->second != 0)
      return InsertRes.first->second;

    // Otherwise, if the value we find is null, then this is the value is not
    // known but it is being computed elsewhere in our recursion.  This means
    // that we have a cycle.  Handle this by inserting a PHI node and returning
    // it.  When we get back to the first instance of the recursion we will fill
    // in the PHI node.
    return InsertRes.first->second =
      PHINode::Create(PrototypeValue->getType(), PrototypeValue->getName(),
                      &BB->front());
  }

  // Okay, the value isn't in the map and we just inserted a null in the entry
  // to indicate that we're processing the block.  Since we have no idea what
  // value is in this block, we have to recurse through our predecessors.
  //
  // While we're walking our predecessors, we keep track of them in a vector,
  // then insert a PHI node in the end if we actually need one.  We could use a
  // smallvector here, but that would take a lot of stack space for every level
  // of the recursion, just use IncomingPredInfo as an explicit stack.
  IncomingPredInfoTy &IncomingPredInfo = getIncomingPredInfo(IPI);
  unsigned FirstPredInfoEntry = IncomingPredInfo.size();

  // As we're walking the predecessors, keep track of whether they are all
  // producing the same value.  If so, this value will capture it, if not, it
  // will get reset to null.  We distinguish the no-predecessor case explicitly
  // below.
  TrackingVH<Value> SingularValue;

  // We can get our predecessor info by walking the pred_iterator list, but it
  // is relatively slow.  If we already have PHI nodes in this block, walk one
  // of them to get the predecessor list instead.
  if (PHINode *SomePhi = dyn_cast<PHINode>(BB->begin())) {
    for (unsigned i = 0, e = SomePhi->getNumIncomingValues(); i != e; ++i) {
      BasicBlock *PredBB = SomePhi->getIncomingBlock(i);
      Value *PredVal = GetValueAtEndOfBlockInternal(PredBB);
      IncomingPredInfo.push_back(std::make_pair(PredBB, PredVal));

      // Compute SingularValue.
      if (i == 0)
        SingularValue = PredVal;
      else if (PredVal != SingularValue)
        SingularValue = 0;
    }
  } else {
    bool isFirstPred = true;
    for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
      BasicBlock *PredBB = *PI;
      Value *PredVal = GetValueAtEndOfBlockInternal(PredBB);
      IncomingPredInfo.push_back(std::make_pair(PredBB, PredVal));

      // Compute SingularValue.
      if (isFirstPred) {
        SingularValue = PredVal;
        isFirstPred = false;
      } else if (PredVal != SingularValue)
        SingularValue = 0;
    }
  }

  // If there are no predecessors, then we must have found an unreachable block
  // just return 'undef'.  Since there are no predecessors, InsertRes must not
  // be invalidated.
  if (IncomingPredInfo.size() == FirstPredInfoEntry)
    return InsertRes.first->second = UndefValue::get(PrototypeValue->getType());

  /// Look up BB's entry in AvailableVals.  'InsertRes' may be invalidated.  If
  /// this block is involved in a loop, a no-entry PHI node will have been
  /// inserted as InsertedVal.  Otherwise, we'll still have the null we inserted
  /// above.
  TrackingVH<Value> &InsertedVal = AvailableVals[BB];

  // If all the predecessor values are the same then we don't need to insert a
  // PHI.  This is the simple and common case.
  if (SingularValue) {
    // If a PHI node got inserted, replace it with the singlar value and delete
    // it.
    if (InsertedVal) {
      PHINode *OldVal = cast<PHINode>(InsertedVal);
      // Be careful about dead loops.  These RAUW's also update InsertedVal.
      if (InsertedVal != SingularValue)
        OldVal->replaceAllUsesWith(SingularValue);
      else
        OldVal->replaceAllUsesWith(UndefValue::get(InsertedVal->getType()));
      OldVal->eraseFromParent();
    } else {
      InsertedVal = SingularValue;
    }

    // Either path through the 'if' should have set insertedVal -> SingularVal.
    assert((InsertedVal == SingularValue || isa<UndefValue>(InsertedVal)) &&
           "RAUW didn't change InsertedVal to be SingularVal");

    // Drop the entries we added in IncomingPredInfo to restore the stack.
    IncomingPredInfo.erase(IncomingPredInfo.begin()+FirstPredInfoEntry,
                           IncomingPredInfo.end());
    return SingularValue;
  }

  // Otherwise, we do need a PHI: insert one now if we don't already have one.
  if (InsertedVal == 0)
    InsertedVal = PHINode::Create(PrototypeValue->getType(),
                                  PrototypeValue->getName(), &BB->front());

  PHINode *InsertedPHI = cast<PHINode>(InsertedVal);
  InsertedPHI->reserveOperandSpace(IncomingPredInfo.size()-FirstPredInfoEntry);

  // Fill in all the predecessors of the PHI.
  for (IncomingPredInfoTy::iterator I =
         IncomingPredInfo.begin()+FirstPredInfoEntry,
       E = IncomingPredInfo.end(); I != E; ++I)
    InsertedPHI->addIncoming(I->second, I->first);

  // Drop the entries we added in IncomingPredInfo to restore the stack.
  IncomingPredInfo.erase(IncomingPredInfo.begin()+FirstPredInfoEntry,
                         IncomingPredInfo.end());

  // See if the PHI node can be merged to a single value.  This can happen in
  // loop cases when we get a PHI of itself and one other value.
  if (Value *ConstVal = InsertedPHI->hasConstantValue()) {
    InsertedPHI->replaceAllUsesWith(ConstVal);
    InsertedPHI->eraseFromParent();
    InsertedVal = ConstVal;
  } else {
    DEBUG(errs() << "  Inserted PHI: " << *InsertedPHI << "\n");

    // If the client wants to know about all new instructions, tell it.
    if (InsertedPHIs) InsertedPHIs->push_back(InsertedPHI);
  }

  return InsertedVal;
}
<|endoftext|>


<commit_before>#include "AppDelegate.h"
#include "scenes/SceneMenu.h"
#include "scenes/SceneFinish.h"
#include "scenes/SceneGame.h"
#include "SoundManager/SoundManager.h"

USING_NS_CC;

AppDelegate::AppDelegate() {

}

AppDelegate::~AppDelegate()
{
}

//if you want a different context,just modify the value of glContextAttrs
//it will takes effect on all platforms
void AppDelegate::initGLContextAttrs()
{
    //set OpenGL context attributions,now can only set six attributions:
    //red,green,blue,alpha,depth,stencil
    GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};

    GLView::setGLContextAttrs(glContextAttrs);
}

bool AppDelegate::applicationDidFinishLaunching() {
    // initialize director
    auto director = Director::getInstance();
    auto glview = director->getOpenGLView();
    if(!glview) {
        glview = GLViewImpl::create("Wonky Monkey");
        director->setOpenGLView(glview);
    }

    // turn on display FPS
//    director->setDisplayStats(true);

    // set FPS. the default value is 1.0/60 if you don't call this
    director->setAnimationInterval(1.0 / 60);

	Size screenSize = glview->getFrameSize();

	//screenSize.height = 540;
	//CCLOG("glview->getFrameSize(): %f, %f\n", screenSize.width, screenSize.height);

	std::vector<std::string> searchPaths;
	if (screenSize.height > 1300) {
		searchPaths.push_back("ipadhd");
		director->setContentScaleFactor(1.0);
	} else if (screenSize.height > 480) {
		searchPaths.push_back("hd");
		director->setContentScaleFactor(0.5);
	} else {
		searchPaths.push_back("sd");
		director->setContentScaleFactor(0.25);
	}
	FileUtils::getInstance()->setSearchPaths(searchPaths);

	director->getOpenGLView()->setDesignResolutionSize(2732, 1536, ResolutionPolicy::NO_BORDER);

    auto scene = SceneGame::createWithPhysics();
    director->runWithScene(scene);

    return true;
}

// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground() {
    Director::getInstance()->stopAnimation();

    cocos2d::experimental::AudioEngine::pauseAll();
    // if you use SimpleAudioEngine, it must be pause
    // SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
}

// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground() {
    Director::getInstance()->startAnimation();

    cocos2d::experimental::AudioEngine::resume(sound_best_loop);
    cocos2d::experimental::AudioEngine::resume(sound_noise_loop);
    // if you use SimpleAudioEngine, it must resume here
    // SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
}
<commit_msg>rand(time(0));<commit_after>#include "AppDelegate.h"
#include "scenes/SceneMenu.h"
#include "scenes/SceneFinish.h"
#include "scenes/SceneGame.h"
#include "SoundManager/SoundManager.h"

USING_NS_CC;

AppDelegate::AppDelegate() {

}

AppDelegate::~AppDelegate()
{
}

//if you want a different context,just modify the value of glContextAttrs
//it will takes effect on all platforms
void AppDelegate::initGLContextAttrs()
{
    //set OpenGL context attributions,now can only set six attributions:
    //red,green,blue,alpha,depth,stencil
    GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};

    GLView::setGLContextAttrs(glContextAttrs);
}

bool AppDelegate::applicationDidFinishLaunching() {
    // initialize director
    auto director = Director::getInstance();
    auto glview = director->getOpenGLView();
    if(!glview) {
        glview = GLViewImpl::create("Wonky Monkey");
        director->setOpenGLView(glview);
    }

    // turn on display FPS
//    director->setDisplayStats(true);

    // set FPS. the default value is 1.0/60 if you don't call this
    director->setAnimationInterval(1.0 / 60);

	Size screenSize = glview->getFrameSize();

	//screenSize.height = 540;
	//CCLOG("glview->getFrameSize(): %f, %f\n", screenSize.width, screenSize.height);

	std::vector<std::string> searchPaths;
	if (screenSize.height > 1300) {
		searchPaths.push_back("ipadhd");
		director->setContentScaleFactor(1.0);
	} else if (screenSize.height > 480) {
		searchPaths.push_back("hd");
		director->setContentScaleFactor(0.5);
	} else {
		searchPaths.push_back("sd");
		director->setContentScaleFactor(0.25);
	}
	FileUtils::getInstance()->setSearchPaths(searchPaths);

	director->getOpenGLView()->setDesignResolutionSize(2732, 1536, ResolutionPolicy::NO_BORDER);

    auto scene = SceneGame::createWithPhysics();
    director->runWithScene(scene);

	srand(time(0));

    return true;
}

// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground() {
    Director::getInstance()->stopAnimation();

    cocos2d::experimental::AudioEngine::pauseAll();
    // if you use SimpleAudioEngine, it must be pause
    // SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
}

// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground() {
    Director::getInstance()->startAnimation();

    cocos2d::experimental::AudioEngine::resume(sound_best_loop);
    cocos2d::experimental::AudioEngine::resume(sound_noise_loop);
    // if you use SimpleAudioEngine, it must resume here
    // SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
}
<|endoftext|>


<commit_before>/*
    pluginloader.cpp - Kopete Plugin Loader

    Copyright (c) 2002      by Duncan Mac-Vicar Prett <duncan@kde.org>
    Copyright (c) 2002-2003 by Martijn Klingens       <klingens@kde.org>

    Portions of this code based in Noatun plugin code:
    Copyright (c) 2000-2002 The Noatun Developers

    Kopete    (c) 2002-2003 by the Kopete developers  <kopete-devel@kde.org>

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

#include "pluginloader.h"

#include <qapplication.h>
#include <qdir.h>
#include <qfile.h>
#include <qregexp.h>

#include <kdebug.h>
#include <kglobal.h>
#include <klocale.h>
#include <knotifyclient.h>
#include <kparts/componentfactory.h>
#include <ksimpleconfig.h>
#include <kstaticdeleter.h>
#include <kstandarddirs.h>
#include <kurl.h>

#include "kopeteplugin.h"

class KopeteLibraryInfo;

// Put the static deleter in its anonymous namespace
namespace
{
	KStaticDeleter<LibraryLoader> sd;
}

bool operator ==(const KopeteLibraryInfo &a, const KopeteLibraryInfo &b)
{
	// Feels like cheating, doesn't it?
	return a.specfile == b.specfile;
}

LibraryLoader* LibraryLoader::s_pluginLoader = 0L;

LibraryLoader* LibraryLoader::pluginLoader()
{
	if( !s_pluginLoader )
		sd.setObject( s_pluginLoader, new LibraryLoader() );

	return s_pluginLoader;
}

LibraryLoader::LibraryLoader()
: QObject( qApp )
{
}

LibraryLoader::~LibraryLoader()
{
	QDictIterator<KopetePlugin> i( m_loadedPlugins );
	while( i.current() )
	{
		// Remove causes the iterator to auto-increment, so
		// only increment explicitly when not removing
		if( getInfo( i.currentKey() ).type != QString::fromLatin1( "Kopete/Protocol" ) )
			delete i.current();
		else
			++i;
	}

	i.toFirst();
	while( i.current() )
		delete i.current();

	kdDebug( 14010 ) << "LibraryLoader::~LibraryLoader(): all plugins removed" << endl;
}

QPtrList<KopetePlugin> LibraryLoader::plugins() const
{
	QPtrList<KopetePlugin> list;
	QDictIterator<KopetePlugin> i( m_loadedPlugins );
	for( ; i.current(); ++i )
		list.append( i.current() );

	return list;
}

QValueList<KopeteLibraryInfo> LibraryLoader::loaded() const
{
	QValueList<KopeteLibraryInfo> items;

	QDictIterator<KopetePlugin> i( m_loadedPlugins );
	for( ; i.current(); ++i )
	{
		if( m_loadedPlugins[ i.currentKey() ] )
			items.append( getInfo( i.currentKey() ) );
	}

	return items;
}

bool LibraryLoader::loadAll()
{
	KConfig *config=KGlobal::config();
	config->setGroup("");
	QStringList modules = config->readListEntry("Plugins");

	// Session management...
/*
	for(QStringList::ConstIterator i=modules.begin(); i!=modules.end(); ++i)
	{
		KopeteLibraryInfo info=getInfo(*i);
		if (!info.type.contains("sm"))
			continue;
		loadPlugin( *i );
	}
*/

	for(QStringList::ConstIterator i=modules.begin(); i!=modules.end(); ++i)
	{
		KopeteLibraryInfo info = getInfo( *i );
		loadPlugin( *i );
	}

	return true;
}

KopeteLibraryInfo LibraryLoader::getInfo(const QString &spec) const
{
	QMap<QString, KopeteLibraryInfo>::iterator cached = m_cachedInfo.find(spec);
	if (cached != m_cachedInfo.end() )
		return *cached;

	KopeteLibraryInfo info;
	QString specPath = ( spec[ 0 ] == '/' ) ? spec : KGlobal::dirs()->findResource( "services", spec );
	if( !QFile::exists( specPath ) )
		return info;

	KSimpleConfig file( specPath );
	if( spec.find( '/' ) >= 0 )
		info.specfile = KURL( spec ).fileName();
	else
		info.specfile = spec;

	file.setGroup( QString::fromLatin1( "Desktop Entry" ) );

	info.filename = file.readEntry( "X-KDE-Library" );
	info.author   = file.readEntry( "X-Kopete-Author" );
	info.site     = file.readEntry( "X-Kopete-Site" );
	info.email    = file.readEntry( "X-Kopete-Email" );
	info.type     = file.readEntry( "ServiceTypes" );
	info.name     = file.readEntry( "Name" );
	info.comment  = file.readEntry( "Comment" );
	info.license  = file.readEntry( "X-Kopete-License" );
	info.icon     = file.readEntry( "Icon" );
	info.pluginId = file.readEntry( "X-Kopete-Plugin-Id" );
	info.messagingProtocol = file.readEntry( "X-Kopete-Messaging-Protocol" );

	if ( info.type != QString::fromLatin1( "Kopete/Plugin" ) && info.type != QString::fromLatin1( "Kopete/Protocol" ) )
		return KopeteLibraryInfo();

	m_cachedInfo[ spec ] = info;
	return info;
}

bool LibraryLoader::isLoaded( const QString &spec ) const
{
	KopetePlugin *p = m_loadedPlugins[ spec ];
	return p;
}

void LibraryLoader::setModules(const QStringList &mods)
{
	KConfig *config=KGlobal::config();
	config->setGroup("");
	config->writeEntry("Plugins", mods);
	KGlobal::config()->sync();
}

QValueList<KopeteLibraryInfo> LibraryLoader::available() const
{
	QValueList<KopeteLibraryInfo> items;
	QStringList files = KGlobal::dirs()->findAllResources( "services", QString::fromLatin1( "*.desktop" ), false, true );
	for( QStringList::Iterator i=files.begin(); i!=files.end(); ++i )
	{
		KopeteLibraryInfo info = getInfo( *i );
		if ( info.type == QString::fromLatin1( "Kopete/Plugin" ) || info.type == QString::fromLatin1( "Kopete/Protocol" ) )
			items.append( info );
	}

	return items;
}

bool LibraryLoader::loadPlugin( const QString &spec )
{
	kdDebug( 14010 ) << k_funcinfo << spec << endl;

	QString pluginId = spec;
	pluginId.remove( QRegExp( QString::fromLatin1( ".desktop$" ) ) );

	KopetePlugin *plugin = KParts::ComponentFactory::createInstanceFromQuery<KopetePlugin>( QString::fromLatin1( "Kopete/Plugin" ),
		QString::fromLatin1( "[X-Kopete-Plugin-Id]=='%1'" ).arg( pluginId ), this );

	//KopetePlugin *plugin = m_loadedPlugins[ spec ];
	if( plugin )
	{
		/*KopeteLibraryInfo info = getInfo( spec );
		if( info.specfile != spec )
			return false;*/

		m_loadedPlugins.insert( spec, plugin );

		connect( plugin, SIGNAL( destroyed( QObject * ) ),
			SLOT( slotPluginDestroyed( QObject * ) ) );

		// Automatically load the i18n catalogue for the plugin
		//KGlobal::locale()->insertCatalogue( info.filename );

		m_addressBookFields.insert( plugin, plugin->addressBookFields() );

		kdDebug( 14010 ) << k_funcinfo << "Successfully loaded plugin '" << pluginId << "'"<< endl;

		emit pluginLoaded( plugin );
		return true;
	}
	else
	{
		kdDebug( 14010 ) << k_funcinfo << "Unable to load plugin '" << pluginId << "'!" << endl;
		return false;
	}
}

bool LibraryLoader::remove( const QString &spec )
{
	KopetePlugin *plugin = m_loadedPlugins[ spec ];
	if( !plugin )
		return false;

	delete plugin;

	return true;
}

void LibraryLoader::slotPluginDestroyed( QObject *o )
{
	m_addressBookFields.remove( static_cast<KopetePlugin *>( o ) );

	QDictIterator<KopetePlugin> it( m_loadedPlugins );
	for( ; it.current() ; ++it )
	{
		if( it.current() == o )
		{
			m_loadedPlugins.remove( it.currentKey() );
			break;
		}
	}

	// FIXME: Most likely most data structures here leak and are bound
	// to cause crashes. Find and identify those.
}

QStringList LibraryLoader::addressBookFields( KopetePlugin *p ) const
{
	if( m_addressBookFields.contains( p ) )
		return m_addressBookFields[ p ];
	else
		return QStringList();
}

KopetePlugin * LibraryLoader::searchByName(const QString &name)
{
	for( QDictIterator<KopetePlugin> i( m_loadedPlugins ); i.current(); ++i )
	{
		if (getInfo(i.currentKey()).name==name)
			return (*i);
	}
	return 0L;
}

KopetePlugin* LibraryLoader::searchByID( const QString &Id )
{
	QValueList<KopeteLibraryInfo> l = loaded();

	for ( QValueList<KopeteLibraryInfo>::Iterator i = l.begin(); i != l.end(); ++i )
	{
		KopetePlugin *tmp_plug = m_loadedPlugins[ ( *i ).specfile ];
		if( tmp_plug->pluginId() == Id )
			return tmp_plug;
	}
	return NULL;
}

QString LibraryLoader::pluginName( const KopetePlugin *plugin ) const
{
	for( QDictIterator<KopetePlugin> i( m_loadedPlugins ); i.current(); ++i )
	{
		if( i.current() == plugin )
			return getInfo( i.currentKey() ).name;
	}
	return QString::fromLatin1( "ERROR: plugin unknown" );
}

QString LibraryLoader::pluginIcon( const KopetePlugin *plugin ) const
{
	for( QDictIterator<KopetePlugin> i( m_loadedPlugins ); i.current(); ++i )
	{
		if( i.current() == plugin )
			return getInfo( i.currentKey() ).icon;
	}
	return QString::fromLatin1( "ERROR: plugin unknown" );
}

#include "pluginloader.moc"

// vim: set noet ts=4 sts=4 sw=4:

<commit_msg>REMOVE THIS ASAP: Workaround for broken kdelibs from CVS HEAD<commit_after>/*
    pluginloader.cpp - Kopete Plugin Loader

    Copyright (c) 2002      by Duncan Mac-Vicar Prett <duncan@kde.org>
    Copyright (c) 2002-2003 by Martijn Klingens       <klingens@kde.org>

    Portions of this code based in Noatun plugin code:
    Copyright (c) 2000-2002 The Noatun Developers

    Kopete    (c) 2002-2003 by the Kopete developers  <kopete-devel@kde.org>

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

#include "pluginloader.h"

#include <qapplication.h>
#include <qdir.h>
#include <qfile.h>
#include <qregexp.h>

#include <kdebug.h>
#include <kglobal.h>
#include <klocale.h>
#include <knotifyclient.h>
#include <kparts/componentfactory.h>
#include <ksimpleconfig.h>
#include <kstaticdeleter.h>
#include <kstandarddirs.h>
#include <kurl.h>

#include "kopeteplugin.h"

class KopeteLibraryInfo;

// Put the static deleter in its anonymous namespace
namespace
{
	KStaticDeleter<LibraryLoader> sd;
}

bool operator ==(const KopeteLibraryInfo &a, const KopeteLibraryInfo &b)
{
	// Feels like cheating, doesn't it?
	return a.specfile == b.specfile;
}

LibraryLoader* LibraryLoader::s_pluginLoader = 0L;

LibraryLoader* LibraryLoader::pluginLoader()
{
	if( !s_pluginLoader )
		sd.setObject( s_pluginLoader, new LibraryLoader() );

	return s_pluginLoader;
}

LibraryLoader::LibraryLoader()
: QObject( qApp )
{
}

LibraryLoader::~LibraryLoader()
{
	QDictIterator<KopetePlugin> i( m_loadedPlugins );
	while( i.current() )
	{
		// Remove causes the iterator to auto-increment, so
		// only increment explicitly when not removing
		if( getInfo( i.currentKey() ).type != QString::fromLatin1( "Kopete/Protocol" ) )
			delete i.current();
		else
			++i;
	}

	i.toFirst();
	while( i.current() )
		delete i.current();

	kdDebug( 14010 ) << "LibraryLoader::~LibraryLoader(): all plugins removed" << endl;
}

QPtrList<KopetePlugin> LibraryLoader::plugins() const
{
	QPtrList<KopetePlugin> list;
	QDictIterator<KopetePlugin> i( m_loadedPlugins );
	for( ; i.current(); ++i )
		list.append( i.current() );

	return list;
}

QValueList<KopeteLibraryInfo> LibraryLoader::loaded() const
{
	QValueList<KopeteLibraryInfo> items;

	QDictIterator<KopetePlugin> i( m_loadedPlugins );
	for( ; i.current(); ++i )
	{
		if( m_loadedPlugins[ i.currentKey() ] )
			items.append( getInfo( i.currentKey() ) );
	}

	return items;
}

bool LibraryLoader::loadAll()
{
	KConfig *config=KGlobal::config();
	config->setGroup("");
	QStringList modules = config->readListEntry("Plugins");

	// Session management...
/*
	for(QStringList::ConstIterator i=modules.begin(); i!=modules.end(); ++i)
	{
		KopeteLibraryInfo info=getInfo(*i);
		if (!info.type.contains("sm"))
			continue;
		loadPlugin( *i );
	}
*/

	for(QStringList::ConstIterator i=modules.begin(); i!=modules.end(); ++i)
	{
		KopeteLibraryInfo info = getInfo( *i );
		loadPlugin( *i );
	}

	return true;
}

KopeteLibraryInfo LibraryLoader::getInfo(const QString &spec) const
{
	QMap<QString, KopeteLibraryInfo>::iterator cached = m_cachedInfo.find(spec);
	if (cached != m_cachedInfo.end() )
		return *cached;

	KopeteLibraryInfo info;
	QString specPath = ( spec[ 0 ] == '/' ) ? spec : KGlobal::dirs()->findResource( "services", spec );
	if( !QFile::exists( specPath ) )
		return info;

	KSimpleConfig file( specPath );
	if( spec.find( '/' ) >= 0 )
		info.specfile = KURL( spec ).fileName();
	else
		info.specfile = spec;

	file.setGroup( QString::fromLatin1( "Desktop Entry" ) );

	info.filename = file.readEntry( "X-KDE-Library" );
	info.author   = file.readEntry( "X-Kopete-Author" );
	info.site     = file.readEntry( "X-Kopete-Site" );
	info.email    = file.readEntry( "X-Kopete-Email" );
	info.type     = file.readEntry( "ServiceTypes" );
	info.name     = file.readEntry( "Name" );
	info.comment  = file.readEntry( "Comment" );
	info.license  = file.readEntry( "X-Kopete-License" );
	info.icon     = file.readEntry( "Icon" );
	info.pluginId = file.readEntry( "X-Kopete-Plugin-Id" );
	info.messagingProtocol = file.readEntry( "X-Kopete-Messaging-Protocol" );

	if ( info.type != QString::fromLatin1( "Kopete/Plugin" ) && info.type != QString::fromLatin1( "Kopete/Protocol" ) )
		return KopeteLibraryInfo();

	m_cachedInfo[ spec ] = info;
	return info;
}

bool LibraryLoader::isLoaded( const QString &spec ) const
{
	KopetePlugin *p = m_loadedPlugins[ spec ];
	return p;
}

void LibraryLoader::setModules(const QStringList &mods)
{
	KConfig *config=KGlobal::config();
	config->setGroup("");
	config->writeEntry("Plugins", mods);
	KGlobal::config()->sync();
}

QValueList<KopeteLibraryInfo> LibraryLoader::available() const
{
	QValueList<KopeteLibraryInfo> items;
	QStringList files = KGlobal::dirs()->findAllResources( "services", QString::fromLatin1( "*.desktop" ), false, true );
	for( QStringList::Iterator i=files.begin(); i!=files.end(); ++i )
	{
		KopeteLibraryInfo info = getInfo( *i );
		if ( info.type == QString::fromLatin1( "Kopete/Plugin" ) || info.type == QString::fromLatin1( "Kopete/Protocol" ) )
			items.append( info );
	}

	return items;
}

bool LibraryLoader::loadPlugin( const QString &spec )
{
	kdDebug( 14010 ) << k_funcinfo << spec << endl;

	QString pluginId = spec;
	pluginId.remove( QRegExp( QString::fromLatin1( ".desktop$" ) ) );

	KopetePlugin *plugin;

	plugin = KParts::ComponentFactory::createInstanceFromQuery<KopetePlugin>(
		QString::fromLatin1("Kopete/Plugin"),
		QString::fromLatin1("[X-Kopete-Plugin-Id]=='%1'").arg(pluginId), this);

	// BEGIN ===========================================================================
	// TODO: REMOVE THIS ASAP, WORKAROUND FOR BROKEN KDELIBS AROUND APRIL 2003!
	if( !plugin ) // maybe it's a protocol?
	{
		plugin = KParts::ComponentFactory::createInstanceFromQuery<KopetePlugin>(
			QString::fromLatin1("Kopete/Protocol"),
			QString::fromLatin1("[X-Kopete-Plugin-Id]=='%1'").arg(pluginId), this);
	}
	// END =============================================================================

	//KopetePlugin *plugin = m_loadedPlugins[ spec ];
	if( plugin )
	{
		/*KopeteLibraryInfo info = getInfo( spec );
		if( info.specfile != spec )
			return false;*/

		m_loadedPlugins.insert( spec, plugin );

		connect( plugin, SIGNAL( destroyed( QObject * ) ),
			SLOT( slotPluginDestroyed( QObject * ) ) );

		// Automatically load the i18n catalogue for the plugin
		//KGlobal::locale()->insertCatalogue( info.filename );

		m_addressBookFields.insert( plugin, plugin->addressBookFields() );

		kdDebug( 14010 ) << k_funcinfo << "Successfully loaded plugin '" << pluginId << "'"<< endl;

		emit pluginLoaded( plugin );
		return true;
	}
	else
	{
		kdDebug( 14010 ) << k_funcinfo << "Unable to load plugin '" << pluginId << "'!" << endl;
		return false;
	}
}

bool LibraryLoader::remove( const QString &spec )
{
	KopetePlugin *plugin = m_loadedPlugins[ spec ];
	if( !plugin )
		return false;

	delete plugin;

	return true;
}

void LibraryLoader::slotPluginDestroyed( QObject *o )
{
	m_addressBookFields.remove( static_cast<KopetePlugin *>( o ) );

	QDictIterator<KopetePlugin> it( m_loadedPlugins );
	for( ; it.current() ; ++it )
	{
		if( it.current() == o )
		{
			m_loadedPlugins.remove( it.currentKey() );
			break;
		}
	}

	// FIXME: Most likely most data structures here leak and are bound
	// to cause crashes. Find and identify those.
}

QStringList LibraryLoader::addressBookFields( KopetePlugin *p ) const
{
	if( m_addressBookFields.contains( p ) )
		return m_addressBookFields[ p ];
	else
		return QStringList();
}

KopetePlugin * LibraryLoader::searchByName(const QString &name)
{
	for( QDictIterator<KopetePlugin> i( m_loadedPlugins ); i.current(); ++i )
	{
		if (getInfo(i.currentKey()).name==name)
			return (*i);
	}
	return 0L;
}

KopetePlugin* LibraryLoader::searchByID( const QString &Id )
{
	QValueList<KopeteLibraryInfo> l = loaded();

	for ( QValueList<KopeteLibraryInfo>::Iterator i = l.begin(); i != l.end(); ++i )
	{
		KopetePlugin *tmp_plug = m_loadedPlugins[ ( *i ).specfile ];
		if( tmp_plug->pluginId() == Id )
			return tmp_plug;
	}
	return NULL;
}

QString LibraryLoader::pluginName( const KopetePlugin *plugin ) const
{
	for( QDictIterator<KopetePlugin> i( m_loadedPlugins ); i.current(); ++i )
	{
		if( i.current() == plugin )
			return getInfo( i.currentKey() ).name;
	}
	return QString::fromLatin1( "ERROR: plugin unknown" );
}

QString LibraryLoader::pluginIcon( const KopetePlugin *plugin ) const
{
	for( QDictIterator<KopetePlugin> i( m_loadedPlugins ); i.current(); ++i )
	{
		if( i.current() == plugin )
			return getInfo( i.currentKey() ).icon;
	}
	return QString::fromLatin1( "ERROR: plugin unknown" );
}

#include "pluginloader.moc"

// vim: set noet ts=4 sts=4 sw=4:

<|endoftext|>


<commit_before>// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "bin/directory.h"

bool Directory::Open(const char* path, intptr_t* dir) {
  UNIMPLEMENTED();
  return false;
}

bool Directory::Close(intptr_t dir) {
  UNIMPLEMENTED();
  return false;
}

void Directory::List(intptr_t dir,
                     bool recursive,
                     Dart_Port dir_handler,
                     Dart_Port file_handler,
                     Dart_Port done_handler,
                     Dart_Port dir_error_handler) {
  UNIMPLEMENTED();
}
<commit_msg>Fix Windows build after directory library changes.<commit_after>// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "bin/directory.h"

bool Directory::Open(const char* path, intptr_t* dir) {
  UNIMPLEMENTED();
  return false;
}

bool Directory::Close(intptr_t dir) {
  UNIMPLEMENTED();
  return false;
}

void Directory::List(const char* path,
                     intptr_t dir,
                     bool recursive,
                     Dart_Port dir_handler,
                     Dart_Port file_handler,
                     Dart_Port done_handler,
                     Dart_Port dir_error_handler) {
  UNIMPLEMENTED();
}
<|endoftext|>


<commit_before>#include <matrix.hpp>
#include <catch.hpp>

SCENARIO("matrix init without parametrs", "[init wp]") {
	Matrix matrix;
	REQUIRE(matrix.rows() == 4);
	REQUIRE(matrix.columns() == 4);

	for (int i=0;i<matrix.rows(); i++) {
		for (int j = 0; j<matrix.columns();j++) {
			REQUIRE(matrix.mas[i][j] == 0);
		}
	}
}

SCENARIO("matrix init with parametrs", "[init withp]") {
	Matrix matrix(6,6);
	REQUIRE(matrix.rows() == 6);
	REQUIRE(matrix.columns() == 6);

	for (int i=0;i<matrix.rows(); i++) {
		for (int j = 0; j<matrix.columns();j++) {
			REQUIRE(matrix.mas[i][j] == 0);
		}
	}
}

SCENARIO("matrix init copy", "[init copy]") {
	Matrix matrix(6,6);
	Matrix matrix1(matrix);
	REQUIRE(matrix1.rows() == matrix.rows());
	REQUIRE(matrix1.columns() == matrix.columns());

	for (int i=0;i<matrix.rows(); i++) {
		for (int j = 0; j<matrix.columns();j++) {
			REQUIRE(matrix.mas[i][j] == matrix1.mas[i][j]);
		}
	}
}

SCENARIO("matrix fill", "[fill]") {
	Matrix matrix(2,2);
	ofstream test1("test1.txt");
	test1 << "1 2 3 4";
	test1.close();
	REQUIRE(matrix.mas[0][0] == 1);
	REQUIRE(matrix.mas[0][1] == 2);
	REQUIRE(matrix.mas[1][0] == 3);
	REQUIRE(matrix.mas[1][1] == 4);
}

<commit_msg>Update init.cpp<commit_after>#include <matrix.hpp>
#include <catch.hpp>

SCENARIO("matrix init without parametrs", "[init wp]") {
	Matrix matrix;
	REQUIRE(matrix.rows() == 4);
	REQUIRE(matrix.columns() == 4);

	for (int i=0;i<matrix.rows(); i++) {
		for (int j = 0; j<matrix.columns();j++) {
			REQUIRE(matrix[i][j] == 0);
		}
	}
}

SCENARIO("matrix init with parametrs", "[init withp]") {
	Matrix matrix(6,6);
	REQUIRE(matrix.rows() == 6);
	REQUIRE(matrix.columns() == 6);

	for (int i=0;i<matrix.rows(); i++) {
		for (int j = 0; j<matrix.columns();j++) {
			REQUIRE(matrix[i][j] == 0);
		}
	}
}

SCENARIO("matrix init copy", "[init copy]") {
	Matrix matrix(6,6);
	Matrix matrix1(matrix);
	REQUIRE(matrix1.rows() == matrix.rows());
	REQUIRE(matrix1.columns() == matrix.columns());

	for (int i=0;i<matrix.rows(); i++) {
		for (int j = 0; j<matrix.columns();j++) {
			REQUIRE(matrix[i][j] == matrix1[i][j]);
		}
	}
}

SCENARIO("matrix fill", "[fill]") {
	Matrix matrix(2,2);
	ofstream test1("test1.txt");
	test1 << "1 2 3 4";
	test1.close();
	REQUIRE(matrix[0][0] == 1);
	REQUIRE(matrix[0][1] == 2);
	REQUIRE(matrix[1][0] == 3);
	REQUIRE(matrix[1][1] == 4);
}

SCENARIO("matrix sum", "[sum]") {
	Matrix matrix(2,2);
	Matrix matrix1(2,2);

<|endoftext|>


<commit_before>#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "coconfig.h"

#if defined(_MSC_VER)
  #define WIN32_LEAN_AND_MEAN
  #define VC_EXTRALEAN
  #include <Windows.h>
#else
  #include <signal.h>
#endif

typedef int32_t (*test_func_t)();

extern int32_t test_simple   ();
extern int32_t test_factoral ();
extern int32_t test_multiple ();
extern int32_t test_allocator();
extern int32_t test_fpregs   ();
extern int32_t test_unchained();
extern int32_t test_yieldmain();
extern int32_t test_nesting  ();
extern int32_t test_params   ();

struct test_t {
    test_func_t func_;
    const char * name_;
};

static
test_t tests[] = {
    { test_simple,    "test_simple"    },
    { test_factoral,  "test_factoral"  },
    { test_multiple,  "test_multiple"  },
    { test_allocator, "test_allocator" },
    { test_fpregs,    "test_fpregs"    },
    { test_unchained, "test_unchained" },
    { test_yieldmain, "test_yieldmain" },
    { test_nesting,   "test_nesting"   },
    { test_params,    "test_params"    },
    { nullptr, nullptr }
};

static
const char * test_name = "";

#if defined(_MSC_VER)
static
LONG CALLBACK segv_handler(PEXCEPTION_POINTERS info) {
    if (info->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT) {
        printf("! fail  '%s'\n", test_name);
    }
    else {
        printf("! crash '%s'\n", test_name);
#if defined(_M_X64)
        printf("  pc  @ 0x%016llx\n", info->ContextRecord->Rip);
        printf("  sp  @ 0x%016llx\n", info->ContextRecord->Rsp);
#else
        printf("  pc  @ 0x%08lx\n", info->ContextRecord->Eip);
        printf("  sp  @ 0x%08lx\n", info->ContextRecord->Esp);
#endif
    }
    getchar();
    exit(1);
}

static
void setup() {
//    AddVectoredExceptionHandler(1, segv_handler);
}
#else
static
void segv_handler(int signal) {
    printf("! crash '%s'\n", test_name);
    exit(1);
}

static
void sigtrap_handler(int signal)
    printf("! fail  '%s'\n", test_name);
    exit(1);
}

static
void setup() {
    signal(SIGSEGV, segv_handler);
    signal(SIGABRT, segv_handler);
    signal(SIGILL,  segv_handler);
    signal(SIGINT,  segv_handler);
    signal(SIGTRAP, sigtrap_handler);
}
#endif

int main() {

    setup();
    int32_t fails = 0;

    for (int32_t i = 0; tests[i].name_; i++) {

        test_t & test = tests[i];
        test_name = test.name_;

        // run this specific test
        int32_t res = test.func_();

        if (res >= 0) {
            printf(". pass  '%s'\n", test.name_);
        }
        else {
            printf("! fail  '%s' (%d)\n", test.name_, res);
            ++fails;
        }
    }

    getchar();
    return fails;
}
<commit_msg>fix typo<commit_after>#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "coconfig.h"

#if defined(_MSC_VER)
  #define WIN32_LEAN_AND_MEAN
  #define VC_EXTRALEAN
  #include <Windows.h>
#else
  #include <signal.h>
#endif

typedef int32_t (*test_func_t)();

extern int32_t test_simple   ();
extern int32_t test_factoral ();
extern int32_t test_multiple ();
extern int32_t test_allocator();
extern int32_t test_fpregs   ();
extern int32_t test_unchained();
extern int32_t test_yieldmain();
extern int32_t test_nesting  ();
extern int32_t test_params   ();

struct test_t {
    test_func_t func_;
    const char * name_;
};

static
test_t tests[] = {
    { test_simple,    "test_simple"    },
    { test_factoral,  "test_factoral"  },
    { test_multiple,  "test_multiple"  },
    { test_allocator, "test_allocator" },
    { test_fpregs,    "test_fpregs"    },
    { test_unchained, "test_unchained" },
    { test_yieldmain, "test_yieldmain" },
    { test_nesting,   "test_nesting"   },
    { test_params,    "test_params"    },
    { nullptr, nullptr }
};

static
const char * test_name = "";

#if defined(_MSC_VER)
static
LONG CALLBACK segv_handler(PEXCEPTION_POINTERS info) {
    if (info->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT) {
        printf("! fail  '%s'\n", test_name);
    }
    else {
        printf("! crash '%s'\n", test_name);
#if defined(_M_X64)
        printf("  pc  @ 0x%016llx\n", info->ContextRecord->Rip);
        printf("  sp  @ 0x%016llx\n", info->ContextRecord->Rsp);
#else
        printf("  pc  @ 0x%08lx\n", info->ContextRecord->Eip);
        printf("  sp  @ 0x%08lx\n", info->ContextRecord->Esp);
#endif
    }
    getchar();
    exit(1);
}

static
void setup() {
//    AddVectoredExceptionHandler(1, segv_handler);
}
#else
static
void segv_handler(int signal) {
    printf("! crash '%s'\n", test_name);
    exit(1);
}

static
void sigtrap_handler(int signal) {
    printf("! fail  '%s'\n", test_name);
    exit(1);
}

static
void setup() {
    signal(SIGSEGV, segv_handler);
    signal(SIGABRT, segv_handler);
    signal(SIGILL,  segv_handler);
    signal(SIGINT,  segv_handler);
    signal(SIGTRAP, sigtrap_handler);
}
#endif

int main() {

    setup();
    int32_t fails = 0;

    for (int32_t i = 0; tests[i].name_; i++) {

        test_t & test = tests[i];
        test_name = test.name_;

        // run this specific test
        int32_t res = test.func_();

        if (res >= 0) {
            printf(". pass  '%s'\n", test.name_);
        }
        else {
            printf("! fail  '%s' (%d)\n", test.name_, res);
            ++fails;
        }
    }

    getchar();
    return fails;
}
<|endoftext|>


<commit_before>#include "lest.hpp"

#include "../twombly.hpp"

#include <iostream>

using namespace tw;

#define RED 2
#define GREEN 1
#define BLUE 0
#define ALPHA 3

int opencv_error_handler(int status, const char* func_name, const char* err_msg,
                   const char* file_name, int line, void*)
{
    return 0;
}

const lest::test drawing_test[] = {
    CASE ( "Mat3b drawing" ) {
        Mat3b im(100, 100);
        auto d = draw(im);
        d.clear(255, 0, 0);
        EXPECT(im.at<Vec3b>(10, 10)[RED] == 255);
        EXPECT(im.at<Vec3b>(10, 10)[GREEN] == 0);
        EXPECT(im.at<Vec3b>(10, 10)[BLUE] == 0);
    },

    CASE ( "Mat4b drawing" ) {
        Mat4b im(100, 100);
        auto d = draw(im);
        d.clear(255, 0, 0);
        EXPECT(im.at<Vec4b>(10, 10)[RED] == 255);
        EXPECT(im.at<Vec4b>(10, 10)[GREEN] == 0);
        EXPECT(im.at<Vec4b>(10, 10)[BLUE] == 0);
        EXPECT(im.at<Vec4b>(10, 10)[ALPHA] == 255);
    },

    CASE ( "Mat3w drawing" ) {
        Mat3w im(100, 100);
        auto d = draw(im);
        d.clear(255, 0, 0);
        EXPECT(im.at<Vec3w>(10, 10)[RED] == 65535);
        EXPECT(im.at<Vec3w>(10, 10)[GREEN] == 0);
        EXPECT(im.at<Vec3w>(10, 10)[BLUE] == 0);
    },

    CASE ( "Mat4w drawing" ) {
        Mat4w im(100, 100);
        auto d = draw(im);
        d.clear(255, 0, 0);
        EXPECT(im.at<Vec4w>(10, 10)[RED] == 65535);
        EXPECT(im.at<Vec4w>(10, 10)[GREEN] == 0);
        EXPECT(im.at<Vec4w>(10, 10)[BLUE] == 0);
        EXPECT(im.at<Vec4w>(10, 10)[ALPHA] == 65535);
    },

    CASE ( "Path" ) {
        Mat3b im(500, 500);
        auto d = draw(im);
        d.preserve(true);
        d.new_path();
        d.set_color(255, 255, 255);
        d.move_to(10, 10);
        d.line_to(490, 490);
        d.stroke();

        int pathid = d.active_path();

        EXPECT (d.total_vertices() == 2);

        double x, y;
        d.vertex(1, &x, &y);
        EXPECT(x == 490);
        EXPECT(y == 490);

        d.modify_vertex(1, 248, 249);
        d.vertex(1, &x, &y);
        EXPECT(x == 248);
        EXPECT(y == 249);

        d.new_path();
        EXPECT (d.active_path() != pathid);
        EXPECT (d.active_path() > pathid);

        d.new_path();
        d.line_width(2);
        d.ellipse(250, 250, 100, 100);
        d.stroke();

        d.active_path(pathid);
        d.stroke();
        d.preserve(false);

#ifndef NO_SHOW
        try{
            namedWindow("Path test");
            imshow("Path test", im);
            waitKey(0);
            destroyAllWindows();
        } catch(std::exception &exc){

        }
#endif
    },

    CASE ( "Curve" ) {
        Mat3b im2(500, 500);
        im2.setTo(Scalar(255, 255, 255));
        auto d = draw(im2);

        d.set_color(255, 0, 0);
        d.move_to(100, 100);
        d.curve_to(400, 400, 100, 320);
        d.stroke();

#ifndef NO_SHOW
        try {
            namedWindow("Curve test");
            imshow("Curve test", im2);
            waitKey(0);
        } catch (std::exception &exc){

        }
#endif

        d.new_path();
        d.clear(255, 255, 255);
        d.set_color(0, 255, 0);
        d.move_to(100, 100);
        d.curve_to(400, 400, 150, 320);
        d.stroke();

#ifndef NO_SHOW
        try{
            imshow("Curve test", im2);
            waitKey(0);
            destroyAllWindows();
        } catch(std::exception &exc){

        }
#endif
    },

    CASE ( "Gradient" ) {
        Mat3w im2(500, 500);
        im2.setTo(Scalar(255, 255, 255));
        auto d = draw(im2);

        d.set_color(255, 0, 0);
        d.move_to(100, 100);
        d.curve_to(400, 400, 100, 320);
        d.stroke();

        d.new_path();
        d.ellipse(250, 250, 250, 250);

        Gradient<Color16> g;
        g.add_stop(Color16(255<<8, 0, 0, 127<<8));
        g.add_stop(Color16(0, 255<<8, 0, 127<<8));
        g.add_stop(Color16(0, 0, 255<<8, 127<<8));

        d.fill_gradient(g, 0, 300, gradient_type_y);
        EXPECT((im2.at<Scalar>(250, 250)[0] > 0));

#ifndef NO_SHOW
        try{
            imshow("Gradient test", im2);
            waitKey(0);
            destroyAllWindows();
        } catch(std::exception &exc){

        }
#endif
    },

    CASE( "cairo-arc-infinite-loop"){
        Mat3b im2(8, 8);
        auto d = draw(im2);
        d.clear(255, 255, 255);

        d.move_to(0, 0);
        d.arc_to(0, 0, 1, 1024 / DBL_EPSILON * M_PI, 0);
        d.arc_to(0, 0, 1, 0, 1024 / DBL_EPSILON * M_PI);

        d.set_color(255, 0, 0);
        d.stroke();

#ifndef NO_SHOW
        try{
            imshow("infinte loop", im2);
            waitKey(0);
            destroyAllWindows();
        } catch(std::exception &exc){

        }
#endif
    }
};

int main(int argc, char **argv){
    cv::redirectError(opencv_error_handler);
    lest::run(drawing_test, argc, argv);
}
<commit_msg>add more tests<commit_after>#include "lest.hpp"

#include "../twombly.hpp"

#include <iostream>

using namespace tw;

#define RED 2
#define GREEN 1
#define BLUE 0
#define ALPHA 3

int opencv_error_handler(int status, const char* func_name, const char* err_msg,
                   const char* file_name, int line, void*)
{
    return 0;
}

const lest::test drawing_test[] = {
    CASE ( "Mat3b drawing" ) {
        Mat3b im(100, 100);
        auto d = draw(im);
        d.clear(255, 0, 0);
        EXPECT(im.at<Vec3b>(10, 10)[RED] == 255);
        EXPECT(im.at<Vec3b>(10, 10)[GREEN] == 0);
        EXPECT(im.at<Vec3b>(10, 10)[BLUE] == 0);
    },

    CASE ( "Mat4b drawing" ) {
        Mat4b im(100, 100);
        auto d = draw(im);
        d.clear(255, 0, 0);
        EXPECT(im.at<Vec4b>(10, 10)[RED] == 255);
        EXPECT(im.at<Vec4b>(10, 10)[GREEN] == 0);
        EXPECT(im.at<Vec4b>(10, 10)[BLUE] == 0);
        EXPECT(im.at<Vec4b>(10, 10)[ALPHA] == 255);
    },

    CASE ( "Mat3w drawing" ) {
        Mat3w im(100, 100);
        auto d = draw(im);
        d.clear(255, 0, 0);
        EXPECT(im.at<Vec3w>(10, 10)[RED] == 65535);
        EXPECT(im.at<Vec3w>(10, 10)[GREEN] == 0);
        EXPECT(im.at<Vec3w>(10, 10)[BLUE] == 0);
    },

    CASE ( "Mat4w drawing" ) {
        Mat4w im(100, 100);
        auto d = draw(im);
        d.clear(255, 0, 0);
        EXPECT(im.at<Vec4w>(10, 10)[RED] == 65535);
        EXPECT(im.at<Vec4w>(10, 10)[GREEN] == 0);
        EXPECT(im.at<Vec4w>(10, 10)[BLUE] == 0);
        EXPECT(im.at<Vec4w>(10, 10)[ALPHA] == 65535);
    },

    CASE ( "Path" ) {
        Mat3b im(500, 500);
        auto d = draw(im);
        d.preserve(true);
        d.new_path();
        d.set_color(255, 255, 255);
        d.move_to(10, 10);
        d.line_to(490, 490);
        d.stroke();

        int pathid = d.active_path();

        EXPECT (d.total_vertices() == 2);

        double x, y;
        d.vertex(1, &x, &y);
        EXPECT(x == 490);
        EXPECT(y == 490);

        d.modify_vertex(1, 248, 249);
        d.vertex(1, &x, &y);
        EXPECT(x == 248);
        EXPECT(y == 249);

        d.new_path();
        EXPECT (d.active_path() != pathid);
        EXPECT (d.active_path() > pathid);

        d.new_path();
        d.line_width(2);
        d.ellipse(250, 250, 100, 100);
        d.stroke();

        d.active_path(pathid);
        d.stroke();
        d.preserve(false);

#ifndef NO_SHOW
        try{
            namedWindow("Path test");
            imshow("Path test", im);
            waitKey(0);
            destroyAllWindows();
        } catch(std::exception &exc){

        }
#endif
    },

    CASE ( "Curve" ) {
        Mat3b im2(500, 500);
        im2.setTo(Scalar(255, 255, 255));
        auto d = draw(im2);

        d.set_color(255, 0, 0);
        d.move_to(100, 100);
        d.curve_to(400, 400, 100, 320);
        d.stroke();

#ifndef NO_SHOW
        try {
            namedWindow("Curve test");
            imshow("Curve test", im2);
            waitKey(0);
        } catch (std::exception &exc){

        }
#endif

        d.new_path();
        d.clear(255, 255, 255);
        d.set_color(0, 255, 0);
        d.move_to(100, 100);
        d.curve_to(400, 400, 150, 320);
        d.stroke();

#ifndef NO_SHOW
        try{
            imshow("Curve test", im2);
            waitKey(0);
            destroyAllWindows();
        } catch(std::exception &exc){

        }
#endif
    },

    CASE ( "Gradient" ) {
        Mat3w im2(500, 500);
        im2.setTo(Scalar(255, 255, 255));
        auto d = draw(im2);

        d.set_color(255, 0, 0);
        d.move_to(100, 100);
        d.curve_to(400, 400, 100, 320);
        d.stroke();

        d.new_path();
        d.ellipse(250, 250, 250, 250);

        Gradient<Color16> g;
        g.add_stop(Color16(255<<8, 0, 0, 127<<8));
        g.add_stop(Color16(0, 255<<8, 0, 127<<8));
        g.add_stop(Color16(0, 0, 255<<8, 127<<8));

        d.fill_gradient(g, 0, 300, gradient_type_y);
        EXPECT((im2.at<Scalar>(250, 250)[0] > 0));

#ifndef NO_SHOW
        try{
            imshow("Gradient test", im2);
            waitKey(0);
            destroyAllWindows();
        } catch(std::exception &exc){

        }
#endif
    },

    CASE("linear gradient many stops"){
        Mat3b im2(800, 800);
        auto d = draw(im2);

        Gradient<Color> g;

        for(int i = 0; i < 255; i++){
            g.add_stop(Color(i, 255-i, 255 * rand(), 255 * rand()));
        }

        d.rect(0, 0, 800, 800);
        d.fill_gradient(g, 0, 800, gradient_type_x);

#ifndef NO_SHOW
        try{
            imshow("Gradient test many stops", im2);
            waitKey(0);
            destroyAllWindows();
        } catch(std::exception &exc){

        }
#endif
    },

    CASE( "cairo-arc-infinite-loop"){
        Mat3b im2(8, 8);
        auto d = draw(im2);
        d.clear(255, 255, 255);

        d.move_to(0, 0);
        d.arc_to(0, 0, 1, 1024 / DBL_EPSILON * M_PI, 0);
        d.arc_to(0, 0, 1, 0, 1024 / DBL_EPSILON * M_PI);

        d.set_color(255, 0, 0);
        d.stroke();

    },

    CASE( "mask"){
        Mat4b im2(8, 8);
        auto d = draw(im2);

        d.antialias(false);
        d.alpha_mask_init();

        d.rect(0, 0, 8, 8);
        d.set_color(255, 0, 0, 255);
        d.alpha_mask_get(5, 5) = 0;
        d.fill();

        imwrite("test1.jpg", im2);

        EXPECT((int)(im2.at<Vec4b>(5, 5)[2]) <  255);
        EXPECT(((int)im2.at<Vec4b>(4, 4)[2]) == 255);

    },

    CASE("Matrix rotation, scaling, translation, "){
        int PAT_WIDTH = 120, PAT_HEIGHT = 120, PAD = 2;
        Mat4b im2(((PAT_WIDTH*2) + 8), ((PAT_WIDTH*2) + 8));
        auto d = draw(im2);

        d.clear(0, 0, 0);

        d.translate(-PAT_WIDTH/2.0, -PAT_WIDTH/2.0);
        d.rotate(1.57079633);
        d.translate(PAT_WIDTH/2.0 + PAD, PAT_WIDTH/2.0-PAD);
        d.mtx.invert();

        d.scale(2, 2);

        d.set_color(255, 0, 255, 127);
        d.rect(PAT_WIDTH/6.0, PAT_HEIGHT/6.0, PAT_WIDTH/6.0 + PAT_WIDTH/4.0, PAT_WIDTH/6.0 + PAT_HEIGHT/4.0);
        d.fill();

        d.set_color (0, 255, 255, 127);
        d.rect(PAT_WIDTH/2.0, PAT_HEIGHT/2.0, PAT_WIDTH/2.0 + PAT_WIDTH/4.0,  PAT_WIDTH/2.0 + PAT_HEIGHT/4.0);
        d.fill();

        d.line_width(1);
        d.move_to(PAT_WIDTH/6.0, 0);
        d.line_to(0, 0);
        d.line_to(0, PAT_HEIGHT/6.0);
        d.set_color(255, 0, 0);
        d.stroke();

        d.move_to(PAT_WIDTH/6.0, PAT_HEIGHT);
        d.line_to(0, PAT_HEIGHT);
        d.line_to(0, 5 * PAT_HEIGHT/6.0);
        d.set_color(0, 0, 255, 255);
        d.stroke();

        d.move_to (5*PAT_WIDTH/6.0, 0);
        d.line_to (PAT_WIDTH, 0);
        d.line_to (PAT_WIDTH, PAT_HEIGHT/6.0);
        d.set_color (0, 0, 255, 255);
        d.stroke ();

        d.move_to (5*PAT_WIDTH/6.0, PAT_HEIGHT);
        d.line_to (PAT_WIDTH, PAT_HEIGHT);
        d.line_to (PAT_WIDTH, 5*PAT_HEIGHT/6.0);
        d.set_color (255, 255, 0, 255);
        d.stroke ();

        d.set_color (127, 127, 127);
        d.line_width (PAT_WIDTH/10.0);

        d.move_to (0,         PAT_HEIGHT/4.0);
        d.line_to (PAT_WIDTH, PAT_HEIGHT/4.0);
        d.stroke ();

        d.move_to (PAT_WIDTH/4.0,         0);
        d.line_to (PAT_WIDTH/4.0, PAT_WIDTH);
        d.stroke ();

#ifndef NO_SHOW
        try{
            imshow("Test Matrix", im2);
            waitKey(0);
            destroyAllWindows();
        } catch(std::exception &exc){

        }
#endif
    }
};

int main(int argc, char **argv){
    cv::redirectError(opencv_error_handler);
    lest::run(drawing_test, argc, argv);
}
<|endoftext|>