<commit_before>#include <yuni/yuni.h>
#include <yuni/thread/utility.h>
#include <yuni/job/taskgroup.h>
#include <yuni/io/file.h>
#include "source.h"
#include "build-info.h"
#include "target.h"
#include "details/errors/errors.h"
#include <memory>
#include "details/context/build.h"

using namespace Yuni;

namespace ny {

Source::Source(CTarget* target, Source::Type type, AnyString filename, AnyString content)
	: m_type{type}
	, m_content{content}
	, m_target(target) {
	switch (type) {
		case Type::file:
			IO::Canonicalize(m_filename, filename);
			break;
		case Type::memory:
			m_filename = filename;
			break;
	}
}

Source::Source(CTarget* target, const Source& rhs) // assuming that rhs is already protected
	: m_type(rhs.m_type)
	, m_filename(rhs.m_filename)
	, m_content(rhs.m_content)
	, m_target(target) {
}

Source::~Source() {
	// keep the symbol local
}

bool Source::isOutdated(yint64& lastModified) const {
	if (m_type == Type::file) {
		auto lmt = IO::File::LastModificationTime(m_filename);
		if (lmt != m_lastCompiled) {
			lastModified = lmt;
			return true;
		}
		return false;
	}
	lastModified = m_lastCompiled;
	return (m_lastCompiled <= 0);
}

bool Source::build(Build& build) {
	bool success = false;
	yint64 modified = build.buildtime;
	try {
		if (not isOutdated(modified)) {
			success = true; // not modified
		}
		else {
			if (modified <= 0)
				modified = build.buildtime;
			if (m_filename.first() != '{') {
				#ifndef YUNI_OS_WINDOWS
				AnyString arrow {"\u2192 "};
				#else
				constexpr const char* arrow = nullptr;
				#endif
				auto entry = (info() << "building " << m_filename);
				entry.message.prefix = arrow;
			}
			success = true;
			if (m_type == Type::file) {
				m_content.clear();
				m_content.shrink();
				success = (IO::errNone == IO::File::LoadFromFile(m_content, m_filename));
				if (unlikely(not success and m_target)) {
					auto f = build.cf.on_error_file_eacces;
					if (f)
						f(build.project.self(), build.self(), m_filename.c_str(), m_filename.size());
				}
			}
			auto report = Logs::Report{*build.messages} .subgroup();
			report.data().origins.location.filename = m_filename;
			report.data().origins.location.target.clear();
			pBuildInfo.reset(nullptr); // making sure that the memory is released first
			pBuildInfo = std::make_unique<BuildInfoSource>(build.cf);
			if (success) {
				success &= passASTFromSourceWL();
				success &= passDuplicateAndNormalizeASTWL(report);
				success &= passTransformASTToIRWL(report);
				if (success) {
					auto& sequence = pBuildInfo->parsing.sequence;
					success &= build.attach(sequence);
				}
			}
			pBuildInfo->parsing.success = success;
		}
	}
	catch (std::bad_alloc&) {
		build.printStderr("ice: not enough memory");
		success = false;
	}
	catch (...) {
		ice() << "uncaught exception when building '" << m_filename << "'";
		success = false;
	}
	if (not success) {
		m_lastCompiled = 0; // error
		build.success = false;
	}
	else
		m_lastCompiled = modified;
	return success;
}

} // namespace ny
<commit_msg>build: remove useless complex condition<commit_after>#include <yuni/yuni.h>
#include <yuni/thread/utility.h>
#include <yuni/job/taskgroup.h>
#include <yuni/io/file.h>
#include "source.h"
#include "build-info.h"
#include "target.h"
#include "details/errors/errors.h"
#include <memory>
#include "details/context/build.h"

using namespace Yuni;

namespace ny {

Source::Source(CTarget* target, Source::Type type, AnyString filename, AnyString content)
	: m_type{type}
	, m_content{content}
	, m_target(target) {
	switch (type) {
		case Type::file:
			IO::Canonicalize(m_filename, filename);
			break;
		case Type::memory:
			m_filename = filename;
			break;
	}
}

Source::Source(CTarget* target, const Source& rhs) // assuming that rhs is already protected
	: m_type(rhs.m_type)
	, m_filename(rhs.m_filename)
	, m_content(rhs.m_content)
	, m_target(target) {
}

Source::~Source() {
	// keep the symbol local
}

bool Source::isOutdated(yint64& lastModified) const {
	if (m_type == Type::file) {
		auto lmt = IO::File::LastModificationTime(m_filename);
		if (lmt != m_lastCompiled) {
			lastModified = lmt;
			return true;
		}
		return false;
	}
	lastModified = m_lastCompiled;
	return (m_lastCompiled <= 0);
}

bool Source::build(Build& build) {
	bool success = false;
	yint64 modified = build.buildtime;
	try {
		if (not isOutdated(modified)) {
			success = true; // not modified
		}
		else {
			if (modified <= 0)
				modified = build.buildtime;
			if (m_filename.first() != '{') {
				#ifndef YUNI_OS_WINDOWS
				AnyString arrow {"\u2192 "};
				#else
				constexpr const char* arrow = nullptr;
				#endif
				auto entry = (info() << "building " << m_filename);
				entry.message.prefix = arrow;
			}
			success = true;
			if (m_type == Type::file) {
				m_content.clear();
				m_content.shrink();
				success = (IO::errNone == IO::File::LoadFromFile(m_content, m_filename));
				if (unlikely(not success and m_target)) {
					auto f = build.cf.on_error_file_eacces;
					if (f)
						f(build.project.self(), build.self(), m_filename.c_str(), m_filename.size());
				}
			}
			auto report = Logs::Report{*build.messages} .subgroup();
			report.data().origins.location.filename = m_filename;
			report.data().origins.location.target.clear();
			pBuildInfo.reset(nullptr); // making sure that the memory is released first
			pBuildInfo = std::make_unique<BuildInfoSource>(build.cf);
			if (success) {
				success &= passASTFromSourceWL();
				success &= passDuplicateAndNormalizeASTWL(report);
				success &= passTransformASTToIRWL(report);
				success = success and build.attach(pBuildInfo->parsing.sequence);
			}
			pBuildInfo->parsing.success = success;
		}
	}
	catch (std::bad_alloc&) {
		build.printStderr("ice: not enough memory");
		success = false;
	}
	catch (...) {
		ice() << "uncaught exception when building '" << m_filename << "'";
		success = false;
	}
	if (not success) {
		m_lastCompiled = 0; // error
		build.success = false;
	}
	else
		m_lastCompiled = modified;
	return success;
}

} // namespace ny
<|endoftext|>


<commit_before>// Copyright (c) 2012, Zeex
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <cassert>
#include <cstddef>
#include <cstdlib>
#include <fstream>
#include <map>
#include <string>

#include "amxpathfinder.h"
#include "jit.h"
#include "jump-x86.h"
#include "options.h"
#include "plugin.h"
#include "version.h"

#ifdef WIN32
	#include <Windows.h>
#else
	#ifndef _GNU_SOURCE
		#define _GNU_SOURCE 1 // for dladdr()
	#endif
	#include <dlfcn.h>
#endif

extern void *pAMXFunctions;

typedef void (*logprintf_t)(const char *format, ...);
static logprintf_t logprintf;

typedef std::map<AMX*, jit::Jitter*> AmxToJitterMap;
static AmxToJitterMap amx2jitter;

static JumpX86 amx_Exec_hook;
static cell *opcodeTable = 0;

static int AMXAPI amx_Exec_JIT(AMX *amx, cell *retval, int index) {
	#if defined __GNUC__ && !defined WIN32
		if ((amx->flags & AMX_FLAG_BROWSE) == AMX_FLAG_BROWSE) {
			assert(::opcodeTable != 0);
			*retval = reinterpret_cast<cell>(::opcodeTable);
			return AMX_ERR_NONE;
		}
	#endif
	AmxToJitterMap::iterator iterator = ::amx2jitter.find(amx);
	if (iterator == ::amx2jitter.end()) {
		JumpX86::ScopedRemove r(&amx_Exec_hook);
		return amx_Exec(amx, retval, index);
	} else {
		jit::Jitter *jitter = iterator->second;
		return jitter->exec(index, retval);
	}
}

static std::string GetModuleNameBySymbol(void *symbol) {
	char module[FILENAME_MAX] = "";
	if (symbol != 0) {
		#ifdef WIN32
			MEMORY_BASIC_INFORMATION mbi;
			VirtualQuery(symbol, &mbi, sizeof(mbi));
			GetModuleFileName((HMODULE)mbi.AllocationBase, module, FILENAME_MAX);
		#else
			Dl_info info;
			dladdr(symbol, &info);
			strcpy(module, info.dli_fname);
		#endif
	}
	return std::string(module);
}

static std::string GetFileName(const std::string &path) {
	std::string::size_type lastSep = path.find_last_of("/\\");
	if (lastSep != std::string::npos) {
		return path.substr(lastSep + 1);
	}
	return path;
}

static void CompileError(const jit::AmxVm &vm, const jit::AmxInstruction &instr) {
	logprintf("JIT failed to compile instruction at %08x:", instr.getAddress());
	logprintf("  %s", instr.asString().c_str());
}

PLUGIN_EXPORT unsigned int PLUGIN_CALL Supports() {
	return SUPPORTS_VERSION | SUPPORTS_AMX_NATIVES;
}

#if defined WIN32
	#define SAMP_SERVER_BINARY "samp-server.exe"
#else
	#define SAMP_SERVER_BINARY "samp03svr"
#endif

static void *AMXAPI amx_Align(void *v) { return v; }

PLUGIN_EXPORT bool PLUGIN_CALL Load(void **ppData) {
	logprintf = (logprintf_t)ppData[PLUGIN_DATA_LOGPRINTF];
	pAMXFunctions = reinterpret_cast<void*>(ppData[PLUGIN_DATA_AMX_EXPORTS]);

	((void**)pAMXFunctions)[PLUGIN_AMX_EXPORT_Align16] = (void*)amx_Align;
	((void**)pAMXFunctions)[PLUGIN_AMX_EXPORT_Align32] = (void*)amx_Align;
	((void**)pAMXFunctions)[PLUGIN_AMX_EXPORT_Align64] = (void*)amx_Align;

	void *ptr = JumpX86::GetTargetAddress(((void**)pAMXFunctions)[PLUGIN_AMX_EXPORT_Exec]);
	if (ptr != 0) {
		std::string module = GetFileName(GetModuleNameBySymbol(ptr));
		if (!module.empty() && module != SAMP_SERVER_BINARY) {
			logprintf("  JIT must be loaded before %s", module.c_str());
			return false;
		}
	}

	#if defined __GNUC__ && !defined WIN32
		// Get opcode list before we hook amx_Exec().
		AMX amx = {0};
		amx.flags |= AMX_FLAG_BROWSE;
		amx_Exec(&amx, reinterpret_cast<cell*>(&::opcodeTable), 0);
		amx.flags &= ~AMX_FLAG_BROWSE;
	#endif

	amx_Exec_hook.Install(
		((void**)pAMXFunctions)[PLUGIN_AMX_EXPORT_Exec],
		(void*)amx_Exec_JIT);

	logprintf("  JIT plugin v%s is OK.", PLUGIN_VERSION_STRING);
	return true;
}

PLUGIN_EXPORT void PLUGIN_CALL Unload() {
	for (AmxToJitterMap::iterator it = amx2jitter.begin(); it != amx2jitter.end(); ++it) {
		delete it->second;
	}
}

PLUGIN_EXPORT int PLUGIN_CALL AmxLoad(AMX *amx) {
	jit::Jitter *jitter = new jit::Jitter(amx);
	#if defined __GNUC__ && defined LINUX
		jitter->setOpcodeTable(::opcodeTable);
	#endif

	AsmJit::X86Assembler as;
	jitter->setAssembler(&as);

	AsmJit::FileLogger logger;
	as.setLogger(&logger);

	AMXPathFinder finder;
	finder.AddSearchPath("./");
	finder.AddSearchPath("gamemodes/");
	finder.AddSearchPath("filterscripts/");

	std::string amxPath = finder.FindAMX(amx);

	if (Options::Get().dump_asm()) {
		std::string asmPath = amxPath + ".asm";
		logger.setStream(std::fopen(asmPath.c_str(), "w"));
	} else {
		as.setLogger(0);
	}

	if (!jitter->compile(CompileError)) {
		delete jitter;
	} else {
		if (logger.getStream() != 0) {
			std::fclose(logger.getStream());
		}
		jitter->setAssembler(0);

		if (Options::Get().dump_bin()) {
			std::string binPath = amxPath + ".bin";
			std::FILE *bin = std::fopen(binPath.c_str(), "w");
			if (bin != 0) {
				std::fwrite(jitter->getCode(), jitter->getCodeSize(), 1, bin);
				std::fclose(bin);
			}
		}

		::amx2jitter.insert(std::make_pair(amx, jitter));
	}

	return AMX_ERR_NONE;
}

PLUGIN_EXPORT int PLUGIN_CALL AmxUnload(AMX *amx) {
	AmxToJitterMap::iterator it = amx2jitter.find(amx);
	if (it != amx2jitter.end()) {
		delete it->second;
		amx2jitter.erase(it);
	}
	return AMX_ERR_NONE;
}
<commit_msg>Remove GetFileName and GetModuleNameBySymbol<commit_after>// Copyright (c) 2012, Zeex
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <cassert>
#include <cstddef>
#include <cstdlib>
#include <fstream>
#include <map>
#include <string>

#include "amxpathfinder.h"
#include "fileutils.h"
#include "jit.h"
#include "jump-x86.h"
#include "options.h"
#include "os.h"
#include "plugin.h"
#include "version.h"

extern void *pAMXFunctions;

typedef void (*logprintf_t)(const char *format, ...);
static logprintf_t logprintf;

typedef std::map<AMX*, jit::Jitter*> AmxToJitterMap;
static AmxToJitterMap amx2jitter;

static JumpX86 amx_Exec_hook;
static cell *opcodeTable = 0;

static int AMXAPI amx_Exec_JIT(AMX *amx, cell *retval, int index)
{
	#if defined __GNUC__ && !defined WIN32
		if ((amx->flags & AMX_FLAG_BROWSE) == AMX_FLAG_BROWSE) {
			assert(::opcodeTable != 0);
			*retval = reinterpret_cast<cell>(::opcodeTable);
			return AMX_ERR_NONE;
		}
	#endif
	AmxToJitterMap::iterator iterator = ::amx2jitter.find(amx);
	if (iterator == ::amx2jitter.end()) {
		JumpX86::ScopedRemove r(&amx_Exec_hook);
		return amx_Exec(amx, retval, index);
	} else {
		jit::Jitter *jitter = iterator->second;
		return jitter->exec(index, retval);
	}
}

static void CompileError(const jit::AmxVm &vm, const jit::AmxInstruction &instr)
{
	logprintf("JIT failed to compile instruction at %08x:", instr.getAddress());
	logprintf("  %s", instr.asString().c_str());
}

PLUGIN_EXPORT unsigned int PLUGIN_CALL Supports()
{
	return SUPPORTS_VERSION | SUPPORTS_AMX_NATIVES;
}

#if defined WIN32
	#define SAMP_SERVER_BINARY "samp-server.exe"
#else
	#define SAMP_SERVER_BINARY "samp03svr"
#endif

static void *AMXAPI amx_Align(void *v) { return v; }

PLUGIN_EXPORT bool PLUGIN_CALL Load(void **ppData)
{
	logprintf = (logprintf_t)ppData[PLUGIN_DATA_LOGPRINTF];
	pAMXFunctions = reinterpret_cast<void*>(ppData[PLUGIN_DATA_AMX_EXPORTS]);

	((void**)pAMXFunctions)[PLUGIN_AMX_EXPORT_Align16] = (void*)amx_Align;
	((void**)pAMXFunctions)[PLUGIN_AMX_EXPORT_Align32] = (void*)amx_Align;
	((void**)pAMXFunctions)[PLUGIN_AMX_EXPORT_Align64] = (void*)amx_Align;

	void *ptr = JumpX86::GetTargetAddress(((void**)pAMXFunctions)[PLUGIN_AMX_EXPORT_Exec]);
	if (ptr != 0) {
		std::string module = fileutils::GetFileName(os::GetModulePath(ptr));
		if (!module.empty() && module != SAMP_SERVER_BINARY) {
			logprintf("  JIT must be loaded before %s", module.c_str());
			return false;
		}
	}

	#if defined __GNUC__ && !defined WIN32
		// Get opcode list before we hook amx_Exec().
		AMX amx = {0};
		amx.flags |= AMX_FLAG_BROWSE;
		amx_Exec(&amx, reinterpret_cast<cell*>(&::opcodeTable), 0);
		amx.flags &= ~AMX_FLAG_BROWSE;
	#endif

	amx_Exec_hook.Install(
		((void**)pAMXFunctions)[PLUGIN_AMX_EXPORT_Exec],
		(void*)amx_Exec_JIT);

	logprintf("  JIT plugin v%s is OK.", PLUGIN_VERSION_STRING);
	return true;
}

PLUGIN_EXPORT void PLUGIN_CALL Unload()
{
	for (AmxToJitterMap::iterator it = amx2jitter.begin(); it != amx2jitter.end(); ++it) {
		delete it->second;
	}
}

PLUGIN_EXPORT int PLUGIN_CALL AmxLoad(AMX *amx)
{
	jit::Jitter *jitter = new jit::Jitter(amx);
	#if defined __GNUC__ && defined LINUX
		jitter->setOpcodeTable(::opcodeTable);
	#endif

	AsmJit::X86Assembler as;
	jitter->setAssembler(&as);

	AsmJit::FileLogger logger;
	as.setLogger(&logger);

	AMXPathFinder finder;
	finder.AddSearchPath("./");
	finder.AddSearchPath("gamemodes/");
	finder.AddSearchPath("filterscripts/");

	std::string amxPath = finder.FindAMX(amx);

	if (Options::Get().dump_asm()) {
		std::string asmPath = amxPath + ".asm";
		logger.setStream(std::fopen(asmPath.c_str(), "w"));
	} else {
		as.setLogger(0);
	}

	if (!jitter->compile(CompileError)) {
		delete jitter;
	} else {
		if (logger.getStream() != 0) {
			std::fclose(logger.getStream());
		}
		jitter->setAssembler(0);

		if (Options::Get().dump_bin()) {
			std::string binPath = amxPath + ".bin";
			std::FILE *bin = std::fopen(binPath.c_str(), "w");
			if (bin != 0) {
				std::fwrite(jitter->getCode(), jitter->getCodeSize(), 1, bin);
				std::fclose(bin);
			}
		}

		::amx2jitter.insert(std::make_pair(amx, jitter));
	}

	return AMX_ERR_NONE;
}

PLUGIN_EXPORT int PLUGIN_CALL AmxUnload(AMX *amx)
{
	AmxToJitterMap::iterator it = amx2jitter.find(amx);
	if (it != amx2jitter.end()) {
		delete it->second;
		amx2jitter.erase(it);
	}
	return AMX_ERR_NONE;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: dbfld.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2004-08-23 08:29:27 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _DBFLD_HXX
#define _DBFLD_HXX

#ifndef INCLUDED_SWDLLAPI_H
#include "swdllapi.h"
#endif
#ifndef _FLDBAS_HXX
#include "fldbas.hxx"
#endif
#ifndef _SWDBDATA_HXX
#include "swdbdata.hxx"
#endif

class SwDoc;
class SwTxtFld;
class SwFrm;

/*--------------------------------------------------------------------
    Beschreibung: Datenbankfeld
 --------------------------------------------------------------------*/

class SW_DLLPUBLIC SwDBFieldType : public SwValueFieldType
{
    SwDBData    aDBData;        //
    String      sName;          // only used in ::GetName() !
    String      sColumn;
    long        nRefCnt;

public:

    SwDBFieldType(SwDoc* pDocPtr, const String& rColumnName, const SwDBData& rDBData);

    virtual const String& GetName() const;
    virtual SwFieldType*  Copy() const;

    inline void     AddRef() { nRefCnt++; }
    void            ReleaseRef();
    inline long     GetRefCount() { return nRefCnt; }

    const String&   GetColumnName() const {return sColumn;}
    const SwDBData& GetDBData() const {return aDBData;}

    virtual BOOL        QueryValue( com::sun::star::uno::Any& rVal, BYTE nMId ) const;
    virtual BOOL        PutValue( const com::sun::star::uno::Any& rVal, BYTE nMId );
};

/*--------------------------------------------------------------------
    Beschreibung:
    von SwFields abgeleitete Klassen. Sie ueberlagern die Expand-Funktion.
    Der Inhalt wird entsprechend dem Format, soweit vorhanden, formatiert.
 --------------------------------------------------------------------*/

class SW_DLLPUBLIC SwDBField : public SwValueField
{
    String  aContent;
    USHORT  nSubType;
    BOOL    bIsInBodyTxt    : 1;
    BOOL    bValidValue     : 1;
    BOOL    bInitialized    : 1;

public:
    SwDBField(SwDBFieldType*, ULONG nFmt = 0);
    virtual ~SwDBField();

    virtual SwFieldType*    ChgTyp( SwFieldType* );

    // Der aktuelle Text
    inline  void        SetExpansion(const String& rStr);
    virtual String      Expand() const;
    virtual SwField*    Copy() const;

    virtual USHORT      GetSubType() const;
    virtual void        SetSubType(USHORT nType);

    // Name oder Inhalt
    virtual String      GetCntnt(BOOL bName = FALSE) const;

    // fuer Berechnungen in Ausdruecken
    void                ChgValue( double d, BOOL bVal );

    // Evaluierung ueber den DBMgr String rauspulen
    void                Evaluate();

    // Evaluierung fuer Kopf und Fusszeilen
    void                ChangeExpansion( const SwFrm*, const SwTxtFld* );
    void                InitContent();
    void                InitContent(const String& rExpansion);
    String              GetOldContent();

    inline void         ChgBodyTxtFlag( BOOL bIsInBody );
    inline BOOL         IsInBodyTxt() const;

    inline BOOL         IsValidValue() const    { return bValidValue; }

    inline BOOL         IsInitialized() const   { return bInitialized; }
    inline void         ClearInitialized()      { bInitialized = FALSE; }
    inline void         SetInitialized()        { bInitialized = TRUE; }

    // Name erfragen
    virtual const String& GetPar1() const;

    // DBName
    inline const SwDBData&  GetDBData() const { return ((SwDBFieldType*)GetTyp())->GetDBData(); }
    virtual BOOL        QueryValue( com::sun::star::uno::Any& rVal, BYTE nMId ) const;
    virtual BOOL        PutValue( const com::sun::star::uno::Any& rVal, BYTE nMId );
};

inline  void SwDBField::SetExpansion(const String& rStr)
    { aContent = rStr; }

// wird von der Formatierung abgefragt
inline BOOL SwDBField::IsInBodyTxt() const
    { return bIsInBodyTxt; }

// wird von UpdateExpFlds gesetzt (dort ist die Node-Position bekannt)
inline void SwDBField::ChgBodyTxtFlag( BOOL bIsInBody )
    { bIsInBodyTxt = bIsInBody; }

/*--------------------------------------------------------------------
    Beschreibung: Basisklasse fuer alle weiteren Datenbankfelder
 --------------------------------------------------------------------*/

class SW_DLLPUBLIC SwDBNameInfField : public SwField
{
    SwDBData    aDBData;
    USHORT      nSubType;

protected:
    const SwDBData& GetDBData() const {return aDBData;}
    SwDBData&       GetDBData() {return aDBData;}

    SwDBNameInfField(SwFieldType* pTyp, const SwDBData& rDBData, ULONG nFmt = 0);

public:
    // DBName
    inline const SwDBData&  GetRealDBData() { return aDBData; }

    SwDBData                GetDBData(SwDoc* pDoc);
    void                    SetDBData(const SwDBData& rDBData); // #111840#

    // Name oder Inhalt
    virtual String          GetCntnt(BOOL bName = FALSE) const;
    virtual BOOL            QueryValue( com::sun::star::uno::Any& rVal, BYTE nMId ) const;
    virtual BOOL            PutValue( const com::sun::star::uno::Any& rVal, BYTE nMId );
    virtual USHORT          GetSubType() const;
    virtual void            SetSubType(USHORT nType);
};

/*--------------------------------------------------------------------
    Beschreibung: Datenbankfeld Naechster Satz
 --------------------------------------------------------------------*/

class SwDBNextSetFieldType : public SwFieldType
{
public:
    SwDBNextSetFieldType();

    virtual SwFieldType*    Copy() const;
};

/*--------------------------------------------------------------------
    Beschreibung: Naechsten Datensatz mit Bedingung
 --------------------------------------------------------------------*/

class SW_DLLPUBLIC SwDBNextSetField : public SwDBNameInfField
{
    String  aCond;
    BOOL    bCondValid;

public:
    SwDBNextSetField( SwDBNextSetFieldType*,
                      const String& rCond, const String& rDummy, const SwDBData& rDBData);

    virtual String          Expand() const;
    virtual SwField*        Copy() const;

    void                    Evaluate(SwDoc*);
    inline void             SetCondValid(BOOL bCond);
    inline BOOL             IsCondValid() const;

    // Condition
    virtual const String&   GetPar1() const;
    virtual void            SetPar1(const String& rStr);
    virtual BOOL        QueryValue( com::sun::star::uno::Any& rVal, BYTE nMId ) const;
    virtual BOOL        PutValue( const com::sun::star::uno::Any& rVal, BYTE nMId );
};

inline BOOL SwDBNextSetField::IsCondValid() const
    { return bCondValid; }

inline void SwDBNextSetField::SetCondValid(BOOL bCond)
    { bCondValid = bCond; }

/*--------------------------------------------------------------------
    Beschreibung: Datenbankfeld Naechster Satz
 --------------------------------------------------------------------*/

class SwDBNumSetFieldType : public SwFieldType
{
public:
    SwDBNumSetFieldType();

    virtual SwFieldType*    Copy() const;
};

/*--------------------------------------------------------------------
    Beschreibung: Datensatz mit Nummer xxx
                  Die Nummer steht in nFormat
                  ! kleiner Missbrauch
 --------------------------------------------------------------------*/

class SwDBNumSetField : public SwDBNameInfField
{
    String  aCond;
    String  aPar2;
    BOOL    bCondValid;

public:
    SwDBNumSetField(SwDBNumSetFieldType*, const String& rCond, const String& rDBNum, const SwDBData& rDBData);

    virtual String          Expand() const;
    virtual SwField*        Copy() const;

    inline BOOL             IsCondValid() const;
    inline void             SetCondValid(BOOL bCond);
    void                    Evaluate(SwDoc*);

    // Condition
    virtual const String&   GetPar1() const;
    virtual void            SetPar1(const String& rStr);

    // Datensatznummer
    virtual String          GetPar2()   const;
    virtual void            SetPar2(const String& rStr);

    // Die Datensatznummer steht in nFormat !!
    virtual BOOL        QueryValue( com::sun::star::uno::Any& rVal, BYTE nMId ) const;
    virtual BOOL        PutValue( const com::sun::star::uno::Any& rVal, BYTE nMId );
};

inline BOOL SwDBNumSetField::IsCondValid() const
    { return bCondValid; }

inline void SwDBNumSetField::SetCondValid(BOOL bCond)
    { bCondValid = bCond; }

/*--------------------------------------------------------------------
    Beschreibung: Datenbankname
 --------------------------------------------------------------------*/

class SwDBNameFieldType : public SwFieldType
{
        SwDoc *pDoc;
public:
    SwDBNameFieldType(SwDoc*);

    String                  Expand(ULONG) const;
    virtual SwFieldType*    Copy() const;
};

/*--------------------------------------------------------------------
    Beschreibung: Datenbankfeld
 --------------------------------------------------------------------*/

class SwDBNameField : public SwDBNameInfField
{
public:
    SwDBNameField(SwDBNameFieldType*, const SwDBData& rDBData, ULONG nFmt = 0);

    virtual String   Expand() const;
    virtual SwField* Copy() const;
    virtual BOOL        QueryValue( com::sun::star::uno::Any& rVal, BYTE nMId ) const;
    virtual BOOL        PutValue( const com::sun::star::uno::Any& rVal, BYTE nMId );
};

/*--------------------------------------------------------------------
    Beschreibung: Datensatznummer
 --------------------------------------------------------------------*/

class SwDBSetNumberFieldType : public SwFieldType
{
public:
    SwDBSetNumberFieldType();

    virtual SwFieldType*    Copy() const;
};

/*--------------------------------------------------------------------
    Beschreibung: Datenbankfeld
 --------------------------------------------------------------------*/

class SwDBSetNumberField : public SwDBNameInfField
{
    long    nNumber;

public:
    SwDBSetNumberField(SwDBSetNumberFieldType*, const SwDBData& rDBData, ULONG nFmt = 0);

    virtual String  Expand() const;
    virtual         SwField* Copy() const;
    void            Evaluate(SwDoc*);

    inline long     GetSetNumber() const;
    inline void     SetSetNumber(long nNum);
    virtual BOOL        QueryValue( com::sun::star::uno::Any& rVal, BYTE nMId ) const;
    virtual BOOL        PutValue( const com::sun::star::uno::Any& rVal, BYTE nMId );
};

inline long SwDBSetNumberField::GetSetNumber() const
    { return nNumber; }

inline void SwDBSetNumberField::SetSetNumber(long nNum)
    { nNumber = nNum; }

#endif // _DBFLD_HXX
<commit_msg>INTEGRATION: CWS ooo19126 (1.6.596); FILE MERGED 2005/09/05 13:35:48 rt 1.6.596.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: dbfld.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 01:38:39 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _DBFLD_HXX
#define _DBFLD_HXX

#ifndef INCLUDED_SWDLLAPI_H
#include "swdllapi.h"
#endif
#ifndef _FLDBAS_HXX
#include "fldbas.hxx"
#endif
#ifndef _SWDBDATA_HXX
#include "swdbdata.hxx"
#endif

class SwDoc;
class SwTxtFld;
class SwFrm;

/*--------------------------------------------------------------------
    Beschreibung: Datenbankfeld
 --------------------------------------------------------------------*/

class SW_DLLPUBLIC SwDBFieldType : public SwValueFieldType
{
    SwDBData    aDBData;        //
    String      sName;          // only used in ::GetName() !
    String      sColumn;
    long        nRefCnt;

public:

    SwDBFieldType(SwDoc* pDocPtr, const String& rColumnName, const SwDBData& rDBData);

    virtual const String& GetName() const;
    virtual SwFieldType*  Copy() const;

    inline void     AddRef() { nRefCnt++; }
    void            ReleaseRef();
    inline long     GetRefCount() { return nRefCnt; }

    const String&   GetColumnName() const {return sColumn;}
    const SwDBData& GetDBData() const {return aDBData;}

    virtual BOOL        QueryValue( com::sun::star::uno::Any& rVal, BYTE nMId ) const;
    virtual BOOL        PutValue( const com::sun::star::uno::Any& rVal, BYTE nMId );
};

/*--------------------------------------------------------------------
    Beschreibung:
    von SwFields abgeleitete Klassen. Sie ueberlagern die Expand-Funktion.
    Der Inhalt wird entsprechend dem Format, soweit vorhanden, formatiert.
 --------------------------------------------------------------------*/

class SW_DLLPUBLIC SwDBField : public SwValueField
{
    String  aContent;
    USHORT  nSubType;
    BOOL    bIsInBodyTxt    : 1;
    BOOL    bValidValue     : 1;
    BOOL    bInitialized    : 1;

public:
    SwDBField(SwDBFieldType*, ULONG nFmt = 0);
    virtual ~SwDBField();

    virtual SwFieldType*    ChgTyp( SwFieldType* );

    // Der aktuelle Text
    inline  void        SetExpansion(const String& rStr);
    virtual String      Expand() const;
    virtual SwField*    Copy() const;

    virtual USHORT      GetSubType() const;
    virtual void        SetSubType(USHORT nType);

    // Name oder Inhalt
    virtual String      GetCntnt(BOOL bName = FALSE) const;

    // fuer Berechnungen in Ausdruecken
    void                ChgValue( double d, BOOL bVal );

    // Evaluierung ueber den DBMgr String rauspulen
    void                Evaluate();

    // Evaluierung fuer Kopf und Fusszeilen
    void                ChangeExpansion( const SwFrm*, const SwTxtFld* );
    void                InitContent();
    void                InitContent(const String& rExpansion);
    String              GetOldContent();

    inline void         ChgBodyTxtFlag( BOOL bIsInBody );
    inline BOOL         IsInBodyTxt() const;

    inline BOOL         IsValidValue() const    { return bValidValue; }

    inline BOOL         IsInitialized() const   { return bInitialized; }
    inline void         ClearInitialized()      { bInitialized = FALSE; }
    inline void         SetInitialized()        { bInitialized = TRUE; }

    // Name erfragen
    virtual const String& GetPar1() const;

    // DBName
    inline const SwDBData&  GetDBData() const { return ((SwDBFieldType*)GetTyp())->GetDBData(); }
    virtual BOOL        QueryValue( com::sun::star::uno::Any& rVal, BYTE nMId ) const;
    virtual BOOL        PutValue( const com::sun::star::uno::Any& rVal, BYTE nMId );
};

inline  void SwDBField::SetExpansion(const String& rStr)
    { aContent = rStr; }

// wird von der Formatierung abgefragt
inline BOOL SwDBField::IsInBodyTxt() const
    { return bIsInBodyTxt; }

// wird von UpdateExpFlds gesetzt (dort ist die Node-Position bekannt)
inline void SwDBField::ChgBodyTxtFlag( BOOL bIsInBody )
    { bIsInBodyTxt = bIsInBody; }

/*--------------------------------------------------------------------
    Beschreibung: Basisklasse fuer alle weiteren Datenbankfelder
 --------------------------------------------------------------------*/

class SW_DLLPUBLIC SwDBNameInfField : public SwField
{
    SwDBData    aDBData;
    USHORT      nSubType;

protected:
    const SwDBData& GetDBData() const {return aDBData;}
    SwDBData&       GetDBData() {return aDBData;}

    SwDBNameInfField(SwFieldType* pTyp, const SwDBData& rDBData, ULONG nFmt = 0);

public:
    // DBName
    inline const SwDBData&  GetRealDBData() { return aDBData; }

    SwDBData                GetDBData(SwDoc* pDoc);
    void                    SetDBData(const SwDBData& rDBData); // #111840#

    // Name oder Inhalt
    virtual String          GetCntnt(BOOL bName = FALSE) const;
    virtual BOOL            QueryValue( com::sun::star::uno::Any& rVal, BYTE nMId ) const;
    virtual BOOL            PutValue( const com::sun::star::uno::Any& rVal, BYTE nMId );
    virtual USHORT          GetSubType() const;
    virtual void            SetSubType(USHORT nType);
};

/*--------------------------------------------------------------------
    Beschreibung: Datenbankfeld Naechster Satz
 --------------------------------------------------------------------*/

class SwDBNextSetFieldType : public SwFieldType
{
public:
    SwDBNextSetFieldType();

    virtual SwFieldType*    Copy() const;
};

/*--------------------------------------------------------------------
    Beschreibung: Naechsten Datensatz mit Bedingung
 --------------------------------------------------------------------*/

class SW_DLLPUBLIC SwDBNextSetField : public SwDBNameInfField
{
    String  aCond;
    BOOL    bCondValid;

public:
    SwDBNextSetField( SwDBNextSetFieldType*,
                      const String& rCond, const String& rDummy, const SwDBData& rDBData);

    virtual String          Expand() const;
    virtual SwField*        Copy() const;

    void                    Evaluate(SwDoc*);
    inline void             SetCondValid(BOOL bCond);
    inline BOOL             IsCondValid() const;

    // Condition
    virtual const String&   GetPar1() const;
    virtual void            SetPar1(const String& rStr);
    virtual BOOL        QueryValue( com::sun::star::uno::Any& rVal, BYTE nMId ) const;
    virtual BOOL        PutValue( const com::sun::star::uno::Any& rVal, BYTE nMId );
};

inline BOOL SwDBNextSetField::IsCondValid() const
    { return bCondValid; }

inline void SwDBNextSetField::SetCondValid(BOOL bCond)
    { bCondValid = bCond; }

/*--------------------------------------------------------------------
    Beschreibung: Datenbankfeld Naechster Satz
 --------------------------------------------------------------------*/

class SwDBNumSetFieldType : public SwFieldType
{
public:
    SwDBNumSetFieldType();

    virtual SwFieldType*    Copy() const;
};

/*--------------------------------------------------------------------
    Beschreibung: Datensatz mit Nummer xxx
                  Die Nummer steht in nFormat
                  ! kleiner Missbrauch
 --------------------------------------------------------------------*/

class SwDBNumSetField : public SwDBNameInfField
{
    String  aCond;
    String  aPar2;
    BOOL    bCondValid;

public:
    SwDBNumSetField(SwDBNumSetFieldType*, const String& rCond, const String& rDBNum, const SwDBData& rDBData);

    virtual String          Expand() const;
    virtual SwField*        Copy() const;

    inline BOOL             IsCondValid() const;
    inline void             SetCondValid(BOOL bCond);
    void                    Evaluate(SwDoc*);

    // Condition
    virtual const String&   GetPar1() const;
    virtual void            SetPar1(const String& rStr);

    // Datensatznummer
    virtual String          GetPar2()   const;
    virtual void            SetPar2(const String& rStr);

    // Die Datensatznummer steht in nFormat !!
    virtual BOOL        QueryValue( com::sun::star::uno::Any& rVal, BYTE nMId ) const;
    virtual BOOL        PutValue( const com::sun::star::uno::Any& rVal, BYTE nMId );
};

inline BOOL SwDBNumSetField::IsCondValid() const
    { return bCondValid; }

inline void SwDBNumSetField::SetCondValid(BOOL bCond)
    { bCondValid = bCond; }

/*--------------------------------------------------------------------
    Beschreibung: Datenbankname
 --------------------------------------------------------------------*/

class SwDBNameFieldType : public SwFieldType
{
        SwDoc *pDoc;
public:
    SwDBNameFieldType(SwDoc*);

    String                  Expand(ULONG) const;
    virtual SwFieldType*    Copy() const;
};

/*--------------------------------------------------------------------
    Beschreibung: Datenbankfeld
 --------------------------------------------------------------------*/

class SwDBNameField : public SwDBNameInfField
{
public:
    SwDBNameField(SwDBNameFieldType*, const SwDBData& rDBData, ULONG nFmt = 0);

    virtual String   Expand() const;
    virtual SwField* Copy() const;
    virtual BOOL        QueryValue( com::sun::star::uno::Any& rVal, BYTE nMId ) const;
    virtual BOOL        PutValue( const com::sun::star::uno::Any& rVal, BYTE nMId );
};

/*--------------------------------------------------------------------
    Beschreibung: Datensatznummer
 --------------------------------------------------------------------*/

class SwDBSetNumberFieldType : public SwFieldType
{
public:
    SwDBSetNumberFieldType();

    virtual SwFieldType*    Copy() const;
};

/*--------------------------------------------------------------------
    Beschreibung: Datenbankfeld
 --------------------------------------------------------------------*/

class SwDBSetNumberField : public SwDBNameInfField
{
    long    nNumber;

public:
    SwDBSetNumberField(SwDBSetNumberFieldType*, const SwDBData& rDBData, ULONG nFmt = 0);

    virtual String  Expand() const;
    virtual         SwField* Copy() const;
    void            Evaluate(SwDoc*);

    inline long     GetSetNumber() const;
    inline void     SetSetNumber(long nNum);
    virtual BOOL        QueryValue( com::sun::star::uno::Any& rVal, BYTE nMId ) const;
    virtual BOOL        PutValue( const com::sun::star::uno::Any& rVal, BYTE nMId );
};

inline long SwDBSetNumberField::GetSetNumber() const
    { return nNumber; }

inline void SwDBSetNumberField::SetSetNumber(long nNum)
    { nNumber = nNum; }

#endif // _DBFLD_HXX
<|endoftext|>


<commit_before><commit_msg>Little Speed boost for rotation Matrix<commit_after><|endoftext|>


<commit_before>#include "enemy.h"
#include <string>
#include <cstdlib>
#include "player.h"

using namespace std;

Enemy::Enemy(Player* player) {
    maxHP = player->getMAX_HP();
    minDamage = player->minDamage();
    maxDamage = player->maxDamage();
    this->player = player;
    weight = 0;
    setPrefix();
    setName();
    setSuffix();
    HP = maxHP;
}

Enemy::~Enemy()
{

}

void Enemy::setPrefix() {
    int level = 0;
    if (player->getLevel() > 50)
        level = 60;
    else
        level = player->getLevel();
    if ((rand() % (101 + level)) - level >= 95) {
        prefix = "Mythic";
        maxHP += getMAX_HP() / 2;
        weight += 10;
    } else if ((rand() % (101 + level)) - level >= 80) {
        prefix = "Heroic";
        maxHP += getMAX_HP() / 5;
        weight += 5;
    } else if ((rand() % (101 + level)) - level >= 50) {
        prefix = "Angry";
        maxHP += getMAX_HP() / 10;
        weight += 2;
    } else if ((rand() % (101 + level)) - level >= 0)
        prefix = "";
}

void Enemy::setName() {
    if (rand() % 101 >= 80) {
        name = "Goblin";
    } else if (rand() % 101 >= 60) {
        name = "Orc";
        maxHP += getMAX_HP() / 10;
        weight += 5;
    } else if (rand() % 101 >= 40) {
        name = "Human";
    } else if (rand() % 101 >= 20) {
        name = "Half-Elf";
    } else if (rand() % 101 >= 0) {
        name = "Demon";
        maxHP += getMAX_HP() / 5;
        weight += 10;
    }
}

void Enemy::setSuffix() {
    int level = 0;
    if (player->getLevel() > 50)
        level = 60;
    else
        level = player->getLevel();
    if ((rand() % (101 + level)) - level >= 99) {
        suffix = "Boss";
        weight += 10;
    } else if ((rand() % (101 + level)) - level >= 95) {
        suffix = "Warlord";
        weight += 5;
    } else if ((rand() % (101 + level)) - level >= 80) {
        suffix = "Spellblade";
        weight += 2;
    } else if ((rand() % (101 + level)) - level >= 50) {
        suffix = "Warrior";
        weight += 1;
    } else if ((rand() % (101 + level)) - level >= 0) {
        suffix = "";
    }
}

int Enemy::getWeight() {
    return weight;
}

bool Enemy::alive() {
    if (HP > 0)
        return true;
    else
        return false;
}

string Enemy::getName() {
    string toString = "";
    if (prefix != "")
        toString += prefix + " ";
    toString += name;
    if (suffix != "")
        toString += " " + suffix;
    return toString;
}

int Enemy::getHP() {
    return HP;
}

void Enemy::setHP(int hp) {
    HP = hp;
}

int Enemy::getMAX_HP() {
    return maxHP;
}

void Enemy::setMAX_HP(int maxHP) {
    this->maxHP = maxHP;
}

int Enemy::getMod() {
    int mod = 0;
    if(prefix == "Mythic")
        mod += 3;
    else if(prefix == "Heroic")
        mod += 2;
    else if(prefix == "Angry")
        mod += 1;

    if(suffix == "Boss")
        mod += 3;
    else  if(suffix == "Warlord")
        mod += 2;
    else if(suffix == "Spell")
        mod += 1;
    if (name == "Orc")
        mod += 1;
    else if (name == "Demon")
        mod += 3;
    mod *= player->getLevel();
    if (mod > maxDamage)
        mod = maxDamage;
    return mod;
}

int Enemy::getMinDamage() {
    return minDamage + getMod();
}

int Enemy::getMaxDamage() {
    return maxDamage + getMod();
}

Player Enemy::meleeAttack(Player actor, bool block) {
    int damage = abs((rand() % (getMaxDamage() - getMinDamage()) + getMinDamage()) * (rand() % (getMaxDamage() + getMod()))) / (player->getLevel() + (getMod() / 5));
    if (damage <= 0) {
        return meleeAttack(actor, block);
    }
    if (!actor.block(block)) {
        actor.setHP(actor.getHP() - damage);
        // TODO Print damage here
    } else {
        // TODO Print damage here
    }
    return actor;
}

Player Enemy::magicAttack(Player actor, bool dodge) {
    int damage = abs((rand() % (getMaxDamage() - getMinDamage()) + getMinDamage()) * (rand() % (getMaxDamage() + getMod()))) / (player->getLevel() + (getMod() / 5));
    if (damage <= 0) {
        return meleeAttack(actor, dodge);
    }
    if (!actor.dodge(dodge)) {
        actor.setHP(actor.getHP() - damage);
        // TODO Print damage here
    } else {
        // TODO Print damage here
    }
    return actor;
}

bool Enemy::block(Player* actor, bool& ability) {
    int blockChance = 90 - ((actor->getDex() + getMod()) / 5);
    if (blockChance < 60)
        blockChance = 60;
    if (ability || rand() % 100 > blockChance)
        return true;
    return false;
}

bool Enemy::dodge(Player* actor, bool& ability) {
    int dodgeChance = 90 - ((actor->getDex() + getMod()) / 5);
    if (dodgeChance < 60)
        dodgeChance = 60;
    if (ability || rand() % 100 > dodgeChance)
        return true;
    return false;
}
<commit_msg>Delete enemy.cpp<commit_after><|endoftext|>


<commit_before>/*******************************************************************************
 * libproxy - A library for proxy configuration
 * Copyright (C) 2006 Nathaniel McCallum <nathaniel@natemccallum.com>
 * Copyright (C) 2016 Fabian Vogt <fvogt@suse.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * 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
 ******************************************************************************/

#include <sys/stat.h>
#include <unistd.h>

#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <sstream>

#include "../extension_config.hpp"
using namespace libproxy;

class kde_config_extension : public config_extension {
public:
    kde_config_extension()
        : cache_time(0)
    {
        try {
            // Try the KF5 one first
            command = "kreadconfig5";
            command_output("kreadconfig5 --key nonexistant");

            try {
                parse_dir_list(command_output("qtpaths --paths GenericConfigLocation"));
            }
            catch(...) {}

            return; // Worked
        }
        catch(...) {}

        try {
            // The KDE4 one next
            command = "kreadconfig";
            command_output(command);

            try {
                parse_dir_list(command_output("kde4-config --path config"));
            }
            catch(...) {}

            return; // Worked
        }
        catch(...) {}

        // Neither worked, so throw in get_config
        command = "";
    }

    vector<url> get_config(const url &dst) throw (runtime_error) {
        // See constructor
        if(command.empty())
            throw runtime_error("Unable to read configuration");

        vector<url> response;

        string tmp, proxyType = kde_config_val("ProxyType", "-1");

        // Just switch on the first byte, either a digit, '-' ("-1") or '\0'
        switch(proxyType.c_str()[0])
        {
        case '1':
            tmp = kde_config_val(dst.get_scheme() + "Proxy", "");
            if(tmp.empty()) {
                tmp = kde_config_val("httpProxy", "");
                if(tmp.empty()) {
                    tmp = kde_config_val("socksProxy", "");
                    if(tmp.empty())
                        tmp = "direct://";
                }
            }

            // KDE uses "http://127.0.0.1 8080" instead of "http://127.0.0.1:8080"
            replace(tmp.begin(), tmp.end(), ' ', ':');

            response.push_back(url(tmp));
            break;

        case '2':
            tmp = "pac+" + kde_config_val("Proxy Config Script", "");
            if (url::is_valid(tmp))
            {
                response.push_back(url(tmp));
                break;
            }
            // else fallthrough

        case '3':
            response.push_back(url(string("wpad://")));
            break;

        case '4':
            throw runtime_error("User config_envvar"); // We'll bypass this config plugin and let the envvar plugin wor

        case '0':
        default: // Not set or unknown/illegal
            response.push_back(url("direct://"));
            break;
        }

        return response;
	}

	string get_ignore(const url&) {
        // See constructor
        if(command.empty())
            return "";

        string proxyType = kde_config_val("ProxyType", "-1");
        if(proxyType.c_str()[0] != '1')
            return ""; // Not manual config

        string prefix = kde_config_val("ReversedException", "false") != "false" ? "-" : "";
        return prefix + kde_config_val("NoProxyFor", ""); // Already in the right format
	}

private:
    string command_output(const string &cmdline) throw (runtime_error) {
        // Capture stderr as well
        const string command = "(" + cmdline + ")2>&1";
        FILE *pipe = popen(command.c_str(), "r");
        if (!pipe)
            throw runtime_error("Unable to run command");

        char buffer[128];
        string result = "";
        while (!feof(pipe)) {
            if (fgets(buffer, 128, pipe) != NULL)
                result += buffer; // TODO: If this throws bad_alloc, pipe is leaked
        }

        if(pclose(pipe) != 0)
            throw runtime_error("Command failed");

        // Trim newlines and whitespace at end
        result.erase(result.begin() + (result.find_last_not_of(" \n\t")+1), result.end());

        return result;
    }

    // Neither key nor def must contain '
    const string &kde_config_val(const string &key, const string &def) throw (runtime_error) {
        if (cache_needs_refresh())
            cache.clear();
        else {
            // Already in cache?
            map<string, string>::iterator it = cache.find(key);
            if(it != cache.end())
                return it->second;
        }

        // Although all values are specified internally and/or validated,
        // checking is better than trusting.
        if(key.find('\'') != string::npos || def.find('\'') != string::npos)
            return def;

        // Add result to cache and return it
        return cache[key] = command_output(
                command + " --file kioslaverc --group 'Proxy Settings' --key '" + key + "' --default '" + def + "'");
    }

    // Used for cache invalidation
    struct configfile {
        string path;
        time_t mtime; // 0 means it doesn't exist
    };

    // Parses output of qtpaths/kde4-config to fill config_locs
    void parse_dir_list(const string &dirs) {
        string config_path;
        stringstream config_paths_stream(dirs);

        // Try each of the listed folders, seperated by ':'
        while (getline(config_paths_stream, config_path, ':')) {
            configfile config_loc; config_loc.path = config_path + "/kioslaverc";
            config_locs.push_back(config_loc);
        }
    }

    // If any of the locations in config_locs changed (different mtime),
    // update config_locs and return true.
    bool cache_needs_refresh() {
        // Play safe here, if we can't determine the location,
        // don't cache at all.
        bool needs_refresh = config_locs.empty();
        struct stat config_info;

        for (unsigned int i = 0; i < config_locs.size(); ++i) {
            configfile &config = config_locs[i];
            time_t current_mtime = stat(config.path.c_str(), &config_info) == 0 ? config_info.st_mtime : 0;
            if (config.mtime != current_mtime) {
                config.mtime = current_mtime;
                needs_refresh = true;
            }
        }

        return needs_refresh;
    }

    // Whether to use kreadconfig or kreadconfig5
    string command;
    // When the cache was flushed last
    time_t cache_time;
    // Cache for config values
    map<string, string> cache;
    // State of the config files at the time of the last cache flush
    vector<configfile> config_locs;
};

MM_MODULE_INIT_EZ(kde_config_extension, getenv("KDE_FULL_SESSION"), NULL, NULL);
<commit_msg>config_kde: Initialize config_loc.mtime explicitly<commit_after>/*******************************************************************************
 * libproxy - A library for proxy configuration
 * Copyright (C) 2006 Nathaniel McCallum <nathaniel@natemccallum.com>
 * Copyright (C) 2016 Fabian Vogt <fvogt@suse.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * 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
 ******************************************************************************/

#include <sys/stat.h>
#include <unistd.h>

#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <sstream>

#include "../extension_config.hpp"
using namespace libproxy;

class kde_config_extension : public config_extension {
public:
    kde_config_extension()
        : cache_time(0)
    {
        try {
            // Try the KF5 one first
            command = "kreadconfig5";
            command_output("kreadconfig5 --key nonexistant");

            try {
                parse_dir_list(command_output("qtpaths --paths GenericConfigLocation"));
            }
            catch(...) {}

            return; // Worked
        }
        catch(...) {}

        try {
            // The KDE4 one next
            command = "kreadconfig";
            command_output(command);

            try {
                parse_dir_list(command_output("kde4-config --path config"));
            }
            catch(...) {}

            return; // Worked
        }
        catch(...) {}

        // Neither worked, so throw in get_config
        command = "";
    }

    vector<url> get_config(const url &dst) throw (runtime_error) {
        // See constructor
        if(command.empty())
            throw runtime_error("Unable to read configuration");

        vector<url> response;

        string tmp, proxyType = kde_config_val("ProxyType", "-1");

        // Just switch on the first byte, either a digit, '-' ("-1") or '\0'
        switch(proxyType.c_str()[0])
        {
        case '1':
            tmp = kde_config_val(dst.get_scheme() + "Proxy", "");
            if(tmp.empty()) {
                tmp = kde_config_val("httpProxy", "");
                if(tmp.empty()) {
                    tmp = kde_config_val("socksProxy", "");
                    if(tmp.empty())
                        tmp = "direct://";
                }
            }

            // KDE uses "http://127.0.0.1 8080" instead of "http://127.0.0.1:8080"
            replace(tmp.begin(), tmp.end(), ' ', ':');

            response.push_back(url(tmp));
            break;

        case '2':
            tmp = "pac+" + kde_config_val("Proxy Config Script", "");
            if (url::is_valid(tmp))
            {
                response.push_back(url(tmp));
                break;
            }
            // else fallthrough

        case '3':
            response.push_back(url(string("wpad://")));
            break;

        case '4':
            throw runtime_error("User config_envvar"); // We'll bypass this config plugin and let the envvar plugin wor

        case '0':
        default: // Not set or unknown/illegal
            response.push_back(url("direct://"));
            break;
        }

        return response;
	}

	string get_ignore(const url&) {
        // See constructor
        if(command.empty())
            return "";

        string proxyType = kde_config_val("ProxyType", "-1");
        if(proxyType.c_str()[0] != '1')
            return ""; // Not manual config

        string prefix = kde_config_val("ReversedException", "false") != "false" ? "-" : "";
        return prefix + kde_config_val("NoProxyFor", ""); // Already in the right format
	}

private:
    string command_output(const string &cmdline) throw (runtime_error) {
        // Capture stderr as well
        const string command = "(" + cmdline + ")2>&1";
        FILE *pipe = popen(command.c_str(), "r");
        if (!pipe)
            throw runtime_error("Unable to run command");

        char buffer[128];
        string result = "";
        while (!feof(pipe)) {
            if (fgets(buffer, 128, pipe) != NULL)
                result += buffer; // TODO: If this throws bad_alloc, pipe is leaked
        }

        if(pclose(pipe) != 0)
            throw runtime_error("Command failed");

        // Trim newlines and whitespace at end
        result.erase(result.begin() + (result.find_last_not_of(" \n\t")+1), result.end());

        return result;
    }

    // Neither key nor def must contain '
    const string &kde_config_val(const string &key, const string &def) throw (runtime_error) {
        if (cache_needs_refresh())
            cache.clear();
        else {
            // Already in cache?
            map<string, string>::iterator it = cache.find(key);
            if(it != cache.end())
                return it->second;
        }

        // Although all values are specified internally and/or validated,
        // checking is better than trusting.
        if(key.find('\'') != string::npos || def.find('\'') != string::npos)
            return def;

        // Add result to cache and return it
        return cache[key] = command_output(
                command + " --file kioslaverc --group 'Proxy Settings' --key '" + key + "' --default '" + def + "'");
    }

    // Used for cache invalidation
    struct configfile {
        string path;
        time_t mtime; // 0 means either not refreshed or doesn't exist
    };

    // Parses output of qtpaths/kde4-config to fill config_locs
    void parse_dir_list(const string &dirs) {
        string config_path;
        stringstream config_paths_stream(dirs);

        // Try each of the listed folders, seperated by ':'
        while (getline(config_paths_stream, config_path, ':')) {
            configfile config_loc;
            config_loc.path = config_path + "/kioslaverc";
            config_loc.mtime = 0;
            config_locs.push_back(config_loc);
        }
    }

    // If any of the locations in config_locs changed (different mtime),
    // update config_locs and return true.
    bool cache_needs_refresh() {
        // Play safe here, if we can't determine the location,
        // don't cache at all.
        bool needs_refresh = config_locs.empty();
        struct stat config_info;

        for (unsigned int i = 0; i < config_locs.size(); ++i) {
            configfile &config = config_locs[i];
            time_t current_mtime = stat(config.path.c_str(), &config_info) == 0 ? config_info.st_mtime : 0;
            if (config.mtime != current_mtime) {
                config.mtime = current_mtime;
                needs_refresh = true;
            }
        }

        return needs_refresh;
    }

    // Whether to use kreadconfig or kreadconfig5
    string command;
    // When the cache was flushed last
    time_t cache_time;
    // Cache for config values
    map<string, string> cache;
    // State of the config files at the time of the last cache flush
    vector<configfile> config_locs;
};

MM_MODULE_INIT_EZ(kde_config_extension, getenv("KDE_FULL_SESSION"), NULL, NULL);
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2003 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/* @file
 * EventQueue interfaces
 */

#ifndef __EVENTQ_HH__
#define __EVENTQ_HH__

#include <assert.h>

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

#include "sim/host.hh"	// for Tick

#include "base/fast_alloc.hh"
#include "sim/serialize.hh"
#include "base/trace.hh"

class EventQueue;	// forward declaration

/*
 * An item on an event queue.  The action caused by a given
 * event is specified by deriving a subclass and overriding the
 * process() member function.
 */
class Event : public Serializable, public FastAlloc
{
    friend class EventQueue;

  private:
    /// queue to which this event belongs (though it may or may not be
    /// scheduled on this queue yet)
    EventQueue *queue;

    Event *next;

    Tick _when;	//!< timestamp when event should be processed
    int _priority;	//!< event priority
    char _flags;

  protected:
    enum Flags {
        None = 0x0,
        Squashed = 0x1,
        Scheduled = 0x2,
        AutoDelete = 0x4,
        AutoSerialize = 0x8
    };

    bool getFlags(Flags f) const { return (_flags & f) == f; }
    void setFlags(Flags f) { _flags |= f; }
    void clearFlags(Flags f) { _flags &= ~f; }

  protected:
    EventQueue *theQueue() const { return queue; }

#if TRACING_ON
    Tick when_created;	//!< Keep track of creation time For debugging
    Tick when_scheduled;	//!< Keep track of creation time For debugging

    virtual void trace(const char *action);	//!< trace event activity
#else
    void trace(const char *) {}
#endif

    unsigned annotated_value;

  public:

    /// Event priorities, to provide tie-breakers for events scheduled
    /// at the same cycle.  Most events are scheduled at the default
    /// priority; these values are used to control events that need to
    /// be ordered within a cycle.
    enum Priority {
        /// Breakpoints should happen before anything else, so we
        /// don't miss any action when debugging.
        Debug_Break_Pri		= -100,

        /// For some reason "delayed" inter-cluster writebacks are
        /// scheduled before regular writebacks (which have default
        /// priority).  Steve?
        Delayed_Writeback_Pri	=   -1,

        /// Default is zero for historical reasons.
        Default_Pri		=    0,

        /// CPU switches schedule the new CPU's tick event for the
        /// same cycle (after unscheduling the old CPU's tick event).
        /// The switch needs to come before any tick events to make
        /// sure we don't tick both CPUs in the same cycle.
        CPU_Switch_Pri		=   31,

        /// Serailization needs to occur before tick events also, so
        /// that a serialize/unserialize is identical to an on-line
        /// CPU switch.
        Serialize_Pri		=   32,

        /// CPU ticks must come after other associated CPU events
        /// (such as writebacks).
        CPU_Tick_Pri		=   50,

        /// Statistics events (dump, reset, etc.) come after
        /// everything else, but before exit.
        Stat_Event_Pri		=   90,

        /// If we want to exit on this cycle, it's the very last thing
        /// we do.
        Sim_Exit_Pri		=  100
    };

    /*
     * Event constructor
     * @param queue that the event gets scheduled on
     */
    Event(EventQueue *q, Priority p = Default_Pri)
        : queue(q), next(NULL), _priority(p), _flags(None),
#if TRACING_ON
          when_created(curTick), when_scheduled(0),
#endif
          annotated_value(0)
    {
    }

    ~Event() {}

    virtual const std::string name() const {
        return csprintf("Event_%x", (uintptr_t)this);
    }

    /// Determine if the current event is scheduled
    bool scheduled() const { return getFlags(Scheduled); }

    /// Schedule the event with the current priority or default priority
    void schedule(Tick t);

    /// Reschedule the event with the current priority
    void reschedule(Tick t);

    /// Remove the event from the current schedule
    void deschedule();

    /// Return a C string describing the event.  This string should
    /// *not* be dynamically allocated; just a const char array
    /// describing the event class.
    virtual const char *description();

    /// Dump the current event data
    void dump();

    /*
     * This member function is invoked when the event is processed
     * (occurs).  There is no default implementation; each subclass
     * must provide its own implementation.  The event is not
     * automatically deleted after it is processed (to allow for
     * statically allocated event objects).
     *
     * If the AutoDestroy flag is set, the object is deleted once it
     * is processed.
     */
    virtual void process() = 0;

    void annotate(unsigned value) { annotated_value = value; };
    unsigned annotation() { return annotated_value; }

    /// Squash the current event
    void squash() { setFlags(Squashed); }

    /// Check whether the event is squashed
    bool squashed() { return getFlags(Squashed); }

    /// Get the time that the event is scheduled
    Tick when() const { return _when; }

    /// Get the event priority
    int priority() const { return _priority; }

    struct priority_compare :
    public std::binary_function<Event *, Event *, bool>
    {
        bool operator()(const Event *l, const Event *r) const {
            return l->when() >= r->when() || l->priority() >= r->priority();
        }
    };

    virtual void serialize(std::ostream &os);
    virtual void unserialize(Checkpoint *cp, const std::string &section);
};

template <class T, void (T::* F)()>
void
DelayFunction(Tick when, T *object)
{
    class DelayEvent : public Event
    {
      private:
        T *object;

      public:
        DelayEvent(Tick when, T *o)
            : Event(&mainEventQueue), object(o)
            { setFlags(AutoDestroy); schedule(when); }
        void process() { (object->*F)(); }
        const char *description() { return "delay"; }
    };

    new DelayEvent(when, object);
}

template <class T, void (T::* F)()>
class EventWrapper : public Event
{
  private:
    T *object;

  public:
    EventWrapper(T *obj, EventQueue *q = &mainEventQueue,
                 Priority p = Default_Pri)
        : Event(q, p), object(obj)
    {}
    void process() { (object->*F)(); }
};

/*
 * Queue of events sorted in time order
 */
class EventQueue : public Serializable
{
  protected:
    std::string objName;

  private:
    Event *head;

    void insert(Event *event);
    void remove(Event *event);

  public:

    // constructor
    EventQueue(const std::string &n)
        : objName(n), head(NULL)
    {}

    virtual const std::string name() const { return objName; }

    // schedule the given event on this queue
    void schedule(Event *ev);
    void deschedule(Event *ev);
    void reschedule(Event *ev);

    Tick nextTick() { return head->when(); }
    void serviceOne();

    // process all events up to the given timestamp.  we inline a
    // quick test to see if there are any events to process; if so,
    // call the internal out-of-line version to process them all.
    void serviceEvents(Tick when) {
        while (!empty()) {
            if (nextTick() > when)
                break;

            assert(head->when() >= when && "event scheduled in the past");
            serviceOne();
        }
    }

    // default: process all events up to 'now' (curTick)
    void serviceEvents() { serviceEvents(curTick); }

    // return true if no events are queued
    bool empty() { return head == NULL; }

    void dump();

    Tick nextEventTime() { return empty() ? curTick : head->when(); }

    virtual void serialize(std::ostream &os);
    virtual void unserialize(Checkpoint *cp, const std::string &section);
};

//////////////////////
//
// inline functions
//
// can't put these inside declaration due to circular dependence
// between Event and EventQueue classes.
//
//////////////////////

// schedule at specified time (place on event queue specified via
// constructor)
inline void
Event::schedule(Tick t)
{
    assert(!scheduled());
    setFlags(Scheduled);
#if TRACING_ON
    when_scheduled = curTick;
#endif
    _when = t;
    queue->schedule(this);
}

inline void
Event::deschedule()
{
    assert(scheduled());

    clearFlags(Squashed);
    clearFlags(Scheduled);
    queue->deschedule(this);
}

inline void
Event::reschedule(Tick t)
{
    assert(scheduled());
    clearFlags(Squashed);

#if TRACING_ON
    when_scheduled = curTick;
#endif
    _when = t;
    queue->reschedule(this);
}

inline void
EventQueue::schedule(Event *event)
{
    insert(event);
    if (DTRACE(Event))
        event->trace("scheduled");
}

inline void
EventQueue::deschedule(Event *event)
{
    remove(event);
    if (DTRACE(Event))
        event->trace("descheduled");
}

inline void
EventQueue::reschedule(Event *event)
{
    remove(event);
    insert(event);
    if (DTRACE(Event))
        event->trace("rescheduled");
}

//////////////////////
//
// Main Event Queue
//
// Events on this queue are processed at the *beginning* of each
// cycle, before the pipeline simulation is performed.
//
// defined in eventq.cc
//
//////////////////////
extern EventQueue mainEventQueue;

#endif // __EVENTQ_HH__
<commit_msg>constructor option to make the wrapped event autodelete<commit_after>/*
 * Copyright (c) 2003 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/* @file
 * EventQueue interfaces
 */

#ifndef __EVENTQ_HH__
#define __EVENTQ_HH__

#include <assert.h>

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

#include "sim/host.hh"	// for Tick

#include "base/fast_alloc.hh"
#include "sim/serialize.hh"
#include "base/trace.hh"

class EventQueue;	// forward declaration

/*
 * An item on an event queue.  The action caused by a given
 * event is specified by deriving a subclass and overriding the
 * process() member function.
 */
class Event : public Serializable, public FastAlloc
{
    friend class EventQueue;

  private:
    /// queue to which this event belongs (though it may or may not be
    /// scheduled on this queue yet)
    EventQueue *queue;

    Event *next;

    Tick _when;	//!< timestamp when event should be processed
    int _priority;	//!< event priority
    char _flags;

  protected:
    enum Flags {
        None = 0x0,
        Squashed = 0x1,
        Scheduled = 0x2,
        AutoDelete = 0x4,
        AutoSerialize = 0x8
    };

    bool getFlags(Flags f) const { return (_flags & f) == f; }
    void setFlags(Flags f) { _flags |= f; }
    void clearFlags(Flags f) { _flags &= ~f; }

  protected:
    EventQueue *theQueue() const { return queue; }

#if TRACING_ON
    Tick when_created;	//!< Keep track of creation time For debugging
    Tick when_scheduled;	//!< Keep track of creation time For debugging

    virtual void trace(const char *action);	//!< trace event activity
#else
    void trace(const char *) {}
#endif

    unsigned annotated_value;

  public:

    /// Event priorities, to provide tie-breakers for events scheduled
    /// at the same cycle.  Most events are scheduled at the default
    /// priority; these values are used to control events that need to
    /// be ordered within a cycle.
    enum Priority {
        /// Breakpoints should happen before anything else, so we
        /// don't miss any action when debugging.
        Debug_Break_Pri		= -100,

        /// For some reason "delayed" inter-cluster writebacks are
        /// scheduled before regular writebacks (which have default
        /// priority).  Steve?
        Delayed_Writeback_Pri	=   -1,

        /// Default is zero for historical reasons.
        Default_Pri		=    0,

        /// CPU switches schedule the new CPU's tick event for the
        /// same cycle (after unscheduling the old CPU's tick event).
        /// The switch needs to come before any tick events to make
        /// sure we don't tick both CPUs in the same cycle.
        CPU_Switch_Pri		=   31,

        /// Serailization needs to occur before tick events also, so
        /// that a serialize/unserialize is identical to an on-line
        /// CPU switch.
        Serialize_Pri		=   32,

        /// CPU ticks must come after other associated CPU events
        /// (such as writebacks).
        CPU_Tick_Pri		=   50,

        /// Statistics events (dump, reset, etc.) come after
        /// everything else, but before exit.
        Stat_Event_Pri		=   90,

        /// If we want to exit on this cycle, it's the very last thing
        /// we do.
        Sim_Exit_Pri		=  100
    };

    /*
     * Event constructor
     * @param queue that the event gets scheduled on
     */
    Event(EventQueue *q, Priority p = Default_Pri)
        : queue(q), next(NULL), _priority(p), _flags(None),
#if TRACING_ON
          when_created(curTick), when_scheduled(0),
#endif
          annotated_value(0)
    {
    }

    ~Event() {}

    virtual const std::string name() const {
        return csprintf("Event_%x", (uintptr_t)this);
    }

    /// Determine if the current event is scheduled
    bool scheduled() const { return getFlags(Scheduled); }

    /// Schedule the event with the current priority or default priority
    void schedule(Tick t);

    /// Reschedule the event with the current priority
    void reschedule(Tick t);

    /// Remove the event from the current schedule
    void deschedule();

    /// Return a C string describing the event.  This string should
    /// *not* be dynamically allocated; just a const char array
    /// describing the event class.
    virtual const char *description();

    /// Dump the current event data
    void dump();

    /*
     * This member function is invoked when the event is processed
     * (occurs).  There is no default implementation; each subclass
     * must provide its own implementation.  The event is not
     * automatically deleted after it is processed (to allow for
     * statically allocated event objects).
     *
     * If the AutoDestroy flag is set, the object is deleted once it
     * is processed.
     */
    virtual void process() = 0;

    void annotate(unsigned value) { annotated_value = value; };
    unsigned annotation() { return annotated_value; }

    /// Squash the current event
    void squash() { setFlags(Squashed); }

    /// Check whether the event is squashed
    bool squashed() { return getFlags(Squashed); }

    /// Get the time that the event is scheduled
    Tick when() const { return _when; }

    /// Get the event priority
    int priority() const { return _priority; }

    struct priority_compare :
    public std::binary_function<Event *, Event *, bool>
    {
        bool operator()(const Event *l, const Event *r) const {
            return l->when() >= r->when() || l->priority() >= r->priority();
        }
    };

    virtual void serialize(std::ostream &os);
    virtual void unserialize(Checkpoint *cp, const std::string &section);
};

template <class T, void (T::* F)()>
void
DelayFunction(Tick when, T *object)
{
    class DelayEvent : public Event
    {
      private:
        T *object;

      public:
        DelayEvent(Tick when, T *o)
            : Event(&mainEventQueue), object(o)
            { setFlags(AutoDestroy); schedule(when); }
        void process() { (object->*F)(); }
        const char *description() { return "delay"; }
    };

    new DelayEvent(when, object);
}

template <class T, void (T::* F)()>
class EventWrapper : public Event
{
  private:
    T *object;

  public:
    EventWrapper(T *obj, bool del = false, EventQueue *q = &mainEventQueue,
                 Priority p = Default_Pri)
        : Event(q, p), object(obj)
    {
        if (del)
            setFlags(AutoDelete);
    }
    void process() { (object->*F)(); }
};

/*
 * Queue of events sorted in time order
 */
class EventQueue : public Serializable
{
  protected:
    std::string objName;

  private:
    Event *head;

    void insert(Event *event);
    void remove(Event *event);

  public:

    // constructor
    EventQueue(const std::string &n)
        : objName(n), head(NULL)
    {}

    virtual const std::string name() const { return objName; }

    // schedule the given event on this queue
    void schedule(Event *ev);
    void deschedule(Event *ev);
    void reschedule(Event *ev);

    Tick nextTick() { return head->when(); }
    void serviceOne();

    // process all events up to the given timestamp.  we inline a
    // quick test to see if there are any events to process; if so,
    // call the internal out-of-line version to process them all.
    void serviceEvents(Tick when) {
        while (!empty()) {
            if (nextTick() > when)
                break;

            assert(head->when() >= when && "event scheduled in the past");
            serviceOne();
        }
    }

    // default: process all events up to 'now' (curTick)
    void serviceEvents() { serviceEvents(curTick); }

    // return true if no events are queued
    bool empty() { return head == NULL; }

    void dump();

    Tick nextEventTime() { return empty() ? curTick : head->when(); }

    virtual void serialize(std::ostream &os);
    virtual void unserialize(Checkpoint *cp, const std::string &section);
};

//////////////////////
//
// inline functions
//
// can't put these inside declaration due to circular dependence
// between Event and EventQueue classes.
//
//////////////////////

// schedule at specified time (place on event queue specified via
// constructor)
inline void
Event::schedule(Tick t)
{
    assert(!scheduled());
    assert(t >= curTick);

    setFlags(Scheduled);
#if TRACING_ON
    when_scheduled = curTick;
#endif
    _when = t;
    queue->schedule(this);
}

inline void
Event::deschedule()
{
    assert(scheduled());

    clearFlags(Squashed);
    clearFlags(Scheduled);
    queue->deschedule(this);
}

inline void
Event::reschedule(Tick t)
{
    assert(scheduled());
    clearFlags(Squashed);

#if TRACING_ON
    when_scheduled = curTick;
#endif
    _when = t;
    queue->reschedule(this);
}

inline void
EventQueue::schedule(Event *event)
{
    insert(event);
    if (DTRACE(Event))
        event->trace("scheduled");
}

inline void
EventQueue::deschedule(Event *event)
{
    remove(event);
    if (DTRACE(Event))
        event->trace("descheduled");
}

inline void
EventQueue::reschedule(Event *event)
{
    remove(event);
    insert(event);
    if (DTRACE(Event))
        event->trace("rescheduled");
}

//////////////////////
//
// Main Event Queue
//
// Events on this queue are processed at the *beginning* of each
// cycle, before the pipeline simulation is performed.
//
// defined in eventq.cc
//
//////////////////////
extern EventQueue mainEventQueue;

#endif // __EVENTQ_HH__
<|endoftext|>


<commit_before>/*
    Copyright (C) 2003 by Jorrit Tyberghein
              (C) 2003 by Frank Richter

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"
#include "csgfx/shadervarcontext.h"

CS_LEAKGUARD_IMPLEMENT (csShaderVariableContext);

SCF_IMPLEMENT_IBASE(csShaderVariableContext)
  SCF_IMPLEMENTS_INTERFACE(iShaderVariableContext)
SCF_IMPLEMENT_IBASE_END

csShaderVariableContext::csShaderVariableContext ()
{
  SCF_CONSTRUCT_IBASE(0);
}

csShaderVariableContext::~csShaderVariableContext ()
{
  SCF_DESTRUCT_IBASE ();
}

class SvVarArrayCmp : public csArrayCmp<csShaderVariable*, csStringID>
{
  static int SvKeyCompare (csShaderVariable* const& r, csStringID const& k)
  {
    return r->GetName() - k;
  }
public:
  SvVarArrayCmp (csStringID key) :
    csArrayCmp<csShaderVariable*, csStringID> (key, SvKeyCompare)
  {
  }
};

static int SvCompare (csShaderVariable* const& r, csShaderVariable* const& k)
{
  return r->GetName() - k->GetName();
}

void csShaderVariableContext::AddVariable
  (csShaderVariable *variable)
{
  csShaderVariable* var = GetVariable (variable->GetName());
  if (var == 0)
    variables.InsertSorted (variable, SvCompare);
  else
    *var = *variable;
}

csShaderVariable* csShaderVariableContext::GetVariable
  (csStringID name) const
{
  size_t index = variables.FindSortedKey (SvVarArrayCmp (name));
  if (index != csArrayItemNotFound)
    return variables[index];
  return 0;
}

void csShaderVariableContext::PushVariables
  (csShaderVarStack &stacks) const
{
  for (size_t i=0; i<variables.Length (); ++i)
  {
    csStringID name = variables[i]->GetName ();
    if (stacks.Length () <= (size_t)name)
      stacks.SetLength (name+1);
    stacks[name] = variables[i];
  }
}<commit_msg>Added missing end-of-file line-terminator.<commit_after>/*
    Copyright (C) 2003 by Jorrit Tyberghein
              (C) 2003 by Frank Richter

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"
#include "csgfx/shadervarcontext.h"

CS_LEAKGUARD_IMPLEMENT (csShaderVariableContext);

SCF_IMPLEMENT_IBASE(csShaderVariableContext)
  SCF_IMPLEMENTS_INTERFACE(iShaderVariableContext)
SCF_IMPLEMENT_IBASE_END

csShaderVariableContext::csShaderVariableContext ()
{
  SCF_CONSTRUCT_IBASE(0);
}

csShaderVariableContext::~csShaderVariableContext ()
{
  SCF_DESTRUCT_IBASE ();
}

class SvVarArrayCmp : public csArrayCmp<csShaderVariable*, csStringID>
{
  static int SvKeyCompare (csShaderVariable* const& r, csStringID const& k)
  {
    return r->GetName() - k;
  }
public:
  SvVarArrayCmp (csStringID key) :
    csArrayCmp<csShaderVariable*, csStringID> (key, SvKeyCompare)
  {
  }
};

static int SvCompare (csShaderVariable* const& r, csShaderVariable* const& k)
{
  return r->GetName() - k->GetName();
}

void csShaderVariableContext::AddVariable
  (csShaderVariable *variable)
{
  csShaderVariable* var = GetVariable (variable->GetName());
  if (var == 0)
    variables.InsertSorted (variable, SvCompare);
  else
    *var = *variable;
}

csShaderVariable* csShaderVariableContext::GetVariable
  (csStringID name) const
{
  size_t index = variables.FindSortedKey (SvVarArrayCmp (name));
  if (index != csArrayItemNotFound)
    return variables[index];
  return 0;
}

void csShaderVariableContext::PushVariables
  (csShaderVarStack &stacks) const
{
  for (size_t i=0; i<variables.Length (); ++i)
  {
    csStringID name = variables[i]->GetName ();
    if (stacks.Length () <= (size_t)name)
      stacks.SetLength (name+1);
    stacks[name] = variables[i];
  }
}
<|endoftext|>


<commit_before>#include "momentum.h"
#include <boost/unordered_map.hpp>
#include <iostream>
#include <semiOrderedMap.cpp>

namespace bts
{
	#define MAX_MOMENTUM_NONCE  (1<<26)
	#define SEARCH_SPACE_BITS 50
	#define BIRTHDAYS_PER_HASH 8

	std::vector< std::pair<uint32_t,uint32_t> > momentum_search( uint256 midHash )
  {
			semiOrderedMap somap;
			somap.allocate(4);
      std::vector< std::pair<uint32_t,uint32_t> > results;

      char  hash_tmp[sizeof(midHash)+4];
      memcpy((char*)&hash_tmp[4], (char*)&midHash, sizeof(midHash) );
      uint32_t* index = (uint32_t*)hash_tmp;

      for( uint32_t i = 0; i < MAX_MOMENTUM_NONCE;  )
      {
          *index = i;
          uint64_t  result_hash[8];
          SHA512((unsigned char*)hash_tmp, sizeof(hash_tmp), (unsigned char*)result_hash);

          for( uint32_t x = 0; x < 8; ++x )
          {
              uint64_t birthday = result_hash[x] >> (64-SEARCH_SPACE_BITS);
              uint32_t nonce = i+x;
              //boost::unordered_map<uint64_t,uint32_t>::const_iterator itr = found.find( birthday );

              uint64_t foundMatch=somap.checkAdd( birthday, nonce );
              if( foundMatch != 0 ){
                  results.push_back( std::make_pair( foundMatch, nonce ) );
              }
          }
          i += BIRTHDAYS_PER_HASH;
      }
      //for( auto itr = results.begin(); itr != results.end(); ++itr )
      //{
      //   assert( momentum_verify( midHash, itr->first, itr->second ) );
     // }
      somap.destroy();
      return results;
   }

	uint64_t getBirthdayHash(const uint256& midHash, uint32_t a)
  {
    uint32_t index = a - (a%8);
    char  hash_tmp[sizeof(midHash)+4];
  //  std::cerr<<"midHash size:" <<sizeof(midHash)<<"\n";
    memcpy(&hash_tmp[4], (char*)&midHash, sizeof(midHash) );
    memcpy(&hash_tmp[0], (char*)&index, sizeof(index) );

    uint64_t  result_hash[8];
//      for( uint32_t i = 0; i < sizeof(hash_tmp); ++i )
 //     {
  //       std::cerr<<" "<<uint16_t((((unsigned char*)hash_tmp)[i]));
   //   }
//      std::cerr<<"\n";
		SHA512((unsigned char*)hash_tmp, sizeof(hash_tmp), (unsigned char*)&result_hash);
//    std::cerr<<"result_hash "<<a<<"  "<<a%8<<"  --- ";
 //   for( uint32_t i = 0; i < 8; ++i ) std::cerr<<result_hash[i]<<" ";
  //  std::cerr<<"\n";

    uint64_t r = result_hash[a%BIRTHDAYS_PER_HASH]>>(64-SEARCH_SPACE_BITS);
  //  std::cerr<<"bdayresult: "<<r<<"\n";
    return r;
	}

	bool momentum_verify( uint256 head, uint32_t a, uint32_t b ){
 //   std::cerr<<"verify  "<<a<<"  and "<<b<<"  mid: "<<head.ToString()<<"\n";
 //   std::cerr<<"    "<<getBirthdayHash(head,a)<<"   "<<getBirthdayHash(head,b)<<"\n";
		if( a == b ) return false;
		if( a > MAX_MOMENTUM_NONCE ) return false;
		if( b > MAX_MOMENTUM_NONCE ) return false;

     bool r = (getBirthdayHash(head,a) == getBirthdayHash(head,b));
  //   std::cerr<< "####### Verified "<<int(r)<<"\n";
     return r;
	}

}
<commit_msg>Reduce stale rate<commit_after>#include "momentum.h"
#include <boost/unordered_map.hpp>
#include <iostream>
#include <semiOrderedMap.cpp>

namespace bts
{
	#define MAX_MOMENTUM_NONCE  (1<<26)
	#define SEARCH_SPACE_BITS 50
	#define BIRTHDAYS_PER_HASH 8

	std::vector< std::pair<uint32_t,uint32_t> > momentum_search( uint256 midHash )
  {
			semiOrderedMap somap;
			somap.allocate(4);
      std::vector< std::pair<uint32_t,uint32_t> > results;

      char  hash_tmp[sizeof(midHash)+4];
      memcpy((char*)&hash_tmp[4], (char*)&midHash, sizeof(midHash) );
      uint32_t* index = (uint32_t*)hash_tmp;

      for( uint32_t i = 0; i < MAX_MOMENTUM_NONCE;  )
      {
          *index = i;
          uint64_t  result_hash[8];
          SHA512((unsigned char*)hash_tmp, sizeof(hash_tmp), (unsigned char*)result_hash);

          for( uint32_t x = 0; x < 8; ++x )
          {
              uint64_t birthday = result_hash[x] >> (64-SEARCH_SPACE_BITS);
              uint32_t nonce = i+x;
              //boost::unordered_map<uint64_t,uint32_t>::const_iterator itr = found.find( birthday );

              uint64_t foundMatch=somap.checkAdd( birthday, nonce );
              if( foundMatch != 0 ){
                  results.push_back( std::make_pair( foundMatch, nonce ) );
                  // Reduce stales by immedately returning on first collision.
                  return results;
              }
          }
          i += BIRTHDAYS_PER_HASH;
      }
      //for( auto itr = results.begin(); itr != results.end(); ++itr )
      //{
      //   assert( momentum_verify( midHash, itr->first, itr->second ) );
     // }
      somap.destroy();
      return results;
   }

	uint64_t getBirthdayHash(const uint256& midHash, uint32_t a)
  {
    uint32_t index = a - (a%8);
    char  hash_tmp[sizeof(midHash)+4];
  //  std::cerr<<"midHash size:" <<sizeof(midHash)<<"\n";
    memcpy(&hash_tmp[4], (char*)&midHash, sizeof(midHash) );
    memcpy(&hash_tmp[0], (char*)&index, sizeof(index) );

    uint64_t  result_hash[8];
//      for( uint32_t i = 0; i < sizeof(hash_tmp); ++i )
 //     {
  //       std::cerr<<" "<<uint16_t((((unsigned char*)hash_tmp)[i]));
   //   }
//      std::cerr<<"\n";
		SHA512((unsigned char*)hash_tmp, sizeof(hash_tmp), (unsigned char*)&result_hash);
//    std::cerr<<"result_hash "<<a<<"  "<<a%8<<"  --- ";
 //   for( uint32_t i = 0; i < 8; ++i ) std::cerr<<result_hash[i]<<" ";
  //  std::cerr<<"\n";

    uint64_t r = result_hash[a%BIRTHDAYS_PER_HASH]>>(64-SEARCH_SPACE_BITS);
  //  std::cerr<<"bdayresult: "<<r<<"\n";
    return r;
	}

	bool momentum_verify( uint256 head, uint32_t a, uint32_t b ){
 //   std::cerr<<"verify  "<<a<<"  and "<<b<<"  mid: "<<head.ToString()<<"\n";
 //   std::cerr<<"    "<<getBirthdayHash(head,a)<<"   "<<getBirthdayHash(head,b)<<"\n";
		if( a == b ) return false;
		if( a > MAX_MOMENTUM_NONCE ) return false;
		if( b > MAX_MOMENTUM_NONCE ) return false;

     bool r = (getBirthdayHash(head,a) == getBirthdayHash(head,b));
  //   std::cerr<< "####### Verified "<<int(r)<<"\n";
     return r;
	}

}
<|endoftext|>