<commit_before>//
//  File:	ActorsLoader.cpp
//  Class:  ActorsLoader
//  Author: John Barbero Unenge
//          All code is my own except where credited to others.
//
//  Copyright (c) 2012 Catch22. All Rights Reserved.
//
//	Date:  	5/10/12.
//
//	License: The following code is licensed under the Catch22-License
//

#include "ActorsLoader.hpp"
#include "../Helper/Logger.hpp"

Actor* MAIN_CHARACTER = 0;
Actor* CHAINSAW = 0;
Actor* PLATFORM_1 = 0;
Actor* PLATFORM_2 = 0;
Actor* PLATFORM_3 = 0;
Actor* OBSTACLE_BOX = 0;

const double IMAGE_WIDTH = 2048;
const double IMAGE_HEIGHT = 2048;

void ActorsLoader::initMainCharacter(int textureID)
{

    double sW = 111; // Character sprite width in pixels
    double sH = 133; // Character sprite height in pixels

    // Player character
    Sprite* s0 = new Sprite(0*sW/IMAGE_WIDTH    ,2/IMAGE_HEIGHT
                            , sW/IMAGE_WIDTH  , sH/IMAGE_HEIGHT , textureID, false);

    Sprite* s1 = new Sprite(1*sW/IMAGE_WIDTH    ,2/IMAGE_HEIGHT
                            , sW/IMAGE_WIDTH  , sH/IMAGE_HEIGHT , textureID, false);

    Sprite* s2 = new Sprite(2*sW/IMAGE_WIDTH    ,2/IMAGE_HEIGHT
                            , sW/IMAGE_WIDTH  , sH/IMAGE_HEIGHT, textureID, false);

    Sprite* s3 = new Sprite(3*sW/IMAGE_WIDTH    ,2/IMAGE_HEIGHT
                            , sW/IMAGE_WIDTH  , sH/IMAGE_HEIGHT , textureID, false);

    Sprite* s4 = new Sprite(4*sW/IMAGE_WIDTH    ,2/IMAGE_HEIGHT
                            , sW/IMAGE_WIDTH  , sH/IMAGE_HEIGHT , textureID, false);

    Sprite* s5 = new Sprite(5*sW/IMAGE_WIDTH    ,2/IMAGE_HEIGHT
                            , sW/IMAGE_WIDTH  , sH/IMAGE_HEIGHT , textureID, false);

    Sprite** sp = new Sprite*[6];
    sp[0] = s0;
    sp[1] = s1;
    sp[2] = s2;
    sp[3] = s3;
    sp[4] = s4;
    sp[5] = s5;

    SpriteArray* arr = new SpriteArray(sp, 6);

    Animation* a = new Animation(arr, s1, 100, true);
    Animation** aArr = new Animation*[1];
    aArr[0] = a;
    AnimationArray* aAnimArr = new AnimationArray(aArr, 1);

    MAIN_CHARACTER = new Actor(aAnimArr, a, new Vector2d(1.f, 1.f),
                           new OffsetMatrix(new Vector2d(0.f,0.f), new Vector2d(0.f,0.f), new Vector2d(0.f,0.f), new Vector2d(0.f,0.f)));
//                                                new Vector2d(.75f, 0.2f),
//                                                new Vector2d(.75f, 0.2f),
//                                                new Vector2d(.75f, .4f),
//                                                new Vector2d(.75f, .4f)));
}
void ActorsLoader::initPlatforms(int textureID)
{
    // Platform 1
    Sprite* s1 = new Sprite(26/IMAGE_WIDTH,
    						266/IMAGE_HEIGHT,
    						203/IMAGE_WIDTH,
    						696/IMAGE_HEIGHT,
    						textureID, false);

    Sprite** sp1 = new Sprite*[1];
    sp1[0] = s1;

    SpriteArray* arr1 = new SpriteArray(sp1, 1);

    Animation* a1 = new Animation(arr1, s1, 300, true);
    Animation** aArr1 = new Animation*[1];
    aArr1[0] = a1;
    AnimationArray* aAnimArr1 = new AnimationArray(aArr1, 1);

    PLATFORM_1 = new Actor(aAnimArr1, a1, new Vector2d(1.f, 3.5f),
					new OffsetMatrix(
						   new Vector2d(0.05f,0.f),
						   new Vector2d(-0.13f,0.f),
						   new Vector2d(0.05f,0.f),
						   new Vector2d(-0.13f,0.f)));

    // Platform 3
    Sprite* s3 = new Sprite(26/IMAGE_WIDTH,
    						266/IMAGE_HEIGHT,
    						203/IMAGE_WIDTH,
    						696/IMAGE_HEIGHT,
    						textureID, true);

    Sprite** sp3 = new Sprite*[1];
    sp3[0] = s3;

    SpriteArray* arr3 = new SpriteArray(sp3, 1);

    Animation* a3 = new Animation(arr3, s3, 300, true);
    Animation** aArr3 = new Animation*[1];
    aArr3[0] = a3;
    AnimationArray* aAnimArr3 = new AnimationArray(aArr3, 1);

    PLATFORM_3 = new Actor(aAnimArr3, a3, new Vector2d(1.f, 3.5f),
					new OffsetMatrix(
						   new Vector2d(0.05f,0.f),
						   new Vector2d(-0.13f,0.f),
						   new Vector2d(0.05f,0.f),
						   new Vector2d(-0.13f,0.f)));
    // Platform 2
    Sprite* s2 = new Sprite(281/IMAGE_WIDTH,
    						266/IMAGE_HEIGHT,
    						221/IMAGE_WIDTH,
    						696/IMAGE_HEIGHT,
    						textureID, false);

    Sprite** sp2 = new Sprite*[1];
    sp2[0] = s2;

    SpriteArray* arr2 = new SpriteArray(sp2, 1);

    Animation* a2 = new Animation(arr2, s2, 300, true);
    Animation** aArr2 = new Animation*[1];
    aArr2[0] = a2;
    AnimationArray* aAnimArr2 = new AnimationArray(aArr2, 1);

    PLATFORM_2 = new Actor(aAnimArr2, a2, new Vector2d(1.f, 3.5f),
                           new OffsetMatrix(
                        		   new Vector2d(0.16f,0.f),
                        		   new Vector2d(-0.15f,0.f),
                        		   new Vector2d(0.16f,0.f),
                        		   new Vector2d(-0.15f,0.f)));

//    Sprite* s3 = new Sprite();

}

void ActorsLoader::initChainsaw(int textureID)
{
	//  Chainsaw
	Sprite* s1 = new Sprite(  5/IMAGE_WIDTH,
							185/IMAGE_HEIGHT,
							 64/IMAGE_WIDTH,
							 27/IMAGE_HEIGHT,
							textureID, false);

	Sprite* s2 = new Sprite(  5/IMAGE_WIDTH,
							218/IMAGE_HEIGHT,
							 64/IMAGE_WIDTH,
							 27/IMAGE_HEIGHT,
							textureID, false);

	Sprite** sp = new Sprite*[2];
	sp[0] = s1;
	sp[1] = s2;

	SpriteArray* arr1 = new SpriteArray(sp, 2);

	Animation* a = new Animation(arr1, s1, 50, true);
	Animation** aArr = new Animation*[1];
	aArr[0] = a;
	AnimationArray* aAnimArr = new AnimationArray(aArr, 1);

	CHAINSAW = new Actor(aAnimArr, a, new Vector2d(0.6f, 0.3f));
}

void ActorsLoader::initObstacle(int textureID)
{
    //  Obstacle Box
    Sprite* s1 = new Sprite(896/IMAGE_WIDTH,
							  2/IMAGE_HEIGHT,
							161/IMAGE_WIDTH,
							159/IMAGE_HEIGHT,
							textureID, true);

    Sprite** sp = new Sprite*[1];
    sp[0] = s1;

    SpriteArray* arr1 = new SpriteArray(sp, 1);

    Animation* a = new Animation(arr1, s1, 1, true);
    Animation** aArr = new Animation*[1];
    aArr[0] = a;
    AnimationArray* aAnimArr = new AnimationArray(aArr, 1);

    OBSTACLE_BOX = new Actor(aAnimArr, a, new Vector2d(1.2, 1.2));
}

void ActorsLoader::init(int textureID)
{
    ActorsLoader::initMainCharacter(textureID);
    ActorsLoader::initPlatforms(textureID);
    ActorsLoader::initChainsaw(textureID);
    ActorsLoader::initObstacle(textureID);
}
Actor* ActorsLoader::newMainCharacterActor()
{
    if (MAIN_CHARACTER == 0) {
        Log(LOG_ERROR, "ActorsLoader", "MAIN_CHARACTER is null, probably because init was never called.");
        return 0;
    }

    return new Actor(MAIN_CHARACTER);
}
Actor* ActorsLoader::newPlatformActor_1()
{
    if (PLATFORM_1 == 0) {
        Log(LOG_ERROR, "ActorsLoader", "PLATFORM_1 is null, probably because init was never called.");
        return 0;
    }

    return new Actor(PLATFORM_1);
}
Actor* ActorsLoader::newPlatformActor_2()
{
    if (PLATFORM_2 == 0) {
        Log(LOG_ERROR, "ActorsLoader", "PLATFORM_1 is null, probably because init was never called.");
        return 0;
    }

    return new Actor(PLATFORM_2);
}

Actor* ActorsLoader::newPlatformActor_3()
{
    if (PLATFORM_3 == 0) {
        Log(LOG_ERROR, "ActorsLoader", "PLATFORM_1 is null, probably because init was never called.");
        return 0;
    }

    return new Actor(PLATFORM_3);
}

Actor* ActorsLoader::newChainsawActor()
{
    if (CHAINSAW == 0) {
        Log(LOG_ERROR, "ActorsLoader", "CHAINSAW is null, probably because init was never called.");
        return 0;
    }

    return new Actor(CHAINSAW);
}

Actor* ActorsLoader::newObstacleBoxActor()
{
    if (OBSTACLE_BOX == 0) {
        Log(LOG_ERROR, "ActorsLoader", "PLATFORM_1 is null, probably because init was never called.");
        return 0;
    }

    return new Actor(OBSTACLE_BOX);
}
<commit_msg>Changed the size of a obstaclebox<commit_after>//
//  File:	ActorsLoader.cpp
//  Class:  ActorsLoader
//  Author: John Barbero Unenge
//          All code is my own except where credited to others.
//
//  Copyright (c) 2012 Catch22. All Rights Reserved.
//
//	Date:  	5/10/12.
//
//	License: The following code is licensed under the Catch22-License
//

#include "ActorsLoader.hpp"
#include "../Helper/Logger.hpp"

Actor* MAIN_CHARACTER = 0;
Actor* CHAINSAW = 0;
Actor* PLATFORM_1 = 0;
Actor* PLATFORM_2 = 0;
Actor* PLATFORM_3 = 0;
Actor* OBSTACLE_BOX = 0;

const double IMAGE_WIDTH = 2048;
const double IMAGE_HEIGHT = 2048;

void ActorsLoader::initMainCharacter(int textureID)
{

    double sW = 111; // Character sprite width in pixels
    double sH = 133; // Character sprite height in pixels

    // Player character
    Sprite* s0 = new Sprite(0*sW/IMAGE_WIDTH    ,2/IMAGE_HEIGHT
                            , sW/IMAGE_WIDTH  , sH/IMAGE_HEIGHT , textureID, false);

    Sprite* s1 = new Sprite(1*sW/IMAGE_WIDTH    ,2/IMAGE_HEIGHT
                            , sW/IMAGE_WIDTH  , sH/IMAGE_HEIGHT , textureID, false);

    Sprite* s2 = new Sprite(2*sW/IMAGE_WIDTH    ,2/IMAGE_HEIGHT
                            , sW/IMAGE_WIDTH  , sH/IMAGE_HEIGHT, textureID, false);

    Sprite* s3 = new Sprite(3*sW/IMAGE_WIDTH    ,2/IMAGE_HEIGHT
                            , sW/IMAGE_WIDTH  , sH/IMAGE_HEIGHT , textureID, false);

    Sprite* s4 = new Sprite(4*sW/IMAGE_WIDTH    ,2/IMAGE_HEIGHT
                            , sW/IMAGE_WIDTH  , sH/IMAGE_HEIGHT , textureID, false);

    Sprite* s5 = new Sprite(5*sW/IMAGE_WIDTH    ,2/IMAGE_HEIGHT
                            , sW/IMAGE_WIDTH  , sH/IMAGE_HEIGHT , textureID, false);

    Sprite** sp = new Sprite*[6];
    sp[0] = s0;
    sp[1] = s1;
    sp[2] = s2;
    sp[3] = s3;
    sp[4] = s4;
    sp[5] = s5;

    SpriteArray* arr = new SpriteArray(sp, 6);

    Animation* a = new Animation(arr, s1, 100, true);
    Animation** aArr = new Animation*[1];
    aArr[0] = a;
    AnimationArray* aAnimArr = new AnimationArray(aArr, 1);

    MAIN_CHARACTER = new Actor(aAnimArr, a, new Vector2d(1.f, 1.f),
                           new OffsetMatrix(new Vector2d(0.f,0.f), new Vector2d(0.f,0.f), new Vector2d(0.f,0.f), new Vector2d(0.f,0.f)));
//                                                new Vector2d(.75f, 0.2f),
//                                                new Vector2d(.75f, 0.2f),
//                                                new Vector2d(.75f, .4f),
//                                                new Vector2d(.75f, .4f)));
}
void ActorsLoader::initPlatforms(int textureID)
{
    // Platform 1
    Sprite* s1 = new Sprite(26/IMAGE_WIDTH,
    						266/IMAGE_HEIGHT,
    						203/IMAGE_WIDTH,
    						696/IMAGE_HEIGHT,
    						textureID, false);

    Sprite** sp1 = new Sprite*[1];
    sp1[0] = s1;

    SpriteArray* arr1 = new SpriteArray(sp1, 1);

    Animation* a1 = new Animation(arr1, s1, 300, true);
    Animation** aArr1 = new Animation*[1];
    aArr1[0] = a1;
    AnimationArray* aAnimArr1 = new AnimationArray(aArr1, 1);

    PLATFORM_1 = new Actor(aAnimArr1, a1, new Vector2d(1.f, 3.5f),
					new OffsetMatrix(
						   new Vector2d(0.05f,0.f),
						   new Vector2d(-0.13f,0.f),
						   new Vector2d(0.05f,0.f),
						   new Vector2d(-0.13f,0.f)));

    // Platform 3
    Sprite* s3 = new Sprite(26/IMAGE_WIDTH,
    						266/IMAGE_HEIGHT,
    						203/IMAGE_WIDTH,
    						696/IMAGE_HEIGHT,
    						textureID, true);

    Sprite** sp3 = new Sprite*[1];
    sp3[0] = s3;

    SpriteArray* arr3 = new SpriteArray(sp3, 1);

    Animation* a3 = new Animation(arr3, s3, 300, true);
    Animation** aArr3 = new Animation*[1];
    aArr3[0] = a3;
    AnimationArray* aAnimArr3 = new AnimationArray(aArr3, 1);

    PLATFORM_3 = new Actor(aAnimArr3, a3, new Vector2d(1.f, 3.5f),
					new OffsetMatrix(
						   new Vector2d(0.05f,0.f),
						   new Vector2d(-0.13f,0.f),
						   new Vector2d(0.05f,0.f),
						   new Vector2d(-0.13f,0.f)));
    // Platform 2
    Sprite* s2 = new Sprite(281/IMAGE_WIDTH,
    						266/IMAGE_HEIGHT,
    						221/IMAGE_WIDTH,
    						696/IMAGE_HEIGHT,
    						textureID, false);

    Sprite** sp2 = new Sprite*[1];
    sp2[0] = s2;

    SpriteArray* arr2 = new SpriteArray(sp2, 1);

    Animation* a2 = new Animation(arr2, s2, 300, true);
    Animation** aArr2 = new Animation*[1];
    aArr2[0] = a2;
    AnimationArray* aAnimArr2 = new AnimationArray(aArr2, 1);

    PLATFORM_2 = new Actor(aAnimArr2, a2, new Vector2d(1.f, 3.5f),
                           new OffsetMatrix(
                        		   new Vector2d(0.16f,0.f),
                        		   new Vector2d(-0.15f,0.f),
                        		   new Vector2d(0.16f,0.f),
                        		   new Vector2d(-0.15f,0.f)));

//    Sprite* s3 = new Sprite();

}

void ActorsLoader::initChainsaw(int textureID)
{
	//  Chainsaw
	Sprite* s1 = new Sprite(  5/IMAGE_WIDTH,
							185/IMAGE_HEIGHT,
							 64/IMAGE_WIDTH,
							 27/IMAGE_HEIGHT,
							textureID, false);

	Sprite* s2 = new Sprite(  5/IMAGE_WIDTH,
							218/IMAGE_HEIGHT,
							 64/IMAGE_WIDTH,
							 27/IMAGE_HEIGHT,
							textureID, false);

	Sprite** sp = new Sprite*[2];
	sp[0] = s1;
	sp[1] = s2;

	SpriteArray* arr1 = new SpriteArray(sp, 2);

	Animation* a = new Animation(arr1, s1, 50, true);
	Animation** aArr = new Animation*[1];
	aArr[0] = a;
	AnimationArray* aAnimArr = new AnimationArray(aArr, 1);

	CHAINSAW = new Actor(aAnimArr, a, new Vector2d(0.6f, 0.3f));
}

void ActorsLoader::initObstacle(int textureID)
{
    //  Obstacle Box
    Sprite* s1 = new Sprite(896/IMAGE_WIDTH,
							  2/IMAGE_HEIGHT,
							161/IMAGE_WIDTH,
							159/IMAGE_HEIGHT,
							textureID, true);

    Sprite** sp = new Sprite*[1];
    sp[0] = s1;

    SpriteArray* arr1 = new SpriteArray(sp, 1);

    Animation* a = new Animation(arr1, s1, 1, true);
    Animation** aArr = new Animation*[1];
    aArr[0] = a;
    AnimationArray* aAnimArr = new AnimationArray(aArr, 1);

    OBSTACLE_BOX = new Actor(aAnimArr, a, new Vector2d(1.0f, 1.0f));
}

void ActorsLoader::init(int textureID)
{
    ActorsLoader::initMainCharacter(textureID);
    ActorsLoader::initPlatforms(textureID);
    ActorsLoader::initChainsaw(textureID);
    ActorsLoader::initObstacle(textureID);
}
Actor* ActorsLoader::newMainCharacterActor()
{
    if (MAIN_CHARACTER == 0) {
        Log(LOG_ERROR, "ActorsLoader", "MAIN_CHARACTER is null, probably because init was never called.");
        return 0;
    }

    return new Actor(MAIN_CHARACTER);
}
Actor* ActorsLoader::newPlatformActor_1()
{
    if (PLATFORM_1 == 0) {
        Log(LOG_ERROR, "ActorsLoader", "PLATFORM_1 is null, probably because init was never called.");
        return 0;
    }

    return new Actor(PLATFORM_1);
}
Actor* ActorsLoader::newPlatformActor_2()
{
    if (PLATFORM_2 == 0) {
        Log(LOG_ERROR, "ActorsLoader", "PLATFORM_1 is null, probably because init was never called.");
        return 0;
    }

    return new Actor(PLATFORM_2);
}

Actor* ActorsLoader::newPlatformActor_3()
{
    if (PLATFORM_3 == 0) {
        Log(LOG_ERROR, "ActorsLoader", "PLATFORM_1 is null, probably because init was never called.");
        return 0;
    }

    return new Actor(PLATFORM_3);
}

Actor* ActorsLoader::newChainsawActor()
{
    if (CHAINSAW == 0) {
        Log(LOG_ERROR, "ActorsLoader", "CHAINSAW is null, probably because init was never called.");
        return 0;
    }

    return new Actor(CHAINSAW);
}

Actor* ActorsLoader::newObstacleBoxActor()
{
    if (OBSTACLE_BOX == 0) {
        Log(LOG_ERROR, "ActorsLoader", "PLATFORM_1 is null, probably because init was never called.");
        return 0;
    }

    return new Actor(OBSTACLE_BOX);
}
<|endoftext|>


<commit_before>//===- PassManagerBuilder.cpp - Build Standard Pass -----------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the PassManagerBuilder class, which is used to set up a
// "standard" optimization sequence suitable for languages like C and C++.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm-c/Transforms/PassManagerBuilder.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/DefaultPasses.h"
#include "llvm/PassManager.h"
#include "llvm/PassManager.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Vectorize.h"

using namespace llvm;

static cl::opt<bool>
RunLoopVectorization("vectorize-loops",
                     cl::desc("Run the Loop vectorization passes"));

static cl::opt<bool>
RunBBVectorization("vectorize", cl::desc("Run the BB vectorization passes"));

static cl::opt<bool>
UseGVNAfterVectorization("use-gvn-after-vectorization",
  cl::init(false), cl::Hidden,
  cl::desc("Run GVN instead of Early CSE after vectorization passes"));

static cl::opt<bool> UseNewSROA("use-new-sroa",
  cl::init(true), cl::Hidden,
  cl::desc("Enable the new, experimental SROA pass"));

PassManagerBuilder::PassManagerBuilder() {
    OptLevel = 2;
    SizeLevel = 0;
    LibraryInfo = 0;
    Inliner = 0;
    DisableSimplifyLibCalls = false;
    DisableUnitAtATime = false;
    DisableUnrollLoops = false;
    Vectorize = RunBBVectorization;
    LoopVectorize = RunLoopVectorization;
}

PassManagerBuilder::~PassManagerBuilder() {
  delete LibraryInfo;
  delete Inliner;
}

/// Set of global extensions, automatically added as part of the standard set.
static ManagedStatic<SmallVector<std::pair<PassManagerBuilder::ExtensionPointTy,
   PassManagerBuilder::ExtensionFn>, 8> > GlobalExtensions;

void PassManagerBuilder::addGlobalExtension(
    PassManagerBuilder::ExtensionPointTy Ty,
    PassManagerBuilder::ExtensionFn Fn) {
  GlobalExtensions->push_back(std::make_pair(Ty, Fn));
}

void PassManagerBuilder::addExtension(ExtensionPointTy Ty, ExtensionFn Fn) {
  Extensions.push_back(std::make_pair(Ty, Fn));
}

void PassManagerBuilder::addExtensionsToPM(ExtensionPointTy ETy,
                                           PassManagerBase &PM) const {
  for (unsigned i = 0, e = GlobalExtensions->size(); i != e; ++i)
    if ((*GlobalExtensions)[i].first == ETy)
      (*GlobalExtensions)[i].second(*this, PM);
  for (unsigned i = 0, e = Extensions.size(); i != e; ++i)
    if (Extensions[i].first == ETy)
      Extensions[i].second(*this, PM);
}

void
PassManagerBuilder::addInitialAliasAnalysisPasses(PassManagerBase &PM) const {
  // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that
  // BasicAliasAnalysis wins if they disagree. This is intended to help
  // support "obvious" type-punning idioms.
  PM.add(createTypeBasedAliasAnalysisPass());
  PM.add(createBasicAliasAnalysisPass());
}

void PassManagerBuilder::populateFunctionPassManager(FunctionPassManager &FPM) {
  addExtensionsToPM(EP_EarlyAsPossible, FPM);

  // Add LibraryInfo if we have some.
  if (LibraryInfo) FPM.add(new TargetLibraryInfo(*LibraryInfo));

  if (OptLevel == 0) return;

  addInitialAliasAnalysisPasses(FPM);

  FPM.add(createCFGSimplificationPass());
  if (UseNewSROA)
    FPM.add(createSROAPass());
  else
    FPM.add(createScalarReplAggregatesPass());
  FPM.add(createEarlyCSEPass());
  FPM.add(createLowerExpectIntrinsicPass());
}

void PassManagerBuilder::populateModulePassManager(PassManagerBase &MPM) {
  // If all optimizations are disabled, just run the always-inline pass.
  if (OptLevel == 0) {
    if (Inliner) {
      MPM.add(Inliner);
      Inliner = 0;
    }

    // FIXME: This is a HACK! The inliner pass above implicitly creates a CGSCC
    // pass manager, but we don't want to add extensions into that pass manager.
    // To prevent this we must insert a no-op module pass to reset the pass
    // manager to get the same behavior as EP_OptimizerLast in non-O0 builds.
    if (!GlobalExtensions->empty() || !Extensions.empty())
      MPM.add(createBarrierNoopPass());

    addExtensionsToPM(EP_EnabledOnOptLevel0, MPM);
    return;
  }

  // Add LibraryInfo if we have some.
  if (LibraryInfo) MPM.add(new TargetLibraryInfo(*LibraryInfo));

  addInitialAliasAnalysisPasses(MPM);

  if (!DisableUnitAtATime) {
    addExtensionsToPM(EP_ModuleOptimizerEarly, MPM);

    MPM.add(createGlobalOptimizerPass());     // Optimize out global vars

    MPM.add(createIPSCCPPass());              // IP SCCP
    MPM.add(createDeadArgEliminationPass());  // Dead argument elimination

    MPM.add(createInstructionCombiningPass());// Clean up after IPCP & DAE
    MPM.add(createCFGSimplificationPass());   // Clean up after IPCP & DAE
  }

  // Start of CallGraph SCC passes.
  if (!DisableUnitAtATime)
    MPM.add(createPruneEHPass());             // Remove dead EH info
  if (Inliner) {
    MPM.add(Inliner);
    Inliner = 0;
  }
  if (!DisableUnitAtATime)
    MPM.add(createFunctionAttrsPass());       // Set readonly/readnone attrs
  if (OptLevel > 2)
    MPM.add(createArgumentPromotionPass());   // Scalarize uninlined fn args

  // Start of function pass.
  // Break up aggregate allocas, using SSAUpdater.
  if (UseNewSROA)
    MPM.add(createSROAPass(/*RequiresDomTree*/ false));
  else
    MPM.add(createScalarReplAggregatesPass(-1, false));
  MPM.add(createEarlyCSEPass());              // Catch trivial redundancies
  if (!DisableSimplifyLibCalls)
    MPM.add(createSimplifyLibCallsPass());    // Library Call Optimizations
  MPM.add(createJumpThreadingPass());         // Thread jumps.
  MPM.add(createCorrelatedValuePropagationPass()); // Propagate conditionals
  MPM.add(createCFGSimplificationPass());     // Merge & remove BBs
  MPM.add(createInstructionCombiningPass());  // Combine silly seq's

  MPM.add(createTailCallEliminationPass());   // Eliminate tail calls
  MPM.add(createCFGSimplificationPass());     // Merge & remove BBs
  MPM.add(createReassociatePass());           // Reassociate expressions
  MPM.add(createLoopRotatePass());            // Rotate Loop
  MPM.add(createLICMPass());                  // Hoist loop invariants
  MPM.add(createLoopUnswitchPass(SizeLevel || OptLevel < 3));
  MPM.add(createInstructionCombiningPass());
  MPM.add(createIndVarSimplifyPass());        // Canonicalize indvars
  MPM.add(createLoopIdiomPass());             // Recognize idioms like memset.
  MPM.add(createLoopDeletionPass());          // Delete dead loops

  if (true && OptLevel > 1)
    MPM.add(createLoopVectorizePass());

  if (!DisableUnrollLoops)
    MPM.add(createLoopUnrollPass());          // Unroll small loops
  addExtensionsToPM(EP_LoopOptimizerEnd, MPM);

  if (OptLevel > 1)
    MPM.add(createGVNPass());                 // Remove redundancies
  MPM.add(createMemCpyOptPass());             // Remove memcpy / form memset
  MPM.add(createSCCPPass());                  // Constant prop with SCCP

  // Run instcombine after redundancy elimination to exploit opportunities
  // opened up by them.
  MPM.add(createInstructionCombiningPass());
  MPM.add(createJumpThreadingPass());         // Thread jumps
  MPM.add(createCorrelatedValuePropagationPass());
  MPM.add(createDeadStoreEliminationPass());  // Delete dead stores

  addExtensionsToPM(EP_ScalarOptimizerLate, MPM);

  if (Vectorize) {
    MPM.add(createBBVectorizePass());
    MPM.add(createInstructionCombiningPass());
    if (OptLevel > 1 && UseGVNAfterVectorization)
      MPM.add(createGVNPass());                   // Remove redundancies
    else
      MPM.add(createEarlyCSEPass());              // Catch trivial redundancies
  }

  MPM.add(createAggressiveDCEPass());         // Delete dead instructions
  MPM.add(createCFGSimplificationPass());     // Merge & remove BBs
  MPM.add(createInstructionCombiningPass());  // Clean up after everything.

  if (!DisableUnitAtATime) {
    // FIXME: We shouldn't bother with this anymore.
    MPM.add(createStripDeadPrototypesPass()); // Get rid of dead prototypes

    // GlobalOpt already deletes dead functions and globals, at -O2 try a
    // late pass of GlobalDCE.  It is capable of deleting dead cycles.
    if (OptLevel > 1) {
      MPM.add(createGlobalDCEPass());         // Remove dead fns and globals.
      MPM.add(createConstantMergePass());     // Merge dup global constants
    }
  }
  addExtensionsToPM(EP_OptimizerLast, MPM);
}

void PassManagerBuilder::populateLTOPassManager(PassManagerBase &PM,
                                                bool Internalize,
                                                bool RunInliner,
                                                bool DisableGVNLoadPRE) {
  // Provide AliasAnalysis services for optimizations.
  addInitialAliasAnalysisPasses(PM);

  // Now that composite has been compiled, scan through the module, looking
  // for a main function.  If main is defined, mark all other functions
  // internal.
  if (Internalize) {
    std::vector<const char*> E;
    E.push_back("main");
    PM.add(createInternalizePass(E));
  }

  // Propagate constants at call sites into the functions they call.  This
  // opens opportunities for globalopt (and inlining) by substituting function
  // pointers passed as arguments to direct uses of functions.
  PM.add(createIPSCCPPass());

  // Now that we internalized some globals, see if we can hack on them!
  PM.add(createGlobalOptimizerPass());

  // Linking modules together can lead to duplicated global constants, only
  // keep one copy of each constant.
  PM.add(createConstantMergePass());

  // Remove unused arguments from functions.
  PM.add(createDeadArgEliminationPass());

  // Reduce the code after globalopt and ipsccp.  Both can open up significant
  // simplification opportunities, and both can propagate functions through
  // function pointers.  When this happens, we often have to resolve varargs
  // calls, etc, so let instcombine do this.
  PM.add(createInstructionCombiningPass());

  // Inline small functions
  if (RunInliner)
    PM.add(createFunctionInliningPass());

  PM.add(createPruneEHPass());   // Remove dead EH info.

  // Optimize globals again if we ran the inliner.
  if (RunInliner)
    PM.add(createGlobalOptimizerPass());
  PM.add(createGlobalDCEPass()); // Remove dead functions.

  // If we didn't decide to inline a function, check to see if we can
  // transform it to pass arguments by value instead of by reference.
  PM.add(createArgumentPromotionPass());

  // The IPO passes may leave cruft around.  Clean up after them.
  PM.add(createInstructionCombiningPass());
  PM.add(createJumpThreadingPass());
  // Break up allocas
  if (UseNewSROA)
    PM.add(createSROAPass());
  else
    PM.add(createScalarReplAggregatesPass());

  // Run a few AA driven optimizations here and now, to cleanup the code.
  PM.add(createFunctionAttrsPass()); // Add nocapture.
  PM.add(createGlobalsModRefPass()); // IP alias analysis.

  PM.add(createLICMPass());                 // Hoist loop invariants.
  PM.add(createGVNPass(DisableGVNLoadPRE)); // Remove redundancies.
  PM.add(createMemCpyOptPass());            // Remove dead memcpys.
  // Nuke dead stores.
  PM.add(createDeadStoreEliminationPass());

  // Cleanup and simplify the code after the scalar optimizations.
  PM.add(createInstructionCombiningPass());

  PM.add(createJumpThreadingPass());

  // Delete basic blocks, which optimization passes may have killed.
  PM.add(createCFGSimplificationPass());

  // Now that we have optimized the program, discard unreachable functions.
  PM.add(createGlobalDCEPass());
}

LLVMPassManagerBuilderRef LLVMPassManagerBuilderCreate() {
  PassManagerBuilder *PMB = new PassManagerBuilder();
  return wrap(PMB);
}

void LLVMPassManagerBuilderDispose(LLVMPassManagerBuilderRef PMB) {
  PassManagerBuilder *Builder = unwrap(PMB);
  delete Builder;
}

void
LLVMPassManagerBuilderSetOptLevel(LLVMPassManagerBuilderRef PMB,
                                  unsigned OptLevel) {
  PassManagerBuilder *Builder = unwrap(PMB);
  Builder->OptLevel = OptLevel;
}

void
LLVMPassManagerBuilderSetSizeLevel(LLVMPassManagerBuilderRef PMB,
                                   unsigned SizeLevel) {
  PassManagerBuilder *Builder = unwrap(PMB);
  Builder->SizeLevel = SizeLevel;
}

void
LLVMPassManagerBuilderSetDisableUnitAtATime(LLVMPassManagerBuilderRef PMB,
                                            LLVMBool Value) {
  PassManagerBuilder *Builder = unwrap(PMB);
  Builder->DisableUnitAtATime = Value;
}

void
LLVMPassManagerBuilderSetDisableUnrollLoops(LLVMPassManagerBuilderRef PMB,
                                            LLVMBool Value) {
  PassManagerBuilder *Builder = unwrap(PMB);
  Builder->DisableUnrollLoops = Value;
}

void
LLVMPassManagerBuilderSetDisableSimplifyLibCalls(LLVMPassManagerBuilderRef PMB,
                                                 LLVMBool Value) {
  PassManagerBuilder *Builder = unwrap(PMB);
  Builder->DisableSimplifyLibCalls = Value;
}

void
LLVMPassManagerBuilderUseInlinerWithThreshold(LLVMPassManagerBuilderRef PMB,
                                              unsigned Threshold) {
  PassManagerBuilder *Builder = unwrap(PMB);
  Builder->Inliner = createFunctionInliningPass(Threshold);
}

void
LLVMPassManagerBuilderPopulateFunctionPassManager(LLVMPassManagerBuilderRef PMB,
                                                  LLVMPassManagerRef PM) {
  PassManagerBuilder *Builder = unwrap(PMB);
  FunctionPassManager *FPM = unwrap<FunctionPassManager>(PM);
  Builder->populateFunctionPassManager(*FPM);
}

void
LLVMPassManagerBuilderPopulateModulePassManager(LLVMPassManagerBuilderRef PMB,
                                                LLVMPassManagerRef PM) {
  PassManagerBuilder *Builder = unwrap(PMB);
  PassManagerBase *MPM = unwrap(PM);
  Builder->populateModulePassManager(*MPM);
}

void LLVMPassManagerBuilderPopulateLTOPassManager(LLVMPassManagerBuilderRef PMB,
                                                  LLVMPassManagerRef PM,
                                                  bool Internalize,
                                                  bool RunInliner) {
  PassManagerBuilder *Builder = unwrap(PMB);
  PassManagerBase *LPM = unwrap(PM);
  Builder->populateLTOPassManager(*LPM, Internalize, RunInliner);
}
<commit_msg>Enable the loop vectorizer in clang and not in the pass manager, so that we can disable it in clang.<commit_after>//===- PassManagerBuilder.cpp - Build Standard Pass -----------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the PassManagerBuilder class, which is used to set up a
// "standard" optimization sequence suitable for languages like C and C++.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm-c/Transforms/PassManagerBuilder.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/DefaultPasses.h"
#include "llvm/PassManager.h"
#include "llvm/PassManager.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Vectorize.h"

using namespace llvm;

static cl::opt<bool>
RunLoopVectorization("vectorize-loops",
                     cl::desc("Run the Loop vectorization passes"));

static cl::opt<bool>
RunBBVectorization("vectorize", cl::desc("Run the BB vectorization passes"));

static cl::opt<bool>
UseGVNAfterVectorization("use-gvn-after-vectorization",
  cl::init(false), cl::Hidden,
  cl::desc("Run GVN instead of Early CSE after vectorization passes"));

static cl::opt<bool> UseNewSROA("use-new-sroa",
  cl::init(true), cl::Hidden,
  cl::desc("Enable the new, experimental SROA pass"));

PassManagerBuilder::PassManagerBuilder() {
    OptLevel = 2;
    SizeLevel = 0;
    LibraryInfo = 0;
    Inliner = 0;
    DisableSimplifyLibCalls = false;
    DisableUnitAtATime = false;
    DisableUnrollLoops = false;
    Vectorize = RunBBVectorization;
    LoopVectorize = RunLoopVectorization;
}

PassManagerBuilder::~PassManagerBuilder() {
  delete LibraryInfo;
  delete Inliner;
}

/// Set of global extensions, automatically added as part of the standard set.
static ManagedStatic<SmallVector<std::pair<PassManagerBuilder::ExtensionPointTy,
   PassManagerBuilder::ExtensionFn>, 8> > GlobalExtensions;

void PassManagerBuilder::addGlobalExtension(
    PassManagerBuilder::ExtensionPointTy Ty,
    PassManagerBuilder::ExtensionFn Fn) {
  GlobalExtensions->push_back(std::make_pair(Ty, Fn));
}

void PassManagerBuilder::addExtension(ExtensionPointTy Ty, ExtensionFn Fn) {
  Extensions.push_back(std::make_pair(Ty, Fn));
}

void PassManagerBuilder::addExtensionsToPM(ExtensionPointTy ETy,
                                           PassManagerBase &PM) const {
  for (unsigned i = 0, e = GlobalExtensions->size(); i != e; ++i)
    if ((*GlobalExtensions)[i].first == ETy)
      (*GlobalExtensions)[i].second(*this, PM);
  for (unsigned i = 0, e = Extensions.size(); i != e; ++i)
    if (Extensions[i].first == ETy)
      Extensions[i].second(*this, PM);
}

void
PassManagerBuilder::addInitialAliasAnalysisPasses(PassManagerBase &PM) const {
  // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that
  // BasicAliasAnalysis wins if they disagree. This is intended to help
  // support "obvious" type-punning idioms.
  PM.add(createTypeBasedAliasAnalysisPass());
  PM.add(createBasicAliasAnalysisPass());
}

void PassManagerBuilder::populateFunctionPassManager(FunctionPassManager &FPM) {
  addExtensionsToPM(EP_EarlyAsPossible, FPM);

  // Add LibraryInfo if we have some.
  if (LibraryInfo) FPM.add(new TargetLibraryInfo(*LibraryInfo));

  if (OptLevel == 0) return;

  addInitialAliasAnalysisPasses(FPM);

  FPM.add(createCFGSimplificationPass());
  if (UseNewSROA)
    FPM.add(createSROAPass());
  else
    FPM.add(createScalarReplAggregatesPass());
  FPM.add(createEarlyCSEPass());
  FPM.add(createLowerExpectIntrinsicPass());
}

void PassManagerBuilder::populateModulePassManager(PassManagerBase &MPM) {
  // If all optimizations are disabled, just run the always-inline pass.
  if (OptLevel == 0) {
    if (Inliner) {
      MPM.add(Inliner);
      Inliner = 0;
    }

    // FIXME: This is a HACK! The inliner pass above implicitly creates a CGSCC
    // pass manager, but we don't want to add extensions into that pass manager.
    // To prevent this we must insert a no-op module pass to reset the pass
    // manager to get the same behavior as EP_OptimizerLast in non-O0 builds.
    if (!GlobalExtensions->empty() || !Extensions.empty())
      MPM.add(createBarrierNoopPass());

    addExtensionsToPM(EP_EnabledOnOptLevel0, MPM);
    return;
  }

  // Add LibraryInfo if we have some.
  if (LibraryInfo) MPM.add(new TargetLibraryInfo(*LibraryInfo));

  addInitialAliasAnalysisPasses(MPM);

  if (!DisableUnitAtATime) {
    addExtensionsToPM(EP_ModuleOptimizerEarly, MPM);

    MPM.add(createGlobalOptimizerPass());     // Optimize out global vars

    MPM.add(createIPSCCPPass());              // IP SCCP
    MPM.add(createDeadArgEliminationPass());  // Dead argument elimination

    MPM.add(createInstructionCombiningPass());// Clean up after IPCP & DAE
    MPM.add(createCFGSimplificationPass());   // Clean up after IPCP & DAE
  }

  // Start of CallGraph SCC passes.
  if (!DisableUnitAtATime)
    MPM.add(createPruneEHPass());             // Remove dead EH info
  if (Inliner) {
    MPM.add(Inliner);
    Inliner = 0;
  }
  if (!DisableUnitAtATime)
    MPM.add(createFunctionAttrsPass());       // Set readonly/readnone attrs
  if (OptLevel > 2)
    MPM.add(createArgumentPromotionPass());   // Scalarize uninlined fn args

  // Start of function pass.
  // Break up aggregate allocas, using SSAUpdater.
  if (UseNewSROA)
    MPM.add(createSROAPass(/*RequiresDomTree*/ false));
  else
    MPM.add(createScalarReplAggregatesPass(-1, false));
  MPM.add(createEarlyCSEPass());              // Catch trivial redundancies
  if (!DisableSimplifyLibCalls)
    MPM.add(createSimplifyLibCallsPass());    // Library Call Optimizations
  MPM.add(createJumpThreadingPass());         // Thread jumps.
  MPM.add(createCorrelatedValuePropagationPass()); // Propagate conditionals
  MPM.add(createCFGSimplificationPass());     // Merge & remove BBs
  MPM.add(createInstructionCombiningPass());  // Combine silly seq's

  MPM.add(createTailCallEliminationPass());   // Eliminate tail calls
  MPM.add(createCFGSimplificationPass());     // Merge & remove BBs
  MPM.add(createReassociatePass());           // Reassociate expressions
  MPM.add(createLoopRotatePass());            // Rotate Loop
  MPM.add(createLICMPass());                  // Hoist loop invariants
  MPM.add(createLoopUnswitchPass(SizeLevel || OptLevel < 3));
  MPM.add(createInstructionCombiningPass());
  MPM.add(createIndVarSimplifyPass());        // Canonicalize indvars
  MPM.add(createLoopIdiomPass());             // Recognize idioms like memset.
  MPM.add(createLoopDeletionPass());          // Delete dead loops

  if (LoopVectorize && OptLevel > 1)
    MPM.add(createLoopVectorizePass());

  if (!DisableUnrollLoops)
    MPM.add(createLoopUnrollPass());          // Unroll small loops
  addExtensionsToPM(EP_LoopOptimizerEnd, MPM);

  if (OptLevel > 1)
    MPM.add(createGVNPass());                 // Remove redundancies
  MPM.add(createMemCpyOptPass());             // Remove memcpy / form memset
  MPM.add(createSCCPPass());                  // Constant prop with SCCP

  // Run instcombine after redundancy elimination to exploit opportunities
  // opened up by them.
  MPM.add(createInstructionCombiningPass());
  MPM.add(createJumpThreadingPass());         // Thread jumps
  MPM.add(createCorrelatedValuePropagationPass());
  MPM.add(createDeadStoreEliminationPass());  // Delete dead stores

  addExtensionsToPM(EP_ScalarOptimizerLate, MPM);

  if (Vectorize) {
    MPM.add(createBBVectorizePass());
    MPM.add(createInstructionCombiningPass());
    if (OptLevel > 1 && UseGVNAfterVectorization)
      MPM.add(createGVNPass());                   // Remove redundancies
    else
      MPM.add(createEarlyCSEPass());              // Catch trivial redundancies
  }

  MPM.add(createAggressiveDCEPass());         // Delete dead instructions
  MPM.add(createCFGSimplificationPass());     // Merge & remove BBs
  MPM.add(createInstructionCombiningPass());  // Clean up after everything.

  if (!DisableUnitAtATime) {
    // FIXME: We shouldn't bother with this anymore.
    MPM.add(createStripDeadPrototypesPass()); // Get rid of dead prototypes

    // GlobalOpt already deletes dead functions and globals, at -O2 try a
    // late pass of GlobalDCE.  It is capable of deleting dead cycles.
    if (OptLevel > 1) {
      MPM.add(createGlobalDCEPass());         // Remove dead fns and globals.
      MPM.add(createConstantMergePass());     // Merge dup global constants
    }
  }
  addExtensionsToPM(EP_OptimizerLast, MPM);
}

void PassManagerBuilder::populateLTOPassManager(PassManagerBase &PM,
                                                bool Internalize,
                                                bool RunInliner,
                                                bool DisableGVNLoadPRE) {
  // Provide AliasAnalysis services for optimizations.
  addInitialAliasAnalysisPasses(PM);

  // Now that composite has been compiled, scan through the module, looking
  // for a main function.  If main is defined, mark all other functions
  // internal.
  if (Internalize) {
    std::vector<const char*> E;
    E.push_back("main");
    PM.add(createInternalizePass(E));
  }

  // Propagate constants at call sites into the functions they call.  This
  // opens opportunities for globalopt (and inlining) by substituting function
  // pointers passed as arguments to direct uses of functions.
  PM.add(createIPSCCPPass());

  // Now that we internalized some globals, see if we can hack on them!
  PM.add(createGlobalOptimizerPass());

  // Linking modules together can lead to duplicated global constants, only
  // keep one copy of each constant.
  PM.add(createConstantMergePass());

  // Remove unused arguments from functions.
  PM.add(createDeadArgEliminationPass());

  // Reduce the code after globalopt and ipsccp.  Both can open up significant
  // simplification opportunities, and both can propagate functions through
  // function pointers.  When this happens, we often have to resolve varargs
  // calls, etc, so let instcombine do this.
  PM.add(createInstructionCombiningPass());

  // Inline small functions
  if (RunInliner)
    PM.add(createFunctionInliningPass());

  PM.add(createPruneEHPass());   // Remove dead EH info.

  // Optimize globals again if we ran the inliner.
  if (RunInliner)
    PM.add(createGlobalOptimizerPass());
  PM.add(createGlobalDCEPass()); // Remove dead functions.

  // If we didn't decide to inline a function, check to see if we can
  // transform it to pass arguments by value instead of by reference.
  PM.add(createArgumentPromotionPass());

  // The IPO passes may leave cruft around.  Clean up after them.
  PM.add(createInstructionCombiningPass());
  PM.add(createJumpThreadingPass());
  // Break up allocas
  if (UseNewSROA)
    PM.add(createSROAPass());
  else
    PM.add(createScalarReplAggregatesPass());

  // Run a few AA driven optimizations here and now, to cleanup the code.
  PM.add(createFunctionAttrsPass()); // Add nocapture.
  PM.add(createGlobalsModRefPass()); // IP alias analysis.

  PM.add(createLICMPass());                 // Hoist loop invariants.
  PM.add(createGVNPass(DisableGVNLoadPRE)); // Remove redundancies.
  PM.add(createMemCpyOptPass());            // Remove dead memcpys.
  // Nuke dead stores.
  PM.add(createDeadStoreEliminationPass());

  // Cleanup and simplify the code after the scalar optimizations.
  PM.add(createInstructionCombiningPass());

  PM.add(createJumpThreadingPass());

  // Delete basic blocks, which optimization passes may have killed.
  PM.add(createCFGSimplificationPass());

  // Now that we have optimized the program, discard unreachable functions.
  PM.add(createGlobalDCEPass());
}

LLVMPassManagerBuilderRef LLVMPassManagerBuilderCreate() {
  PassManagerBuilder *PMB = new PassManagerBuilder();
  return wrap(PMB);
}

void LLVMPassManagerBuilderDispose(LLVMPassManagerBuilderRef PMB) {
  PassManagerBuilder *Builder = unwrap(PMB);
  delete Builder;
}

void
LLVMPassManagerBuilderSetOptLevel(LLVMPassManagerBuilderRef PMB,
                                  unsigned OptLevel) {
  PassManagerBuilder *Builder = unwrap(PMB);
  Builder->OptLevel = OptLevel;
}

void
LLVMPassManagerBuilderSetSizeLevel(LLVMPassManagerBuilderRef PMB,
                                   unsigned SizeLevel) {
  PassManagerBuilder *Builder = unwrap(PMB);
  Builder->SizeLevel = SizeLevel;
}

void
LLVMPassManagerBuilderSetDisableUnitAtATime(LLVMPassManagerBuilderRef PMB,
                                            LLVMBool Value) {
  PassManagerBuilder *Builder = unwrap(PMB);
  Builder->DisableUnitAtATime = Value;
}

void
LLVMPassManagerBuilderSetDisableUnrollLoops(LLVMPassManagerBuilderRef PMB,
                                            LLVMBool Value) {
  PassManagerBuilder *Builder = unwrap(PMB);
  Builder->DisableUnrollLoops = Value;
}

void
LLVMPassManagerBuilderSetDisableSimplifyLibCalls(LLVMPassManagerBuilderRef PMB,
                                                 LLVMBool Value) {
  PassManagerBuilder *Builder = unwrap(PMB);
  Builder->DisableSimplifyLibCalls = Value;
}

void
LLVMPassManagerBuilderUseInlinerWithThreshold(LLVMPassManagerBuilderRef PMB,
                                              unsigned Threshold) {
  PassManagerBuilder *Builder = unwrap(PMB);
  Builder->Inliner = createFunctionInliningPass(Threshold);
}

void
LLVMPassManagerBuilderPopulateFunctionPassManager(LLVMPassManagerBuilderRef PMB,
                                                  LLVMPassManagerRef PM) {
  PassManagerBuilder *Builder = unwrap(PMB);
  FunctionPassManager *FPM = unwrap<FunctionPassManager>(PM);
  Builder->populateFunctionPassManager(*FPM);
}

void
LLVMPassManagerBuilderPopulateModulePassManager(LLVMPassManagerBuilderRef PMB,
                                                LLVMPassManagerRef PM) {
  PassManagerBuilder *Builder = unwrap(PMB);
  PassManagerBase *MPM = unwrap(PM);
  Builder->populateModulePassManager(*MPM);
}

void LLVMPassManagerBuilderPopulateLTOPassManager(LLVMPassManagerBuilderRef PMB,
                                                  LLVMPassManagerRef PM,
                                                  bool Internalize,
                                                  bool RunInliner) {
  PassManagerBuilder *Builder = unwrap(PMB);
  PassManagerBase *LPM = unwrap(PM);
  Builder->populateLTOPassManager(*LPM, Internalize, RunInliner);
}
<|endoftext|>


<commit_before>//===--------- LoopSimplifyCFG.cpp - Loop CFG Simplification Pass ---------===//
//
//                     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 Loop SimplifyCFG Pass. This pass is responsible for
// basic loop CFG cleanup, primarily to assist other loop passes. If you
// encounter a noncanonical CFG construct that causes another loop pass to
// perform suboptimally, this is the place to fix it up.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Scalar/LoopSimplifyCFG.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/DependenceAnalysis.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/MemorySSA.h"
#include "llvm/Analysis/MemorySSAUpdater.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/DomTreeUpdater.h"
#include "llvm/IR/Dominators.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Scalar/LoopPassManager.h"
#include "llvm/Transforms/Utils.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
using namespace llvm;

#define DEBUG_TYPE "loop-simplifycfg"

static bool simplifyLoopCFG(Loop &L, DominatorTree &DT, LoopInfo &LI,
                            ScalarEvolution &SE, MemorySSAUpdater *MSSAU) {
  bool Changed = false;
  DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
  // Copy blocks into a temporary array to avoid iterator invalidation issues
  // as we remove them.
  SmallVector<WeakTrackingVH, 16> Blocks(L.blocks());

  for (auto &Block : Blocks) {
    // Attempt to merge blocks in the trivial case. Don't modify blocks which
    // belong to other loops.
    BasicBlock *Succ = cast_or_null<BasicBlock>(Block);
    if (!Succ)
      continue;

    BasicBlock *Pred = Succ->getSinglePredecessor();
    if (!Pred || !Pred->getSingleSuccessor() || LI.getLoopFor(Pred) != &L)
      continue;

    // Merge Succ into Pred and delete it.
    MergeBlockIntoPredecessor(Succ, &DTU, &LI, MSSAU);

    SE.forgetTopmostLoop(&L);

    Changed = true;
  }

  return Changed;
}

PreservedAnalyses LoopSimplifyCFGPass::run(Loop &L, LoopAnalysisManager &AM,
                                           LoopStandardAnalysisResults &AR,
                                           LPMUpdater &) {
  Optional<MemorySSAUpdater> MSSAU;
  if (EnableMSSALoopDependency && AR.MSSA)
    MSSAU = MemorySSAUpdater(AR.MSSA);
  if (!simplifyLoopCFG(L, AR.DT, AR.LI, AR.SE,
                       MSSAU.hasValue() ? MSSAU.getPointer() : nullptr))
    return PreservedAnalyses::all();

  return getLoopPassPreservedAnalyses();
}

namespace {
class LoopSimplifyCFGLegacyPass : public LoopPass {
public:
  static char ID; // Pass ID, replacement for typeid
  LoopSimplifyCFGLegacyPass() : LoopPass(ID) {
    initializeLoopSimplifyCFGLegacyPassPass(*PassRegistry::getPassRegistry());
  }

  bool runOnLoop(Loop *L, LPPassManager &) override {
    if (skipLoop(L))
      return false;

    DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
    LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
    ScalarEvolution &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
    Optional<MemorySSAUpdater> MSSAU;
    if (EnableMSSALoopDependency) {
      MemorySSA *MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA();
      MSSAU = MemorySSAUpdater(MSSA);
      if (VerifyMemorySSA)
        MSSA->verifyMemorySSA();
    }
    return simplifyLoopCFG(*L, DT, LI, SE,
                           MSSAU.hasValue() ? MSSAU.getPointer() : nullptr);
  }

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    if (EnableMSSALoopDependency) {
      AU.addRequired<MemorySSAWrapperPass>();
      AU.addPreserved<MemorySSAWrapperPass>();
    }
    AU.addPreserved<DependenceAnalysisWrapperPass>();
    getLoopAnalysisUsage(AU);
  }
};
}

char LoopSimplifyCFGLegacyPass::ID = 0;
INITIALIZE_PASS_BEGIN(LoopSimplifyCFGLegacyPass, "loop-simplifycfg",
                      "Simplify loop CFG", false, false)
INITIALIZE_PASS_DEPENDENCY(LoopPass)
INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
INITIALIZE_PASS_END(LoopSimplifyCFGLegacyPass, "loop-simplifycfg",
                    "Simplify loop CFG", false, false)

Pass *llvm::createLoopSimplifyCFGPass() {
  return new LoopSimplifyCFGLegacyPass();
}
<commit_msg>[NFC] Reorganize code to prepare it for more transforms<commit_after>//===--------- LoopSimplifyCFG.cpp - Loop CFG Simplification Pass ---------===//
//
//                     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 Loop SimplifyCFG Pass. This pass is responsible for
// basic loop CFG cleanup, primarily to assist other loop passes. If you
// encounter a noncanonical CFG construct that causes another loop pass to
// perform suboptimally, this is the place to fix it up.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Scalar/LoopSimplifyCFG.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/DependenceAnalysis.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/MemorySSA.h"
#include "llvm/Analysis/MemorySSAUpdater.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/DomTreeUpdater.h"
#include "llvm/IR/Dominators.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Scalar/LoopPassManager.h"
#include "llvm/Transforms/Utils.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
using namespace llvm;

#define DEBUG_TYPE "loop-simplifycfg"

static bool mergeBlocksIntoPredecessors(Loop &L, DominatorTree &DT,
                                        LoopInfo &LI, MemorySSAUpdater *MSSAU) {
  bool Changed = false;
  DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
  // Copy blocks into a temporary array to avoid iterator invalidation issues
  // as we remove them.
  SmallVector<WeakTrackingVH, 16> Blocks(L.blocks());

  for (auto &Block : Blocks) {
    // Attempt to merge blocks in the trivial case. Don't modify blocks which
    // belong to other loops.
    BasicBlock *Succ = cast_or_null<BasicBlock>(Block);
    if (!Succ)
      continue;

    BasicBlock *Pred = Succ->getSinglePredecessor();
    if (!Pred || !Pred->getSingleSuccessor() || LI.getLoopFor(Pred) != &L)
      continue;

    // Merge Succ into Pred and delete it.
    MergeBlockIntoPredecessor(Succ, &DTU, &LI, MSSAU);

    Changed = true;
  }

  return Changed;
}

static bool simplifyLoopCFG(Loop &L, DominatorTree &DT, LoopInfo &LI,
                            ScalarEvolution &SE, MemorySSAUpdater *MSSAU) {
  bool Changed = false;

  // Eliminate unconditional branches by merging blocks into their predecessors.
  Changed |= mergeBlocksIntoPredecessors(L, DT, LI, MSSAU);

  if (Changed)
    SE.forgetTopmostLoop(&L);

  return Changed;
}

PreservedAnalyses LoopSimplifyCFGPass::run(Loop &L, LoopAnalysisManager &AM,
                                           LoopStandardAnalysisResults &AR,
                                           LPMUpdater &) {
  Optional<MemorySSAUpdater> MSSAU;
  if (EnableMSSALoopDependency && AR.MSSA)
    MSSAU = MemorySSAUpdater(AR.MSSA);
  if (!simplifyLoopCFG(L, AR.DT, AR.LI, AR.SE,
                       MSSAU.hasValue() ? MSSAU.getPointer() : nullptr))
    return PreservedAnalyses::all();

  return getLoopPassPreservedAnalyses();
}

namespace {
class LoopSimplifyCFGLegacyPass : public LoopPass {
public:
  static char ID; // Pass ID, replacement for typeid
  LoopSimplifyCFGLegacyPass() : LoopPass(ID) {
    initializeLoopSimplifyCFGLegacyPassPass(*PassRegistry::getPassRegistry());
  }

  bool runOnLoop(Loop *L, LPPassManager &) override {
    if (skipLoop(L))
      return false;

    DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
    LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
    ScalarEvolution &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
    Optional<MemorySSAUpdater> MSSAU;
    if (EnableMSSALoopDependency) {
      MemorySSA *MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA();
      MSSAU = MemorySSAUpdater(MSSA);
      if (VerifyMemorySSA)
        MSSA->verifyMemorySSA();
    }
    return simplifyLoopCFG(*L, DT, LI, SE,
                           MSSAU.hasValue() ? MSSAU.getPointer() : nullptr);
  }

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    if (EnableMSSALoopDependency) {
      AU.addRequired<MemorySSAWrapperPass>();
      AU.addPreserved<MemorySSAWrapperPass>();
    }
    AU.addPreserved<DependenceAnalysisWrapperPass>();
    getLoopAnalysisUsage(AU);
  }
};
}

char LoopSimplifyCFGLegacyPass::ID = 0;
INITIALIZE_PASS_BEGIN(LoopSimplifyCFGLegacyPass, "loop-simplifycfg",
                      "Simplify loop CFG", false, false)
INITIALIZE_PASS_DEPENDENCY(LoopPass)
INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
INITIALIZE_PASS_END(LoopSimplifyCFGLegacyPass, "loop-simplifycfg",
                    "Simplify loop CFG", false, false)

Pass *llvm::createLoopSimplifyCFGPass() {
  return new LoopSimplifyCFGLegacyPass();
}
<|endoftext|>


<commit_before>/*=========================================================================

  Library:   CTK

  Copyright (c) Kitware Inc.

  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.txt

  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.

=========================================================================*/

// Qt includes
#include <QApplication>
#include <QDebug>
#include <QIcon>
#include <QMouseEvent>
#include <QPainter>
#include <QRect>
#include <QStyleOption>

// CTK includes
#include "ctkSearchBox.h"

// --------------------------------------------------
class ctkSearchBoxPrivate
{
  Q_DECLARE_PUBLIC(ctkSearchBox);
protected:
  ctkSearchBox* const q_ptr;
public:
  ctkSearchBoxPrivate(ctkSearchBox& object);
  void init();

  /// Position and size for the clear icon in the QLineEdit
  QRect clearRect()const;
  /// Position and size for the search icon in the QLineEdit
  QRect searchRect()const;

  QIcon clearIcon;
  QIcon searchIcon;
  bool showSearchIcon;
  bool alwaysShowClearIcon;
  bool hideClearIcon;

#if QT_VERSION < 0x040700
  QString placeholderText;
#endif
};

// --------------------------------------------------
ctkSearchBoxPrivate::ctkSearchBoxPrivate(ctkSearchBox &object)
  : q_ptr(&object)
{
  this->clearIcon = QIcon(":Icons/clear2.svg");
  this->searchIcon = QIcon(":Icons/search.svg");
  this->showSearchIcon = false;
  this->alwaysShowClearIcon = false;
  this->hideClearIcon = true;
}

// --------------------------------------------------
void ctkSearchBoxPrivate::init()
{
  Q_Q(ctkSearchBox);

  // Set a text by default on the QLineEdit
  q->setPlaceholderText(q->tr("Search..."));

  QObject::connect(q, SIGNAL(textChanged(QString)),
                   q, SLOT(updateClearButtonState()));
}

// --------------------------------------------------
QRect ctkSearchBoxPrivate::clearRect()const
{
  Q_Q(const ctkSearchBox);
  QRect cRect = this->searchRect();
  cRect.moveLeft(q->width() - cRect.width() - cRect.left());
  return cRect;
}

// --------------------------------------------------
QRect ctkSearchBoxPrivate::searchRect()const
{
  Q_Q(const ctkSearchBox);
  QRect sRect = q->contentsRect();
  // If the QLineEdit has a frame, the icon must be shifted from
  // the frame line width
  if (q->hasFrame())
    {
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
    QStyleOptionFrameV2 opt;
#else
    QStyleOptionFrame opt;
#endif
    q->initStyleOption(&opt);
    sRect.adjust(opt.lineWidth, opt.lineWidth, -opt.lineWidth, -opt.lineWidth);
    }
  // Hardcoded: shrink by 1 pixel because some styles have a focus frame inside
  // the line edit frame.
  sRect.adjust(1, 1, -1, -1);
  // Square size
  sRect.setWidth(sRect.height());
  return sRect;
}

// --------------------------------------------------
ctkSearchBox::ctkSearchBox(QWidget* _parent)
  : QLineEdit(_parent)
  , d_ptr(new ctkSearchBoxPrivate(*this))
{
  Q_D(ctkSearchBox);
  d->init();
}

// --------------------------------------------------
ctkSearchBox::~ctkSearchBox()
{
}

#if QT_VERSION < 0x040700
// --------------------------------------------------
QString ctkSearchBox::placeholderText()const
{
  Q_D(const ctkSearchBox);
  return d->placeholderText;
}

// --------------------------------------------------
void ctkSearchBox::setPlaceholderText(const QString &defaultText)
{
  Q_D(ctkSearchBox);
  d->placeholderText = defaultText;
  if (!this->hasFocus())
    {
    this->update();
    }
}
#endif

// --------------------------------------------------
void ctkSearchBox::setShowSearchIcon(bool show)
{
  Q_D(ctkSearchBox);
  d->showSearchIcon = show;
  this->update();
}

// --------------------------------------------------
bool ctkSearchBox::showSearchIcon()const
{
  Q_D(const ctkSearchBox);
  return d->showSearchIcon;
}

// --------------------------------------------------
void ctkSearchBox::setAlwaysShowClearIcon(bool show)
{
  Q_D(ctkSearchBox);
  d->alwaysShowClearIcon = show;
  if (show == true)
    {
    d->hideClearIcon = false;
    }
  this->update();
}

// --------------------------------------------------
bool ctkSearchBox::alwaysShowClearIcon()const
{
  Q_D(const ctkSearchBox);
  return d->alwaysShowClearIcon;
}

// --------------------------------------------------
void ctkSearchBox::setSearchIcon(const QIcon& icon)
{
  Q_D(ctkSearchBox);
  d->searchIcon = icon;
  this->update();
}

// --------------------------------------------------
QIcon ctkSearchBox::searchIcon()const
{
  Q_D(const ctkSearchBox);
  return d->searchIcon;
}

// --------------------------------------------------
void ctkSearchBox::setClearIcon(const QIcon& icon)
{
  Q_D(ctkSearchBox);
  d->clearIcon = icon;
  this->update();
}

// --------------------------------------------------
QIcon ctkSearchBox::clearIcon()const
{
  Q_D(const ctkSearchBox);
  return d->clearIcon;
}

// --------------------------------------------------
void ctkSearchBox::paintEvent(QPaintEvent * event)
{
  Q_D(ctkSearchBox);

  // Draw the line edit with text.
  // Text has already been shifted to the right (in resizeEvent()) to leave
  // space for the search icon.
  this->Superclass::paintEvent(event);

  QPainter p(this);

  QRect cRect = d->clearRect();
  QRect sRect = d->showSearchIcon ? d->searchRect() : QRect();

#if QT_VERSION >= 0x040700
  QRect r = rect();
  QPalette pal = palette();

#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
  QStyleOptionFrameV2 panel;
#else
  QStyleOptionFrame panel;
#endif
  initStyleOption(&panel);
  r = this->style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);
  r.setX(r.x() + this->textMargins().left());
  r.setY(r.y() + this->textMargins().top());
  r.setRight(r.right() - this->textMargins().right());
  r.setBottom(r.bottom() - this->textMargins().bottom());
  p.setClipRect(r);

  QFontMetrics fm = fontMetrics();
  Qt::Alignment va = QStyle::visualAlignment(this->layoutDirection(),
                                             QFlag(this->alignment()));
  int vscroll = 0;
  const int verticalMargin = 1;
  const int horizontalMargin = 2;
  switch (va & Qt::AlignVertical_Mask) {
   case Qt::AlignBottom:
       vscroll = r.y() + r.height() - fm.height() - verticalMargin;
       break;
   case Qt::AlignTop:
       vscroll = r.y() + verticalMargin;
       break;
   default:
       //center
       vscroll = r.y() + (r.height() - fm.height() + 1) / 2;
       break;
  }
  QRect lineRect(r.x() + horizontalMargin, vscroll,
                 r.width() - 2*horizontalMargin, fm.height());

  int minLB = qMax(0, -fm.minLeftBearing());

  if (this->text().isEmpty())
    {
    if (!this->hasFocus() && !this->placeholderText().isEmpty())
      {
      QColor col = pal.text().color();
      col.setAlpha(128);
      QPen oldpen = p.pen();
      p.setPen(col);
      lineRect.adjust(minLB, 0, 0, 0);
      QString elidedText = fm.elidedText(this->placeholderText(), Qt::ElideRight, lineRect.width());
      p.drawText(lineRect, va, elidedText);
      p.setPen(oldpen);
      }
    }
  p.setClipRect(this->rect());
#endif

  // Draw clearIcon
  if (!d->hideClearIcon)
    {
    QPixmap closePixmap = d->clearIcon.pixmap(cRect.size(),this->isEnabled() ? QIcon::Normal : QIcon::Disabled);
    this->style()->drawItemPixmap(&p, cRect, Qt::AlignCenter, closePixmap);
    }

  // Draw searchIcon
  if (d->showSearchIcon)
    {
    QPixmap searchPixmap = d->searchIcon.pixmap(sRect.size(), this->isEnabled() ? QIcon::Normal : QIcon::Disabled);
    this->style()->drawItemPixmap(&p, sRect, Qt::AlignCenter, searchPixmap);
    }
}

// --------------------------------------------------
void ctkSearchBox::mousePressEvent(QMouseEvent *e)
{
  Q_D(ctkSearchBox);

  if(d->clearRect().contains(e->pos()))
    {
    this->clear();
    emit this->textEdited(this->text());
    return;
    }

  if(d->showSearchIcon && d->searchRect().contains(e->pos()))
    {
    this->selectAll();
    return;
    }

  this->Superclass::mousePressEvent(e);
}

// --------------------------------------------------
void ctkSearchBox::mouseMoveEvent(QMouseEvent *e)
{
  Q_D(ctkSearchBox);

  if(d->clearRect().contains(e->pos()) ||
     (d->showSearchIcon && d->searchRect().contains(e->pos())))
    {
    this->setCursor(Qt::PointingHandCursor);
    }
  else
    {
    this->setCursor(this->isReadOnly() ? Qt::ArrowCursor : Qt::IBeamCursor);
    }
  this->Superclass::mouseMoveEvent(e);
}

// --------------------------------------------------
void ctkSearchBox::resizeEvent(QResizeEvent * event)
{
  Q_D(ctkSearchBox);
  static int iconSpacing = 0; // hardcoded,
  QRect cRect = d->clearRect();
  QRect sRect = d->showSearchIcon ? d->searchRect() : QRect();
  // Set 2 margins each sides of the QLineEdit, according to the icons
  this->setTextMargins( sRect.right() + iconSpacing, 0,
                        event->size().width() - cRect.left() - iconSpacing,0);
}

// --------------------------------------------------
void ctkSearchBox::updateClearButtonState()
{
  Q_D(ctkSearchBox);
  if (!d->alwaysShowClearIcon)
    {
    d->hideClearIcon = this->text().isEmpty() ? true : false;
    }
}

<commit_msg>BUG: Fixed duplicate "Search" placeholder text in ctkSearchBox<commit_after>/*=========================================================================

  Library:   CTK

  Copyright (c) Kitware Inc.

  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.txt

  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.

=========================================================================*/

// Qt includes
#include <QApplication>
#include <QDebug>
#include <QIcon>
#include <QMouseEvent>
#include <QPainter>
#include <QRect>
#include <QStyleOption>

// CTK includes
#include "ctkSearchBox.h"

// --------------------------------------------------
class ctkSearchBoxPrivate
{
  Q_DECLARE_PUBLIC(ctkSearchBox);
protected:
  ctkSearchBox* const q_ptr;
public:
  ctkSearchBoxPrivate(ctkSearchBox& object);
  void init();

  /// Position and size for the clear icon in the QLineEdit
  QRect clearRect()const;
  /// Position and size for the search icon in the QLineEdit
  QRect searchRect()const;

  QIcon clearIcon;
  QIcon searchIcon;
  bool showSearchIcon;
  bool alwaysShowClearIcon;
  bool hideClearIcon;

#if QT_VERSION < 0x040700
  QString placeholderText;
#endif
};

// --------------------------------------------------
ctkSearchBoxPrivate::ctkSearchBoxPrivate(ctkSearchBox &object)
  : q_ptr(&object)
{
  this->clearIcon = QIcon(":Icons/clear2.svg");
  this->searchIcon = QIcon(":Icons/search.svg");
  this->showSearchIcon = false;
  this->alwaysShowClearIcon = false;
  this->hideClearIcon = true;
}

// --------------------------------------------------
void ctkSearchBoxPrivate::init()
{
  Q_Q(ctkSearchBox);

  // Set a text by default on the QLineEdit
  q->setPlaceholderText(q->tr("Search..."));

  QObject::connect(q, SIGNAL(textChanged(QString)),
                   q, SLOT(updateClearButtonState()));
}

// --------------------------------------------------
QRect ctkSearchBoxPrivate::clearRect()const
{
  Q_Q(const ctkSearchBox);
  QRect cRect = this->searchRect();
  cRect.moveLeft(q->width() - cRect.width() - cRect.left());
  return cRect;
}

// --------------------------------------------------
QRect ctkSearchBoxPrivate::searchRect()const
{
  Q_Q(const ctkSearchBox);
  QRect sRect = q->contentsRect();
  // If the QLineEdit has a frame, the icon must be shifted from
  // the frame line width
  if (q->hasFrame())
    {
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
    QStyleOptionFrameV2 opt;
#else
    QStyleOptionFrame opt;
#endif
    q->initStyleOption(&opt);
    sRect.adjust(opt.lineWidth, opt.lineWidth, -opt.lineWidth, -opt.lineWidth);
    }
  // Hardcoded: shrink by 1 pixel because some styles have a focus frame inside
  // the line edit frame.
  sRect.adjust(1, 1, -1, -1);
  // Square size
  sRect.setWidth(sRect.height());
  return sRect;
}

// --------------------------------------------------
ctkSearchBox::ctkSearchBox(QWidget* _parent)
  : QLineEdit(_parent)
  , d_ptr(new ctkSearchBoxPrivate(*this))
{
  Q_D(ctkSearchBox);
  d->init();
}

// --------------------------------------------------
ctkSearchBox::~ctkSearchBox()
{
}

#if QT_VERSION < 0x040700
// --------------------------------------------------
QString ctkSearchBox::placeholderText()const
{
  Q_D(const ctkSearchBox);
  return d->placeholderText;
}

// --------------------------------------------------
void ctkSearchBox::setPlaceholderText(const QString &defaultText)
{
  Q_D(ctkSearchBox);
  d->placeholderText = defaultText;
  if (!this->hasFocus())
    {
    this->update();
    }
}
#endif

// --------------------------------------------------
void ctkSearchBox::setShowSearchIcon(bool show)
{
  Q_D(ctkSearchBox);
  d->showSearchIcon = show;
  this->update();
}

// --------------------------------------------------
bool ctkSearchBox::showSearchIcon()const
{
  Q_D(const ctkSearchBox);
  return d->showSearchIcon;
}

// --------------------------------------------------
void ctkSearchBox::setAlwaysShowClearIcon(bool show)
{
  Q_D(ctkSearchBox);
  d->alwaysShowClearIcon = show;
  if (show == true)
    {
    d->hideClearIcon = false;
    }
  this->update();
}

// --------------------------------------------------
bool ctkSearchBox::alwaysShowClearIcon()const
{
  Q_D(const ctkSearchBox);
  return d->alwaysShowClearIcon;
}

// --------------------------------------------------
void ctkSearchBox::setSearchIcon(const QIcon& icon)
{
  Q_D(ctkSearchBox);
  d->searchIcon = icon;
  this->update();
}

// --------------------------------------------------
QIcon ctkSearchBox::searchIcon()const
{
  Q_D(const ctkSearchBox);
  return d->searchIcon;
}

// --------------------------------------------------
void ctkSearchBox::setClearIcon(const QIcon& icon)
{
  Q_D(ctkSearchBox);
  d->clearIcon = icon;
  this->update();
}

// --------------------------------------------------
QIcon ctkSearchBox::clearIcon()const
{
  Q_D(const ctkSearchBox);
  return d->clearIcon;
}

// --------------------------------------------------
void ctkSearchBox::paintEvent(QPaintEvent * event)
{
  Q_D(ctkSearchBox);

  // Draw the line edit with text.
  // Text has already been shifted to the right (in resizeEvent()) to leave
  // space for the search icon.
  this->Superclass::paintEvent(event);

  QPainter p(this);

  QRect cRect = d->clearRect();
  QRect sRect = d->showSearchIcon ? d->searchRect() : QRect();

#if QT_VERSION < 0x040700
  QRect r = rect();
  QPalette pal = palette();

  QStyleOptionFrameV2 panel;
  initStyleOption(&panel);
  r = this->style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);
  r.setX(r.x() + this->textMargins().left());
  r.setY(r.y() + this->textMargins().top());
  r.setRight(r.right() - this->textMargins().right());
  r.setBottom(r.bottom() - this->textMargins().bottom());
  p.setClipRect(r);

  QFontMetrics fm = fontMetrics();
  Qt::Alignment va = QStyle::visualAlignment(this->layoutDirection(),
                                             QFlag(this->alignment()));
  int vscroll = 0;
  const int verticalMargin = 1;
  const int horizontalMargin = 2;
  switch (va & Qt::AlignVertical_Mask) {
   case Qt::AlignBottom:
       vscroll = r.y() + r.height() - fm.height() - verticalMargin;
       break;
   case Qt::AlignTop:
       vscroll = r.y() + verticalMargin;
       break;
   default:
       //center
       vscroll = r.y() + (r.height() - fm.height() + 1) / 2;
       break;
  }
  QRect lineRect(r.x() + horizontalMargin, vscroll,
                 r.width() - 2*horizontalMargin, fm.height());

  int minLB = qMax(0, -fm.minLeftBearing());

  if (this->text().isEmpty())
    {
    if (!this->hasFocus() && !this->placeholderText().isEmpty())
      {
      QColor col = pal.text().color();
      col.setAlpha(128);
      QPen oldpen = p.pen();
      p.setPen(col);
      lineRect.adjust(minLB, 0, 0, 0);
      QString elidedText = fm.elidedText(this->placeholderText(), Qt::ElideRight, lineRect.width());
      p.drawText(lineRect, va, elidedText);
      p.setPen(oldpen);
      }
    }
  p.setClipRect(this->rect());
#endif

  // Draw clearIcon
  if (!d->hideClearIcon)
    {
    QPixmap closePixmap = d->clearIcon.pixmap(cRect.size(),this->isEnabled() ? QIcon::Normal : QIcon::Disabled);
    this->style()->drawItemPixmap(&p, cRect, Qt::AlignCenter, closePixmap);
    }

  // Draw searchIcon
  if (d->showSearchIcon)
    {
    QPixmap searchPixmap = d->searchIcon.pixmap(sRect.size(), this->isEnabled() ? QIcon::Normal : QIcon::Disabled);
    this->style()->drawItemPixmap(&p, sRect, Qt::AlignCenter, searchPixmap);
    }
}

// --------------------------------------------------
void ctkSearchBox::mousePressEvent(QMouseEvent *e)
{
  Q_D(ctkSearchBox);

  if(d->clearRect().contains(e->pos()))
    {
    this->clear();
    emit this->textEdited(this->text());
    return;
    }

  if(d->showSearchIcon && d->searchRect().contains(e->pos()))
    {
    this->selectAll();
    return;
    }

  this->Superclass::mousePressEvent(e);
}

// --------------------------------------------------
void ctkSearchBox::mouseMoveEvent(QMouseEvent *e)
{
  Q_D(ctkSearchBox);

  if(d->clearRect().contains(e->pos()) ||
     (d->showSearchIcon && d->searchRect().contains(e->pos())))
    {
    this->setCursor(Qt::PointingHandCursor);
    }
  else
    {
    this->setCursor(this->isReadOnly() ? Qt::ArrowCursor : Qt::IBeamCursor);
    }
  this->Superclass::mouseMoveEvent(e);
}

// --------------------------------------------------
void ctkSearchBox::resizeEvent(QResizeEvent * event)
{
  Q_D(ctkSearchBox);
  static int iconSpacing = 0; // hardcoded,
  QRect cRect = d->clearRect();
  QRect sRect = d->showSearchIcon ? d->searchRect() : QRect();
  // Set 2 margins each sides of the QLineEdit, according to the icons
  this->setTextMargins( sRect.right() + iconSpacing, 0,
                        event->size().width() - cRect.left() - iconSpacing,0);
}

// --------------------------------------------------
void ctkSearchBox::updateClearButtonState()
{
  Q_D(ctkSearchBox);
  if (!d->alwaysShowClearIcon)
    {
    d->hideClearIcon = this->text().isEmpty() ? true : false;
    }
}

<|endoftext|>


<commit_before>/*
    sievedebugdialog.cpp

    KMail, the KDE mail client.
    Copyright (c) 2005 Martijn Klingens <klingens@kde.org>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License,
    version 2.0, as published by the Free Software Foundation.
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software Foundation,
    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US
*/

// This file is only compiled when debug is enabled, it is
// not useful enough for non-developers to have this in releases.
#if !defined(NDEBUG)

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "sievedebugdialog.h"

#include <cassert>
#include <limits.h>

#include <QDateTime>

#include <kdebug.h>
#include <klocale.h>
#include <kmessagebox.h>

#include <kmime/kmime_header_parsing.h>
#include <ksieve/error.h>
#include <ksieve/parser.h>
#include <ksieve/scriptbuilder.h>
#include <libkpimidentities/identity.h>
#include <libkpimidentities/identitymanager.h>

#include "kmacctimap.h"
#include "accountmanager.h"
using KMail::AccountManager;
#include "kmkernel.h"
#include "sievejob.h"
#include <QTextEdit>

using KMail::SieveJob;
using KMime::Types::AddrSpecList;

namespace
{

class SieveDebugDataExtractor : public KSieve::ScriptBuilder
{
    enum Context
    {
        None = 0,

        // command itself:
        SieveDebugCommand,

        // tagged args:
        Days, Addresses
    };

public:
    SieveDebugDataExtractor()
    :   KSieve::ScriptBuilder()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    virtual ~SieveDebugDataExtractor()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

private:
    void commandStart( const QString & identifier )
    {
        kDebug( 5006 ) << k_funcinfo << "Identifier: '" << identifier << "'" << endl;
        reset();
    }

    void commandEnd()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void testStart( const QString & )
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void testEnd()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void testListStart()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void testListEnd()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void blockStart()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void blockEnd()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void hashComment( const QString & )
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void bracketComment( const QString & )
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void lineFeed()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void error( const KSieve::Error & e )
    {
        kDebug( 5006 ) << "### " << k_funcinfo << "Error: " <<
            e.asString() << " @ " << e.line() << "," << e.column() << endl;
    }

    void finished()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void taggedArgument( const QString & tag )
    {
        kDebug( 5006 ) << k_funcinfo << "Tag: '" << tag << "'" << endl;
    }

    void stringArgument( const QString & string, bool, const QString & )
    {
        kDebug( 5006 ) << k_funcinfo << "String: '" << string << "'" << endl;
    }

    void numberArgument( unsigned long number, char )
    {
        kDebug( 5006 ) << k_funcinfo << "Number: " << number << endl;
    }

    void stringListArgumentStart()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void stringListEntry( const QString & string, bool, const QString & )
    {
        kDebug( 5006 ) << k_funcinfo << "String: '" << string << "'" << endl;
    }

    void stringListArgumentEnd()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

private:
    void reset()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }
};

} // Anon namespace

namespace KMail
{

SieveDebugDialog::SieveDebugDialog( QWidget *parent )
:   KDialog( parent ),
    mSieveJob( 0 )
{
    setCaption( i18n( "Sieve Diagnostics" ) );
    setButtons( Ok );
    // Collect all accounts
    AccountManager *am = kmkernel->acctMgr();
    assert( am );
    for ( KMAccount *a = am->first(); a; a = am->next() )
        mAccountList.append( a );

    mEdit = new QTextEdit( this );
    setMainWidget( mEdit );

    mEdit->setText( i18n( "Collecting diagnostic information about Sieve support...\n\n" ) );

    setInitialSize( QSize( 640, 480 ) );

    if ( !mAccountList.isEmpty() )
        QTimer::singleShot( 0, this, SLOT( slotDiagNextAccount() ) );
}

SieveDebugDialog::~SieveDebugDialog()
{
    if ( mSieveJob )
    {
        mSieveJob->kill();
        mSieveJob = 0;
    }
    kDebug( 5006 ) << k_funcinfo << endl;
}

void SieveDebugDialog::slotDiagNextAccount()
{
    if ( mAccountList.isEmpty() )
        return;

    KMAccount *acc = mAccountList.first();
    mAccountList.pop_front();

    mEdit->append( i18n( "Collecting data for account '%1'...\n", acc->name() ) );
    mEdit->append( i18n( "------------------------------------------------------------\n" ) );
    mAccountBase = dynamic_cast<KMail::ImapAccountBase *>( acc );
    if ( mAccountBase )
    {
        // Detect URL for this IMAP account
        SieveConfig sieve = mAccountBase->sieveConfig();
        if ( !sieve.managesieveSupported() )
        {
            mEdit->append( i18n( "(Account does not support Sieve)\n\n" ) );
        } else {
            if ( sieve.reuseConfig() )
            {
                // assemble Sieve url from the settings of the account:
                mUrl.setProtocol( "sieve" );
                mUrl.setHost( mAccountBase->host() );
                mUrl.setUser( mAccountBase->login() );
                mUrl.setPass( mAccountBase->passwd() );
                mUrl.setPort( sieve.port() );

                // Translate IMAP LOGIN to PLAIN:
                mUrl.setQuery( "x-mech=" + ( mAccountBase->auth() == "*" ? "PLAIN" : mAccountBase->auth() ) );
            } else {
                sieve.alternateURL();
                mUrl.setFileName( sieve.vacationFileName() );
            }

            mSieveJob = SieveJob::list( mUrl );

            connect( mSieveJob, SIGNAL( gotList( KMail::SieveJob *, bool, const QStringList &, const QString & ) ),
                SLOT( slotGetScriptList( KMail::SieveJob *, bool, const QStringList &, const QString & ) ) );

            // Bypass the singleShot timer -- it's fired when we get our data
            return;
        }
    } else {
        mEdit->append( i18n( "(Account is not an IMAP account)\n\n" ) );
    }

    // Handle next account async
    QTimer::singleShot( 0, this, SLOT( slotDiagNextAccount() ) );
}

void SieveDebugDialog::slotDiagNextScript()
{
    if ( mScriptList.isEmpty() )
    {
        // Continue handling accounts instead
        mScriptList.clear();
        QTimer::singleShot( 0, this, SLOT( slotDiagNextAccount() ) );
        return;
    }

    QString scriptFile = mScriptList.first();
    mScriptList.pop_front();

    mEdit->append( i18n( "Contents of script '%1':\n", scriptFile ) );
    SieveConfig sieve = mAccountBase->sieveConfig();
    if ( sieve.reuseConfig() )
    {
        // assemble Sieve url from the settings of the account:
        mUrl.setProtocol( "sieve" );
        mUrl.setHost( mAccountBase->host() );
        mUrl.setUser( mAccountBase->login() );
        mUrl.setPass( mAccountBase->passwd() );
        mUrl.setPort( sieve.port() );
        // Translate IMAP LOGIN to PLAIN
        mUrl.setQuery( "x-mech=" + ( mAccountBase->auth() == "*" ? "PLAIN" : mAccountBase->auth() ) );
        mUrl.setFileName( scriptFile );
    } else {
        sieve.alternateURL();
        mUrl.setFileName( scriptFile );
    }

    mSieveJob = SieveJob::get( mUrl );

    connect( mSieveJob, SIGNAL( gotScript( KMail::SieveJob *, bool, const QString &, bool ) ),
        SLOT( slotGetScript( KMail::SieveJob *, bool, const QString &, bool ) ) );
}

void SieveDebugDialog::slotGetScript( SieveJob * /* job */, bool success,
    const QString &script, bool active )
{
    kDebug( 5006 ) << "SieveDebugDialog::slotGetScript( ??, " << success
              << ", ?, " << active << " )" << endl
              << "script:" << endl
              << script << endl;
    mSieveJob = 0; // job deletes itself after returning from this slot!

    if ( script.isEmpty() )
    {
        mEdit->append( i18n( "(This script is empty.)\n\n" ) );
    }
    else
    {
        mEdit->append( i18n(
            "------------------------------------------------------------\n"
            "%1\n"
            "------------------------------------------------------------\n\n", script ) );
    }

    // Fetch next script
    QTimer::singleShot( 0, this, SLOT( slotDiagNextScript() ) );
}

void SieveDebugDialog::slotGetScriptList( SieveJob *job, bool success,
    const QStringList &scriptList, const QString &activeScript )
{
    kDebug( 5006 ) << k_funcinfo << "Success: " << success << ", List: " << scriptList.join( ", " ) <<
        ", active: " << activeScript << endl;
    mSieveJob = 0; // job deletes itself after returning from this slot!

    mEdit->append( i18n( "Sieve capabilities:\n" ) );
    QStringList caps = job->sieveCapabilities();
    if ( caps.isEmpty() )
    {
        mEdit->append( i18n( "(No special capabilities available)" ) );
    }
    else
    {
        for ( QStringList::const_iterator it = caps.begin(); it != caps.end(); ++it )
            mEdit->append( "* " + *it + '\n' );
        mEdit->append( "\n" );
    }

    mEdit->append( i18n( "Available Sieve scripts:\n" ) );

    if ( scriptList.isEmpty() )
    {
        mEdit->append( i18n( "(No Sieve scripts available on this server)\n\n" ) );
    }
    else
    {
        mScriptList = scriptList;
        for ( QStringList::const_iterator it = scriptList.begin(); it != scriptList.end(); ++it )
            mEdit->append( "* " + *it + '\n' );
        mEdit->append( "\n" );
        mEdit->append( i18n( "Active script: %1\n\n", activeScript ) );
    }

    // Handle next job: dump scripts for this server
    QTimer::singleShot( 0, this, SLOT( slotDiagNextScript() ) );
}

void SieveDebugDialog::slotDialogOk()
{
    kDebug(5006) << "SieveDebugDialog::slotDialogOk()" << endl;
}

void SieveDebugDialog::slotPutActiveResult( SieveJob * job, bool success )
{
    handlePutResult( job, success, true );
}

void SieveDebugDialog::slotPutInactiveResult( SieveJob * job, bool success )
{
    handlePutResult( job, success, false );
}

void SieveDebugDialog::handlePutResult( SieveJob *, bool success, bool activated )
{
    if ( success )
    {
        KMessageBox::information( 0, activated ? i18n(
            "Sieve script installed successfully on the server.\n"
            "Out of Office reply is now active." )
            : i18n( "Sieve script installed successfully on the server.\n"
            "Out of Office reply has been deactivated." ) );
    }

    kDebug( 5006 ) << "SieveDebugDialog::handlePutResult( ???, " << success << ", ? )" << endl;
    mSieveJob = 0; // job deletes itself after returning from this slot!
}

} // namespace KMail

#include "sievedebugdialog.moc"

#endif // NDEBUG

<commit_msg>Make it readonly<commit_after>/*
    sievedebugdialog.cpp

    KMail, the KDE mail client.
    Copyright (c) 2005 Martijn Klingens <klingens@kde.org>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License,
    version 2.0, as published by the Free Software Foundation.
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software Foundation,
    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US
*/

// This file is only compiled when debug is enabled, it is
// not useful enough for non-developers to have this in releases.
#if !defined(NDEBUG)

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "sievedebugdialog.h"

#include <cassert>
#include <limits.h>

#include <QDateTime>

#include <kdebug.h>
#include <klocale.h>
#include <kmessagebox.h>

#include <kmime/kmime_header_parsing.h>
#include <ksieve/error.h>
#include <ksieve/parser.h>
#include <ksieve/scriptbuilder.h>
#include <libkpimidentities/identity.h>
#include <libkpimidentities/identitymanager.h>

#include "kmacctimap.h"
#include "accountmanager.h"
using KMail::AccountManager;
#include "kmkernel.h"
#include "sievejob.h"
#include <QTextEdit>

using KMail::SieveJob;
using KMime::Types::AddrSpecList;

namespace
{

class SieveDebugDataExtractor : public KSieve::ScriptBuilder
{
    enum Context
    {
        None = 0,

        // command itself:
        SieveDebugCommand,

        // tagged args:
        Days, Addresses
    };

public:
    SieveDebugDataExtractor()
    :   KSieve::ScriptBuilder()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    virtual ~SieveDebugDataExtractor()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

private:
    void commandStart( const QString & identifier )
    {
        kDebug( 5006 ) << k_funcinfo << "Identifier: '" << identifier << "'" << endl;
        reset();
    }

    void commandEnd()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void testStart( const QString & )
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void testEnd()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void testListStart()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void testListEnd()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void blockStart()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void blockEnd()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void hashComment( const QString & )
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void bracketComment( const QString & )
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void lineFeed()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void error( const KSieve::Error & e )
    {
        kDebug( 5006 ) << "### " << k_funcinfo << "Error: " <<
            e.asString() << " @ " << e.line() << "," << e.column() << endl;
    }

    void finished()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void taggedArgument( const QString & tag )
    {
        kDebug( 5006 ) << k_funcinfo << "Tag: '" << tag << "'" << endl;
    }

    void stringArgument( const QString & string, bool, const QString & )
    {
        kDebug( 5006 ) << k_funcinfo << "String: '" << string << "'" << endl;
    }

    void numberArgument( unsigned long number, char )
    {
        kDebug( 5006 ) << k_funcinfo << "Number: " << number << endl;
    }

    void stringListArgumentStart()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

    void stringListEntry( const QString & string, bool, const QString & )
    {
        kDebug( 5006 ) << k_funcinfo << "String: '" << string << "'" << endl;
    }

    void stringListArgumentEnd()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }

private:
    void reset()
    {
        kDebug( 5006 ) << k_funcinfo << endl;
    }
};

} // Anon namespace

namespace KMail
{

SieveDebugDialog::SieveDebugDialog( QWidget *parent )
:   KDialog( parent ),
    mSieveJob( 0 )
{
    setCaption( i18n( "Sieve Diagnostics" ) );
    setButtons( Ok );
    // Collect all accounts
    AccountManager *am = kmkernel->acctMgr();
    assert( am );
    for ( KMAccount *a = am->first(); a; a = am->next() )
        mAccountList.append( a );

    mEdit = new QTextEdit( this );
    mEdit->setReadOnly( true );
    setMainWidget( mEdit );

    mEdit->setText( i18n( "Collecting diagnostic information about Sieve support...\n\n" ) );

    setInitialSize( QSize( 640, 480 ) );

    if ( !mAccountList.isEmpty() )
        QTimer::singleShot( 0, this, SLOT( slotDiagNextAccount() ) );
}

SieveDebugDialog::~SieveDebugDialog()
{
    if ( mSieveJob )
    {
        mSieveJob->kill();
        mSieveJob = 0;
    }
    kDebug( 5006 ) << k_funcinfo << endl;
}

void SieveDebugDialog::slotDiagNextAccount()
{
    if ( mAccountList.isEmpty() )
        return;

    KMAccount *acc = mAccountList.first();
    mAccountList.pop_front();

    mEdit->append( i18n( "Collecting data for account '%1'...\n", acc->name() ) );
    mEdit->append( i18n( "------------------------------------------------------------\n" ) );
    mAccountBase = dynamic_cast<KMail::ImapAccountBase *>( acc );
    if ( mAccountBase )
    {
        // Detect URL for this IMAP account
        SieveConfig sieve = mAccountBase->sieveConfig();
        if ( !sieve.managesieveSupported() )
        {
            mEdit->append( i18n( "(Account does not support Sieve)\n\n" ) );
        } else {
            if ( sieve.reuseConfig() )
            {
                // assemble Sieve url from the settings of the account:
                mUrl.setProtocol( "sieve" );
                mUrl.setHost( mAccountBase->host() );
                mUrl.setUser( mAccountBase->login() );
                mUrl.setPass( mAccountBase->passwd() );
                mUrl.setPort( sieve.port() );

                // Translate IMAP LOGIN to PLAIN:
                mUrl.setQuery( "x-mech=" + ( mAccountBase->auth() == "*" ? "PLAIN" : mAccountBase->auth() ) );
            } else {
                sieve.alternateURL();
                mUrl.setFileName( sieve.vacationFileName() );
            }

            mSieveJob = SieveJob::list( mUrl );

            connect( mSieveJob, SIGNAL( gotList( KMail::SieveJob *, bool, const QStringList &, const QString & ) ),
                SLOT( slotGetScriptList( KMail::SieveJob *, bool, const QStringList &, const QString & ) ) );

            // Bypass the singleShot timer -- it's fired when we get our data
            return;
        }
    } else {
        mEdit->append( i18n( "(Account is not an IMAP account)\n\n" ) );
    }

    // Handle next account async
    QTimer::singleShot( 0, this, SLOT( slotDiagNextAccount() ) );
}

void SieveDebugDialog::slotDiagNextScript()
{
    if ( mScriptList.isEmpty() )
    {
        // Continue handling accounts instead
        mScriptList.clear();
        QTimer::singleShot( 0, this, SLOT( slotDiagNextAccount() ) );
        return;
    }

    QString scriptFile = mScriptList.first();
    mScriptList.pop_front();

    mEdit->append( i18n( "Contents of script '%1':\n", scriptFile ) );
    SieveConfig sieve = mAccountBase->sieveConfig();
    if ( sieve.reuseConfig() )
    {
        // assemble Sieve url from the settings of the account:
        mUrl.setProtocol( "sieve" );
        mUrl.setHost( mAccountBase->host() );
        mUrl.setUser( mAccountBase->login() );
        mUrl.setPass( mAccountBase->passwd() );
        mUrl.setPort( sieve.port() );
        // Translate IMAP LOGIN to PLAIN
        mUrl.setQuery( "x-mech=" + ( mAccountBase->auth() == "*" ? "PLAIN" : mAccountBase->auth() ) );
        mUrl.setFileName( scriptFile );
    } else {
        sieve.alternateURL();
        mUrl.setFileName( scriptFile );
    }

    mSieveJob = SieveJob::get( mUrl );

    connect( mSieveJob, SIGNAL( gotScript( KMail::SieveJob *, bool, const QString &, bool ) ),
        SLOT( slotGetScript( KMail::SieveJob *, bool, const QString &, bool ) ) );
}

void SieveDebugDialog::slotGetScript( SieveJob * /* job */, bool success,
    const QString &script, bool active )
{
    kDebug( 5006 ) << "SieveDebugDialog::slotGetScript( ??, " << success
              << ", ?, " << active << " )" << endl
              << "script:" << endl
              << script << endl;
    mSieveJob = 0; // job deletes itself after returning from this slot!

    if ( script.isEmpty() )
    {
        mEdit->append( i18n( "(This script is empty.)\n\n" ) );
    }
    else
    {
        mEdit->append( i18n(
            "------------------------------------------------------------\n"
            "%1\n"
            "------------------------------------------------------------\n\n", script ) );
    }

    // Fetch next script
    QTimer::singleShot( 0, this, SLOT( slotDiagNextScript() ) );
}

void SieveDebugDialog::slotGetScriptList( SieveJob *job, bool success,
    const QStringList &scriptList, const QString &activeScript )
{
    kDebug( 5006 ) << k_funcinfo << "Success: " << success << ", List: " << scriptList.join( ", " ) <<
        ", active: " << activeScript << endl;
    mSieveJob = 0; // job deletes itself after returning from this slot!

    mEdit->append( i18n( "Sieve capabilities:\n" ) );
    QStringList caps = job->sieveCapabilities();
    if ( caps.isEmpty() )
    {
        mEdit->append( i18n( "(No special capabilities available)" ) );
    }
    else
    {
        for ( QStringList::const_iterator it = caps.begin(); it != caps.end(); ++it )
            mEdit->append( "* " + *it + '\n' );
        mEdit->append( "\n" );
    }

    mEdit->append( i18n( "Available Sieve scripts:\n" ) );

    if ( scriptList.isEmpty() )
    {
        mEdit->append( i18n( "(No Sieve scripts available on this server)\n\n" ) );
    }
    else
    {
        mScriptList = scriptList;
        for ( QStringList::const_iterator it = scriptList.begin(); it != scriptList.end(); ++it )
            mEdit->append( "* " + *it + '\n' );
        mEdit->append( "\n" );
        mEdit->append( i18n( "Active script: %1\n\n", activeScript ) );
    }

    // Handle next job: dump scripts for this server
    QTimer::singleShot( 0, this, SLOT( slotDiagNextScript() ) );
}

void SieveDebugDialog::slotDialogOk()
{
    kDebug(5006) << "SieveDebugDialog::slotDialogOk()" << endl;
}

void SieveDebugDialog::slotPutActiveResult( SieveJob * job, bool success )
{
    handlePutResult( job, success, true );
}

void SieveDebugDialog::slotPutInactiveResult( SieveJob * job, bool success )
{
    handlePutResult( job, success, false );
}

void SieveDebugDialog::handlePutResult( SieveJob *, bool success, bool activated )
{
    if ( success )
    {
        KMessageBox::information( 0, activated ? i18n(
            "Sieve script installed successfully on the server.\n"
            "Out of Office reply is now active." )
            : i18n( "Sieve script installed successfully on the server.\n"
            "Out of Office reply has been deactivated." ) );
    }

    kDebug( 5006 ) << "SieveDebugDialog::handlePutResult( ???, " << success << ", ? )" << endl;
    mSieveJob = 0; // job deletes itself after returning from this slot!
}

} // namespace KMail

#include "sievedebugdialog.moc"

#endif // NDEBUG

<|endoftext|>