<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2009 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgrePlatform.h"
#include "OgreStableHeaders.h"
#include "OgrePrerequisites.h"
#include "OgreMemoryTracker.h"
#include "OgreString.h"

namespace Ogre
{

#if OGRE_MEMORY_TRACKER
	//--------------------------------------------------------------------------
	MemoryTracker& MemoryTracker::get()
	{
		static MemoryTracker tracker;
		return tracker;
	}
	//--------------------------------------------------------------------------
	void MemoryTracker::_recordAlloc(void* ptr, size_t sz, unsigned int pool,
					  const char* file, size_t ln, const char* func)
	{
		OGRE_LOCK_AUTO_MUTEX

		assert(mAllocations.find(ptr) == mAllocations.end() && "Double allocation with same address - "
			"this probably means you have a mismatched allocation / deallocation style, "
			"check if you're are using OGRE_ALLOC_T / OGRE_FREE and OGRE_NEW_T / OGRE_DELETE_T consistently");

		mAllocations[ptr] = Alloc(sz, pool, file, ln, func);
		if(pool >= mAllocationsByPool.size())
			mAllocationsByPool.resize(pool+1, 0);
		mAllocationsByPool[pool] += sz;
		mTotalAllocations += sz;
	}
	//--------------------------------------------------------------------------
	void MemoryTracker::_recordDealloc(void* ptr)
	{
		// deal cleanly with null pointers
		if (!ptr)
			return;

		OGRE_LOCK_AUTO_MUTEX

		AllocationMap::iterator i = mAllocations.find(ptr);
		assert(i != mAllocations.end() && "Unable to locate allocation unit - "
			"this probably means you have a mismatched allocation / deallocation style, "
			"check if you're are using OGRE_ALLOC_T / OGRE_FREE and OGRE_NEW_T / OGRE_DELETE_T consistently");
		// update category stats
		mAllocationsByPool[i->second.pool] -= i->second.bytes;
		// global stats
		mTotalAllocations -= i->second.bytes;
		mAllocations.erase(i);
	}
	//--------------------------------------------------------------------------
	size_t MemoryTracker::getTotalMemoryAllocated() const
	{
		return mTotalAllocations;
	}
	//--------------------------------------------------------------------------
	size_t MemoryTracker::getMemoryAllocatedForPool(unsigned int pool) const
	{
		return mAllocationsByPool[pool];
	}
	//--------------------------------------------------------------------------
	void MemoryTracker::reportLeaks()
	{
		StringUtil::StrStreamType os;

		if (mAllocations.empty())
			os << "No leaks!";
		else
		{
			size_t totalMem = 0;
			os << "Leaks detected:" << std::endl << std::endl;
			for (AllocationMap::const_iterator i = mAllocations.begin(); i != mAllocations.end(); ++i)
			{
				const Alloc& alloc = i->second;
				if (!alloc.filename.empty())
					os << alloc.filename << "(" << alloc.line << ", " << alloc.function << "): ";
				else
					os << "(unknown source): ";
				os << alloc.bytes << " bytes";
				os << std::endl;
				totalMem += alloc.bytes;
			}

			os << std::endl;
			os << mAllocations.size() << " leaks detected, " << totalMem << " bytes total";
		}

		if (mDumpToStdOut)
			std::cout << os.str();

		std::ofstream of;
		of.open(mLeakFileName.c_str());
		of << os.str();
		of.close();
	}
#endif // OGRE_DEBUG_MODE

}

<commit_msg>MemoryTracker: Prints leaks to debug output window under WIN32 with the standard file:line form which enables tracing the leak line by clicking that line in the debugger output.<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2009 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgrePlatform.h"
#include "OgreStableHeaders.h"
#include "OgrePrerequisites.h"
#include "OgreMemoryTracker.h"
#include "OgreString.h"

namespace Ogre
{

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#	define Ogre_OutputCString(str) ::OutputDebugStringA(str)
#	define Ogre_OutputWString(str) ::OutputDebugStringW(str)
#else
#	define Ogre_OutputCString(str) std::err << str
#	define Ogre_OutputWString(str) std::err << str
#endif

#if OGRE_MEMORY_TRACKER
	//--------------------------------------------------------------------------
	MemoryTracker& MemoryTracker::get()
	{
		static MemoryTracker tracker;
		return tracker;
	}
	//--------------------------------------------------------------------------
	void MemoryTracker::_recordAlloc(void* ptr, size_t sz, unsigned int pool,
					  const char* file, size_t ln, const char* func)
	{
		OGRE_LOCK_AUTO_MUTEX

		assert(mAllocations.find(ptr) == mAllocations.end() && "Double allocation with same address - "
			"this probably means you have a mismatched allocation / deallocation style, "
			"check if you're are using OGRE_ALLOC_T / OGRE_FREE and OGRE_NEW_T / OGRE_DELETE_T consistently");

		mAllocations[ptr] = Alloc(sz, pool, file, ln, func);
		if(pool >= mAllocationsByPool.size())
			mAllocationsByPool.resize(pool+1, 0);
		mAllocationsByPool[pool] += sz;
		mTotalAllocations += sz;
	}
	//--------------------------------------------------------------------------
	void MemoryTracker::_recordDealloc(void* ptr)
	{
		// deal cleanly with null pointers
		if (!ptr)
			return;

		OGRE_LOCK_AUTO_MUTEX

		AllocationMap::iterator i = mAllocations.find(ptr);
		assert(i != mAllocations.end() && "Unable to locate allocation unit - "
			"this probably means you have a mismatched allocation / deallocation style, "
			"check if you're are using OGRE_ALLOC_T / OGRE_FREE and OGRE_NEW_T / OGRE_DELETE_T consistently");
		// update category stats
		mAllocationsByPool[i->second.pool] -= i->second.bytes;
		// global stats
		mTotalAllocations -= i->second.bytes;
		mAllocations.erase(i);
	}
	//--------------------------------------------------------------------------
	size_t MemoryTracker::getTotalMemoryAllocated() const
	{
		return mTotalAllocations;
	}
	//--------------------------------------------------------------------------
	size_t MemoryTracker::getMemoryAllocatedForPool(unsigned int pool) const
	{
		return mAllocationsByPool[pool];
	}
	//--------------------------------------------------------------------------
	void MemoryTracker::reportLeaks()
	{
		StringUtil::StrStreamType os;

		if (mAllocations.empty())
		{
			os << "Ogre Memory: No memory leaks" << std::endl;
		}
		else
		{
			os << "Ogre Memory: Detected memory leaks !!! " << std::endl;
			os << "Ogre Memory: (" << mAllocations.size() << ") Allocation(s) with total " << mTotalAllocations << " bytes." << std::endl;
			os << "Ogre Memory: Dumping allocations -> " << std::endl;

			for (AllocationMap::const_iterator i = mAllocations.begin(); i != mAllocations.end(); ++i)
			{
				const Alloc& alloc = i->second;
				if (!alloc.filename.empty())
					os << alloc.filename;
				else
					os << "(unknown source):";

				os << "(" << alloc.line << ") : {" << alloc.bytes << " bytes}" << " function: " << alloc.function << std::endl;

			}
			os << std::endl;
		}

		if (mDumpToStdOut)
			std::cout << os.str();

		std::cout << os.str();
		std::ofstream of;
		of.open(mLeakFileName.c_str());
		of << os.str();
		of.close();

		Ogre_OutputCString(os.str().c_str());
	}
#endif // OGRE_DEBUG_MODE

}

<|endoftext|>


<commit_before>// $Id$
/// @author Andrew Olson <olson at cshl.edu>
/// @file
/// A simple test program for adaptive 2D histogram function.
///
#include <ibis.h>
#include <set>		// std::set
#include <iomanip>	// std::setprecision
#include <algorithm>

// printout the usage string
static void usage(const char* name) {
	std::cout << "usage:\n" << name
	      << "[-d directory containing a dataset]\n"
	      << "[-c1 column 1]\n"
	      << "[-c2 column 2]\n"
         << "[-b1 bins for c1]\n"
         << "[-b2 bins for c2]\n"
			<< "[-f fudge factor (default: 1.0)]\n"
			<< "[-m maxbins cutoff (default: 10000)]\n"
			<< "[-n1 min for c1]\n"
			<< "[-n2 min for c2]\n"
			<< "[-x1 max for c1]\n"
			<< "[-x2 max for c2]\n"
	      << "[-w where-clause]\n"
	      << std::endl;
} // usage

// function to parse the command line arguments
//parse_args(argc, argv, tbl, &nbins1, &nbins2, col1, col2, qcnd, &fudge, &maxbins, &umin1, &umax1, &umin2, &umax2);
static void parse_args(int argc, char** argv, ibis::table*& tbl,
	int* nbins1, int* nbins2, const char*& col1, const char*& col2, const char*& qcnd,
	double* fudge, int* maxbins, double* umin1, double* umax1, double* umin2, double* umax2) {

   std::vector<const char*> dirs;

	for (int i=1; i<argc; ++i) {
		if (*argv[i] == '-') { // normal arguments starting with -
			switch (argv[i][1]) {
	    		default:
	    		case 'h':
	    		case 'H':
					usage(*argv);
					exit(0);
	    		case 'd':
	    		case 'D':
					if (i+1 < argc) {
		    			++ i;
		    			dirs.push_back(argv[i]);
					}
					break;
				case 'f':
					if (i+1 < argc) {
						++ i;
						*fudge = atof(argv[i]);
					}
					break;
				case 'm':
					if (i+1 < argc) {
						++ i;
						*maxbins = atoi(argv[i]);
					}
					break;
	    		case 'b':
					if (i+1 < argc) {
	    				if(argv[i][2] == '1') {
							++ i;
							*nbins1 = atoi(argv[i]);
	    				} else {
							++ i;
							*nbins2 = atoi(argv[i]);
	    				}
					}
					break;
	    		case 'c':
					if (i+1 < argc) {
		    			if(argv[i][2] == '1') {
							++ i;
							col1 = argv[i];
		    			} else {
							++ i;
							col2 = argv[i];
		    			}
					}
					break;
	    		case 'n':
					if (i+1 < argc) {
			    		if(argv[i][2] == '1') {
							++ i;
							*umin1 = atof(argv[i]);
			    		} else {
							++ i;
							*umin2 = atof(argv[i]);
			    		}
					}
					break;
			    case 'x':
					if (i+1 < argc) {
						if(argv[i][2] == '1') {
							++ i;
							*umax1 = atof(argv[i]);
						} else {
							++ i;
							*umax2 = atof(argv[i]);
						}
					}
					break;
	    		case 'q':
	    		case 'Q':
	    		case 'w':
	    		case 'W':
					if (i+1 < argc) {
		    			++ i;
		    			qcnd = argv[i];
					}
					break;
			} // switch (argv[i][1])
		} // normal arguments
	} // for (inti=1; ...)

   tbl = ibis::table::create(0);
   // add data partitions from explicitly specified directories
   for (std::vector<const char*>::const_iterator it = dirs.begin();
	 	it != dirs.end(); ++ it) {
		if (tbl != 0)
	   		tbl->addPartition(*it);
		else
	   		tbl = ibis::table::create(*it);
   }
   if (tbl == 0) {
		usage(argv[0]);
		exit(-2);
   }
} // parse_args

int first = 1;
double epsilon = 0.000001;

static void get2DDist(const ibis::part*& part, const char *col1, double min1, double max1, int nb1,
 	const char *col2, double min2, double max2, int nb2, const char *qcnd, uint32_t cutoff) {

	char combined_cond[200]="";
	if (qcnd == 0 || *qcnd == 0)
		sprintf(combined_cond, "1=1");
	else
		sprintf(combined_cond, "%s", qcnd);

//	printf("\n\nget2DDist(%s, %s, %f, %f, %d, %s, %f, %f, %d, %s, %d)\n\n", part->name(), col1, min1, max1, nb1, col2, min2, max2, nb2, qcnd, cutoff);

	double stride1 = ibis::util::incrDouble((max1-min1)/nb1);
	double stride2 = ibis::util::incrDouble((max2-min2)/nb2);
   std::vector<uint32_t> cnts;
	long ierr = part->get2DDistribution(combined_cond,
		col1, min1, max1, stride1,
		col2, min2, max2, stride2,
		cnts);
   if (ierr < 0) {
		std::cerr << "Warning -- part[" << part->name()
			       << "].get2DDistribution returned with ierr = " << ierr << std::endl
					<< "cnts.size() = " << cnts.size() << std::endl;
		exit(-1);
	}
//	printf("min1 %f, max1 %f, stride1 %f\n",min1,max1,stride1);
//	printf("min2 %f, max2 %f, stride2 %f\n",min2,max2,stride2);
//	printf("nb1 %d, nb2 %d, cnts.size() %d\n",nb1,nb2,cnts.size());
	// success

	const char* fmt_int = "%1.0f";
	const char* fmt_float = "%f";
	const char* f1;
	const char* f2;

	// lookup type of col1 and type of col2
	switch (part->getColumn(col1)->type()) {
		case ibis::FLOAT:
		case ibis::DOUBLE: {
			f1 = fmt_float;
			break;
		}
		default: {
			f1 = fmt_int;
			break;
		}
	}
	switch (part->getColumn(col2)->type()) {
		case ibis::FLOAT:
		case ibis::DOUBLE: {
			f2 = fmt_float;
			break;
		}
		default: {
			f2 = fmt_int;
			break;
		}
	}

	for (uint32_t i = 0; i < cnts.size(); ++ i) {
		if (cnts[i] > 0) {

			// i == nb2 * i1 + i2

			uint32_t i1 = i / nb2;
			uint32_t i2 = i % nb2;
			double bmin1 = i1*stride1 + min1;
			double bmax1 = bmin1 + stride1;
			double bmin2 = i2*stride2 + min2;
			double bmax2 = bmin2 + stride2;
			if (cnts[i] < cutoff) {
				// call it again with modified min1,max1,min2,max2
				get2DDist(part,col1,bmin1,bmax1,nb1,col2,bmin2,bmax2,nb2,qcnd,0);
			} else {
				if (!first){
					printf(",");
				} else {
					first = 0;
				}
				printf("[");//%d,%d,%d,",i,i1,i2);
				printf(f1,bmin1);printf(",");
				printf(f1,bmax1);printf(",");
				printf(f2,bmin2);printf(",");
				printf(f2,bmax2);
				printf(",%d,0]\n",cnts[i]);
			}
		}
	}
}

double get_val(ibis::table::cursor*& cur, uint32_t offset, ibis::table::typeList tps) {
	double one = 1.0;
	uint32_t ierr;
	switch (tps[offset]) {
		case ibis::BYTE: {
			char val;
			ierr = cur->getColumnAsByte(offset, val);
			return val*one;
		}
		case ibis::UBYTE: {
			unsigned char val;
			ierr = cur->getColumnAsUByte(offset, val);
			return val*one;
		}
		case ibis::SHORT: {
			int16_t val;
			ierr = cur->getColumnAsShort(offset, val);
			return val*one;
		}
		case ibis::USHORT: {
			uint16_t val;
			ierr = cur->getColumnAsUShort(offset, val);
			return val*one;
		}
		case ibis::INT: {
			int32_t val;
			ierr = cur->getColumnAsInt(offset, val);
			return val*one;
		}
		case ibis::UINT: {
			uint32_t val;
			ierr = cur->getColumnAsUInt(offset, val);
			return val*one;
		}
		case ibis::LONG: {
			int64_t val;
			ierr = cur->getColumnAsLong(offset, val);
			return val*one;
		}
		case ibis::ULONG: {
			uint64_t val;
			ierr = cur->getColumnAsULong(offset, val);
			return val*one;
		}
		case ibis::FLOAT: {
			float val;
			ierr = cur->getColumnAsFloat(offset, val);
			return val*one;
		}
		case ibis::DOUBLE: {
			double val;
			ierr = cur->getColumnAsDouble(offset, val);
			return val*one;
		}
		default: break;
	}
	return 0;
}

void get_data(ibis::table* tbl, uint32_t *tally, double *area, double *min1, double *max1, double *min2, double *max2) {
	ibis::table::cursor *cur = tbl->createCursor();
	if (cur == 0) return;
	uint32_t ierr;
	ierr = cur->fetch();

	ibis::table::typeList tps = tbl->columnTypes();

	*min1 = get_val(cur,0,tps);
	*max1 = get_val(cur,1,tps);
	*min2 = get_val(cur,2,tps);
	*max2 = get_val(cur,3,tps);
	*area = (*max1-*min1)*(*max2-*min2);
	ierr = cur->getColumnAsUInt(4,*tally);
	delete cur;
}

int main(int argc, char** argv) {
	ibis::table* tbl=0;
   const char* qcnd=0;
   const char* col1;
   const char* col2;
   int nbins1=25;
	int nbins2=25;
	int maxbins = 10000;
	double fudge = 1.0;
	double umin1,umax1,umin2,umax2;
	double uninitialized = -9.473829456;
	umin1 = uninitialized;
	umax1 = uninitialized;
	umin2 = uninitialized;
	umax2 = uninitialized;
   parse_args(argc, argv, tbl, &nbins1, &nbins2, col1, col2, qcnd, &fudge, &maxbins, &umin1, &umax1, &umin2, &umax2);

	char selstr[100];
	sprintf(selstr,"min(%s),max(%s),min(%s),max(%s)",col1,col1,col2,col2);
	ibis::table *sel;
	if (qcnd == 0 || *qcnd == 0)
		sel = tbl->select(selstr,"1=1");
	else
		sel = tbl->select(selstr,qcnd);

	uint32_t tally;
	double area, min1, max1, min2, max2;
	get_data(sel,&tally,&area,&min1,&max1,&min2,&max2);
	if (umin1 != uninitialized) min1 = umin1;
	if (umax1 != uninitialized) max1 = umax1;
	if (umin2 != uninitialized) min2 = umin2;
	if (umax2 != uninitialized) max2 = umax2;

	delete sel;

//	printf("Content-type: application/json\n\n");
	printf("{\"c1\":\"%s\",\"min1\":%f,\"max1\":%f,",col1,min1,max1);
	printf("\"c2\":\"%s\",\"min2\":%f,\"max2\":%f,",col1,min1,max1);
	printf("\"total\":%d,\"data\":[\n",tally);

	std::vector<const ibis::part*> parts;
	tbl->getPartitions(parts);

	int nbins = nbins1*nbins2;
	if (nbins > maxbins) {
		int nb1 = ceil(sqrt(nbins1));
		int nb2 = ceil(sqrt(nbins2));
		int cutoff = ceil(fudge*tally/(nb1*nb2));
		get2DDist(parts[0],col1,min1,max1,nb1,col2,min2,max2,nb2,qcnd,cutoff);
	} else {
		get2DDist(parts[0],col1,min1,max1,nbins1,col2,min2,max2,nbins2,qcnd,0);
	}
	printf("]}\n");

	delete tbl;
   return 0;
} // main
<commit_msg>progressive refinement<commit_after>// $Id$
/// @author Andrew Olson <olson at cshl.edu>
/// @file
/// A simple test program for adaptive 2D histogram function.
///
#include <ibis.h>
#include <set>		// std::set
#include <iomanip>	// std::setprecision
#include <algorithm>
double fudge = 1.0;

// printout the usage string
static void usage(const char* name) {
	std::cout << "usage:\n" << name
	      << "[-d directory containing a dataset]\n"
	      << "[-c1 column 1]\n"
	      << "[-c2 column 2]\n"
         << "[-b1 bins for c1]\n"
         << "[-b2 bins for c2]\n"
			<< "[-f fudge factor (default: 1.0)]\n"
			<< "[-m maxbins cutoff (default: 10000)]\n"
			<< "[-n1 min for c1]\n"
			<< "[-n2 min for c2]\n"
			<< "[-x1 max for c1]\n"
			<< "[-x2 max for c2]\n"
	      << "[-w where-clause]\n"
	      << std::endl;
} // usage

// function to parse the command line arguments
//parse_args(argc, argv, tbl, &nbins1, &nbins2, col1, col2, qcnd, &fudge, &maxbins, &umin1, &umax1, &umin2, &umax2);
static void parse_args(int argc, char** argv, ibis::table*& tbl,
	int* nbins1, int* nbins2, const char*& col1, const char*& col2, const char*& qcnd,
	double* fudge, int* maxbins, double* umin1, double* umax1, double* umin2, double* umax2) {

   std::vector<const char*> dirs;

	for (int i=1; i<argc; ++i) {
		if (*argv[i] == '-') { // normal arguments starting with -
			switch (argv[i][1]) {
	    		default:
	    		case 'h':
	    		case 'H':
					usage(*argv);
					exit(0);
	    		case 'd':
	    		case 'D':
					if (i+1 < argc) {
		    			++ i;
		    			dirs.push_back(argv[i]);
					}
					break;
				case 'f':
					if (i+1 < argc) {
						++ i;
						*fudge = atof(argv[i]);
					}
					break;
				case 'm':
					if (i+1 < argc) {
						++ i;
						*maxbins = atoi(argv[i]);
					}
					break;
	    		case 'b':
					if (i+1 < argc) {
	    				if(argv[i][2] == '1') {
							++ i;
							*nbins1 = atoi(argv[i]);
	    				} else {
							++ i;
							*nbins2 = atoi(argv[i]);
	    				}
					}
					break;
	    		case 'c':
					if (i+1 < argc) {
		    			if(argv[i][2] == '1') {
							++ i;
							col1 = argv[i];
		    			} else {
							++ i;
							col2 = argv[i];
		    			}
					}
					break;
	    		case 'n':
					if (i+1 < argc) {
			    		if(argv[i][2] == '1') {
							++ i;
							*umin1 = atof(argv[i]);
			    		} else {
							++ i;
							*umin2 = atof(argv[i]);
			    		}
					}
					break;
			    case 'x':
					if (i+1 < argc) {
						if(argv[i][2] == '1') {
							++ i;
							*umax1 = atof(argv[i]);
						} else {
							++ i;
							*umax2 = atof(argv[i]);
						}
					}
					break;
	    		case 'q':
	    		case 'Q':
	    		case 'w':
	    		case 'W':
					if (i+1 < argc) {
		    			++ i;
		    			qcnd = argv[i];
					}
					break;
			} // switch (argv[i][1])
		} // normal arguments
	} // for (inti=1; ...)

   tbl = ibis::table::create(0);
   // add data partitions from explicitly specified directories
   for (std::vector<const char*>::const_iterator it = dirs.begin();
	 	it != dirs.end(); ++ it) {
		if (tbl != 0)
	   		tbl->addPartition(*it);
		else
	   		tbl = ibis::table::create(*it);
   }
   if (tbl == 0) {
		usage(argv[0]);
		exit(-2);
   }
} // parse_args

int first = 1;

static void get2DDist(const ibis::part*& part, const char *col1, double min1, double max1, int nb1, int iter1,
 	const char *col2, double min2, double max2, int nb2, int iter2, const char *qcnd, uint32_t cutoff) {

	char combined_cond[200]="";
	if (qcnd == 0 || *qcnd == 0)
		sprintf(combined_cond, "1=1");
	else
		sprintf(combined_cond, "%s", qcnd);

//	printf("\n\nget2DDist(%s, %s, %f, %f, %d, %s, %f, %f, %d, %s, %d)\n\n", part->name(), col1, min1, max1, nb1, col2, min2, max2, nb2, qcnd, cutoff);

	double stride1 = ibis::util::incrDouble((max1-min1)/nb1);
	double stride2 = ibis::util::incrDouble((max2-min2)/nb2);
   std::vector<uint32_t> cnts;
	long ierr = part->get2DDistribution(combined_cond,
		col1, min1, max1, stride1,
		col2, min2, max2, stride2,
		cnts);
   if (ierr < 0) {
		std::cerr << "Warning -- part[" << part->name()
			       << "].get2DDistribution returned with ierr = " << ierr << std::endl
					<< "cnts.size() = " << cnts.size() << std::endl;
		exit(-1);
	}
//	printf("min1 %f, max1 %f, stride1 %f\n",min1,max1,stride1);
//	printf("min2 %f, max2 %f, stride2 %f\n",min2,max2,stride2);
//	printf("nb1 %d, nb2 %d, cnts.size() %d\n",nb1,nb2,cnts.size());
	// success

	const char* fmt_int = "%1.0f";
	const char* fmt_float = "%f";
	const char* f1;
	const char* f2;

	// lookup type of col1 and type of col2
	switch (part->getColumn(col1)->type()) {
		case ibis::FLOAT:
		case ibis::DOUBLE: {
			f1 = fmt_float;
			break;
		}
		default: {
			f1 = fmt_int;
			break;
		}
	}
	switch (part->getColumn(col2)->type()) {
		case ibis::FLOAT:
		case ibis::DOUBLE: {
			f2 = fmt_float;
			break;
		}
		default: {
			f2 = fmt_int;
			break;
		}
	}

	for (uint32_t i = 0; i < cnts.size(); ++ i) {
		if (cnts[i] > 0) {

			// i == nb2 * i1 + i2

			uint32_t i1 = i / nb2;
			uint32_t i2 = i % nb2;
			double bmin1 = i1*stride1 + min1;
			double bmax1 = bmin1 + stride1;
			double bmin2 = i2*stride2 + min2;
			double bmax2 = bmin2 + stride2;
			if (cnts[i] < cutoff && (iter1 > 0 || iter2 > 0)) {
				// call it again with modified min1,max1,min2,max2
				if (iter1 > 0) {
					-- iter1;
				}
				else {
					nb1=1;
				}
				if (iter2 > 0) {
					-- iter2;
				}
				else {
					nb2=1;
				}
				int newcutoff = ceil(fudge*cnts[i]/(nb1*nb2));
				get2DDist(part,col1,bmin1,bmax1,nb1,iter1,
								   col2,bmin2,bmax2,nb2,iter2,qcnd,newcutoff);
			} else {
				if (!first){
					printf(",");
				} else {
					first = 0;
				}
				printf("[");//%d,%d,%d,",i,i1,i2);
				printf(f1,bmin1);printf(",");
				printf(f1,bmax1);printf(",");
				printf(f2,bmin2);printf(",");
				printf(f2,bmax2);
				printf(",%d,%d]\n",cnts[i],iter1+iter2);
			}
		}
	}
}

double get_val(ibis::table::cursor*& cur, uint32_t offset, ibis::table::typeList tps) {
	double one = 1.0;
	uint32_t ierr;
	switch (tps[offset]) {
		case ibis::BYTE: {
			char val;
			ierr = cur->getColumnAsByte(offset, val);
			return val*one;
		}
		case ibis::UBYTE: {
			unsigned char val;
			ierr = cur->getColumnAsUByte(offset, val);
			return val*one;
		}
		case ibis::SHORT: {
			int16_t val;
			ierr = cur->getColumnAsShort(offset, val);
			return val*one;
		}
		case ibis::USHORT: {
			uint16_t val;
			ierr = cur->getColumnAsUShort(offset, val);
			return val*one;
		}
		case ibis::INT: {
			int32_t val;
			ierr = cur->getColumnAsInt(offset, val);
			return val*one;
		}
		case ibis::UINT: {
			uint32_t val;
			ierr = cur->getColumnAsUInt(offset, val);
			return val*one;
		}
		case ibis::LONG: {
			int64_t val;
			ierr = cur->getColumnAsLong(offset, val);
			return val*one;
		}
		case ibis::ULONG: {
			uint64_t val;
			ierr = cur->getColumnAsULong(offset, val);
			return val*one;
		}
		case ibis::FLOAT: {
			float val;
			ierr = cur->getColumnAsFloat(offset, val);
			return val*one;
		}
		case ibis::DOUBLE: {
			double val;
			ierr = cur->getColumnAsDouble(offset, val);
			return val*one;
		}
		default: break;
	}
	return 0;
}

void get_data(ibis::table* tbl, uint32_t *tally, double *area, double *min1, double *max1, double *min2, double *max2) {
	ibis::table::cursor *cur = tbl->createCursor();
	if (cur == 0) return;
	uint32_t ierr;
	ierr = cur->fetch();

	ibis::table::typeList tps = tbl->columnTypes();

	*min1 = get_val(cur,0,tps);
	*max1 = get_val(cur,1,tps);
	*min2 = get_val(cur,2,tps);
	*max2 = get_val(cur,3,tps);
	*area = (*max1-*min1)*(*max2-*min2);
	ierr = cur->getColumnAsUInt(4,*tally);
	delete cur;
}

int main(int argc, char** argv) {
	ibis::table* tbl=0;
   const char* qcnd=0;
   const char* col1;
   const char* col2;
   int nbins1=25;
	int nbins2=25;
	int minbins = 5;
	double umin1,umax1,umin2,umax2;
	double uninitialized = -9.473829456;
	umin1 = uninitialized;
	umax1 = uninitialized;
	umin2 = uninitialized;
	umax2 = uninitialized;
   parse_args(argc, argv, tbl, &nbins1, &nbins2, col1, col2, qcnd, &fudge, &minbins, &umin1, &umax1, &umin2, &umax2);

	char selstr[100];
	sprintf(selstr,"min(%s),max(%s),min(%s),max(%s)",col1,col1,col2,col2);
	ibis::table *sel;
	if (qcnd == 0 || *qcnd == 0)
		sel = tbl->select(selstr,"1=1");
	else
		sel = tbl->select(selstr,qcnd);

	uint32_t tally;
	double area, min1, max1, min2, max2;
	get_data(sel,&tally,&area,&min1,&max1,&min2,&max2);
	if (umin1 != uninitialized) min1 = umin1;
	if (umax1 != uninitialized) max1 = umax1;
	if (umin2 != uninitialized) min2 = umin2;
	if (umax2 != uninitialized) max2 = umax2;

	delete sel;

//	printf("Content-type: application/json\n\n");
	printf("{\"c1\":\"%s\",\"min1\":%f,\"max1\":%f,",col1,min1,max1);
	printf("\"c2\":\"%s\",\"min2\":%f,\"max2\":%f,",col2,min2,max2);
	printf("\"total\":%d,\"data\":[\n",tally);

	std::vector<const ibis::part*> parts;
	tbl->getPartitions(parts);

	double scale1 = log(nbins1)/log(minbins);
	int iter1 = 0;
	if (scale1 > 1) {
		nbins1 = ceil(scale1);
		iter1 = floor(scale1);
	}
	double scale2 = log(nbins2)/log(minbins);
	int iter2 = 0;
	if (scale2 > 1) {
		nbins2 = ceil(scale2);
		iter2 = floor(scale2);
	}
	int cutoff = ceil(fudge*tally/(nbins1*nbins2));
	get2DDist(parts[0],col1,min1,max1,nbins1,iter1,
		                col2,min2,max2,nbins2,iter2,qcnd,cutoff);
	printf("]}\n");

	delete tbl;
   return 0;
} // main
<|endoftext|>


<commit_before>// Copyright (c) 2010-2021, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#ifndef MFEM_RESTRICTION
#define MFEM_RESTRICTION

#include "../linalg/operator.hpp"
#include "../mesh/mesh.hpp"

namespace mfem
{

class FiniteElementSpace;
enum class ElementDofOrdering;

/// Operator that converts FiniteElementSpace L-vectors to E-vectors.
/** Objects of this type are typically created and owned by FiniteElementSpace
    objects, see FiniteElementSpace::GetElementRestriction(). */
class ElementRestriction : public Operator
{
private:
   /** This number defines the maximum number of elements any dof can belong to
       for the FillSparseMatrix method. */
   static const int MaxNbNbr = 16;

protected:
   const FiniteElementSpace &fes;
   const int ne;
   const int vdim;
   const bool byvdim;
   const int ndofs;
   const int dof;
   const int nedofs;
   Array<int> offsets;
   Array<int> indices;
   Array<int> gatherMap;

public:
   ElementRestriction(const FiniteElementSpace&, ElementDofOrdering);
   void Mult(const Vector &x, Vector &y) const;
   void MultTranspose(const Vector &x, Vector &y) const;

   /// Compute Mult without applying signs based on DOF orientations.
   void MultUnsigned(const Vector &x, Vector &y) const;
   /// Compute MultTranspose without applying signs based on DOF orientations.
   void MultTransposeUnsigned(const Vector &x, Vector &y) const;

   /// Compute MultTranspose by setting (rather than adding) element
   /// contributions; this is a left inverse of the Mult() operation
   void MultLeftInverse(const Vector &x, Vector &y) const;

   /// @brief Fills the E-vector y with `boolean` values 0.0 and 1.0 such that each
   /// each entry of the L-vector is uniquely represented in `y`.
   /** This means, the sum of the E-vector `y` is equal to the sum of the
       corresponding L-vector filled with ones. The boolean mask is required to
       emulate SetSubVector and its transpose on GPUs. This method is running on
       the host, since the `processed` array requires a large shared memory. */
   void BooleanMask(Vector& y) const;

   /// Fill a Sparse Matrix with Element Matrices.
   void FillSparseMatrix(const Vector &mat_ea, SparseMatrix &mat) const;

   /** Fill the I array of SparseMatrix corresponding to the sparsity pattern
       given by this ElementRestriction. */
   int FillI(SparseMatrix &mat) const;
   /** Fill the J and Data arrays of SparseMatrix corresponding to the sparsity
       pattern given by this ElementRestriction, and the values of ea_data. */
   void FillJAndData(const Vector &ea_data, SparseMatrix &mat) const;
};

/// Operator that converts L2 FiniteElementSpace L-vectors to E-vectors.
/** Objects of this type are typically created and owned by FiniteElementSpace
    objects, see FiniteElementSpace::GetElementRestriction(). L-vectors
    corresponding to grid functions in L2 finite element spaces differ from
    E-vectors only in the ordering of the degrees of freedom. */
class L2ElementRestriction : public Operator
{
   const int ne;
   const int vdim;
   const bool byvdim;
   const int ndof;
   const int ndofs;
public:
   L2ElementRestriction(const FiniteElementSpace&);
   void Mult(const Vector &x, Vector &y) const;
   void MultTranspose(const Vector &x, Vector &y) const;
   /** Fill the I array of SparseMatrix corresponding to the sparsity pattern
       given by this ElementRestriction. */
   void FillI(SparseMatrix &mat) const;
   /** Fill the J and Data arrays of SparseMatrix corresponding to the sparsity
       pattern given by this L2FaceRestriction, and the values of ea_data. */
   void FillJAndData(const Vector &ea_data, SparseMatrix &mat) const;
};

/// Base class for operators that extracts Face degrees of freedom.
/** Objects of this type are typically created and owned by FiniteElementSpace
    objects, see FiniteElementSpace::GetFaceRestriction(). */
class FaceRestriction
{
protected:
   int height;
   int width;
public:

   FaceRestriction(): height(0), width(0) { }

   FaceRestriction(int h, int w): height(h), width(w) { }

   virtual ~FaceRestriction() { }

   /** Extract the face degrees of freedom from @a x. */
   virtual void Mult(const Vector &x, Vector &y) const = 0;

   /** Add face degrees of freedom @a x to the element degrees of freedom @a y.*/
   virtual void AddMultTranspose(const Vector &x, Vector &y) const = 0;

   int Height() const { return height; }

   int Width() const { return width; }
};

/// Operator that extracts Face degrees of freedom.
/** Objects of this type are typically created and owned by FiniteElementSpace
    objects, see FiniteElementSpace::GetFaceRestriction(). */
class H1FaceRestriction : public FaceRestriction
{
protected:
   const FiniteElementSpace &fes;
   const int nf;
   const int vdim;
   const bool byvdim;
   const int ndofs;
   const int dof;
   const int nfdofs;
   Array<int> scatter_indices;
   Array<int> offsets;
   Array<int> gather_indices;

public:
   H1FaceRestriction(const FiniteElementSpace&, const ElementDofOrdering,
                     const FaceType);
   /** Extract the face degrees of freedom from @a x. */
   void Mult(const Vector &x, Vector &y) const override;
   /** Add face degrees of freedom @a x to the element degrees of freedom @a y.*/
   void AddMultTranspose(const Vector &x, Vector &y) const override;
};

/** An enum type to specify if only e1 value is requested (SingleValued) or both
    e1 and e2 (DoubleValued). */
enum class L2FaceValues : bool {SingleValued, DoubleValued};

/// Operator that extracts Face degrees of freedom.
/** Objects of this type are typically created and owned by FiniteElementSpace
    objects, see FiniteElementSpace::GetFaceRestriction(). */
class L2FaceRestriction : public FaceRestriction
{
protected:
   const FiniteElementSpace &fes;
   const int nf;
   const int ne;
   const int vdim;
   const bool byvdim;
   const int ndofs;
   const int dof;
   const int elemDofs;
   const L2FaceValues m;
   const int nfdofs;
   Array<int> scatter_indices1;
   Array<int> scatter_indices2;
   Array<int> offsets;
   Array<int> gather_indices;

   L2FaceRestriction(const FiniteElementSpace&,
                     const FaceType,
                     const L2FaceValues m = L2FaceValues::DoubleValued);

public:
   L2FaceRestriction(const FiniteElementSpace&, const ElementDofOrdering,
                     const FaceType,
                     const L2FaceValues m = L2FaceValues::DoubleValued);
   void Mult(const Vector &x, Vector &y) const override;
   void AddMultTranspose(const Vector &x, Vector &y) const override;
   /** Fill the I array of SparseMatrix corresponding to the sparsity pattern
       given by this L2FaceRestriction. */
   virtual void FillI(SparseMatrix &mat, const bool keep_nbr_block = false) const;
   /** Fill the J and Data arrays of SparseMatrix corresponding to the sparsity
       pattern given by this L2FaceRestriction, and the values of ea_data. */
   virtual void FillJAndData(const Vector &ea_data,
                             SparseMatrix &mat,
                             const bool keep_nbr_block = false) const;
   /// This methods adds the DG face matrices to the element matrices.
   void AddFaceMatricesToElementMatrices(Vector &fea_data,
                                         Vector &ea_data) const;
};

// Return the face degrees of freedom returned in Lexicographic order.
void GetFaceDofs(const int dim, const int face_id,
                 const int dof1d, Array<int> &faceMap);

// Convert from Native ordering to lexicographic ordering
int ToLexOrdering(const int dim, const int face_id, const int size1d,
                  const int index);

// Permute dofs or quads on a face for e2 to match with the ordering of e1
int PermuteFaceL2(const int dim, const int face_id1,
                  const int face_id2, const int orientation,
                  const int size1d, const int index);

}

#endif //MFEM_RESTRICTION
<commit_msg>Add some documentation.<commit_after>// Copyright (c) 2010-2021, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#ifndef MFEM_RESTRICTION
#define MFEM_RESTRICTION

#include "../linalg/operator.hpp"
#include "../mesh/mesh.hpp"

namespace mfem
{

class FiniteElementSpace;
enum class ElementDofOrdering;

/// Operator that converts FiniteElementSpace L-vectors to E-vectors.
/** Objects of this type are typically created and owned by FiniteElementSpace
    objects, see FiniteElementSpace::GetElementRestriction(). */
class ElementRestriction : public Operator
{
private:
   /** This number defines the maximum number of elements any dof can belong to
       for the FillSparseMatrix method. */
   static const int MaxNbNbr = 16;

protected:
   const FiniteElementSpace &fes;
   const int ne;
   const int vdim;
   const bool byvdim;
   const int ndofs;
   const int dof;
   const int nedofs;
   Array<int> offsets;
   Array<int> indices;
   Array<int> gatherMap;

public:
   ElementRestriction(const FiniteElementSpace&, ElementDofOrdering);
   void Mult(const Vector &x, Vector &y) const;
   void MultTranspose(const Vector &x, Vector &y) const;

   /// Compute Mult without applying signs based on DOF orientations.
   void MultUnsigned(const Vector &x, Vector &y) const;
   /// Compute MultTranspose without applying signs based on DOF orientations.
   void MultTransposeUnsigned(const Vector &x, Vector &y) const;

   /// Compute MultTranspose by setting (rather than adding) element
   /// contributions; this is a left inverse of the Mult() operation
   void MultLeftInverse(const Vector &x, Vector &y) const;

   /// @brief Fills the E-vector y with `boolean` values 0.0 and 1.0 such that each
   /// each entry of the L-vector is uniquely represented in `y`.
   /** This means, the sum of the E-vector `y` is equal to the sum of the
       corresponding L-vector filled with ones. The boolean mask is required to
       emulate SetSubVector and its transpose on GPUs. This method is running on
       the host, since the `processed` array requires a large shared memory. */
   void BooleanMask(Vector& y) const;

   /// Fill a Sparse Matrix with Element Matrices.
   void FillSparseMatrix(const Vector &mat_ea, SparseMatrix &mat) const;

   /** Fill the I array of SparseMatrix corresponding to the sparsity pattern
       given by this ElementRestriction. */
   int FillI(SparseMatrix &mat) const;
   /** Fill the J and Data arrays of SparseMatrix corresponding to the sparsity
       pattern given by this ElementRestriction, and the values of ea_data. */
   void FillJAndData(const Vector &ea_data, SparseMatrix &mat) const;
};

/// Operator that converts L2 FiniteElementSpace L-vectors to E-vectors.
/** Objects of this type are typically created and owned by FiniteElementSpace
    objects, see FiniteElementSpace::GetElementRestriction(). L-vectors
    corresponding to grid functions in L2 finite element spaces differ from
    E-vectors only in the ordering of the degrees of freedom. */
class L2ElementRestriction : public Operator
{
   const int ne;
   const int vdim;
   const bool byvdim;
   const int ndof;
   const int ndofs;
public:
   L2ElementRestriction(const FiniteElementSpace&);
   void Mult(const Vector &x, Vector &y) const;
   void MultTranspose(const Vector &x, Vector &y) const;
   /** Fill the I array of SparseMatrix corresponding to the sparsity pattern
       given by this ElementRestriction. */
   void FillI(SparseMatrix &mat) const;
   /** Fill the J and Data arrays of SparseMatrix corresponding to the sparsity
       pattern given by this L2FaceRestriction, and the values of ea_data. */
   void FillJAndData(const Vector &ea_data, SparseMatrix &mat) const;
};

/** An enum type to specify if only e1 value is requested (SingleValued) or both
    e1 and e2 (DoubleValued). */
enum class L2FaceValues : bool {SingleValued, DoubleValued};

/** @brief Base class for operators that extracts Face degrees of freedom.

    In order to compute quantities on the faces of a mesh, it is often useful to
    extract the degrees of freedom on the faces of the elements. This class
    provides an interface for such operations.

    If the FiniteElementSpace is ordered by Ordering::byVDIM, then the expected
    format for the L-vector is (vdim x ndofs), otherwise if Ordering::byNODES
    the expected format is (ndofs x vdim), where ndofs is the total number of
    degrees of freedom.
    Since FiniteElementSpace can either be continuous or discontinuous, the
    degrees of freedom on a face can either be single valued or double valued,
    this is what we refer to as the multiplicity and is represented by the
    L2FaceValues enum type.
    The format of the output face E-vector of degrees of freedom is
    (face_dofs x vdim x multiplicity x nfaces), where face_dofs is the number of
    degrees of freedom on each face, and nfaces the number of faces of the
    requested FaceType (see FiniteElementSpace::GetNFbyType).

    @note Objects of this type are typically created and owned by
    FiniteElementSpace objects, see FiniteElementSpace::GetFaceRestriction(). */
class FaceRestriction : public Operator
{
public:
   FaceRestriction(): Operator() { }

   FaceRestriction(int h, int w): Operator(h, w) { }

   virtual ~FaceRestriction() { }

   /** @brief Extract the face degrees of freedom from @a x into @a y.

       @param[in]  x The L-vector of degrees of freedom.
       @param[out] y The degrees of freedom on the face, corresponding to a face
                     E-vector.
   */
   void Mult(const Vector &x, Vector &y) const override = 0;

   /** @brief Add the face degrees of freedom @a x to the element degrees of
       freedom @a y.

       @param[in]     x The face degrees of freedom on the face.
       @param[in,out] y The L-vector of degrees of freedom to which we add the
                        face degrees of freedom.
   */
   virtual void AddMultTranspose(const Vector &x, Vector &y) const = 0;

   /** @brief Set the face degrees of freedom in the element degrees of freedom
       @a y to the values given in @a x.

       @param[in]     x The face degrees of freedom on the face.
       @param[in,out] y The L-vector of degrees of freedom to which we add the
                        face degrees of freedom.
   */
   void MultTranspose(const Vector &x, Vector &y) const override
   {
      y = 0.0;
      AddMultTranspose(x, y);
   }
};

/// Operator that extracts Face degrees of freedom for H1 FiniteElementSpaces.
/** Objects of this type are typically created and owned by FiniteElementSpace
    objects, see FiniteElementSpace::GetFaceRestriction(). */
class H1FaceRestriction : public FaceRestriction
{
protected:
   const FiniteElementSpace &fes;
   const int nf;
   const int vdim;
   const bool byvdim;
   const int ndofs;
   const int dof;
   const int nfdofs;
   Array<int> scatter_indices;
   Array<int> offsets;
   Array<int> gather_indices;

public:
   /** @brief Constructor for a H1FaceRestriction.

       @param[in] fes The FiniteElementSpace on which this H1FaceRestriction
                      operates.
       @param[in] ordering The requested output ordering of the
                           H1FaceRestriction, either Native or Lexicographic.
       @param[in] type The requested type of faces on which this operator
                       extracts the degrees of freedom, either Interior or
                       Boundary.
   */
   H1FaceRestriction(const FiniteElementSpace& fes,
                     const ElementDofOrdering ordering,
                     const FaceType type);

   /** @brief Extract the face degrees of freedom from @a x into @a y.

       @param[in]  x The L-vector of degrees of freedom.
       @param[out] y The degrees of freedom on the face, corresponding to a face
                     E-vector.
   */
   void Mult(const Vector &x, Vector &y) const override;

   /** @brief Add the face degrees of freedom @a x to the element degrees of
       freedom @a y.

       @param[in]     x The face degrees of freedom on the face.
       @param[in,out] y The L-vector of degrees of freedom to which we add the
                        face degrees of freedom.
   */
   void AddMultTranspose(const Vector &x, Vector &y) const override;
};

/// Operator that extracts Face degrees of freedom on L2 FiniteElementSpaces.
/** Objects of this type are typically created and owned by FiniteElementSpace
    objects, see FiniteElementSpace::GetFaceRestriction(). */
class L2FaceRestriction : public FaceRestriction
{
protected:
   const FiniteElementSpace &fes;
   const int nf;
   const int ne;
   const int vdim;
   const bool byvdim;
   const int ndofs;
   const int dof;
   const int elemDofs;
   const L2FaceValues m;
   const int nfdofs;
   Array<int> scatter_indices1;
   Array<int> scatter_indices2;
   Array<int> offsets;
   Array<int> gather_indices;

   L2FaceRestriction(const FiniteElementSpace&,
                     const FaceType,
                     const L2FaceValues m = L2FaceValues::DoubleValued);

public:
   L2FaceRestriction(const FiniteElementSpace&,
                     const ElementDofOrdering,
                     const FaceType,
                     const L2FaceValues m = L2FaceValues::DoubleValued);

   /** @brief Extract the face degrees of freedom from @a x into @a y.

       @param[in]  x The L-vector of degrees of freedom.
       @param[out] y The degrees of freedom on the face, corresponding to a face
                     E-vector.
   */
   void Mult(const Vector &x, Vector &y) const override;

   /** @brief Add the face degrees of freedom @a x to the element degrees of
       freedom @a y.

       @param[in]     x The face degrees of freedom on the face.
       @param[in,out] y The L-vector of degrees of freedom to which we add the
                        face degrees of freedom.
   */
   void AddMultTranspose(const Vector &x, Vector &y) const override;

   /** Fill the I array of SparseMatrix corresponding to the sparsity pattern
       given by this L2FaceRestriction. */
   virtual void FillI(SparseMatrix &mat, const bool keep_nbr_block = false) const;

   /** Fill the J and Data arrays of SparseMatrix corresponding to the sparsity
       pattern given by this L2FaceRestriction, and the values of ea_data. */
   virtual void FillJAndData(const Vector &ea_data,
                             SparseMatrix &mat,
                             const bool keep_nbr_block = false) const;

   /// This methods adds the DG face matrices to the element matrices.
   void AddFaceMatricesToElementMatrices(Vector &fea_data,
                                         Vector &ea_data) const;
};

// Return the face degrees of freedom returned in Lexicographic order.
void GetFaceDofs(const int dim, const int face_id,
                 const int dof1d, Array<int> &faceMap);

// Convert from Native ordering to lexicographic ordering
int ToLexOrdering(const int dim, const int face_id, const int size1d,
                  const int index);

// Permute dofs or quads on a face for e2 to match with the ordering of e1
int PermuteFaceL2(const int dim, const int face_id1,
                  const int face_id2, const int orientation,
                  const int size1d, const int index);

}

#endif //MFEM_RESTRICTION
<|endoftext|>


<commit_before>AliESDtrackCuts* CreateCuts(Bool_t fieldOn = kTRUE, Bool_t hists = kTRUE);

AliAnalysisTask* AddTaskFilteredTree(TString outputFile="")
{
  gSystem->Load("libANALYSIS");
  gSystem->Load("libANALYSISalice");
  gSystem->Load("libTender");
  gSystem->Load("libCORRFW");
  gSystem->Load("libPWGUDbase");
  gSystem->Load("libTPCcalib");
  gSystem->Load("libPWGPP");
  gSystem->Load("libPWGLFspectra");
  ::Info("AddTaskFilteredTree","BEGIN");
  printf("AddTaskFilteredTree::BEGIN\n");
  gRandom->SetSeed(0);

  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();

  if (!mgr) {
    Error("AddTaskFilteredTree", "No analysis manager found.");
    return 0;
  }

  // Switch off all AliInfo (too much output!!!)
  AliLog::SetClassDebugLevel("AliAnalysisTaskFilteredTree", AliLog::kError);

  //
  // Create physics trigger selection class
  //
  //AliPhysicsSelection *physTrigSel =  new AliPhysicsSelection();

  //
  // Create event cuts
  //
  Float_t zvWindow = 30. ;

  AliFilteredTreeEventCuts *evtCuts = new AliFilteredTreeEventCuts("AliFilteredTreeEventCuts","Event cuts");
  evtCuts->SetZvRange(-zvWindow,zvWindow);
  evtCuts->SetMeanXYZv(0.0,0.0,0.0);
  evtCuts->SetSigmaMeanXYZv(1.0,1.0,10.0);
  evtCuts->SetTriggerRequired(kFALSE);
  //evtCuts->SetTriggerRequired(kTRUE);

  //
  // Create geom. acceptance cuts
  //
  Float_t etaWindow = 1.0 ;
  Float_t ptMin = 0.15 ;

  AliFilteredTreeAcceptanceCuts *accCuts = new AliFilteredTreeAcceptanceCuts("AliFilteredTreeAcceptanceCuts","Geom. acceptance cuts");
  accCuts->SetEtaRange(-etaWindow,etaWindow);
  accCuts->SetPtRange(ptMin,1.e10);
  accCuts->SetMaxDCAr(3.0);
  accCuts->SetMaxDCAz(30.0);

  //
  // Create standard esd track cuts
  //

  AliESDtrackCuts* esdTrackCuts = CreateCuts();
  if (!esdTrackCuts) {
    printf("ERROR: esdTrackCuts could not be created\n");
    return 0;
  } else {
    esdTrackCuts->SetHistogramsOn(kTRUE);
  }
  Bool_t hasMC=(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()!=0x0);

  //
  // Create task
  //
  AliAnalysisTaskFilteredTree *task = new AliAnalysisTaskFilteredTree("AliAnalysisTaskFilteredTree");
  //task->SetUseMCInfo(hasMC);
  task->SetLowPtTrackDownscaligF(5.e3);
  task->SetLowPtV0DownscaligF(5.e2);
  //task->SetLowPtTrackDownscaligF(1.e5);
  //task->SetLowPtV0DownscaligF(2.e3);
  task->SetProcessAll(kTRUE);
  task->SetProcessCosmics(kTRUE);
  if (gSystem->Getenv("AliAnalysisTaskFilteredTree_SetLowPtTrackDownscalingF")) {
    Float_t downscale=TString(gSystem->Getenv("AliAnalysisTaskFilteredTree_SetLowPtTrackDownscalingF")).Atof();
    task->SetLowPtTrackDownscaligF(downscale);
    printf("AliAnalysisTaskFilteredTree_SetLowPtTrackDownscalingF: From env. variable\t%f\n", downscale);
  }else {
    ::Info("AliAnalysisTaskFilteredTree__SetLowPtTrackDownscalingF", "Use default");
    printf("AliAnalysisTaskFilteredTree_SetLowPtV0DownscalingF::Use DEFAULT\t\n");
  }
  if (gSystem->Getenv("AliAnalysisTaskFilteredTree_SetLowPtV0DownscalingF")) {
    Float_t downscale=TString(gSystem->Getenv("AliAnalysisTaskFilteredTree_SetLowPtV0DownscalingF")).Atof();
    task->SetLowPtV0DownscaligF(downscale);
    printf("AliAnalysisTaskFilteredTree_SetLowPtV0DownscalingF:From enc. variable\t%f\n",downscale);
  }else {
    printf("AliAnalysisTaskFilteredTree_SetLowPtV0DownscalingF::Use DEFAULT\t\n");
  }
  //task->Dump();
  //task->SetProcessAll(kFALSE);
  //task->SetFillTrees(kFALSE); // only histograms are filled

  // trigger
  //task->SelectCollisionCandidates(AliVEvent::kMB);

  //
  // set analysis options from the Helper here !!!
  //
  // AlidNdPtHelper::OutputObject outputObject = AlidNdPtHelper::kCutAnalysisPbPb;
  // AlidNdPtHelper::ParticleMode particleMode = AlidNdPtHelper::kAllPart ;
  //AlidNdPtHelper::AnalysisMode analysisMode = AlidNdPtHelper::kTPCITS;

  task->SetEventCuts(evtCuts);
  task->SetAcceptanceCuts(accCuts);
  task->SetTrackCuts(esdTrackCuts);
  task->SetAnalysisMode(AliAnalysisTaskFilteredTree::kTPCITSAnalysisMode);
  task->SetCentralityEstimator("V0M");

  // Add task
  mgr->AddTask(task);

  // Create containers for input
  AliAnalysisDataContainer *cinput = mgr->GetCommonInputContainer();
  mgr->ConnectInput(task, 0, cinput);

  if (outputFile.IsNull())
    outputFile=Form("%s", AliAnalysisManager::GetCommonFileName());

  AliAnalysisDataContainer *coutput1 = mgr->CreateContainer("filtered1", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 1, coutput1);
  AliAnalysisDataContainer *coutput2 = mgr->CreateContainer("filtered2", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 2, coutput2);
  AliAnalysisDataContainer *coutput3 = mgr->CreateContainer("filtered3", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 3, coutput3);
  AliAnalysisDataContainer *coutput4 = mgr->CreateContainer("filtered4", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 4, coutput4);
  AliAnalysisDataContainer *coutput5 = mgr->CreateContainer("filtered5", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 5, coutput5);
  AliAnalysisDataContainer *coutput6 = mgr->CreateContainer("filtered6", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 6, coutput6);

 // store histograms in the separate file
  TString outputFileHisto = "PtResHistograms.root";

  AliAnalysisDataContainer *coutput7 = mgr->CreateContainer("histo7", TList::Class(), AliAnalysisManager::kOutputContainer, outputFileHisto.Data());
  mgr->ConnectOutput(task, 7, coutput7);

   ::Info("AddTaskFilteredTree","END");
  printf("AddTaskFilteredTree::END\n");
  return task;
}

AliESDtrackCuts* CreateCuts(Bool_t fieldOn, Bool_t hists)
{
  AliESDtrackCuts* esdTrackCuts = new AliESDtrackCuts("AliESDtrackCuts");
  if(!esdTrackCuts) return 0;

  if (hists)
    esdTrackCuts->DefineHistograms(1);

  Double_t cov1, cov2, cov3, cov4, cov5;
  Double_t nSigma;
  Double_t maxDCAtoVertex, maxDCAtoVertexXY, maxDCAtoVertexZ;
  Double_t minNClustersTPC;
  Double_t maxChi2PerClusterTPC;
  Double_t minPt, maxPt;

  //
  // TPC
  //
  esdTrackCuts->SetRequireTPCRefit(kTRUE);
  esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
  //
  // ITS
  //
  //esdTrackCuts->SetRequireITSRefit(kTRUE);
  //esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
  //

  TString tag = "TPC+ITS refit and KinkRejection required - for cut studies";

  // cuts for data without field
  if (!fieldOn)
  {
    cov5 = 1e10;
    tag += " without field";
  }

  Printf("Created track cuts for: %s", tag.Data());

  return esdTrackCuts;
}
<commit_msg>ATO-465 - Increasing default downsampling by factor 4<commit_after>AliESDtrackCuts* CreateCuts(Bool_t fieldOn = kTRUE, Bool_t hists = kTRUE);

AliAnalysisTask* AddTaskFilteredTree(TString outputFile="")
{
  gSystem->Load("libANALYSIS");
  gSystem->Load("libANALYSISalice");
  gSystem->Load("libTender");
  gSystem->Load("libCORRFW");
  gSystem->Load("libPWGUDbase");
  gSystem->Load("libTPCcalib");
  gSystem->Load("libPWGPP");
  gSystem->Load("libPWGLFspectra");
  ::Info("AddTaskFilteredTree","BEGIN");
  printf("AddTaskFilteredTree::BEGIN\n");
  gRandom->SetSeed(0);

  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();

  if (!mgr) {
    Error("AddTaskFilteredTree", "No analysis manager found.");
    return 0;
  }

  // Switch off all AliInfo (too much output!!!)
  AliLog::SetClassDebugLevel("AliAnalysisTaskFilteredTree", AliLog::kError);

  //
  // Create physics trigger selection class
  //
  //AliPhysicsSelection *physTrigSel =  new AliPhysicsSelection();

  //
  // Create event cuts
  //
  Float_t zvWindow = 30. ;

  AliFilteredTreeEventCuts *evtCuts = new AliFilteredTreeEventCuts("AliFilteredTreeEventCuts","Event cuts");
  evtCuts->SetZvRange(-zvWindow,zvWindow);
  evtCuts->SetMeanXYZv(0.0,0.0,0.0);
  evtCuts->SetSigmaMeanXYZv(1.0,1.0,10.0);
  evtCuts->SetTriggerRequired(kFALSE);
  //evtCuts->SetTriggerRequired(kTRUE);

  //
  // Create geom. acceptance cuts
  //
  Float_t etaWindow = 1.0 ;
  Float_t ptMin = 0.15 ;

  AliFilteredTreeAcceptanceCuts *accCuts = new AliFilteredTreeAcceptanceCuts("AliFilteredTreeAcceptanceCuts","Geom. acceptance cuts");
  accCuts->SetEtaRange(-etaWindow,etaWindow);
  accCuts->SetPtRange(ptMin,1.e10);
  accCuts->SetMaxDCAr(3.0);
  accCuts->SetMaxDCAz(30.0);

  //
  // Create standard esd track cuts
  //

  AliESDtrackCuts* esdTrackCuts = CreateCuts();
  if (!esdTrackCuts) {
    printf("ERROR: esdTrackCuts could not be created\n");
    return 0;
  } else {
    esdTrackCuts->SetHistogramsOn(kTRUE);
  }
  Bool_t hasMC=(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()!=0x0);

  //
  // Create task
  //
  AliAnalysisTaskFilteredTree *task = new AliAnalysisTaskFilteredTree("AliAnalysisTaskFilteredTree");
  //task->SetUseMCInfo(hasMC);
  task->SetLowPtTrackDownscaligF(2.e4);
  task->SetLowPtV0DownscaligF(2.e3);
  //task->SetLowPtTrackDownscaligF(1.e5);
  //task->SetLowPtV0DownscaligF(2.e3);
  task->SetProcessAll(kTRUE);
  task->SetProcessCosmics(kTRUE);
  if (gSystem->Getenv("AliAnalysisTaskFilteredTree_SetLowPtTrackDownscalingF")) {
    Float_t downscale=TString(gSystem->Getenv("AliAnalysisTaskFilteredTree_SetLowPtTrackDownscalingF")).Atof();
    task->SetLowPtTrackDownscaligF(downscale);
    printf("AliAnalysisTaskFilteredTree_SetLowPtTrackDownscalingF: From env. variable\t%f\n", downscale);
  }else {
    ::Info("AliAnalysisTaskFilteredTree__SetLowPtTrackDownscalingF", "Use default");
    printf("AliAnalysisTaskFilteredTree_SetLowPtV0DownscalingF::Use DEFAULT\t\n");
  }
  if (gSystem->Getenv("AliAnalysisTaskFilteredTree_SetLowPtV0DownscalingF")) {
    Float_t downscale=TString(gSystem->Getenv("AliAnalysisTaskFilteredTree_SetLowPtV0DownscalingF")).Atof();
    task->SetLowPtV0DownscaligF(downscale);
    printf("AliAnalysisTaskFilteredTree_SetLowPtV0DownscalingF:From enc. variable\t%f\n",downscale);
  }else {
    printf("AliAnalysisTaskFilteredTree_SetLowPtV0DownscalingF::Use DEFAULT\t\n");
  }
  //task->Dump();
  //task->SetProcessAll(kFALSE);
  //task->SetFillTrees(kFALSE); // only histograms are filled

  // trigger
  //task->SelectCollisionCandidates(AliVEvent::kMB);

  //
  // set analysis options from the Helper here !!!
  //
  // AlidNdPtHelper::OutputObject outputObject = AlidNdPtHelper::kCutAnalysisPbPb;
  // AlidNdPtHelper::ParticleMode particleMode = AlidNdPtHelper::kAllPart ;
  //AlidNdPtHelper::AnalysisMode analysisMode = AlidNdPtHelper::kTPCITS;

  task->SetEventCuts(evtCuts);
  task->SetAcceptanceCuts(accCuts);
  task->SetTrackCuts(esdTrackCuts);
  task->SetAnalysisMode(AliAnalysisTaskFilteredTree::kTPCITSAnalysisMode);
  task->SetCentralityEstimator("V0M");

  // Add task
  mgr->AddTask(task);

  // Create containers for input
  AliAnalysisDataContainer *cinput = mgr->GetCommonInputContainer();
  mgr->ConnectInput(task, 0, cinput);

  if (outputFile.IsNull())
    outputFile=Form("%s", AliAnalysisManager::GetCommonFileName());

  AliAnalysisDataContainer *coutput1 = mgr->CreateContainer("filtered1", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 1, coutput1);
  AliAnalysisDataContainer *coutput2 = mgr->CreateContainer("filtered2", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 2, coutput2);
  AliAnalysisDataContainer *coutput3 = mgr->CreateContainer("filtered3", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 3, coutput3);
  AliAnalysisDataContainer *coutput4 = mgr->CreateContainer("filtered4", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 4, coutput4);
  AliAnalysisDataContainer *coutput5 = mgr->CreateContainer("filtered5", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 5, coutput5);
  AliAnalysisDataContainer *coutput6 = mgr->CreateContainer("filtered6", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 6, coutput6);

 // store histograms in the separate file
  TString outputFileHisto = "PtResHistograms.root";

  AliAnalysisDataContainer *coutput7 = mgr->CreateContainer("histo7", TList::Class(), AliAnalysisManager::kOutputContainer, outputFileHisto.Data());
  mgr->ConnectOutput(task, 7, coutput7);

   ::Info("AddTaskFilteredTree","END");
  printf("AddTaskFilteredTree::END\n");
  return task;
}

AliESDtrackCuts* CreateCuts(Bool_t fieldOn, Bool_t hists)
{
  AliESDtrackCuts* esdTrackCuts = new AliESDtrackCuts("AliESDtrackCuts");
  if(!esdTrackCuts) return 0;

  if (hists)
    esdTrackCuts->DefineHistograms(1);

  Double_t cov1, cov2, cov3, cov4, cov5;
  Double_t nSigma;
  Double_t maxDCAtoVertex, maxDCAtoVertexXY, maxDCAtoVertexZ;
  Double_t minNClustersTPC;
  Double_t maxChi2PerClusterTPC;
  Double_t minPt, maxPt;

  //
  // TPC
  //
  esdTrackCuts->SetRequireTPCRefit(kTRUE);
  esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
  //
  // ITS
  //
  //esdTrackCuts->SetRequireITSRefit(kTRUE);
  //esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
  //

  TString tag = "TPC+ITS refit and KinkRejection required - for cut studies";

  // cuts for data without field
  if (!fieldOn)
  {
    cov5 = 1e10;
    tag += " without field";
  }

  Printf("Created track cuts for: %s", tag.Data());

  return esdTrackCuts;
}
<|endoftext|>


<commit_before>// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/shell_integration.h"

#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <string>
#include <vector>

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/process_util.h"
#include "base/scoped_temp_dir.h"
#include "base/string_tokenizer.h"
#include "base/string_util.h"
#include "base/task.h"
#include "base/thread.h"
#include "chrome/browser/browser_process.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "googleurl/src/gurl.h"

namespace {

const char* GetDesktopName() {
#if defined(GOOGLE_CHROME_BUILD)
  return "google-chrome.desktop";
#else  // CHROMIUM_BUILD
  static const char* name = NULL;
  if (!name) {
    // Allow $CHROME_DESKTOP to override the built-in value, so that development
    // versions can set themselves as the default without interfering with
    // non-official, packaged versions using the built-in value.
    name = getenv("CHROME_DESKTOP");
    if (!name)
      name = "chromium-browser.desktop";
  }
  return name;
#endif
}

// Helper to launch xdg scripts. We don't want them to ask any questions on the
// terminal etc.
bool LaunchXdgUtility(const std::vector<std::string>& argv) {
  // xdg-settings internally runs xdg-mime, which uses mv to move newly-created
  // files on top of originals after making changes to them. In the event that
  // the original files are owned by another user (e.g. root, which can happen
  // if they are updated within sudo), mv will prompt the user to confirm if
  // standard input is a terminal (otherwise it just does it). So make sure it's
  // not, to avoid locking everything up waiting for mv.
  int devnull = open("/dev/null", O_RDONLY);
  if (devnull < 0)
    return false;
  base::file_handle_mapping_vector no_stdin;
  no_stdin.push_back(std::make_pair(devnull, STDIN_FILENO));

  base::ProcessHandle handle;
  if (!base::LaunchApp(argv, no_stdin, false, &handle)) {
    close(devnull);
    return false;
  }
  close(devnull);

  int success_code;
  base::WaitForExitCode(handle, &success_code);
  return success_code == EXIT_SUCCESS;
}

bool GetDesktopShortcutTemplate(std::string* output) {
  std::vector<std::string> search_paths;

  const char* xdg_data_home = getenv("XDG_DATA_HOME");
  if (xdg_data_home)
    search_paths.push_back(xdg_data_home);

  const char* xdg_data_dirs = getenv("XDG_DATA_DIRS");
  if (xdg_data_dirs) {
    CStringTokenizer tokenizer(xdg_data_dirs,
                               xdg_data_dirs + strlen(xdg_data_dirs), ":");
    while (tokenizer.GetNext()) {
      search_paths.push_back(tokenizer.token());
    }
  }

  std::string template_filename(GetDesktopName());
  for (std::vector<std::string>::const_iterator i = search_paths.begin();
       i != search_paths.end(); ++i) {
    FilePath path = FilePath(*i).Append(template_filename);
    if (file_util::PathExists(path))
      return file_util::ReadFileToString(path, output);
  }

  return false;
}

class CreateDesktopShortcutTask : public Task {
 public:
  CreateDesktopShortcutTask(const ShellIntegration::ShortcutInfo& shortcut_info)
      : shortcut_info_(shortcut_info) {
  }

  virtual void Run() {
    // TODO(phajdan.jr): Report errors from this function, possibly as infobars.
    std::string template_contents;
    if (!GetDesktopShortcutTemplate(&template_contents))
      return;

    std::string contents = ShellIntegration::GetDesktopFileContents(
        template_contents, shortcut_info_.url, shortcut_info_.title);

    ScopedTempDir temp_dir;
    if (!temp_dir.CreateUniqueTempDir())
      return;

    FilePath shortcut_filename =
        ShellIntegration::GetDesktopShortcutFilename(shortcut_info_.url);

    FilePath temp_file_path = temp_dir.path().Append(shortcut_filename);

    int bytes_written = file_util::WriteFile(temp_file_path, contents.data(),
                                             contents.length());

    if (bytes_written != static_cast<int>(contents.length()))
        return;

    if (shortcut_info_.create_on_desktop) {
      FilePath desktop_path;
      if (!PathService::Get(chrome::DIR_USER_DESKTOP, &desktop_path))
        return;
      desktop_path = desktop_path.Append(shortcut_filename);

      if (!file_util::PathExists(desktop_path))
        file_util::CopyFile(temp_file_path, desktop_path);
    }

    if (shortcut_info_.create_in_applications_menu) {
      std::vector<std::string> argv;
      argv.push_back("xdg-desktop-menu");
      argv.push_back("install");

      // Always install in user mode, even if someone runs the browser as root
      // (people do that).
      argv.push_back("--mode");
      argv.push_back("user");

      argv.push_back(temp_file_path.value());
      LaunchXdgUtility(argv);
    }
  }

 private:
  const ShellIntegration::ShortcutInfo shortcut_info_;

  DISALLOW_COPY_AND_ASSIGN(CreateDesktopShortcutTask);
};

}  // namespace

// We delegate the difficulty of setting the default browser in Linux desktop
// environments to a new xdg utility, xdg-settings. We have to include a copy of
// it for this to work, obviously, but that's actually the suggested approach
// for xdg utilities anyway.

bool ShellIntegration::SetAsDefaultBrowser() {
  std::vector<std::string> argv;
  argv.push_back("xdg-settings");
  argv.push_back("set");
  argv.push_back("default-web-browser");
  argv.push_back(GetDesktopName());
  return LaunchXdgUtility(argv);
}

ShellIntegration::DefaultBrowserState ShellIntegration::IsDefaultBrowser() {
  std::vector<std::string> argv;
  argv.push_back("xdg-settings");
  argv.push_back("check");
  argv.push_back("default-web-browser");
  argv.push_back(GetDesktopName());

  std::string reply;
  if (!base::GetAppOutput(CommandLine(argv), &reply)) {
    // xdg-settings failed: we can't determine or set the default browser.
    return UNKNOWN_DEFAULT_BROWSER;
  }

  // Allow any reply that starts with "yes".
  return (reply.find("yes") == 0) ? IS_DEFAULT_BROWSER : NOT_DEFAULT_BROWSER;
}

bool ShellIntegration::IsFirefoxDefaultBrowser() {
  std::vector<std::string> argv;
  argv.push_back("xdg-settings");
  argv.push_back("get");
  argv.push_back("default-web-browser");

  std::string browser;
  // We don't care about the return value here.
  base::GetAppOutput(CommandLine(argv), &browser);
  return browser.find("irefox") != std::string::npos;
}

FilePath ShellIntegration::GetDesktopShortcutFilename(const GURL& url) {
  // Use a prefix, because xdg-desktop-menu requires it.
  std::wstring filename = std::wstring(chrome::kBrowserProcessExecutableName) +
      L"-" + UTF8ToWide(url.spec()) + L".desktop";
  file_util::ReplaceIllegalCharacters(&filename, '_');

  // Return BaseName to be absolutely sure we're not vulnerable to a directory
  // traversal attack.
  return FilePath::FromWStringHack(filename).BaseName();
}

std::string ShellIntegration::GetDesktopFileContents(
    const std::string& template_contents, const GURL& url,
    const string16& title) {
  // See http://standards.freedesktop.org/desktop-entry-spec/latest/
  std::string output_buffer;
  StringTokenizer tokenizer(template_contents, "\n");
  while (tokenizer.GetNext()) {
    // TODO(phajdan.jr): Add the icon.

    if (tokenizer.token().substr(0, 5) == "Exec=") {
      std::string exec_path = tokenizer.token().substr(5);
      StringTokenizer exec_tokenizer(exec_path, " ");
      std::string final_path;
      while (exec_tokenizer.GetNext()) {
        if (exec_tokenizer.token() != "%U")
          final_path += exec_tokenizer.token() + " ";
      }
      std::wstring app_switch_wide(switches::kApp);
      std::string app_switch(StringPrintf("\"--%s=%s\"",
                                          WideToUTF8(app_switch_wide).c_str(),
                                          url.spec().c_str()));
      ReplaceSubstringsAfterOffset(&app_switch, 0, "%", "%%");
      output_buffer += std::string("Exec=") + final_path + app_switch + "\n";
    } else if (tokenizer.token().substr(0, 5) == "Name=") {
      std::string final_title = UTF16ToUTF8(title);
      // Make sure no endline characters can slip in and possibly introduce
      // additional lines (like Exec, which makes it a security risk). Also
      // use the URL as a default when the title is empty.
      if (final_title.empty() ||
          final_title.find("\n") != std::string::npos ||
          final_title.find("\r") != std::string::npos)
        final_title = url.spec();
      output_buffer += StringPrintf("Name=%s\n", final_title.c_str());
    } else if (tokenizer.token().substr(0, 8) == "Comment=") {
      // Skip the line.
    } else {
      output_buffer += tokenizer.token() + "\n";
    }
  }
  return output_buffer;
}

void ShellIntegration::CreateDesktopShortcut(
    const ShortcutInfo& shortcut_info) {
  g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE,
      new CreateDesktopShortcutTask(shortcut_info));
}
<commit_msg>More reliably find the .desktop file for the browser.<commit_after>// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/shell_integration.h"

#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <string>
#include <vector>

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/process_util.h"
#include "base/scoped_temp_dir.h"
#include "base/string_tokenizer.h"
#include "base/string_util.h"
#include "base/task.h"
#include "base/thread.h"
#include "chrome/browser/browser_process.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "googleurl/src/gurl.h"

namespace {

const char* GetDesktopName() {
#if defined(GOOGLE_CHROME_BUILD)
  return "google-chrome.desktop";
#else  // CHROMIUM_BUILD
  static const char* name = NULL;
  if (!name) {
    // Allow $CHROME_DESKTOP to override the built-in value, so that development
    // versions can set themselves as the default without interfering with
    // non-official, packaged versions using the built-in value.
    name = getenv("CHROME_DESKTOP");
    if (!name)
      name = "chromium-browser.desktop";
  }
  return name;
#endif
}

// Helper to launch xdg scripts. We don't want them to ask any questions on the
// terminal etc.
bool LaunchXdgUtility(const std::vector<std::string>& argv) {
  // xdg-settings internally runs xdg-mime, which uses mv to move newly-created
  // files on top of originals after making changes to them. In the event that
  // the original files are owned by another user (e.g. root, which can happen
  // if they are updated within sudo), mv will prompt the user to confirm if
  // standard input is a terminal (otherwise it just does it). So make sure it's
  // not, to avoid locking everything up waiting for mv.
  int devnull = open("/dev/null", O_RDONLY);
  if (devnull < 0)
    return false;
  base::file_handle_mapping_vector no_stdin;
  no_stdin.push_back(std::make_pair(devnull, STDIN_FILENO));

  base::ProcessHandle handle;
  if (!base::LaunchApp(argv, no_stdin, false, &handle)) {
    close(devnull);
    return false;
  }
  close(devnull);

  int success_code;
  base::WaitForExitCode(handle, &success_code);
  return success_code == EXIT_SUCCESS;
}

bool GetDesktopShortcutTemplate(std::string* output) {
  std::vector<FilePath> search_paths;

  const char* xdg_data_home = getenv("XDG_DATA_HOME");
  if (xdg_data_home)
    search_paths.push_back(FilePath(xdg_data_home));

  const char* xdg_data_dirs = getenv("XDG_DATA_DIRS");
  if (xdg_data_dirs) {
    CStringTokenizer tokenizer(xdg_data_dirs,
                               xdg_data_dirs + strlen(xdg_data_dirs), ":");
    while (tokenizer.GetNext()) {
      FilePath data_dir(tokenizer.token());
      search_paths.push_back(data_dir);
      search_paths.push_back(data_dir.Append("applications"));
    }
  }

  std::string template_filename(GetDesktopName());
  for (std::vector<FilePath>::const_iterator i = search_paths.begin();
       i != search_paths.end(); ++i) {
    FilePath path = (*i).Append(template_filename);
    if (file_util::PathExists(path))
      return file_util::ReadFileToString(path, output);
  }

  return false;
}

class CreateDesktopShortcutTask : public Task {
 public:
  CreateDesktopShortcutTask(const ShellIntegration::ShortcutInfo& shortcut_info)
      : shortcut_info_(shortcut_info) {
  }

  virtual void Run() {
    // TODO(phajdan.jr): Report errors from this function, possibly as infobars.
    std::string template_contents;
    if (!GetDesktopShortcutTemplate(&template_contents))
      return;

    std::string contents = ShellIntegration::GetDesktopFileContents(
        template_contents, shortcut_info_.url, shortcut_info_.title);

    ScopedTempDir temp_dir;
    if (!temp_dir.CreateUniqueTempDir())
      return;

    FilePath shortcut_filename =
        ShellIntegration::GetDesktopShortcutFilename(shortcut_info_.url);

    FilePath temp_file_path = temp_dir.path().Append(shortcut_filename);

    int bytes_written = file_util::WriteFile(temp_file_path, contents.data(),
                                             contents.length());

    if (bytes_written != static_cast<int>(contents.length()))
        return;

    if (shortcut_info_.create_on_desktop) {
      FilePath desktop_path;
      if (!PathService::Get(chrome::DIR_USER_DESKTOP, &desktop_path))
        return;
      desktop_path = desktop_path.Append(shortcut_filename);

      if (!file_util::PathExists(desktop_path))
        file_util::CopyFile(temp_file_path, desktop_path);
    }

    if (shortcut_info_.create_in_applications_menu) {
      std::vector<std::string> argv;
      argv.push_back("xdg-desktop-menu");
      argv.push_back("install");

      // Always install in user mode, even if someone runs the browser as root
      // (people do that).
      argv.push_back("--mode");
      argv.push_back("user");

      argv.push_back(temp_file_path.value());
      LaunchXdgUtility(argv);
    }
  }

 private:
  const ShellIntegration::ShortcutInfo shortcut_info_;

  DISALLOW_COPY_AND_ASSIGN(CreateDesktopShortcutTask);
};

}  // namespace

// We delegate the difficulty of setting the default browser in Linux desktop
// environments to a new xdg utility, xdg-settings. We have to include a copy of
// it for this to work, obviously, but that's actually the suggested approach
// for xdg utilities anyway.

bool ShellIntegration::SetAsDefaultBrowser() {
  std::vector<std::string> argv;
  argv.push_back("xdg-settings");
  argv.push_back("set");
  argv.push_back("default-web-browser");
  argv.push_back(GetDesktopName());
  return LaunchXdgUtility(argv);
}

ShellIntegration::DefaultBrowserState ShellIntegration::IsDefaultBrowser() {
  std::vector<std::string> argv;
  argv.push_back("xdg-settings");
  argv.push_back("check");
  argv.push_back("default-web-browser");
  argv.push_back(GetDesktopName());

  std::string reply;
  if (!base::GetAppOutput(CommandLine(argv), &reply)) {
    // xdg-settings failed: we can't determine or set the default browser.
    return UNKNOWN_DEFAULT_BROWSER;
  }

  // Allow any reply that starts with "yes".
  return (reply.find("yes") == 0) ? IS_DEFAULT_BROWSER : NOT_DEFAULT_BROWSER;
}

bool ShellIntegration::IsFirefoxDefaultBrowser() {
  std::vector<std::string> argv;
  argv.push_back("xdg-settings");
  argv.push_back("get");
  argv.push_back("default-web-browser");

  std::string browser;
  // We don't care about the return value here.
  base::GetAppOutput(CommandLine(argv), &browser);
  return browser.find("irefox") != std::string::npos;
}

FilePath ShellIntegration::GetDesktopShortcutFilename(const GURL& url) {
  // Use a prefix, because xdg-desktop-menu requires it.
  std::wstring filename = std::wstring(chrome::kBrowserProcessExecutableName) +
      L"-" + UTF8ToWide(url.spec()) + L".desktop";
  file_util::ReplaceIllegalCharacters(&filename, '_');

  // Return BaseName to be absolutely sure we're not vulnerable to a directory
  // traversal attack.
  return FilePath::FromWStringHack(filename).BaseName();
}

std::string ShellIntegration::GetDesktopFileContents(
    const std::string& template_contents, const GURL& url,
    const string16& title) {
  // See http://standards.freedesktop.org/desktop-entry-spec/latest/
  std::string output_buffer;
  StringTokenizer tokenizer(template_contents, "\n");
  while (tokenizer.GetNext()) {
    // TODO(phajdan.jr): Add the icon.

    if (tokenizer.token().substr(0, 5) == "Exec=") {
      std::string exec_path = tokenizer.token().substr(5);
      StringTokenizer exec_tokenizer(exec_path, " ");
      std::string final_path;
      while (exec_tokenizer.GetNext()) {
        if (exec_tokenizer.token() != "%U")
          final_path += exec_tokenizer.token() + " ";
      }
      std::wstring app_switch_wide(switches::kApp);
      std::string app_switch(StringPrintf("\"--%s=%s\"",
                                          WideToUTF8(app_switch_wide).c_str(),
                                          url.spec().c_str()));
      ReplaceSubstringsAfterOffset(&app_switch, 0, "%", "%%");
      output_buffer += std::string("Exec=") + final_path + app_switch + "\n";
    } else if (tokenizer.token().substr(0, 5) == "Name=") {
      std::string final_title = UTF16ToUTF8(title);
      // Make sure no endline characters can slip in and possibly introduce
      // additional lines (like Exec, which makes it a security risk). Also
      // use the URL as a default when the title is empty.
      if (final_title.empty() ||
          final_title.find("\n") != std::string::npos ||
          final_title.find("\r") != std::string::npos)
        final_title = url.spec();
      output_buffer += StringPrintf("Name=%s\n", final_title.c_str());
    } else if (tokenizer.token().substr(0, 8) == "Comment=") {
      // Skip the line.
    } else {
      output_buffer += tokenizer.token() + "\n";
    }
  }
  return output_buffer;
}

void ShellIntegration::CreateDesktopShortcut(
    const ShortcutInfo& shortcut_info) {
  g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE,
      new CreateDesktopShortcutTask(shortcut_info));
}
<|endoftext|>


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

#include "chrome/common/service_process_util.h"

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/scoped_ptr.h"
#include "base/string16.h"
#include "base/task.h"
#include "base/utf_string_conversions.h"
#include "base/win/object_watcher.h"
#include "base/win/scoped_handle.h"
#include "base/win/win_util.h"
#include "chrome/common/chrome_switches.h"

namespace {

string16 GetServiceProcessReadyEventName() {
  return UTF8ToWide(
      GetServiceProcessScopedVersionedName("_service_ready"));
}

string16 GetServiceProcessShutdownEventName() {
  return UTF8ToWide(
      GetServiceProcessScopedVersionedName("_service_shutdown_evt"));
}

std::string GetServiceProcessAutoRunKey() {
  return GetServiceProcessScopedName("_service_run");
}

class ServiceProcessShutdownMonitor
    : public base::win::ObjectWatcher::Delegate {
 public:
  explicit ServiceProcessShutdownMonitor(Task* shutdown_task)
      : shutdown_task_(shutdown_task) {
  }
  void Start() {
    string16 event_name = GetServiceProcessShutdownEventName();
    CHECK(event_name.length() <= MAX_PATH);
    shutdown_event_.Set(CreateEvent(NULL, TRUE, FALSE, event_name.c_str()));
    watcher_.StartWatching(shutdown_event_.Get(), this);
  }

  // base::ObjectWatcher::Delegate implementation.
  virtual void OnObjectSignaled(HANDLE object) {
    shutdown_task_->Run();
    shutdown_task_.reset();
  }

 private:
  base::win::ScopedHandle shutdown_event_;
  base::win::ObjectWatcher watcher_;
  scoped_ptr<Task> shutdown_task_;
};

}  // namespace

bool ForceServiceProcessShutdown(const std::string& version,
                                 base::ProcessId process_id) {
  base::win::ScopedHandle shutdown_event;
  std::string versioned_name = version;
  versioned_name.append("_service_shutdown_evt");
  string16 event_name =
      UTF8ToWide(GetServiceProcessScopedName(versioned_name));
  shutdown_event.Set(OpenEvent(EVENT_MODIFY_STATE, FALSE, event_name.c_str()));
  if (!shutdown_event.IsValid())
    return false;
  SetEvent(shutdown_event.Get());
  return true;
}

bool CheckServiceProcessReady() {
  string16 event_name = GetServiceProcessReadyEventName();
  base::win::ScopedHandle event(
      OpenEvent(SYNCHRONIZE | READ_CONTROL, false, event_name.c_str()));
  if (!event.IsValid())
    return false;
  // Check if the event is signaled.
  return WaitForSingleObject(event, 0) == WAIT_OBJECT_0;
}

struct ServiceProcessState::StateData {
  // An event that is signaled when a service process is ready.
  base::win::ScopedHandle ready_event;
  scoped_ptr<ServiceProcessShutdownMonitor> shutdown_monitor;
};

bool ServiceProcessState::InitializeState() {
  DCHECK(!state_);
  state_ = new StateData;
  return true;
}

bool ServiceProcessState::TakeSingletonLock() {
  DCHECK(state_);
  string16 event_name = GetServiceProcessReadyEventName();
  CHECK(event_name.length() <= MAX_PATH);
  base::win::ScopedHandle service_process_ready_event;
  service_process_ready_event.Set(
      CreateEvent(NULL, TRUE, FALSE, event_name.c_str()));
  DWORD error = GetLastError();
  if ((error == ERROR_ALREADY_EXISTS) || (error == ERROR_ACCESS_DENIED))
    return false;
  DCHECK(service_process_ready_event.IsValid());
  state_->ready_event.Set(service_process_ready_event.Take());
  return true;
}

bool ServiceProcessState::SignalReady(
    base::MessageLoopProxy* message_loop_proxy, Task* shutdown_task) {
  DCHECK(state_);
  DCHECK(state_->ready_event.IsValid());
  if (!SetEvent(state_->ready_event.Get())) {
    return false;
  }
  if (shutdown_task) {
    state_->shutdown_monitor.reset(
        new ServiceProcessShutdownMonitor(shutdown_task));
    state_->shutdown_monitor->Start();
  }
  return true;
}

bool ServiceProcessState::AddToAutoRun() {
  DCHECK(autorun_command_line_.get());
  return base::win::AddCommandToAutoRun(
      HKEY_CURRENT_USER,
      UTF8ToWide(GetServiceProcessAutoRunKey()),
      autorun_command_line_->command_line_string());
}

bool ServiceProcessState::RemoveFromAutoRun() {
  return base::win::RemoveCommandFromAutoRun(
      HKEY_CURRENT_USER, UTF8ToWide(GetServiceProcessAutoRunKey()));
}

void ServiceProcessState::TearDownState() {
  delete state_;
  state_ = NULL;
}
<commit_msg>Removed obsolete autorun value on Windows.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/common/service_process_util.h"

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/scoped_ptr.h"
#include "base/string16.h"
#include "base/task.h"
#include "base/utf_string_conversions.h"
#include "base/win/object_watcher.h"
#include "base/win/scoped_handle.h"
#include "base/win/win_util.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"

namespace {

string16 GetServiceProcessReadyEventName() {
  return UTF8ToWide(
      GetServiceProcessScopedVersionedName("_service_ready"));
}

string16 GetServiceProcessShutdownEventName() {
  return UTF8ToWide(
      GetServiceProcessScopedVersionedName("_service_shutdown_evt"));
}

std::string GetServiceProcessAutoRunKey() {
  return GetServiceProcessScopedName("_service_run");
}

// Returns the name of the autotun reg value that we used to use for older
// versions of Chrome.
std::string GetObsoleteServiceProcessAutoRunKey() {
  FilePath user_data_dir;
  PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
  std::string scoped_name = WideToUTF8(user_data_dir.value());
  std::replace(scoped_name.begin(), scoped_name.end(), '\\', '!');
  std::replace(scoped_name.begin(), scoped_name.end(), '/', '!');
  scoped_name.append("_service_run");
  return scoped_name;
}

class ServiceProcessShutdownMonitor
    : public base::win::ObjectWatcher::Delegate {
 public:
  explicit ServiceProcessShutdownMonitor(Task* shutdown_task)
      : shutdown_task_(shutdown_task) {
  }
  void Start() {
    string16 event_name = GetServiceProcessShutdownEventName();
    CHECK(event_name.length() <= MAX_PATH);
    shutdown_event_.Set(CreateEvent(NULL, TRUE, FALSE, event_name.c_str()));
    watcher_.StartWatching(shutdown_event_.Get(), this);
  }

  // base::ObjectWatcher::Delegate implementation.
  virtual void OnObjectSignaled(HANDLE object) {
    shutdown_task_->Run();
    shutdown_task_.reset();
  }

 private:
  base::win::ScopedHandle shutdown_event_;
  base::win::ObjectWatcher watcher_;
  scoped_ptr<Task> shutdown_task_;
};

}  // namespace

bool ForceServiceProcessShutdown(const std::string& version,
                                 base::ProcessId process_id) {
  base::win::ScopedHandle shutdown_event;
  std::string versioned_name = version;
  versioned_name.append("_service_shutdown_evt");
  string16 event_name =
      UTF8ToWide(GetServiceProcessScopedName(versioned_name));
  shutdown_event.Set(OpenEvent(EVENT_MODIFY_STATE, FALSE, event_name.c_str()));
  if (!shutdown_event.IsValid())
    return false;
  SetEvent(shutdown_event.Get());
  return true;
}

bool CheckServiceProcessReady() {
  string16 event_name = GetServiceProcessReadyEventName();
  base::win::ScopedHandle event(
      OpenEvent(SYNCHRONIZE | READ_CONTROL, false, event_name.c_str()));
  if (!event.IsValid())
    return false;
  // Check if the event is signaled.
  return WaitForSingleObject(event, 0) == WAIT_OBJECT_0;
}

struct ServiceProcessState::StateData {
  // An event that is signaled when a service process is ready.
  base::win::ScopedHandle ready_event;
  scoped_ptr<ServiceProcessShutdownMonitor> shutdown_monitor;
};

bool ServiceProcessState::InitializeState() {
  DCHECK(!state_);
  state_ = new StateData;
  return true;
}

bool ServiceProcessState::TakeSingletonLock() {
  DCHECK(state_);
  string16 event_name = GetServiceProcessReadyEventName();
  CHECK(event_name.length() <= MAX_PATH);
  base::win::ScopedHandle service_process_ready_event;
  service_process_ready_event.Set(
      CreateEvent(NULL, TRUE, FALSE, event_name.c_str()));
  DWORD error = GetLastError();
  if ((error == ERROR_ALREADY_EXISTS) || (error == ERROR_ACCESS_DENIED))
    return false;
  DCHECK(service_process_ready_event.IsValid());
  state_->ready_event.Set(service_process_ready_event.Take());
  return true;
}

bool ServiceProcessState::SignalReady(
    base::MessageLoopProxy* message_loop_proxy, Task* shutdown_task) {
  DCHECK(state_);
  DCHECK(state_->ready_event.IsValid());
  if (!SetEvent(state_->ready_event.Get())) {
    return false;
  }
  if (shutdown_task) {
    state_->shutdown_monitor.reset(
        new ServiceProcessShutdownMonitor(shutdown_task));
    state_->shutdown_monitor->Start();
  }
  return true;
}

bool ServiceProcessState::AddToAutoRun() {
  DCHECK(autorun_command_line_.get());
  // Remove the old autorun value first because we changed the naming scheme
  // for the autorun value name.
  base::win::RemoveCommandFromAutoRun(
      HKEY_CURRENT_USER, UTF8ToWide(GetObsoleteServiceProcessAutoRunKey()));
  return base::win::AddCommandToAutoRun(
      HKEY_CURRENT_USER,
      UTF8ToWide(GetServiceProcessAutoRunKey()),
      autorun_command_line_->command_line_string());
}

bool ServiceProcessState::RemoveFromAutoRun() {
  // Remove the old autorun value first because we changed the naming scheme
  // for the autorun value name.
  base::win::RemoveCommandFromAutoRun(
      HKEY_CURRENT_USER, UTF8ToWide(GetObsoleteServiceProcessAutoRunKey()));
  return base::win::RemoveCommandFromAutoRun(
      HKEY_CURRENT_USER, UTF8ToWide(GetServiceProcessAutoRunKey()));
}

void ServiceProcessState::TearDownState() {
  delete state_;
  state_ = NULL;
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>

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

    int matriz[10];

    matriz[3] = 7;
    printf("%i\n", matriz[3]);

    return EXIT_SUCCESS;
}
<commit_msg>Delete inicio.cpp<commit_after><|endoftext|>