<commit_before>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifdef _MSC_VER
#pragma warning(4:4786)
#endif

#include <string>
#include <fstream>
#include <stdio.h>
#include "Bundle.h"
#include "StateDatabase.h"

Bundle::Bundle(const Bundle *pBundle)
{
  if (pBundle == NULL)
    return;

  mappings = pBundle->mappings;
}

void Bundle::load(const std::string &path)
{
  std::string untranslated;
  std::string translated;
  char buffer[1024];

  std::ifstream poStrm(path.c_str());
  if (!poStrm.good())
    return;

  poStrm.getline(buffer,1024);
  while (poStrm.good()) {
    std::string line = buffer;
    std::string data;
    TLineType type = parseLine(line, data);
    if (type == tMSGID) {
      if (untranslated.length() > 0) {
	mappings.erase(untranslated);
	ensureNormalText(translated);
	mappings.insert(std::pair<std::string,std::string>(untranslated, translated));
      }
      untranslated = data;
      translated.resize(0);
    }
    else if (type == tMSGSTR) {
      if (untranslated.length() > 0)
	translated = data;
    }
    else if (type == tAPPEND) {
      if (untranslated.length() > 0)
	translated += data;
    }
    else if (type == tERROR) {

    }

    poStrm.getline(buffer,1024);
  }

  if ((untranslated.length() > 0) && (translated.length() > 0)) {
    mappings.erase(untranslated);
    ensureNormalText(translated);
    mappings.insert(std::pair<std::string,std::string>(untranslated, translated));
  }
}

Bundle::TLineType Bundle::parseLine(const std::string &line, std::string &data) const
{
  int startPos, endPos;
  TLineType type;

  data.resize(0);
  startPos = line.find_first_not_of("\t \r\n");

  if ((startPos < 0) || (line.at(startPos) == '#'))
    return tCOMMENT;

  else if (line.at(startPos) == '"') {
    endPos = line.find_first_of('"', startPos+1);
    if (endPos < 0)
      endPos = line.length();
    data = line.substr(startPos+1, endPos-startPos-1);
    return tAPPEND;
  }

  endPos = line.find_first_of("\t \r\n\"");
  if (endPos < 0)
    endPos = line.length();
  std::string key = line.substr(startPos, endPos-startPos);
  if (key == "msgid")
    type = tMSGID;
  else if (key == "msgstr")
    type = tMSGSTR;
  else
    return tERROR;

  startPos = line.find_first_of('"', endPos + 1);
  if (startPos >= 0) {
    startPos++;
    endPos = line.find_first_of('"', startPos);
    if (endPos < 0)
      endPos = line.length();
    data = line.substr( startPos, endPos-startPos);
  }
  return type;
}

#include <set>
static std::set<std::string> unmapped;

std::string Bundle::getLocalString(const std::string &key) const
{
  if (key == "") return key;
  BundleStringMap::const_iterator it = mappings.find(key);
  if (it != mappings.end()) {
    return it->second;
  } else {
    if (BZDB.getDebug()) {
      if (unmapped.find( key ) == unmapped.end( )) {
        unmapped.insert( key );
	std::string debugStr = "Unmapped Locale String: " + key + "\n";
	DEBUG1( debugStr.c_str( ));
      }
    }
    return key;
  }
}

void Bundle::ensureNormalText(std::string &msg)
{
// This is an ugly hack. If you don't like it fix it.
// BZFlag's font bitmaps don't contain letters with accents, so strip them here
// Would be nice if some kind sole added them.

  for (std::string::size_type i = 0; i < msg.length(); i++) {
    char c = msg.at(i);
    switch (c) {
      case '':
      case '':
      case '':
      case '':
      case '':
      case '':
	msg[i] = 'a';
      break;
      case '':
	msg[i] = 'a';
	i++;
	msg.insert(i, 1, 'a');
      break;
      case '':
      case '':
	msg[i] = 'a';
	i++;
	msg.insert(i, 1, 'e');
      break;
      case '':
      case '':
      case '':
	msg[i] = 'A';
      break;
      case '':
      case '':
	msg[i] = 'A';
	i++;
	msg.insert(i, 1, 'e');
      break;
      case '':
	msg[i] = 'A';
	i++;
	msg.insert(i, 1, 'a');
      break;
      case '':
	msg[i] = 'c';
      break;
      case '':
      case '':
      case '':
      case '':
	msg[i] = 'e';
      break;
      case '':
      case '':
      case '':
      case '':
	msg[i] = 'i';
      break;
      case '':
      case '':
      case '':
      case '':
	msg[i] = 'o';
      break;
      case '':
      case '':
	msg[i] = 'o';
	i++;
	msg.insert(i, 1, 'e');
      break;
      case '':
	msg[i] = 'O';
      break;
      case '':
      case '':
	msg[i] = 'O';
	i++;
	msg.insert(i, 1, 'e');
      break;
      case '':
      case '':
      case '':
	msg[i] = 'u';
      break;
      case '':
	msg[i] = 'u';
	i++;
	msg.insert(i, 1, 'e');
      break;
      case '':
	msg[i] = 'U';
	i++;
	msg.insert(i, 1, 'e');
      break;
      case '':
	msg[i] = 'n';
      break;
      case '':
	msg[i] = 'Y';
      break;
      case '':
	msg[i] = 's';
	i++;
	msg.insert(i, 1, 's');
      break;
      case '':
      case '':
	msg[i] = ' ';
      break;

      default: // A temporary patch, to catch untranslated chars.. To be removed eventually
	if (((c >= 'A') && (c <= 'Z'))
	    || ((c >= 'a') && (c <= 'z'))
	    || ((c >= '0') && (c <= '9'))
	    || (c == '}') || (c == '{') || (c == ' ')
	    || (c == ':') || (c == '/') || (c == '-')
	    || (c == ',') || (c == '&') || (c == '?')
	    || (c == '<') || (c == '>') || (c == '.')
	    || (c == '(') || (c == ')') || (c == '%')
	    || (c == '!') || (c == '+') || (c == '-')
	    || (c == '$') || (c == ';') || (c == '@')
	    || (c == '[') || (c == ']')
	    || (c == '=') || (c == '\''))
	;
	else {
		msg = std::string("unsupported char:") + c;
		return;
	}
      break;

    }
  }
}

std::string Bundle::formatMessage(const std::string &key, const std::vector<std::string> *parms) const
{
  std::string messageIn = getLocalString(key);
  std::string messageOut;

  if (!parms || (parms->size() == 0))
    return messageIn;

  int parmCnt = parms->size();
  int startPos = 0;
  int lCurlyPos = messageIn.find_first_of("{");

  while (lCurlyPos >= 0) {
    messageOut += messageIn.substr( startPos, lCurlyPos - startPos);
    int rCurlyPos = messageIn.find_first_of("}", lCurlyPos++);
    if (rCurlyPos < 0) {
      messageOut += messageIn.substr(lCurlyPos);
      return messageOut;
    }
    std::string numStr = messageIn.substr(lCurlyPos, rCurlyPos-lCurlyPos);
    int num;
    if (sscanf(numStr.c_str(), "%d", &num) != 1)
      messageOut += messageIn.substr(lCurlyPos, rCurlyPos-lCurlyPos);
    else {
      num--;
      if ((num >= 0) && (num < parmCnt))
	messageOut += (*parms)[num];
    }
    startPos = rCurlyPos+1;
    lCurlyPos = messageIn.find_first_of("{", startPos);
  }
  messageOut += messageIn.substr(startPos);
  return messageOut;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<commit_msg>prevent possible format specifier attack<commit_after>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifdef _MSC_VER
#pragma warning(4:4786)
#endif

#include <string>
#include <fstream>
#include <stdio.h>
#include "Bundle.h"
#include "StateDatabase.h"

Bundle::Bundle(const Bundle *pBundle)
{
  if (pBundle == NULL)
    return;

  mappings = pBundle->mappings;
}

void Bundle::load(const std::string &path)
{
  std::string untranslated;
  std::string translated;
  char buffer[1024];

  std::ifstream poStrm(path.c_str());
  if (!poStrm.good())
    return;

  poStrm.getline(buffer,1024);
  while (poStrm.good()) {
    std::string line = buffer;
    std::string data;
    TLineType type = parseLine(line, data);
    if (type == tMSGID) {
      if (untranslated.length() > 0) {
	mappings.erase(untranslated);
	ensureNormalText(translated);
	mappings.insert(std::pair<std::string,std::string>(untranslated, translated));
      }
      untranslated = data;
      translated.resize(0);
    }
    else if (type == tMSGSTR) {
      if (untranslated.length() > 0)
	translated = data;
    }
    else if (type == tAPPEND) {
      if (untranslated.length() > 0)
	translated += data;
    }
    else if (type == tERROR) {

    }

    poStrm.getline(buffer,1024);
  }

  if ((untranslated.length() > 0) && (translated.length() > 0)) {
    mappings.erase(untranslated);
    ensureNormalText(translated);
    mappings.insert(std::pair<std::string,std::string>(untranslated, translated));
  }
}

Bundle::TLineType Bundle::parseLine(const std::string &line, std::string &data) const
{
  int startPos, endPos;
  TLineType type;

  data.resize(0);
  startPos = line.find_first_not_of("\t \r\n");

  if ((startPos < 0) || (line.at(startPos) == '#'))
    return tCOMMENT;

  else if (line.at(startPos) == '"') {
    endPos = line.find_first_of('"', startPos+1);
    if (endPos < 0)
      endPos = line.length();
    data = line.substr(startPos+1, endPos-startPos-1);
    return tAPPEND;
  }

  endPos = line.find_first_of("\t \r\n\"");
  if (endPos < 0)
    endPos = line.length();
  std::string key = line.substr(startPos, endPos-startPos);
  if (key == "msgid")
    type = tMSGID;
  else if (key == "msgstr")
    type = tMSGSTR;
  else
    return tERROR;

  startPos = line.find_first_of('"', endPos + 1);
  if (startPos >= 0) {
    startPos++;
    endPos = line.find_first_of('"', startPos);
    if (endPos < 0)
      endPos = line.length();
    data = line.substr( startPos, endPos-startPos);
  }
  return type;
}

#include <set>
static std::set<std::string> unmapped;

std::string Bundle::getLocalString(const std::string &key) const
{
  if (key == "") return key;
  BundleStringMap::const_iterator it = mappings.find(key);
  if (it != mappings.end()) {
    return it->second;
  } else {
    if (BZDB.getDebug()) {
      if (unmapped.find( key ) == unmapped.end( )) {
        unmapped.insert( key );
	std::string debugStr = "Unmapped Locale String: " + key + "\n";
	DEBUG1("%s", debugStr.c_str());
      }
    }
    return key;
  }
}

void Bundle::ensureNormalText(std::string &msg)
{
// This is an ugly hack. If you don't like it fix it.
// BZFlag's font bitmaps don't contain letters with accents, so strip them here
// Would be nice if some kind sole added them.

  for (std::string::size_type i = 0; i < msg.length(); i++) {
    char c = msg.at(i);
    switch (c) {
      case '':
      case '':
      case '':
      case '':
      case '':
      case '':
	msg[i] = 'a';
      break;
      case '':
	msg[i] = 'a';
	i++;
	msg.insert(i, 1, 'a');
      break;
      case '':
      case '':
	msg[i] = 'a';
	i++;
	msg.insert(i, 1, 'e');
      break;
      case '':
      case '':
      case '':
	msg[i] = 'A';
      break;
      case '':
      case '':
	msg[i] = 'A';
	i++;
	msg.insert(i, 1, 'e');
      break;
      case '':
	msg[i] = 'A';
	i++;
	msg.insert(i, 1, 'a');
      break;
      case '':
	msg[i] = 'c';
      break;
      case '':
      case '':
      case '':
      case '':
	msg[i] = 'e';
      break;
      case '':
      case '':
      case '':
      case '':
	msg[i] = 'i';
      break;
      case '':
      case '':
      case '':
      case '':
	msg[i] = 'o';
      break;
      case '':
      case '':
	msg[i] = 'o';
	i++;
	msg.insert(i, 1, 'e');
      break;
      case '':
	msg[i] = 'O';
      break;
      case '':
      case '':
	msg[i] = 'O';
	i++;
	msg.insert(i, 1, 'e');
      break;
      case '':
      case '':
      case '':
	msg[i] = 'u';
      break;
      case '':
	msg[i] = 'u';
	i++;
	msg.insert(i, 1, 'e');
      break;
      case '':
	msg[i] = 'U';
	i++;
	msg.insert(i, 1, 'e');
      break;
      case '':
	msg[i] = 'n';
      break;
      case '':
	msg[i] = 'Y';
      break;
      case '':
	msg[i] = 's';
	i++;
	msg.insert(i, 1, 's');
      break;
      case '':
      case '':
	msg[i] = ' ';
      break;

      default: // A temporary patch, to catch untranslated chars.. To be removed eventually
	if (((c >= 'A') && (c <= 'Z'))
	    || ((c >= 'a') && (c <= 'z'))
	    || ((c >= '0') && (c <= '9'))
	    || (c == '}') || (c == '{') || (c == ' ')
	    || (c == ':') || (c == '/') || (c == '-')
	    || (c == ',') || (c == '&') || (c == '?')
	    || (c == '<') || (c == '>') || (c == '.')
	    || (c == '(') || (c == ')') || (c == '%')
	    || (c == '!') || (c == '+') || (c == '-')
	    || (c == '$') || (c == ';') || (c == '@')
	    || (c == '[') || (c == ']')
	    || (c == '=') || (c == '\''))
	;
	else {
		msg = std::string("unsupported char:") + c;
		return;
	}
      break;

    }
  }
}

std::string Bundle::formatMessage(const std::string &key, const std::vector<std::string> *parms) const
{
  std::string messageIn = getLocalString(key);
  std::string messageOut;

  if (!parms || (parms->size() == 0))
    return messageIn;

  int parmCnt = parms->size();
  int startPos = 0;
  int lCurlyPos = messageIn.find_first_of("{");

  while (lCurlyPos >= 0) {
    messageOut += messageIn.substr( startPos, lCurlyPos - startPos);
    int rCurlyPos = messageIn.find_first_of("}", lCurlyPos++);
    if (rCurlyPos < 0) {
      messageOut += messageIn.substr(lCurlyPos);
      return messageOut;
    }
    std::string numStr = messageIn.substr(lCurlyPos, rCurlyPos-lCurlyPos);
    int num;
    if (sscanf(numStr.c_str(), "%d", &num) != 1)
      messageOut += messageIn.substr(lCurlyPos, rCurlyPos-lCurlyPos);
    else {
      num--;
      if ((num >= 0) && (num < parmCnt))
	messageOut += (*parms)[num];
    }
    startPos = rCurlyPos+1;
    lCurlyPos = messageIn.find_first_of("{", startPos);
  }
  messageOut += messageIn.substr(startPos);
  return messageOut;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<|endoftext|>


<commit_before>//------------------------------------------------------
#include "stdafx.h"
#include "Common.h"

#include "config.h"					// for MASHAPE_API_URL, MASHAPE_API_ID
#include "version.h"				// for VERSION_PRODUCT_NAME, MAIN_PRODUCT_VERSION_STR_A

#include <json/json.h>

#include <chrono>
#include <thread>

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

#ifdef _MSC_VER
//#pragma comment (lib, "jsoncpp.lib")
#endif // _MSC_VER > 1000

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

using namespace std;

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

volatile bool g_bTerminateProgram = false;

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

ProbeApiRequester::Request::Request(const std::string& sRequestWithArgs)
{
	eMethod = HTTP_GET;
	sUrl = MASHAPE_API_URL + sRequestWithArgs;
	headers.emplace_back("X-Mashape-Key", MASHAPE_API_ID);
	headers.emplace_back("Accept", "application/json");

	sUserAgent = VERSION_PRODUCT_NAME " HTTP client v." MAIN_PRODUCT_VERSION_STR_A;
	nHttpTimeoutSec = 2 * 60;
	bKnownBadSslCertificate = false;
}

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

ProbeApiRequester::Reply ProbeApiRequester::DoRequest(const ProbeApiRequester::Request& requestInfo, const bool bVerbose)
{
	ProbeApiRequester::Reply reply = HttpRequester::DoRequest(requestInfo, bVerbose);

	// reply HTTP code: 401 Unauthorized
	// Content-Type: application/json
	// {"message":"Missing Mashape application key. Go to http:\/\/docs.mashape.com\/api-keys to learn how to get your API application key."}
	//
	// reply HTTP code: 402
	// Content-Type: application/json
	// {"message":"You need to subscribe to a plan before consuming the API"}
	//
	// reply HTTP code : 403
	// Content-Type: application/json
	// {"message":"Invalid Mashape Key"}
	//
	// reply HTTP code: 404
	// Content-Type: text/html; charset=UTF-8
	//
	//

	//
Service

	//
Endpoint not found.

	//

	//

	const bool bJsonReply = begins(reply.sContentType, "application/json");

	if (reply.bSucceeded)
	{
		if (reply.nHttpCode != 200 && bJsonReply)
		{
			string sMessage;
			{
				Json::Reader reader;
				Json::Value root;
				const bool parsedOK = reader.parse(reply.sBody, root);
				if (parsedOK)
				{
					sMessage = root.get("message", "").asString();
				}
			}

			reply.bSucceeded = false;
			reply.sErrorDescription = OSSFMT("Bad HTTP reply code: " << reply.nHttpCode << "; message: " << sMessage);
		}
		else if (!bJsonReply)
		{
			reply.bSucceeded = false;
			reply.sErrorDescription = OSSFMT("Bad reply format. HTTP code: " << reply.nHttpCode << "; Content-Type: " << reply.sContentType);
		}
	}

	if (bVerbose)
	{
		HttpReplyDebugPrint(reply);
	}

	return reply;
}

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

void ProbeApiRequester::HttpReplyDebugPrint(const ProbeApiRequester::Reply &reply)
{
	cout << "request succeeded: " << reply.bSucceeded << endl;
	cout << "request error desc: " << reply.sErrorDescription << endl;
	cout << "reply HTTP code: " << reply.nHttpCode << endl;
	cout << "reply EffectiveUrl: " << reply.sEffectiveUrl << endl;
	cout << "reply Content-Type: " << reply.sContentType << endl;
	cout << "reply body length: " << reply.sBody.length() << endl;

	cout << "REPLY BODY: [[[" << reply.sBody << "]]]" << endl;
}

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

void MySleep(const uint32_t nSleepMs)
{
	std::this_thread::sleep_for(std::chrono::milliseconds(nSleepMs));
}

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

template<class T>
inline T findandreplaceConstT(const T& source, const T& find, const T& replace)
{
	if (find.empty() || source.empty())
		return source;

	ptrdiff_t nPredictReplaces = 0;
	for (std::size_t pos = source.find(find); pos != source.npos; pos = source.find(find, pos))
	{
		++nPredictReplaces;
		pos += find.length();
	}

	T res;
	res.reserve(source.length() + nPredictReplaces * (replace.length() - find.length()));

	T::size_type posPrev = 0;
	for (std::size_t pos = source.find(find); pos != source.npos; pos = source.find(find, pos))
	{
		if (pos > posPrev)
		{
			res += source.substr(posPrev, pos - posPrev);
		}
		res += replace;
		pos += find.length();
		posPrev = pos;
	}

	if (posPrev != T::npos)
	{
		// Copy rest of the string:
		res += source.substr(posPrev);
	}

	return res;
}

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

template<class T>
inline void findandreplaceT(T& source, const T& find, const T& replace)
{
	if (find.empty() || source.empty())
		return;

	// Optimize performance if find and replace have different size.
	// In this case we can't replace in-place without moving rest of string in memory.

	if (find.length() != replace.length())
	{
		std::swap(source, findandreplaceConstT(source, find, replace));
		return;
	}

	// Fast in-place string replacement:

	T::size_type pos = 0;
	while ((pos = source.find(find, pos)) != T::npos)
	{
		source.replace(pos, find.length(), replace);
		pos += replace.length();
	}
}

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

std::string findandreplaceConst(const std::string& source, const std::string& find, const std::string& replace)
{
	return findandreplaceConstT(source, find, replace);
}

std::wstring findandreplaceConst(const std::wstring& source, const std::wstring& find, const std::wstring& replace)
{
	return findandreplaceConstT(source, find, replace);
}

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

void findandreplace(std::string& source, const std::string& find, const std::string& replace)
{
	findandreplaceT(source, find, replace);
}

void findandreplace(std::wstring& source, const std::wstring& find, const std::wstring& replace)
{
	findandreplaceT(source, find, replace);
}

//------------------------------------------------------
<commit_msg>changes for gcc compatibility<commit_after>//------------------------------------------------------
#include "stdafx.h"
#include "Common.h"

#include "config.h"					// for MASHAPE_API_URL, MASHAPE_API_ID
#include "version.h"				// for VERSION_PRODUCT_NAME, MAIN_PRODUCT_VERSION_STR_A

#include <json/json.h>

#include <chrono>
#include <thread>

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

#ifdef _MSC_VER
//#pragma comment (lib, "jsoncpp.lib")
#endif // _MSC_VER > 1000

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

using namespace std;

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

volatile bool g_bTerminateProgram = false;

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

ProbeApiRequester::Request::Request(const std::string& sRequestWithArgs)
{
	eMethod = HTTP_GET;
	sUrl = MASHAPE_API_URL + sRequestWithArgs;
	headers.emplace_back("X-Mashape-Key", MASHAPE_API_ID);
	headers.emplace_back("Accept", "application/json");

	sUserAgent = VERSION_PRODUCT_NAME " HTTP client v." MAIN_PRODUCT_VERSION_STR_A;
	nHttpTimeoutSec = 2 * 60;
	bKnownBadSslCertificate = false;
}

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

ProbeApiRequester::Reply ProbeApiRequester::DoRequest(const ProbeApiRequester::Request& requestInfo, const bool bVerbose)
{
	ProbeApiRequester::Reply reply = HttpRequester::DoRequest(requestInfo, bVerbose);

	// reply HTTP code: 401 Unauthorized
	// Content-Type: application/json
	// {"message":"Missing Mashape application key. Go to http:\/\/docs.mashape.com\/api-keys to learn how to get your API application key."}
	//
	// reply HTTP code: 402
	// Content-Type: application/json
	// {"message":"You need to subscribe to a plan before consuming the API"}
	//
	// reply HTTP code : 403
	// Content-Type: application/json
	// {"message":"Invalid Mashape Key"}
	//
	// reply HTTP code: 404
	// Content-Type: text/html; charset=UTF-8
	//
	//

	//
Service

	//
Endpoint not found.

	//

	//

	const bool bJsonReply = begins(reply.sContentType, "application/json");

	if (reply.bSucceeded)
	{
		if (reply.nHttpCode != 200 && bJsonReply)
		{
			string sMessage;
			{
				Json::Reader reader;
				Json::Value root;
				const bool parsedOK = reader.parse(reply.sBody, root);
				if (parsedOK)
				{
					sMessage = root.get("message", "").asString();
				}
			}

			reply.bSucceeded = false;
			reply.sErrorDescription = OSSFMT("Bad HTTP reply code: " << reply.nHttpCode << "; message: " << sMessage);
		}
		else if (!bJsonReply)
		{
			reply.bSucceeded = false;
			reply.sErrorDescription = OSSFMT("Bad reply format. HTTP code: " << reply.nHttpCode << "; Content-Type: " << reply.sContentType);
		}
	}

	if (bVerbose)
	{
		HttpReplyDebugPrint(reply);
	}

	return reply;
}

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

void ProbeApiRequester::HttpReplyDebugPrint(const ProbeApiRequester::Reply &reply)
{
	cout << "request succeeded: " << reply.bSucceeded << endl;
	cout << "request error desc: " << reply.sErrorDescription << endl;
	cout << "reply HTTP code: " << reply.nHttpCode << endl;
	cout << "reply EffectiveUrl: " << reply.sEffectiveUrl << endl;
	cout << "reply Content-Type: " << reply.sContentType << endl;
	cout << "reply body length: " << reply.sBody.length() << endl;

	cout << "REPLY BODY: [[[" << reply.sBody << "]]]" << endl;
}

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

void MySleep(const uint32_t nSleepMs)
{
	std::this_thread::sleep_for(std::chrono::milliseconds(nSleepMs));
}

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

template<class T>
inline T findandreplaceConstT(const T& source, const T& find, const T& replace)
{
	if (find.empty() || source.empty())
		return source;

	ptrdiff_t nPredictReplaces = 0;
	for (std::size_t pos = source.find(find); pos != source.npos; pos = source.find(find, pos))
	{
		++nPredictReplaces;
		pos += find.length();
	}

	T res;
	res.reserve(source.length() + nPredictReplaces * (replace.length() - find.length()));

	typename T::size_type posPrev = 0;
	for (std::size_t pos = source.find(find); pos != source.npos; pos = source.find(find, pos))
	{
		if (pos > posPrev)
		{
			res += source.substr(posPrev, pos - posPrev);
		}
		res += replace;
		pos += find.length();
		posPrev = pos;
	}

	if (posPrev != T::npos)
	{
		// Copy rest of the string:
		res += source.substr(posPrev);
	}

	return res;
}

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

template<class T>
inline void findandreplaceT(T& source, const T& find, const T& replace)
{
	if (find.empty() || source.empty())
		return;

	// Optimize performance if find and replace have different size.
	// In this case we can't replace in-place without moving rest of string in memory.

	if (find.length() != replace.length())
	{
		std::swap(source, findandreplaceConstT(source, find, replace));
		return;
	}

	// Fast in-place string replacement:

	typename T::size_type pos = 0;
	while ((pos = source.find(find, pos)) != T::npos)
	{
		source.replace(pos, find.length(), replace);
		pos += replace.length();
	}
}

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

std::string findandreplaceConst(const std::string& source, const std::string& find, const std::string& replace)
{
	return findandreplaceConstT(source, find, replace);
}

std::wstring findandreplaceConst(const std::wstring& source, const std::wstring& find, const std::wstring& replace)
{
	return findandreplaceConstT(source, find, replace);
}

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

void findandreplace(std::string& source, const std::string& find, const std::string& replace)
{
	findandreplaceT(source, find, replace);
}

void findandreplace(std::wstring& source, const std::wstring& find, const std::wstring& replace)
{
	findandreplaceT(source, find, replace);
}

//------------------------------------------------------
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2003 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "global.h"

// todo: do this for non windows too, as soon as autoconf can make version.h
#ifdef _MSC_VER
#include "version.h"
#endif

GlobalDBItem				globalDBItems[] = {
	{ "_angleTolerance",		"0.01",				false, StateDatabase::Locked},
	{ "_angularAd",			"1.5",				false, StateDatabase::Locked},
	{ "_boxHeight",			"6.0*_muzzleHeight",		false, StateDatabase::Locked},
	{ "_burrowAngularAd",		"0.55",				false, StateDatabase::Locked},
	{ "_burrowDepth",		"-1.32",			false, StateDatabase::Locked},
	{ "_burrowSpeedAd",		"0.80",				false, StateDatabase::Locked},
	{ "_explodeTime",		"5.0",				false, StateDatabase::Locked},
	{ "_flagAltitude",		"11.0",				false, StateDatabase::Locked},
	{ "_flagHeight",                "10.0",                         false, StateDatabase::Locked},
	{ "_flagRadius",		"2.5",				false, StateDatabase::Locked},
	{ "_gMissileAng",		"0.628319", 			false, StateDatabase::Locked},
	{ "_gravity",			"-9.8",				false, StateDatabase::Locked},
	{ "_identifyRange",		"50.0",				false, StateDatabase::Locked},
	{ "_jumpVelocity",		"19.0",				false, StateDatabase::Locked},
	{ "_laserAdLife",		"0.1",				false, StateDatabase::Locked},
	{ "_laserAdRate",		"0.5",				false, StateDatabase::Locked},
	{ "_laserAdVel",		"1000.0",			false, StateDatabase::Locked},
	{ "_lockOnAngle",		"0.15",				false, StateDatabase::Locked},
	{ "_lRAdRate",			"0.5",				false, StateDatabase::Locked},
	{ "_maxLOD",			"32767.0",			false, StateDatabase::Locked},
	{ "_momentumAngAcc",		"1.0",				false, StateDatabase::Locked},
	{ "_momentumLinAcc",		"1.0",				false, StateDatabase::Locked},
	{ "_mGunAdLife",		"1.0 / _mGunAdRate",		false, StateDatabase::Locked},
	{ "_mGunAdRate",		"10.0",				false, StateDatabase::Locked},
	{ "_mGunAdVel",			"1.5",				false, StateDatabase::Locked},
	{ "_muzzleFront",		"_tankRadius + 0.1",		false, StateDatabase::Locked},
	{ "_muzzleHeight",		"1.57",				false, StateDatabase::Locked},
	{ "_obeseFactor",		"2.5",				false, StateDatabase::Locked},
	{ "_positionTolerance",         "0.01",				false, StateDatabase::Locked},
	{ "_pyrBase",			"4.0*_tankHeight",		false, StateDatabase::Locked},
	{ "_pyrHeight",                 "5.0*_tankHeight",		false, StateDatabase::Locked},
	{ "_reloadTime",		"_shotRange / _shotSpeed",	false, StateDatabase::Locked},
	{ "_rFireAdLife",		"1.0 / _rFireAdRate",		false, StateDatabase::Locked},
	{ "_rFireAdRate",		"2.0",				false, StateDatabase::Locked},
	{ "_rFireAdVel",		"1.5",				false, StateDatabase::Locked},
	{ "_shieldFlight",		"2.7",				false, StateDatabase::Locked},
	{ "_shockAdLife",		"0.2",				false, StateDatabase::Locked},
	{ "_shockInRadius",		"_tankLength",			false, StateDatabase::Locked},
	{ "_shockOutRadius",		"60.0",				false, StateDatabase::Locked},
	{ "_shotRange",			"350.0",			false, StateDatabase::Locked},
	{ "_shotSpeed",			"100.0",			false, StateDatabase::Locked},
	{ "_srRadiusMult",		"2.0",				false, StateDatabase::Locked},
	{ "_tankAngVel",		"0.785398", 			false, StateDatabase::Locked},
	{ "_tankHeight",		"2.05",				false, StateDatabase::Locked},
	{ "_tankLength",		"6.0",				false, StateDatabase::Locked},
	{ "_tankRadius",		"0.72 * _tankLength",		false, StateDatabase::Locked},
	{ "_tankSpeed",			"25.0",				false, StateDatabase::Locked},
	{ "_tankWidth",			"2.8",				false, StateDatabase::Locked},
	{ "_targetingAngle",		"0.3",				false, StateDatabase::Locked},
	{ "_teleportTime",		"1.0",				false, StateDatabase::Locked},
	{ "_thiefAdLife",               "0.05",				false, StateDatabase::Locked},
	{ "_thiefAdRate",		"12.0",				false, StateDatabase::Locked},
	{ "_thiefAdShotVel",		"8.0",				false, StateDatabase::Locked},
	{ "_thiefTinyFactor",		"0.5",				false, StateDatabase::Locked},
	{ "_thiefVelAd",		"1.67",				false, StateDatabase::Locked},
	{ "_tinyFactor",		"0.4",				false, StateDatabase::Locked},
	{ "_updateThrottleRate",        "30.0",                         false, StateDatabase::Locked},
	{ "_velocityAd",		"1.5",				false, StateDatabase::Locked},
	{ "_wallHeight",		"3.0*_tankHeight",              false, StateDatabase::Locked},
	{ "_wideAngleAng",		"1.745329", 			false, StateDatabase::Locked},
	{ "_worldSize",			"800.0",			false, StateDatabase::Locked},
};

// just a place to put the version stuff, as there was no where else
// version strings
char	serverVersion[16] = {0};
char	protVersion[16] = {0};
char	appVersion[24] = {0};

const char*			getServerVersion()
{
	if (!serverVersion[0])
		sprintf(serverVersion,"BZFS%s",getProtocolVersion());

	return serverVersion;
}

const char*			getProtocolVersion()
{
	if (!protVersion[0])
		sprintf(protVersion,"%s",BZ_PROTO_VERSION);

	return protVersion;
}

const char*		getAppVersion()
{
	if (!appVersion[0])
		sprintf(appVersion,"%d.%d.%d-%s-%s%d",BZ_MAJOR_VERSION,BZ_MINOR_VERSION,BZ_REV,BZ_BUILD_OS,BZ_BUILD_SOURCE,BZ_BUILD_DATE);

	return appVersion;
}

<commit_msg>23 characters is too small for some verison strings, making it supersize<commit_after>/* bzflag
 * Copyright (c) 1993 - 2003 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "global.h"

// todo: do this for non windows too, as soon as autoconf can make version.h
#ifdef _MSC_VER
#include "version.h"
#endif

GlobalDBItem				globalDBItems[] = {
	{ "_angleTolerance",		"0.01",				false, StateDatabase::Locked},
	{ "_angularAd",			"1.5",				false, StateDatabase::Locked},
	{ "_boxHeight",			"6.0*_muzzleHeight",		false, StateDatabase::Locked},
	{ "_burrowAngularAd",		"0.55",				false, StateDatabase::Locked},
	{ "_burrowDepth",		"-1.32",			false, StateDatabase::Locked},
	{ "_burrowSpeedAd",		"0.80",				false, StateDatabase::Locked},
	{ "_explodeTime",		"5.0",				false, StateDatabase::Locked},
	{ "_flagAltitude",		"11.0",				false, StateDatabase::Locked},
	{ "_flagHeight",                "10.0",                         false, StateDatabase::Locked},
	{ "_flagRadius",		"2.5",				false, StateDatabase::Locked},
	{ "_gMissileAng",		"0.628319", 			false, StateDatabase::Locked},
	{ "_gravity",			"-9.8",				false, StateDatabase::Locked},
	{ "_identifyRange",		"50.0",				false, StateDatabase::Locked},
	{ "_jumpVelocity",		"19.0",				false, StateDatabase::Locked},
	{ "_laserAdLife",		"0.1",				false, StateDatabase::Locked},
	{ "_laserAdRate",		"0.5",				false, StateDatabase::Locked},
	{ "_laserAdVel",		"1000.0",			false, StateDatabase::Locked},
	{ "_lockOnAngle",		"0.15",				false, StateDatabase::Locked},
	{ "_lRAdRate",			"0.5",				false, StateDatabase::Locked},
	{ "_maxLOD",			"32767.0",			false, StateDatabase::Locked},
	{ "_momentumAngAcc",		"1.0",				false, StateDatabase::Locked},
	{ "_momentumLinAcc",		"1.0",				false, StateDatabase::Locked},
	{ "_mGunAdLife",		"1.0 / _mGunAdRate",		false, StateDatabase::Locked},
	{ "_mGunAdRate",		"10.0",				false, StateDatabase::Locked},
	{ "_mGunAdVel",			"1.5",				false, StateDatabase::Locked},
	{ "_muzzleFront",		"_tankRadius + 0.1",		false, StateDatabase::Locked},
	{ "_muzzleHeight",		"1.57",				false, StateDatabase::Locked},
	{ "_obeseFactor",		"2.5",				false, StateDatabase::Locked},
	{ "_positionTolerance",         "0.01",				false, StateDatabase::Locked},
	{ "_pyrBase",			"4.0*_tankHeight",		false, StateDatabase::Locked},
	{ "_pyrHeight",                 "5.0*_tankHeight",		false, StateDatabase::Locked},
	{ "_reloadTime",		"_shotRange / _shotSpeed",	false, StateDatabase::Locked},
	{ "_rFireAdLife",		"1.0 / _rFireAdRate",		false, StateDatabase::Locked},
	{ "_rFireAdRate",		"2.0",				false, StateDatabase::Locked},
	{ "_rFireAdVel",		"1.5",				false, StateDatabase::Locked},
	{ "_shieldFlight",		"2.7",				false, StateDatabase::Locked},
	{ "_shockAdLife",		"0.2",				false, StateDatabase::Locked},
	{ "_shockInRadius",		"_tankLength",			false, StateDatabase::Locked},
	{ "_shockOutRadius",		"60.0",				false, StateDatabase::Locked},
	{ "_shotRange",			"350.0",			false, StateDatabase::Locked},
	{ "_shotSpeed",			"100.0",			false, StateDatabase::Locked},
	{ "_srRadiusMult",		"2.0",				false, StateDatabase::Locked},
	{ "_tankAngVel",		"0.785398", 			false, StateDatabase::Locked},
	{ "_tankHeight",		"2.05",				false, StateDatabase::Locked},
	{ "_tankLength",		"6.0",				false, StateDatabase::Locked},
	{ "_tankRadius",		"0.72 * _tankLength",		false, StateDatabase::Locked},
	{ "_tankSpeed",			"25.0",				false, StateDatabase::Locked},
	{ "_tankWidth",			"2.8",				false, StateDatabase::Locked},
	{ "_targetingAngle",		"0.3",				false, StateDatabase::Locked},
	{ "_teleportTime",		"1.0",				false, StateDatabase::Locked},
	{ "_thiefAdLife",               "0.05",				false, StateDatabase::Locked},
	{ "_thiefAdRate",		"12.0",				false, StateDatabase::Locked},
	{ "_thiefAdShotVel",		"8.0",				false, StateDatabase::Locked},
	{ "_thiefTinyFactor",		"0.5",				false, StateDatabase::Locked},
	{ "_thiefVelAd",		"1.67",				false, StateDatabase::Locked},
	{ "_tinyFactor",		"0.4",				false, StateDatabase::Locked},
	{ "_updateThrottleRate",        "30.0",                         false, StateDatabase::Locked},
	{ "_velocityAd",		"1.5",				false, StateDatabase::Locked},
	{ "_wallHeight",		"3.0*_tankHeight",              false, StateDatabase::Locked},
	{ "_wideAngleAng",		"1.745329", 			false, StateDatabase::Locked},
	{ "_worldSize",			"800.0",			false, StateDatabase::Locked},
};

// just a place to put the version stuff, as there was no where else
// version strings
char	serverVersion[16] = {0};
char	protVersion[16] = {0};
char	appVersion[64] = {0};

const char*			getServerVersion()
{
	if (!serverVersion[0])
		sprintf(serverVersion,"BZFS%s",getProtocolVersion());

	return serverVersion;
}

const char*			getProtocolVersion()
{
	if (!protVersion[0])
		sprintf(protVersion,"%s",BZ_PROTO_VERSION);

	return protVersion;
}

const char*		getAppVersion()w
{
	if (!appVersion[0])
		sprintf(appVersion,"%d.%d.%d-%s-%s%d",BZ_MAJOR_VERSION,BZ_MINOR_VERSION,BZ_REV,BZ_BUILD_OS,BZ_BUILD_SOURCE,BZ_BUILD_DATE);

	return appVersion;
}

<|endoftext|>


<commit_before>/*
 * point.cpp
 *
 *  Created on: June 12, 2016
 *      Author: Tumblr
 */

#include <string>
#include "point.h"

using namespace std;

/*
 * Default Point constructor
 */
Point::Point() {
    // TODO
}

/*
 * Creates a Point with the given coordinates (x_coord, y_coord)
 */
Point::Point(int x_coord, int y_coord) {
    // TODO
}

/*
 * Point clone constructor
 */
Point::Point(const Point& clone) {
    // TODO
}

/*
 * Default Point destructor
 */
Point::~Point() {
    // TODO
}

/*
 * Checks if this point is equal to the given Point pnt.
 */
bool Point::equals(Point pnt) {
    // TODO
    return false;
}

/*
 * Returns the position of this Point as a Point.
 */
Point Point::get_location() {
    Point ret;
    // TODO
    return ret;
}

/*
 * Sets this point's coordinates equals to that of the
 * given Point (x_coord, y_coord).
 */
void Point::set_location(int x_coord, int y_coord) {
    // TODO
}

/*
 * Sets this point's coordinates equals to that of the
 * given Point pnt.
 */
void Point::set_location(Point pnt) {
    // TODO
}

/*
 * Returns this Point as a string in the format (x, y).
 */
string Point::to_string() {
    string ret;
    // TODO
    return ret;
}

/*
 * Moves this Point by dx in the x direction and dy in the
 * y direction. The position of this Point becomes
 * (x + dx, y + dy).
 */
void Point::translate(int dx, int dy) {
    // TODO
}
<commit_msg>Update point.pp methods<commit_after>/*
 * point.cpp
 *
 *  Created on: June 12, 2016
 *      Author: Tumblr
 */

#include <string>
#include "point.h"

using namespace std;

/*
 * Default Point constructor
 */
Point::Point() {
    x = 0;
    y = 0;
}

/*
 * Creates a Point with the given coordinates (x_coord, y_coord)
 */
Point::Point(int x_coord, int y_coord) {
    x = x_coord;
    y = y_coord;
}

/*
 * Point clone constructor
 */
Point::Point(const Point& clone) {
    // TODO
}

/*
 * Default Point destructor
 */
Point::~Point() {
    // TODO
}

/*
 * Checks if this point is equal to the given Point pnt.
 */
bool Point::equals(Point pnt) {
    // TODO
    if(pnt.x == x && point.y == y){
        return true
    }
    return false;
}

/*
 * Returns the position of this Point as a Point.
 */
Point Point::get_location() {
    Point ret;
    // TODO
    ret.x = x;
    ret.y = y;
    return ret;
}

/*
 * Sets this point's coordinates equals to that of the
 * given Point (x_coord, y_coord).
 */
void Point::set_location(int x_coord, int y_coord) {
    // TODO
    x = x_coord;
    y = y_coord;
}

/*
 * Sets this point's coordinates equals to that of the
 * given Point pnt.
 */
void Point::set_location(Point pnt) {
    // TODO
    x = pnt.x;
    y = pnt.y;
}

/*
 * Returns this Point as a string in the format (x, y).
 */
string Point::to_string() {
    string ret;
    ret = "(" + to_string(x)+ "," + to_string(y) + ")"
    return ret;
}

/*
 * Moves this Point by dx in the x direction and dy in the
 * y direction. The position of this Point becomes
 * (x + dx, y + dy).
 */
void Point::translate(int dx, int dy) {
    // TODO
    x = x + dx;
    y = y + dy;
}
<|endoftext|>


<commit_before>#include "compiler.h"

#include <cstring>
#include <string>
#include <sstream>
#include <clang/Frontend/CompilerInvocation.h>
#include <clang/Frontend/TextDiagnosticPrinter.h>
#include <clang/Frontend/LangStandard.h>
#include <clang/Basic/Diagnostic.h>
#include <clang/CodeGen/CodeGenAction.h>
#include <llvm/ADT/SmallVector.h>
#include <llvm/Support/Host.h>
#include <llvm/Module.h>
#include <llvm/LLVMContext.h>

using namespace Coal;

Compiler::Compiler()
: p_log_stream(p_log), p_log_printer(0)
{

}

Compiler::~Compiler()
{

}

bool Compiler::setOptions(const std::string &options)
{
    p_options = options;

    // Set codegen options
    clang::CodeGenOptions &codegen_opts = p_compiler.getCodeGenOpts();
    codegen_opts.DebugInfo = false;
    codegen_opts.AsmVerbose = true;
    codegen_opts.OptimizationLevel = 2;

    // Set diagnostic options
    clang::DiagnosticOptions &diag_opts = p_compiler.getDiagnosticOpts();
    diag_opts.Pedantic = true;
    diag_opts.ShowColumn = true;
    diag_opts.ShowLocation = true;
    diag_opts.ShowCarets = false;
    diag_opts.ShowFixits = true;
    diag_opts.ShowColors = false;
    diag_opts.ErrorLimit = 19;
    diag_opts.MessageLength = 0;
    diag_opts.DumpBuildInformation = std::string();
    diag_opts.DiagnosticLogFile = std::string();

    // Set frontend options
    clang::FrontendOptions &frontend_opts = p_compiler.getFrontendOpts();
    frontend_opts.ProgramAction = clang::frontend::EmitLLVMOnly;
    frontend_opts.DisableFree = true;
    frontend_opts.Inputs.push_back(std::make_pair(clang::IK_OpenCL, "program.cl"));

    // Set header search options
    clang::HeaderSearchOptions &header_opts = p_compiler.getHeaderSearchOpts();
    header_opts.Verbose = false;
    header_opts.UseBuiltinIncludes = false;
    header_opts.UseStandardIncludes = false;
    header_opts.UseStandardCXXIncludes = false;

    // Set lang options
    clang::LangOptions &lang_opts = p_compiler.getLangOpts();
    lang_opts.NoBuiltin = true;
    lang_opts.OpenCL = true;

    // Set target options
    clang::TargetOptions &target_opts = p_compiler.getTargetOpts();
    target_opts.Triple = llvm::sys::getHostTriple();

    // Set preprocessor options
    clang::PreprocessorOptions &prep_opts = p_compiler.getPreprocessorOpts();
    //prep_opts.Includes.push_back("stdlib.h");
    //prep_opts.addRemappedFile("stdlib.h", ...);

    clang::CompilerInvocation &invocation = p_compiler.getInvocation();
    invocation.setLangDefaults(clang::IK_OpenCL);

    // Parse the user options
    std::istringstream options_stream(options);
    std::string token;
    bool Werror = false, inI = false, inD = false;

    while (options_stream >> token)
    {
        if (inI)
        {
            // token is an include path
            header_opts.AddPath(token, clang::frontend::Angled, true, false, false);
            inI = false;
            continue;
        }
        else if (inD)
        {
            // token is name or name=value
            prep_opts.addMacroDef(token);
        }

        if (token == "-I")
        {
            inI = true;
        }
        else if (token == "-D")
        {
            inD = true;
        }
        else if (token == "-cl-single-precision-constant")
        {
            lang_opts.SinglePrecisionConstants = true;
        }
        else if (token == "-cl-opt-disable")
        {
            codegen_opts.OptimizationLevel = 0;
        }
        else if (token == "-cl-mad-enable")
        {
            codegen_opts.LessPreciseFPMAD = true;
        }
        else if (token == "-cl-unsafe-math-optimizations")
        {
            codegen_opts.UnsafeFPMath = true;
        }
        else if (token == "-cl-finite-math-only")
        {
            codegen_opts.NoInfsFPMath = true;
            codegen_opts.NoNaNsFPMath = true;
        }
        else if (token == "-cl-fast-relaxed-math")
        {
            codegen_opts.UnsafeFPMath = true;
            codegen_opts.NoInfsFPMath = true;
            codegen_opts.NoNaNsFPMath = true;
            lang_opts.FastRelaxedMath = true;
        }
        else if (token == "-w")
        {
            diag_opts.IgnoreWarnings = true;
        }
        else if (token == "-Werror")
        {
            Werror = true;
        }
    }

    // Create the diagnostics engine
    p_log_printer = new clang::TextDiagnosticPrinter(p_log_stream, diag_opts);
    p_compiler.createDiagnostics(0, NULL, p_log_printer);

    if (!p_compiler.hasDiagnostics())
        return false;

    p_compiler.getDiagnostics().setWarningsAsErrors(Werror);

    return true;
}

llvm::Module *Compiler::compile(llvm::MemoryBuffer *source)
{
    // Feed the compiler with source
    clang::PreprocessorOptions &prep_opts = p_compiler.getPreprocessorOpts();
    prep_opts.addRemappedFile("program.cl", source);
    prep_opts.RetainRemappedFileBuffers = true;

    // Compile
    llvm::Module *module = 0;

    llvm::OwningPtr<clang::CodeGenAction> act(
        new clang::EmitLLVMOnlyAction(new llvm::LLVMContext)
    );

    if (!p_compiler.ExecuteAction(*act))
    {
        return 0;
    }

    p_log_stream.flush();
    module = act->takeModule();

    // Cleanup
    prep_opts.eraseRemappedFile(prep_opts.remapped_file_buffer_end());

    return module;
}

const std::string &Compiler::log() const
{
    return p_log;
}

const std::string &Compiler::options() const
{
    return p_options;
}
<commit_msg>Remove two useless lines<commit_after>#include "compiler.h"

#include <cstring>
#include <string>
#include <sstream>
#include <clang/Frontend/CompilerInvocation.h>
#include <clang/Frontend/TextDiagnosticPrinter.h>
#include <clang/Frontend/LangStandard.h>
#include <clang/Basic/Diagnostic.h>
#include <clang/CodeGen/CodeGenAction.h>
#include <llvm/ADT/SmallVector.h>
#include <llvm/Support/Host.h>
#include <llvm/Module.h>
#include <llvm/LLVMContext.h>

using namespace Coal;

Compiler::Compiler()
: p_log_stream(p_log), p_log_printer(0)
{

}

Compiler::~Compiler()
{

}

bool Compiler::setOptions(const std::string &options)
{
    p_options = options;

    // Set codegen options
    clang::CodeGenOptions &codegen_opts = p_compiler.getCodeGenOpts();
    codegen_opts.DebugInfo = false;
    codegen_opts.AsmVerbose = true;
    codegen_opts.OptimizationLevel = 2;

    // Set diagnostic options
    clang::DiagnosticOptions &diag_opts = p_compiler.getDiagnosticOpts();
    diag_opts.Pedantic = true;
    diag_opts.ShowColumn = true;
    diag_opts.ShowLocation = true;
    diag_opts.ShowCarets = false;
    diag_opts.ShowFixits = true;
    diag_opts.ShowColors = false;
    diag_opts.ErrorLimit = 19;
    diag_opts.MessageLength = 0;

    // Set frontend options
    clang::FrontendOptions &frontend_opts = p_compiler.getFrontendOpts();
    frontend_opts.ProgramAction = clang::frontend::EmitLLVMOnly;
    frontend_opts.DisableFree = true;
    frontend_opts.Inputs.push_back(std::make_pair(clang::IK_OpenCL, "program.cl"));

    // Set header search options
    clang::HeaderSearchOptions &header_opts = p_compiler.getHeaderSearchOpts();
    header_opts.Verbose = false;
    header_opts.UseBuiltinIncludes = false;
    header_opts.UseStandardIncludes = false;
    header_opts.UseStandardCXXIncludes = false;

    // Set lang options
    clang::LangOptions &lang_opts = p_compiler.getLangOpts();
    lang_opts.NoBuiltin = true;
    lang_opts.OpenCL = true;

    // Set target options
    clang::TargetOptions &target_opts = p_compiler.getTargetOpts();
    target_opts.Triple = llvm::sys::getHostTriple();

    // Set preprocessor options
    clang::PreprocessorOptions &prep_opts = p_compiler.getPreprocessorOpts();
    //prep_opts.Includes.push_back("stdlib.h");
    //prep_opts.addRemappedFile("stdlib.h", ...);

    clang::CompilerInvocation &invocation = p_compiler.getInvocation();
    invocation.setLangDefaults(clang::IK_OpenCL);

    // Parse the user options
    std::istringstream options_stream(options);
    std::string token;
    bool Werror = false, inI = false, inD = false;

    while (options_stream >> token)
    {
        if (inI)
        {
            // token is an include path
            header_opts.AddPath(token, clang::frontend::Angled, true, false, false);
            inI = false;
            continue;
        }
        else if (inD)
        {
            // token is name or name=value
            prep_opts.addMacroDef(token);
        }

        if (token == "-I")
        {
            inI = true;
        }
        else if (token == "-D")
        {
            inD = true;
        }
        else if (token == "-cl-single-precision-constant")
        {
            lang_opts.SinglePrecisionConstants = true;
        }
        else if (token == "-cl-opt-disable")
        {
            codegen_opts.OptimizationLevel = 0;
        }
        else if (token == "-cl-mad-enable")
        {
            codegen_opts.LessPreciseFPMAD = true;
        }
        else if (token == "-cl-unsafe-math-optimizations")
        {
            codegen_opts.UnsafeFPMath = true;
        }
        else if (token == "-cl-finite-math-only")
        {
            codegen_opts.NoInfsFPMath = true;
            codegen_opts.NoNaNsFPMath = true;
        }
        else if (token == "-cl-fast-relaxed-math")
        {
            codegen_opts.UnsafeFPMath = true;
            codegen_opts.NoInfsFPMath = true;
            codegen_opts.NoNaNsFPMath = true;
            lang_opts.FastRelaxedMath = true;
        }
        else if (token == "-w")
        {
            diag_opts.IgnoreWarnings = true;
        }
        else if (token == "-Werror")
        {
            Werror = true;
        }
    }

    // Create the diagnostics engine
    p_log_printer = new clang::TextDiagnosticPrinter(p_log_stream, diag_opts);
    p_compiler.createDiagnostics(0, NULL, p_log_printer);

    if (!p_compiler.hasDiagnostics())
        return false;

    p_compiler.getDiagnostics().setWarningsAsErrors(Werror);

    return true;
}

llvm::Module *Compiler::compile(llvm::MemoryBuffer *source)
{
    // Feed the compiler with source
    clang::PreprocessorOptions &prep_opts = p_compiler.getPreprocessorOpts();
    prep_opts.addRemappedFile("program.cl", source);
    prep_opts.RetainRemappedFileBuffers = true;

    // Compile
    llvm::Module *module = 0;

    llvm::OwningPtr<clang::CodeGenAction> act(
        new clang::EmitLLVMOnlyAction(new llvm::LLVMContext)
    );

    if (!p_compiler.ExecuteAction(*act))
    {
        return 0;
    }

    p_log_stream.flush();
    module = act->takeModule();

    // Cleanup
    prep_opts.eraseRemappedFile(prep_opts.remapped_file_buffer_end());

    return module;
}

const std::string &Compiler::log() const
{
    return p_log;
}

const std::string &Compiler::options() const
{
    return p_options;
}
<|endoftext|>


<commit_before>//
//  Created by Robert Segal on 2014-04-01.
//  Copyright (c) 2016 Get Set Games Inc. All rights reserved.
//

#include "UpsightPrivatePCH.h"

#include "Android/AndroidJNI.h"
#include "AndroidApplication.h"

bool ValidateValues(TArray<FString> &Keys, TArray<FString> &Values)
{
    const int32 kNumKeys   = Keys.Num();
    const int32 kNumValues = Values.Num();

    if (kNumKeys == 0 || kNumValues == 0)
    {
        return false;
    }

    if (kNumKeys != kNumValues)
    {
        return false;
    }

    return true;
}

#if __OBJC__
NSDictionary* CreateNSDictionary(TArray<FString> &Keys, TArray<FString> &Values)
{
    const int32 kNumKeys = Keys.Num();

    NSMutableDictionary* d = [NSMutableDictionary dictionaryWithCapacity:kNumKeys];

    for (uint32 i = 0; i < kNumKeys; i++)
    {
        FString &k = Keys[i];
        FString &v = Values[i];

        d[k.GetNSString()] = v.GetNSString();
    }

    return d;
}
#endif

void UUpsightFunctions::UpsightRecordAnalyticsEventWithName(FString eventName, TArray<FString> eventKeys, TArray<FString> eventValues)
{
    if ( ValidateValues(eventKeys, eventValues) )
    {
#if PLATFORM_IOS
        NSDictionary *p = CreateNSDictionary(eventKeys, eventValues);

        [Upsight recordAnalyticsEventWithName:eventName.GetNSString() properties: p];

#elif PLATFORM_ANDROID
        if (JNIEnv* Env = FAndroidApplication::GetJavaEnv())
        {
            static jmethodID Method = FJavaWrapper::FindMethod(Env,
                                                               FJavaWrapper::GameActivityClassID,
                                                               "AndroidThunkJava_UpsightRecordAnalyticsEventWithName",
                                                               "()Ljava/lang/String;[java/lang/String;[java/lang/String;",
                                                               false);

            FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, Method);
        }
#endif
    }
    else
    {
        UE_LOG(LogUpsight, Log, TEXT("keys and/or value arguments are empty or nil"));
    }
}

void UUpsightFunctions::UpsightRecordMilestoneEventForScope(FString scope, TArray<FString> eventKeys, TArray<FString> eventValues)
{
    if ( ValidateValues(eventKeys, eventValues) )
    {
#if PLATFORM_IOS
        NSDictionary *p = CreateNSDictionary(eventKeys, eventValues);

        [Upsight recordMilestoneEventForScope:scope.GetNSString() properties:p];

#elif PLATFORM_ANDROID

        if (JNIEnv* Env = FAndroidApplication::GetJavaEnv())
        {
            static jmethodID Method = FJavaWrapper::FindMethod(Env,
                                                               FJavaWrapper::GameActivityClassID,
                                                               "AndroidThunkJava_UpsightRecordMilestoneEventForScope",
                                                               "()Ljava/lang/String;[java/lang/String;[java/lang/String;",
                                                               false);

            FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, Method);
        }
#endif
    }
    else
    {
        UE_LOG(LogUpsight, Log, TEXT("keys and/or value arguments are empty or nil"));
    }
}

<commit_msg>Should only be referenced for Android builds<commit_after>//
//  Created by Robert Segal on 2014-04-01.
//  Copyright (c) 2016 Get Set Games Inc. All rights reserved.
//

#include "UpsightPrivatePCH.h"

#if PLATFORM_ANDROID
#include "Android/AndroidJNI.h"
#include "AndroidApplication.h"
#endif

bool ValidateValues(TArray<FString> &Keys, TArray<FString> &Values)
{
    const int32 kNumKeys   = Keys.Num();
    const int32 kNumValues = Values.Num();

    if (kNumKeys == 0 || kNumValues == 0)
    {
        return false;
    }

    if (kNumKeys != kNumValues)
    {
        return false;
    }

    return true;
}

#if __OBJC__
NSDictionary* CreateNSDictionary(TArray<FString> &Keys, TArray<FString> &Values)
{
    const int32 kNumKeys = Keys.Num();

    NSMutableDictionary* d = [NSMutableDictionary dictionaryWithCapacity:kNumKeys];

    for (uint32 i = 0; i < kNumKeys; i++)
    {
        FString &k = Keys[i];
        FString &v = Values[i];

        d[k.GetNSString()] = v.GetNSString();
    }

    return d;
}
#endif

void UUpsightFunctions::UpsightRecordAnalyticsEventWithName(FString eventName, TArray<FString> eventKeys, TArray<FString> eventValues)
{
    if ( ValidateValues(eventKeys, eventValues) )
    {
#if PLATFORM_IOS
        NSDictionary *p = CreateNSDictionary(eventKeys, eventValues);

        [Upsight recordAnalyticsEventWithName:eventName.GetNSString() properties: p];

#elif PLATFORM_ANDROID
        if (JNIEnv* Env = FAndroidApplication::GetJavaEnv())
        {
            static jmethodID Method = FJavaWrapper::FindMethod(Env,
                                                               FJavaWrapper::GameActivityClassID,
                                                               "AndroidThunkJava_UpsightRecordAnalyticsEventWithName",
                                                               "()Ljava/lang/String;[java/lang/String;[java/lang/String;",
                                                               false);

            FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, Method);
        }
#endif
    }
    else
    {
        UE_LOG(LogUpsight, Log, TEXT("keys and/or value arguments are empty or nil"));
    }
}

void UUpsightFunctions::UpsightRecordMilestoneEventForScope(FString scope, TArray<FString> eventKeys, TArray<FString> eventValues)
{
    if ( ValidateValues(eventKeys, eventValues) )
    {
#if PLATFORM_IOS
        NSDictionary *p = CreateNSDictionary(eventKeys, eventValues);

        [Upsight recordMilestoneEventForScope:scope.GetNSString() properties:p];

#elif PLATFORM_ANDROID

        if (JNIEnv* Env = FAndroidApplication::GetJavaEnv())
        {
            static jmethodID Method = FJavaWrapper::FindMethod(Env,
                                                               FJavaWrapper::GameActivityClassID,
                                                               "AndroidThunkJava_UpsightRecordMilestoneEventForScope",
                                                               "()Ljava/lang/String;[java/lang/String;[java/lang/String;",
                                                               false);

            FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, Method);
        }
#endif
    }
    else
    {
        UE_LOG(LogUpsight, Log, TEXT("keys and/or value arguments are empty or nil"));
    }
}

<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
//  StackTrace.cc
//------------------------------------------------------------------------------
#if ORYOL_WINDOWS||ORYOL_EMSCRIPTEN||ORYOL_ANDROID||ORYOL_PNACL
#define HAVE_BACKTRACE (0)
#define HAVE_STACKWALKER (1)
#else
#define HAVE_BACKTRACE (1)
#define HAVE_STACKWALKER (0)
#endif
#include "Pre.h"
#include "StackTrace.h"
#if HAVE_BACKTRACE
#include <execinfo.h>
#endif
#if HAVE_STACKWALKER
#include "Core/windows/StackWalker.h"
#endif
#include <cstdlib>
#include <cstring>
#include <cstdio>

/*
    NOTE: The code in StackTrace might be called from signal handlers,
    from any thread, at any time. Be very careful what other functions
    you call!
*/

namespace Oryol {

//------------------------------------------------------------------------------
static char*
appendString(char* str, char* dst, const char* dstEndPtr, bool insertNewLine) {
    if (dst < (dstEndPtr-1)) {
        char c;
        while ((c = *str++) && (dst < (dstEndPtr-1))) {
            *dst++ = c;
        }
        if (dst == (dstEndPtr-1)) {
            --dst;
        }
    }
    // append newline if still room for it
    if (insertNewLine) {
        if (dst < (dstEndPtr-1)) {
            *dst++ = '\n';
        }
    }
    // always terminate with 0
    *dst = 0;
    return dst;
}

//------------------------------------------------------------------------------
#if HAVE_BACKTRACE
void
StackTrace::Dump(char* buf, int bufSize) {
    buf[0] = 0;
    static const int maxFrames = 64;
    void* frames[maxFrames];
    unsigned int numFrames = backtrace(frames, maxFrames);
    if (0 == numFrames) {
        return;
    }
    char** symbols = backtrace_symbols(frames, numFrames);
    char* dstPtr = buf;
    const char* dstEndPtr = buf + bufSize;
    for (unsigned int i = 0; i < numFrames; i++) {
        dstPtr = appendString(symbols[i], dstPtr, dstEndPtr);
    }
    std::free(symbols);
}

//------------------------------------------------------------------------------
#elif HAVE_STACKWALKER
class OryolStackWalker : public StackWalker {
public:
    // this stuff must be initialized before calling StackWalker::ShowCallstack()
    char* dstPtr = nullptr;
    const char* dstEndPtr = nullptr;

    // constructor to hand options up to parent class
    OryolStackWalker(int options) : StackWalker(options) { };
    // this is called by parent class to output text (originally it calls OutputDebugString)
    virtual void OnOutput(LPCSTR szText) {
        this->dstPtr = appendString((char*)szText, this->dstPtr, this->dstEndPtr, false);
    };
};

void
StackTrace::Dump(char* buf, int bufSize) {
    OryolStackWalker stackWalker(StackWalker::RetrieveSymbol);
    stackWalker.dstPtr = buf;
    stackWalker.dstEndPtr = buf + bufSize;
    stackWalker.ShowCallstack();
}

//------------------------------------------------------------------------------
#else
void
StackTrace::Dump(char* buf, int bufSize) {
    std::strncpy(buf, "STACK TRACE NOT IMPLEMENTED\n", bufSize);
    buf[bufSize-1] = 0;
}
#endif

} // namespace Oryol
<commit_msg>Fixed StackTrace for Linux/OSX etc<commit_after>//------------------------------------------------------------------------------
//  StackTrace.cc
//------------------------------------------------------------------------------
#if ORYOL_WINDOWS||ORYOL_EMSCRIPTEN||ORYOL_ANDROID||ORYOL_PNACL
#define HAVE_BACKTRACE (0)
#define HAVE_STACKWALKER (1)
#else
#define HAVE_BACKTRACE (1)
#define HAVE_STACKWALKER (0)
#endif
#include "Pre.h"
#include "StackTrace.h"
#if HAVE_BACKTRACE
#include <execinfo.h>
#endif
#if HAVE_STACKWALKER
#include "Core/windows/StackWalker.h"
#endif
#include <cstdlib>
#include <cstring>
#include <cstdio>

/*
    NOTE: The code in StackTrace might be called from signal handlers,
    from any thread, at any time. Be very careful what other functions
    you call!
*/

namespace Oryol {

//------------------------------------------------------------------------------
static char*
appendString(char* str, char* dst, const char* dstEndPtr, bool insertNewLine) {
    if (dst < (dstEndPtr-1)) {
        char c;
        while ((c = *str++) && (dst < (dstEndPtr-1))) {
            *dst++ = c;
        }
        if (dst == (dstEndPtr-1)) {
            --dst;
        }
    }
    // append newline if still room for it
    if (insertNewLine) {
        if (dst < (dstEndPtr-1)) {
            *dst++ = '\n';
        }
    }
    // always terminate with 0
    *dst = 0;
    return dst;
}

//------------------------------------------------------------------------------
#if HAVE_BACKTRACE
void
StackTrace::Dump(char* buf, int bufSize) {
    buf[0] = 0;
    static const int maxFrames = 64;
    void* frames[maxFrames];
    unsigned int numFrames = backtrace(frames, maxFrames);
    if (0 == numFrames) {
        return;
    }
    char** symbols = backtrace_symbols(frames, numFrames);
    char* dstPtr = buf;
    const char* dstEndPtr = buf + bufSize;
    for (unsigned int i = 0; i < numFrames; i++) {
        dstPtr = appendString(symbols[i], dstPtr, dstEndPtr, true);
    }
    std::free(symbols);
}

//------------------------------------------------------------------------------
#elif HAVE_STACKWALKER
class OryolStackWalker : public StackWalker {
public:
    // this stuff must be initialized before calling StackWalker::ShowCallstack()
    char* dstPtr = nullptr;
    const char* dstEndPtr = nullptr;

    // constructor to hand options up to parent class
    OryolStackWalker(int options) : StackWalker(options) { };
    // this is called by parent class to output text (originally it calls OutputDebugString)
    virtual void OnOutput(LPCSTR szText) {
        this->dstPtr = appendString((char*)szText, this->dstPtr, this->dstEndPtr, false);
    };
};

void
StackTrace::Dump(char* buf, int bufSize) {
    OryolStackWalker stackWalker(StackWalker::RetrieveSymbol);
    stackWalker.dstPtr = buf;
    stackWalker.dstEndPtr = buf + bufSize;
    stackWalker.ShowCallstack();
}

//------------------------------------------------------------------------------
#else
void
StackTrace::Dump(char* buf, int bufSize) {
    std::strncpy(buf, "STACK TRACE NOT IMPLEMENTED\n", bufSize);
    buf[bufSize-1] = 0;
}
#endif

} // namespace Oryol
<|endoftext|>


<commit_before>#include "ruderegistrywin.h"

#include <WinError.h>

RudeRegistryWin::RudeRegistryWin(void)
{
}

RudeRegistryWin::~RudeRegistryWin(void)
{
}

int RudeRegistryWin::QueryByte(const TCHAR *app, const TCHAR *name, void *buffer, int *buffersize)
{
	HKEY hkey;
	DWORD type;
	DWORD bufsize = *buffersize;
	TCHAR keypath[400];

	_stprintf(keypath, _T("SOFTWARE\\Bork3D\\%s"), app);

	LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keypath,
						NULL, KEY_ALL_ACCESS, &hkey);
	if(result != ERROR_SUCCESS)
		return result;

	result = RegQueryValueEx(hkey, name, NULL, &type, (LPBYTE) buffer, &bufsize);

	*buffersize = bufsize;
	RegCloseKey(hkey);

	return result;
}

int RudeRegistryWin::SetByte(const TCHAR *app, const TCHAR *name, void *buffer, int buffersize)
{
	HKEY software_hkey, bork3d_hkey, app_hkey;

	DWORD disposition;
	LONG result = RegCreateKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE"),
		NULL, NULL, NULL, KEY_ALL_ACCESS, NULL, &software_hkey, &disposition);
	RUDE_ASSERT(result == ERROR_SUCCESS, "Unable to open HKEY_LOCAL_MACHINE\\SOFTWARE - %d", result);

	result = RegCreateKeyEx(software_hkey, _T("Bork3D"),
		NULL, NULL, NULL, KEY_ALL_ACCESS, NULL, &bork3d_hkey, &disposition);
	RUDE_ASSERT(result == ERROR_SUCCESS, "Unable to open HKEY_LOCAL_MACHINE\\SOFTWARE\\Bork3D - %d", result);

	result = RegCreateKeyEx(bork3d_hkey, app,
		NULL, NULL, NULL, KEY_ALL_ACCESS, NULL, &app_hkey, &disposition);
	RUDE_ASSERT(result == ERROR_SUCCESS, "Unable to open HKEY_LOCAL_MACHINE\\SOFTWARE\\Bork3D\\%s - %d", app, result);

	result = RegSetValueEx(app_hkey, name, NULL, REG_BINARY, (LPBYTE) buffer, buffersize);
	RUDE_ASSERT(result == ERROR_SUCCESS, "Unable to write registry key, got error %d", result);

	RegCloseKey(app_hkey);
	RegCloseKey(bork3d_hkey);
	RegCloseKey(software_hkey);

	return 0;
}
<commit_msg>Fix for registry issue in Win7<commit_after>#include "ruderegistrywin.h"

#include <WinError.h>

RudeRegistryWin::RudeRegistryWin(void)
{
}

RudeRegistryWin::~RudeRegistryWin(void)
{
}

int RudeRegistryWin::QueryByte(const TCHAR *app, const TCHAR *name, void *buffer, int *buffersize)
{
	HKEY hkey;
	DWORD type;
	DWORD bufsize = *buffersize;
	TCHAR keypath[400];

	_stprintf(keypath, _T("SOFTWARE\\Bork3D\\%s"), app);

	LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keypath,
						NULL, KEY_ALL_ACCESS, &hkey);
	if(result != ERROR_SUCCESS)
		return result;

	result = RegQueryValueEx(hkey, name, NULL, &type, (LPBYTE) buffer, &bufsize);

	*buffersize = bufsize;
	RegCloseKey(hkey);

	return result;
}

int RudeRegistryWin::SetByte(const TCHAR *app, const TCHAR *name, void *buffer, int buffersize)
{
	HKEY bork3d_hkey, app_hkey;

	DWORD disposition;
	LONG result;

	result = RegCreateKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Bork3D"),
		NULL, NULL, NULL, KEY_ALL_ACCESS, NULL, &bork3d_hkey, &disposition);
	RUDE_ASSERT(result == ERROR_SUCCESS, "Unable to open HKEY_LOCAL_MACHINE\\SOFTWARE\\Bork3D - %d", result);

	result = RegCreateKeyEx(bork3d_hkey, app,
		NULL, NULL, NULL, KEY_ALL_ACCESS, NULL, &app_hkey, &disposition);
	RUDE_ASSERT(result == ERROR_SUCCESS, "Unable to open HKEY_LOCAL_MACHINE\\SOFTWARE\\Bork3D\\%s - %d", app, result);

	result = RegSetValueEx(app_hkey, name, NULL, REG_BINARY, (LPBYTE) buffer, buffersize);
	RUDE_ASSERT(result == ERROR_SUCCESS, "Unable to write registry key, got error %d", result);

	RegCloseKey(app_hkey);
	RegCloseKey(bork3d_hkey);

	return 0;
}
<|endoftext|>


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

/// \file
/// Tests for the OsgView class.

#include <SurgSim/Graphics/UnitTests/MockObjects.h>
#include <SurgSim/Graphics/UnitTests/MockOsgObjects.h>

#include <gtest/gtest.h>

#include <random>

using SurgSim::Graphics::Camera;
using SurgSim::Graphics::Manager;
using SurgSim::Graphics::View;
using SurgSim::Graphics::OsgCamera;
using SurgSim::Graphics::OsgView;

TEST(OsgViewTests, InitTest)
{
	ASSERT_NO_THROW({std::shared_ptr<View> view = std::make_shared<OsgView>("test name");});

	std::shared_ptr<View> view = std::make_shared<OsgView>("test name");

	EXPECT_EQ("test name", view->getName());

	EXPECT_EQ(nullptr, view->getCamera());

	int x, y;
	view->getPosition(&x, &y);
	EXPECT_EQ(0, x);
	EXPECT_EQ(0, y);

	int width, height;
	view->getDimensions(&width, &height);
	EXPECT_EQ(800, width);
	EXPECT_EQ(600, height);
}

TEST(OsgViewTests, PositionAndDimensionsTest)
{
	std::shared_ptr<OsgView> osgView = std::make_shared<MockOsgView>("test name");
	std::shared_ptr<View> view = std::make_shared<MockOsgView>("test name");

	std::default_random_engine generator;
	std::uniform_int_distribution<int> distribution(0, 1000);

	int x = distribution(generator);
	int y = distribution(generator);
	int width = distribution(generator);
	int height = distribution(generator);

	/// Set position and check that it set correctly
	EXPECT_TRUE(view->setPosition(x, y));

	int testX, testY;
	view->getPosition(&testX, &testY);

	EXPECT_EQ(x, testX);
	EXPECT_EQ(y, testY);

	/// Set dimensions and check that it set correctly
	EXPECT_TRUE(view->setDimensions(width, height));

	int testWidth, testHeight;
	view->getDimensions(&testWidth, &testHeight);

	EXPECT_EQ(width, testWidth);
	EXPECT_EQ(height, testHeight);
}

TEST(OsgViewTests, CameraTest)
{
	std::shared_ptr<View> view = std::make_shared<OsgView>("test name");

	std::shared_ptr<Camera> camera = std::make_shared<OsgCamera>("test camera");

	/// Set the camera and check that it set correctly
	EXPECT_TRUE(view->setCamera(camera));
	EXPECT_EQ(camera, view->getCamera());

	std::shared_ptr<Camera> mockCamera = std::make_shared<MockCamera>("non-osg camera");

	/// Try to set a camera that does not derive from OsgCamera
	EXPECT_FALSE(view->setCamera(mockCamera));
	EXPECT_EQ(camera, view->getCamera());
}

TEST(OsgViewTests, UpdateTest)
{
	std::shared_ptr<MockOsgView> mockOsgView = std::make_shared<MockOsgView>("test view");
	std::shared_ptr<View> view = mockOsgView;

	std::shared_ptr<Camera> camera = std::make_shared<OsgCamera>("test camera");
	view->setCamera(camera);

	/// Make sure that we can successfully initialize, which setups up the window
	EXPECT_TRUE(mockOsgView->initialize());

	EXPECT_EQ(0u, mockOsgView->getNumUpdates());
	EXPECT_EQ(0.0, mockOsgView->getSumDt());

	double sumDt = 0.0;
	std::default_random_engine generator;
	std::uniform_real_distribution<double> distribution(0.0, 1.0);

	/// Do 10 updates with random dt and check each time that the number of updates and sum of dt are correct.
	/// Also change the position and then dimensions and check that they are updated correctly at the OSG level.
	for (int i = 1; i <= 10; ++i)
	{
		double dt = distribution(generator);
		sumDt += dt;

		/// Try changing the position
		if (i == 3)
		{
			view->setPosition(50, 60);
		}
		/// Try changing the dimensions
		if (i == 6)
		{
			view->setDimensions(100, 200);
		}

		view->update(dt);

		EXPECT_EQ(i, mockOsgView->getNumUpdates());
		EXPECT_EQ(sumDt, mockOsgView->getSumDt());

		/// The position should initially be (0, 0) and dimensions 800 x 600
		if (i < 3)
		{
			std::shared_ptr<OsgCamera> osgCamera = std::dynamic_pointer_cast<OsgCamera>(mockOsgView->getCamera());
			EXPECT_NE(nullptr, osgCamera);

			osgViewer::GraphicsWindow* window = dynamic_cast<osgViewer::GraphicsWindow*>(
				osgCamera->getOsgCamera()->getGraphicsContext());

			EXPECT_NE(nullptr, window);
			int testX, testY, testWidth, testHeight;
			window->getWindowRectangle(testX, testY, testWidth, testHeight);

			EXPECT_EQ(0, testX);
			EXPECT_EQ(0, testY);
			EXPECT_EQ(0, testWidth);
			EXPECT_EQ(0, testHeight);
		}
		/// The position should now be (50, 60) and dimensions 800 x 600
		else if (i >= 3 && i < 6)
		{
			std::shared_ptr<OsgCamera> osgCamera = std::dynamic_pointer_cast<OsgCamera>(mockOsgView->getCamera());
			EXPECT_NE(nullptr, osgCamera);

			osgViewer::GraphicsWindow* window = dynamic_cast<osgViewer::GraphicsWindow*>(
				osgCamera->getOsgCamera()->getGraphicsContext());

			EXPECT_NE(nullptr, window);
			int testX, testY, testWidth, testHeight;
			window->getWindowRectangle(testX, testY, testWidth, testHeight);

			EXPECT_EQ(50, testX);
			EXPECT_EQ(60, testY);
			EXPECT_EQ(800, testWidth);
			EXPECT_EQ(600, testHeight);
		}
		/// The position should now be (50, 60) and dimensions 100 x 200
		else if (i >= 6)
		{
			std::shared_ptr<OsgCamera> osgCamera = std::dynamic_pointer_cast<OsgCamera>(mockOsgView->getCamera());
			EXPECT_NE(nullptr, osgCamera);

			osgViewer::GraphicsWindow* window = dynamic_cast<osgViewer::GraphicsWindow*>(
				osgCamera->getOsgCamera()->getGraphicsContext());

			EXPECT_NE(nullptr, window);
			int testX, testY, testWidth, testHeight;
			window->getWindowRectangle(testX, testY, testWidth, testHeight);

			EXPECT_EQ(50, testX);
			EXPECT_EQ(60, testY);
			EXPECT_EQ(100, testWidth);
			EXPECT_EQ(200, testHeight);
		}
	}
}
<commit_msg>Remove low level testing of window rectangle in OsgViewTests.cpp. Some osg::GraphicsWindow implementations will not update these traits until doing a frame(). This test will appear in the OsgManager tests, where the osg::CompositeViewer will collect these views.<commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2012-2013, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// \file
/// Tests for the OsgView class.

#include <SurgSim/Graphics/UnitTests/MockObjects.h>
#include <SurgSim/Graphics/UnitTests/MockOsgObjects.h>

#include <gtest/gtest.h>

#include <random>

using SurgSim::Graphics::Camera;
using SurgSim::Graphics::Manager;
using SurgSim::Graphics::View;
using SurgSim::Graphics::OsgCamera;
using SurgSim::Graphics::OsgView;

TEST(OsgViewTests, InitTest)
{
	ASSERT_NO_THROW({std::shared_ptr<View> view = std::make_shared<OsgView>("test name");});

	std::shared_ptr<View> view = std::make_shared<OsgView>("test name");

	EXPECT_EQ("test name", view->getName());

	EXPECT_EQ(nullptr, view->getCamera());

	int x, y;
	view->getPosition(&x, &y);
	EXPECT_EQ(0, x);
	EXPECT_EQ(0, y);

	int width, height;
	view->getDimensions(&width, &height);
	EXPECT_EQ(800, width);
	EXPECT_EQ(600, height);
}

TEST(OsgViewTests, PositionAndDimensionsTest)
{
	std::shared_ptr<OsgView> osgView = std::make_shared<MockOsgView>("test name");
	std::shared_ptr<View> view = std::make_shared<MockOsgView>("test name");

	std::default_random_engine generator;
	std::uniform_int_distribution<int> distribution(0, 1000);

	int x = distribution(generator);
	int y = distribution(generator);
	int width = distribution(generator);
	int height = distribution(generator);

	/// Set position and check that it set correctly
	EXPECT_TRUE(view->setPosition(x, y));

	int testX, testY;
	view->getPosition(&testX, &testY);

	EXPECT_EQ(x, testX);
	EXPECT_EQ(y, testY);

	/// Set dimensions and check that it set correctly
	EXPECT_TRUE(view->setDimensions(width, height));

	int testWidth, testHeight;
	view->getDimensions(&testWidth, &testHeight);

	EXPECT_EQ(width, testWidth);
	EXPECT_EQ(height, testHeight);
}

TEST(OsgViewTests, CameraTest)
{
	std::shared_ptr<View> view = std::make_shared<OsgView>("test name");

	std::shared_ptr<Camera> camera = std::make_shared<OsgCamera>("test camera");

	/// Set the camera and check that it set correctly
	EXPECT_TRUE(view->setCamera(camera));
	EXPECT_EQ(camera, view->getCamera());

	std::shared_ptr<Camera> mockCamera = std::make_shared<MockCamera>("non-osg camera");

	/// Try to set a camera that does not derive from OsgCamera
	EXPECT_FALSE(view->setCamera(mockCamera));
	EXPECT_EQ(camera, view->getCamera());
}

TEST(OsgViewTests, UpdateTest)
{
	std::shared_ptr<MockOsgView> mockOsgView = std::make_shared<MockOsgView>("test view");
	std::shared_ptr<View> view = mockOsgView;

	std::shared_ptr<Camera> camera = std::make_shared<OsgCamera>("test camera");
	view->setCamera(camera);

	/// Make sure that we can successfully initialize, which setups up the window
	EXPECT_TRUE(mockOsgView->initialize());

	EXPECT_EQ(0u, mockOsgView->getNumUpdates());
	EXPECT_EQ(0.0, mockOsgView->getSumDt());

	double sumDt = 0.0;
	std::default_random_engine generator;
	std::uniform_real_distribution<double> distribution(0.0, 1.0);

	/// Do 10 updates with random dt and check each time that the number of updates and sum of dt are correct.
	for (int i = 1; i <= 10; ++i)
	{
		double dt = distribution(generator);
		sumDt += dt;

		view->update(dt);

		EXPECT_EQ(i, mockOsgView->getNumUpdates());
		EXPECT_EQ(sumDt, mockOsgView->getSumDt());
	}
}
<|endoftext|>


<commit_before>#include "vm.hpp"
#include "objectmemory.hpp"
#include "event.hpp"
#include "global_cache.hpp"
#include "llvm.hpp"
#include "builtin/class.hpp"
#include "builtin/contexts.hpp"
#include "builtin/fixnum.hpp"
#include "builtin/list.hpp"
#include "builtin/symbol.hpp"
#include "builtin/thread.hpp"
#include "builtin/tuple.hpp"
#include "builtin/string.hpp"
#include "builtin/taskprobe.hpp"

#include "context_cache.hpp"
#include "config.hpp"

#include <iostream>

// Reset macros since we're inside state
#undef G
#undef GO
#define G(whatever) globals.whatever.get()
#define GO(whatever) globals.whatever

namespace rubinius {
  VM::VM(size_t bytes) : wait_events(false), reuse_llvm(true) {
    config.compile_up_front = false;
    context_cache = NULL;

    VM::register_state(this);

    user_config = new ConfigParser();

    om = new ObjectMemory(this, bytes);
    probe.set(Qnil, &globals.roots);

    MethodContext::initialize_cache(this);
    TypeInfo::init(this);

    bootstrap_ontology();

    signal_events = new event::Loop();
    //events = new event::Loop(EVFLAG_FORKCHECK);
    events = signal_events;

    global_cache = new GlobalCache;

    VMLLVMMethod::init("vm/instructions.bc");
    boot_threads();
  }

  VM::~VM() {
    delete om;
    delete signal_events;
    delete global_cache;
    if(!reuse_llvm) llvm_cleanup();
  }

  // HACK so not thread safe or anything!
  static VM* __state = NULL;

  VM* VM::current_state() {
    return __state;
  }

  void VM::register_state(VM *vm) {
    __state = vm;
  }

  void VM::boot_threads() {
    Thread* thr = Thread::create(this);

    activate_thread(thr);
  }

  OBJECT VM::new_object(Class *cls) {
    return om->new_object(cls, cls->instance_fields()->to_native());
  }

  Class* VM::new_basic_class(Class* sup, size_t fields) {
    Class *cls = (Class*)om->new_object(G(klass), Class::fields);
    cls->instance_fields(this, Fixnum::from(fields));
    if(sup->nil_p()) {
      cls->instance_type(this, Fixnum::from(ObjectType));
    } else {
      cls->instance_type(this, sup->instance_type()); // HACK test that this is always true
    }
    cls->superclass(this, sup);

    return cls;
  }

  Class* VM::new_class(const char* name) {
    return new_class(name, G(object), G(object)->instance_fields()->to_native(),
        G(object));
  }

  Class* VM::new_class(const char* name, Class* super_class) {
    return new_class(name, super_class, G(object)->instance_fields()->to_native(),
        G(object));
  }

  Class* VM::new_class(const char* name, Class* sup, size_t fields) {
    return new_class(name, sup, fields, G(object));
  }

  Class* VM::new_class(const char* name, Class* sup, size_t fields, Module* under) {
    Class* cls = new_basic_class(sup, fields);
    cls->setup(this, name, under);

    // HACK test that we've got the MOP setup properly
    MetaClass::attach(this, cls, sup->metaclass(this));
    return cls;
  }

  Class* VM::new_class_under(const char* name, Module* under) {
    return new_class(name, G(object), G(object)->instance_fields()->to_native(), under);
  }

  Module* VM::new_module(const char* name, Module* under) {
    Module *mod = (Module*)om->new_object(G(module), Module::fields);
    mod->setup(this, name, under);
    return mod;
  }

  SYMBOL VM::symbol(const char* str) {
    return symbols.lookup(this, str);
  }

  SYMBOL VM::symbol(String* str) {
    return symbols.lookup(this, str);
  }

  SYMBOL VM::symbol(std::string str) {
    return symbols.lookup(this, str);
  }

  OBJECT VM::new_struct(Class* cls, size_t bytes) {
    Object* obj = om->new_object_bytes(cls, bytes);
    obj->ivars(this, Qnil);
    return obj;
  }

  void type_assert(STATE, OBJECT obj, object_type type, const char* reason) {
    if((obj->reference_p() && obj->obj_type != type)
        || (type == FixnumType && !obj->fixnum_p())) {
      Exception::type_error(state, type, obj, reason);
    }
  }

  void VM::add_type_info(TypeInfo* ti) {
    om->add_type_info(ti);
    ti->state = this;
  }

  TypeInfo* VM::find_type(int type) {
    return om->type_info[type];
  }

  Thread *VM::current_thread() {
    return globals.current_thread.get();
  }

  void VM::collect() {
    om->collect_young(globals.roots);
    om->collect_mature(globals.roots);
  }

  bool VM::find_and_activate_thread() {
    for(size_t i = globals.scheduled_threads->num_fields() - 1; i > 0; i--) {
      List* lst = as<List>(globals.scheduled_threads->at(this, i));
      if(lst->empty_p()) continue;
      activate_thread(as<Thread>(lst->shift(this)));
      return true;
    }

    return false;
  }

  bool VM::run_best_thread() {
    events->poll();

    if(!find_and_activate_thread()) {
      if(events->num_of_events() == 0) {
        throw DeadLock("no runnable threads, present or future.");
      }

      wait_events = true;
      return false;
    }
    return true;
  }

  void VM::return_value(OBJECT val) {
    globals.current_task->push(val);
  }

  void VM::queue_thread(Thread* thread) {
    List* lst = as<List>(globals.scheduled_threads->at(this,
          thread->priority()->to_native()));
    lst->append(this, thread);

    thread->woken(this);
  }

  void VM::activate_thread(Thread* thread) {
    globals.current_thread.set(thread);
    if(globals.current_task.get() != thread->task()) {
      activate_task(thread->task());
    }

    thread->woken(this);
  }

  void VM::activate_task(Task* task) {
    // Don't try and reclaim any contexts, they belong to someone else.
    context_cache->reclaim = 0;

    globals.current_task.set(task);
    interrupts.check = true;
    interrupts.switch_task = true;
  }

  OBJECT VM::current_block() {
    return globals.current_task->active()->block();
  }

  void VM::raise_from_errno(const char* msg) {
    // TODO: implement me
  }

  void VM::raise_exception(Exception* exc) {
    // TODO: implement me
  }

  void VM::set_const(const char* name, OBJECT val) {
    globals.object->set_const(this, (char*)name, val);
  }

  void VM::set_const(Module* mod, const char* name, OBJECT val) {
    mod->set_const(this, (char*)name, val);
  }

  void VM::print_backtrace() {
    globals.current_task.get()->print_backtrace();
  }

  Task* VM::new_task() {
    Task* task = Task::create(this);
    activate_task(task);
    return task;
  }

  void VM::run_and_monitor() {
    for(;;) {
      while(wait_events) {
        wait_events = false;
        events->run_and_wait();
        wait_events = !find_and_activate_thread();
      }

      G(current_task)->check_interrupts();
      G(current_task)->execute();
    }
  }

  /* For debugging. */
  extern "C" {
    void __printbt__() {
      VM::current_state()->print_backtrace();
    }
  }
};
<commit_msg>Add forkcheck flag to event loop and init SIGCHLD handler at VM startup.<commit_after>#include "vm.hpp"
#include "objectmemory.hpp"
#include "event.hpp"
#include "global_cache.hpp"
#include "llvm.hpp"
#include "builtin/class.hpp"
#include "builtin/contexts.hpp"
#include "builtin/fixnum.hpp"
#include "builtin/list.hpp"
#include "builtin/symbol.hpp"
#include "builtin/thread.hpp"
#include "builtin/tuple.hpp"
#include "builtin/string.hpp"
#include "builtin/taskprobe.hpp"

#include "context_cache.hpp"
#include "config.hpp"

#include <iostream>

// Reset macros since we're inside state
#undef G
#undef GO
#define G(whatever) globals.whatever.get()
#define GO(whatever) globals.whatever

namespace rubinius {
  VM::VM(size_t bytes) : wait_events(false), reuse_llvm(true) {
    config.compile_up_front = false;
    context_cache = NULL;

    VM::register_state(this);

    user_config = new ConfigParser();

    om = new ObjectMemory(this, bytes);
    probe.set(Qnil, &globals.roots);

    MethodContext::initialize_cache(this);
    TypeInfo::init(this);

    bootstrap_ontology();

    /* TODO: Using a single default loop, revisit when many loops.
     * TODO: This needs to be handled through the environment.
     */
    signal_events = new event::Loop(EVFLAG_FORKCHECK);
    events = signal_events;

    signal_events->start(new event::Child::Event(this));

    global_cache = new GlobalCache;

    VMLLVMMethod::init("vm/instructions.bc");
    boot_threads();
  }

  VM::~VM() {
    delete om;
    delete signal_events;
    delete global_cache;
    if(!reuse_llvm) llvm_cleanup();
  }

  // HACK so not thread safe or anything!
  static VM* __state = NULL;

  VM* VM::current_state() {
    return __state;
  }

  void VM::register_state(VM *vm) {
    __state = vm;
  }

  void VM::boot_threads() {
    Thread* thr = Thread::create(this);

    activate_thread(thr);
  }

  OBJECT VM::new_object(Class *cls) {
    return om->new_object(cls, cls->instance_fields()->to_native());
  }

  Class* VM::new_basic_class(Class* sup, size_t fields) {
    Class *cls = (Class*)om->new_object(G(klass), Class::fields);
    cls->instance_fields(this, Fixnum::from(fields));
    if(sup->nil_p()) {
      cls->instance_type(this, Fixnum::from(ObjectType));
    } else {
      cls->instance_type(this, sup->instance_type()); // HACK test that this is always true
    }
    cls->superclass(this, sup);

    return cls;
  }

  Class* VM::new_class(const char* name) {
    return new_class(name, G(object), G(object)->instance_fields()->to_native(),
        G(object));
  }

  Class* VM::new_class(const char* name, Class* super_class) {
    return new_class(name, super_class, G(object)->instance_fields()->to_native(),
        G(object));
  }

  Class* VM::new_class(const char* name, Class* sup, size_t fields) {
    return new_class(name, sup, fields, G(object));
  }

  Class* VM::new_class(const char* name, Class* sup, size_t fields, Module* under) {
    Class* cls = new_basic_class(sup, fields);
    cls->setup(this, name, under);

    // HACK test that we've got the MOP setup properly
    MetaClass::attach(this, cls, sup->metaclass(this));
    return cls;
  }

  Class* VM::new_class_under(const char* name, Module* under) {
    return new_class(name, G(object), G(object)->instance_fields()->to_native(), under);
  }

  Module* VM::new_module(const char* name, Module* under) {
    Module *mod = (Module*)om->new_object(G(module), Module::fields);
    mod->setup(this, name, under);
    return mod;
  }

  SYMBOL VM::symbol(const char* str) {
    return symbols.lookup(this, str);
  }

  SYMBOL VM::symbol(String* str) {
    return symbols.lookup(this, str);
  }

  SYMBOL VM::symbol(std::string str) {
    return symbols.lookup(this, str);
  }

  OBJECT VM::new_struct(Class* cls, size_t bytes) {
    Object* obj = om->new_object_bytes(cls, bytes);
    obj->ivars(this, Qnil);
    return obj;
  }

  void type_assert(STATE, OBJECT obj, object_type type, const char* reason) {
    if((obj->reference_p() && obj->obj_type != type)
        || (type == FixnumType && !obj->fixnum_p())) {
      Exception::type_error(state, type, obj, reason);
    }
  }

  void VM::add_type_info(TypeInfo* ti) {
    om->add_type_info(ti);
    ti->state = this;
  }

  TypeInfo* VM::find_type(int type) {
    return om->type_info[type];
  }

  Thread *VM::current_thread() {
    return globals.current_thread.get();
  }

  void VM::collect() {
    om->collect_young(globals.roots);
    om->collect_mature(globals.roots);
  }

  bool VM::find_and_activate_thread() {
    for(size_t i = globals.scheduled_threads->num_fields() - 1; i > 0; i--) {
      List* lst = as<List>(globals.scheduled_threads->at(this, i));
      if(lst->empty_p()) continue;
      activate_thread(as<Thread>(lst->shift(this)));
      return true;
    }

    return false;
  }

  bool VM::run_best_thread() {
    events->poll();

    if(!find_and_activate_thread()) {
      if(events->num_of_events() == 0) {
        throw DeadLock("no runnable threads, present or future.");
      }

      wait_events = true;
      return false;
    }
    return true;
  }

  void VM::return_value(OBJECT val) {
    globals.current_task->push(val);
  }

  void VM::queue_thread(Thread* thread) {
    List* lst = as<List>(globals.scheduled_threads->at(this,
          thread->priority()->to_native()));
    lst->append(this, thread);

    thread->woken(this);
  }

  void VM::activate_thread(Thread* thread) {
    globals.current_thread.set(thread);
    if(globals.current_task.get() != thread->task()) {
      activate_task(thread->task());
    }

    thread->woken(this);
  }

  void VM::activate_task(Task* task) {
    // Don't try and reclaim any contexts, they belong to someone else.
    context_cache->reclaim = 0;

    globals.current_task.set(task);
    interrupts.check = true;
    interrupts.switch_task = true;
  }

  OBJECT VM::current_block() {
    return globals.current_task->active()->block();
  }

  void VM::raise_from_errno(const char* msg) {
    // TODO: implement me
  }

  void VM::raise_exception(Exception* exc) {
    // TODO: implement me
  }

  void VM::set_const(const char* name, OBJECT val) {
    globals.object->set_const(this, (char*)name, val);
  }

  void VM::set_const(Module* mod, const char* name, OBJECT val) {
    mod->set_const(this, (char*)name, val);
  }

  void VM::print_backtrace() {
    globals.current_task.get()->print_backtrace();
  }

  Task* VM::new_task() {
    Task* task = Task::create(this);
    activate_task(task);
    return task;
  }

  void VM::run_and_monitor() {
    for(;;) {
      while(wait_events) {
        wait_events = false;
        events->run_and_wait();
        wait_events = !find_and_activate_thread();
      }

      G(current_task)->check_interrupts();
      G(current_task)->execute();
    }
  }

  /* For debugging. */
  extern "C" {
    void __printbt__() {
      VM::current_state()->print_backtrace();
    }
  }
};
<|endoftext|>