<commit_before>//===- ReadConst.cpp - Code to constants and constant pools -----------------===
//
// This file implements functionality to deserialize constants and entire
// constant pools.
//
// Note that this library should be as fast as possible, reentrant, and
// threadsafe!!
//
//===------------------------------------------------------------------------===

#include "llvm/Module.h"
#include "llvm/BasicBlock.h"
#include "llvm/ConstPoolVals.h"
#include "llvm/DerivedTypes.h"
#include "llvm/GlobalVariable.h"
#include "ReaderInternals.h"
#include <algorithm>

const Type *BytecodeParser::parseTypeConstant(const uchar *&Buf,
					      const uchar *EndBuf) {
  unsigned PrimType;
  if (read_vbr(Buf, EndBuf, PrimType)) return failure<const Type*>(0);

  const Type *Val = 0;
  if ((Val = Type::getPrimitiveType((Type::PrimitiveID)PrimType)))
    return Val;

  switch (PrimType) {
  case Type::MethodTyID: {
    unsigned Typ;
    if (read_vbr(Buf, EndBuf, Typ)) return failure(Val);
    const Type *RetType = getType(Typ);
    if (RetType == 0) return failure(Val);

    unsigned NumParams;
    if (read_vbr(Buf, EndBuf, NumParams)) return failure(Val);

    vector<const Type*> Params;
    while (NumParams--) {
      if (read_vbr(Buf, EndBuf, Typ)) return failure(Val);
      const Type *Ty = getType(Typ);
      if (Ty == 0) return failure(Val);
      Params.push_back(Ty);
    }

    bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
    if (isVarArg) Params.pop_back();

    Val = MethodType::get(RetType, Params, isVarArg);
    break;
  }
  case Type::ArrayTyID: {
    unsigned ElTyp;
    if (read_vbr(Buf, EndBuf, ElTyp)) return failure(Val);
    const Type *ElementType = getType(ElTyp);
    if (ElementType == 0) return failure(Val);

    int NumElements;
    if (read_vbr(Buf, EndBuf, NumElements)) return failure(Val);
    Val = ArrayType::get(ElementType, NumElements);
    break;
  }
  case Type::StructTyID: {
    unsigned Typ;
    vector<const Type*> Elements;

    if (read_vbr(Buf, EndBuf, Typ)) return failure(Val);
    while (Typ) {         // List is terminated by void/0 typeid
      const Type *Ty = getType(Typ);
      if (Ty == 0) return failure(Val);
      Elements.push_back(Ty);

      if (read_vbr(Buf, EndBuf, Typ)) return failure(Val);
    }

    Val = StructType::get(Elements);
    break;
  }
  case Type::PointerTyID: {
    unsigned ElTyp;
    if (read_vbr(Buf, EndBuf, ElTyp)) return failure(Val);
    const Type *ElementType = getType(ElTyp);
    if (ElementType == 0) return failure(Val);
    Val = PointerType::get(ElementType);
    break;
  }

  case Type::OpaqueTyID: {
    Val = OpaqueType::get();
    break;
  }

  default:
    cerr << __FILE__ << ":" << __LINE__ << ": Don't know how to deserialize"
	 << " primitive Type " << PrimType << "\n";
    return failure(Val);
  }

  return Val;
}

// refineAbstractType - The callback method is invoked when one of the
// elements of TypeValues becomes more concrete...
//
void BytecodeParser::refineAbstractType(const DerivedType *OldType,
					const Type *NewType) {
  if (OldType == NewType) return;  // Type is modified, but same

  TypeValuesListTy::iterator I = find(MethodTypeValues.begin(),
				      MethodTypeValues.end(), OldType);
  if (I == MethodTypeValues.end()) {
    I = find(ModuleTypeValues.begin(), ModuleTypeValues.end(), OldType);
    assert(I != ModuleTypeValues.end() &&
	   "Can't refine a type I don't know about!");
  }

  *I = NewType;  // Update to point to new, more refined type.
}

// parseTypeConstants - We have to use this wierd code to handle recursive
// types.  We know that recursive types will only reference the current slab of
// values in the type plane, but they can forward reference types before they
// have been read.  For example, Type #0 might be '{ Ty#1 }' and Type #1 might
// be 'Ty#0*'.  When reading Type #0, type number one doesn't exist.  To fix
// this ugly problem, we pesimistically insert an opaque type for each type we
// are about to read.  This means that forward references will resolve to
// something and when we reread the type later, we can replace the opaque type
// with a new resolved concrete type.
//
bool BytecodeParser::parseTypeConstants(const uchar *&Buf, const uchar *EndBuf,
					TypeValuesListTy &Tab,
					unsigned NumEntries) {
  assert(Tab.size() == 0 && "should not have read type constants in before!");

  // Insert a bunch of opaque types to be resolved later...
  for (unsigned i = 0; i < NumEntries; i++)
    Tab.push_back(PATypeHandle<Type>(OpaqueType::get(), this));

  // Loop through reading all of the types.  Forward types will make use of the
  // opaque types just inserted.
  //
  for (unsigned i = 0; i < NumEntries; i++) {
    const Type *NewTy = parseTypeConstant(Buf, EndBuf), *OldTy = Tab[i].get();
    if (NewTy == 0) return failure(true);
    BCR_TRACE(4, "Read Type Constant: '" << NewTy << "'\n");

    // Don't insertValue the new type... instead we want to replace the opaque
    // type with the new concrete value...
    //

    // Refine the abstract type to the new type.  This causes all uses of the
    // abstract type to use the newty.  This also will cause the opaque type
    // to be deleted...
    //
    cast<DerivedType>(Tab[i].get())->refineAbstractTypeTo(NewTy);

    // This should have replace the old opaque type with the new type in the
    // value table... or with a preexisting type that was already in the system
    assert(Tab[i] != OldTy && "refineAbstractType didn't work!");
  }

  BCR_TRACE(5, "Resulting types:\n");
  for (unsigned i = 0; i < NumEntries; i++) {
    BCR_TRACE(5, cast<const Type>(Tab[i]) << "\n");
  }
  return false;
}

bool BytecodeParser::parseConstPoolValue(const uchar *&Buf,
					 const uchar *EndBuf,
					 const Type *Ty, ConstPoolVal *&V) {
  switch (Ty->getPrimitiveID()) {
  case Type::BoolTyID: {
    unsigned Val;
    if (read_vbr(Buf, EndBuf, Val)) return failure(true);
    if (Val != 0 && Val != 1) return failure(true);
    V = ConstPoolBool::get(Val == 1);
    break;
  }

  case Type::UByteTyID:   // Unsigned integer types...
  case Type::UShortTyID:
  case Type::UIntTyID: {
    unsigned Val;
    if (read_vbr(Buf, EndBuf, Val)) return failure(true);
    if (!ConstPoolUInt::isValueValidForType(Ty, Val)) return failure(true);
    V = ConstPoolUInt::get(Ty, Val);
    break;
  }

  case Type::ULongTyID: {
    uint64_t Val;
    if (read_vbr(Buf, EndBuf, Val)) return failure(true);
    V = ConstPoolUInt::get(Ty, Val);
    break;
  }

  case Type::SByteTyID:   // Unsigned integer types...
  case Type::ShortTyID:
  case Type::IntTyID: {
    int Val;
    if (read_vbr(Buf, EndBuf, Val)) return failure(true);
    if (!ConstPoolSInt::isValueValidForType(Ty, Val)) return failure(true);
    V = ConstPoolSInt::get(Ty, Val);
    break;
  }

  case Type::LongTyID: {
    int64_t Val;
    if (read_vbr(Buf, EndBuf, Val)) return failure(true);
    V = ConstPoolSInt::get(Ty, Val);
    break;
  }

  case Type::FloatTyID: {
    float F;
    if (input_data(Buf, EndBuf, &F, &F+1)) return failure(true);
    V = ConstPoolFP::get(Ty, F);
    break;
  }

  case Type::DoubleTyID: {
    double Val;
    if (input_data(Buf, EndBuf, &Val, &Val+1)) return failure(true);
    V = ConstPoolFP::get(Ty, Val);
    break;
  }

  case Type::TypeTyID:
    assert(0 && "Type constants should be handled seperately!!!");
    abort();

  case Type::ArrayTyID: {
    const ArrayType *AT = cast<const ArrayType>(Ty);
    unsigned NumElements;
    if (AT->isSized())          // Sized array, # elements stored in type!
      NumElements = (unsigned)AT->getNumElements();
    else                        // Unsized array, # elements stored in stream!
      if (read_vbr(Buf, EndBuf, NumElements)) return failure(true);

    vector<ConstPoolVal *> Elements;
    while (NumElements--) {   // Read all of the elements of the constant.
      unsigned Slot;
      if (read_vbr(Buf, EndBuf, Slot)) return failure(true);
      Value *V = getValue(AT->getElementType(), Slot, false);
      if (!V || !isa<ConstPoolVal>(V)) return failure(true);
      Elements.push_back(cast<ConstPoolVal>(V));
    }
    V = ConstPoolArray::get(AT, Elements);
    break;
  }

  case Type::StructTyID: {
    const StructType *ST = cast<StructType>(Ty);
    const StructType::ElementTypes &ET = ST->getElementTypes();

    vector<ConstPoolVal *> Elements;
    for (unsigned i = 0; i < ET.size(); ++i) {
      unsigned Slot;
      if (read_vbr(Buf, EndBuf, Slot)) return failure(true);
      Value *V = getValue(ET[i], Slot, false);
      if (!V || !isa<ConstPoolVal>(V))
	return failure(true);
      Elements.push_back(cast<ConstPoolVal>(V));
    }

    V = ConstPoolStruct::get(ST, Elements);
    break;
  }

  case Type::PointerTyID: {
    const PointerType *PT = cast<const PointerType>(Ty);
    unsigned SubClass;
    if (read_vbr(Buf, EndBuf, SubClass)) return failure(true);
    switch (SubClass) {
    case 0:    // ConstPoolPointerNull value...
      V = ConstPoolPointerNull::get(PT);
      break;

    case 1: {  // ConstPoolPointerRef value...
      unsigned Slot;
      if (read_vbr(Buf, EndBuf, Slot)) return failure(true);
      BCR_TRACE(4, "CPPR: Type: '" << Ty << "'  slot: " << Slot << "\n");

      // Check to see if we have already read this global variable yet...
      Value *Val = getValue(PT, Slot, false);
      GlobalValue *GV;
      if (Val) {
	if (!(GV = dyn_cast<GlobalValue>(Val))) return failure(true);
	BCR_TRACE(5, "Value Found in ValueTable!\n");
      } else {         // Nope... see if we have previously forward ref'd it
	GlobalRefsType::iterator I = GlobalRefs.find(make_pair(PT, Slot));
	if (I != GlobalRefs.end()) {
	  BCR_TRACE(5, "Previous forward ref found!\n");
	  GV = I->second;
	} else {
	  BCR_TRACE(5, "Creating new forward ref variable!\n");

	  // Create a placeholder for the global variable reference...
	  GlobalVariable *GVar = new GlobalVariable(PT->getValueType(), false);

	  // Keep track of the fact that we have a forward ref to recycle it
	  GlobalRefs.insert(make_pair(make_pair(PT, Slot), GVar));

	  // Must temporarily push this value into the module table...
	  TheModule->getGlobalList().push_back(GVar);
	  GV = GVar;
	}
      }

      V = ConstPoolPointerRef::get(GV);
      break;
    }
    default:
      return failure(true);
    }
    break;
  }

  default:
    cerr << __FILE__ << ":" << __LINE__
	 << ": Don't know how to deserialize constant value of type '"
	 << Ty->getName() << "'\n";
    return failure(true);
  }

  return false;
}

bool BytecodeParser::ParseConstantPool(const uchar *&Buf, const uchar *EndBuf,
				       ValueTable &Tab,
				       TypeValuesListTy &TypeTab) {
  while (Buf < EndBuf) {
    unsigned NumEntries, Typ;

    if (read_vbr(Buf, EndBuf, NumEntries) ||
        read_vbr(Buf, EndBuf, Typ)) return failure(true);
    const Type *Ty = getType(Typ);
    if (Ty == 0) return failure(true);
    BCR_TRACE(3, "Type: '" << Ty << "'  NumEntries: " << NumEntries << "\n");

    if (Typ == Type::TypeTyID) {
      if (parseTypeConstants(Buf, EndBuf, TypeTab, NumEntries)) return true;
    } else {
      for (unsigned i = 0; i < NumEntries; i++) {
	ConstPoolVal *I;
	if (parseConstPoolValue(Buf, EndBuf, Ty, I)) return failure(true);
	BCR_TRACE(4, "Read Constant: '" << I << "'\n");
	if (insertValue(I, Tab) == -1) return failure(true);
      }
    }
  }

  if (Buf > EndBuf) return failure(true);
  return false;
}
<commit_msg>Frivolous cleanups<commit_after>//===- ReadConst.cpp - Code to constants and constant pools -----------------===
//
// This file implements functionality to deserialize constants and entire
// constant pools.
//
// Note that this library should be as fast as possible, reentrant, and
// threadsafe!!
//
//===------------------------------------------------------------------------===

#include "llvm/Module.h"
#include "llvm/BasicBlock.h"
#include "llvm/ConstPoolVals.h"
#include "llvm/DerivedTypes.h"
#include "llvm/GlobalVariable.h"
#include "ReaderInternals.h"
#include <algorithm>

const Type *BytecodeParser::parseTypeConstant(const uchar *&Buf,
					      const uchar *EndBuf) {
  unsigned PrimType;
  if (read_vbr(Buf, EndBuf, PrimType)) return failure<const Type*>(0);

  const Type *Val = 0;
  if ((Val = Type::getPrimitiveType((Type::PrimitiveID)PrimType)))
    return Val;

  switch (PrimType) {
  case Type::MethodTyID: {
    unsigned Typ;
    if (read_vbr(Buf, EndBuf, Typ)) return failure(Val);
    const Type *RetType = getType(Typ);
    if (RetType == 0) return failure(Val);

    unsigned NumParams;
    if (read_vbr(Buf, EndBuf, NumParams)) return failure(Val);

    vector<const Type*> Params;
    while (NumParams--) {
      if (read_vbr(Buf, EndBuf, Typ)) return failure(Val);
      const Type *Ty = getType(Typ);
      if (Ty == 0) return failure(Val);
      Params.push_back(Ty);
    }

    bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
    if (isVarArg) Params.pop_back();

    return MethodType::get(RetType, Params, isVarArg);
  }
  case Type::ArrayTyID: {
    unsigned ElTyp;
    if (read_vbr(Buf, EndBuf, ElTyp)) return failure(Val);
    const Type *ElementType = getType(ElTyp);
    if (ElementType == 0) return failure(Val);

    int NumElements;
    if (read_vbr(Buf, EndBuf, NumElements)) return failure(Val);

    BCR_TRACE(5, "Array Type Constant #" << ElTyp << " size="
              << NumElements << endl);
    return ArrayType::get(ElementType, NumElements);
  }
  case Type::StructTyID: {
    unsigned Typ;
    vector<const Type*> Elements;

    if (read_vbr(Buf, EndBuf, Typ)) return failure(Val);
    while (Typ) {         // List is terminated by void/0 typeid
      const Type *Ty = getType(Typ);
      if (Ty == 0) return failure(Val);
      Elements.push_back(Ty);

      if (read_vbr(Buf, EndBuf, Typ)) return failure(Val);
    }

    return StructType::get(Elements);
  }
  case Type::PointerTyID: {
    unsigned ElTyp;
    if (read_vbr(Buf, EndBuf, ElTyp)) return failure(Val);
    BCR_TRACE(5, "Pointer Type Constant #" << (ElTyp-14) << endl);
    const Type *ElementType = getType(ElTyp);
    if (ElementType == 0) return failure(Val);
    return PointerType::get(ElementType);
  }

  case Type::OpaqueTyID: {
    return OpaqueType::get();
  }

  default:
    cerr << __FILE__ << ":" << __LINE__ << ": Don't know how to deserialize"
         << " primitive Type " << PrimType << "\n";
    return failure(Val);
  }
}

// refineAbstractType - The callback method is invoked when one of the
// elements of TypeValues becomes more concrete...
//
void BytecodeParser::refineAbstractType(const DerivedType *OldType,
					const Type *NewType) {
  if (OldType == NewType) return;  // Type is modified, but same

  TypeValuesListTy::iterator I = find(MethodTypeValues.begin(),
				      MethodTypeValues.end(), OldType);
  if (I == MethodTypeValues.end()) {
    I = find(ModuleTypeValues.begin(), ModuleTypeValues.end(), OldType);
    assert(I != ModuleTypeValues.end() &&
	   "Can't refine a type I don't know about!");
  }

  *I = NewType;  // Update to point to new, more refined type.
}

// parseTypeConstants - We have to use this wierd code to handle recursive
// types.  We know that recursive types will only reference the current slab of
// values in the type plane, but they can forward reference types before they
// have been read.  For example, Type #0 might be '{ Ty#1 }' and Type #1 might
// be 'Ty#0*'.  When reading Type #0, type number one doesn't exist.  To fix
// this ugly problem, we pesimistically insert an opaque type for each type we
// are about to read.  This means that forward references will resolve to
// something and when we reread the type later, we can replace the opaque type
// with a new resolved concrete type.
//
bool BytecodeParser::parseTypeConstants(const uchar *&Buf, const uchar *EndBuf,
					TypeValuesListTy &Tab,
					unsigned NumEntries) {
  assert(Tab.size() == 0 && "should not have read type constants in before!");

  // Insert a bunch of opaque types to be resolved later...
  for (unsigned i = 0; i < NumEntries; ++i)
    Tab.push_back(PATypeHandle<Type>(OpaqueType::get(), this));

  // Loop through reading all of the types.  Forward types will make use of the
  // opaque types just inserted.
  //
  for (unsigned i = 0; i < NumEntries; ++i) {
    const Type *NewTy = parseTypeConstant(Buf, EndBuf), *OldTy = Tab[i].get();
    if (NewTy == 0) return failure(true);
    BCR_TRACE(4, "#" << i << ": Read Type Constant: '" << NewTy <<
              "' Replacing: " << OldTy << "\n");

    // Don't insertValue the new type... instead we want to replace the opaque
    // type with the new concrete value...
    //

    // Refine the abstract type to the new type.  This causes all uses of the
    // abstract type to use the newty.  This also will cause the opaque type
    // to be deleted...
    //
    cast<DerivedType>(Tab[i].get())->refineAbstractTypeTo(NewTy);

    // This should have replace the old opaque type with the new type in the
    // value table... or with a preexisting type that was already in the system
    assert(Tab[i] != OldTy && "refineAbstractType didn't work!");
  }

  BCR_TRACE(5, "Resulting types:\n");
  for (unsigned i = 0; i < NumEntries; ++i) {
    BCR_TRACE(5, cast<const Type>(Tab[i]) << "\n");
  }
  return false;
}

bool BytecodeParser::parseConstPoolValue(const uchar *&Buf,
					 const uchar *EndBuf,
					 const Type *Ty, ConstPoolVal *&V) {
  switch (Ty->getPrimitiveID()) {
  case Type::BoolTyID: {
    unsigned Val;
    if (read_vbr(Buf, EndBuf, Val)) return failure(true);
    if (Val != 0 && Val != 1) return failure(true);
    V = ConstPoolBool::get(Val == 1);
    break;
  }

  case Type::UByteTyID:   // Unsigned integer types...
  case Type::UShortTyID:
  case Type::UIntTyID: {
    unsigned Val;
    if (read_vbr(Buf, EndBuf, Val)) return failure(true);
    if (!ConstPoolUInt::isValueValidForType(Ty, Val)) return failure(true);
    V = ConstPoolUInt::get(Ty, Val);
    break;
  }

  case Type::ULongTyID: {
    uint64_t Val;
    if (read_vbr(Buf, EndBuf, Val)) return failure(true);
    V = ConstPoolUInt::get(Ty, Val);
    break;
  }

  case Type::SByteTyID:   // Unsigned integer types...
  case Type::ShortTyID:
  case Type::IntTyID: {
    int Val;
    if (read_vbr(Buf, EndBuf, Val)) return failure(true);
    if (!ConstPoolSInt::isValueValidForType(Ty, Val)) return failure(true);
    V = ConstPoolSInt::get(Ty, Val);
    break;
  }

  case Type::LongTyID: {
    int64_t Val;
    if (read_vbr(Buf, EndBuf, Val)) return failure(true);
    V = ConstPoolSInt::get(Ty, Val);
    break;
  }

  case Type::FloatTyID: {
    float F;
    if (input_data(Buf, EndBuf, &F, &F+1)) return failure(true);
    V = ConstPoolFP::get(Ty, F);
    break;
  }

  case Type::DoubleTyID: {
    double Val;
    if (input_data(Buf, EndBuf, &Val, &Val+1)) return failure(true);
    V = ConstPoolFP::get(Ty, Val);
    break;
  }

  case Type::TypeTyID:
    assert(0 && "Type constants should be handled seperately!!!");
    abort();

  case Type::ArrayTyID: {
    const ArrayType *AT = cast<const ArrayType>(Ty);
    unsigned NumElements;
    if (AT->isSized())          // Sized array, # elements stored in type!
      NumElements = (unsigned)AT->getNumElements();
    else                        // Unsized array, # elements stored in stream!
      if (read_vbr(Buf, EndBuf, NumElements)) return failure(true);

    vector<ConstPoolVal *> Elements;
    while (NumElements--) {   // Read all of the elements of the constant.
      unsigned Slot;
      if (read_vbr(Buf, EndBuf, Slot)) return failure(true);
      Value *V = getValue(AT->getElementType(), Slot, false);
      if (!V || !isa<ConstPoolVal>(V)) return failure(true);
      Elements.push_back(cast<ConstPoolVal>(V));
    }
    V = ConstPoolArray::get(AT, Elements);
    break;
  }

  case Type::StructTyID: {
    const StructType *ST = cast<StructType>(Ty);
    const StructType::ElementTypes &ET = ST->getElementTypes();

    vector<ConstPoolVal *> Elements;
    for (unsigned i = 0; i < ET.size(); ++i) {
      unsigned Slot;
      if (read_vbr(Buf, EndBuf, Slot)) return failure(true);
      Value *V = getValue(ET[i], Slot, false);
      if (!V || !isa<ConstPoolVal>(V))
	return failure(true);
      Elements.push_back(cast<ConstPoolVal>(V));
    }

    V = ConstPoolStruct::get(ST, Elements);
    break;
  }

  case Type::PointerTyID: {
    const PointerType *PT = cast<const PointerType>(Ty);
    unsigned SubClass;
    if (read_vbr(Buf, EndBuf, SubClass)) return failure(true);
    switch (SubClass) {
    case 0:    // ConstPoolPointerNull value...
      V = ConstPoolPointerNull::get(PT);
      break;

    case 1: {  // ConstPoolPointerRef value...
      unsigned Slot;
      if (read_vbr(Buf, EndBuf, Slot)) return failure(true);
      BCR_TRACE(4, "CPPR: Type: '" << Ty << "'  slot: " << Slot << "\n");

      // Check to see if we have already read this global variable yet...
      Value *Val = getValue(PT, Slot, false);
      GlobalValue *GV;
      if (Val) {
	if (!(GV = dyn_cast<GlobalValue>(Val))) return failure(true);
	BCR_TRACE(5, "Value Found in ValueTable!\n");
      } else {         // Nope... see if we have previously forward ref'd it
	GlobalRefsType::iterator I = GlobalRefs.find(make_pair(PT, Slot));
	if (I != GlobalRefs.end()) {
	  BCR_TRACE(5, "Previous forward ref found!\n");
	  GV = I->second;
	} else {
	  BCR_TRACE(5, "Creating new forward ref variable!\n");

	  // Create a placeholder for the global variable reference...
	  GlobalVariable *GVar = new GlobalVariable(PT->getValueType(), false);

	  // Keep track of the fact that we have a forward ref to recycle it
	  GlobalRefs.insert(make_pair(make_pair(PT, Slot), GVar));

	  // Must temporarily push this value into the module table...
	  TheModule->getGlobalList().push_back(GVar);
	  GV = GVar;
	}
      }

      V = ConstPoolPointerRef::get(GV);
      break;
    }
    default:
      return failure(true);
    }
    break;
  }

  default:
    cerr << __FILE__ << ":" << __LINE__
	 << ": Don't know how to deserialize constant value of type '"
	 << Ty->getName() << "'\n";
    return failure(true);
  }

  return false;
}

bool BytecodeParser::ParseConstantPool(const uchar *&Buf, const uchar *EndBuf,
				       ValueTable &Tab,
				       TypeValuesListTy &TypeTab) {
  while (Buf < EndBuf) {
    unsigned NumEntries, Typ;

    if (read_vbr(Buf, EndBuf, NumEntries) ||
        read_vbr(Buf, EndBuf, Typ)) return failure(true);
    const Type *Ty = getType(Typ);
    if (Ty == 0) return failure(true);
    BCR_TRACE(3, "Type: '" << Ty << "'  NumEntries: " << NumEntries << "\n");

    if (Typ == Type::TypeTyID) {
      if (parseTypeConstants(Buf, EndBuf, TypeTab, NumEntries)) return true;
    } else {
      for (unsigned i = 0; i < NumEntries; ++i) {
	ConstPoolVal *I;
	if (parseConstPoolValue(Buf, EndBuf, Ty, I)) return failure(true);
	BCR_TRACE(4, "Read Constant: '" << I << "'\n");
	if (insertValue(I, Tab) == -1) return failure(true);
      }
    }
  }

  if (Buf > EndBuf) return failure(true);
  return false;
}
<|endoftext|>


<commit_before>//===- diagtool_main.h - Entry point for invoking all diagnostic tools ----===//
//
//                     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 main function for diagtool.
//
//===----------------------------------------------------------------------===//

#include "DiagTool.h"

using namespace diagtool;

int main(int argc, char *argv[]) {
  if (argc > 1)
    if (DiagTool *tool = diagTools->getTool(argv[1]))
      return tool->run(argc - 1, &argv[2], llvm::errs());

  llvm::errs() << "usage: diagtool <command> [<args>]\n\n";
  diagTools->printCommands(llvm::errs());
  return 1;
}
<commit_msg>[diagtool] The driver skips two arguments, not one.<commit_after>//===- diagtool_main.h - Entry point for invoking all diagnostic tools ----===//
//
//                     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 main function for diagtool.
//
//===----------------------------------------------------------------------===//

#include "DiagTool.h"

using namespace diagtool;

int main(int argc, char *argv[]) {
  if (argc > 1)
    if (DiagTool *tool = diagTools->getTool(argv[1]))
      return tool->run(argc - 2, &argv[2], llvm::errs());

  llvm::errs() << "usage: diagtool <command> [<args>]\n\n";
  diagTools->printCommands(llvm::errs());
  return 1;
}
<|endoftext|>


<commit_before>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2018 IncludeOS AS, Oslo, Norway
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once
#ifndef POSIX_UNIX_FD_HPP
#define POSIX_UNIX_FD_HPP

#include "sockfd.hpp"
#include "unix_fd_impl.hpp"
#include <sys/socket.h>

class Unix_FD : public SockFD {
public:
  using Impl = Unix_FD_impl;
  Unix_FD(int id, int type)
    : SockFD(id), type_(type)
  {
  }

  /** SOCKET */
  long    connect(const struct sockaddr *, socklen_t) override;
  ssize_t sendto(const void* buf, size_t, int fl,
                 const struct sockaddr* addr, socklen_t addrlen) override;
  int     close() override;
private:
  Impl* impl = nullptr;
  const int type_ [[maybe_unused]]; // it's probably gonna be necessary
                                    // to tell if socket is stream or dgram

  long set_impl_if_needed(const struct sockaddr* addr, socklen_t addrlen);
};

#endif
<commit_msg>fd: Fix warning in unix_fd<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2018 IncludeOS AS, Oslo, Norway
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once
#ifndef POSIX_UNIX_FD_HPP
#define POSIX_UNIX_FD_HPP

#include "sockfd.hpp"
#include "unix_fd_impl.hpp"
#include <sys/socket.h>

class Unix_FD : public SockFD {
public:
  using Impl = Unix_FD_impl;
  Unix_FD(int id, int type)
    : SockFD(id), type_(type)
  {
  }

  /** SOCKET */
  long    connect(const struct sockaddr *, socklen_t) override;
  ssize_t sendto(const void* buf, size_t, int fl,
                 const struct sockaddr* addr, socklen_t addrlen) override;
  int     close() override;
private:
  Impl* impl = nullptr;
  const int type_; // it's probably gonna be necessary
                   // to tell if socket is stream or dgram

  long set_impl_if_needed(const struct sockaddr* addr, socklen_t addrlen);
};

#endif
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 WinT 3794 <http://wint3794.org>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

//=============================================================================
// System includes
//=============================================================================

#include <QList>

//=============================================================================
// Library includes
//=============================================================================

#include "LibDS/Core/ProtocolBase.h"
#include "LibDS/Core/ProtocolManager.h"

//=============================================================================
// DS_ProtocolManager::DS_ProtocolManager
//=============================================================================

DS_ProtocolManager::DS_ProtocolManager()
{
    m_protocol = Q_NULLPTR;
    m_joysticks = new QList<DS_Joystick*>;
}

//=============================================================================
// DS_ProtocolManager::~DS_ProtocolManager
//=============================================================================

DS_ProtocolManager::~DS_ProtocolManager()
{
    delete m_protocol;
    delete m_joysticks;
}

//=============================================================================
// DS_ProtocolManager::currentProtocol
//=============================================================================

DS_ProtocolBase* DS_ProtocolManager::currentProtocol() const
{
    return isValid() ? m_protocol : Q_NULLPTR;
}

//=============================================================================
// DS_ProtocolManager::isValid
//=============================================================================

bool DS_ProtocolManager::isValid() const
{
    return (m_protocol != Q_NULLPTR);
}

//=============================================================================
// DS_ProtocolManager::joystickCount
//=============================================================================

int DS_ProtocolManager::joystickCount() const
{
    return isValid() ? currentProtocol()->joysticks()->count() : 0;
}

//=============================================================================
// DS_ProtocolManager::setProtocol
//=============================================================================

void DS_ProtocolManager::setProtocol (DS_ProtocolBase* protocol)
{
    if (protocol != Q_NULLPTR)
        {
            delete m_protocol;
            m_protocol = protocol;
            m_protocol->setJoysticks (m_joysticks);

            connect (m_protocol, SIGNAL (emergencyStopped       (void)),
                     this,       SIGNAL (emergencyStopped       (void)));
            connect (m_protocol, SIGNAL (codeChanged            (bool)),
                     this,       SIGNAL (codeChanged            (bool)));
            connect (m_protocol, SIGNAL (radioCommChanged       (bool)),
                     this,       SIGNAL (radioCommChanged       (bool)));
            connect (m_protocol, SIGNAL (communicationsChanged  (DS_CommStatus)),
                     this,       SIGNAL (communicationsChanged  (DS_CommStatus)));
            connect (m_protocol, SIGNAL (robotAddressChanged    (QString)),
                     this,       SIGNAL (robotAddressChanged    (QString)));
            connect (m_protocol, SIGNAL (controlModeChanged     (DS_ControlMode)),
                     this,       SIGNAL (controlModeChanged     (DS_ControlMode)));
            connect (m_protocol, SIGNAL (diskUsageChanged       (int)),
                     this,       SIGNAL (diskUsageChanged       (int)));
            connect (m_protocol, SIGNAL (ramUsageChanged        (int)),
                     this,       SIGNAL (ramUsageChanged        (int)));
            connect (m_protocol, SIGNAL (cpuUsageChanged        (int)),
                     this,       SIGNAL (cpuUsageChanged        (int)));
            connect (m_protocol, SIGNAL (voltageChanged         (QString)),
                     this,       SIGNAL (voltageChanged         (QString)));
            connect (m_protocol, SIGNAL (voltageBrownoutChanged (bool)),
                     this,       SIGNAL (voltageBrownoutChanged (bool)));
            connect (m_protocol, SIGNAL (CANInfoReceived        (DS_CAN)),
                     this,       SIGNAL (CANInfoReceived        (DS_CAN)));
            connect (m_protocol, SIGNAL (fmsChanged             (bool)),
                     this,       SIGNAL (fmsChanged             (bool)));

            m_protocol->setRobotAddress ("127.0.0.1");
        }
}

//=============================================================================
// DS_ProtocolManager::resetJoysticks
//=============================================================================

void DS_ProtocolManager::resetJoysticks()
{
    m_joysticks->clear();

    if (isValid())
        currentProtocol()->onJoysticksChanged();
}

//=============================================================================
// DS_ProtocolManager::addJoystick
//=============================================================================

void DS_ProtocolManager::addJoystick (int axes, int buttons, int POVs)
{
    DS_Joystick* js = new DS_Joystick;

    js->numAxes = axes;
    js->numPOVs = POVs;
    js->numButtons = buttons;

    js->axes = new double  [axes];
    js->POVs = new int  [POVs];
    js->buttons = new bool [buttons];

    for (int i = 0; i < js->numAxes; i++)
        js->axes [i] = 0;

    for (int i = 0; i < js->numPOVs; i++)
        js->POVs [i] = -1;

    for (int i = 0; i < js->numButtons; i++)
        js->buttons [i] = false;

    m_joysticks->append (js);

    if (isValid())
        currentProtocol()->onJoysticksChanged();
}

//=============================================================================
// DS_ProtocolManager::updateJoystickPOV
//=============================================================================

void DS_ProtocolManager::updateJoystickPOV (int js, int hat, int angle)
{
    if (joystickExists (js))
        m_joysticks->at (js)->POVs [hat] = angle;
}

//=============================================================================
// DS_ProtocolManager::updateJoystickAxis
//=============================================================================

void DS_ProtocolManager::updateJoystickAxis (int js, int axis, double value)
{
    if (joystickExists (js))
        m_joysticks->at (js)->axes [axis] = value;
}

//=============================================================================
// DS_ProtocolManager::updateJoystickButton
//=============================================================================

void DS_ProtocolManager::updateJoystickButton (int js, int bt, bool status)
{
    if (joystickExists (js))
        m_joysticks->at (js)->buttons [bt] = status;
}

//=============================================================================
// DS_ProtocolManager::readRobotPacket
//=============================================================================

void DS_ProtocolManager::readRobotPacket (QByteArray data)
{
    if (isValid())
        currentProtocol()->readRobotPacket (data);
}

//=============================================================================
// DS_ProtocolManager::joystickExists
//=============================================================================

bool DS_ProtocolManager::joystickExists (int js) const
{
    return (js < m_joysticks->count());
}
<commit_msg>Update ProtocolManager.cpp<commit_after>/*
 * Copyright (c) 2015 WinT 3794 <http://wint3794.org>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

//=============================================================================
// System includes
//=============================================================================

#include <QList>

//=============================================================================
// Library includes
//=============================================================================

#include "LibDS/Core/ProtocolBase.h"
#include "LibDS/Core/ProtocolManager.h"

//=============================================================================
// DS_ProtocolManager::DS_ProtocolManager
//=============================================================================

DS_ProtocolManager::DS_ProtocolManager()
{
    m_protocol = Q_NULLPTR;
    m_joysticks = new QList<DS_Joystick*>;
}

//=============================================================================
// DS_ProtocolManager::~DS_ProtocolManager
//=============================================================================

DS_ProtocolManager::~DS_ProtocolManager()
{
    delete m_protocol;
    delete m_joysticks;
}

//=============================================================================
// DS_ProtocolManager::currentProtocol
//=============================================================================

DS_ProtocolBase* DS_ProtocolManager::currentProtocol() const
{
    return isValid() ? m_protocol : Q_NULLPTR;
}

//=============================================================================
// DS_ProtocolManager::isValid
//=============================================================================

bool DS_ProtocolManager::isValid() const
{
    return (m_protocol != Q_NULLPTR);
}

//=============================================================================
// DS_ProtocolManager::joystickCount
//=============================================================================

int DS_ProtocolManager::joystickCount() const
{
    return isValid() ? currentProtocol()->joysticks()->count() : 0;
}

//=============================================================================
// DS_ProtocolManager::setProtocol
//=============================================================================

void DS_ProtocolManager::setProtocol (DS_ProtocolBase* protocol)
{
    if (protocol != Q_NULLPTR)
        {
            delete m_protocol;
            m_protocol = protocol;
            m_protocol->setJoysticks (m_joysticks);

            connect (m_protocol, SIGNAL (emergencyStopped       (void)),
                     this,       SIGNAL (emergencyStopped       (void)));
            connect (m_protocol, SIGNAL (codeChanged            (bool)),
                     this,       SIGNAL (codeChanged            (bool)));
            connect (m_protocol, SIGNAL (radioCommChanged       (bool)),
                     this,       SIGNAL (radioCommChanged       (bool)));
            connect (m_protocol, SIGNAL (communicationsChanged  (DS_CommStatus)),
                     this,       SIGNAL (communicationsChanged  (DS_CommStatus)));
            connect (m_protocol, SIGNAL (robotAddressChanged    (QString)),
                     this,       SIGNAL (robotAddressChanged    (QString)));
            connect (m_protocol, SIGNAL (controlModeChanged     (DS_ControlMode)),
                     this,       SIGNAL (controlModeChanged     (DS_ControlMode)));
            connect (m_protocol, SIGNAL (diskUsageChanged       (int)),
                     this,       SIGNAL (diskUsageChanged       (int)));
            connect (m_protocol, SIGNAL (ramUsageChanged        (int)),
                     this,       SIGNAL (ramUsageChanged        (int)));
            connect (m_protocol, SIGNAL (cpuUsageChanged        (int)),
                     this,       SIGNAL (cpuUsageChanged        (int)));
            connect (m_protocol, SIGNAL (voltageChanged         (QString)),
                     this,       SIGNAL (voltageChanged         (QString)));
            connect (m_protocol, SIGNAL (voltageBrownoutChanged (bool)),
                     this,       SIGNAL (voltageBrownoutChanged (bool)));
            connect (m_protocol, SIGNAL (CANInfoReceived        (DS_CAN)),
                     this,       SIGNAL (CANInfoReceived        (DS_CAN)));
            connect (m_protocol, SIGNAL (fmsChanged             (bool)),
                     this,       SIGNAL (fmsChanged             (bool)));
        }
}

//=============================================================================
// DS_ProtocolManager::resetJoysticks
//=============================================================================

void DS_ProtocolManager::resetJoysticks()
{
    m_joysticks->clear();

    if (isValid())
        currentProtocol()->onJoysticksChanged();
}

//=============================================================================
// DS_ProtocolManager::addJoystick
//=============================================================================

void DS_ProtocolManager::addJoystick (int axes, int buttons, int POVs)
{
    DS_Joystick* js = new DS_Joystick;

    js->numAxes = axes;
    js->numPOVs = POVs;
    js->numButtons = buttons;

    js->axes = new double  [axes];
    js->POVs = new int  [POVs];
    js->buttons = new bool [buttons];

    for (int i = 0; i < js->numAxes; i++)
        js->axes [i] = 0;

    for (int i = 0; i < js->numPOVs; i++)
        js->POVs [i] = -1;

    for (int i = 0; i < js->numButtons; i++)
        js->buttons [i] = false;

    m_joysticks->append (js);

    if (isValid())
        currentProtocol()->onJoysticksChanged();
}

//=============================================================================
// DS_ProtocolManager::updateJoystickPOV
//=============================================================================

void DS_ProtocolManager::updateJoystickPOV (int js, int hat, int angle)
{
    if (joystickExists (js))
        m_joysticks->at (js)->POVs [hat] = angle;
}

//=============================================================================
// DS_ProtocolManager::updateJoystickAxis
//=============================================================================

void DS_ProtocolManager::updateJoystickAxis (int js, int axis, double value)
{
    if (joystickExists (js))
        m_joysticks->at (js)->axes [axis] = value;
}

//=============================================================================
// DS_ProtocolManager::updateJoystickButton
//=============================================================================

void DS_ProtocolManager::updateJoystickButton (int js, int bt, bool status)
{
    if (joystickExists (js))
        m_joysticks->at (js)->buttons [bt] = status;
}

//=============================================================================
// DS_ProtocolManager::readRobotPacket
//=============================================================================

void DS_ProtocolManager::readRobotPacket (QByteArray data)
{
    if (isValid())
        currentProtocol()->readRobotPacket (data);
}

//=============================================================================
// DS_ProtocolManager::joystickExists
//=============================================================================

bool DS_ProtocolManager::joystickExists (int js) const
{
    return (js < m_joysticks->count());
}
<|endoftext|>


<commit_before>/**************************************************************************
** This file is part of LiteIDE
**
** Copyright (c) 2011-2016 LiteIDE Team. All rights reserved.
**
** 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.
**
** In addition, as a special exception,  that plugins developed for LiteIDE,
** are allowed to remain closed sourced and can be distributed under any license .
** These rights are included in the file LGPL_EXCEPTION.txt in this package.
**
**************************************************************************/
// Module: filesearch.cpp
// Creator: visualfc <visualfc@gmail.com>

#include "filesearch.h"
#include "litefind_global.h"
#include <QFile>
#include <QTableWidget>
#include <QTextStream>
#include <QTextDocument>
#include <QRegExp>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QComboBox>
#include <QCheckBox>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QDir>
#include <QTextBlock>
#include <QTextCursor>
#include <QPlainTextEdit>
#include <QTextBrowser>
#include <QFileDialog>
#include <QAction>
#include <QDebug>
//lite_memory_check_begin
#if defined(WIN32) && defined(_MSC_VER) &&  defined(_DEBUG)
     #define _CRTDBG_MAP_ALLOC
     #include <stdlib.h>
     #include <crtdbg.h>
     #define DEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
     #define new DEBUG_NEW
#endif
//lite_memory_check_end

FindThread::FindThread(QObject *parent) :
    QThread(parent),
    useRegExp(true),
    matchWord(true),
    matchCase(true),
    findSub(true)
{
    qRegisterMetaType<LiteApi::FileSearchResult>("LiteApi::FileSearchResult");
}

void FindThread::findDir(const QRegExp &reg, const QString &path)
{
    QDir dir(path);
    if (!dir.exists()) {
        return;
    }

    foreach(QFileInfo info, dir.entryInfoList(nameFilter,QDir::Files|QDir::NoSymLinks)) {
        findFile(reg,info.filePath());
        if (!finding) {
            return;
        }
    }
    if (findSub) {
        foreach(QFileInfo info, dir.entryInfoList(QDir::Dirs|QDir::NoDotAndDotDot)) {
            findDir(reg,info.filePath());
            if(!finding) {
                return;
            }
        }
    }
}

void FindThread::findFile(const QRegExp &reg, const QString &fileName)
{
    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly)) {
        return;
    }

    QTextStream stream(&file);
    stream.setCodec("utf-8");
    QString line;
    int lineNr = 1;
    while (!stream.atEnd()) {
        line = stream.readLine();
        int pos = 0;
        while ((pos = reg.indexIn(line, pos)) != -1) {
            if (!useRegExp && matchWord) {
                const int start = pos;
                const int end = start + reg.matchedLength();
                if ((start != 0 && line.at(start - 1).isLetterOrNumber())
                        || (end != line.length() && line.at(end).isLetterOrNumber())) {
                    //if this is not a whole word, continue the search in the string
                    pos = end+1;
                    continue;
                }
            }
            emit findResult(LiteApi::FileSearchResult(fileName, line,lineNr,pos, reg.matchedLength()));
            pos += reg.matchedLength();
        }
        lineNr++;
        if (!finding) {
            break;
        }
    }
}

void FindThread::stop()
{
    finding = false;
    if (this->isRunning()) {
        if (!this->wait(200))
            this->terminate();
    }
}

void FindThread::run()
{
    finding = true;
    QRegExp reg;
    reg.setCaseSensitivity(matchCase ? Qt::CaseSensitive : Qt::CaseInsensitive);

    if (useRegExp) {
        if (matchWord) {
            reg.setPattern(QString::fromLatin1("\\b%1\\b").arg(findText));
        } else {
            reg.setPattern(findText);
        }
    } else {
       reg.setPattern(findText);
       reg.setPatternSyntax(QRegExp::FixedString);
    }
    findDir(reg,findPath);
    finding = false;
}

ResultTextEdit::ResultTextEdit(QWidget *parent) :
    QPlainTextEdit(parent)
{
    this->setWordWrapMode(QTextOption::NoWrap);

    connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(slotCursorPositionChanged()));
}

void ResultTextEdit::slotCursorPositionChanged()
{
    QList<QTextEdit::ExtraSelection> extraSelections;

    QTextEdit::ExtraSelection selection;

    QColor lineColor = QColor(180,200,200,128);

    selection.format.setBackground(lineColor);
    selection.format.setProperty(QTextFormat::FullWidthSelection, true);
    selection.cursor = textCursor();
    selection.cursor.clearSelection();
    extraSelections.append(selection);

    setExtraSelections(extraSelections);
}

void ResultTextEdit::mouseDoubleClickEvent(QMouseEvent *e)
{
    QTextCursor cur = cursorForPosition(e->pos());
    cur.select(QTextCursor::LineUnderCursor);

    emit dbclickEvent(cur);
}

FileSearch::FileSearch(LiteApi::IApplication *app, QObject *parent) :
    LiteApi::IFileSearch(parent),
    m_liteApp(app)
{
    m_thread = new FindThread;

    m_findWidget = new QWidget;

    QGridLayout *topLayout = new QGridLayout;
    topLayout->setSpacing(1);

    m_findCombo = new QComboBox;
    m_findCombo->setEditable(true);
    m_findCombo->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Preferred);

    QHBoxLayout *optLayout = new QHBoxLayout;
    m_matchWordCheckBox = new QCheckBox(tr("Match whole word"));
    m_matchCaseCheckBox = new QCheckBox(tr("Match case"));
    m_useRegexCheckBox = new QCheckBox(tr("Regular expression"));
    m_findSubCheckBox = new QCheckBox(tr("Scan subdirectories"));
    optLayout->addWidget(m_matchWordCheckBox);
    optLayout->addWidget(m_matchCaseCheckBox);
    optLayout->addWidget(m_useRegexCheckBox);
    optLayout->addWidget(m_findSubCheckBox);
    optLayout->addStretch();

    QHBoxLayout *findLayout = new QHBoxLayout;
    //findLayout->setMargin(0);
    m_findButton = new QPushButton(tr("Search"));
    m_stopButton = new QPushButton(tr("Cancel"));
    m_stopButton->setEnabled(false);
    //findLayout->addWidget();
    findLayout->addWidget(m_findCombo);
    findLayout->addWidget(m_findButton);
    findLayout->addWidget(m_stopButton);
    //findLayout->addStretch(0);
    //topLayout->addLayout(findLayout,4,1);

    topLayout->addWidget(new QLabel(tr("Search for:")),0,0);
    topLayout->addLayout(findLayout,0,1);
    topLayout->addWidget(new QLabel(tr("Options:")),1,0);
    topLayout->addLayout(optLayout,1,1);

    QHBoxLayout *dirLayout = new QHBoxLayout;
    m_findPathCombo = new QComboBox;
    m_findPathCombo->setEditable(true);
    QPushButton *browserBtn = new QPushButton(tr("Browse..."));
    QPushButton *currentBtn = new QPushButton(tr("Current Folder"));

    m_autoSwitchPathCheckBox = new QCheckBox;
    m_autoSwitchPathCheckBox->setText(tr("Auto Switch"));

    dirLayout->addWidget(m_findPathCombo,1);
    dirLayout->addWidget(m_autoSwitchPathCheckBox);
    dirLayout->addWidget(currentBtn);
    dirLayout->addWidget(browserBtn);

    topLayout->addWidget(new QLabel("Directory:"),2,0);
    topLayout->addLayout(dirLayout,2,1);

    m_filterCombo = new QComboBox;
    m_filterCombo->setEditable(true);

    m_filterCombo->addItem("*.go");
    m_filterCombo->addItem("*.lua;*.wlua");
    m_filterCombo->addItem("*.c;*.cpp;*.cxx;*.cc;*.c++;*.h;*.hpp;*.hh;*.hxx;*.h++;*.hcc;*.moc");
    m_filterCombo->addItem("*.htm;*.html;*.shtml;*.shtm");
    m_filterCombo->addItem("*");

    topLayout->addWidget(new QLabel(tr("Filter:")),3,0);
    topLayout->addWidget(m_filterCombo,3,1);

    m_findWidget->setLayout(topLayout);

    QAction *clearAct = new QAction(tr("Clear"),this);
    clearAct->setIcon(QIcon("icon:images/cleanoutput.png"));

    m_findPathCombo->setEditText(QDir::homePath());
    m_liteApp->settings()->beginGroup("findfiles");
    m_matchWordCheckBox->setChecked(m_liteApp->settings()->value("matchWord",false).toBool());
    m_matchCaseCheckBox->setChecked(m_liteApp->settings()->value("matchCase",false).toBool());
    m_useRegexCheckBox->setChecked(m_liteApp->settings()->value("useRegexp",false).toBool());
    m_findSubCheckBox->setChecked(m_liteApp->settings()->value("findSub",true).toBool());
    m_liteApp->settings()->endGroup();

    connect(browserBtn,SIGNAL(clicked()),this,SLOT(browser()));
    connect(currentBtn,SIGNAL(clicked()),this,SLOT(currentDir()));
    connect(m_findButton,SIGNAL(clicked()),this,SLOT(findInFiles()));
    connect(m_stopButton,SIGNAL(clicked()),m_thread,SLOT(stop()));
    connect(m_thread,SIGNAL(started()),this,SIGNAL(findStarted()));
    connect(m_thread,SIGNAL(finished()),this,SIGNAL(findFinished()));
    connect(m_thread,SIGNAL(findResult(LiteApi::FileSearchResult)),this,SIGNAL(findResult(LiteApi::FileSearchResult)));
    connect(m_findCombo->lineEdit(),SIGNAL(returnPressed()),this,SLOT(findInFiles()));

    bool b = m_liteApp->settings()->value(FILESEARCH_AUTOSWITCHDIR,true).toBool();
    m_autoSwitchPathCheckBox->setChecked(b);
}

FileSearch::~FileSearch()
{
    m_liteApp->settings()->beginGroup("findfiles");
    m_liteApp->settings()->setValue("matchWord",m_matchWordCheckBox->isChecked());
    m_liteApp->settings()->setValue("matchCase",m_matchCaseCheckBox->isChecked());
    m_liteApp->settings()->setValue("useRegexp",m_useRegexCheckBox->isChecked());
    m_liteApp->settings()->setValue("findSub",m_findSubCheckBox->isChecked());
    m_liteApp->settings()->endGroup();

    m_liteApp->settings()->setValue(FILESEARCH_AUTOSWITCHDIR,m_autoSwitchPathCheckBox->isChecked());

    if (m_thread) {
        m_thread->stop();
        delete m_thread;
    }
    if (m_findWidget) {
        delete m_findWidget;
    }
}

void FileSearch::setVisible(bool b)
{
    if (b) {
        LiteApi::IProject *proj = m_liteApp->projectManager()->currentProject();
        if (proj && !LiteApi::mimeIsFolder(proj->mimeType())) {
            QFileInfo info(proj->filePath());
            if (info.isDir())
                m_findPathCombo->setEditText(info.filePath());
            else
                m_findPathCombo->setEditText(info.path());
        }
        m_findCombo->setFocus();
        m_findCombo->lineEdit()->selectAll();
        LiteApi::IEditor *editor = m_liteApp->editorManager()->currentEditor();
        if (editor) {
            QString text;
            QPlainTextEdit *ed = LiteApi::findExtensionObject<QPlainTextEdit*>(editor,"LiteApi.QPlainTextEdit");
            if (ed) {
                text = ed->textCursor().selectedText();
            } else {
                QTextBrowser *ed = LiteApi::findExtensionObject<QTextBrowser*>(editor,"LiteApi.QTextBrowser");
                if (ed) {
                    text = ed->textCursor().selectedText();
                }
            }
            if (!text.isEmpty()) {
                this->m_findCombo->setEditText(text);
            }
            if (editor && !editor->filePath().isEmpty() && m_autoSwitchPathCheckBox->isChecked()) {
                QFileInfo info(editor->filePath());
                m_findPathCombo->setEditText(info.path());
            }
        }
    }
}

QString FileSearch::mimeType() const
{
    return "search/filesystem";
}

QString FileSearch::displayName() const
{
    return tr("Files on File System");
}

QWidget *FileSearch::widget() const
{
    return m_findWidget;
}

void FileSearch::start()
{
    this->findInFiles();
}

void FileSearch::cancel()
{
    m_thread->stop();
}

void FileSearch::activate()
{
    LiteApi::IProject *proj = m_liteApp->projectManager()->currentProject();
    if (proj && !LiteApi::mimeIsFolder(proj->mimeType())) {
        QFileInfo info(proj->filePath());
        if (info.isDir())
            m_findPathCombo->setEditText(info.filePath());
        else
            m_findPathCombo->setEditText(info.path());
    }
    m_findCombo->setFocus();
    m_findCombo->lineEdit()->selectAll();
    LiteApi::IEditor *editor = m_liteApp->editorManager()->currentEditor();
    if (editor) {
        QString text;
        QPlainTextEdit *ed = LiteApi::findExtensionObject<QPlainTextEdit*>(editor,"LiteApi.QPlainTextEdit");
        if (ed) {
            text = ed->textCursor().selectedText();
        } else {
            QTextBrowser *ed = LiteApi::findExtensionObject<QTextBrowser*>(editor,"LiteApi.QTextBrowser");
            if (ed) {
                text = ed->textCursor().selectedText();
            }
        }
        if (!text.isEmpty()) {
            this->m_findCombo->setEditText(text);
        }
        if (editor && !editor->filePath().isEmpty() && m_autoSwitchPathCheckBox->isChecked()) {
            QFileInfo info(editor->filePath());
            m_findPathCombo->setEditText(info.path());
        }
    }
}

QString FileSearch::searchText() const
{
    return m_thread->findText;
}

void FileSearch::findInFiles()
{
    if (m_thread->isRunning()) {
        m_thread->stop();
    }
    QString text = m_findCombo->currentText();
    QString path = m_findPathCombo->currentText();
    if (text.isEmpty() || path.isEmpty()) {
        return;
    }
    m_thread->findPath = path;
    m_thread->findText = text;
    m_thread->useRegExp = m_useRegexCheckBox->isChecked();
    m_thread->matchCase = m_matchCaseCheckBox->isChecked();
    m_thread->matchWord = m_matchWordCheckBox->isChecked();
    m_thread->findSub = m_findSubCheckBox->isChecked();
    m_thread->nameFilter = m_filterCombo->currentText().split(";");
    m_thread->start(QThread::LowPriority);
    if (m_findCombo->findText(text) < 0) {
        m_findCombo->addItem(text);
    }
    if (m_findPathCombo->findText(path) < 0) {
        m_findPathCombo->addItem(path);
    }
}

void FileSearch::currentDir()
{
    LiteApi::IProject *proj = m_liteApp->projectManager()->currentProject();
    if (proj && !LiteApi::mimeIsFolder(proj->mimeType())) {
        QFileInfo info(proj->filePath());
        if (info.isDir()) {
            m_findPathCombo->setEditText(info.filePath());
        } else {
            m_findPathCombo->setEditText(info.path());
        }
    } else {
        LiteApi::IEditor *editor = m_liteApp->editorManager()->currentEditor();
        if (editor && !editor->filePath().isEmpty()) {
            QFileInfo info(editor->filePath());
            m_findPathCombo->setEditText(info.path());
        }
    }

}

void FileSearch::browser()
{
    QString dir = QFileDialog::getExistingDirectory(m_liteApp->mainWindow(), tr("Open Directory"),
                                                    m_findPathCombo->currentText(),
                                                     QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
    if (!dir.isEmpty()) {
        m_findPathCombo->setEditText(dir);
    }
}
<commit_msg>fix filesearch space<commit_after>/**************************************************************************
** This file is part of LiteIDE
**
** Copyright (c) 2011-2016 LiteIDE Team. All rights reserved.
**
** 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.
**
** In addition, as a special exception,  that plugins developed for LiteIDE,
** are allowed to remain closed sourced and can be distributed under any license .
** These rights are included in the file LGPL_EXCEPTION.txt in this package.
**
**************************************************************************/
// Module: filesearch.cpp
// Creator: visualfc <visualfc@gmail.com>

#include "filesearch.h"
#include "litefind_global.h"
#include <QFile>
#include <QTableWidget>
#include <QTextStream>
#include <QTextDocument>
#include <QRegExp>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QComboBox>
#include <QCheckBox>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QDir>
#include <QTextBlock>
#include <QTextCursor>
#include <QPlainTextEdit>
#include <QTextBrowser>
#include <QFileDialog>
#include <QAction>
#include <QDebug>
//lite_memory_check_begin
#if defined(WIN32) && defined(_MSC_VER) &&  defined(_DEBUG)
     #define _CRTDBG_MAP_ALLOC
     #include <stdlib.h>
     #include <crtdbg.h>
     #define DEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
     #define new DEBUG_NEW
#endif
//lite_memory_check_end

FindThread::FindThread(QObject *parent) :
    QThread(parent),
    useRegExp(true),
    matchWord(true),
    matchCase(true),
    findSub(true)
{
    qRegisterMetaType<LiteApi::FileSearchResult>("LiteApi::FileSearchResult");
}

void FindThread::findDir(const QRegExp &reg, const QString &path)
{
    QDir dir(path);
    if (!dir.exists()) {
        return;
    }

    foreach(QFileInfo info, dir.entryInfoList(nameFilter,QDir::Files|QDir::NoSymLinks)) {
        findFile(reg,info.filePath());
        if (!finding) {
            return;
        }
    }
    if (findSub) {
        foreach(QFileInfo info, dir.entryInfoList(QDir::Dirs|QDir::NoDotAndDotDot)) {
            findDir(reg,info.filePath());
            if(!finding) {
                return;
            }
        }
    }
}

void FindThread::findFile(const QRegExp &reg, const QString &fileName)
{
    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly)) {
        return;
    }

    QTextStream stream(&file);
    stream.setCodec("utf-8");
    QString line;
    int lineNr = 1;
    while (!stream.atEnd()) {
        line = stream.readLine();
        int pos = 0;
        while ((pos = reg.indexIn(line, pos)) != -1) {
            if (!useRegExp && matchWord) {
                const int start = pos;
                const int end = start + reg.matchedLength();
                if ((start != 0 && line.at(start - 1).isLetterOrNumber())
                        || (end != line.length() && line.at(end).isLetterOrNumber())) {
                    //if this is not a whole word, continue the search in the string
                    pos = end+1;
                    continue;
                }
            }
            emit findResult(LiteApi::FileSearchResult(fileName, line,lineNr,pos, reg.matchedLength()));
            pos += reg.matchedLength();
        }
        lineNr++;
        if (!finding) {
            break;
        }
    }
}

void FindThread::stop()
{
    finding = false;
    if (this->isRunning()) {
        if (!this->wait(200))
            this->terminate();
    }
}

void FindThread::run()
{
    finding = true;
    QRegExp reg;
    reg.setCaseSensitivity(matchCase ? Qt::CaseSensitive : Qt::CaseInsensitive);

    if (useRegExp) {
        if (matchWord) {
            reg.setPattern(QString::fromLatin1("\\b%1\\b").arg(findText));
        } else {
            reg.setPattern(findText);
        }
    } else {
       reg.setPattern(findText);
       reg.setPatternSyntax(QRegExp::FixedString);
    }
    findDir(reg,findPath);
    finding = false;
}

ResultTextEdit::ResultTextEdit(QWidget *parent) :
    QPlainTextEdit(parent)
{
    this->setWordWrapMode(QTextOption::NoWrap);

    connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(slotCursorPositionChanged()));
}

void ResultTextEdit::slotCursorPositionChanged()
{
    QList<QTextEdit::ExtraSelection> extraSelections;

    QTextEdit::ExtraSelection selection;

    QColor lineColor = QColor(180,200,200,128);

    selection.format.setBackground(lineColor);
    selection.format.setProperty(QTextFormat::FullWidthSelection, true);
    selection.cursor = textCursor();
    selection.cursor.clearSelection();
    extraSelections.append(selection);

    setExtraSelections(extraSelections);
}

void ResultTextEdit::mouseDoubleClickEvent(QMouseEvent *e)
{
    QTextCursor cur = cursorForPosition(e->pos());
    cur.select(QTextCursor::LineUnderCursor);

    emit dbclickEvent(cur);
}

FileSearch::FileSearch(LiteApi::IApplication *app, QObject *parent) :
    LiteApi::IFileSearch(parent),
    m_liteApp(app)
{
    m_thread = new FindThread;

    m_findWidget = new QWidget;

    QGridLayout *topLayout = new QGridLayout;
    topLayout->setSpacing(1);

    m_findCombo = new QComboBox;
    m_findCombo->setEditable(true);
    m_findCombo->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Preferred);

    QHBoxLayout *optLayout = new QHBoxLayout;
    optLayout->setSpacing(6);
    m_matchWordCheckBox = new QCheckBox(tr("Match whole word"));
    m_matchCaseCheckBox = new QCheckBox(tr("Match case"));
    m_useRegexCheckBox = new QCheckBox(tr("Regular expression"));
    m_findSubCheckBox = new QCheckBox(tr("Scan subdirectories"));
    optLayout->addWidget(m_matchWordCheckBox);
    optLayout->addWidget(m_matchCaseCheckBox);
    optLayout->addWidget(m_useRegexCheckBox);
    optLayout->addWidget(m_findSubCheckBox);
    optLayout->addStretch();

    QHBoxLayout *findLayout = new QHBoxLayout;
    findLayout->setSpacing(6);
    //findLayout->setMargin(0);
    m_findButton = new QPushButton(tr("Search"));
    m_stopButton = new QPushButton(tr("Cancel"));
    m_stopButton->setEnabled(false);
    //findLayout->addWidget();
    findLayout->addWidget(m_findCombo);
    findLayout->addWidget(m_findButton);
    findLayout->addWidget(m_stopButton);
    //findLayout->addStretch(0);
    //topLayout->addLayout(findLayout,4,1);

    topLayout->addWidget(new QLabel(tr("Search for:")),0,0);
    topLayout->addLayout(findLayout,0,1);
    topLayout->addWidget(new QLabel(tr("Options:")),1,0);
    topLayout->addLayout(optLayout,1,1);

    QHBoxLayout *dirLayout = new QHBoxLayout;
    dirLayout->setSpacing(6);
    m_findPathCombo = new QComboBox;
    m_findPathCombo->setEditable(true);
    QPushButton *browserBtn = new QPushButton(tr("Browse..."));
    QPushButton *currentBtn = new QPushButton(tr("Current Folder"));

    m_autoSwitchPathCheckBox = new QCheckBox;
    m_autoSwitchPathCheckBox->setText(tr("Auto Switch"));

    dirLayout->addWidget(m_findPathCombo,1);
    dirLayout->addWidget(m_autoSwitchPathCheckBox);
    dirLayout->addWidget(currentBtn);
    dirLayout->addWidget(browserBtn);

    topLayout->addWidget(new QLabel("Directory:"),2,0);
    topLayout->addLayout(dirLayout,2,1);

    m_filterCombo = new QComboBox;
    m_filterCombo->setEditable(true);

    m_filterCombo->addItem("*.go");
    m_filterCombo->addItem("*.lua;*.wlua");
    m_filterCombo->addItem("*.c;*.cpp;*.cxx;*.cc;*.c++;*.h;*.hpp;*.hh;*.hxx;*.h++;*.hcc;*.moc");
    m_filterCombo->addItem("*.htm;*.html;*.shtml;*.shtm");
    m_filterCombo->addItem("*");

    topLayout->addWidget(new QLabel(tr("Filter:")),3,0);
    topLayout->addWidget(m_filterCombo,3,1);

    m_findWidget->setLayout(topLayout);

    QAction *clearAct = new QAction(tr("Clear"),this);
    clearAct->setIcon(QIcon("icon:images/cleanoutput.png"));

    m_findPathCombo->setEditText(QDir::homePath());
    m_liteApp->settings()->beginGroup("findfiles");
    m_matchWordCheckBox->setChecked(m_liteApp->settings()->value("matchWord",false).toBool());
    m_matchCaseCheckBox->setChecked(m_liteApp->settings()->value("matchCase",false).toBool());
    m_useRegexCheckBox->setChecked(m_liteApp->settings()->value("useRegexp",false).toBool());
    m_findSubCheckBox->setChecked(m_liteApp->settings()->value("findSub",true).toBool());
    m_liteApp->settings()->endGroup();

    connect(browserBtn,SIGNAL(clicked()),this,SLOT(browser()));
    connect(currentBtn,SIGNAL(clicked()),this,SLOT(currentDir()));
    connect(m_findButton,SIGNAL(clicked()),this,SLOT(findInFiles()));
    connect(m_stopButton,SIGNAL(clicked()),m_thread,SLOT(stop()));
    connect(m_thread,SIGNAL(started()),this,SIGNAL(findStarted()));
    connect(m_thread,SIGNAL(finished()),this,SIGNAL(findFinished()));
    connect(m_thread,SIGNAL(findResult(LiteApi::FileSearchResult)),this,SIGNAL(findResult(LiteApi::FileSearchResult)));
    connect(m_findCombo->lineEdit(),SIGNAL(returnPressed()),this,SLOT(findInFiles()));

    bool b = m_liteApp->settings()->value(FILESEARCH_AUTOSWITCHDIR,true).toBool();
    m_autoSwitchPathCheckBox->setChecked(b);
}

FileSearch::~FileSearch()
{
    m_liteApp->settings()->beginGroup("findfiles");
    m_liteApp->settings()->setValue("matchWord",m_matchWordCheckBox->isChecked());
    m_liteApp->settings()->setValue("matchCase",m_matchCaseCheckBox->isChecked());
    m_liteApp->settings()->setValue("useRegexp",m_useRegexCheckBox->isChecked());
    m_liteApp->settings()->setValue("findSub",m_findSubCheckBox->isChecked());
    m_liteApp->settings()->endGroup();

    m_liteApp->settings()->setValue(FILESEARCH_AUTOSWITCHDIR,m_autoSwitchPathCheckBox->isChecked());

    if (m_thread) {
        m_thread->stop();
        delete m_thread;
    }
    if (m_findWidget) {
        delete m_findWidget;
    }
}

void FileSearch::setVisible(bool b)
{
    if (b) {
        LiteApi::IProject *proj = m_liteApp->projectManager()->currentProject();
        if (proj && !LiteApi::mimeIsFolder(proj->mimeType())) {
            QFileInfo info(proj->filePath());
            if (info.isDir())
                m_findPathCombo->setEditText(info.filePath());
            else
                m_findPathCombo->setEditText(info.path());
        }
        m_findCombo->setFocus();
        m_findCombo->lineEdit()->selectAll();
        LiteApi::IEditor *editor = m_liteApp->editorManager()->currentEditor();
        if (editor) {
            QString text;
            QPlainTextEdit *ed = LiteApi::findExtensionObject<QPlainTextEdit*>(editor,"LiteApi.QPlainTextEdit");
            if (ed) {
                text = ed->textCursor().selectedText();
            } else {
                QTextBrowser *ed = LiteApi::findExtensionObject<QTextBrowser*>(editor,"LiteApi.QTextBrowser");
                if (ed) {
                    text = ed->textCursor().selectedText();
                }
            }
            if (!text.isEmpty()) {
                this->m_findCombo->setEditText(text);
            }
            if (editor && !editor->filePath().isEmpty() && m_autoSwitchPathCheckBox->isChecked()) {
                QFileInfo info(editor->filePath());
                m_findPathCombo->setEditText(info.path());
            }
        }
    }
}

QString FileSearch::mimeType() const
{
    return "search/filesystem";
}

QString FileSearch::displayName() const
{
    return tr("Files on File System");
}

QWidget *FileSearch::widget() const
{
    return m_findWidget;
}

void FileSearch::start()
{
    this->findInFiles();
}

void FileSearch::cancel()
{
    m_thread->stop();
}

void FileSearch::activate()
{
    LiteApi::IProject *proj = m_liteApp->projectManager()->currentProject();
    if (proj && !LiteApi::mimeIsFolder(proj->mimeType())) {
        QFileInfo info(proj->filePath());
        if (info.isDir())
            m_findPathCombo->setEditText(info.filePath());
        else
            m_findPathCombo->setEditText(info.path());
    }
    m_findCombo->setFocus();
    m_findCombo->lineEdit()->selectAll();
    LiteApi::IEditor *editor = m_liteApp->editorManager()->currentEditor();
    if (editor) {
        QString text;
        QPlainTextEdit *ed = LiteApi::findExtensionObject<QPlainTextEdit*>(editor,"LiteApi.QPlainTextEdit");
        if (ed) {
            text = ed->textCursor().selectedText();
        } else {
            QTextBrowser *ed = LiteApi::findExtensionObject<QTextBrowser*>(editor,"LiteApi.QTextBrowser");
            if (ed) {
                text = ed->textCursor().selectedText();
            }
        }
        if (!text.isEmpty()) {
            this->m_findCombo->setEditText(text);
        }
        if (editor && !editor->filePath().isEmpty() && m_autoSwitchPathCheckBox->isChecked()) {
            QFileInfo info(editor->filePath());
            m_findPathCombo->setEditText(info.path());
        }
    }
}

QString FileSearch::searchText() const
{
    return m_thread->findText;
}

void FileSearch::findInFiles()
{
    if (m_thread->isRunning()) {
        m_thread->stop();
    }
    QString text = m_findCombo->currentText();
    QString path = m_findPathCombo->currentText();
    if (text.isEmpty() || path.isEmpty()) {
        return;
    }
    m_thread->findPath = path;
    m_thread->findText = text;
    m_thread->useRegExp = m_useRegexCheckBox->isChecked();
    m_thread->matchCase = m_matchCaseCheckBox->isChecked();
    m_thread->matchWord = m_matchWordCheckBox->isChecked();
    m_thread->findSub = m_findSubCheckBox->isChecked();
    m_thread->nameFilter = m_filterCombo->currentText().split(";");
    m_thread->start(QThread::LowPriority);
    if (m_findCombo->findText(text) < 0) {
        m_findCombo->addItem(text);
    }
    if (m_findPathCombo->findText(path) < 0) {
        m_findPathCombo->addItem(path);
    }
}

void FileSearch::currentDir()
{
    LiteApi::IProject *proj = m_liteApp->projectManager()->currentProject();
    if (proj && !LiteApi::mimeIsFolder(proj->mimeType())) {
        QFileInfo info(proj->filePath());
        if (info.isDir()) {
            m_findPathCombo->setEditText(info.filePath());
        } else {
            m_findPathCombo->setEditText(info.path());
        }
    } else {
        LiteApi::IEditor *editor = m_liteApp->editorManager()->currentEditor();
        if (editor && !editor->filePath().isEmpty()) {
            QFileInfo info(editor->filePath());
            m_findPathCombo->setEditText(info.path());
        }
    }

}

void FileSearch::browser()
{
    QString dir = QFileDialog::getExistingDirectory(m_liteApp->mainWindow(), tr("Open Directory"),
                                                    m_findPathCombo->currentText(),
                                                     QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
    if (!dir.isEmpty()) {
        m_findPathCombo->setEditText(dir);
    }
}
<|endoftext|>


<commit_before>#include "troff_display_driver.hpp"

#include "document/bold_line_element.hpp"
#include "document/italic_line_element.hpp"
#include "document/code_line_element.hpp"
#include "document/url_line_element.hpp"

#include <iostream>
using namespace std;

void TroffDisplayDriver::display(Document * doc) {
	Paragraph *p = nullptr;
	LineElement *l = nullptr;

	BoldLineElement *bold_le(nullptr);
	ItalicLineElement *italic_le(nullptr);
	CodeLineElement *code_le(nullptr);
	UrlLineElement *url_le(nullptr);

	bool is_verbatim(false),
		is_quotation(false),
		is_ulist(false);

	for (size_t i(0); i < doc->size(); ++i) {
		p = (*doc)[i];

		switch (p->level()) {
			case Paragraph::Level::Title1:
				cout << ".TH ";
				break;
			case Paragraph::Level::Title2:
				cout << ".SH ";
				break;
			case Paragraph::Level::Code:
			case Paragraph::Level::UList1:
			case Paragraph::Level::Quote:
			default:
				break;
		}

		for (size_t j(0); j < p->size(); ++j) {
			l = (*p)[j];

			bold_le = dynamic_cast<BoldLineElement*>(l);
			italic_le = dynamic_cast<ItalicLineElement*>(l);
			code_le = dynamic_cast<CodeLineElement*>(l);
			url_le = dynamic_cast<UrlLineElement*>(l);

			if (italic_le) {
				cout << "\\fI";
			} else if (bold_le) {
				cout << "\\fB";
			} else if (code_le and p->level() != Paragraph::Level::Code) {
			} else if (url_le) {
			}

			cout << l->content();

			if (italic_le or bold_le) {
				cout << "\\fR";
			} else if (code_le and p->level() != Paragraph::Level::Code) {
			}
		}

		switch (p->level()) {
			case Paragraph::Level::Code:
				break;
			case Paragraph::Level::Quote:
				break;
			case Paragraph::Level::UList1:
				break;
			case Paragraph::Level::Title1:
			case Paragraph::Level::Title2:
			default:
				cout << endl;
				break;
		}
	}
}

/* vim: set ts=4 sw=4: */
<commit_msg>Handle URL's<commit_after>#include "troff_display_driver.hpp"

#include "document/bold_line_element.hpp"
#include "document/italic_line_element.hpp"
#include "document/code_line_element.hpp"
#include "document/url_line_element.hpp"

#include <iostream>
using namespace std;

void TroffDisplayDriver::display(Document * doc) {
	Paragraph *p = nullptr;
	LineElement *l = nullptr;

	BoldLineElement *bold_le(nullptr);
	ItalicLineElement *italic_le(nullptr);
	CodeLineElement *code_le(nullptr);
	UrlLineElement *url_le(nullptr);

	bool is_verbatim(false),
		is_quotation(false),
		is_ulist(false);

	for (size_t i(0); i < doc->size(); ++i) {
		p = (*doc)[i];

		switch (p->level()) {
			case Paragraph::Level::Title1:
				cout << ".TH ";
				break;
			case Paragraph::Level::Title2:
				cout << ".SH ";
				break;
			case Paragraph::Level::Code:
			case Paragraph::Level::UList1:
			case Paragraph::Level::Quote:
			default:
				cout << ".PP" << endl;
				break;
		}

		for (size_t j(0); j < p->size(); ++j) {
			l = (*p)[j];

			bold_le = dynamic_cast<BoldLineElement*>(l);
			italic_le = dynamic_cast<ItalicLineElement*>(l);
			code_le = dynamic_cast<CodeLineElement*>(l);
			url_le = dynamic_cast<UrlLineElement*>(l);

			if (italic_le) {
				cout << "\\fI";
			} else if (bold_le) {
				cout << "\\fB";
			} else if (code_le and p->level() != Paragraph::Level::Code) {
			}

			if (url_le) {
				cout << endl << ".IR " << url_le->url() << endl;
			} else {
				cout << l->content();
			}

			if (italic_le or bold_le) {
				cout << "\\fR";
			} else if (code_le and p->level() != Paragraph::Level::Code) {
			}
		}

		switch (p->level()) {
			case Paragraph::Level::Code:
				break;
			case Paragraph::Level::Quote:
				break;
			case Paragraph::Level::UList1:
				break;
			case Paragraph::Level::Title1:
			case Paragraph::Level::Title2:
			default:
				cout << endl;
				break;
		}
	}
}

/* vim: set ts=4 sw=4: */
<|endoftext|>


<commit_before>// Simple keogram composition program using OpenCV
// Copyright 2018 Jarno Paananen <jarno.paananen@gmail.com>
// Based on a script by Thomas Jacquin
// SPDX-License-Identifier: MIT

#include <cstdlib>
#include <glob.h>
#include <iostream>
#include <string>
#include <sys/stat.h>
#include <vector>

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#define KNRM "\x1B[0m"
#define KRED "\x1B[31m"
#define KGRN "\x1B[32m"
#define KYEL "\x1B[33m"
#define KBLU "\x1B[34m"
#define KMAG "\x1B[35m"
#define KCYN "\x1B[36m"
#define KWHT "\x1B[37m"

//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------

int main(int argc, char *argv[])
{
    if (argc < 4)
    {
        std::cout << KRED << "You need to pass 3 arguments: source directory, "
                             "image extension, output file"
                  << std::endl;
        std::cout << "Optionally you can pass after them: " << std::endl;
        std::cout << " -no-label                    - Disable hour labels" << std::endl;
        std::cout << " -fontname = Font Name        - Default = 0    - Font Types "
                     "(0-7), Ex. 0 = simplex, 4 = triplex, 7 = script"
                  << std::endl;
        std::cout << " -fontcolor = Font Color      - Default = 255 0 0  - Text "
                     "blue (BRG)"
                  << std::endl;
        std::cout << " -fonttype = Font Type        - Default = 8    - Font Line "
                     "Type,(0-2), 0 = AA, 1 = 8, 2 = 4"
                  << std::endl;
        std::cout << " -fontsize                    - Default = 2.0  - Text Font Size" << std::endl;
        std::cout << " -fontline                    - Default = 3    - Text Font "
                     "Line Thickness"
                  << std::endl;
        std::cout << "    ex: keogram ../images/current/ jpg keogram.jpg -fontsize 2" << std::endl;
        std::cout << "    ex: keogram . png /home/pi/allsky/keogram.jpg -no-label" << KNRM << std::endl;
        return 3;
    }

    std::string directory  = argv[1];
    std::string extension  = argv[2];
    std::string outputfile = argv[3];

    bool labelsEnabled = true;
    int fontFace       = cv::FONT_HERSHEY_SCRIPT_SIMPLEX;
    double fontScale   = 2;
    int fontType       = 8;
    int thickness      = 3;
    char fontColor[3]  = { 255, 0, 0 };

    // Handle optional parameters
    for (int a = 4; a < argc; ++a)
    {
        if (!strcmp(argv[a], "-no-label"))
        {
            labelsEnabled = false;
        }
        else if (!strcmp(argv[a], "-fontname"))
        {
            fontFace = atoi(argv[++a]);
        }
        else if (!strcmp(argv[a], "-fonttype"))
        {
            fontType = atoi(argv[++a]);
        }
        else if (!strcmp(argv[a], "-fontsize"))
        {
            fontScale = atof(argv[++a]);
        }
        else if (!strcmp(argv[a], "-fontline"))
        {
            thickness = atoi(argv[++a]);
        }
        else if (!strcmp(argv[a], "-fontcolor"))
        {
            fontColor[0] = atoi(argv[++a]);
            fontColor[1] = atoi(argv[++a]);
            fontColor[2] = atoi(argv[++a]);
        }
    }

    glob_t files;
    std::string wildcard = directory + "/*." + extension;
    glob(wildcard.c_str(), 0, NULL, &files);

    cv::Mat accumulated;

    int prevHour = -1;

    for (size_t f = 0; f < files.gl_pathc; f++)
    {
        cv::Mat image = cv::imread(files.gl_pathv[f], cv::IMREAD_UNCHANGED);
        if (!image.data)
        {
            std::cout << "Error reading file " << basename(files.gl_pathv[f]) << std::endl;
            continue;
        }

        std::cout << "[" << f + 1 << "/" << files.gl_pathc << "] " << basename(files.gl_pathv[f]) << std::endl;

        // If we don't have image yet, create one using height and format from
        // the source image and width from number of files
        if (accumulated.empty())
        {
            accumulated.create(image.rows, files.gl_pathc, image.type());
        }
        // Copy middle column to destination
        image.col(image.cols / 2).copyTo(accumulated.col(f));

        if (labelsEnabled)
        {
            struct stat s;
            stat(files.gl_pathv[f], &s);

            struct tm *t = localtime(&s.st_mtime);
            if (t->tm_hour != prevHour)
            {
                if (prevHour != -1)
                {
                    // Draw a dashed line and label for hour
                    cv::LineIterator it(accumulated, cv::Point(f, 0), cv::Point(f, accumulated.rows));
                    for (int i = 0; i < it.count; i++, ++it)
                    {
                        // 4 pixel dashed line
                        if (i & 4)
                        {
                            uchar *p = *it;
                            for (int c = 0; c < it.elemSize; c++)
                            {
                                *p = ~(*p);
                                p++;
                            }
                        }
                    }

                    // Draw text label to the left of the dash
                    char hour[3];
                    snprintf(hour, 3, "%02d", t->tm_hour);
                    std::string text(hour);
                    int baseline      = 0;
                    cv::Size textSize = cv::getTextSize(text, fontFace, fontScale, thickness, &baseline);

                    if (f - textSize.width >= 0)
                    {
                        cv::putText(accumulated, text,
                                    cv::Point(f - textSize.width, accumulated.rows - textSize.height), fontFace,
                                    fontScale, cv::Scalar(fontColor[0], fontColor[1], fontColor[2]), thickness,
                                    fontType);
                    }
                }
                prevHour = t->tm_hour;
            }
        }
    }
    globfree(&files);

    std::vector<int> compression_params;
    compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
    compression_params.push_back(9);
    compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);
    compression_params.push_back(95);

    cv::imwrite(outputfile, accumulated, compression_params);
}
<commit_msg>Added stdio.h<commit_after>// Simple keogram composition program using OpenCV
// Copyright 2018 Jarno Paananen <jarno.paananen@gmail.com>
// Based on a script by Thomas Jacquin
// SPDX-License-Identifier: MIT

#include <cstdlib>
#include <glob.h>
#include <iostream>
#include <string>
#include <sys/stat.h>
#include <vector>
#include <stdio.h>

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#define KNRM "\x1B[0m"
#define KRED "\x1B[31m"
#define KGRN "\x1B[32m"
#define KYEL "\x1B[33m"
#define KBLU "\x1B[34m"
#define KMAG "\x1B[35m"
#define KCYN "\x1B[36m"
#define KWHT "\x1B[37m"

//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------

int main(int argc, char *argv[])
{
    if (argc < 4)
    {
        std::cout << KRED << "You need to pass 3 arguments: source directory, "
                             "image extension, output file"
                  << std::endl;
        std::cout << "Optionally you can pass after them: " << std::endl;
        std::cout << " -no-label                    - Disable hour labels" << std::endl;
        std::cout << " -fontname = Font Name        - Default = 0    - Font Types "
                     "(0-7), Ex. 0 = simplex, 4 = triplex, 7 = script"
                  << std::endl;
        std::cout << " -fontcolor = Font Color      - Default = 255 0 0  - Text "
                     "blue (BRG)"
                  << std::endl;
        std::cout << " -fonttype = Font Type        - Default = 8    - Font Line "
                     "Type,(0-2), 0 = AA, 1 = 8, 2 = 4"
                  << std::endl;
        std::cout << " -fontsize                    - Default = 2.0  - Text Font Size" << std::endl;
        std::cout << " -fontline                    - Default = 3    - Text Font "
                     "Line Thickness"
                  << std::endl;
        std::cout << "    ex: keogram ../images/current/ jpg keogram.jpg -fontsize 2" << std::endl;
        std::cout << "    ex: keogram . png /home/pi/allsky/keogram.jpg -no-label" << KNRM << std::endl;
        return 3;
    }

    std::string directory  = argv[1];
    std::string extension  = argv[2];
    std::string outputfile = argv[3];

    bool labelsEnabled = true;
    int fontFace       = cv::FONT_HERSHEY_SCRIPT_SIMPLEX;
    double fontScale   = 2;
    int fontType       = 8;
    int thickness      = 3;
    char fontColor[3]  = { 255, 0, 0 };

    // Handle optional parameters
    for (int a = 4; a < argc; ++a)
    {
        if (!strcmp(argv[a], "-no-label"))
        {
            labelsEnabled = false;
        }
        else if (!strcmp(argv[a], "-fontname"))
        {
            fontFace = atoi(argv[++a]);
        }
        else if (!strcmp(argv[a], "-fonttype"))
        {
            fontType = atoi(argv[++a]);
        }
        else if (!strcmp(argv[a], "-fontsize"))
        {
            fontScale = atof(argv[++a]);
        }
        else if (!strcmp(argv[a], "-fontline"))
        {
            thickness = atoi(argv[++a]);
        }
        else if (!strcmp(argv[a], "-fontcolor"))
        {
            fontColor[0] = atoi(argv[++a]);
            fontColor[1] = atoi(argv[++a]);
            fontColor[2] = atoi(argv[++a]);
        }
    }

    glob_t files;
    std::string wildcard = directory + "/*." + extension;
    glob(wildcard.c_str(), 0, NULL, &files);

    cv::Mat accumulated;

    int prevHour = -1;

    for (size_t f = 0; f < files.gl_pathc; f++)
    {
        cv::Mat image = cv::imread(files.gl_pathv[f], cv::IMREAD_UNCHANGED);
        if (!image.data)
        {
            std::cout << "Error reading file " << basename(files.gl_pathv[f]) << std::endl;
            continue;
        }

        std::cout << "[" << f + 1 << "/" << files.gl_pathc << "] " << basename(files.gl_pathv[f]) << std::endl;

        // If we don't have image yet, create one using height and format from
        // the source image and width from number of files
        if (accumulated.empty())
        {
            accumulated.create(image.rows, files.gl_pathc, image.type());
        }
        // Copy middle column to destination
        image.col(image.cols / 2).copyTo(accumulated.col(f));

        if (labelsEnabled)
        {
            struct stat s;
            stat(files.gl_pathv[f], &s);

            struct tm *t = localtime(&s.st_mtime);
            if (t->tm_hour != prevHour)
            {
                if (prevHour != -1)
                {
                    // Draw a dashed line and label for hour
                    cv::LineIterator it(accumulated, cv::Point(f, 0), cv::Point(f, accumulated.rows));
                    for (int i = 0; i < it.count; i++, ++it)
                    {
                        // 4 pixel dashed line
                        if (i & 4)
                        {
                            uchar *p = *it;
                            for (int c = 0; c < it.elemSize; c++)
                            {
                                *p = ~(*p);
                                p++;
                            }
                        }
                    }

                    // Draw text label to the left of the dash
                    char hour[3];
                    snprintf(hour, 3, "%02d", t->tm_hour);
                    std::string text(hour);
                    int baseline      = 0;
                    cv::Size textSize = cv::getTextSize(text, fontFace, fontScale, thickness, &baseline);

                    if (f - textSize.width >= 0)
                    {
                        cv::putText(accumulated, text,
                                    cv::Point(f - textSize.width, accumulated.rows - textSize.height), fontFace,
                                    fontScale, cv::Scalar(fontColor[0], fontColor[1], fontColor[2]), thickness,
                                    fontType);
                    }
                }
                prevHour = t->tm_hour;
            }
        }
    }
    globfree(&files);

    std::vector<int> compression_params;
    compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
    compression_params.push_back(9);
    compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);
    compression_params.push_back(95);

    cv::imwrite(outputfile, accumulated, compression_params);
}
<|endoftext|>