<commit_before>#pragma once

#include <cstdint>
#include <vector>
#include <string>

namespace rtp {

/// Max packet size.  This is limited by the CC1201 buffer size.
static const unsigned int MAX_DATA_SZ = 120;

const uint8_t BROADCAST_ADDRESS = 0;
const uint8_t BASE_STATION_ADDRESS = 1;
const uint8_t LOOPBACK_ADDRESS = 2;

/**
 * @brief Port enumerations for different communication protocols.
 */
enum port { SINK = 0, LINK, CONTROL, LEGACY, PING };

struct header_data {
    enum Type { Control, Tuning, FirmwareUpdate, Misc };

    header_data(uint8_t p = SINK) : address(0), port(p), type(Control){};

    uint8_t address;
    unsigned int port : 4;
    Type type : 4;

    /// "packed" size (in bytes) of header data
    size_t size() const { return 2; }

    void pack(std::vector<uint8_t>* buf) const {
        buf->push_back(address);
        buf->push_back(port << 4 | type);
    }

    void unpack(const std::vector<uint8_t>& buf) { unpack(buf.data()); }

    void unpack(const uint8_t* buf) {
        address = buf[1];
        port = buf[2] >> 4;
        type = (Type)(buf[2] & 0x0F);
    }
};

/**
 * @brief Real-Time packet definition
 */
class packet {
public:
    rtp::header_data header;
    std::vector<uint8_t> payload;

    packet(){};
    packet(const std::string& s, uint8_t p = SINK) : header(p) {
        for (char c : s) payload.push_back(c);
        payload.push_back('\0');
    }

    template <class T>
    packet(const std::vector<T>& v, uint8_t p = SINK)
        : header(p) {
        for (T val : v) payload.push_back(val);
    }

    size_t size() const { return payload.size() + header.size(); }

    int port() const { return static_cast<int>(header.port); }
    template <class T>
    void port(T p) {
        header.port = static_cast<unsigned int>(p);
    }

    int address() { return header.address; }
    void address(int a) { header.address = static_cast<unsigned int>(a); }

    template <class T>
    void recv(const std::vector<T>& v) {
        recv(v.data(), v.size());
    }

    void recv(const uint8_t* buffer, size_t size) {
        // note: header ignores the first byte since it's the size byte
        header.unpack(buffer);

        // Everything after the header is payload data
        payload.clear();
        for (size_t i = header.size() + 1; i < size; i++) {
            payload.push_back(buffer[i]);
        }
    }

    void pack(std::vector<uint8_t>* buffer) const {
        // first byte is total size (excluding the size byte)
        const uint8_t total_size = payload.size() + header.size();
        buffer->reserve(total_size + 1);

        buffer->push_back(total_size);

        header.pack(buffer);

        // payload
        buffer->insert(buffer->end(), payload.begin(), payload.end());
    }
};
}
<commit_msg>assigned values to port enum<commit_after>#pragma once

#include <cstdint>
#include <vector>
#include <string>

namespace rtp {

/// Max packet size.  This is limited by the CC1201 buffer size.
static const unsigned int MAX_DATA_SZ = 120;

const uint8_t BROADCAST_ADDRESS = 0;
const uint8_t BASE_STATION_ADDRESS = 1;
const uint8_t LOOPBACK_ADDRESS = 2;

/**
 * @brief Port enumerations for different communication protocols.
 */
enum port { SINK = 0, LINK = 1, CONTROL = 2, LEGACY = 3, PING = 4 };

struct header_data {
    enum Type { Control, Tuning, FirmwareUpdate, Misc };

    header_data(uint8_t p = SINK) : address(0), port(p), type(Control){};

    uint8_t address;
    unsigned int port : 4;
    Type type : 4;

    /// "packed" size (in bytes) of header data
    size_t size() const { return 2; }

    void pack(std::vector<uint8_t>* buf) const {
        buf->push_back(address);
        buf->push_back(port << 4 | type);
    }

    void unpack(const std::vector<uint8_t>& buf) { unpack(buf.data()); }

    void unpack(const uint8_t* buf) {
        address = buf[1];
        port = buf[2] >> 4;
        type = (Type)(buf[2] & 0x0F);
    }
};

/**
 * @brief Real-Time packet definition
 */
class packet {
public:
    rtp::header_data header;
    std::vector<uint8_t> payload;

    packet(){};
    packet(const std::string& s, uint8_t p = SINK) : header(p) {
        for (char c : s) payload.push_back(c);
        payload.push_back('\0');
    }

    template <class T>
    packet(const std::vector<T>& v, uint8_t p = SINK)
        : header(p) {
        for (T val : v) payload.push_back(val);
    }

    size_t size() const { return payload.size() + header.size(); }

    int port() const { return static_cast<int>(header.port); }
    template <class T>
    void port(T p) {
        header.port = static_cast<unsigned int>(p);
    }

    int address() { return header.address; }
    void address(int a) { header.address = static_cast<unsigned int>(a); }

    template <class T>
    void recv(const std::vector<T>& v) {
        recv(v.data(), v.size());
    }

    void recv(const uint8_t* buffer, size_t size) {
        // note: header ignores the first byte since it's the size byte
        header.unpack(buffer);

        // Everything after the header is payload data
        payload.clear();
        for (size_t i = header.size() + 1; i < size; i++) {
            payload.push_back(buffer[i]);
        }
    }

    void pack(std::vector<uint8_t>* buffer) const {
        // first byte is total size (excluding the size byte)
        const uint8_t total_size = payload.size() + header.size();
        buffer->reserve(total_size + 1);

        buffer->push_back(total_size);

        header.pack(buffer);

        // payload
        buffer->insert(buffer->end(), payload.begin(), payload.end());
    }
};
}
<|endoftext|>


<commit_before>/*
 * GameKeeper Framework
 *
 * Copyright (C) 2013 Karol Herbst <gamekeeper@karolherbst.de>
 *
 * 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 "runtime.h"

#include <gamekeeper/core/common.h>

#include <cstdlib>

#include <gamekeeper/core/logger.h>
#include <gamekeeper/core/loggerStream.h>
#include <gamekeeper/client/gamekeeper.h>
#include <gamekeeper/client/hypodermic.h>

#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>

#include <Hypodermic/ContainerBuilder.h>
#include <Hypodermic/Helpers.h>

#include <gamekeeper/core/curlfiledownloader.h>
#ifdef GAMEKEEPER_OS_IS_WINDOWS
  #include <gamekeeper/core/windowsinformation.h>
  #define OSINFORMATIONCLASS WindowsInformation
#else
  #include <gamekeeper/core/linuxinformation.h>
  #define OSINFORMATIONCLASS LinuxInformation
#endif
#include <gamekeeper/core/log4cpploggerFactory.h>
#include <gamekeeper/core/xdgpaths.h>

namespace po = boost::program_options;

GAMEKEEPER_NAMESPACE_START(client)

static std::shared_ptr<Hypodermic::IContainer> localContainer;
static std::shared_ptr<Hypodermic::IContainer> container;

GameKeeperRuntime::GameKeeperRuntime()
{
	using namespace gamekeeper::core;
	Hypodermic::ContainerBuilder containerBuilder;

	// set up IoC container
	containerBuilder.registerType<Log4cppLoggerFactory>()->
	        as<LoggerFactory>()->
	        singleInstance();
	localContainer = containerBuilder.build();
}

GameKeeperRuntime::~GameKeeperRuntime()
{
	delete this->gameKeeperUI;
}

gamekeeper::core::Logger&
GameKeeperRuntime::getUILogger()
{
	return localContainer->resolve<gamekeeper::core::LoggerFactory>()->getComponentLogger("UI.client");
}

static void
fillProperties(po::options_description & cmd, po::options_description & file)
{
	po::options_description descGlobalCmd("Global options");

	descGlobalCmd.add_options()
		("help,h", "produce help message");

	cmd.add(descGlobalCmd);
}

int
GameKeeperRuntime::main(int argc, const char* argv[], GameKeeperUI * gameKeeperUI)
{
	this->gameKeeperUI = gameKeeperUI;

	po::options_description descCmd;
	po::options_description descFile;

	fillProperties(descCmd, descFile);

	po::options_description cmdClient("Client options");
	po::options_description fileClient;
	po::options_description bothClient;
	po::options_description_easy_init cmdClientEasy = cmdClient.add_options();
	po::options_description_easy_init fileClientEasy = fileClient.add_options();
	po::options_description_easy_init bothClientEasy = bothClient.add_options();

	this->gameKeeperUI->addOptions(cmdClientEasy, fileClientEasy, bothClientEasy);

	if(!bothClient.options().empty())
	{
		cmdClient.add(bothClient);
		fileClient.add(bothClient);
	}

	if(!cmdClient.options().empty())
	{
		descCmd.add(cmdClient);
	}

	if(!fileClient.options().empty())
	{
		descFile.add(fileClient);
	}

	po::variables_map vm;
	po::store(po::parse_command_line(argc, argv, descCmd), vm);
	//po::store(po::parse_config_file("", descFile), vm);

	if(vm.count("help") > 0)
	{
		std::cout << descCmd << std::endl;
		return EXIT_SUCCESS;
	}

	po::notify(vm);

	Hypodermic::ContainerBuilder containerBuilder;
	{
		using namespace gamekeeper::core;

		// set up IoC container
		containerBuilder.registerInstance<LoggerFactory>(
			localContainer->resolve<gamekeeper::core::LoggerFactory>())->
			as<LoggerFactory>()->
			singleInstance();
		containerBuilder.registerType<OSINFORMATIONCLASS>()->
		        as<OSInformation>()->
		        singleInstance();
		containerBuilder.registerType<XDGPaths>(CREATE(new XDGPaths(INJECT(OSInformation))))->
		        as<OSPaths>()->
		        singleInstance();
		containerBuilder.registerType<CurlFileDownloader>(CREATE(new CurlFileDownloader(INJECT(LoggerFactory))))->
		        as<FileDownloader>()->
		        as<HttpFileDownloader>()->
		        singleInstance();
	}
	container = containerBuilder.build();

	std::shared_ptr<gamekeeper::core::LoggerFactory> loggerFactory = container->resolve<gamekeeper::core::LoggerFactory>();
	loggerFactory->getComponentLogger("main") << gamekeeper::core::LogLevel::Debug << "firing up GameKeeper" << gamekeeper::core::endl;

	this->gameKeeperUI->init(vm);
	this->gameKeeperUI->startEventLoop();
	this->gameKeeperUI->onShutdown();

	return EXIT_SUCCESS;
}

Hypodermic::IContainer&
HypodermicUtil::getContainer()
{
	return *container;
}

GAMEKEEPER_NAMESPACE_END(client)
<commit_msg>client/runtime: add PropertyResolver<commit_after>/*
 * GameKeeper Framework
 *
 * Copyright (C) 2013 Karol Herbst <gamekeeper@karolherbst.de>
 *
 * 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 "runtime.h"

#include <gamekeeper/core/common.h>

#include <cstdlib>

#include <gamekeeper/core/logger.h>
#include <gamekeeper/core/loggerStream.h>
#include <gamekeeper/client/gamekeeper.h>
#include <gamekeeper/client/hypodermic.h>

#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>

#include <Hypodermic/ContainerBuilder.h>
#include <Hypodermic/Helpers.h>

#include <gamekeeper/core/boostpopropertyresolver.h>
#include <gamekeeper/core/curlfiledownloader.h>
#ifdef GAMEKEEPER_OS_IS_WINDOWS
  #include <gamekeeper/core/windowsinformation.h>
  #define OSINFORMATIONCLASS WindowsInformation
#else
  #include <gamekeeper/core/linuxinformation.h>
  #define OSINFORMATIONCLASS LinuxInformation
#endif
#include <gamekeeper/core/log4cpploggerFactory.h>
#include <gamekeeper/core/xdgpaths.h>

namespace po = boost::program_options;

GAMEKEEPER_NAMESPACE_START(client)

static std::shared_ptr<Hypodermic::IContainer> localContainer;
static std::shared_ptr<Hypodermic::IContainer> container;

GameKeeperRuntime::GameKeeperRuntime()
{
	using namespace gamekeeper::core;
	Hypodermic::ContainerBuilder containerBuilder;

	// set up IoC container
	containerBuilder.registerType<Log4cppLoggerFactory>()->
	        as<LoggerFactory>()->
	        singleInstance();
	localContainer = containerBuilder.build();
}

GameKeeperRuntime::~GameKeeperRuntime()
{
	delete this->gameKeeperUI;
}

gamekeeper::core::Logger&
GameKeeperRuntime::getUILogger()
{
	return localContainer->resolve<gamekeeper::core::LoggerFactory>()->getComponentLogger("UI.client");
}

static void
fillProperties(po::options_description & cmd, po::options_description & file)
{
	po::options_description descGlobalCmd("Global options");

	descGlobalCmd.add_options()
		("help,h", "produce help message");

	cmd.add(descGlobalCmd);
}

int
GameKeeperRuntime::main(int argc, const char* argv[], GameKeeperUI * gameKeeperUI)
{
	this->gameKeeperUI = gameKeeperUI;

	po::options_description descCmd;
	po::options_description descFile;

	fillProperties(descCmd, descFile);

	po::options_description cmdClient("Client options");
	po::options_description fileClient;
	po::options_description bothClient;
	po::options_description_easy_init cmdClientEasy = cmdClient.add_options();
	po::options_description_easy_init fileClientEasy = fileClient.add_options();
	po::options_description_easy_init bothClientEasy = bothClient.add_options();

	this->gameKeeperUI->addOptions(cmdClientEasy, fileClientEasy, bothClientEasy);

	if(!bothClient.options().empty())
	{
		cmdClient.add(bothClient);
		fileClient.add(bothClient);
	}

	if(!cmdClient.options().empty())
	{
		descCmd.add(cmdClient);
	}

	if(!fileClient.options().empty())
	{
		descFile.add(fileClient);
	}

	po::variables_map vm;
	po::store(po::parse_command_line(argc, argv, descCmd), vm);
	//po::store(po::parse_config_file("", descFile), vm);

	if(vm.count("help") > 0)
	{
		std::cout << descCmd << std::endl;
		return EXIT_SUCCESS;
	}

	po::notify(vm);

	Hypodermic::ContainerBuilder containerBuilder;
	{
		using namespace gamekeeper::core;

		// set up IoC container
		containerBuilder.registerInstance<LoggerFactory>(
			localContainer->resolve<gamekeeper::core::LoggerFactory>())->
			as<LoggerFactory>()->
			singleInstance();
		containerBuilder.registerType<BoostPOPropertyResolver>(CREATE_CAPTURED([&vm], new BoostPOPropertyResolver(vm)))->
			as<PropertyResolver>()->
			singleInstance();
		containerBuilder.registerType<OSINFORMATIONCLASS>()->
		        as<OSInformation>()->
		        singleInstance();
		containerBuilder.registerType<XDGPaths>(CREATE(new XDGPaths(INJECT(OSInformation))))->
		        as<OSPaths>()->
		        singleInstance();
		containerBuilder.registerType<CurlFileDownloader>(CREATE(new CurlFileDownloader(INJECT(LoggerFactory))))->
		        as<FileDownloader>()->
		        as<HttpFileDownloader>()->
		        singleInstance();
	}
	container = containerBuilder.build();

	std::shared_ptr<gamekeeper::core::LoggerFactory> loggerFactory = container->resolve<gamekeeper::core::LoggerFactory>();
	loggerFactory->getComponentLogger("main") << gamekeeper::core::LogLevel::Debug << "firing up GameKeeper" << gamekeeper::core::endl;

	this->gameKeeperUI->init(vm);
	this->gameKeeperUI->startEventLoop();
	this->gameKeeperUI->onShutdown();

	return EXIT_SUCCESS;
}

Hypodermic::IContainer&
HypodermicUtil::getContainer()
{
	return *container;
}

GAMEKEEPER_NAMESPACE_END(client)
<|endoftext|>


<commit_before>/**
 * @file logging.cpp
 * @brief Logging class
 *
 * (c) 2013-2014 by Mega Limited, Auckland, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK 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.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 *
 * This file is also distributed under the terms of the GNU General
 * Public License, see http://www.gnu.org/copyleft/gpl.txt for details.
 */

#if defined(WINDOWS_PHONE) && !defined(__STDC_LIMIT_MACROS)
#define __STDC_LIMIT_MACROS
#endif

#include "mega/logging.h"

#include <ctime>

#if defined(WINDOWS_PHONE)
#include <stdint.h>
#endif

namespace mega {

Logger *SimpleLogger::logger = nullptr;

// by the default, display logs with level equal or less than logInfo
enum LogLevel SimpleLogger::logCurrentLevel = logInfo;
long long SimpleLogger::maxPayloadLogSize  = 10240;

#ifdef ENABLE_LOG_PERFORMANCE

#ifdef WIN32
thread_local std::array<char, LOGGER_CHUNKS_SIZE> SimpleLogger::mBuffer;
#else
__thread std::array<char, LOGGER_CHUNKS_SIZE> SimpleLogger::mBuffer;
#endif

#else
// static member initialization
std::mutex SimpleLogger::outputs_mutex;
OutputMap SimpleLogger::outputs;

std::string SimpleLogger::getTime()
{
    char ts[50];
    time_t t = std::time(NULL);
    struct tm tp;

    if (gmtime_r(&t, &tp) && std::strftime(ts, sizeof(ts), "%H:%M:%S", &tp)) return ts;

    return {};
}

void SimpleLogger::flush()
{
    for (auto& o : outputs)
    {
        OutputStreams::iterator iter;
        OutputStreams vec;

        {
            std::lock_guard<std::mutex> guard(outputs_mutex);
            vec = o;
        }

        for (iter = vec.begin(); iter != vec.end(); iter++)
        {
            std::ostream *os = *iter;
            os->flush();
        }
    }
}

OutputStreams SimpleLogger::getOutput(enum LogLevel ll)
{
    assert(unsigned(ll) < outputs.size());
    std::lock_guard<std::mutex> guard(outputs_mutex);
    return outputs[ll];
}

void SimpleLogger::addOutput(enum LogLevel ll, std::ostream *os)
{
    assert(unsigned(ll) < outputs.size());
    std::lock_guard<std::mutex> guard(outputs_mutex);
    outputs[ll].push_back(os);
}

void SimpleLogger::setAllOutputs(std::ostream *os)
{
    std::lock_guard<std::mutex> guard(outputs_mutex);
    for (auto& o : outputs)
    {
        o.push_back(os);
    }
}
#endif

} // namespace
<commit_msg>use gmtime_s on win<commit_after>/**
 * @file logging.cpp
 * @brief Logging class
 *
 * (c) 2013-2014 by Mega Limited, Auckland, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK 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.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 *
 * This file is also distributed under the terms of the GNU General
 * Public License, see http://www.gnu.org/copyleft/gpl.txt for details.
 */

#if defined(WINDOWS_PHONE) && !defined(__STDC_LIMIT_MACROS)
#define __STDC_LIMIT_MACROS
#endif

#include "mega/logging.h"

#include <ctime>

#if defined(WINDOWS_PHONE)
#include <stdint.h>
#endif

namespace mega {

Logger *SimpleLogger::logger = nullptr;

// by the default, display logs with level equal or less than logInfo
enum LogLevel SimpleLogger::logCurrentLevel = logInfo;
long long SimpleLogger::maxPayloadLogSize  = 10240;

#ifdef ENABLE_LOG_PERFORMANCE

#ifdef WIN32
thread_local std::array<char, LOGGER_CHUNKS_SIZE> SimpleLogger::mBuffer;
#else
__thread std::array<char, LOGGER_CHUNKS_SIZE> SimpleLogger::mBuffer;
#endif

#else
// static member initialization
std::mutex SimpleLogger::outputs_mutex;
OutputMap SimpleLogger::outputs;

std::string SimpleLogger::getTime()
{
    char ts[50];
    time_t t = std::time(NULL);
    std::tm tm{};

#ifdef WIN32
    gmtime_s(&tm, &t);
#else
    gmtime_r(&t, &tm);
#endif

    if (std::strftime(ts, sizeof(ts), "%H:%M:%S", &tm)) return ts;

    return {};
}

void SimpleLogger::flush()
{
    for (auto& o : outputs)
    {
        OutputStreams::iterator iter;
        OutputStreams vec;

        {
            std::lock_guard<std::mutex> guard(outputs_mutex);
            vec = o;
        }

        for (iter = vec.begin(); iter != vec.end(); iter++)
        {
            std::ostream *os = *iter;
            os->flush();
        }
    }
}

OutputStreams SimpleLogger::getOutput(enum LogLevel ll)
{
    assert(unsigned(ll) < outputs.size());
    std::lock_guard<std::mutex> guard(outputs_mutex);
    return outputs[ll];
}

void SimpleLogger::addOutput(enum LogLevel ll, std::ostream *os)
{
    assert(unsigned(ll) < outputs.size());
    std::lock_guard<std::mutex> guard(outputs_mutex);
    outputs[ll].push_back(os);
}

void SimpleLogger::setAllOutputs(std::ostream *os)
{
    std::lock_guard<std::mutex> guard(outputs_mutex);
    for (auto& o : outputs)
    {
        o.push_back(os);
    }
}
#endif

} // namespace
<|endoftext|>


<commit_before>/*
 * Copyright © 2010 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include <cstdio>
#include "glsl_symbol_table.h"
#include "ast.h"
#include "glsl_types.h"
#include "ir.h"

static ir_instruction *
match_function_by_name(exec_list *instructions, const char *name,
		       YYLTYPE *loc, simple_node *parameters,
		       struct _mesa_glsl_parse_state *state)
{
   ir_function *f = state->symbols->get_function(name);

   if (f == NULL) {
      _mesa_glsl_error(loc, state, "function `%s' undeclared", name);
      return ir_call::get_error_instruction();
   }

   /* Once we've determined that the function being called might exist,
    * process the parameters.
    */
   exec_list actual_parameters;
   simple_node *const first = parameters;
   if (first != NULL) {
      simple_node *ptr = first;
      do {
	 ir_instruction *const result =
	    ((ast_node *) ptr)->hir(instructions, state);
	 ptr = ptr->next;

	 actual_parameters.push_tail(result);
      } while (ptr != first);
   }

   /* After processing the function's actual parameters, try to find an
    * overload of the function that matches.
    */
   const ir_function_signature *sig =
      f->matching_signature(& actual_parameters);
   if (sig != NULL) {
      /* FINISHME: The list of actual parameters needs to be modified to
       * FINISHME: include any necessary conversions.
       */
      return new ir_call(sig, & actual_parameters);
   } else {
      /* FINISHME: Log a better error message here.  G++ will show the types
       * FINISHME: of the actual parameters and the set of candidate
       * FINISHME: functions.  A different error should also be logged when
       * FINISHME: multiple functions match.
       */
      _mesa_glsl_error(loc, state, "no matching function for call to `%s'",
		       name);
      return ir_call::get_error_instruction();
   }
}

ir_instruction *
ast_function_expression::hir(exec_list *instructions,
			     struct _mesa_glsl_parse_state *state)
{
   /* There are three sorts of function calls.
    *
    * 1. contstructors - The first subexpression is an ast_type_specifier.
    * 2. methods - Only the .length() method of array types.
    * 3. functions - Calls to regular old functions.
    *
    * There are two kinds of constructor call.  Constructors for built-in
    * language types, such as mat4 and vec2, are free form.  The only
    * requirement is that the parameters must provide enough values of the
    * correct scalar type.  Constructors for arrays and structures must have
    * the exact number of parameters with matching types in the correct order.
    * These constructors follow essentially the same type matching rules as
    * functions.
    *
    * Method calls are actually detected when the ast_field_selection
    * expression is handled.
    */
   if (is_constructor()) {
      return ir_call::get_error_instruction();
   } else {
      const ast_expression *id = subexpressions[0];
      YYLTYPE loc = id->get_location();

      return match_function_by_name(instructions,
				    id->primary_expression.identifier, & loc,
				    subexpressions[1], state);
   }

   return ir_call::get_error_instruction();
}
<commit_msg>Begin processing constructors<commit_after>/*
 * Copyright © 2010 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include <cstdio>
#include "glsl_symbol_table.h"
#include "ast.h"
#include "glsl_types.h"
#include "ir.h"

static ir_instruction *
match_function_by_name(exec_list *instructions, const char *name,
		       YYLTYPE *loc, simple_node *parameters,
		       struct _mesa_glsl_parse_state *state)
{
   ir_function *f = state->symbols->get_function(name);

   if (f == NULL) {
      _mesa_glsl_error(loc, state, "function `%s' undeclared", name);
      return ir_call::get_error_instruction();
   }

   /* Once we've determined that the function being called might exist,
    * process the parameters.
    */
   exec_list actual_parameters;
   simple_node *const first = parameters;
   if (first != NULL) {
      simple_node *ptr = first;
      do {
	 ir_instruction *const result =
	    ((ast_node *) ptr)->hir(instructions, state);
	 ptr = ptr->next;

	 actual_parameters.push_tail(result);
      } while (ptr != first);
   }

   /* After processing the function's actual parameters, try to find an
    * overload of the function that matches.
    */
   const ir_function_signature *sig =
      f->matching_signature(& actual_parameters);
   if (sig != NULL) {
      /* FINISHME: The list of actual parameters needs to be modified to
       * FINISHME: include any necessary conversions.
       */
      return new ir_call(sig, & actual_parameters);
   } else {
      /* FINISHME: Log a better error message here.  G++ will show the types
       * FINISHME: of the actual parameters and the set of candidate
       * FINISHME: functions.  A different error should also be logged when
       * FINISHME: multiple functions match.
       */
      _mesa_glsl_error(loc, state, "no matching function for call to `%s'",
		       name);
      return ir_call::get_error_instruction();
   }
}

ir_instruction *
ast_function_expression::hir(exec_list *instructions,
			     struct _mesa_glsl_parse_state *state)
{
   /* There are three sorts of function calls.
    *
    * 1. contstructors - The first subexpression is an ast_type_specifier.
    * 2. methods - Only the .length() method of array types.
    * 3. functions - Calls to regular old functions.
    *
    * Method calls are actually detected when the ast_field_selection
    * expression is handled.
    */
   if (is_constructor()) {
      const ast_type_specifier *type = (ast_type_specifier *) subexpressions[0];
      YYLTYPE loc = type->get_location();

      const glsl_type *const constructor_type =
	 state->symbols->get_type(type->type_name);

      /* Constructors for samplers are illegal.
       */
      if (constructor_type->is_sampler()) {
	 _mesa_glsl_error(& loc, state, "cannot construct sampler type `%s'",
			  constructor_type->name);
	 return ir_call::get_error_instruction();
      }

      /* There are two kinds of constructor call.  Constructors for built-in
       * language types, such as mat4 and vec2, are free form.  The only
       * requirement is that the parameters must provide enough values of the
       * correct scalar type.  Constructors for arrays and structures must
       * have the exact number of parameters with matching types in the
       * correct order.  These constructors follow essentially the same type
       * matching rules as functions.
       */

      return ir_call::get_error_instruction();
   } else {
      const ast_expression *id = subexpressions[0];
      YYLTYPE loc = id->get_location();

      return match_function_by_name(instructions,
				    id->primary_expression.identifier, & loc,
				    subexpressions[1], state);
   }

   return ir_call::get_error_instruction();
}
<|endoftext|>


<commit_before>// NOTE/NUANCE: When including WITHIN a library, no sub-dir prefix is needed.
#include "uber-library-example.h"

// Constructor
UberLibraryExample::Pin::Pin(int _number)
{
  number = _number;
  state = LOW;
}

// Initializers that should be called in the `setup()` function
void UberLibraryExample::Pin::beginInPinMode(PinMode _pinMode)
{
  pinMode(number, _pinMode);
}

// Main API functions that the library provides
// typically called in `loop()` or `setup()` functions
void UberLibraryExample::Pin::modulateAtFrequency(int _ms)
{
  setHigh();
  delay(_ms);
  setLow();
  delay(_ms);
}

// Getters
int UberLibraryExample::Pin::getNumber()
{
  return number;
}
bool UberLibraryExample::Pin::getState()
{
  return state;
}
bool UberLibraryExample::Pin::getMode()
{
  return mode;
}
bool UberLibraryExample::Pin::isHigh()
{
  return state == HIGH ? true : false;
}

// Setters
void UberLibraryExample::Pin::setHigh()
{
  state = HIGH;
  setActualPinState();
}
void UberLibraryExample::Pin::setLow()
{
  state = LOW;
  setActualPinState();
}
void UberLibraryExample::Pin::setActualPinState()
{
  digitalWrite(number, state);
}
<commit_msg>Delete uber-library-example.cpp<commit_after><|endoftext|>


<commit_before><?hh
/*
include('b/blackhole.hh');
include('p/log.hh');

require('p/header.hh');
require('p/forms.hh');
require('p/footer.hh');

require('p/aws.hh');
require('p/aws_constants.hh');
*/

function get_num_links(): string{
	$dyclient = mk_aws()->get('DynamoDb');

	$result = $dyclient->describeTable(
		array(
			'TableName' => aws_config::LINK_TABLE));
	return $result['Table']['ItemCount'];
}

function is_meta(): string{
	if(
	( isset($_SERVER['HTTP_REFERER']) && preg_match("/(https?:\/\/)?(cdn\.)?jump\.wtf(\/.*)?/", $_SERVER['HTTP_REFERER']))
	||
	( isset($_ENV['HTTP_REFERER']) && preg_match("/(https?:\/\/)?(cdn\.)?jump\.wtf(\/.*)?/", $_ENV['HTTP_REFERER']))
	) return "This is so meta.";
	else return "";
}

function i_main(): void{

echo gen_html_tag();
echo gen_head();

$body = ;
$body->appendChild(gen_nav());
$body->appendChild(

Link Shortening / File Hosting Service

			An experiment with AWS resources.

			By submitting a link or file, you are agreeing to this site's Terms of Service and Privacy Policy.

			A total of {get_num_links()} links have been generated.

			{is_meta()}

);

$body->appendChild(gen_form());

$body->appendChild(gen_footer());
foreach( gen_footer_scripts() as $script )
	$body->appendChild($script);

echo $body;

echo "";
}

//i_main();
<commit_msg>Another type error<commit_after><?hh
/*
include('b/blackhole.hh');
include('p/log.hh');

require('p/header.hh');
require('p/forms.hh');
require('p/footer.hh');

require('p/aws.hh');
require('p/aws_constants.hh');
*/

function get_num_links(): string{
	$dyclient = mk_aws()->get('DynamoDb');

	$result = $dyclient->describeTable(
		array(
			'TableName' => aws_config::LINK_TABLE));
	return (string) $result['Table']['ItemCount'];
}

function is_meta(): string{
	if(
	( isset($_SERVER['HTTP_REFERER']) && preg_match("/(https?:\/\/)?(cdn\.)?jump\.wtf(\/.*)?/", $_SERVER['HTTP_REFERER']))
	||
	( isset($_ENV['HTTP_REFERER']) && preg_match("/(https?:\/\/)?(cdn\.)?jump\.wtf(\/.*)?/", $_ENV['HTTP_REFERER']))
	) return "This is so meta.";
	else return "";
}

function i_main(): void{

echo gen_html_tag();
echo gen_head();

$body = ;
$body->appendChild(gen_nav());
$body->appendChild(

Link Shortening / File Hosting Service

			An experiment with AWS resources.

			By submitting a link or file, you are agreeing to this site's Terms of Service and Privacy Policy.

			A total of {get_num_links()} links have been generated.

			{is_meta()}

);

$body->appendChild(gen_form());

$body->appendChild(gen_footer());
foreach( gen_footer_scripts() as $script )
	$body->appendChild($script);

echo $body;

echo "";
}

//i_main();
<|endoftext|>


<commit_before>/* Copyright (C) 2005-2008, Thorvald Natvig <thorvald@natvig.com>
   Copyright (C) 2007, Sebastian Schlingmann <mit_service@users.sourceforge.net>

   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 Mumble Developers 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 FOUNDATION 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.
*/

/* need the undef or else the include would not work
 it would help to include the header before QT, but that might mess with QT */
#undef qDebug
#include "ApplicationServices/ApplicationServices.h"

#undef check
#include "Global.h"
#include "TextToSpeech.h"

static QMutex qmLock;
static Fixed fVolume;
static QList<QByteArray> qlMessages;
static bool bRunning;
static bool bEnabled;

static void process_speech();

static void speech_done_cb(SpeechChannel scChannel, long, void **, unsigned long *, long *) {
	DisposeSpeechChannel(scChannel);

	if (qlMessages.isEmpty())
		bRunning = false;
	else
		process_speech();
}

static void process_speech() {
	SpeechChannel scChannel;
	QByteArray ba;

	qmLock.lock();
	ba = qlMessages.takeFirst();
	qmLock.unlock();

	NewSpeechChannel(NULL, &scChannel);
	SetSpeechInfo(scChannel, soVolume, &fVolume);
	SetSpeechInfo(scChannel, soSpeechDoneCallBack, reinterpret_cast<void *>(speech_done_cb));
	SpeakText(scChannel, ba.constData(), ba.size());
}

TextToSpeech::TextToSpeech(QObject *) {
	bEnabled = true;
}

TextToSpeech::~TextToSpeech() {
}

void TextToSpeech::say(const QString &text) {
	if (!bEnabled)
		return;

	QTextCodec *codec = QTextCodec::codecForName("Apple Roman");
	Q_ASSERT(codec != NULL);

	qmLock.lock();
	qlMessages.append(codec->fromUnicode(text));
	qmLock.unlock();

	if (!bRunning) {
		process_speech();
		bRunning = true;
	}
}

void TextToSpeech::setEnabled(bool e) {
	bEnabled = e;
}

void TextToSpeech::setVolume(int volume) {
	fVolume = FixRatio(volume, 100);
}

bool TextToSpeech::isEnabled() const {
	return bEnabled;
}
<commit_msg>TextToSpeechMac: Fix the parameters for our SpeechDone callback. I confused it with another function. This doesn't change any code, as we were only using the first parameter anyway.<commit_after>/* Copyright (C) 2005-2008, Thorvald Natvig <thorvald@natvig.com>
   Copyright (C) 2007, Sebastian Schlingmann <mit_service@users.sourceforge.net>

   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 Mumble Developers 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 FOUNDATION 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.
*/

/* need the undef or else the include would not work
 it would help to include the header before QT, but that might mess with QT */
#undef qDebug
#include "ApplicationServices/ApplicationServices.h"

#undef check
#include "Global.h"
#include "TextToSpeech.h"

static QMutex qmLock;
static Fixed fVolume;
static QList<QByteArray> qlMessages;
static bool bRunning;
static bool bEnabled;

static void process_speech();

static void speech_done_cb(SpeechChannel scChannel, long) {
	DisposeSpeechChannel(scChannel);

	if (qlMessages.isEmpty())
		bRunning = false;
	else
		process_speech();
}

static void process_speech() {
	SpeechChannel scChannel;
	QByteArray ba;

	qmLock.lock();
	ba = qlMessages.takeFirst();
	qmLock.unlock();

	NewSpeechChannel(NULL, &scChannel);
	SetSpeechInfo(scChannel, soVolume, &fVolume);
	SetSpeechInfo(scChannel, soSpeechDoneCallBack, reinterpret_cast<void *>(speech_done_cb));
	SpeakText(scChannel, ba.constData(), ba.size());
}

TextToSpeech::TextToSpeech(QObject *) {
	bEnabled = true;
}

TextToSpeech::~TextToSpeech() {
}

void TextToSpeech::say(const QString &text) {
	if (!bEnabled)
		return;

	QTextCodec *codec = QTextCodec::codecForName("Apple Roman");
	Q_ASSERT(codec != NULL);

	qmLock.lock();
	qlMessages.append(codec->fromUnicode(text));
	qmLock.unlock();

	if (!bRunning) {
		process_speech();
		bRunning = true;
	}
}

void TextToSpeech::setEnabled(bool e) {
	bEnabled = e;
}

void TextToSpeech::setVolume(int volume) {
	fVolume = FixRatio(volume, 100);
}

bool TextToSpeech::isEnabled() const {
	return bEnabled;
}
<|endoftext|>


<commit_before>#include "Halide.h"
#include <stdio.h>
#include "clock.h"

using namespace Halide;

// 32-bit windows defines powf as a macro, which won't work for us.
#ifdef WIN32
extern "C" __declspec(dllexport) float pow_ref(float x, float y) {
    return pow(x, y);
}
#else
extern "C" float pow_ref(float x, float y) {
    return powf(x, y);
}
#endif

HalideExtern_2(float, pow_ref, float, float);

int main(int argc, char **argv) {
    Func f, g, h;
    Var x, y;

    f(x, y) = pow_ref((x+1)/512.0f, (y+1)/512.0f);
    g(x, y) = pow((x+1)/512.0f, (y+1)/512.0f);
    h(x, y) = fast_pow((x+1)/512.0f, (y+1)/512.0f);
    f.vectorize(x, 8);
    g.vectorize(x, 8);
    h.vectorize(x, 8);

    f.compile_jit();
    g.compile_jit();
    h.compile_jit();

    Image<float> correct_result(2048, 768);
    Image<float> fast_result(2048, 768);
    Image<float> faster_result(2048, 768);

    const int iterations = 20;

    double t1 = current_time();
    for (int i = 0; i < iterations; i++) {
        f.realize(correct_result);
    }
    double t2 = current_time();
    for (int i = 0; i < iterations; i++) {
        g.realize(fast_result);
    }
    double t3 = current_time();
    for (int i = 0; i < iterations; i++) {
        h.realize(faster_result);
    }
    double t4 = current_time();

    RDom r(correct_result);
    Func fast_error, faster_error;
    Expr fast_delta = correct_result(r.x, r.y) - fast_result(r.x, r.y);
    Expr faster_delta = correct_result(r.x, r.y) - faster_result(r.x, r.y);
    fast_error() += cast<double>(fast_delta * fast_delta);
    faster_error() += cast<double>(faster_delta * faster_delta);

    Image<double> fast_err = fast_error.realize();
    Image<double> faster_err = faster_error.realize();

    int N = correct_result.width() * correct_result.height() * iterations;
    fast_err(0) = sqrt(fast_err(0)/N);
    faster_err(0) = sqrt(faster_err(0)/N);

    printf("powf: %f ns per pixel\n"
           "Halide's pow: %f ns per pixel (rms error = %0.10f)\n"
           "Halide's fast_pow: %f ns per pixel (rms error = %0.10f)\n",
           1000000*(t2-t1) / N,
           1000000*(t3-t2) / N, fast_err(0),
           1000000*(t4-t3) / N, faster_err(0));

    if (fast_err(0) > 0.000001) {
        printf("Error for pow too large\n");
        return -1;
    }

    if (faster_err(0) > 0.0001) {
        printf("Error for fast_pow too large\n");
        return -1;
    }

    if (t2-t1 < t3-t2) {
        printf("powf is faster than Halide's pow\n");
        return -1;
    }

    if (t3-t2 < t4-t3) {
        printf("pow is faster than fast_pow\n");
        return -1;
    }

    printf("Success!\n");

    return 0;
}
<commit_msg>Made fast_pow timing test more reliable<commit_after>#include "Halide.h"
#include <stdio.h>
#include "clock.h"

using namespace Halide;

// 32-bit windows defines powf as a macro, which won't work for us.
#ifdef WIN32
extern "C" __declspec(dllexport) float pow_ref(float x, float y) {
    return pow(x, y);
}
#else
extern "C" float pow_ref(float x, float y) {
    return powf(x, y);
}
#endif

HalideExtern_2(float, pow_ref, float, float);

int main(int argc, char **argv) {
    Func f, g, h;
    Var x, y;

    f(x, y) = pow_ref((x+1)/512.0f, (y+1)/512.0f);
    g(x, y) = pow((x+1)/512.0f, (y+1)/512.0f);
    h(x, y) = fast_pow((x+1)/512.0f, (y+1)/512.0f);
    f.vectorize(x, 8);
    g.vectorize(x, 8);
    h.vectorize(x, 8);

    Image<float> correct_result(2048, 768);
    Image<float> fast_result(2048, 768);
    Image<float> faster_result(2048, 768);

    f.realize(correct_result);
    g.realize(fast_result);
    h.realize(faster_result);

    const int trials = 5;
    const int iterations = 5;

    double t1 = 1e10;
    double t2 = 1e10;
    double t3 = 1e10;

    // All profiling runs are done into the same buffer, to avoid
    // cache weirdness.
    Image<float> timing_scratch(400, 400);
    for (int i = 0; i < trials; i++) {
        double start = current_time();
        for (int j = 0; j < iterations; j++) {
            f.realize(timing_scratch);
        }
        double end = current_time();
        t1 = std::min(end - start, t1);

        start = current_time();
        for (int j = 0; j < iterations; j++) {
            g.realize(timing_scratch);
        }
        end = current_time();
        t2 = std::min(end - start, t2);

        start = current_time();
        for (int j = 0; j < iterations; j++) {
            h.realize(timing_scratch);
        }
        end = current_time();
        t3 = std::min(end - start, t3);
    }

    RDom r(correct_result);
    Func fast_error, faster_error;
    Expr fast_delta = correct_result(r.x, r.y) - fast_result(r.x, r.y);
    Expr faster_delta = correct_result(r.x, r.y) - faster_result(r.x, r.y);
    fast_error() += cast<double>(fast_delta * fast_delta);
    faster_error() += cast<double>(faster_delta * faster_delta);

    Image<double> fast_err = fast_error.realize();
    Image<double> faster_err = faster_error.realize();

    int timing_N = timing_scratch.width() * timing_scratch.height() * iterations;
    int correctness_N = fast_result.width() * fast_result.height() * iterations;
    fast_err(0) = sqrt(fast_err(0)/correctness_N);
    faster_err(0) = sqrt(faster_err(0)/correctness_N);

    printf("powf: %f ns per pixel\n"
           "Halide's pow: %f ns per pixel (rms error = %0.10f)\n"
           "Halide's fast_pow: %f ns per pixel (rms error = %0.10f)\n",
           1000000*t1 / timing_N,
           1000000*t2 / timing_N, fast_err(0),
           1000000*t3 / timing_N, faster_err(0));

    if (fast_err(0) > 0.000001) {
        printf("Error for pow too large\n");
        return -1;
    }

    if (faster_err(0) > 0.0001) {
        printf("Error for fast_pow too large\n");
        return -1;
    }

    if (t1 < t2) {
        printf("powf is faster than Halide's pow\n");
        return -1;
    }

    if (t2 < t3) {
        printf("pow is faster than fast_pow\n");
        return -1;
    }

    printf("Success!\n");

    return 0;
}
<|endoftext|>


<commit_before>
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <cmath>
#include <cassert>
#include <iomanip>
#include <cstdio>
#include <utility>
#include <algorithm>
#include <ios>
#include <limits>

#include <stdint.h>

#include <vector>
#include <string>
#include <cstring>
#include <list>
#include <map>
#include <set>
//#include <unordered_map>

using namespace std;

//One Dimension

void print_vector_of_ints(const string& message, const vector<int>& vector_of_ints);
void print_vector_of_chars(const string& message, const vector<char>& vector_of_chars);
void print_vector_of_strings(const string& message, const vector<string>& vector_of_strings);
void print_vector_of_floats(const string& message, const vector<float>& vector_of_floats);
void print_vector_of_doubles(const string& message, const vector<double>& vector_of_doubles);

void print_list_of_ints(const string& message, const list<int>& list_of_ints);
void print_list_of_chars(const string& message, const list<char>& list_of_chars);
void print_list_of_strings(const string& message, const list<string>& list_of_strings);
void print_list_of_floats(const string& message, const list<float>& list_of_floats);
void print_list_of_doubles(const string& message, const list<double>& list_of_doubles);

void print_set_of_ints(const string& message, const set<int>& set_of_ints);
void print_set_of_chars(const string& message, const set<char>& set_of_chars);
void print_set_of_strings(const string& message, const set<string> &set_of_strings);
void print_set_of_floats(const string& message, const set<float>& set_of_floats);
void print_set_of_doubles(const string& message, const set<double>& set_of_doubles);

//Two Dimensions

void print_vector_of_vectors_of_strings(const string& message, const vector<vector<string> >& vector_of_vectors_of_strings);

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

	vector<int> vector_of_ints;
	vector<char> vector_of_chars;
	vector<string> vector_of_strings;
	vector<float> vector_of_floats;
	vector<double> vector_of_doubles;

	list<int> list_of_ints;
	list<char> list_of_chars;
	list<string> list_of_strings;
	list<float> list_of_floats;
	list<double> list_of_doubles;

	set<int> set_of_ints;
	set<char> set_of_chars;
	set<string> set_of_strings;
	set<float> set_of_floats;
	set<double> set_of_doubles;

	vector_of_ints = {1, 2, 3};
	print_vector_of_ints("vertor of ints initialized by {}", vector_of_ints);

	vector_of_strings = {"cat", "meow", "kitty"};
	print_vector_of_strings("vertor of ints initialized by {}", vector_of_strings);

	vector_of_doubles = {1.0, 2.0, 3.0};
	print_vector_of_doubles("vertor of ints initialized by {}", vector_of_doubles);

	vector_of_floats = {12.0, 22.0, 32.0};
	print_vector_of_floats("vertor of ints initialized by {}", vector_of_floats);

	list_of_ints.push_back(2);
	list_of_ints.push_back(3);
	list_of_ints.push_back(4);
	list_of_ints.push_back(5);
	print_list_of_ints("testing function", list_of_ints);

	list_of_chars.push_back('a');
	list_of_chars.push_back('b');
	list_of_chars.push_back('c');
	list_of_chars.push_back('d');
	print_list_of_chars("testing function", list_of_chars);

	list_of_strings.push_back("hi");
	list_of_strings.push_back("there");
	list_of_strings.push_back("cout");
	list_of_strings.push_back("statement");
	print_list_of_strings("testing function", list_of_strings);

	list_of_floats.push_back(1.0);
	list_of_floats.push_back(2.0);
	list_of_floats.push_back(3.0);
	list_of_floats.push_back(4.0);
	print_list_of_floats("testing function", list_of_floats);

	list_of_doubles.push_back(11.0);
	list_of_doubles.push_back(21.0);
	list_of_doubles.push_back(31.0);
	list_of_doubles.push_back(41.0);
	print_list_of_doubles("testing function", list_of_doubles);

	//print_vector_of_ints("vector initialized given number and filler", vector_of_ints);

	return 0;
}

//=================================VECTORS===============================================

void print_vector_of_ints(const string& message, const vector<int>& vector_of_ints){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	for(unsigned int v = 0; v < vector_of_ints.size() -1; v++){
		cout << vector_of_ints[v] << ", ";
	}
	cout << vector_of_ints[vector_of_ints.size()-1] << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

void print_vector_of_chars(const string& message, const vector<char>& vector_of_chars){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	for(unsigned int v = 0; v < vector_of_chars.size() -1; v++){
		cout << vector_of_chars[v] << ", ";
	}
	cout << vector_of_chars[vector_of_chars.size()-1] << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

void print_vector_of_strings(const string& message, const vector<string>& vector_of_strings){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	for(unsigned int v = 0; v < vector_of_strings.size() -1; v++){
		cout << vector_of_strings[v] << ", ";
	}
	cout << vector_of_strings[vector_of_strings.size()-1] << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

void print_vector_of_floats(const string& message, const vector<float>& vector_of_floats){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	for(unsigned int v = 0; v < vector_of_floats.size() -1; v++){
		cout << vector_of_floats[v] << ", ";
	}
	cout << vector_of_floats[vector_of_floats.size()-1] << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

void print_vector_of_doubles(const string& message, const vector<double>& vector_of_doubles){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	for(unsigned int v = 0; v < vector_of_doubles.size() -1; v++){
		cout << vector_of_doubles[v] << ", ";
	}
	cout << vector_of_doubles[vector_of_doubles.size()-1] << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

//=================================LISTS================================================

void print_list_of_ints(const string& message, const list<int>& list_of_ints){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	list<int>::const_iterator last_item_itr = list_of_ints.end();
	last_item_itr--;
	for(list<int>::const_iterator l = list_of_ints.begin(); l != last_item_itr; l++){
		cout << *l << ", ";
	}
	cout << *last_item_itr << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

void print_list_of_chars(const string& message, const list<char>& list_of_chars){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	list<char>::const_iterator last_item_itr = list_of_chars.end();
	last_item_itr--;
	for(list<char>::const_iterator l = list_of_chars.begin(); l != last_item_itr; l++){
		cout << *l << ", ";
	}
	cout << *last_item_itr << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

void print_list_of_strings(const string& message, const list<string>& list_of_strings){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	list<string>::const_iterator last_item_itr = list_of_strings.end();
	last_item_itr--;
	for(list<string>::const_iterator l = list_of_strings.begin(); l != last_item_itr; l++){
		cout << *l << ", ";
	}
	cout << *last_item_itr << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

void print_list_of_floats(const string& message, const list<float>& list_of_floats){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	list<float>::const_iterator last_item_itr = list_of_floats.end();
	last_item_itr--;
	for(list<float>::const_iterator l = list_of_floats.begin(); l != last_item_itr; l++){
		cout << *l << ", ";
	}
	cout << *last_item_itr << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

void print_list_of_doubles(const string& message, const list<double>& list_of_doubles){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	list<double>::const_iterator last_item_itr = list_of_doubles.end();
	last_item_itr--;
	for(list<double>::const_iterator l = list_of_doubles.begin(); l != last_item_itr; l++){
		cout << *l << ", ";
	}
	cout << *last_item_itr << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

//==================================SETS================================================

void print_set_of_ints(const string& message, const set<int>& set_of_ints){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	set<int>::const_iterator last_item_itr = set_of_ints.end();
	last_item_itr--;
	for(set<int>::const_iterator l = set_of_ints.begin(); l != last_item_itr; l++){
		cout << *l << ", ";
	}
	cout << *last_item_itr << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

void print_set_of_chars(const string& message, const set<char>& set_of_chars){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	set<char>::const_iterator last_item_itr = set_of_chars.end();
	last_item_itr--;
	for(set<char>::const_iterator l = set_of_chars.begin(); l != last_item_itr; l++){
		cout << *l << ", ";
	}
	cout << *last_item_itr << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

void print_set_of_strings(const string& message, const set<string>& set_of_strings){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	set<string>::const_iterator last_item_itr = set_of_strings.end();
	last_item_itr--;
	for(set<string>::const_iterator l = set_of_strings.begin(); l != last_item_itr; l++){
		cout << *l << ", ";
	}
	cout << *last_item_itr << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

//=================================VECTORS OF VECTORS===================================

void print_vector_of_vectors_of_strings(const string& message, const vector<vector<string> >& vector_of_vectors_of_strings){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl;

	//find maximum length row (maximum number of colunms)
	unsigned int maximum_length_row = 0;
	for(unsigned int r = 0; r < vector_of_vectors_of_strings.size(); r++){
		if(vector_of_vectors_of_strings[r].size() > maximum_length_row){
			maximum_length_row = vector_of_vectors_of_strings[r].size();
		}
	}

	//find the largest string in each column to use as the column width for that column
	vector<unsigned int> maximum_length_per_col(maximum_length_row, 0);
	for(unsigned int r = 0; r < vector_of_vectors_of_strings.size(); r++){
		for(unsigned int c = 0; c < vector_of_vectors_of_strings[r].size(); c++){
			if(vector_of_vectors_of_strings[r][c].size() > maximum_length_per_col[c]){
				maximum_length_per_col[c] = vector_of_vectors_of_strings[r][c].size();
			}
		}
	}

	//print things according to column widths (left alligned and 1 extra spaces for padding between colums)
	//TODO: change from right aligned to left aligned.  Try std::left, but if not, 2 prints where padding is (length you want - length you have) before regular print
	//TODO: also, change the way you are printing to not put an etxra space even at the edges (like before with the "last one" that you did in list/set/1D vector)
	for(unsigned int r = 0; r < vector_of_vectors_of_strings.size(); r++){
		for(unsigned int c = 0; c < vector_of_vectors_of_strings[r].size(); c++){
			std::cout << std::setfill (' ') << std::setw (maximum_length_per_col[c] + 1);
  			std::cout << vector_of_vectors_of_strings[r][c] << std::endl;
		}
	}

	cout << "-----------------------------------------------------------------" << endl;
}<commit_msg>vector of vector of strings print is working -> tested<commit_after>
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <cmath>
#include <cassert>
#include <iomanip>
#include <cstdio>
#include <utility>
#include <algorithm>
#include <ios>
#include <limits>

#include <stdint.h>

#include <vector>
#include <string>
#include <cstring>
#include <list>
#include <map>
#include <set>
//#include <unordered_map>

using namespace std;

//One Dimension

void print_vector_of_ints(const string& message, const vector<int>& vector_of_ints);
void print_vector_of_chars(const string& message, const vector<char>& vector_of_chars);
void print_vector_of_strings(const string& message, const vector<string>& vector_of_strings);
void print_vector_of_floats(const string& message, const vector<float>& vector_of_floats);
void print_vector_of_doubles(const string& message, const vector<double>& vector_of_doubles);

void print_list_of_ints(const string& message, const list<int>& list_of_ints);
void print_list_of_chars(const string& message, const list<char>& list_of_chars);
void print_list_of_strings(const string& message, const list<string>& list_of_strings);
void print_list_of_floats(const string& message, const list<float>& list_of_floats);
void print_list_of_doubles(const string& message, const list<double>& list_of_doubles);

void print_set_of_ints(const string& message, const set<int>& set_of_ints);
void print_set_of_chars(const string& message, const set<char>& set_of_chars);
void print_set_of_strings(const string& message, const set<string> &set_of_strings);
void print_set_of_floats(const string& message, const set<float>& set_of_floats);
void print_set_of_doubles(const string& message, const set<double>& set_of_doubles);

//Two Dimensions

void print_vector_of_vectors_of_strings(const string& message, const vector<vector<string> >& vector_of_vectors_of_strings);

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

	vector<int> vector_of_ints;
	vector<char> vector_of_chars;
	vector<string> vector_of_strings;
	vector<float> vector_of_floats;
	vector<double> vector_of_doubles;

	list<int> list_of_ints;
	list<char> list_of_chars;
	list<string> list_of_strings;
	list<float> list_of_floats;
	list<double> list_of_doubles;

	set<int> set_of_ints;
	set<char> set_of_chars;
	set<string> set_of_strings;
	set<float> set_of_floats;
	set<double> set_of_doubles;

	vector_of_ints = {1, 2, 3};
	print_vector_of_ints("vertor of ints initialized by {}", vector_of_ints);

	vector_of_strings = {"cat", "meow", "kitty"};
	print_vector_of_strings("vertor of ints initialized by {}", vector_of_strings);

	vector_of_doubles = {1.0, 2.0, 3.0};
	print_vector_of_doubles("vertor of ints initialized by {}", vector_of_doubles);

	vector_of_floats = {12.0, 22.0, 32.0};
	print_vector_of_floats("vertor of ints initialized by {}", vector_of_floats);

	list_of_ints.push_back(2);
	list_of_ints.push_back(3);
	list_of_ints.push_back(4);
	list_of_ints.push_back(5);
	print_list_of_ints("testing function", list_of_ints);

	list_of_chars.push_back('a');
	list_of_chars.push_back('b');
	list_of_chars.push_back('c');
	list_of_chars.push_back('d');
	print_list_of_chars("testing function", list_of_chars);

	list_of_strings.push_back("hi");
	list_of_strings.push_back("there");
	list_of_strings.push_back("cout");
	list_of_strings.push_back("statement");
	print_list_of_strings("testing function", list_of_strings);

	list_of_floats.push_back(1.0);
	list_of_floats.push_back(2.0);
	list_of_floats.push_back(3.0);
	list_of_floats.push_back(4.0);
	print_list_of_floats("testing function", list_of_floats);

	list_of_doubles.push_back(11.0);
	list_of_doubles.push_back(21.0);
	list_of_doubles.push_back(31.0);
	list_of_doubles.push_back(41.0);
	print_list_of_doubles("testing function", list_of_doubles);

	vector<vector<string> > vector_of_vectors_of_strings;
	vector<string> vec1 = {"cat", "dog", "puppy", "buscuit"};
	vector<string> vec2 = {"one", "two", "three", "four", "five", "six"};
	vector<string> vec3 = {"oh", "hai", "thar"};
	vector<string> vec4 = {"do", "you", "want", "to", "build", "a", "snowman?"};
	vector_of_vectors_of_strings.push_back(vec1);
	vector_of_vectors_of_strings.push_back(vec2);
	vector_of_vectors_of_strings.push_back(vec3);
	vector_of_vectors_of_strings.push_back(vec4);

	print_vector_of_vectors_of_strings("testing vector of vector of strings", vector_of_vectors_of_strings);

	//print_vector_of_ints("vector initialized given number and filler", vector_of_ints);

	return 0;
}

//=================================VECTORS===============================================

void print_vector_of_ints(const string& message, const vector<int>& vector_of_ints){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	for(unsigned int v = 0; v < vector_of_ints.size() -1; v++){
		cout << vector_of_ints[v] << ", ";
	}
	cout << vector_of_ints[vector_of_ints.size()-1] << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

void print_vector_of_chars(const string& message, const vector<char>& vector_of_chars){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	for(unsigned int v = 0; v < vector_of_chars.size() -1; v++){
		cout << vector_of_chars[v] << ", ";
	}
	cout << vector_of_chars[vector_of_chars.size()-1] << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

void print_vector_of_strings(const string& message, const vector<string>& vector_of_strings){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	for(unsigned int v = 0; v < vector_of_strings.size() -1; v++){
		cout << vector_of_strings[v] << ", ";
	}
	cout << vector_of_strings[vector_of_strings.size()-1] << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

void print_vector_of_floats(const string& message, const vector<float>& vector_of_floats){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	for(unsigned int v = 0; v < vector_of_floats.size() -1; v++){
		cout << vector_of_floats[v] << ", ";
	}
	cout << vector_of_floats[vector_of_floats.size()-1] << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

void print_vector_of_doubles(const string& message, const vector<double>& vector_of_doubles){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	for(unsigned int v = 0; v < vector_of_doubles.size() -1; v++){
		cout << vector_of_doubles[v] << ", ";
	}
	cout << vector_of_doubles[vector_of_doubles.size()-1] << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

//=================================LISTS================================================

void print_list_of_ints(const string& message, const list<int>& list_of_ints){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	list<int>::const_iterator last_item_itr = list_of_ints.end();
	last_item_itr--;
	for(list<int>::const_iterator l = list_of_ints.begin(); l != last_item_itr; l++){
		cout << *l << ", ";
	}
	cout << *last_item_itr << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

void print_list_of_chars(const string& message, const list<char>& list_of_chars){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	list<char>::const_iterator last_item_itr = list_of_chars.end();
	last_item_itr--;
	for(list<char>::const_iterator l = list_of_chars.begin(); l != last_item_itr; l++){
		cout << *l << ", ";
	}
	cout << *last_item_itr << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

void print_list_of_strings(const string& message, const list<string>& list_of_strings){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	list<string>::const_iterator last_item_itr = list_of_strings.end();
	last_item_itr--;
	for(list<string>::const_iterator l = list_of_strings.begin(); l != last_item_itr; l++){
		cout << *l << ", ";
	}
	cout << *last_item_itr << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

void print_list_of_floats(const string& message, const list<float>& list_of_floats){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	list<float>::const_iterator last_item_itr = list_of_floats.end();
	last_item_itr--;
	for(list<float>::const_iterator l = list_of_floats.begin(); l != last_item_itr; l++){
		cout << *l << ", ";
	}
	cout << *last_item_itr << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

void print_list_of_doubles(const string& message, const list<double>& list_of_doubles){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	list<double>::const_iterator last_item_itr = list_of_doubles.end();
	last_item_itr--;
	for(list<double>::const_iterator l = list_of_doubles.begin(); l != last_item_itr; l++){
		cout << *l << ", ";
	}
	cout << *last_item_itr << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

//==================================SETS================================================

void print_set_of_ints(const string& message, const set<int>& set_of_ints){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	set<int>::const_iterator last_item_itr = set_of_ints.end();
	last_item_itr--;
	for(set<int>::const_iterator l = set_of_ints.begin(); l != last_item_itr; l++){
		cout << *l << ", ";
	}
	cout << *last_item_itr << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

void print_set_of_chars(const string& message, const set<char>& set_of_chars){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	set<char>::const_iterator last_item_itr = set_of_chars.end();
	last_item_itr--;
	for(set<char>::const_iterator l = set_of_chars.begin(); l != last_item_itr; l++){
		cout << *l << ", ";
	}
	cout << *last_item_itr << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

void print_set_of_strings(const string& message, const set<string>& set_of_strings){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl << "[";
	set<string>::const_iterator last_item_itr = set_of_strings.end();
	last_item_itr--;
	for(set<string>::const_iterator l = set_of_strings.begin(); l != last_item_itr; l++){
		cout << *l << ", ";
	}
	cout << *last_item_itr << "]" << endl;
	cout << "-----------------------------------------------------------------" << endl;
}

//=================================VECTORS OF VECTORS===================================

void print_vector_of_vectors_of_strings(const string& message, const vector<vector<string> >& vector_of_vectors_of_strings){
	cout << "-----------------------------------------------------------------" << endl;
	cout << message << endl;

	//find maximum length row (maximum number of colunms)
	unsigned int maximum_length_row = 0;
	for(unsigned int r = 0; r < vector_of_vectors_of_strings.size(); r++){
		if(vector_of_vectors_of_strings[r].size() > maximum_length_row){
			maximum_length_row = vector_of_vectors_of_strings[r].size();
		}
	}

	//find the largest string in each column to use as the column width for that column
	vector<unsigned int> maximum_length_per_col(maximum_length_row, 0);
	for(unsigned int r = 0; r < vector_of_vectors_of_strings.size(); r++){
		for(unsigned int c = 0; c < vector_of_vectors_of_strings[r].size(); c++){
			if(vector_of_vectors_of_strings[r][c].size() > maximum_length_per_col[c]){
				maximum_length_per_col[c] = vector_of_vectors_of_strings[r][c].size();
			}
		}
	}

	//print things according to column widths (left alligned and 1 extra spaces for padding between colums)
	//TODO: change from right aligned to left aligned.  Try std::left, but if not, 2 prints where padding is (length you want - length you have) before regular print
	//TODO: also, change the way you are printing to not put an etxra space even at the edges (like before with the "last one" that you did in list/set/1D vector)
	for(unsigned int r = 0; r < vector_of_vectors_of_strings.size(); r++){
		for(unsigned int c = 0; c < vector_of_vectors_of_strings[r].size(); c++){
			std::cout << std::left << std::setw (maximum_length_per_col[c] + 1) << std::setfill (' ') << vector_of_vectors_of_strings[r][c];
		}
		std::cout << std::endl;
	}

	cout << "-----------------------------------------------------------------" << endl;
}<|endoftext|>


<commit_before>/**************************************************************************
 *
 * Copyright 2013-2014 RAD Game Tools and Valve Software
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 **************************************************************************/

// File: vogl_trace.cpp
#include "vogl_trace.h"
#include "vogl_command_line_params.h"
#include "vogl_colorized_console.h"
#include <signal.h>

#include "vogl_port.h"

#if VOGL_PLATFORM_SUPPORTS_BTRACE
    #include "btrace.h"
#endif

#if defined(PLATFORM_LINUX)
    #include <execinfo.h>
    #include <linux/unistd.h>
#endif

#if defined(COMPILER_MSVC)
	// As long as we include windows.h, we will get different dll linkage for this. However, we will "win" in here
	// so we get the results we are looking for.
	#pragma warning( disable : 4273 )
#endif

//----------------------------------------------------------------------------------------------------------------------
// Has exception hooks, dlopen() interception, super low-level global init.  Be super careful what you
//  do in some of these funcs (particularly vogl_shared_object_constructor_func() or any of the funcs
//  it calls).  I've found it's possible to do shit here that will work fine in primitive apps (like
//  vogltest) but kill tracing in some real apps.
//----------------------------------------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------------------------------------
// globals
//----------------------------------------------------------------------------------------------------------------------
void *g_vogl_actual_libgl_module_handle = NULL;
bool g_vogl_initializing_flag = false;

//----------------------------------------------------------------------------------------------------------------------
// dlopen interceptor
//----------------------------------------------------------------------------------------------------------------------
#if defined(PLATFORM_LINUX)

// Console initialization.
bool vogl_console_init(bool doinit);

typedef void *(*dlopen_func_ptr_t)(const char *pFile, int mode);
VOGL_API_EXPORT void *dlopen(const char *pFile, int mode)
{
    static dlopen_func_ptr_t s_pActual_dlopen = (dlopen_func_ptr_t)dlsym(RTLD_NEXT, "dlopen");
    if (!s_pActual_dlopen)
        return NULL;

    // Check to see if the vogl_console has been initialized. Only use the vogl console APIs if so.
    bool ret = vogl_console_init(false);
    if (ret)
    {
        vogl_verbose_printf("dlopen: %s %i\n", pFile ? pFile : "(nullptr)", mode);
    }

    // Only redirect libGL.so when it comes from the app, NOT the driver or one of its associated helpers.
    // This is definitely fragile as all fuck.
    if (!g_vogl_initializing_flag)
    {
        if (pFile && (strstr(pFile, "libGL.so") != NULL))
        {
            const char *calling_module = btrace_get_calling_module();
            bool should_redirect = !strstr(calling_module, "fglrx");

            if (should_redirect)
            {
                pFile = btrace_get_current_module();
                if (ret)
                {
                    vogl_verbose_printf("redirecting dlopen to %s\n", pFile);
                    vogl_verbose_printf("------------\n");
                }
            }
            else if (ret)
            {
                vogl_verbose_printf("NOT redirecting dlopen to %s, this dlopen() call appears to be coming from the driver\n", pFile);
                vogl_verbose_printf("------------\n");
            }
        }
    }

    // Check if this module is already loaded.
    void *is_loaded = (*s_pActual_dlopen)(pFile, RTLD_NOLOAD);
    // Call the real dlopen().
    void *dlopen_ret = (*s_pActual_dlopen)(pFile, mode);

    // Only call btrace routines after vogl has been initialized. Otherwise we get
    //  called before memory routines have been set up, etc. and possibly crash.
    if (g_vogl_has_been_initialized)
    {
        // If this file hadn't been loaded before, notify btrace.
        if (!is_loaded && dlopen_ret)
            btrace_dlopen_notify(pFile);
    }

    return dlopen_ret;
}

//----------------------------------------------------------------------------------------------------------------------
// Intercept _exit() so we get a final chance to flush our trace/log files
//----------------------------------------------------------------------------------------------------------------------
typedef void (*exit_func_ptr_t)(int status);
VOGL_API_EXPORT VOGL_NORETURN void _exit(int status)
{
    static exit_func_ptr_t s_pActual_exit = (exit_func_ptr_t)dlsym(RTLD_NEXT, "_exit");

    vogl_deinit();

    if (s_pActual_exit)
        (*s_pActual_exit)(status);

    raise(SIGKILL);

    // to shut up compiler about this func marked as noreturn
    for (;;)
        ;
}

//----------------------------------------------------------------------------------------------------------------------
// Intercept _exit() so we get a final chance to flush our trace/log files
//----------------------------------------------------------------------------------------------------------------------
typedef void (*Exit_func_ptr_t)(int status);
VOGL_API_EXPORT VOGL_NORETURN void _Exit(int status)
{
    static Exit_func_ptr_t s_pActual_Exit = (Exit_func_ptr_t)dlsym(RTLD_NEXT, "_Exit");

    vogl_deinit();

    if (s_pActual_Exit)
        (*s_pActual_Exit)(status);

    raise(SIGKILL);

    // to shut up compiler about this func marked as noreturn
    for (;;)
        ;
}

#endif // defined(PLATFORM_LINUX)

//----------------------------------------------------------------------------------------------------------------------
// vogl_glInternalTraceCommandRAD_dummy_func
//----------------------------------------------------------------------------------------------------------------------
static void vogl_glInternalTraceCommandRAD_dummy_func(GLuint cmd, GLuint size, const GLubyte *data)
{
    // Nothing to do, this is an internal command used for serialization purposes that only we understand.
    VOGL_NOTE_UNUSED(cmd);
    VOGL_NOTE_UNUSED(size);
    VOGL_NOTE_UNUSED(data);
}

//----------------------------------------------------------------------------------------------------------------------
// vogl_get_proc_address_helper_return_actual
//----------------------------------------------------------------------------------------------------------------------
vogl_void_func_ptr_t vogl_get_proc_address_helper_return_actual(const char *pName)
{
    if (!strcmp(pName, "glInternalTraceCommandRAD"))
        return reinterpret_cast<vogl_void_func_ptr_t>(vogl_glInternalTraceCommandRAD_dummy_func);

    vogl_void_func_ptr_t pFunc = reinterpret_cast<vogl_void_func_ptr_t>(plat_dlsym(g_vogl_actual_libgl_module_handle ? g_vogl_actual_libgl_module_handle : PLAT_RTLD_NEXT, pName));

    #if (VOGL_PLATFORM_HAS_GLX)
        if ((!pFunc) && (g_vogl_actual_gl_entrypoints.m_glXGetProcAddress))
            pFunc = reinterpret_cast<vogl_void_func_ptr_t>(g_vogl_actual_gl_entrypoints.m_glXGetProcAddress(reinterpret_cast<const GLubyte *>(pName)));
    #elif (VOGL_PLATFORM_HAS_WGL)
        if ((!pFunc) && (g_vogl_actual_gl_entrypoints.m_wglGetProcAddress))
            pFunc = reinterpret_cast<vogl_void_func_ptr_t>(g_vogl_actual_gl_entrypoints.m_wglGetProcAddress(pName));
    #else
        #error "impl get_proc_address functions in g_vogl_actual_gl_entrypoints for this platform"
    #endif

    return pFunc;
}

//----------------------------------------------------------------------------------------------------------------------
// global constructor init
// Note: Be VERY careful what you do in here! It's called very early during init (long before main, during c++ init)
//----------------------------------------------------------------------------------------------------------------------
#if defined(PLATFORM_LINUX)

#include "vogl_file_utils.h"

    VOGL_CONSTRUCTOR_FUNCTION(vogl_shared_object_constructor_func);
    static void vogl_shared_object_constructor_func()
    {
        // We really don't want to be hooking terminals running shell scripts to launch the games, and it
        //  only causes problems when we do wind up in those processes.
        // So check if we're one of the fairly well known shells and bail if so.
        static const char *s_notrace[] =
        {
            "bash", "dash", "sh", "tcsh", "xterm", "zsh", "zsh5",
            "cgdb", "gdb", "strace", "desktop-launcher", "glxinfo", "kmod",
            "python", "python2.7", "python3", "python3.4",
            "dpkg-query", "grep", "egrep", "head", "free", "lsusb", "uname",
            "minidump_stackwalk"
        };

        char exec_filename[PATH_MAX];
        vogl::file_utils::get_exec_filename(exec_filename, sizeof(exec_filename));

        const char *fname = strrchr(exec_filename, '/');
        fname = fname ? (fname + 1) : exec_filename;

        for (size_t i = 0; i < sizeof(s_notrace) / sizeof(s_notrace[0]); i++)
        {
            if (vogl::vogl_strncasecmp(fname, s_notrace[i], sizeof(exec_filename)) == 0)
                return;
        }

        vogl_init();
    }

    __attribute__((destructor)) static void vogl_shared_object_destructor_func()
    {
        if (vogl_is_capturing())
        {
            // This shouldn't ever happen hopefully. Ie, our atexit() handler or exit() hooks should call vogl_deinit()
            //  well before this destructor is called.
            vogl_warning_printf_once("ERROR: Called with open trace file. Somehow vogl_deinit() hasn't been called?");

            // Try to do vogl_deinit().
            vogl_deinit();
        }
    }

#elif defined(PLATFORM_WINDOWS)

    BOOL WINAPI DllMain(_In_  HINSTANCE hinstDLL, _In_  DWORD fdwReason, _In_  LPVOID lpvReserved)
    {
        switch (fdwReason)
        {
            case DLL_PROCESS_ATTACH:
                vogl_init();
                break;
            case DLL_PROCESS_DETACH:
                vogl_deinit();
                break;

            case DLL_THREAD_ATTACH:
            case DLL_THREAD_DETACH:
                // Nothing to do for this case.
                break;

            default:
                VOGL_ASSERT(!"Unexpected fdwReason passed to DllMain.");
                break;
        };

        return TRUE;
    }

    VOGL_API_EXPORT void VOGL_API_CALLCONV GlmfBeginGlsBlock(DWORD _d1) { }
    VOGL_API_EXPORT void VOGL_API_CALLCONV GlmfCloseMetaFile(DWORD _d1) { }
    VOGL_API_EXPORT void VOGL_API_CALLCONV GlmfEndGlsBlock(DWORD _d1) { }
    VOGL_API_EXPORT void VOGL_API_CALLCONV GlmfEndPlayback(DWORD _d1) { }
    VOGL_API_EXPORT void VOGL_API_CALLCONV GlmfInitPlayback(DWORD _d1, DWORD _d2, DWORD _d3) { }
    VOGL_API_EXPORT void VOGL_API_CALLCONV GlmfPlayGlsRecord(DWORD _d1, DWORD _d2, DWORD _d3, DWORD _d4) { }
    VOGL_API_EXPORT void VOGL_API_CALLCONV glDebugEntry(DWORD _d1, DWORD _d2) { }
    VOGL_API_EXPORT DWORD VOGL_API_CALLCONV wglSwapMultipleBuffers(UINT, CONST WGLSWAP *) { return 0; }
    VOGL_API_EXPORT BOOL VOGL_API_CALLCONV wglUseFontOutlinesA(HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf) { return FALSE; }
    VOGL_API_EXPORT BOOL VOGL_API_CALLCONV wglUseFontOutlinesW(HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf) { return FALSE; }

#else

    #error "Need a way to call vogl_init and vogl_deinit for this platform."

#endif
<commit_msg>Add check for mesa libGL to no-redirect block.<commit_after>/**************************************************************************
 *
 * Copyright 2013-2014 RAD Game Tools and Valve Software
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 **************************************************************************/

// File: vogl_trace.cpp
#include "vogl_trace.h"
#include "vogl_command_line_params.h"
#include "vogl_colorized_console.h"
#include <signal.h>

#include "vogl_port.h"

#if VOGL_PLATFORM_SUPPORTS_BTRACE
    #include "btrace.h"
#endif

#if defined(PLATFORM_LINUX)
    #include <execinfo.h>
    #include <linux/unistd.h>
#endif

#if defined(COMPILER_MSVC)
	// As long as we include windows.h, we will get different dll linkage for this. However, we will "win" in here
	// so we get the results we are looking for.
	#pragma warning( disable : 4273 )
#endif

//----------------------------------------------------------------------------------------------------------------------
// Has exception hooks, dlopen() interception, super low-level global init.  Be super careful what you
//  do in some of these funcs (particularly vogl_shared_object_constructor_func() or any of the funcs
//  it calls).  I've found it's possible to do shit here that will work fine in primitive apps (like
//  vogltest) but kill tracing in some real apps.
//----------------------------------------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------------------------------------
// globals
//----------------------------------------------------------------------------------------------------------------------
void *g_vogl_actual_libgl_module_handle = NULL;
bool g_vogl_initializing_flag = false;

//----------------------------------------------------------------------------------------------------------------------
// dlopen interceptor
//----------------------------------------------------------------------------------------------------------------------
#if defined(PLATFORM_LINUX)

// Console initialization.
bool vogl_console_init(bool doinit);

typedef void *(*dlopen_func_ptr_t)(const char *pFile, int mode);
VOGL_API_EXPORT void *dlopen(const char *pFile, int mode)
{
    static dlopen_func_ptr_t s_pActual_dlopen = (dlopen_func_ptr_t)dlsym(RTLD_NEXT, "dlopen");
    if (!s_pActual_dlopen)
        return NULL;

    // Check to see if the vogl_console has been initialized. Only use the vogl console APIs if so.
    bool ret = vogl_console_init(false);
    if (ret)
    {
        vogl_verbose_printf("dlopen: %s %i\n", pFile ? pFile : "(nullptr)", mode);
    }

    // Only redirect libGL.so when it comes from the app, NOT the driver or one of its associated helpers.
    // This is definitely fragile as all fuck.
    if (!g_vogl_initializing_flag)
    {
        if (pFile && (strstr(pFile, "libGL.so") != NULL))
        {
            // When the AMD or Intel driver tries to dlopen libGL.so, we need to return the real libGL.so handle.
            const char *calling_module = btrace_get_calling_module();
            bool should_redirect = !strstr(calling_module, "fglrx") &&
                    !strstr(calling_module, "mesa/lib/libGL.so.1");

            if (should_redirect)
            {
                pFile = btrace_get_current_module();
            }

            if (ret)
            {
                vogl_verbose_printf("%sRedirecting dlopen to: %s.\n", (should_redirect ? "" : " NOT"), pFile);
                vogl_verbose_printf("  Calling module: %s.\n", calling_module);
            }
        }
    }

    // Check if this module is already loaded.
    void *is_loaded = (*s_pActual_dlopen)(pFile, RTLD_NOLOAD);
    // Call the real dlopen().
    void *dlopen_ret = (*s_pActual_dlopen)(pFile, mode);

    // Only call btrace routines after vogl has been initialized. Otherwise we get
    //  called before memory routines have been set up, etc. and possibly crash.
    if (g_vogl_has_been_initialized)
    {
        // If this file hadn't been loaded before, notify btrace.
        if (!is_loaded && dlopen_ret)
            btrace_dlopen_notify(pFile);
    }

    return dlopen_ret;
}

//----------------------------------------------------------------------------------------------------------------------
// Intercept _exit() so we get a final chance to flush our trace/log files
//----------------------------------------------------------------------------------------------------------------------
typedef void (*exit_func_ptr_t)(int status);
VOGL_API_EXPORT VOGL_NORETURN void _exit(int status)
{
    static exit_func_ptr_t s_pActual_exit = (exit_func_ptr_t)dlsym(RTLD_NEXT, "_exit");

    vogl_deinit();

    if (s_pActual_exit)
        (*s_pActual_exit)(status);

    raise(SIGKILL);

    // to shut up compiler about this func marked as noreturn
    for (;;)
        ;
}

//----------------------------------------------------------------------------------------------------------------------
// Intercept _exit() so we get a final chance to flush our trace/log files
//----------------------------------------------------------------------------------------------------------------------
typedef void (*Exit_func_ptr_t)(int status);
VOGL_API_EXPORT VOGL_NORETURN void _Exit(int status)
{
    static Exit_func_ptr_t s_pActual_Exit = (Exit_func_ptr_t)dlsym(RTLD_NEXT, "_Exit");

    vogl_deinit();

    if (s_pActual_Exit)
        (*s_pActual_Exit)(status);

    raise(SIGKILL);

    // to shut up compiler about this func marked as noreturn
    for (;;)
        ;
}

#endif // defined(PLATFORM_LINUX)

//----------------------------------------------------------------------------------------------------------------------
// vogl_glInternalTraceCommandRAD_dummy_func
//----------------------------------------------------------------------------------------------------------------------
static void vogl_glInternalTraceCommandRAD_dummy_func(GLuint cmd, GLuint size, const GLubyte *data)
{
    // Nothing to do, this is an internal command used for serialization purposes that only we understand.
    VOGL_NOTE_UNUSED(cmd);
    VOGL_NOTE_UNUSED(size);
    VOGL_NOTE_UNUSED(data);
}

//----------------------------------------------------------------------------------------------------------------------
// vogl_get_proc_address_helper_return_actual
//----------------------------------------------------------------------------------------------------------------------
vogl_void_func_ptr_t vogl_get_proc_address_helper_return_actual(const char *pName)
{
    if (!strcmp(pName, "glInternalTraceCommandRAD"))
        return reinterpret_cast<vogl_void_func_ptr_t>(vogl_glInternalTraceCommandRAD_dummy_func);

    vogl_void_func_ptr_t pFunc = reinterpret_cast<vogl_void_func_ptr_t>(plat_dlsym(g_vogl_actual_libgl_module_handle ? g_vogl_actual_libgl_module_handle : PLAT_RTLD_NEXT, pName));

    #if (VOGL_PLATFORM_HAS_GLX)
        if ((!pFunc) && (g_vogl_actual_gl_entrypoints.m_glXGetProcAddress))
            pFunc = reinterpret_cast<vogl_void_func_ptr_t>(g_vogl_actual_gl_entrypoints.m_glXGetProcAddress(reinterpret_cast<const GLubyte *>(pName)));
    #elif (VOGL_PLATFORM_HAS_WGL)
        if ((!pFunc) && (g_vogl_actual_gl_entrypoints.m_wglGetProcAddress))
            pFunc = reinterpret_cast<vogl_void_func_ptr_t>(g_vogl_actual_gl_entrypoints.m_wglGetProcAddress(pName));
    #else
        #error "impl get_proc_address functions in g_vogl_actual_gl_entrypoints for this platform"
    #endif

    return pFunc;
}

//----------------------------------------------------------------------------------------------------------------------
// global constructor init
// Note: Be VERY careful what you do in here! It's called very early during init (long before main, during c++ init)
//----------------------------------------------------------------------------------------------------------------------
#if defined(PLATFORM_LINUX)

#include "vogl_file_utils.h"

    VOGL_CONSTRUCTOR_FUNCTION(vogl_shared_object_constructor_func);
    static void vogl_shared_object_constructor_func()
    {
        // We really don't want to be hooking terminals running shell scripts to launch the games, and it
        //  only causes problems when we do wind up in those processes.
        // So check if we're one of the fairly well known shells and bail if so.
        static const char *s_notrace[] =
        {
            "bash", "dash", "sh", "tcsh", "xterm", "zsh", "zsh5",
            "cgdb", "gdb", "strace", "desktop-launcher", "glxinfo", "kmod",
            "python", "python2.7", "python3", "python3.4",
            "dpkg-query", "grep", "egrep", "head", "free", "lsusb", "uname",
            "minidump_stackwalk"
        };

        char exec_filename[PATH_MAX];
        vogl::file_utils::get_exec_filename(exec_filename, sizeof(exec_filename));

        const char *fname = strrchr(exec_filename, '/');
        fname = fname ? (fname + 1) : exec_filename;

        for (size_t i = 0; i < sizeof(s_notrace) / sizeof(s_notrace[0]); i++)
        {
            if (vogl::vogl_strncasecmp(fname, s_notrace[i], sizeof(exec_filename)) == 0)
                return;
        }

        vogl_init();
    }

    __attribute__((destructor)) static void vogl_shared_object_destructor_func()
    {
        if (vogl_is_capturing())
        {
            // This shouldn't ever happen hopefully. Ie, our atexit() handler or exit() hooks should call vogl_deinit()
            //  well before this destructor is called.
            vogl_warning_printf_once("ERROR: Called with open trace file. Somehow vogl_deinit() hasn't been called?");

            // Try to do vogl_deinit().
            vogl_deinit();
        }
    }

#elif defined(PLATFORM_WINDOWS)

    BOOL WINAPI DllMain(_In_  HINSTANCE hinstDLL, _In_  DWORD fdwReason, _In_  LPVOID lpvReserved)
    {
        switch (fdwReason)
        {
            case DLL_PROCESS_ATTACH:
                vogl_init();
                break;
            case DLL_PROCESS_DETACH:
                vogl_deinit();
                break;

            case DLL_THREAD_ATTACH:
            case DLL_THREAD_DETACH:
                // Nothing to do for this case.
                break;

            default:
                VOGL_ASSERT(!"Unexpected fdwReason passed to DllMain.");
                break;
        };

        return TRUE;
    }

    VOGL_API_EXPORT void VOGL_API_CALLCONV GlmfBeginGlsBlock(DWORD _d1) { }
    VOGL_API_EXPORT void VOGL_API_CALLCONV GlmfCloseMetaFile(DWORD _d1) { }
    VOGL_API_EXPORT void VOGL_API_CALLCONV GlmfEndGlsBlock(DWORD _d1) { }
    VOGL_API_EXPORT void VOGL_API_CALLCONV GlmfEndPlayback(DWORD _d1) { }
    VOGL_API_EXPORT void VOGL_API_CALLCONV GlmfInitPlayback(DWORD _d1, DWORD _d2, DWORD _d3) { }
    VOGL_API_EXPORT void VOGL_API_CALLCONV GlmfPlayGlsRecord(DWORD _d1, DWORD _d2, DWORD _d3, DWORD _d4) { }
    VOGL_API_EXPORT void VOGL_API_CALLCONV glDebugEntry(DWORD _d1, DWORD _d2) { }
    VOGL_API_EXPORT DWORD VOGL_API_CALLCONV wglSwapMultipleBuffers(UINT, CONST WGLSWAP *) { return 0; }
    VOGL_API_EXPORT BOOL VOGL_API_CALLCONV wglUseFontOutlinesA(HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf) { return FALSE; }
    VOGL_API_EXPORT BOOL VOGL_API_CALLCONV wglUseFontOutlinesW(HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf) { return FALSE; }

#else

    #error "Need a way to call vogl_init and vogl_deinit for this platform."

#endif
<|endoftext|>


<commit_before><commit_msg>Fixing scaling problems with karts<commit_after><|endoftext|>