<commit_before>/* -*- mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
// vim:sts=4:sw=4:ts=4:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s

/*
 * Copyright (C) FFLAS-FFPACK
 * Written by Clément Pernet
 * This file is Free Software and part of FFLAS-FFPACK.
 *
 * ========LICENCE========
 * This file is part of the library FFLAS-FFPACK.
 *
 * FFLAS-FFPACK is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 *.
 */

//--------------------------------------------------------------------------
//          Test for the computations of rank profiles
//--------------------------------------------------------------------------

#include "fflas-ffpack/fflas-ffpack-config.h"
#include "fflas-ffpack/ffpack/ffpack.h"
#include "fflas-ffpack/utils/args-parser.h"

#include <iostream>
#include <iomanip>
#include <givaro/modular.h>

#include "test-utils.h"
#include "Matio.h"

using namespace FFPACK;

template<class Field>
bool run_with_field(Givaro::Integer q, unsigned long b, size_t m, size_t n, size_t r, size_t iters){
	bool ok = true ;
	int nbit=(int)iters;

	while (ok &&  nbit){
		// choose Field
		Field* F= chooseField<Field>(q,b);
		if (F==nullptr)
			return true;
		std::ostringstream oss;
		F->write(oss);

		std::cout.fill('.');
		std::cout<<"Checking ";
		std::cout.width(40);
		std::cout<<oss.str();
		std::cout<<" ... ";

		size_t lda = n;
		typename Field::Element_ptr A=FFLAS::fflas_new (*F, m,lda);
		typename Field::Element_ptr B=FFLAS::fflas_new (*F, m,lda);
		RandomMatrixWithRankandRandomRPM(*F,A,lda,r,m,n);
		FFLAS::fassign (*F, m, n, A, lda, B, lda);

		{
				// Testing if LUdivine and PLUQ return the same result
			size_t* RP1, * RP2;
			FFPACK::RowRankProfile (*F, m, n, A, lda, RP1, FFPACK::FfpackSlabRecursive);
			FFLAS::fassign (*F, m, n, B, lda, A, lda);
			FFPACK::RowRankProfile (*F, m, n, A, lda, RP2, FFPACK::FfpackTileRecursive);
			for (size_t i=0; i<r; i++)
				ok &= (RP1[i] == RP2[i]);
			FFLAS::fflas_delete(RP1);
			FFLAS::fflas_delete(RP2);

			FFLAS::fassign (*F, m, n, B, lda, A, lda);
			FFPACK::ColumnRankProfile (*F, m, n, A, lda, RP1, FFPACK::FfpackSlabRecursive);
			FFLAS::fassign (*F, m, n, B, lda, A, lda);
			FFPACK::ColumnRankProfile (*F, m, n, A, lda, RP2, FFPACK::FfpackTileRecursive);
			for (size_t i=0; i<r; i++)
				ok &= (RP1[i] == RP2[i]);
			FFLAS::fflas_delete(RP1);
			FFLAS::fflas_delete(RP2);
		}

		{
			// Testing if 1 PLUQ computes the rank profiles of all leading submatrices
			size_t* RP1, * RP2;
			size_t * P = FFLAS::fflas_new<size_t>(m);
			size_t * Q = FFLAS::fflas_new<size_t>(n);
			FFLAS::fassign (*F, m, n, B, lda, A, lda);
			PLUQ(*F, FFLAS::FflasNonUnit, m, n, A, lda, P, Q);

			for (size_t i=0; i<1;i++){
				size_t mm = 1 + (rand() % m);
				size_t nn = 1 + (rand() % n);
				FFLAS::fassign (*F, m, n, B, lda, A, lda);
				size_t rr = FFPACK::ColumnRankProfile (*F, mm, nn, A, lda, RP1, FFPACK::FfpackSlabRecursive);
				FFLAS::fassign (*F, m, n, B, lda, A, lda);
				FFPACK::RowRankProfile (*F, mm, nn, A, lda, RP2, FFPACK::FfpackSlabRecursive);
				size_t* RRP = FFLAS::fflas_new<size_t>(r);
				size_t* CRP = FFLAS::fflas_new<size_t>(r);

				LeadingSubmatrixRankProfiles (m,n,r,mm,nn,P,Q,RRP,CRP);
				for (size_t ii=0; ii<rr; ii++)
					ok &= (RP1[ii] == CRP[ii]) && (RP2[ii] == RRP[ii]);

				FFLAS::fflas_delete(CRP);
				FFLAS::fflas_delete(RRP);
				FFLAS::fflas_delete(RP1);
				FFLAS::fflas_delete(RP2);

			}
			FFLAS::fflas_delete(P);
			FFLAS::fflas_delete(Q);
		}
		{
            // Testing PLUQ and LUDivine return a specified rank profile
			size_t* RRP = FFLAS::fflas_new<size_t>(r);
			size_t* CRP = FFLAS::fflas_new<size_t>(r);
			size_t* RRPLUD, * RRPPLUQ, *CRPLUD, *CRPPLUQ;
			RandomRankProfile (m, r, RRP);
			RandomRankProfile (n, r, CRP);

			// write_perm (std::cout<<"RRP = ", RRP, m);
			// write_perm (std::cout<<"CRP = ", CRP, n);
			RandomMatrixWithRankandRPM(*F,A,lda,r,m,n, RRP, CRP);
			FFLAS::fassign (*F, m, n, A, lda, B, lda);
			FFPACK::ColumnRankProfile (*F, m, n, A, lda, CRPLUD, FFPACK::FfpackSlabRecursive);
			FFLAS::fassign (*F, m, n, B, lda, A, lda);
			FFPACK::ColumnRankProfile (*F, m, n, A, lda, CRPPLUQ, FFPACK::FfpackTileRecursive);
			FFLAS::fassign (*F, m, n, B, lda, A, lda);
			FFPACK::RowRankProfile (*F, m, n, A, lda, RRPLUD, FFPACK::FfpackSlabRecursive);
			FFLAS::fassign (*F, m, n, B, lda, A, lda);
			FFPACK::RowRankProfile (*F, m, n, A, lda, RRPPLUQ, FFPACK::FfpackTileRecursive);
			std::sort(CRP,CRP+r);
			std::sort(RRP,RRP+r);
			for (size_t i=0; i<r; i++)
				ok &= (CRPLUD[i] == CRP[i]) && (CRPPLUQ[i] == CRP[i]) &&
					  (RRPLUD[i] == RRP[i]) && (RRPPLUQ[i] == RRP[i]);
			FFLAS::fflas_delete(CRP);
			FFLAS::fflas_delete(RRP);
			FFLAS::fflas_delete(CRPLUD);
			FFLAS::fflas_delete(RRPLUD);
			FFLAS::fflas_delete(CRPPLUQ);
			FFLAS::fflas_delete(RRPPLUQ);
		}

		FFLAS::fflas_delete(A);
		FFLAS::fflas_delete(B);
		delete F;

		nbit--;
		if (!ok)
				//std::cout << "\033[1;31mFAILED\033[0m "<<std::endl;
			std::cout << "FAILED "<<std::endl;
		else
				//std::cout << "\033[1;32mPASSED\033[0m "<<std::endl;
			std::cout << "PASSED "<<std::endl;
	}
	return ok;
	}

int main(int argc, char** argv){
	std::cerr<<std::setprecision(20);

	Givaro::Integer q = -1;
	size_t b = 0;
	size_t m = 150;
	size_t n = 280;
	size_t r = 85;
	size_t iters = 6 ;
	bool loop=false;
	static Argument as[] = {
		{ 'q', "-q Q", "Set the field cardinality.",         TYPE_INT , &q },
		{ 'b', "-b B", "Set the bitsize of the field characteristic.",  TYPE_INT , &b },
		{ 'n', "-n N", "Set the number of cols in the matrix.", TYPE_INT , &n },
		{ 'm', "-m N", "Set the number of rows in the matrix.", TYPE_INT , &m },
		{ 'r', "-r r", "Set the rank of the matrix."          , TYPE_INT , &r },
		{ 'i', "-i R", "Set number of repetitions.",            TYPE_INT , &iters },
		{ 'l', "-loop Y/N", "run the test in an infinite loop.", TYPE_BOOL , &loop },
		    // { 'f', "-f file", "Set input file", TYPE_STR, &file },
		END_OF_ARGUMENTS
	};

	FFLAS::parseArguments(argc,argv,as);

	if (r > std::min (m,n))
		r = std::min (m, n);

	bool ok=true;
	do{
		ok&=run_with_field<Givaro::Modular<float> >           (q,b,m,n,r,iters);
		ok&=run_with_field<Givaro::Modular<double> >          (q,b,m,n,r,iters);
		ok&=run_with_field<Givaro::ModularBalanced<float> >   (q,b,m,n,r,iters);
		ok&=run_with_field<Givaro::ModularBalanced<double> >   (q,b,m,n,r,iters);
		ok&=run_with_field<Givaro::Modular<int32_t> >   (q,b,m,n,r,iters);
		ok&=run_with_field<Givaro::ModularBalanced<int32_t> >   (q,b,m,n,r,iters);
		ok&=run_with_field<Givaro::Modular<int64_t> >   (q,b,m,n,r,iters);
		ok&=run_with_field<Givaro::ModularBalanced<int64_t> >   (q,b,m,n,r,iters);
	} while (loop && ok);

	return !ok;
}
<commit_msg>improves test-rankprofiles<commit_after>/* -*- mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
// vim:sts=4:sw=4:ts=4:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s

/*
 * Copyright (C) FFLAS-FFPACK
 * Written by Clément Pernet
 * This file is Free Software and part of FFLAS-FFPACK.
 *
 * ========LICENCE========
 * This file is part of the library FFLAS-FFPACK.
 *
 * FFLAS-FFPACK is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 *.
 */

//--------------------------------------------------------------------------
//          Test for the computations of rank profiles
//--------------------------------------------------------------------------

#include "fflas-ffpack/fflas-ffpack-config.h"
#include "fflas-ffpack/ffpack/ffpack.h"
#include "fflas-ffpack/utils/args-parser.h"

#include <iostream>
#include <iomanip>
#include <givaro/modular.h>

#include "test-utils.h"
#include "Matio.h"

using namespace FFPACK;

template<class Field>
bool run_with_field(Givaro::Integer q, unsigned long b, size_t m, size_t n, size_t r, size_t iters){
	bool ok = true ;
	int nbit=(int)iters;

	while (ok &&  nbit){
		// choose Field
		Field* F= chooseField<Field>(q,b);
		if (F==nullptr)
			return true;
		std::ostringstream oss;
		F->write(oss);

		std::cout.fill('.');
		std::cout<<"Checking ";
		std::cout.width(40);
		std::cout<<oss.str();
		std::cout<<" ... ";

		size_t lda = n;
		typename Field::Element_ptr A=FFLAS::fflas_new (*F, m,lda);
		typename Field::Element_ptr B=FFLAS::fflas_new (*F, m,lda);
		RandomMatrixWithRankandRandomRPM(*F,A,lda,r,m,n);
		FFLAS::fassign (*F, m, n, A, lda, B, lda);

		{
				// Testing if LUdivine and PLUQ return the same result
			size_t* RP1, * RP2;
			FFPACK::RowRankProfile (*F, m, n, A, lda, RP1, FFPACK::FfpackSlabRecursive);
			FFLAS::fassign (*F, m, n, B, lda, A, lda);
			FFPACK::RowRankProfile (*F, m, n, A, lda, RP2, FFPACK::FfpackTileRecursive);
			for (size_t i=0; i<r; i++)
				ok &= (RP1[i] == RP2[i]);
			FFLAS::fflas_delete(RP1);
			FFLAS::fflas_delete(RP2);

			FFLAS::fassign (*F, m, n, B, lda, A, lda);
			FFPACK::ColumnRankProfile (*F, m, n, A, lda, RP1, FFPACK::FfpackSlabRecursive);
			FFLAS::fassign (*F, m, n, B, lda, A, lda);
			FFPACK::ColumnRankProfile (*F, m, n, A, lda, RP2, FFPACK::FfpackTileRecursive);
			for (size_t i=0; i<r; i++)
				ok &= (RP1[i] == RP2[i]);
			FFLAS::fflas_delete(RP1);
			FFLAS::fflas_delete(RP2);
		}
		{
			// Testing if 1 PLUQ computes the rank profiles of all leading submatrices
			size_t* RP1, * RP2;
			size_t * P = FFLAS::fflas_new<size_t>(m);
			size_t * Q = FFLAS::fflas_new<size_t>(n);
			FFLAS::fassign (*F, m, n, B, lda, A, lda);
			PLUQ(*F, FFLAS::FflasNonUnit, m, n, A, lda, P, Q);

			for (size_t i=0; i<1;i++){
				size_t mm = 1 + (rand() % m);
				size_t nn = 1 + (rand() % n);
				FFLAS::fassign (*F, m, n, B, lda, A, lda);
				size_t rr = FFPACK::ColumnRankProfile (*F, mm, nn, A, lda, RP1, FFPACK::FfpackSlabRecursive);
				FFLAS::fassign (*F, m, n, B, lda, A, lda);
				FFPACK::RowRankProfile (*F, mm, nn, A, lda, RP2, FFPACK::FfpackSlabRecursive);
				size_t* RRP = FFLAS::fflas_new<size_t>(r);
				size_t* CRP = FFLAS::fflas_new<size_t>(r);

				LeadingSubmatrixRankProfiles (m,n,r,mm,nn,P,Q,RRP,CRP);
				for (size_t ii=0; ii<rr; ii++)
					ok &= (RP1[ii] == CRP[ii]) && (RP2[ii] == RRP[ii]);

				FFLAS::fflas_delete(CRP);
				FFLAS::fflas_delete(RRP);
				FFLAS::fflas_delete(RP1);
				FFLAS::fflas_delete(RP2);

			}
			FFLAS::fflas_delete(P);
			FFLAS::fflas_delete(Q);
		}
		{
            // Testing PLUQ and LUDivine return a specified rank profile
			size_t* RRP = FFLAS::fflas_new<size_t>(r);
			size_t* CRP = FFLAS::fflas_new<size_t>(r);
			size_t* RRPLUD, * RRPPLUQ, *CRPLUD, *CRPPLUQ;
			RandomRankProfile (m, r, RRP);
			RandomRankProfile (n, r, CRP);

			RandomMatrixWithRankandRPM(*F,A,lda,r,m,n, RRP, CRP);
			FFLAS::fassign (*F, m, n, A, lda, B, lda);
			size_t cs = FFPACK::ColumnRankProfile (*F, m, n, A, lda, CRPLUD, FFPACK::FfpackSlabRecursive);
			FFLAS::fassign (*F, m, n, B, lda, A, lda);
			size_t ct = FFPACK::ColumnRankProfile (*F, m, n, A, lda, CRPPLUQ, FFPACK::FfpackTileRecursive);
			FFLAS::fassign (*F, m, n, B, lda, A, lda);
			size_t rs = FFPACK::RowRankProfile (*F, m, n, A, lda, RRPLUD, FFPACK::FfpackSlabRecursive);
			FFLAS::fassign (*F, m, n, B, lda, A, lda);
			size_t rt = FFPACK::RowRankProfile (*F, m, n, A, lda, RRPPLUQ, FFPACK::FfpackTileRecursive);
			// write_perm (std::cout<<"RRP     = ", RRP, r);
			// write_perm (std::cout<<"CRP     = ", CRP, r);
			std::sort(CRP,CRP+r);
			std::sort(RRP,RRP+r);
			ok &= (cs==ct)&(cs==rs)&(cs==rt)&(cs==r);
			for (size_t i=0; i<r; i++)
				ok &= (CRPLUD[i] == CRP[i]) && (CRPPLUQ[i] == CRP[i]) &&
					(RRPLUD[i] == RRP[i]) && (RRPPLUQ[i] == RRP[i]);
			FFLAS::fflas_delete(CRP);
			FFLAS::fflas_delete(RRP);
			FFLAS::fflas_delete(CRPLUD);
			FFLAS::fflas_delete(RRPLUD);
			FFLAS::fflas_delete(CRPPLUQ);
			FFLAS::fflas_delete(RRPPLUQ);
		}

		FFLAS::fflas_delete(A);
		FFLAS::fflas_delete(B);
		delete F;

		nbit--;
		if (!ok)
				//std::cout << "\033[1;31mFAILED\033[0m "<<std::endl;
			std::cout << "FAILED "<<std::endl;
		else
				//std::cout << "\033[1;32mPASSED\033[0m "<<std::endl;
			std::cout << "PASSED "<<std::endl;
	}
	return ok;
	}

int main(int argc, char** argv){
	std::cerr<<std::setprecision(20);

	Givaro::Integer q = -1;
	size_t b = 0;
	size_t m = 150;
	size_t n = 280;
	size_t r = 85;
	size_t iters = 6 ;
	bool loop=false;
	static Argument as[] = {
		{ 'q', "-q Q", "Set the field cardinality.",         TYPE_INTEGER , &q },
		{ 'b', "-b B", "Set the bitsize of the field characteristic.",  TYPE_INT , &b },
		{ 'n', "-n N", "Set the number of cols in the matrix.", TYPE_INT , &n },
		{ 'm', "-m N", "Set the number of rows in the matrix.", TYPE_INT , &m },
		{ 'r', "-r r", "Set the rank of the matrix."          , TYPE_INT , &r },
		{ 'i', "-i R", "Set number of repetitions.",            TYPE_INT , &iters },
		{ 'l', "-loop Y/N", "run the test in an infinite loop.", TYPE_BOOL , &loop },
		    // { 'f', "-f file", "Set input file", TYPE_STR, &file },
		END_OF_ARGUMENTS
	};

	FFLAS::parseArguments(argc,argv,as);

	if (r > std::min (m,n))
		r = std::min (m, n);

	bool ok=true;
	do{
		ok&=run_with_field<Givaro::Modular<float> >           (q,b,m,n,r,iters);
		ok&=run_with_field<Givaro::Modular<double> >          (q,b,m,n,r,iters);
		ok&=run_with_field<Givaro::ModularBalanced<float> >   (q,b,m,n,r,iters);
		ok&=run_with_field<Givaro::ModularBalanced<double> >   (q,b,m,n,r,iters);
		ok&=run_with_field<Givaro::Modular<int32_t> >   (q,b,m,n,r,iters);
		ok&=run_with_field<Givaro::ModularBalanced<int32_t> >   (q,b,m,n,r,iters);
		ok&=run_with_field<Givaro::Modular<int64_t> >   (q,b,m,n,r,iters);
		ok&=run_with_field<Givaro::ModularBalanced<int64_t> >   (q,b,m,n,r,iters);
	} while (loop && ok);

	return !ok;
}
<|endoftext|>


<commit_before>//===- LoopInstSimplify.cpp - Loop Instruction Simplification Pass --------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass performs lightweight instruction simplification on loop bodies.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "loop-instsimplify"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Support/Debug.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/ADT/Statistic.h"
using namespace llvm;

STATISTIC(NumSimplified, "Number of redundant instructions simplified");

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

    bool runOnLoop(Loop*, LPPassManager&);

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.setPreservesCFG();
      AU.addRequired<LoopInfo>();
      AU.addRequiredID(LoopSimplifyID);
      AU.addPreservedID(LCSSAID);
    }
  };
}

char LoopInstSimplify::ID = 0;
INITIALIZE_PASS_BEGIN(LoopInstSimplify, "loop-instsimplify",
                "Simplify instructions in loops", false, false)
INITIALIZE_PASS_DEPENDENCY(DominatorTree)
INITIALIZE_PASS_DEPENDENCY(LoopInfo)
INITIALIZE_PASS_DEPENDENCY(LCSSA)
INITIALIZE_PASS_END(LoopInstSimplify, "loop-instsimplify",
                "Simplify instructions in loops", false, false)

Pass* llvm::createLoopInstSimplifyPass() {
  return new LoopInstSimplify();
}

bool LoopInstSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
  DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>();
  LoopInfo *LI = &getAnalysis<LoopInfo>();
  const TargetData *TD = getAnalysisIfAvailable<TargetData>();

  SmallVector<BasicBlock*, 8> ExitBlocks;
  L->getUniqueExitBlocks(ExitBlocks);
  array_pod_sort(ExitBlocks.begin(), ExitBlocks.end());

  SmallPtrSet<const Instruction*, 8> S1, S2, *ToSimplify = &S1, *Next = &S2;

  SmallVector<BasicBlock*, 16> VisitStack;
  SmallPtrSet<BasicBlock*, 32> Visited;

  bool Changed = false;
  bool LocalChanged;
  do {
    LocalChanged = false;

    VisitStack.clear();
    Visited.clear();

    VisitStack.push_back(L->getHeader());

    while (!VisitStack.empty()) {
      BasicBlock *BB = VisitStack.pop_back_val();

      // Simplify instructions in the current basic block.
      for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
        Instruction *I = BI++;

        // The first time through the loop ToSimplify is empty and we try to
        // simplify all instructions. On later iterations ToSimplify is not
        // empty and we only bother simplifying instructions that are in it.
        if (!ToSimplify->empty() && !ToSimplify->count(I))
          continue;

        // Don't bother simplifying unused instructions.
        if (!I->use_empty()) {
          Value *V = SimplifyInstruction(I, TD, DT);
          if (V && LI->replacementPreservesLCSSAForm(I, V)) {
            // Mark all uses for resimplification next time round the loop.
            for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
                 UI != UE; ++UI)
              Next->insert(cast<Instruction>(*UI));

            I->replaceAllUsesWith(V);
            LocalChanged = true;
            ++NumSimplified;
          }
        }
        LocalChanged |= RecursivelyDeleteTriviallyDeadInstructions(I);
      }

      // Add all successors to the worklist, except for loop exit blocks.
      for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE;
           ++SI) {
        BasicBlock *SuccBB = *SI;
        bool IsExitBlock = std::binary_search(ExitBlocks.begin(),
                                             ExitBlocks.end(), SuccBB);
        if (!IsExitBlock && Visited.insert(SuccBB))
          VisitStack.push_back(SuccBB);
      }
    }

    // Place the list of instructions to simplify on the next loop iteration
    // into ToSimplify.
    std::swap(ToSimplify, Next);
    Next->clear();

    Changed |= LocalChanged;
  } while (LocalChanged);

  return Changed;
}
<commit_msg>Contract subloop bodies. However, it is still important to visit the phis at the top of subloop headers, as the phi uses logically occur outside of the subloop.<commit_after>//===- LoopInstSimplify.cpp - Loop Instruction Simplification Pass --------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass performs lightweight instruction simplification on loop bodies.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "loop-instsimplify"
#include "llvm/Instructions.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Support/Debug.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/ADT/Statistic.h"
using namespace llvm;

STATISTIC(NumSimplified, "Number of redundant instructions simplified");

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

    bool runOnLoop(Loop*, LPPassManager&);

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.setPreservesCFG();
      AU.addRequired<LoopInfo>();
      AU.addRequiredID(LoopSimplifyID);
      AU.addPreservedID(LCSSAID);
    }
  };
}

char LoopInstSimplify::ID = 0;
INITIALIZE_PASS_BEGIN(LoopInstSimplify, "loop-instsimplify",
                "Simplify instructions in loops", false, false)
INITIALIZE_PASS_DEPENDENCY(DominatorTree)
INITIALIZE_PASS_DEPENDENCY(LoopInfo)
INITIALIZE_PASS_DEPENDENCY(LCSSA)
INITIALIZE_PASS_END(LoopInstSimplify, "loop-instsimplify",
                "Simplify instructions in loops", false, false)

Pass* llvm::createLoopInstSimplifyPass() {
  return new LoopInstSimplify();
}

bool LoopInstSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
  DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>();
  LoopInfo *LI = &getAnalysis<LoopInfo>();
  const TargetData *TD = getAnalysisIfAvailable<TargetData>();

  SmallVector<BasicBlock*, 8> ExitBlocks;
  L->getUniqueExitBlocks(ExitBlocks);
  array_pod_sort(ExitBlocks.begin(), ExitBlocks.end());

  SmallPtrSet<const Instruction*, 8> S1, S2, *ToSimplify = &S1, *Next = &S2;

  // The bit we are stealing from the pointer represents whether this basic
  // block is the header of a subloop, in which case we only process its phis.
  typedef PointerIntPair<BasicBlock*, 1> WorklistItem;
  SmallVector<WorklistItem, 16> VisitStack;
  SmallPtrSet<BasicBlock*, 32> Visited;

  bool Changed = false;
  bool LocalChanged;
  do {
    LocalChanged = false;

    VisitStack.clear();
    Visited.clear();

    VisitStack.push_back(WorklistItem(L->getHeader(), false));

    while (!VisitStack.empty()) {
      WorklistItem Item = VisitStack.pop_back_val();
      BasicBlock* BB = Item.getPointer();
      bool IsSubloopHeader = Item.getInt();

      // Simplify instructions in the current basic block.
      for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
        Instruction *I = BI++;

        // The first time through the loop ToSimplify is empty and we try to
        // simplify all instructions. On later iterations ToSimplify is not
        // empty and we only bother simplifying instructions that are in it.
        if (!ToSimplify->empty() && !ToSimplify->count(I))
          continue;

        // Don't bother simplifying unused instructions.
        if (!I->use_empty()) {
          Value *V = SimplifyInstruction(I, TD, DT);
          if (V && LI->replacementPreservesLCSSAForm(I, V)) {
            // Mark all uses for resimplification next time round the loop.
            for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
                 UI != UE; ++UI)
              Next->insert(cast<Instruction>(*UI));

            I->replaceAllUsesWith(V);
            LocalChanged = true;
            ++NumSimplified;
          }
        }
        LocalChanged |= RecursivelyDeleteTriviallyDeadInstructions(I);

        if (IsSubloopHeader && !isa<PHINode>(I))
          break;
      }

      // Add all successors to the worklist, except for loop exit blocks and the
      // bodies of subloops. We visit the headers of loops so that we can process
      // their phis, but we contract the rest of the subloop body and only follow
      // edges leading back to the original loop.
      for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE;
           ++SI) {
        BasicBlock *SuccBB = *SI;
        if (!Visited.insert(SuccBB))
          continue;

        const Loop *SuccLoop = LI->getLoopFor(SuccBB);
        if (SuccLoop && SuccLoop->getHeader() == SuccBB
                     && L->contains(SuccLoop)) {
          VisitStack.push_back(WorklistItem(SuccBB, true));

          SmallVector<BasicBlock*, 8> SubLoopExitBlocks;
          SuccLoop->getExitBlocks(SubLoopExitBlocks);

          for (unsigned i = 0; i < SubLoopExitBlocks.size(); ++i) {
            BasicBlock *ExitBB = SubLoopExitBlocks[i];
            if (LI->getLoopFor(ExitBB) == L && Visited.insert(ExitBB))
              VisitStack.push_back(WorklistItem(ExitBB, false));
          }

          continue;
        }

        bool IsExitBlock = std::binary_search(ExitBlocks.begin(),
                                              ExitBlocks.end(), SuccBB);
        if (IsExitBlock)
          continue;

        VisitStack.push_back(WorklistItem(SuccBB, false));
      }
    }

    // Place the list of instructions to simplify on the next loop iteration
    // into ToSimplify.
    std::swap(ToSimplify, Next);
    Next->clear();

    Changed |= LocalChanged;
  } while (LocalChanged);

  return Changed;
}
<|endoftext|>


<commit_before>/// \file ROOT/TDrawingOptsBase.hxx
/// \ingroup Gpad ROOT7
/// \author Axel Naumann <axel@cern.ch>
/// \date 2017-09-26
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!

/*************************************************************************
 * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT7_TDrawingOptsBase
#define ROOT7_TDrawingOptsBase

#include <ROOT/TColor.hxx>
#include <ROOT/TDrawingAttrs.hxx>

#include <RStringView.h>

#include <map>
#include <string>
#include <vector>

namespace ROOT {
namespace Experimental {
class TCanvas;
class TPadBase;
class TDrawingOptsBaseNoDefault;

/** \class ROOT::Experimental::TDrawingOptsBase
  Base class for drawing options. Implements access to the default and the default's initialization
  from a config file.

  Drawing options are made up of three kinds of primitives:
    - TColor
    - integer (long long)
    - floating point (double)
  They register the primitives with their `TCanvas`, and then refer to the registered primitives.
  Upon destruction, the `TDrawingOptsBase` deregisters the use of its primitives with the `TCanvas`,
  which empties the respective slots in the tables of the `TCanvas`, unless other options reference
  the same primitives (through `SameAs()`), and until the last use has deregistered.

  In derived classes (e.g. drawing options for the class `MyFancyBox`), declare attribute members as
     TOptsAttrRef<TColor> fLineColor{*this, "MyFancyBox.LineColor"};
  The attribute's value will be taken from the  will be initialized
  */

class TDrawingOptsBaseNoDefault {
public:
   template <class PRIMITIVE>
   class OptsAttrRefArr {
      /// Indexes of the `TCanvas`'s attribute table entries used by the options object.
      std::vector<TOptsAttrRef<PRIMITIVE>> fRefArray;

   public:
      ~OptsAttrRefArr();
      /// Register an attribute.
      ///\returns the index of the new attribute.
      TOptsAttrRef<PRIMITIVE> Register(TCanvas &canv, const PRIMITIVE &val);

      /// Re-use an existing attribute.
      ///\returns the index of the attribute (i.e. valRef).
      TOptsAttrRef<PRIMITIVE> SameAs(TCanvas &canv, TOptsAttrRef<PRIMITIVE> idx);

      /// Re-use an existing attribute.
      ///\returns the index of the attribute, might be `IsInvalid()` if `val` could not be found.
      TOptsAttrRef<PRIMITIVE> SameAs(TCanvas &canv, const PRIMITIVE &val);

      /// Update the attribute at index `idx` to the value `val`.
      void Update(TCanvas &canv, TOptsAttrRef<PRIMITIVE> idx, const PRIMITIVE &val);

      /// Clear all attribute references, removing their uses in `TCanvas`.
      void Release(TCanvas &canv);

      /// Once copied, elements of a OptsAttrRefArr need to increase their use count.
      void RegisterCopy(TCanvas &canv);

      /// Access to attribute (const version).
      const PRIMITIVE &Get(TCanvas &canv, TOptsAttrRef<PRIMITIVE> idx) const;

      /// Access to attribute (non-const version).
      PRIMITIVE &Get(TCanvas &canv, TOptsAttrRef<PRIMITIVE> idx);
   };

private:
   /// The `TCanvas` holding the `TDrawable` (or its `TPad`).
   TCanvas *fCanvas = nullptr;

   /// String vector specifying the prefixes used to select the right setting from the style file,
   /// e.g. `{"1D", "Hist", "Line"}`.
   /// \note Requires external string storage; usually, this parameter is passed as
   /// ```
   ///     TXYZDrawingOpts fOpts{*this, "Hist.Foo", {12, red}};
   /// ```
   std::vector<std::string_view> fConfigPrefix;

   /// Indexes of the `TCanvas`'s color table entries used by this options object.
   OptsAttrRefArr<TColor> fColorIdx;

   /// Indexes of the `TCanvas`'s integer table entries used by this options object.
   OptsAttrRefArr<long long> fIntIdx;

   /// Indexes of the `TCanvas`'s floating point table entries used by this options object.
   OptsAttrRefArr<double> fFPIdx;

   /// Access to the attribute tables (non-const version).
   OptsAttrRefArr<TColor> &GetAttrsRefArr(TColor *) { return fColorIdx; }
   OptsAttrRefArr<long long> &GetAttrsRefArr(long long *) { return fIntIdx; }
   OptsAttrRefArr<double> &GetAttrsRefArr(double *) { return fFPIdx; }

   /// Access to the attribute tables (const version).
   const OptsAttrRefArr<TColor> &GetAttrsRefArr(TColor *) const { return fColorIdx; }
   const OptsAttrRefArr<long long> &GetAttrsRefArr(long long *) const { return fIntIdx; }
   const OptsAttrRefArr<double> &GetAttrsRefArr(double *) const { return fFPIdx; }

protected:
   /// Construct from the pad that holds our `TDrawable`.
   TDrawingOptsBaseNoDefault(TPadBase &pad, const std::vector<string_view> &configPrefix);

   /// Default attributes need to register their values in a pad - they will take this pad!
   static TPadBase &GetDefaultCanvas();

   /// The `TCanvas` holding the `TDrawable` (or its `TPad`) (non-const version).
   TCanvas &GetCanvas() { return *fCanvas; }

   /// The `TCanvas` holding the `TDrawable` (or its `TPad`) (const version).
   const TCanvas &GetCanvas() const { return *fCanvas; }

   template <class PRIMITIVE>
   TOptsAttrRef<PRIMITIVE> Register(const PRIMITIVE &val)
   {
      return GetAttrsRefArr((PRIMITIVE *)nullptr).Register(GetCanvas(), val);
   }

   template <class PRIMITIVE>
   void Update(TOptsAttrRef<PRIMITIVE> idx, const PRIMITIVE &val)
   {
      GetAttrsRefArr((PRIMITIVE *)nullptr).Update(GetCanvas(), idx, val);
   }

   template <class PRIMITIVE>
   TOptsAttrRef<PRIMITIVE> SameAs(TOptsAttrRef<PRIMITIVE> idx)
   {
      return GetAttrsRefArr((PRIMITIVE *)nullptr).SameAs(GetCanvas(), idx);
   }

   template <class PRIMITIVE>
   TOptsAttrRef<PRIMITIVE> SameAs(const PRIMITIVE &val)
   {
      return GetAttrsRefArr((PRIMITIVE *)nullptr).SameAs(GetCanvas(), val);
   }

   template <class PRIMITIVE>
   friend class TOptsAttrRef;

public:
   TDrawingOptsBaseNoDefault() = default;
   ~TDrawingOptsBaseNoDefault();
   TDrawingOptsBaseNoDefault(const TDrawingOptsBaseNoDefault &other);
   TDrawingOptsBaseNoDefault(TDrawingOptsBaseNoDefault &&other) = default;

   std::string GetConfigPrefix() const {
      std::string ret;
      for (auto el: fConfigPrefix) {
         ret += el;
         ret += '.';
      }
      ret.erase(ret.end() - 1);
   }

   /// Access to the attribute (non-const version).
   template <class PRIMITIVE>
   PRIMITIVE &Get(TOptsAttrRef<PRIMITIVE> ref) { return GetAttrsRefArr((PRIMITIVE*)nullptr).Get(GetCanvas(), ref); }
   /// Access to the attribute (const version).
   template <class PRIMITIVE>
   const PRIMITIVE &Get(TOptsAttrRef<PRIMITIVE> ref) const { return GetAttrsRefArr((PRIMITIVE*)nullptr).Get(GetCanvas(), ref); }
};

extern template class TDrawingOptsBaseNoDefault::OptsAttrRefArr<TColor>;
extern template class TDrawingOptsBaseNoDefault::OptsAttrRefArr<long long>;
extern template class TDrawingOptsBaseNoDefault::OptsAttrRefArr<double>;

template <class DERIVED>
class TDrawingOptsBase: public TDrawingOptsBaseNoDefault {
public:
   TDrawingOptsBase() = default;
   /// Construct from the pad that holds our `TDrawable`.
   TDrawingOptsBase(TPadBase &pad, const std::vector<string_view> &configPrefix):
   TDrawingOptsBaseNoDefault(pad, []&configPrefix(){configPrefix.push_back("Line"); return configPrefix;})
   {
      if (&pad != &GetDefaultCanvas())
         Default(configPrefix);
   }

   /// Retrieve the default drawing options for `DERIVED`. Can be used to query and adjust the
   /// default options.
   static DERIVED &Default(string_view configPrefix = {})
   {
      static DERIVED defaultOpts(GetDefaultCanvas(), configPrefix);
      return defaultOpts;
   }
};

} // namespace Experimental
} // namespace ROOT

#endif
<commit_msg>Remove unused fwd decl.<commit_after>/// \file ROOT/TDrawingOptsBase.hxx
/// \ingroup Gpad ROOT7
/// \author Axel Naumann <axel@cern.ch>
/// \date 2017-09-26
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!

/*************************************************************************
 * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT7_TDrawingOptsBase
#define ROOT7_TDrawingOptsBase

#include <ROOT/TColor.hxx>
#include <ROOT/TDrawingAttrs.hxx>

#include <RStringView.h>

#include <map>
#include <string>
#include <vector>

namespace ROOT {
namespace Experimental {
class TCanvas;
class TPadBase;

/** \class ROOT::Experimental::TDrawingOptsBase
  Base class for drawing options. Implements access to the default and the default's initialization
  from a config file.

  Drawing options are made up of three kinds of primitives:
    - TColor
    - integer (long long)
    - floating point (double)
  They register the primitives with their `TCanvas`, and then refer to the registered primitives.
  Upon destruction, the `TDrawingOptsBase` deregisters the use of its primitives with the `TCanvas`,
  which empties the respective slots in the tables of the `TCanvas`, unless other options reference
  the same primitives (through `SameAs()`), and until the last use has deregistered.

  In derived classes (e.g. drawing options for the class `MyFancyBox`), declare attribute members as
     TOptsAttrRef<TColor> fLineColor{*this, "MyFancyBox.LineColor"};
  The attribute's value will be taken from the  will be initialized
  */

class TDrawingOptsBaseNoDefault {
public:
   template <class PRIMITIVE>
   class OptsAttrRefArr {
      /// Indexes of the `TCanvas`'s attribute table entries used by the options object.
      std::vector<TOptsAttrRef<PRIMITIVE>> fRefArray;

   public:
      ~OptsAttrRefArr();
      /// Register an attribute.
      ///\returns the index of the new attribute.
      TOptsAttrRef<PRIMITIVE> Register(TCanvas &canv, const PRIMITIVE &val);

      /// Re-use an existing attribute.
      ///\returns the index of the attribute (i.e. valRef).
      TOptsAttrRef<PRIMITIVE> SameAs(TCanvas &canv, TOptsAttrRef<PRIMITIVE> idx);

      /// Re-use an existing attribute.
      ///\returns the index of the attribute, might be `IsInvalid()` if `val` could not be found.
      TOptsAttrRef<PRIMITIVE> SameAs(TCanvas &canv, const PRIMITIVE &val);

      /// Update the attribute at index `idx` to the value `val`.
      void Update(TCanvas &canv, TOptsAttrRef<PRIMITIVE> idx, const PRIMITIVE &val);

      /// Clear all attribute references, removing their uses in `TCanvas`.
      void Release(TCanvas &canv);

      /// Once copied, elements of a OptsAttrRefArr need to increase their use count.
      void RegisterCopy(TCanvas &canv);

      /// Access to attribute (const version).
      const PRIMITIVE &Get(TCanvas &canv, TOptsAttrRef<PRIMITIVE> idx) const;

      /// Access to attribute (non-const version).
      PRIMITIVE &Get(TCanvas &canv, TOptsAttrRef<PRIMITIVE> idx);
   };

private:
   /// The `TCanvas` holding the `TDrawable` (or its `TPad`).
   TCanvas *fCanvas = nullptr;

   /// String vector specifying the prefixes used to select the right setting from the style file,
   /// e.g. `{"1D", "Hist", "Line"}`.
   /// \note Requires external string storage; usually, this parameter is passed as
   /// ```
   ///     TXYZDrawingOpts fOpts{*this, "Hist.Foo", {12, red}};
   /// ```
   std::vector<std::string_view> fConfigPrefix;

   /// Indexes of the `TCanvas`'s color table entries used by this options object.
   OptsAttrRefArr<TColor> fColorIdx;

   /// Indexes of the `TCanvas`'s integer table entries used by this options object.
   OptsAttrRefArr<long long> fIntIdx;

   /// Indexes of the `TCanvas`'s floating point table entries used by this options object.
   OptsAttrRefArr<double> fFPIdx;

   /// Access to the attribute tables (non-const version).
   OptsAttrRefArr<TColor> &GetAttrsRefArr(TColor *) { return fColorIdx; }
   OptsAttrRefArr<long long> &GetAttrsRefArr(long long *) { return fIntIdx; }
   OptsAttrRefArr<double> &GetAttrsRefArr(double *) { return fFPIdx; }

   /// Access to the attribute tables (const version).
   const OptsAttrRefArr<TColor> &GetAttrsRefArr(TColor *) const { return fColorIdx; }
   const OptsAttrRefArr<long long> &GetAttrsRefArr(long long *) const { return fIntIdx; }
   const OptsAttrRefArr<double> &GetAttrsRefArr(double *) const { return fFPIdx; }

protected:
   /// Construct from the pad that holds our `TDrawable`.
   TDrawingOptsBaseNoDefault(TPadBase &pad, const std::vector<string_view> &configPrefix);

   /// Default attributes need to register their values in a pad - they will take this pad!
   static TPadBase &GetDefaultCanvas();

   /// The `TCanvas` holding the `TDrawable` (or its `TPad`) (non-const version).
   TCanvas &GetCanvas() { return *fCanvas; }

   /// The `TCanvas` holding the `TDrawable` (or its `TPad`) (const version).
   const TCanvas &GetCanvas() const { return *fCanvas; }

   template <class PRIMITIVE>
   TOptsAttrRef<PRIMITIVE> Register(const PRIMITIVE &val)
   {
      return GetAttrsRefArr((PRIMITIVE *)nullptr).Register(GetCanvas(), val);
   }

   template <class PRIMITIVE>
   void Update(TOptsAttrRef<PRIMITIVE> idx, const PRIMITIVE &val)
   {
      GetAttrsRefArr((PRIMITIVE *)nullptr).Update(GetCanvas(), idx, val);
   }

   template <class PRIMITIVE>
   TOptsAttrRef<PRIMITIVE> SameAs(TOptsAttrRef<PRIMITIVE> idx)
   {
      return GetAttrsRefArr((PRIMITIVE *)nullptr).SameAs(GetCanvas(), idx);
   }

   template <class PRIMITIVE>
   TOptsAttrRef<PRIMITIVE> SameAs(const PRIMITIVE &val)
   {
      return GetAttrsRefArr((PRIMITIVE *)nullptr).SameAs(GetCanvas(), val);
   }

   template <class PRIMITIVE>
   friend class TOptsAttrRef;

public:
   TDrawingOptsBaseNoDefault() = default;
   ~TDrawingOptsBaseNoDefault();
   TDrawingOptsBaseNoDefault(const TDrawingOptsBaseNoDefault &other);
   TDrawingOptsBaseNoDefault(TDrawingOptsBaseNoDefault &&other) = default;

   std::string GetConfigPrefix() const {
      std::string ret;
      for (auto el: fConfigPrefix) {
         ret += el;
         ret += '.';
      }
      ret.erase(ret.end() - 1);
   }

   /// Access to the attribute (non-const version).
   template <class PRIMITIVE>
   PRIMITIVE &Get(TOptsAttrRef<PRIMITIVE> ref) { return GetAttrsRefArr((PRIMITIVE*)nullptr).Get(GetCanvas(), ref); }
   /// Access to the attribute (const version).
   template <class PRIMITIVE>
   const PRIMITIVE &Get(TOptsAttrRef<PRIMITIVE> ref) const { return GetAttrsRefArr((PRIMITIVE*)nullptr).Get(GetCanvas(), ref); }
};

extern template class TDrawingOptsBaseNoDefault::OptsAttrRefArr<TColor>;
extern template class TDrawingOptsBaseNoDefault::OptsAttrRefArr<long long>;
extern template class TDrawingOptsBaseNoDefault::OptsAttrRefArr<double>;

template <class DERIVED>
class TDrawingOptsBase: public TDrawingOptsBaseNoDefault {
public:
   TDrawingOptsBase() = default;
   /// Construct from the pad that holds our `TDrawable`.
   TDrawingOptsBase(TPadBase &pad, const std::vector<string_view> &configPrefix):
   TDrawingOptsBaseNoDefault(pad, []&configPrefix(){configPrefix.push_back("Line"); return configPrefix;})
   {
      if (&pad != &GetDefaultCanvas())
         Default(configPrefix);
   }

   /// Retrieve the default drawing options for `DERIVED`. Can be used to query and adjust the
   /// default options.
   static DERIVED &Default(string_view configPrefix = {})
   {
      static DERIVED defaultOpts(GetDefaultCanvas(), configPrefix);
      return defaultOpts;
   }
};

} // namespace Experimental
} // namespace ROOT

#endif
<|endoftext|>


<commit_before>/*****************************************************************************
 * qvlcframe.hpp : A few helpers
 *****************************************************************************
 * Copyright (C) 2006-2007 the VideoLAN team
 * $Id$
 *
 * Authors: Clément Stenac <zorglub@videolan.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * 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, USA.
 *****************************************************************************/

#ifndef _QVLCFRAME_H_
#define _QVLCFRAME_H_

#include <QWidget>
#include <QDialog>
#include <QSpacerItem>
#include <QHBoxLayout>
#include <QApplication>
#include <QMainWindow>
#include <QPushButton>
#include <QKeyEvent>
#include <QDesktopWidget>
#include <QSettings>

#include "qt4.hpp"

class QVLCTools
{
   public:
       /*
        use this function to save a widgets screen position
        only for windows / dialogs which are floating, if a
        window is docked into an other - don't all this function
        or it may write garbage to position info!
       */
       static void saveWidgetPosition( QSettings *settings, QWidget *widget)
       {
         settings->setValue("geometry", widget->saveGeometry());
       }
       static void saveWidgetPosition( intf_thread_t *p_intf,
                                       QString configName,
                                       QWidget *widget)
       {
         getSettings()->beginGroup( configName );
         QVLCTools::saveWidgetPosition(getSettings(), widget);
         getSettings()->endGroup();
       }

       /*
         use this method only for restoring window state of non docked
         windows!
       */
       static bool restoreWidgetPosition(QSettings *settings,
                                           QWidget *widget,
                                           QSize defSize = QSize( 0, 0 ),
                                           QPoint defPos = QPoint( 0, 0 ))
       {
          if(!widget->restoreGeometry(settings->value("geometry")
                                      .toByteArray()))
          {
            widget->move(defPos);
            widget->resize(defSize);

            if(defPos.x() == 0 && defPos.y()==0)
               centerWidgetOnScreen(widget);
            return true;
          }
          return false;
       }

       static bool restoreWidgetPosition( intf_thread_t *p_intf,
                                           QString configName,
                                           QWidget *widget,
                                           QSize defSize = QSize( 0, 0 ),
                                           QPoint defPos = QPoint( 0, 0 ) )
       {
         getSettings()->beginGroup( configName );
         bool defaultUsed = QVLCTools::restoreWidgetPosition( getSettings(),
                                                                   widget,
                                                                   defSize,
                                                                   defPos);
         getSettings()->endGroup();

         return defaultUsed;
       }

      /*
        call this method for a window or dialog to show it centred on
        current screen
      */
      static void centerWidgetOnScreen(QWidget *widget)
      {
         QDesktopWidget * const desktop = QApplication::desktop();
         QRect screenRect = desktop->availableGeometry(widget);
         QPoint p1 = widget->frameGeometry().center();

         widget->move ( screenRect.center() - p1 );
      }
};

class QVLCFrame : public QWidget
{
public:
#ifdef __APPLE__
    QVLCFrame( intf_thread_t *_p_intf ) : QWidget( NULL, Qt::Window ), p_intf( _p_intf )
#else
    QVLCFrame( intf_thread_t *_p_intf ) : QWidget( NULL ), p_intf( _p_intf )
#endif
    {};
    virtual ~QVLCFrame()   {};

    void toggleVisible()
    {
        if( isVisible() ) hide();
        else show();
    }
protected:
    intf_thread_t *p_intf;

    void readSettings( QString name,
                       QSize defSize = QSize( 1, 1 ),
                       QPoint defPos = QPoint( 0, 0 ) )
    {
        QVLCTools::restoreWidgetPosition(p_intf, name, this, defSize, defPos);
    }

    void writeSettings( QString name )
    {
        QVLCTools::saveWidgetPosition( p_intf, name, this);
    }

    virtual void cancel()
    {
        hide();
    }
    virtual void close()
    {
        hide();
    }
    virtual void keyPressEvent( QKeyEvent *keyEvent )
    {
        if( keyEvent->key() == Qt::Key_Escape )
        {
            msg_Dbg( p_intf, "Escp Key pressed" );
            cancel();
        }
        else if( keyEvent->key() == Qt::Key_Return
              || keyEvent->key() == Qt::Key_Enter )
        {
             msg_Dbg( p_intf, "Enter Key pressed" );
             close();
         }
    }
};

class QVLCDialog : public QDialog
{
public:
    QVLCDialog( QWidget* parent, intf_thread_t *_p_intf ) :
                                    QDialog( parent ), p_intf( _p_intf )
    {}
    virtual ~QVLCDialog() {};
    void toggleVisible()
    {
        if( isVisible() ) hide();
        else show();
    }

protected:
    intf_thread_t *p_intf;

    virtual void cancel()
    {
        hide();
    }
    virtual void close()
    {
        hide();
    }
    virtual void keyPressEvent( QKeyEvent *keyEvent )
    {
        if( keyEvent->key() == Qt::Key_Escape )
        {
            msg_Dbg( p_intf, "Escp Key pressed" );
            cancel();
        }
        else if( keyEvent->key() == Qt::Key_Return
              || keyEvent->key() == Qt::Key_Enter )
        {
             msg_Dbg( p_intf, "Enter Key pressed" );
             close();
        }
    }
};

class QVLCMW : public QMainWindow
{
public:
    QVLCMW( intf_thread_t *_p_intf ) : QMainWindow( NULL ), p_intf( _p_intf )
    {    }
    virtual ~QVLCMW() {};
    void toggleVisible()
    {
        if( isVisible() ) hide();
        else show();
    }
protected:
    intf_thread_t *p_intf;
    QSize mainSize;

    void readSettings( QString name, QSize defSize )
    {
        QVLCTools::restoreWidgetPosition( p_intf, name, this, defSize);
    }

    void readSettings( QString name )
    {
        QVLCTools::restoreWidgetPosition( p_intf, name, this);
    }
    void readSettings( QSettings *settings )
    {
        QVLCTools::restoreWidgetPosition(settings, this);
    }

    void readSettings( QSettings *settings, QSize defSize)
    {
        QVLCTools::restoreWidgetPosition(settings, this, defSize);
    }

    void writeSettings(QString name )
    {
        QVLCTools::saveWidgetPosition( p_intf, name, this);
    }
    void writeSettings(QSettings *settings )
    {
        QVLCTools::saveWidgetPosition(settings, this);
    }
};

#endif
<commit_msg>Qt: remove unneeded debug.<commit_after>/*****************************************************************************
 * qvlcframe.hpp : A few helpers
 *****************************************************************************
 * Copyright (C) 2006-2007 the VideoLAN team
 * $Id$
 *
 * Authors: Clément Stenac <zorglub@videolan.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * 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, USA.
 *****************************************************************************/

#ifndef _QVLCFRAME_H_
#define _QVLCFRAME_H_

#include <QWidget>
#include <QDialog>
#include <QSpacerItem>
#include <QHBoxLayout>
#include <QApplication>
#include <QMainWindow>
#include <QPushButton>
#include <QKeyEvent>
#include <QDesktopWidget>
#include <QSettings>

#include "qt4.hpp"

class QVLCTools
{
   public:
       /*
        use this function to save a widgets screen position
        only for windows / dialogs which are floating, if a
        window is docked into an other - don't all this function
        or it may write garbage to position info!
       */
       static void saveWidgetPosition( QSettings *settings, QWidget *widget)
       {
         settings->setValue("geometry", widget->saveGeometry());
       }
       static void saveWidgetPosition( intf_thread_t *p_intf,
                                       QString configName,
                                       QWidget *widget)
       {
         getSettings()->beginGroup( configName );
         QVLCTools::saveWidgetPosition(getSettings(), widget);
         getSettings()->endGroup();
       }

       /*
         use this method only for restoring window state of non docked
         windows!
       */
       static bool restoreWidgetPosition(QSettings *settings,
                                           QWidget *widget,
                                           QSize defSize = QSize( 0, 0 ),
                                           QPoint defPos = QPoint( 0, 0 ))
       {
          if(!widget->restoreGeometry(settings->value("geometry")
                                      .toByteArray()))
          {
            widget->move(defPos);
            widget->resize(defSize);

            if(defPos.x() == 0 && defPos.y()==0)
               centerWidgetOnScreen(widget);
            return true;
          }
          return false;
       }

       static bool restoreWidgetPosition( intf_thread_t *p_intf,
                                           QString configName,
                                           QWidget *widget,
                                           QSize defSize = QSize( 0, 0 ),
                                           QPoint defPos = QPoint( 0, 0 ) )
       {
         getSettings()->beginGroup( configName );
         bool defaultUsed = QVLCTools::restoreWidgetPosition( getSettings(),
                                                                   widget,
                                                                   defSize,
                                                                   defPos);
         getSettings()->endGroup();

         return defaultUsed;
       }

      /*
        call this method for a window or dialog to show it centred on
        current screen
      */
      static void centerWidgetOnScreen(QWidget *widget)
      {
         QDesktopWidget * const desktop = QApplication::desktop();
         QRect screenRect = desktop->availableGeometry(widget);
         QPoint p1 = widget->frameGeometry().center();

         widget->move ( screenRect.center() - p1 );
      }
};

class QVLCFrame : public QWidget
{
public:
#ifdef __APPLE__
    QVLCFrame( intf_thread_t *_p_intf ) : QWidget( NULL, Qt::Window ), p_intf( _p_intf )
#else
    QVLCFrame( intf_thread_t *_p_intf ) : QWidget( NULL ), p_intf( _p_intf )
#endif
    {};
    virtual ~QVLCFrame()   {};

    void toggleVisible()
    {
        if( isVisible() ) hide();
        else show();
    }
protected:
    intf_thread_t *p_intf;

    void readSettings( QString name,
                       QSize defSize = QSize( 1, 1 ),
                       QPoint defPos = QPoint( 0, 0 ) )
    {
        QVLCTools::restoreWidgetPosition(p_intf, name, this, defSize, defPos);
    }

    void writeSettings( QString name )
    {
        QVLCTools::saveWidgetPosition( p_intf, name, this);
    }

    virtual void cancel()
    {
        hide();
    }
    virtual void close()
    {
        hide();
    }
    virtual void keyPressEvent( QKeyEvent *keyEvent )
    {
        if( keyEvent->key() == Qt::Key_Escape )
        {
            cancel();
        }
        else if( keyEvent->key() == Qt::Key_Return
              || keyEvent->key() == Qt::Key_Enter )
        {
             close();
         }
    }
};

class QVLCDialog : public QDialog
{
public:
    QVLCDialog( QWidget* parent, intf_thread_t *_p_intf ) :
                                    QDialog( parent ), p_intf( _p_intf )
    {}
    virtual ~QVLCDialog() {};
    void toggleVisible()
    {
        if( isVisible() ) hide();
        else show();
    }

protected:
    intf_thread_t *p_intf;

    virtual void cancel()
    {
        hide();
    }
    virtual void close()
    {
        hide();
    }
    virtual void keyPressEvent( QKeyEvent *keyEvent )
    {
        if( keyEvent->key() == Qt::Key_Escape )
        {
            msg_Dbg( p_intf, "Escp Key pressed" );
            cancel();
        }
        else if( keyEvent->key() == Qt::Key_Return
              || keyEvent->key() == Qt::Key_Enter )
        {
             msg_Dbg( p_intf, "Enter Key pressed" );
             close();
        }
    }
};

class QVLCMW : public QMainWindow
{
public:
    QVLCMW( intf_thread_t *_p_intf ) : QMainWindow( NULL ), p_intf( _p_intf )
    {    }
    virtual ~QVLCMW() {};
    void toggleVisible()
    {
        if( isVisible() ) hide();
        else show();
    }
protected:
    intf_thread_t *p_intf;
    QSize mainSize;

    void readSettings( QString name, QSize defSize )
    {
        QVLCTools::restoreWidgetPosition( p_intf, name, this, defSize);
    }

    void readSettings( QString name )
    {
        QVLCTools::restoreWidgetPosition( p_intf, name, this);
    }
    void readSettings( QSettings *settings )
    {
        QVLCTools::restoreWidgetPosition(settings, this);
    }

    void readSettings( QSettings *settings, QSize defSize)
    {
        QVLCTools::restoreWidgetPosition(settings, this, defSize);
    }

    void writeSettings(QString name )
    {
        QVLCTools::saveWidgetPosition( p_intf, name, this);
    }
    void writeSettings(QSettings *settings )
    {
        QVLCTools::saveWidgetPosition(settings, this);
    }
};

#endif
<|endoftext|>


<commit_before>
#include <assert.h>
#include <thread>
#include <boost/atomic.hpp>

#include "LinkedList.hpp"

void test0() {
	LinkedList<int> l;
	assert(l.empty());
	l._checkSanity();

	auto item = l.push_back();
	item->value = 42;
	item = NULL;
	l._checkSanity();
	assert(!l.empty());
	assert(l.size() == 1);

	auto ret = l.pop_front();
	assert(ret);
	assert(ret->value == 42);
	ret = NULL;

	assert(l.empty());
	assert(l.size() == 0);
	l._checkSanity();
}

void test1() {
	LinkedList<int> l;
	l._checkSanity();

	for(int i = 0; i < 100; ++i) {
		auto item = l.push_back();
		l._checkSanity();
		item->value = i;
	}

	assert(!l.empty());
	assert(l.size() == 100);

	for(int i = 0; i < 100; ++i) {
		auto ret = l.pop_front();
		l._checkSanity();
		assert(ret);
		assert(ret->value == i);
	}

	assert(l.empty());
}

void test2() {
	LinkedList<int> l;
	l._checkSanity();

	auto producer = [&l](){
		for(int i = 0; i < 100; ++i) {
			LinkedList<int>::ItemPtr item(new LinkedList<int>::Item);
			item->value = i;
			l.push_back(item);
		}
	};

	auto consumer = [&l](){
		for(int i = 0; i < 100; ++i) {
			while(l.empty()) {} // wait for entry
			auto ret = l.pop_front();
			assert(ret);
			assert(ret->value == i);
		}
	};

	for(int i = 0; i < 1000; ++i) {
		std::thread t1(producer), t2(consumer);
		t1.join();
		t2.join();
		assert(l.empty());
		l._checkSanity();
	}
}

void test3() {
	LinkedList<int> l;
	boost::atomic<int> state;

	auto producer = [&l, &state](){
		for(int i = 0; i < 100; ++i) {
			if(i == 50) state++;
			LinkedList<int>::ItemPtr item(new LinkedList<int>::Item);
			item->value = i;
			l.push_back(item);
		}
		state++;
	};

	auto consumer = [&l, &state](){
		while(state == 0) {}
		for(int i = 0; i < 40; ++i) {
			while(l.empty()); // wait for entry
			auto ret = l.pop_front();
			assert(ret);
			assert(ret->value == i);
		}
		state++;
	};

	auto reader = [&l, &state]() {
		while(state < 3) {
			if(state == 0) continue;
			int first = -1;
			int old = -1;
			int count = 0;
			for(auto v : l) {
				assert(v >= 0);
				if(first < 0) first = v;
				if(old >= 0) assert(old < v);
				old = v;
				++count;
			}
			assert(count > 10);
		}
	};

	for(int i = 0; i < 1000; ++i) {
		state = 0;

		std::thread t1(producer), t2(consumer), t3(reader);
		t1.join();
		t2.join();
		t3.join();

		l._checkSanity();
		l.clear();
	}
}

void test4() {
	LinkedList<int> l;

	auto producer = [&l](){
		for(int i = 3; i <= 100; ++i) {
			LinkedList<int>::ItemPtr item(new LinkedList<int>::Item);
			item->value = i;
			if(i < 50)
				l.push_back(item);
			else
				l.push_front(item);
		}
		for(int i = 100; i >= 50; --i) {
			LinkedList<int>::ItemPtr item = l.pop_front();
			assert(item->value == i);
		}
	};

	auto reader = [&l]() {
		int endCount = 0;
		while(true) {
			int old = -1;
			int m = 0;
			int count = 0;
			for(auto v : l) {
				assert(v >= 1);
				if(old >= 50 && v == 1) {}
				else if(old >= 50) assert(old - 1 == v);
				else if(old >= 0) assert(old + 1 == v);
				old = v;
				if(v > m) m = v;
				++count;
			}
			assert(count >= 2);
			assert(count <= 100);
			assert(count == m);
			if(count >= 50) assert(old == 49);
			if(count < 100) assert(endCount == 0);
			if(count == 100) endCount++;
			if(endCount >= 10) break;
		}
	};

	for(int i = 0; i < 1000; ++i) {
		l.push_back()->value = 1;
		l.push_back()->value = 2;

		std::thread t1(producer), t3(reader);
		t1.join();
		t3.join();

		l._checkSanity();
		l.clear();
	}
}

int main() {
	test0();
	test1();
	test2();
	test3();
	test4();
}
<commit_msg>better<commit_after>
#include <assert.h>
#include <thread>
#include <boost/atomic.hpp>

#include "LinkedList.hpp"

void test0() {
	LinkedList<int> l;
	assert(l.empty());
	l._checkSanity();

	auto item = l.push_back();
	item->value = 42;
	item = NULL;
	l._checkSanity();
	assert(!l.empty());
	assert(l.size() == 1);

	auto ret = l.pop_front();
	assert(ret);
	assert(ret->value == 42);
	ret = NULL;

	assert(l.empty());
	assert(l.size() == 0);
	l._checkSanity();
}

void test1() {
	LinkedList<int> l;
	l._checkSanity();

	for(int i = 0; i < 100; ++i) {
		auto item = l.push_back();
		l._checkSanity();
		item->value = i;
	}

	assert(!l.empty());
	assert(l.size() == 100);

	for(int i = 0; i < 100; ++i) {
		auto ret = l.pop_front();
		l._checkSanity();
		assert(ret);
		assert(ret->value == i);
	}

	assert(l.empty());
}

void test2() {
	LinkedList<int> l;
	l._checkSanity();

	auto producer = [&l](){
		for(int i = 0; i < 100; ++i) {
			LinkedList<int>::ItemPtr item(new LinkedList<int>::Item);
			item->value = i;
			l.push_back(item);
		}
	};

	auto consumer = [&l](){
		for(int i = 0; i < 100; ++i) {
			while(l.empty()) {} // wait for entry
			auto ret = l.pop_front();
			assert(ret);
			assert(ret->value == i);
		}
	};

	for(int i = 0; i < 1000; ++i) {
		std::thread t1(producer), t2(consumer);
		t1.join();
		t2.join();
		assert(l.empty());
		l._checkSanity();
	}
}

void test3() {
	LinkedList<int> l;
	boost::atomic<int> state;

	auto producer = [&l, &state](){
		for(int i = 0; i < 100; ++i) {
			if(i == 50) state++;
			LinkedList<int>::ItemPtr item(new LinkedList<int>::Item);
			item->value = i;
			l.push_back(item);
		}
		state++;
	};

	auto consumer = [&l, &state](){
		while(state == 0) {}
		for(int i = 0; i < 40; ++i) {
			while(l.empty()); // wait for entry
			auto ret = l.pop_front();
			assert(ret);
			assert(ret->value == i);
		}
		state++;
	};

	auto reader = [&l, &state]() {
		while(state < 3) {
			if(state == 0) continue;
			int first = -1;
			int old = -1;
			int count = 0;
			for(auto v : l) {
				assert(v >= 0);
				if(first < 0) first = v;
				if(old >= 0) assert(old < v);
				old = v;
				++count;
			}
			assert(count > 10);
		}
	};

	for(int i = 0; i < 1000; ++i) {
		state = 0;

		std::thread t1(producer), t2(consumer), t3(reader);
		t1.join();
		t2.join();
		t3.join();

		l._checkSanity();
		l.clear();
	}
}

void test4() {
	LinkedList<int> l;

	auto producer = [&l](){
		for(int i = 3; i <= 100; ++i) {
			LinkedList<int>::ItemPtr item(new LinkedList<int>::Item);
			item->value = i;
			if(i < 50)
				l.push_back(item);
			else
				l.push_front(item);
		}
		for(int i = 100; i >= 50; --i) {
			LinkedList<int>::ItemPtr item = l.pop_front();
			assert(item->value == i);
		}
	};

	auto reader = [&l]() {
		int endCount = 0;
		while(true) {
			int old = -1;
			int m = 0;
			int count = 0;
			for(auto v : l) {
				assert(v >= 1);
				if(old >= 50 && v == 1) {}
				else if(old >= 50) assert(old - 1 == v);
				else if(old >= 0) assert(old + 1 == v);
				old = v;
				if(v > m) m = v;
				++count;
				assert(count <= 100);
			}
			assert(count >= 2);
			assert(count == m);
			if(count >= 50) assert(old == 49);
			if(count < 100) assert(endCount == 0);
			if(count == 100) endCount++;
			if(endCount >= 10) break;
		}
	};

	for(int i = 0; i < 1000; ++i) {
		l.push_back()->value = 1;
		l.push_back()->value = 2;

		std::thread t1(producer), t3(reader);
		t1.join();
		t3.join();

		l._checkSanity();
		l.clear();
	}
}

int main() {
	test0();
	test1();
	test2();
	test3();
	test4();
}
<|endoftext|>


<commit_before>// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "app/atom_main_delegate.h"

#include "base/command_line.h"
#include "base/logging.h"
#include "browser/atom_browser_client.h"
#include "content/public/common/content_switches.h"
#include "renderer/atom_renderer_client.h"
#include "ui/base/resource/resource_bundle.h"
#include "base/path_service.h"

namespace atom {

AtomMainDelegate::AtomMainDelegate() {
}

AtomMainDelegate::~AtomMainDelegate() {
}

bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
  // Disable logging out to debug.log on Windows
#if defined(OS_WIN)
  logging::LoggingSettings settings;
#if defined(DEBUG)
  settings.logging_dest = logging::LOG_TO_ALL;
  settings.log_file = L"debug.log";
  settings.lock_log = logging::LOCK_LOG_FILE;
  settings.delete_old = logging::DELETE_OLD_LOG_FILE;
#else
  settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
#endif
  settings.dcheck_state =
      logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS;
  logging::InitLogging(settings);
  // Logging with pid, tid and timestamp.
  logging::SetLogItems(true, true, true, false);
#endif  // defined(OS_WIN)

  return brightray::MainDelegate::BasicStartupComplete(exit_code);
}

void AtomMainDelegate::PreSandboxStartup() {
#if defined(OS_MACOSX)
  OverrideChildProcessPath();
  OverrideFrameworkBundlePath();
#endif
  InitializeResourceBundle();

  CommandLine* command_line = CommandLine::ForCurrentProcess();

  // Disable renderer sandbox for most of node's functions.
  command_line->AppendSwitch(switches::kNoSandbox);

  // Disable accelerated compositing since it caused a lot of troubles (black
  // devtools, screen flashes) and needed lots of effort to make it right.
  command_line->AppendSwitch(switches::kDisableAcceleratedCompositing);

  // Add a flag to mark the end of switches added by atom-shell.
  command_line->AppendSwitch("no-more-switches");
}

void AtomMainDelegate::InitializeResourceBundle() {
  base::FilePath path;
#if defined(OS_MACOSX)
  path = GetResourcesPakFilePath();
#else
  base::FilePath pak_dir;
  PathService::Get(base::DIR_MODULE, &pak_dir);
  path = pak_dir.Append(FILE_PATH_LITERAL("content_shell.pak"));
#endif

  ui::ResourceBundle::InitSharedInstanceWithPakPath(path);
}

content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() {
  browser_client_.reset(new AtomBrowserClient);
  return browser_client_.get();
}

content::ContentRendererClient*
    AtomMainDelegate::CreateContentRendererClient() {
  renderer_client_.reset(new AtomRendererClient);
  return renderer_client_.get();
}

}  // namespace atom
<commit_msg>Print pid when logging.<commit_after>// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "app/atom_main_delegate.h"

#include "base/command_line.h"
#include "base/logging.h"
#include "browser/atom_browser_client.h"
#include "content/public/common/content_switches.h"
#include "renderer/atom_renderer_client.h"
#include "ui/base/resource/resource_bundle.h"
#include "base/path_service.h"

namespace atom {

AtomMainDelegate::AtomMainDelegate() {
}

AtomMainDelegate::~AtomMainDelegate() {
}

bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
  // Disable logging out to debug.log on Windows
#if defined(OS_WIN)
  logging::LoggingSettings settings;
#if defined(DEBUG)
  settings.logging_dest = logging::LOG_TO_ALL;
  settings.log_file = L"debug.log";
  settings.lock_log = logging::LOCK_LOG_FILE;
  settings.delete_old = logging::DELETE_OLD_LOG_FILE;
#else
  settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
#endif
  settings.dcheck_state =
      logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS;
  logging::InitLogging(settings);
#endif  // defined(OS_WIN)

  // Logging with pid and timestamp.
  logging::SetLogItems(true, false, true, false);

  return brightray::MainDelegate::BasicStartupComplete(exit_code);
}

void AtomMainDelegate::PreSandboxStartup() {
#if defined(OS_MACOSX)
  OverrideChildProcessPath();
  OverrideFrameworkBundlePath();
#endif
  InitializeResourceBundle();

  CommandLine* command_line = CommandLine::ForCurrentProcess();

  // Disable renderer sandbox for most of node's functions.
  command_line->AppendSwitch(switches::kNoSandbox);

  // Disable accelerated compositing since it caused a lot of troubles (black
  // devtools, screen flashes) and needed lots of effort to make it right.
  command_line->AppendSwitch(switches::kDisableAcceleratedCompositing);

  // Add a flag to mark the end of switches added by atom-shell.
  command_line->AppendSwitch("no-more-switches");
}

void AtomMainDelegate::InitializeResourceBundle() {
  base::FilePath path;
#if defined(OS_MACOSX)
  path = GetResourcesPakFilePath();
#else
  base::FilePath pak_dir;
  PathService::Get(base::DIR_MODULE, &pak_dir);
  path = pak_dir.Append(FILE_PATH_LITERAL("content_shell.pak"));
#endif

  ui::ResourceBundle::InitSharedInstanceWithPakPath(path);
}

content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() {
  browser_client_.reset(new AtomBrowserClient);
  return browser_client_.get();
}

content::ContentRendererClient*
    AtomMainDelegate::CreateContentRendererClient() {
  renderer_client_.reset(new AtomRendererClient);
  return renderer_client_.get();
}

}  // namespace atom
<|endoftext|>


<commit_before>//=============================================================================
//
// Adventure Game Studio (AGS)
//
// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others
// The full list of copyright holders can be found in the Copyright.txt
// file, which is part of this source code distribution.
//
// The AGS source code is provided under the Artistic License 2.0.
// A copy of this license can be found in the file License.txt and at
// http://www.opensource.org/licenses/artistic-license-2.0.php
//
//=============================================================================

//
// Entry point of the application here.
//
//
// For Windows main() function is really called _mangled_main and is called
// not by system, but from insides of allegro library.
// (See allegro\platform\alwin.h)
// What about other platforms?
//

#include "util/wgt2allg.h"
#include "ac/common.h"
#include "ac/gamesetup.h"
#include "ac/gamestate.h"
#include "debug/agseditordebugger.h"
#include "debug/debug_log.h"
#include "main/engine.h"
#include "main/mainheader.h"
#include "main/main.h"
#include "platform/base/agsplatformdriver.h"
#include "ac/route_finder.h"
#include "core/assetmanager.h"

#ifdef _DEBUG
#include "test/test_all.h"
#endif

char appDirectory[512]; // Needed for library loading

#ifdef MAC_VERSION
char dataDirectory[512];
extern "C"
{
    int osx_sys_question(const char *msg, const char *but1, const char *but2);
}
#endif

#ifdef WINDOWS_VERSION

int wArgc;
LPWSTR *wArgv;

#endif

#ifndef WINDOWS_VERSION
char **global_argv = 0;
#endif

extern GameSetup usetup;
extern GameState play;
extern int our_eip;
extern AGSPlatformDriver *platform;
extern int debug_flags;
extern int force_letterbox;
extern int debug_15bit_mode, debug_24bit_mode;
extern int convert_16bit_bgr;
extern int display_fps;
extern int editor_debugging_enabled;
extern int editor_debugging_initialized;
extern char editor_debugger_instance_token[100];

// Startup flags, set from parameters to engine
int datafile_argv=0, change_to_game_dir = 0, force_window = 0;
int override_start_room = 0, force_16bit = 0;
bool justRegisterGame = false;
bool justUnRegisterGame = false;
const char *loadSaveGameOnStartup = NULL;

#if !defined(IOS_VERSION) && !defined(PSP_VERSION) && !defined(ANDROID_VERSION)
int psp_video_framedrop = 1;
int psp_audio_enabled = 1;
int psp_midi_enabled = 1;
int psp_ignore_acsetup_cfg_file = 0;
int psp_clear_cache_on_room_change = 0;

int psp_midi_preload_patches = 0;
int psp_audio_cachesize = 10;
char psp_game_file_name[] = "ac2game.dat";
int psp_gfx_smooth_sprites = 1;
char psp_translation[] = "default";
#endif

void main_pre_init()
{
    our_eip = -999;
    Common::AssetManager::SetSearchPriority(Common::kAssetPriorityDir);
    play.recording = 0;
    play.playback = 0;
    play.takeover_data = 0;
}

void main_create_platform_driver()
{
    platform = AGSPlatformDriver::GetDriver();
}

void main_init()
{
    Common::AssetManager::CreateInstance();
    main_pre_init();
    main_create_platform_driver();
}

int main_preprocess_cmdline(int argc,char*argv[])
{
#ifdef WINDOWS_VERSION
    wArgv = CommandLineToArgvW(GetCommandLineW(), &wArgc);
    if (wArgv == NULL)
    {
        platform->DisplayAlert("CommandLineToArgvW failed, unable to start the game.");
        return 9;
    }
#else
    global_argv = argv;
#endif
    return RETURN_CONTINUE;
}

extern char return_to_roomedit[30];
extern char return_to_room[150];

void main_print_help() {
    printf("\nUsage: ags [<options>] <gamefile or directory>\n\n"
           "Options:\n"
           "-windowed           Set display mode to windowed\n"
           "-fullscreen         Set display mode to fullscreen\n"
           "-hicolor            Enable 16bit colors\n"
           "-letterbox          Enable letterbox mode\n"
           "--help              Print this help message\n");
}

int main_process_cmdline(int argc,char*argv[])
{
    for (int ee=1;ee<argc;ee++) {
        if (stricmp(argv[ee],"--help") == 0 || argv[ee][1]=='?') {
            return 0;
        }
        if (stricmp(argv[ee],"-shelllaunch") == 0)
            change_to_game_dir = 1;
        else if (stricmp(argv[ee],"-updatereg") == 0)
            debug_flags |= DBG_REGONLY;
        else if (stricmp(argv[ee],"-windowed") == 0)
            force_window = 1;
        else if (stricmp(argv[ee],"-fullscreen") == 0)
            force_window = 2;
        else if (stricmp(argv[ee],"-hicolor") == 0)
            force_16bit = 1;
        else if (stricmp(argv[ee],"-letterbox") == 0)
            force_letterbox = 1;
        else if (stricmp(argv[ee],"-record") == 0)
            play.recording = 1;
        else if (stricmp(argv[ee],"-playback") == 0)
            play.playback = 1;
#ifdef _DEBUG
        else if ((stricmp(argv[ee],"--startr") == 0) && (ee < argc-1)) {
            override_start_room = atoi(argv[ee+1]);
            ee++;
        }
#endif
        else if ((stricmp(argv[ee],"--testre") == 0) && (ee < argc-2)) {
            strcpy(return_to_roomedit, argv[ee+1]);
            strcpy(return_to_room, argv[ee+2]);
            ee+=2;
        }
        else if (stricmp(argv[ee],"--15bit")==0) debug_15bit_mode = 1;
        else if (stricmp(argv[ee],"--24bit")==0) debug_24bit_mode = 1;
        else if (stricmp(argv[ee],"--fps")==0) display_fps = 2;
        else if (stricmp(argv[ee],"--test")==0) debug_flags|=DBG_DEBUGMODE;
        else if (stricmp(argv[ee],"-noiface")==0) debug_flags|=DBG_NOIFACE;
        else if (stricmp(argv[ee],"-nosprdisp")==0) debug_flags|=DBG_NODRAWSPRITES;
        else if (stricmp(argv[ee],"-nospr")==0) debug_flags|=DBG_NOOBJECTS;
        else if (stricmp(argv[ee],"-noupdate")==0) debug_flags|=DBG_NOUPDATE;
        else if (stricmp(argv[ee],"-nosound")==0) debug_flags|=DBG_NOSFX;
        else if (stricmp(argv[ee],"-nomusic")==0) debug_flags|=DBG_NOMUSIC;
        else if (stricmp(argv[ee],"-noscript")==0) debug_flags|=DBG_NOSCRIPT;
        else if (stricmp(argv[ee],"-novideo")==0) debug_flags|=DBG_NOVIDEO;
        else if (stricmp(argv[ee],"-noexceptionhandler")==0) usetup.disable_exception_handling = 1;
        else if (stricmp(argv[ee],"-dbgscript")==0) debug_flags|=DBG_DBGSCRIPT;
        else if (stricmp(argv[ee],"-registergame") == 0)
        {
            justRegisterGame = true;
        }
        else if (stricmp(argv[ee],"-unregistergame") == 0)
        {
            justUnRegisterGame = true;
        }
        else if ((stricmp(argv[ee],"-loadsavedgame") == 0) && (argc > ee + 1))
        {
            loadSaveGameOnStartup = argv[ee + 1];
            ee++;
        }
        else if ((stricmp(argv[ee],"--enabledebugger") == 0) && (argc > ee + 1))
        {
            strcpy(editor_debugger_instance_token, argv[ee + 1]);
            editor_debugging_enabled = 1;
            force_window = 1;
            ee++;
        }
        else if (stricmp(argv[ee],"--takeover")==0) {
            if (argc < ee+2)
                break;
            play.takeover_data = atoi (argv[ee + 1]);
            strncpy (play.takeover_from, argv[ee + 2], 49);
            play.takeover_from[49] = 0;
            ee += 2;
        }
        else if (argv[ee][0]!='-') datafile_argv=ee;
    }

    return RETURN_CONTINUE;
}

void main_init_crt_report()
{
#ifdef _DEBUG
    /* logfile=fopen("g:\\ags.log","at");
    //_CrtSetReportHook( OurReportingFunction );
    int tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
    //tmpDbgFlag |= _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_DELAY_FREE_MEM_DF;

    tmpDbgFlag = (tmpDbgFlag & 0x0000FFFF) | _CRTDBG_CHECK_EVERY_16_DF | _CRTDBG_DELAY_FREE_MEM_DF;

    _CrtSetDbgFlag(tmpDbgFlag);

    /*
    //  _CrtMemState memstart,memnow;
    _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_WNDW );
    _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_WNDW );
    _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_WNDW );
    /*
    //   _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR );
    //   _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );
    //   _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR );

    //  _CrtMemCheckpoint(&memstart);
    //  _CrtMemDumpStatistics( &memstart );*/
#endif
}

void change_to_directory_of_file(LPCWSTR fileName)
{
    WCHAR wcbuffer[MAX_PATH];
    StrCpyW(wcbuffer, fileName);

#if defined (WINDOWS_VERSION)
    LPWSTR backSlashAt = StrRChrW(wcbuffer, NULL, L'\\');
    if (backSlashAt != NULL) {
        wcbuffer[wcslen(wcbuffer) - wcslen(backSlashAt)] = L'\0';
        SetCurrentDirectoryW(wcbuffer);
    }
#else
    if (strrchr(wcbuffer, '/') != NULL) {
        strrchr(wcbuffer, '/')[0] = 0;
        chdir(wcbuffer);
    }
#endif
}

void main_set_gamedir(int argc,char*argv[])
{
    if ((loadSaveGameOnStartup != NULL) && (argv[0] != NULL))
    {
        // When launched by double-clicking a save game file, the curdir will
        // be the save game folder unless we correct it
        change_to_directory_of_file(wArgv[0]);
    }

    getcwd(appDirectory, 512);

    //if (change_to_game_dir == 1)  {
    if (datafile_argv > 0) {
        // If launched by double-clicking .AGS file, change to that
        // folder; else change to this exe's folder
        change_to_directory_of_file(wArgv[datafile_argv]);
    }

#ifdef MAC_VERSION
    getcwd(dataDirectory, 512);
#endif
}

#if defined(WINDOWS_VERSION)
#include <new.h>
char tempmsg[100];
char*printfworkingspace;
int malloc_fail_handler(size_t amountwanted) {
  free(printfworkingspace);
  sprintf(tempmsg,"Out of memory: failed to allocate %ld bytes (at PP=%d)",amountwanted, our_eip);
  quit(tempmsg);
  return 0;
}
#endif

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

#ifdef _DEBUG
    Test_DoAllTests();
#endif

    int res;
    main_init();

    res = main_preprocess_cmdline(argc, argv);
    if (res != RETURN_CONTINUE) {
        return res;
    }

    printf("Adventure Creator v%sInterpreter\n"
      "Copyright (c) 1999-2001 Chris Jones\n" "ACI version %s\n", AC_VERSION_TEXT, ACI_VERSION_TEXT);

    if ((argc>1) && (stricmp(argv[1],"--help") == 0 || argv[1][1]=='?')) {
        main_print_help();
        return 0;
    }

    initialize_debug_system();
    write_log_debug("***** ENGINE STARTUP");

#if defined(WINDOWS_VERSION)
    _set_new_handler(malloc_fail_handler);
    _set_new_mode(1);
    printfworkingspace=(char*)malloc(7000);
#endif
    debug_flags=0;

    res = main_process_cmdline(argc, argv);
    if (res != RETURN_CONTINUE) {
        return res;
    }

    main_init_crt_report();

    main_set_gamedir(argc, argv);

    // Update shell associations and exit
    if (debug_flags & DBG_REGONLY)
        exit(0);

#ifndef USE_CUSTOM_EXCEPTION_HANDLER
    usetup.disable_exception_handling = 1;
#endif

    if (usetup.disable_exception_handling)
    {
        int result = initialize_engine(argc, argv);
        platform->PostAllegroExit();
        return result;
    }
    else
    {
        return initialize_engine_with_exception_handling(argc, argv);
    }
}

#if !defined (DOS_VERSION)
END_OF_MAIN()
#endif
<commit_msg>Engine: Update copyright message emitted by the engine.<commit_after>//=============================================================================
//
// Adventure Game Studio (AGS)
//
// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others
// The full list of copyright holders can be found in the Copyright.txt
// file, which is part of this source code distribution.
//
// The AGS source code is provided under the Artistic License 2.0.
// A copy of this license can be found in the file License.txt and at
// http://www.opensource.org/licenses/artistic-license-2.0.php
//
//=============================================================================

//
// Entry point of the application here.
//
//
// For Windows main() function is really called _mangled_main and is called
// not by system, but from insides of allegro library.
// (See allegro\platform\alwin.h)
// What about other platforms?
//

#include "util/wgt2allg.h"
#include "ac/common.h"
#include "ac/gamesetup.h"
#include "ac/gamestate.h"
#include "debug/agseditordebugger.h"
#include "debug/debug_log.h"
#include "main/engine.h"
#include "main/mainheader.h"
#include "main/main.h"
#include "platform/base/agsplatformdriver.h"
#include "ac/route_finder.h"
#include "core/assetmanager.h"

#ifdef _DEBUG
#include "test/test_all.h"
#endif

char appDirectory[512]; // Needed for library loading

#ifdef MAC_VERSION
char dataDirectory[512];
extern "C"
{
    int osx_sys_question(const char *msg, const char *but1, const char *but2);
}
#endif

#ifdef WINDOWS_VERSION

int wArgc;
LPWSTR *wArgv;

#endif

#ifndef WINDOWS_VERSION
char **global_argv = 0;
#endif

extern GameSetup usetup;
extern GameState play;
extern int our_eip;
extern AGSPlatformDriver *platform;
extern int debug_flags;
extern int force_letterbox;
extern int debug_15bit_mode, debug_24bit_mode;
extern int convert_16bit_bgr;
extern int display_fps;
extern int editor_debugging_enabled;
extern int editor_debugging_initialized;
extern char editor_debugger_instance_token[100];

// Startup flags, set from parameters to engine
int datafile_argv=0, change_to_game_dir = 0, force_window = 0;
int override_start_room = 0, force_16bit = 0;
bool justRegisterGame = false;
bool justUnRegisterGame = false;
const char *loadSaveGameOnStartup = NULL;

#if !defined(IOS_VERSION) && !defined(PSP_VERSION) && !defined(ANDROID_VERSION)
int psp_video_framedrop = 1;
int psp_audio_enabled = 1;
int psp_midi_enabled = 1;
int psp_ignore_acsetup_cfg_file = 0;
int psp_clear_cache_on_room_change = 0;

int psp_midi_preload_patches = 0;
int psp_audio_cachesize = 10;
char psp_game_file_name[] = "ac2game.dat";
int psp_gfx_smooth_sprites = 1;
char psp_translation[] = "default";
#endif

void main_pre_init()
{
    our_eip = -999;
    Common::AssetManager::SetSearchPriority(Common::kAssetPriorityDir);
    play.recording = 0;
    play.playback = 0;
    play.takeover_data = 0;
}

void main_create_platform_driver()
{
    platform = AGSPlatformDriver::GetDriver();
}

void main_init()
{
    Common::AssetManager::CreateInstance();
    main_pre_init();
    main_create_platform_driver();
}

int main_preprocess_cmdline(int argc,char*argv[])
{
#ifdef WINDOWS_VERSION
    wArgv = CommandLineToArgvW(GetCommandLineW(), &wArgc);
    if (wArgv == NULL)
    {
        platform->DisplayAlert("CommandLineToArgvW failed, unable to start the game.");
        return 9;
    }
#else
    global_argv = argv;
#endif
    return RETURN_CONTINUE;
}

extern char return_to_roomedit[30];
extern char return_to_room[150];

void main_print_help() {
    printf("\nUsage: ags [<options>] <gamefile or directory>\n\n"
           "Options:\n"
           "-windowed           Set display mode to windowed\n"
           "-fullscreen         Set display mode to fullscreen\n"
           "-hicolor            Enable 16bit colors\n"
           "-letterbox          Enable letterbox mode\n"
           "--help              Print this help message\n");
}

int main_process_cmdline(int argc,char*argv[])
{
    for (int ee=1;ee<argc;ee++) {
        if (stricmp(argv[ee],"--help") == 0 || argv[ee][1]=='?') {
            return 0;
        }
        if (stricmp(argv[ee],"-shelllaunch") == 0)
            change_to_game_dir = 1;
        else if (stricmp(argv[ee],"-updatereg") == 0)
            debug_flags |= DBG_REGONLY;
        else if (stricmp(argv[ee],"-windowed") == 0)
            force_window = 1;
        else if (stricmp(argv[ee],"-fullscreen") == 0)
            force_window = 2;
        else if (stricmp(argv[ee],"-hicolor") == 0)
            force_16bit = 1;
        else if (stricmp(argv[ee],"-letterbox") == 0)
            force_letterbox = 1;
        else if (stricmp(argv[ee],"-record") == 0)
            play.recording = 1;
        else if (stricmp(argv[ee],"-playback") == 0)
            play.playback = 1;
#ifdef _DEBUG
        else if ((stricmp(argv[ee],"--startr") == 0) && (ee < argc-1)) {
            override_start_room = atoi(argv[ee+1]);
            ee++;
        }
#endif
        else if ((stricmp(argv[ee],"--testre") == 0) && (ee < argc-2)) {
            strcpy(return_to_roomedit, argv[ee+1]);
            strcpy(return_to_room, argv[ee+2]);
            ee+=2;
        }
        else if (stricmp(argv[ee],"--15bit")==0) debug_15bit_mode = 1;
        else if (stricmp(argv[ee],"--24bit")==0) debug_24bit_mode = 1;
        else if (stricmp(argv[ee],"--fps")==0) display_fps = 2;
        else if (stricmp(argv[ee],"--test")==0) debug_flags|=DBG_DEBUGMODE;
        else if (stricmp(argv[ee],"-noiface")==0) debug_flags|=DBG_NOIFACE;
        else if (stricmp(argv[ee],"-nosprdisp")==0) debug_flags|=DBG_NODRAWSPRITES;
        else if (stricmp(argv[ee],"-nospr")==0) debug_flags|=DBG_NOOBJECTS;
        else if (stricmp(argv[ee],"-noupdate")==0) debug_flags|=DBG_NOUPDATE;
        else if (stricmp(argv[ee],"-nosound")==0) debug_flags|=DBG_NOSFX;
        else if (stricmp(argv[ee],"-nomusic")==0) debug_flags|=DBG_NOMUSIC;
        else if (stricmp(argv[ee],"-noscript")==0) debug_flags|=DBG_NOSCRIPT;
        else if (stricmp(argv[ee],"-novideo")==0) debug_flags|=DBG_NOVIDEO;
        else if (stricmp(argv[ee],"-noexceptionhandler")==0) usetup.disable_exception_handling = 1;
        else if (stricmp(argv[ee],"-dbgscript")==0) debug_flags|=DBG_DBGSCRIPT;
        else if (stricmp(argv[ee],"-registergame") == 0)
        {
            justRegisterGame = true;
        }
        else if (stricmp(argv[ee],"-unregistergame") == 0)
        {
            justUnRegisterGame = true;
        }
        else if ((stricmp(argv[ee],"-loadsavedgame") == 0) && (argc > ee + 1))
        {
            loadSaveGameOnStartup = argv[ee + 1];
            ee++;
        }
        else if ((stricmp(argv[ee],"--enabledebugger") == 0) && (argc > ee + 1))
        {
            strcpy(editor_debugger_instance_token, argv[ee + 1]);
            editor_debugging_enabled = 1;
            force_window = 1;
            ee++;
        }
        else if (stricmp(argv[ee],"--takeover")==0) {
            if (argc < ee+2)
                break;
            play.takeover_data = atoi (argv[ee + 1]);
            strncpy (play.takeover_from, argv[ee + 2], 49);
            play.takeover_from[49] = 0;
            ee += 2;
        }
        else if (argv[ee][0]!='-') datafile_argv=ee;
    }

    return RETURN_CONTINUE;
}

void main_init_crt_report()
{
#ifdef _DEBUG
    /* logfile=fopen("g:\\ags.log","at");
    //_CrtSetReportHook( OurReportingFunction );
    int tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
    //tmpDbgFlag |= _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_DELAY_FREE_MEM_DF;

    tmpDbgFlag = (tmpDbgFlag & 0x0000FFFF) | _CRTDBG_CHECK_EVERY_16_DF | _CRTDBG_DELAY_FREE_MEM_DF;

    _CrtSetDbgFlag(tmpDbgFlag);

    /*
    //  _CrtMemState memstart,memnow;
    _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_WNDW );
    _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_WNDW );
    _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_WNDW );
    /*
    //   _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR );
    //   _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );
    //   _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR );

    //  _CrtMemCheckpoint(&memstart);
    //  _CrtMemDumpStatistics( &memstart );*/
#endif
}

void change_to_directory_of_file(LPCWSTR fileName)
{
    WCHAR wcbuffer[MAX_PATH];
    StrCpyW(wcbuffer, fileName);

#if defined (WINDOWS_VERSION)
    LPWSTR backSlashAt = StrRChrW(wcbuffer, NULL, L'\\');
    if (backSlashAt != NULL) {
        wcbuffer[wcslen(wcbuffer) - wcslen(backSlashAt)] = L'\0';
        SetCurrentDirectoryW(wcbuffer);
    }
#else
    if (strrchr(wcbuffer, '/') != NULL) {
        strrchr(wcbuffer, '/')[0] = 0;
        chdir(wcbuffer);
    }
#endif
}

void main_set_gamedir(int argc,char*argv[])
{
    if ((loadSaveGameOnStartup != NULL) && (argv[0] != NULL))
    {
        // When launched by double-clicking a save game file, the curdir will
        // be the save game folder unless we correct it
        change_to_directory_of_file(wArgv[0]);
    }

    getcwd(appDirectory, 512);

    //if (change_to_game_dir == 1)  {
    if (datafile_argv > 0) {
        // If launched by double-clicking .AGS file, change to that
        // folder; else change to this exe's folder
        change_to_directory_of_file(wArgv[datafile_argv]);
    }

#ifdef MAC_VERSION
    getcwd(dataDirectory, 512);
#endif
}

#if defined(WINDOWS_VERSION)
#include <new.h>
char tempmsg[100];
char*printfworkingspace;
int malloc_fail_handler(size_t amountwanted) {
  free(printfworkingspace);
  sprintf(tempmsg,"Out of memory: failed to allocate %ld bytes (at PP=%d)",amountwanted, our_eip);
  quit(tempmsg);
  return 0;
}
#endif

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

#ifdef _DEBUG
    Test_DoAllTests();
#endif

    int res;
    main_init();

    res = main_preprocess_cmdline(argc, argv);
    if (res != RETURN_CONTINUE) {
        return res;
    }

    printf("Adventure Game Studio v%sInterpreter\n"
           "Copyright (c) 1999-2011 Chris Jones and 2011-20xx others\n"
           "ACI version %s\n", AC_VERSION_TEXT, ACI_VERSION_TEXT);

    if ((argc>1) && (stricmp(argv[1],"--help") == 0 || argv[1][1]=='?')) {
        main_print_help();
        return 0;
    }

    initialize_debug_system();
    write_log_debug("***** ENGINE STARTUP");

#if defined(WINDOWS_VERSION)
    _set_new_handler(malloc_fail_handler);
    _set_new_mode(1);
    printfworkingspace=(char*)malloc(7000);
#endif
    debug_flags=0;

    res = main_process_cmdline(argc, argv);
    if (res != RETURN_CONTINUE) {
        return res;
    }

    main_init_crt_report();

    main_set_gamedir(argc, argv);

    // Update shell associations and exit
    if (debug_flags & DBG_REGONLY)
        exit(0);

#ifndef USE_CUSTOM_EXCEPTION_HANDLER
    usetup.disable_exception_handling = 1;
#endif

    if (usetup.disable_exception_handling)
    {
        int result = initialize_engine(argc, argv);
        platform->PostAllegroExit();
        return result;
    }
    else
    {
        return initialize_engine_with_exception_handling(argc, argv);
    }
}

#if !defined (DOS_VERSION)
END_OF_MAIN()
#endif
<|endoftext|>