<commit_before>// Copyright 2016-2017 Francesco Biscani (bluescarni@gmail.com)
//
// This file is part of the mp++ library.
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <algorithm>
#include <fstream>
#include <iostream>
#include <mp++/mp++.hpp>
#include <random>
#include <string>
#include <tuple>
#include <vector>

#include "simple_timer.hpp"

#if defined(MPPP_BENCHMARK_BOOST)
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/gmp.hpp>
#include <gmp.h>
#endif

#if defined(MPPP_BENCHMARK_FLINT)
#include <flint/flint.h>
#include <flint/fmpzxx.h>
#endif

using namespace mppp;
using namespace mppp_bench;

#if defined(MPPP_BENCHMARK_BOOST)
using cpp_int = boost::multiprecision::cpp_int;
using mpz_int = boost::multiprecision::mpz_int;
#endif

#if defined(MPPP_BENCHMARK_FLINT)
using fmpzxx = flint::fmpzxx;
#endif

static std::mt19937 rng;

using integer_t = integer<2>;
static const std::string name = "integer2_vec_mul_unsigned";

constexpr auto size = 30000000ul;

template <typename T>
static inline std::tuple<std::vector<T>, std::vector<T>, std::vector<T>> get_init_vectors(double &init_time)
{
    rng.seed(0);
    std::uniform_int_distribution<unsigned> dist(1u, 7u);
    simple_timer st;
    std::vector<T> v1(size), v2(size), v3(size);
    std::generate(v1.begin(), v1.end(), [&dist]() { return T(dist(rng)); });
    std::generate(v2.begin(), v2.end(), [&dist]() { return T(dist(rng)); });
    std::cout << "\nInit runtime: ";
    init_time = st.elapsed();
    return std::make_tuple(std::move(v1), std::move(v2), std::move(v3));
}

int main()
{
    // Warm up.
    for (auto volatile counter = 0ull; counter < 1000000000ull; ++counter) {
    }
    // Setup of the python output.
    std::string s = "# -*- coding: utf-8 -*-\n"
                    "def get_data():\n"
                    "    import pandas\n"
                    "    data = [";
    {
        std::cout << "\n\nBenchmarking mp++.";
        simple_timer st1;
        double init_time;
        auto p = get_init_vectors<integer_t>(init_time);
        s += "['mp++','init'," + std::to_string(init_time) + "],";
        {
            simple_timer st2;
            integer_t ret(0);
            for (auto i = 0ul; i < size; ++i) {
                mul(std::get<2>(p)[i], std::get<0>(p)[i], std::get<1>(p)[i]);
            }
            for (auto i = 0ul; i < size; ++i) {
                add(ret, ret, std::get<2>(p)[i]);
            }
            std::cout << ret << '\n';
            s += "['mp++','arithmetic'," + std::to_string(st2.elapsed()) + "],";
            std::cout << "\nArithmetic runtime: ";
        }
        s += "['mp++','total'," + std::to_string(st1.elapsed()) + "],";
        std::cout << "\nTotal runtime: ";
    }
#if defined(MPPP_BENCHMARK_BOOST)
    {
        std::cout << "\n\nBenchmarking cpp_int.";
        simple_timer st1;
        double init_time;
        auto p = get_init_vectors<cpp_int>(init_time);
        s += "['Boost (cpp_int)','init'," + std::to_string(init_time) + "],";
        {
            simple_timer st2;
            cpp_int ret(0);
            for (auto i = 0ul; i < size; ++i) {
                std::get<2>(p)[i] = std::get<0>(p)[i] * std::get<1>(p)[i];
            }
            for (auto i = 0ul; i < size; ++i) {
                ret += std::get<2>(p)[i];
            }
            std::cout << ret << '\n';
            s += "['Boost (cpp_int)','arithmetic'," + std::to_string(st2.elapsed()) + "],";
            std::cout << "\nArithmetic runtime: ";
        }
        s += "['Boost (cpp_int)','total'," + std::to_string(st1.elapsed()) + "],";
        std::cout << "\nTotal runtime: ";
    }
    {
        std::cout << "\n\nBenchmarking mpz_int.";
        simple_timer st1;
        double init_time;
        auto p = get_init_vectors<mpz_int>(init_time);
        s += "['Boost (mpz_int)','init'," + std::to_string(init_time) + "],";
        {
            simple_timer st2;
            mpz_int ret(0);
            for (auto i = 0ul; i < size; ++i) {
                ::mpz_mul(std::get<2>(p)[i].backend().data(), std::get<0>(p)[i].backend().data(),
                          std::get<1>(p)[i].backend().data());
            }
            for (auto i = 0ul; i < size; ++i) {
                ::mpz_add(ret.backend().data(), ret.backend().data(), std::get<2>(p)[i].backend().data());
            }
            std::cout << ret << '\n';
            s += "['Boost (mpz_int)','arithmetic'," + std::to_string(st2.elapsed()) + "],";
            std::cout << "\nArithmetic runtime: ";
        }
        s += "['Boost (mpz_int)','total'," + std::to_string(st1.elapsed()) + "],";
        std::cout << "\nTotal runtime: ";
    }
#endif
#if defined(MPPP_BENCHMARK_FLINT)
    {
        std::cout << "\n\nBenchmarking fmpzxx.";
        simple_timer st1;
        double init_time;
        auto p = get_init_vectors<fmpzxx>(init_time);
        s += "['FLINT','init'," + std::to_string(init_time) + "],";
        {
            simple_timer st2;
            fmpzxx ret(0);
            for (auto i = 0ul; i < size; ++i) {
                ::fmpz_mul(std::get<2>(p)[i]._data().inner, std::get<0>(p)[i]._data().inner,
                           std::get<1>(p)[i]._data().inner);
            }
            for (auto i = 0ul; i < size; ++i) {
                ::fmpz_add(ret._data().inner, ret._data().inner, std::get<2>(p)[i]._data().inner);
            }
            std::cout << ret << '\n';
            s += "['FLINT','arithmetic'," + std::to_string(st2.elapsed()) + "],";
            std::cout << "\nArithmetic runtime: ";
        }
        s += "['FLINT','total'," + std::to_string(st1.elapsed()) + "],";
        std::cout << "\nTotal runtime: ";
    }
#endif
    s += "]\n"
         "    retval = pandas.DataFrame(data)\n"
         "    retval.columns = ['Library','Task','Runtime (ms)']\n"
         "    return retval\n\n"
         "if __name__ == '__main__':\n"
         "    import matplotlib as mpl\n"
         "    mpl.use('Agg')\n"
         "    from matplotlib.pyplot import legend\n"
         "    import seaborn as sns\n"
         "    df = get_data()\n"
         "    g = sns.factorplot(x='Library', y = 'Runtime (ms)', hue='Task', data=df, kind='bar', palette='muted', "
         "legend = False, size = 5.5, aspect = 1.5)\n"
         "    legend(loc='upper right')\n"
         "    g.fig.suptitle('"
         + name + "')\n"
                  "    g.savefig('"
         + name + ".svg', bbox_inches='tight')\n";
    std::ofstream of(name + ".py", std::ios_base::trunc);
    of << s;
}
<commit_msg>WIP on a benchmark.<commit_after>// Copyright 2016-2017 Francesco Biscani (bluescarni@gmail.com)
//
// This file is part of the mp++ library.
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <algorithm>
#include <fstream>
#include <iostream>
#include <mp++/mp++.hpp>
#include <random>
#include <string>
#include <tuple>
#include <vector>

#include "simple_timer.hpp"

#if defined(MPPP_BENCHMARK_BOOST)
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/gmp.hpp>
#include <gmp.h>
#endif

#if defined(MPPP_BENCHMARK_FLINT)
#include <flint/flint.h>
#include <flint/fmpzxx.h>
#endif

using namespace mppp;
using namespace mppp_bench;

#if defined(MPPP_BENCHMARK_BOOST)
using cpp_int = boost::multiprecision::cpp_int;
using mpz_int = boost::multiprecision::mpz_int;
#endif

#if defined(MPPP_BENCHMARK_FLINT)
using fmpzxx = flint::fmpzxx;
#endif

static std::mt19937 rng;

using integer_t = integer<2>;
static const std::string name = "integer2_vec_mul_unsigned";

constexpr auto size = 30000000ul;

template <typename T>
static inline std::tuple<std::vector<T>, std::vector<T>, std::vector<T>> get_init_vectors(double &init_time)
{
    rng.seed(0);
    std::uniform_int_distribution<unsigned> dist(1u, 7u);
    simple_timer st;
    std::vector<T> v1(size), v2(size), v3(size);
    std::generate(v1.begin(), v1.end(), [&dist]() { return static_cast<T>(T(dist(rng)) << (GMP_NUMB_BITS / 2)); });
    std::generate(v2.begin(), v2.end(), [&dist]() { return static_cast<T>(T(dist(rng)) << (GMP_NUMB_BITS / 2)); });
    std::cout << "\nInit runtime: ";
    init_time = st.elapsed();
    return std::make_tuple(std::move(v1), std::move(v2), std::move(v3));
}

int main()
{
    // Warm up.
    for (auto volatile counter = 0ull; counter < 1000000000ull; ++counter) {
    }
    // Setup of the python output.
    std::string s = "# -*- coding: utf-8 -*-\n"
                    "def get_data():\n"
                    "    import pandas\n"
                    "    data = [";
    {
        std::cout << "\n\nBenchmarking mp++.";
        simple_timer st1;
        double init_time;
        auto p = get_init_vectors<integer_t>(init_time);
        s += "['mp++','init'," + std::to_string(init_time) + "],";
        {
            simple_timer st2;
            integer_t ret(0);
            for (auto i = 0ul; i < size; ++i) {
                mul(std::get<2>(p)[i], std::get<0>(p)[i], std::get<1>(p)[i]);
            }
            for (auto i = 0ul; i < size; ++i) {
                add(ret, ret, std::get<2>(p)[i]);
            }
            std::cout << ret << '\n';
            s += "['mp++','arithmetic'," + std::to_string(st2.elapsed()) + "],";
            std::cout << "\nArithmetic runtime: ";
        }
        s += "['mp++','total'," + std::to_string(st1.elapsed()) + "],";
        std::cout << "\nTotal runtime: ";
    }
#if defined(MPPP_BENCHMARK_BOOST)
    {
        std::cout << "\n\nBenchmarking cpp_int.";
        simple_timer st1;
        double init_time;
        auto p = get_init_vectors<cpp_int>(init_time);
        s += "['Boost (cpp_int)','init'," + std::to_string(init_time) + "],";
        {
            simple_timer st2;
            cpp_int ret(0);
            for (auto i = 0ul; i < size; ++i) {
                std::get<2>(p)[i] = std::get<0>(p)[i] * std::get<1>(p)[i];
            }
            for (auto i = 0ul; i < size; ++i) {
                ret += std::get<2>(p)[i];
            }
            std::cout << ret << '\n';
            s += "['Boost (cpp_int)','arithmetic'," + std::to_string(st2.elapsed()) + "],";
            std::cout << "\nArithmetic runtime: ";
        }
        s += "['Boost (cpp_int)','total'," + std::to_string(st1.elapsed()) + "],";
        std::cout << "\nTotal runtime: ";
    }
    {
        std::cout << "\n\nBenchmarking mpz_int.";
        simple_timer st1;
        double init_time;
        auto p = get_init_vectors<mpz_int>(init_time);
        s += "['Boost (mpz_int)','init'," + std::to_string(init_time) + "],";
        {
            simple_timer st2;
            mpz_int ret(0);
            for (auto i = 0ul; i < size; ++i) {
                ::mpz_mul(std::get<2>(p)[i].backend().data(), std::get<0>(p)[i].backend().data(),
                          std::get<1>(p)[i].backend().data());
            }
            for (auto i = 0ul; i < size; ++i) {
                ::mpz_add(ret.backend().data(), ret.backend().data(), std::get<2>(p)[i].backend().data());
            }
            std::cout << ret << '\n';
            s += "['Boost (mpz_int)','arithmetic'," + std::to_string(st2.elapsed()) + "],";
            std::cout << "\nArithmetic runtime: ";
        }
        s += "['Boost (mpz_int)','total'," + std::to_string(st1.elapsed()) + "],";
        std::cout << "\nTotal runtime: ";
    }
#endif
#if defined(MPPP_BENCHMARK_FLINT)
    {
        std::cout << "\n\nBenchmarking fmpzxx.";
        simple_timer st1;
        double init_time;
        auto p = get_init_vectors<fmpzxx>(init_time);
        s += "['FLINT','init'," + std::to_string(init_time) + "],";
        {
            simple_timer st2;
            fmpzxx ret(0);
            for (auto i = 0ul; i < size; ++i) {
                ::fmpz_mul(std::get<2>(p)[i]._data().inner, std::get<0>(p)[i]._data().inner,
                           std::get<1>(p)[i]._data().inner);
            }
            for (auto i = 0ul; i < size; ++i) {
                ::fmpz_add(ret._data().inner, ret._data().inner, std::get<2>(p)[i]._data().inner);
            }
            std::cout << ret << '\n';
            s += "['FLINT','arithmetic'," + std::to_string(st2.elapsed()) + "],";
            std::cout << "\nArithmetic runtime: ";
        }
        s += "['FLINT','total'," + std::to_string(st1.elapsed()) + "],";
        std::cout << "\nTotal runtime: ";
    }
#endif
    s += "]\n"
         "    retval = pandas.DataFrame(data)\n"
         "    retval.columns = ['Library','Task','Runtime (ms)']\n"
         "    return retval\n\n"
         "if __name__ == '__main__':\n"
         "    import matplotlib as mpl\n"
         "    mpl.use('Agg')\n"
         "    from matplotlib.pyplot import legend\n"
         "    import seaborn as sns\n"
         "    df = get_data()\n"
         "    g = sns.factorplot(x='Library', y = 'Runtime (ms)', hue='Task', data=df, kind='bar', palette='muted', "
         "legend = False, size = 5.5, aspect = 1.5)\n"
         "    legend(loc='upper right')\n"
         "    g.fig.suptitle('"
         + name + "')\n"
                  "    g.savefig('"
         + name + ".svg', bbox_inches='tight')\n";
    std::ofstream of(name + ".py", std::ios_base::trunc);
    of << s;
}
<|endoftext|>


<commit_before>#include <cctype>
#include <iostream>

#include <Lexer.hpp>

namespace miniMAT {
    namespace lexer {
        Lexer& Lexer::operator=(const Lexer& lexer) {
            this->input_line   = lexer.input_line;
            this->current_char = lexer.current_char;

            this->stream.str(input_line);
            this->stream >> std::noskipws;

            this->is_done = false;

            return *this;
        }

        Lexer::Lexer(const std::string& input_line) {
            this->input_line   = input_line;
            this->current_char = ' ';

            this->stream.str(input_line);
            this->stream >> std::noskipws;

            this->is_done = false;
        }

        Token Lexer::GetToken() {
           // Pass through whitespace
            while (current_char == ' ' || current_char == '\t' || current_char == '\n')
                TakeIt();

            // Check for end of line
            if (is_done)
                return Token(TokenKind::TOK_EOF, "__EOF__");

            // Non-identifiers
            char temp;
            std::string numstr;
            switch (current_char) {
                case '+':
                case '-':
                case '*':
                case '/':
                case '^':
                    temp = current_char;
                    TakeIt();

                    // Reject -- and ++
                    if ((temp == '+' && current_char == '+') || (temp == '-' && current_char == '-')) {
                        TakeIt();
                        std::string wrong_tok = std::string(1, temp) + std::string(1, temp);
                        return Token(TokenKind::TOK_ERROR, wrong_tok + " not allowed in miniMat!");
                    }

                    return Token(TokenKind::TOK_ARITHOP, std::string(1, temp));

                case '(':
                    TakeIt();
                    return Token(TokenKind::TOK_LPAREN, "(");
                case ')':
                    TakeIt();
                    return Token(TokenKind::TOK_RPAREN, ")");

                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    numstr = "";

                    // To the left of the decimal point
                    while (std::isdigit(current_char)) {
                        numstr += current_char;
                        TakeIt();
                    }

                    // The decimal point
                    if (current_char == '.') {
                        numstr += current_char;
                        TakeIt();

                        // To the right of the decimal point
                        while (std::isdigit(current_char)) {
                            numstr += current_char;
                            TakeIt();
                        }
                    }

                    return Token(TokenKind::TOK_FLOATLIT, numstr);

                case '.':
                    numstr = "";
                    numstr += current_char;
                    TakeIt();
                    if (std::isdigit(current_char)) {
                        while (std::isdigit(current_char)) {
                            numstr += current_char;
                            TakeIt();
                        }
                        return Token(TokenKind::TOK_FLOATLIT, numstr);
                    } else {
                        return Token(TokenKind::TOK_DOT, ".");
                    }

                default:
                    temp = current_char;
                    TakeIt();
                    std::string unknownChar = std::string(1, temp);
                    return Token(TokenKind::TOK_ERROR, "Unrecognized character '" + unknownChar + "' in input");
            }
        }

        /*
         * Get next character from input stream
         */
        void Lexer::NextChar() {
            /*
            if (iterator == input_line.end()) {
                is_done = true;
                current_char = '\0';
                iterator++;
            } else {
                current_char = *iterator;
                iterator++;
            }
            */
            char temp;
            if (stream >> temp) {
                current_char = temp;
            } else {
                is_done = true;
                current_char = '\0';
            }
        }

        void Lexer::TakeIt() {
            NextChar();
        }
    }
}
<commit_msg>Fix lexer behavior with single dot<commit_after>#include <cctype>
#include <iostream>

#include <Lexer.hpp>

namespace miniMAT {
    namespace lexer {
        Lexer& Lexer::operator=(const Lexer& lexer) {
            this->input_line   = lexer.input_line;
            this->current_char = lexer.current_char;

            this->stream.str(input_line);
            this->stream >> std::noskipws;

            this->is_done = false;

            return *this;
        }

        Lexer::Lexer(const std::string& input_line) {
            this->input_line   = input_line;
            this->current_char = ' ';

            this->stream.str(input_line);
            this->stream >> std::noskipws;

            this->is_done = false;
        }

        Token Lexer::GetToken() {
           // Pass through whitespace
            while (current_char == ' ' || current_char == '\t' || current_char == '\n')
                TakeIt();

            // Check for end of line
            if (is_done)
                return Token(TokenKind::TOK_EOF, "__EOF__");

            // Non-identifiers
            char temp;
            std::string numstr;
            switch (current_char) {
                case '+':
                case '-':
                case '*':
                case '/':
                case '^':
                    temp = current_char;
                    TakeIt();

                    // Reject -- and ++
                    if ((temp == '+' && current_char == '+') || (temp == '-' && current_char == '-')) {
                        TakeIt();
                        std::string wrong_tok = std::string(1, temp) + std::string(1, temp);
                        return Token(TokenKind::TOK_ERROR, wrong_tok + " not allowed in miniMat!");
                    }

                    return Token(TokenKind::TOK_ARITHOP, std::string(1, temp));

                case '(':
                    TakeIt();
                    return Token(TokenKind::TOK_LPAREN, "(");
                case ')':
                    TakeIt();
                    return Token(TokenKind::TOK_RPAREN, ")");

                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    numstr = "";

                    // To the left of the decimal point
                    while (std::isdigit(current_char)) {
                        numstr += current_char;
                        TakeIt();
                    }

                    // The decimal point
                    if (current_char == '.') {
                        numstr += current_char;
                        TakeIt();

                        // To the right of the decimal point
                        while (std::isdigit(current_char)) {
                            numstr += current_char;
                            TakeIt();
                        }
                    }

                    return Token(TokenKind::TOK_FLOATLIT, numstr);

                case '.':
                    numstr = "";
                    numstr += current_char;
                    TakeIt();
                    if (std::isdigit(current_char)) {
                        while (std::isdigit(current_char)) {
                            numstr += current_char;
                            TakeIt();
                        }
                        return Token(TokenKind::TOK_FLOATLIT, numstr);
                    } else {
                        //return Token(TokenKind::TOK_DOT, ".");
                        return Token(TokenKind::TOK_ERROR, "Single . not allowed!");
                    }

                default:
                    temp = current_char;
                    TakeIt();
                    std::string unknownChar = std::string(1, temp);
                    return Token(TokenKind::TOK_ERROR, "Unrecognized character '" + unknownChar + "' in input");
            }
        }

        /*
         * Get next character from input stream
         */
        void Lexer::NextChar() {
            /*
            if (iterator == input_line.end()) {
                is_done = true;
                current_char = '\0';
                iterator++;
            } else {
                current_char = *iterator;
                iterator++;
            }
            */
            char temp;
            if (stream >> temp) {
                current_char = temp;
            } else {
                is_done = true;
                current_char = '\0';
            }
        }

        void Lexer::TakeIt() {
            NextChar();
        }
    }
}
<|endoftext|>


<commit_before>#include "modinclude.h"
#include "bot_admin.h"

class DieCommand : public AdminHook {
	public:
		DieCommand(std::tr1::unordered_map<std::string, std::string> modConf, Base* modFace, std::string modName, std::string dir, unsigned short debug);
		int botAPIversion();
		bool onLoadComplete();
		void onRehash();
		void onModuleChange();
		std::string description();
		std::vector<std::string> supports();
		std::vector<std::vector<std::string> > adminCommands();
		void onAdminCommand(std::string server, std::string client, std::string nick, std::string command, std::string message, dccSender* dccMod, bool master);
};

DieCommand::DieCommand(std::tr1::unordered_map<std::string, std::string> modConf, Base* modFace, std::string modName, std::string dir, unsigned short debug) : AdminHook(modConf, modFace, modName, dir, debug) {}

int DieCommand::botAPIversion() {
	return 2000;
}

bool DieCommand::onLoadComplete() {
	std::multimap<std::string, std::string> moduleAbilities = modAbilities();
	if (moduleAbilities.find("BOT_ADMIN") == moduleAbilities.end()) { // BOT_ADMIN not provided but required for this module
		std::cout << "A module providing BOT_ADMIN is required for " << moduleName << ".  Unloading" << moduleName << "..." << std::endl; // debug level 1
		unloadModule();
		return false;
	}
	if (config["masteronly"] != "") {
		if (config["masteronly"][0] == 'n')
			config["masteronly"] = "no";
		else
			config["masteronly"] = "yes";
	} else
		config["masteronly"] = "yes";
	return true;
}

void DieCommand::onRehash() {
	if (config["masteronly"] != "") {
		if (config["masteronly"][0] == 'n')
			config["masteronly"] = "no";
		else
			config["masteronly"] = "yes";
	} else
		config["masteronly"] = "yes";
}

void DieCommand::onModuleChange() {
	std::multimap<std::string, std::string> moduleAbilities = modAbilities();
	std::multimap<std::string, std::string>::iterator botAdminAbility = moduleAbilities.find("BOT_ADMIN");
	if (botAdminAbility == moduleAbilities.end()) { // BOT_ADMIN not provided but required for this module
		std::cout << "A module providing BOT_ADMIN is required for " << moduleName << ".  Unloading" << moduleName << "..." << std::endl; // debug level 1
		unloadModule();
	}
}

std::string DieCommand::description() {
	return "Allows " + (config["masteronly"] == "yes" ? "the bot master" : "bot admins") + " to shut the bot down from IRC.";
}

std::vector<std::string> DieCommand::supports() {
	std::vector<std::string> supporting;
	supporting.push_back("BOT_ADMIN");
	return supporting;
}

std::vector<std::vector<std::string> > DieCommand::adminCommands() {
	std::vector<std::vector<std::string> > theCommands;
	std::vector<std::string> dieCommand;
	dieCommand.push_back("die");
	dieCommand.push_back("Makes the bot shut down.");
	dieCommand.push_back("Syntax: die [reason]");
	dieCommand.push_back("This command causes the bot to shut down.  If a reason is given, it will be used as the quit reason on all servers.");
	if (config["masteronly"] == "yes")
		dieCommand.push_back("This command is available only to bot admins.");
	theCommands.push_back(dieCommand);
	return theCommands;
}

void DieCommand::onAdminCommand(std::string server, std::string client, std::string nick, std::string command, std::string message, dccSender* dccMod, bool master) {
	if (config["masteronly"] == "yes" && !master) {
		if (dccMod == NULL)
			sendPrivMsg(server, client, nick, "The die command is available only to bot masters.");
		else
			dccMod->dccSend(server + "/" + nick, "The die command is available only to bot masters.");
		return;
	}
	std::list<std::string> connectedServers = servers();
	for (std::list<std::string>::iterator servIter = connectedServers.begin(); servIter != connectedServers.end(); ++servIter)
		quitServer(*servIter, message);
	if (dccMod != NULL) {
		std::vector<std::string> connectedDCC = dccMod->getConnections();
		for (unsigned int i = 0; i < connectedDCC.size(); i++)
			dccMod->closeDCCConnection(connectedDCC[i]);
	}
	std::cout << "Shutting down by admin command: die" << std::endl; // debug level 1
	sleep(1); // give the send queue a little time to flush quits in case of client protocol use (likely)
	std::exit(0);
}

extern "C" Module* spawn(std::tr1::unordered_map<std::string, std::string> modConf, Base* modFace, std::string modName, std::string dir, unsigned short debug) {
	return new DieCommand (modConf, modFace, modName, dir, debug);
}<commit_msg>OK, fine.  I screwed up.  Here's the proper m_admin_die.<commit_after>#include "modinclude.h"
#include "bot_admin.h"

class DieCommand : public AdminHook {
	public:
		DieCommand(std::tr1::unordered_map<std::string, std::string> modConf, Base* modFace, std::string modName, std::string dir, unsigned short debug);
		int botAPIversion();
		bool onLoadComplete();
		void onRehash();
		void onModuleChange();
		std::string description();
		std::vector<std::string> supports();
		std::vector<std::vector<std::string> > adminCommands();
		void onAdminCommand(std::string server, std::string client, std::string nick, std::string command, std::string message, dccSender* dccMod, bool master);
};

DieCommand::DieCommand(std::tr1::unordered_map<std::string, std::string> modConf, Base* modFace, std::string modName, std::string dir, unsigned short debug) : AdminHook(modConf, modFace, modName, dir, debug) {}

int DieCommand::botAPIversion() {
	return 2000;
}

bool DieCommand::onLoadComplete() {
	std::multimap<std::string, std::string> moduleAbilities = modAbilities();
	if (moduleAbilities.find("BOT_ADMIN") == moduleAbilities.end()) { // BOT_ADMIN not provided but required for this module
		std::cout << "A module providing BOT_ADMIN is required for " << moduleName << ".  Unloading" << moduleName << "..." << std::endl; // debug level 1
		unloadModule();
		return false;
	}
	if (config["masteronly"] != "") {
		if (config["masteronly"][0] == 'n')
			config["masteronly"] = "no";
		else
			config["masteronly"] = "yes";
	} else
		config["masteronly"] = "yes";
	return true;
}

void DieCommand::onRehash() {
	if (config["masteronly"] != "") {
		if (config["masteronly"][0] == 'n')
			config["masteronly"] = "no";
		else
			config["masteronly"] = "yes";
	} else
		config["masteronly"] = "yes";
}

void DieCommand::onModuleChange() {
	std::multimap<std::string, std::string> moduleAbilities = modAbilities();
	std::multimap<std::string, std::string>::iterator botAdminAbility = moduleAbilities.find("BOT_ADMIN");
	if (botAdminAbility == moduleAbilities.end()) { // BOT_ADMIN not provided but required for this module
		std::cout << "A module providing BOT_ADMIN is required for " << moduleName << ".  Unloading" << moduleName << "..." << std::endl; // debug level 1
		unloadModule();
	}
}

std::string DieCommand::description() {
	std::string desc = "Allows ";
	desc += config["masteronly"] == "yes" ? "the bot master" : "bot admins";
	desc += " to shut the bot down from IRC.";
	return desc;
}

std::vector<std::string> DieCommand::supports() {
	std::vector<std::string> supporting;
	supporting.push_back("BOT_ADMIN");
	return supporting;
}

std::vector<std::vector<std::string> > DieCommand::adminCommands() {
	std::vector<std::vector<std::string> > theCommands;
	std::vector<std::string> dieCommand;
	dieCommand.push_back("die");
	dieCommand.push_back("Makes the bot shut down.");
	dieCommand.push_back("Syntax: die [reason]");
	dieCommand.push_back("This command causes the bot to shut down.  If a reason is given, it will be used as the quit reason on all servers.");
	if (config["masteronly"] == "yes")
		dieCommand.push_back("This command is available only to bot admins.");
	theCommands.push_back(dieCommand);
	return theCommands;
}

void DieCommand::onAdminCommand(std::string server, std::string client, std::string nick, std::string command, std::string message, dccSender* dccMod, bool master) {
	if (config["masteronly"] == "yes" && !master) {
		if (dccMod == NULL)
			sendPrivMsg(server, client, nick, "The die command is available only to bot masters.");
		else
			dccMod->dccSend(server + "/" + nick, "The die command is available only to bot masters.");
		return;
	}
	std::list<std::string> connectedServers = servers();
	for (std::list<std::string>::iterator servIter = connectedServers.begin(); servIter != connectedServers.end(); ++servIter)
		quitServer(*servIter, message);
	if (dccMod != NULL) {
		std::vector<std::string> connectedDCC = dccMod->getConnections();
		for (unsigned int i = 0; i < connectedDCC.size(); i++)
			dccMod->closeDCCConnection(connectedDCC[i]);
	}
	std::cout << "Shutting down by admin command: die" << std::endl; // debug level 1
	sleep(1); // give the send queue a little time to flush quits in case of client protocol use (likely)
	std::exit(0);
}

extern "C" Module* spawn(std::tr1::unordered_map<std::string, std::string> modConf, Base* modFace, std::string modName, std::string dir, unsigned short debug) {
	return new DieCommand (modConf, modFace, modName, dir, debug);
}<|endoftext|>


<commit_before>// Font.cc
// Copyright (c) 2002 Henrik Kinnunen (fluxgen@linuxmail.org)
//
// 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.

//$Id: Font.cc,v 1.1 2002/03/21 10:51:48 fluxgen Exp $
#include "Font.hh"
#include <cstdarg>
#include <iostream> //for debug msg
using namespace std;

//use gnu extensions
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif //_GNU_SOURCE

#ifdef    HAVE_CONFIG_H
#  include "../config.h"
#endif // HAVE_CONFIG_H

namespace FbTk
{

bool Font::m_multibyte = false; //TODO: fix multibyte

Font::Font(Display *display, const char *name):m_loaded(false),
m_display(display) {
	m_font.fontstruct = 0;
	m_font.set_extents = 0;
	m_font.set = 0;
	if (name!=0) {
		load(name);
	}

}

Font::~Font() {
	freeFont();
}

bool Font::load(const char *name) {
	if (m_multibyte) {
		XFontSet set = createFontSet(m_display, name);
		if (!set)
			return false;
		freeFont();

		m_font.set = set;
		m_font.set_extents = XExtentsOfFontSet(m_font.set);

	} else {
		XFontStruct *font = XLoadQueryFont(m_display, name);
		if (font==0)
			return false;
		freeFont(); //free old font
		m_font.fontstruct = font; //set new font
	}

	m_loaded = true; //mark the font loaded

	return true;
}

bool Font::loadFromDatabase(XrmDatabase &database, const char *rname, const char *rclass) {
	assert(rname);
	assert(rclass);

	XrmValue value;
	char *value_type;

	//this should probably be moved to a Database class so we can keep
	//track of database init

	if (XrmGetResource(database, rname, rclass, &value_type, &value)) {
		#ifdef DEBUG
		cerr<<__FILE__<<"("<<__LINE__<<"): Load font:"<<value.addr<<endl;
		#endif
		return load(value.addr);
	}

	return false;

}
unsigned int Font::getTextWidth(const char *text, unsigned int size) const {
	if (text==0)
		return 0;
	if (multibyte()) {
		XRectangle ink, logical;
		XmbTextExtents(m_font.set, text, size,
			&ink, &logical);
		return logical.width;
	} else {
		assert(m_font.fontstruct);
		return XTextWidth(m_font.fontstruct,
			text, size);
	}

	return 0;
}

unsigned int Font::getHeight() const {
	if (multibyte() && getFontSetExtents())
		return getFontSetExtents()->max_ink_extent.height;
	if (getFontStruct())
		return getFontStruct()->ascent + getFontStruct()->descent;
	return 0;
}

XFontSet Font::createFontSet(Display *display, const char *fontname) {
	XFontSet fs;
	const int FONT_ELEMENT_SIZE=50;
	char **missing, *def = "-";
	int nmissing, pixel_size = 0, buf_size = 0;
	char weight[FONT_ELEMENT_SIZE], slant[FONT_ELEMENT_SIZE];

	fs = XCreateFontSet(display,
					fontname, &missing, &nmissing, &def);
	if (fs && (! nmissing)) return fs;

#ifdef		HAVE_SETLOCALE
	if (! fs) {
		if (nmissing) XFreeStringList(missing);

		setlocale(LC_CTYPE, "C");
		fs = XCreateFontSet(m_display, fontname,
			&missing, &nmissing, &def);
		setlocale(LC_CTYPE, "");
	}
#endif // HAVE_SETLOCALE

	if (fs) {
		XFontStruct **fontstructs;
		char **fontnames;
		XFontsOfFontSet(fs, &fontstructs, &fontnames);
		fontname = fontnames[0];
	}

	getFontElement(fontname, weight, FONT_ELEMENT_SIZE,
		 "-medium-", "-bold-", "-demibold-", "-regular-", NULL);
	getFontElement(fontname, slant, FONT_ELEMENT_SIZE,
		 "-r-", "-i-", "-o-", "-ri-", "-ro-", NULL);
	getFontSize(fontname, &pixel_size);

	if (! strcmp(weight, "*"))
		strncpy(weight, "medium", FONT_ELEMENT_SIZE);
	if (! strcmp(slant, "*"))
		strncpy(slant, "r", FONT_ELEMENT_SIZE);
	if (pixel_size < 3)
		pixel_size = 3;
	else if (pixel_size > 97)
		pixel_size = 97;

	buf_size = strlen(fontname) + (FONT_ELEMENT_SIZE * 2) + 64;
	char *pattern2 = new char[buf_size];
	snprintf(pattern2, buf_size - 1,
		 "%s,"
		 "-*-*-%s-%s-*-*-%d-*-*-*-*-*-*-*,"
		 "-*-*-*-*-*-*-%d-*-*-*-*-*-*-*,*",
		 fontname, weight, slant, pixel_size, pixel_size);
	fontname = pattern2;

	if (nmissing)
		XFreeStringList(missing);
	if (fs)
		XFreeFontSet(display, fs);

	fs = XCreateFontSet(display, fontname,
					&missing, &nmissing, &def);
	delete [] pattern2;

	return fs;
}

const char *Font::getFontElement(const char *pattern, char *buf, int bufsiz, ...) {
	const char *p, *v;
	char *p2;
	va_list va;

	va_start(va, bufsiz);
	buf[bufsiz-1] = 0;
	buf[bufsiz-2] = '*';
	while((v = va_arg(va, char *)) != NULL) {
		p = strcasestr(pattern, v);
		if (p) {
			strncpy(buf, p+1, bufsiz-2);
			p2 = strchr(buf, '-');
			if (p2) *p2=0;
			va_end(va);
			return p;
		}
	}
	va_end(va);
	strncpy(buf, "*", bufsiz);
	return NULL;
}

const char *Font::getFontSize(const char *pattern, int *size) {
	const char *p;
	const char *p2=0;
	int n=0;

	for (p=pattern; 1; p++) {
		if (!*p) {
			if (p2!=NULL && n>1 && n<72) {
				*size = n; return p2+1;
			} else {
				*size = 16; return NULL;
			}
		} else if (*p=='-') {
			if (n>1 && n<72 && p2!=NULL) {
				*size = n;
				return p2+1;
			}
			p2=p; n=0;
		} else if (*p>='0' && *p<='9' && p2!=NULL) {
			n *= 10;
			n += *p-'0';
		} else {
			p2=NULL; n=0;
		}
	}
}

void Font::freeFont() {
	//free memory
	if (m_font.fontstruct!=0)
		XFreeFont(m_display, m_font.fontstruct);
	if (m_font.set)
		XFreeFontSet(m_display, m_font.set);

	//clear struct
	m_font.fontstruct = 0;
	m_font.set = 0;
	m_font.set_extents = 0;

	m_loaded = false; //mark the font not loaded
}

};
<commit_msg>minor fix<commit_after>// Font.cc
// Copyright (c) 2002 Henrik Kinnunen (fluxgen@linuxmail.org)
//
// 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.

//$Id: Font.cc,v 1.2 2002/03/21 11:05:41 fluxgen Exp $
#include "Font.hh"
#include <cstdarg>
#include <iostream> //for debug msg
using namespace std;

//use gnu extensions
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif //_GNU_SOURCE

#ifdef    HAVE_CONFIG_H
#  include "../config.h"
#endif // HAVE_CONFIG_H

namespace FbTk
{

bool Font::m_multibyte = false; //TODO: fix multibyte

Font::Font(Display *display, const char *name):m_loaded(false),
m_display(display) {
	m_font.fontstruct = 0;
	m_font.set_extents = 0;
	m_font.set = 0;
	if (name!=0) {
		load(name);
	}

}

Font::~Font() {
	freeFont();
}

bool Font::load(const char *name) {
	if (m_multibyte) {
		XFontSet set = createFontSet(m_display, name);
		if (!set)
			return false;
		freeFont();

		m_font.set = set;
		m_font.set_extents = XExtentsOfFontSet(m_font.set);

	} else {
		XFontStruct *font = XLoadQueryFont(m_display, name);
		if (font==0)
			return false;
		freeFont(); //free old font
		m_font.fontstruct = font; //set new font
	}

	m_loaded = true; //mark the font loaded

	return true;
}

bool Font::loadFromDatabase(XrmDatabase &database, const char *rname, const char *rclass) {
	assert(rname);
	assert(rclass);

	XrmValue value;
	char *value_type;

	//this should probably be moved to a Database class so we can keep
	//track of database init

	if (XrmGetResource(database, rname, rclass, &value_type, &value)) {
		#ifdef DEBUG
		cerr<<__FILE__<<"("<<__LINE__<<"): Load font:"<<value.addr<<endl;
		#endif
		return load(value.addr);
	}

	return false;

}
unsigned int Font::getTextWidth(const char *text, unsigned int size) const {
	if (text==0)
		return 0;
	if (multibyte()) {
		XRectangle ink, logical;
		XmbTextExtents(m_font.set, text, size,
			&ink, &logical);
		return logical.width;
	} else {
		assert(m_font.fontstruct);
		return XTextWidth(m_font.fontstruct,
			text, size);
	}

	return 0;
}

unsigned int Font::getHeight() const {
	if (multibyte() && getFontSetExtents())
		return getFontSetExtents()->max_ink_extent.height;
	if (getFontStruct())
		return getFontStruct()->ascent + getFontStruct()->descent;
	return 0;
}

XFontSet Font::createFontSet(Display *display, const char *fontname) {
	XFontSet fs;
	const int FONT_ELEMENT_SIZE=50;
	char **missing, *def = "-";
	int nmissing, pixel_size = 0, buf_size = 0;
	char weight[FONT_ELEMENT_SIZE], slant[FONT_ELEMENT_SIZE];

	fs = XCreateFontSet(display,
					fontname, &missing, &nmissing, &def);
	if (fs && (! nmissing)) return fs;

#ifdef		HAVE_SETLOCALE
	if (! fs) {
		if (nmissing) XFreeStringList(missing);

		setlocale(LC_CTYPE, "C");
		fs = XCreateFontSet(display, fontname,
			&missing, &nmissing, &def);
		setlocale(LC_CTYPE, "");
	}
#endif // HAVE_SETLOCALE

	if (fs) {
		XFontStruct **fontstructs;
		char **fontnames;
		XFontsOfFontSet(fs, &fontstructs, &fontnames);
		fontname = fontnames[0];
	}

	getFontElement(fontname, weight, FONT_ELEMENT_SIZE,
		 "-medium-", "-bold-", "-demibold-", "-regular-", NULL);
	getFontElement(fontname, slant, FONT_ELEMENT_SIZE,
		 "-r-", "-i-", "-o-", "-ri-", "-ro-", NULL);
	getFontSize(fontname, &pixel_size);

	if (! strcmp(weight, "*"))
		strncpy(weight, "medium", FONT_ELEMENT_SIZE);
	if (! strcmp(slant, "*"))
		strncpy(slant, "r", FONT_ELEMENT_SIZE);
	if (pixel_size < 3)
		pixel_size = 3;
	else if (pixel_size > 97)
		pixel_size = 97;

	buf_size = strlen(fontname) + (FONT_ELEMENT_SIZE * 2) + 64;
	char *pattern2 = new char[buf_size];
	snprintf(pattern2, buf_size - 1,
		 "%s,"
		 "-*-*-%s-%s-*-*-%d-*-*-*-*-*-*-*,"
		 "-*-*-*-*-*-*-%d-*-*-*-*-*-*-*,*",
		 fontname, weight, slant, pixel_size, pixel_size);
	fontname = pattern2;

	if (nmissing)
		XFreeStringList(missing);
	if (fs)
		XFreeFontSet(display, fs);

	fs = XCreateFontSet(display, fontname,
					&missing, &nmissing, &def);
	delete [] pattern2;

	return fs;
}

const char *Font::getFontElement(const char *pattern, char *buf, int bufsiz, ...) {
	const char *p, *v;
	char *p2;
	va_list va;

	va_start(va, bufsiz);
	buf[bufsiz-1] = 0;
	buf[bufsiz-2] = '*';
	while((v = va_arg(va, char *)) != NULL) {
		p = strcasestr(pattern, v);
		if (p) {
			strncpy(buf, p+1, bufsiz-2);
			p2 = strchr(buf, '-');
			if (p2) *p2=0;
			va_end(va);
			return p;
		}
	}
	va_end(va);
	strncpy(buf, "*", bufsiz);
	return NULL;
}

const char *Font::getFontSize(const char *pattern, int *size) {
	const char *p;
	const char *p2=0;
	int n=0;

	for (p=pattern; 1; p++) {
		if (!*p) {
			if (p2!=NULL && n>1 && n<72) {
				*size = n; return p2+1;
			} else {
				*size = 16; return NULL;
			}
		} else if (*p=='-') {
			if (n>1 && n<72 && p2!=NULL) {
				*size = n;
				return p2+1;
			}
			p2=p; n=0;
		} else if (*p>='0' && *p<='9' && p2!=NULL) {
			n *= 10;
			n += *p-'0';
		} else {
			p2=NULL; n=0;
		}
	}
}

void Font::freeFont() {
	//free memory
	if (m_font.fontstruct!=0)
		XFreeFont(m_display, m_font.fontstruct);
	if (m_font.set)
		XFreeFontSet(m_display, m_font.set);

	//clear struct
	m_font.fontstruct = 0;
	m_font.set = 0;
	m_font.set_extents = 0;

	m_loaded = false; //mark the font not loaded
}

};
<|endoftext|>


<commit_before>/*
===========================================================================

Daemon GPL Source Code
Copyright (C) 2012 Unvanquished Developers

This file is part of the Daemon GPL Source Code (Daemon Source Code).

Daemon Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Daemon Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Daemon Source Code.  If not, see <http://www.gnu.org/licenses/>.

In addition, the Daemon Source Code is also subject to certain additional terms.
You should have received a copy of these additional terms immediately following the
terms and conditions of the GNU General Public License which accompanied the Daemon
Source Code.  If not, please request a copy in writing from id Software at the address
below.

If you have questions concerning this license or the applicable additional terms, you
may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville,
Maryland 20850 USA.

===========================================================================
*/

extern "C"
{
#include "q_shared.h"
#include "qcommon.h"
#include "../../libs/findlocale/findlocale.h"
}

#include "../../libs/tinygettext/tinygettext.hpp"
#include <sstream>

using namespace tinygettext;

DictionaryManager trans_manager;
DictionaryManager trans_managergame;
Dictionary        trans_dict;
Dictionary        trans_dictgame;

cvar_t            *language;
cvar_t            *language_debug;
cvar_t            *trans_encodings;
cvar_t            *trans_languages;
bool              enabled = false;
int               modificationCount=0;

#define _(x) Trans_Gettext(x)

/*
====================
Trans_ReturnLanguage

Return a loaded language. If desired language is not found, return closest match.
If no languages are close, force English.
====================
*/
Language Trans_ReturnLanguage( const char *lang )
{
	int bestScore = 0;
	Language bestLang, language = Language::from_env( std::string( lang ) );

	std::set<Language> langs = trans_manager.get_languages();
	for( std::set<Language>::iterator i = langs.begin(); i != langs.end(); i++ )
	{
		int score = Language::match( language, *i );

		if( score > bestScore )
		{
			bestScore = score;
			bestLang = *i;
		}
	}

	// Return "en" if language not found
	if( !bestLang )
	{
		Com_Printf( _("^3WARNING:^7 Language \"%s\" (%s) not found. Default to \"English\" (en)\n"),
					language.get_name().empty() ? _("Unknown Language") : language.get_name().c_str(),
					lang );
		bestLang = Language::from_env( "en" );
	}

	return bestLang;
}

extern "C" void Trans_UpdateLanguage_f( void )
{
	Language lang = Trans_ReturnLanguage( language->string );
	trans_dict = trans_manager.get_dictionary( lang );
	trans_dictgame = trans_managergame.get_dictionary( lang );
	Com_Printf(_( "Switched language to %s\n"), lang.get_name().c_str() );

#ifndef DEDICATED
	// update the default console keys string
	extern cvar_t *cl_consoleKeys; // should really #include client.h
	Z_Free( cl_consoleKeys->resetString );
	const char *default_consoleKeys = _("~ ` 0x7e 0x60");
	cl_consoleKeys->resetString = (char *) Z_Malloc( strlen( default_consoleKeys ) + 1 );
	strcpy( cl_consoleKeys->resetString, default_consoleKeys );
#endif
}

/*
============
Trans_Init
============
*/
extern "C" void Trans_Init( void )
{
	char                **poFiles, langList[ MAX_TOKEN_CHARS ], encList[ MAX_TOKEN_CHARS ];
	int                 numPoFiles, i;
	FL_Locale           *locale;
	std::set<Language>  langs;
	Language            lang;

	language = Cvar_Get( "language", "", CVAR_ARCHIVE );
	language_debug = Cvar_Get( "language_debug", "0", CVAR_ARCHIVE );
	trans_languages = Cvar_Get( "trans_languages", "", CVAR_ROM );
	trans_encodings = Cvar_Get( "trans_languages", "", CVAR_ROM );

	// Only detect locale if no previous language set.
	if( !language->string[0] )
	{
		FL_FindLocale( &locale, FL_MESSAGES );

		// Invalid or not found. Just use builtin language.
		if( !locale->lang || !locale->lang[0] || !locale->country || !locale->country[0] )
		{
			Cvar_Set( "language", "en" );
		}
		else
		{
			Cvar_Set( "language", va( "%s%s%s", locale->lang,
									  locale->country[0] ? "_" : "",
									  locale->country ) );
		}
	}

	poFiles = FS_ListFiles( "translation/client", ".po", &numPoFiles );

	// This assumes that the filenames in both folders are the same
	for( i = 0; i < numPoFiles; i++ )
	{
		int ret;
		Dictionary *dict1;
		Dictionary *dict2;
		char *buffer, language[ 6 ];

		if( FS_ReadFile( va( "translation/client/%s", poFiles[ i ] ), ( void ** ) &buffer ) > 0 )
		{
			dict1 = new Dictionary();
			COM_StripExtension2( poFiles[ i ], language, sizeof( language ) );
			std::stringstream ss( buffer );
			trans_manager.add_po( poFiles[ i ], ss, Language::from_env( std::string( language ) ) );
			FS_FreeFile( buffer );
		}
		else
		{
			Com_Printf(_( "^1ERROR: Could not open client translation: %s\n"), poFiles[ i ] );
		}

		if( FS_ReadFile( va( "translation/game/%s", poFiles[ i ] ), ( void ** ) &buffer ) > 0 )
		{
			dict2 = new Dictionary();
			COM_StripExtension2( poFiles[ i ], language, sizeof( language ) );
			std::stringstream ss( buffer );
			trans_managergame.add_po( poFiles[ i ], ss, Language::from_env( std::string( language ) ) );
			FS_FreeFile( buffer );
		}
		else
		{
			Com_Printf(_( "^1ERROR: Could not open game translation: %s\n"), poFiles[ i ] );
		}
	}
	FS_FreeFileList( poFiles );
	langs = trans_manager.get_languages();
	for( std::set<Language>::iterator p = langs.begin(); p != langs.end(); p++ )
	{
		Q_strcat( langList, sizeof( langList ), va( "\"%s\" ", p->get_name().c_str() ) );
		Q_strcat( encList, sizeof( encList ), va( "\"%s%s%s\" ", p->get_language().c_str(),
												  p->get_country().c_str()[0] ? "_" : "",
												  p->get_country().c_str() ) );
	}
	Cvar_Set( "trans_languages", langList );
	Cvar_Set( "trans_encodings", encList );
	Com_Printf(_( "Loaded %lu language(s)\n"), langs.size() );
	Cmd_AddCommand( "updatelanguage", Trans_UpdateLanguage_f );

	lang = Trans_ReturnLanguage( language->string );
	trans_dict = trans_manager.get_dictionary( lang );
	trans_dictgame = trans_managergame.get_dictionary( lang );
	enabled = true;
}

extern "C" const char* Trans_Gettext( const char *msgid )
{
	if( !enabled ) { return msgid; }
	return trans_dict.translate( std::string( msgid ) ).c_str();
}

extern "C" const char* Trans_GettextGame( const char *msgid )
{
	if( !enabled ) { return msgid; }
	return trans_dictgame.translate( std::string( msgid ) ).c_str();
}

extern "C" const char* Trans_GettextPlural( const char *msgid, const char *msgid_plural, int num )
{
	if( !enabled ) { return num == 1 ? msgid : msgid_plural; }
	return trans_dict.translate_plural( std::string( msgid ), std::string( msgid_plural ), num ).c_str();
}

extern "C" const char* Trans_GettextGamePlural( const char *msgid, const char *msgid_plural, int num )
{
	if( !enabled ) { return num == 1 ? msgid : msgid_plural; }
	return trans_dictgame.translate_plural( std::string( msgid ), std::string( msgid_plural ), num ).c_str();
}
<commit_msg>Fix crash when there are no translation files present<commit_after>/*
===========================================================================

Daemon GPL Source Code
Copyright (C) 2012 Unvanquished Developers

This file is part of the Daemon GPL Source Code (Daemon Source Code).

Daemon Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Daemon Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Daemon Source Code.  If not, see <http://www.gnu.org/licenses/>.

In addition, the Daemon Source Code is also subject to certain additional terms.
You should have received a copy of these additional terms immediately following the
terms and conditions of the GNU General Public License which accompanied the Daemon
Source Code.  If not, please request a copy in writing from id Software at the address
below.

If you have questions concerning this license or the applicable additional terms, you
may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville,
Maryland 20850 USA.

===========================================================================
*/

extern "C"
{
#include "q_shared.h"
#include "qcommon.h"
#include "../../libs/findlocale/findlocale.h"
}

#include "../../libs/tinygettext/tinygettext.hpp"
#include <sstream>

using namespace tinygettext;

DictionaryManager trans_manager;
DictionaryManager trans_managergame;
Dictionary        trans_dict;
Dictionary        trans_dictgame;

cvar_t            *language;
cvar_t            *language_debug;
cvar_t            *trans_encodings;
cvar_t            *trans_languages;
bool              enabled = false;
int               modificationCount=0;

#define _(x) Trans_Gettext(x)

/*
====================
Trans_ReturnLanguage

Return a loaded language. If desired language is not found, return closest match.
If no languages are close, force English.
====================
*/
Language Trans_ReturnLanguage( const char *lang )
{
	int bestScore = 0;
	Language bestLang, language = Language::from_env( std::string( lang ) );

	std::set<Language> langs = trans_manager.get_languages();
	for( std::set<Language>::iterator i = langs.begin(); i != langs.end(); i++ )
	{
		int score = Language::match( language, *i );

		if( score > bestScore )
		{
			bestScore = score;
			bestLang = *i;
		}
	}

	// Return "en" if language not found
	if( !bestLang )
	{
		Com_Printf( _("^3WARNING:^7 Language \"%s\" (%s) not found. Default to \"English\" (en)\n"),
					language.get_name().empty() ? _("Unknown Language") : language.get_name().c_str(),
					lang );
		bestLang = Language::from_env( "en" );
	}

	return bestLang;
}

extern "C" void Trans_UpdateLanguage_f( void )
{
	Language lang = Trans_ReturnLanguage( language->string );
	trans_dict = trans_manager.get_dictionary( lang );
	trans_dictgame = trans_managergame.get_dictionary( lang );
	Com_Printf(_( "Switched language to %s\n"), lang.get_name().c_str() );

#ifndef DEDICATED
	// update the default console keys string
	extern cvar_t *cl_consoleKeys; // should really #include client.h
	Z_Free( cl_consoleKeys->resetString );
	const char *default_consoleKeys = _("~ ` 0x7e 0x60");
	cl_consoleKeys->resetString = (char *) Z_Malloc( strlen( default_consoleKeys ) + 1 );
	strcpy( cl_consoleKeys->resetString, default_consoleKeys );
#endif
}

/*
============
Trans_Init
============
*/
extern "C" void Trans_Init( void )
{
	char                **poFiles, langList[ MAX_TOKEN_CHARS ], encList[ MAX_TOKEN_CHARS ];
	int                 numPoFiles, i;
	FL_Locale           *locale;
	std::set<Language>  langs;
	Language            lang;

	language = Cvar_Get( "language", "", CVAR_ARCHIVE );
	language_debug = Cvar_Get( "language_debug", "0", CVAR_ARCHIVE );
	trans_languages = Cvar_Get( "trans_languages", "", CVAR_ROM );
	trans_encodings = Cvar_Get( "trans_languages", "", CVAR_ROM );

	// Only detect locale if no previous language set.
	if( !language->string[0] )
	{
		FL_FindLocale( &locale, FL_MESSAGES );

		// Invalid or not found. Just use builtin language.
		if( !locale->lang || !locale->lang[0] || !locale->country || !locale->country[0] )
		{
			Cvar_Set( "language", "en" );
		}
		else
		{
			Cvar_Set( "language", va( "%s%s%s", locale->lang,
									  locale->country[0] ? "_" : "",
									  locale->country ) );
		}
	}

	poFiles = FS_ListFiles( "translation/client", ".po", &numPoFiles );

	// This assumes that the filenames in both folders are the same
	for( i = 0; i < numPoFiles; i++ )
	{
		int ret;
		Dictionary *dict1;
		Dictionary *dict2;
		char *buffer, language[ 6 ];

		if( FS_ReadFile( va( "translation/client/%s", poFiles[ i ] ), ( void ** ) &buffer ) > 0 )
		{
			dict1 = new Dictionary();
			COM_StripExtension2( poFiles[ i ], language, sizeof( language ) );
			std::stringstream ss( buffer );
			trans_manager.add_po( poFiles[ i ], ss, Language::from_env( std::string( language ) ) );
			FS_FreeFile( buffer );
		}
		else
		{
			Com_Printf(_( "^1ERROR: Could not open client translation: %s\n"), poFiles[ i ] );
		}

		if( FS_ReadFile( va( "translation/game/%s", poFiles[ i ] ), ( void ** ) &buffer ) > 0 )
		{
			dict2 = new Dictionary();
			COM_StripExtension2( poFiles[ i ], language, sizeof( language ) );
			std::stringstream ss( buffer );
			trans_managergame.add_po( poFiles[ i ], ss, Language::from_env( std::string( language ) ) );
			FS_FreeFile( buffer );
		}
		else
		{
			Com_Printf(_( "^1ERROR: Could not open game translation: %s\n"), poFiles[ i ] );
		}
	}
	FS_FreeFileList( poFiles );
	langs = trans_manager.get_languages();
	for( std::set<Language>::iterator p = langs.begin(); p != langs.end(); p++ )
	{
		Q_strcat( langList, sizeof( langList ), va( "\"%s\" ", p->get_name().c_str() ) );
		Q_strcat( encList, sizeof( encList ), va( "\"%s%s%s\" ", p->get_language().c_str(),
												  p->get_country().c_str()[0] ? "_" : "",
												  p->get_country().c_str() ) );
	}
	Cvar_Set( "trans_languages", langList );
	Cvar_Set( "trans_encodings", encList );
	Com_Printf(_( "Loaded %lu language(s)\n"), langs.size() );
	Cmd_AddCommand( "updatelanguage", Trans_UpdateLanguage_f );
	if( langs.size() )
	{
		lang = Trans_ReturnLanguage( language->string );
		trans_dict = trans_manager.get_dictionary( lang );
		trans_dictgame = trans_managergame.get_dictionary( lang );
		enabled = true;
	}
}

extern "C" const char* Trans_Gettext( const char *msgid )
{
	if( !enabled ) { return msgid; }
	return trans_dict.translate( std::string( msgid ) ).c_str();
}

extern "C" const char* Trans_GettextGame( const char *msgid )
{
	if( !enabled ) { return msgid; }
	return trans_dictgame.translate( std::string( msgid ) ).c_str();
}

extern "C" const char* Trans_GettextPlural( const char *msgid, const char *msgid_plural, int num )
{
	if( !enabled ) { return num == 1 ? msgid : msgid_plural; }
	return trans_dict.translate_plural( std::string( msgid ), std::string( msgid_plural ), num ).c_str();
}

extern "C" const char* Trans_GettextGamePlural( const char *msgid, const char *msgid_plural, int num )
{
	if( !enabled ) { return num == 1 ? msgid : msgid_plural; }
	return trans_dictgame.translate_plural( std::string( msgid ), std::string( msgid_plural ), num ).c_str();
}
<|endoftext|>


<commit_before>/*
 * GraphEventPublisher.hpp
 *
 *  Created on: Sep 16, 2015
 *      Author: aboeckmann
 */

#pragma once
#include <vector>
#include "GraphEvent.hpp"

namespace envire { namespace core
{
    class GraphEvent;
    class GraphEventSubscriber;

    /**
     * Base class for frame-event publishers.
     * Handles the subscription and notification of subscribers.
     */
    class GraphEventPublisher
    {
    private:
      std::vector<GraphEventSubscriber*> subscribers;

    public:
        /**Subscribes the @param handler to all events by this event source */
        void subscribe(GraphEventSubscriber* pSubscriber);
        void unsubscribe(GraphEventSubscriber* pSubscriber);

    protected:
        /**Notify all subscribers about a certain frame event */
        void notify(const GraphEvent& e);

        //there is no use in creating an instance of the publisher
        //on its own.
        GraphEventPublisher() {}
        ~GraphEventPublisher() {}

    };
}}

<commit_msg>made destructor of graph event publisher virtual<commit_after>/*
 * GraphEventPublisher.hpp
 *
 *  Created on: Sep 16, 2015
 *      Author: aboeckmann
 */

#pragma once
#include <vector>
#include "GraphEvent.hpp"

namespace envire { namespace core
{
    class GraphEvent;
    class GraphEventSubscriber;

    /**
     * Base class for frame-event publishers.
     * Handles the subscription and notification of subscribers.
     */
    class GraphEventPublisher
    {
    private:
      std::vector<GraphEventSubscriber*> subscribers;

    public:
        /**Subscribes the @param handler to all events by this event source */
        void subscribe(GraphEventSubscriber* pSubscriber);
        void unsubscribe(GraphEventSubscriber* pSubscriber);

    protected:
        /**Notify all subscribers about a certain frame event */
        void notify(const GraphEvent& e);

        //there is no use in creating an instance of the publisher
        //on its own.
        GraphEventPublisher() {}
        virtual ~GraphEventPublisher() {}

    };
}}

<|endoftext|>


<commit_before>/** \copyright
 * Copyright (c) 2012, Stuart W Baker
 * 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file HwInit.cxx
 * This file represents the hardware initialization for the TI Tiva MCU.
 *
 * @author Stuart W. Baker
 * @date 5 January 2013
 */

#include <new>
#include <cstdint>

#include "stm32f3xx_hal_conf.h"

#include "os/OS.hxx"
#include "Stm32Uart.hxx"
#include "Stm32Can.hxx"
#include "Stm32EEPROMEmulation.hxx"
#include "hardware.hxx"

/** override stdin */
const char *STDIN_DEVICE = "/dev/ser0";

/** override stdout */
const char *STDOUT_DEVICE = "/dev/ser0";

/** override stderr */
const char *STDERR_DEVICE = "/dev/ser0";

/** UART 0 serial driver instance */
static Stm32Uart uart0("/dev/ser0", USART2, USART2_IRQn);

/** CAN 0 CAN driver instance */
static Stm32Can can0("/dev/can0");

/** EEPROM emulation driver. The file size might be made bigger. */
static Stm32EEPROMEmulation eeprom0("/dev/eeprom", 512);

const size_t EEPROMEmulation::SECTOR_SIZE = 2048;

extern "C" {

/** Blink LED */
uint32_t blinker_pattern = 0;
static uint32_t rest_pattern = 0;

void hw_set_to_safe(void)
{
}

void resetblink(uint32_t pattern)
{
    blinker_pattern = pattern;
    rest_pattern = pattern ? 1 : 0;
    BLINKER_RAW_Pin::set(pattern ? true : false);
    /* make a timer event trigger immediately */
}

void setblink(uint32_t pattern)
{
    resetblink(pattern);
}

/// TIM17 shares this interrupt with certain features of timer1
void tim1_trg_com_interrupt_handler(void)
{
    //
    // Clear the timer interrupt.
    //
    TIM17->SR = ~TIM_IT_UPDATE;

    // Set output LED.
    BLINKER_RAW_Pin::set(rest_pattern & 1);

    // Shift and maybe reset pattern.
    rest_pattern >>= 1;
    if (!rest_pattern)
    {
        rest_pattern = blinker_pattern;
    }
}

void diewith(uint32_t pattern)
{
    // vPortClearInterruptMask(0x20);
    asm("cpsie i\n");

    resetblink(pattern);
    while (1)
        ;
}

/** CPU clock speed. */
const unsigned long cm3_cpu_clock_hz = 72000000;
uint32_t SystemCoreClock;
const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
const uint8_t APBPrescTable[8]  = {0, 0, 0, 0, 1, 2, 3, 4};

/**
  * @brief  System Clock Configuration
  *         The system Clock is configured as follow :
  *            System Clock source            = PLL (HSE)
  *            SYSCLK(Hz)                     = 72000000
  *            HCLK(Hz)                       = 72000000
  *            AHB Prescaler                  = 1
  *            APB1 Prescaler                 = 2
  *            APB2 Prescaler                 = 1
  *            HSE Frequency(Hz)              = 8000000
  *            HSE PREDIV                     = 1
  *            PLLMUL                         = 9
  *            Flash Latency(WS)              = 2
  * @param  None
  * @retval None
  */
static void clock_setup(void)
{
    HAL_RCC_DeInit();

    RCC_ClkInitTypeDef RCC_ClkInitStruct;
    RCC_OscInitTypeDef RCC_OscInitStruct;

    /* Enable HSE Oscillator and activate PLL with HSE as source on bypass
     * mode. This allows using the MCO clock output from the ST_Link part of
     * the nucleo board and freeing up the other clock pin for GPIO. */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;

    HAL_RCC_OscConfig(&RCC_OscInitStruct);

    /* Select PLL as system clock source and configure the HCLK, PCLK1 and
     * PCLK2 clocks dividers
     */
    RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK |
                                   RCC_CLOCKTYPE_PCLK1  | RCC_CLOCKTYPE_PCLK2);
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

    HASSERT(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) == HAL_OK);

    SystemCoreClock = cm3_cpu_clock_hz;
}

/** Initialize the processor hardware.
 */
void hw_preinit(void)
{
    /* Globally disables interrupts until the FreeRTOS scheduler is up. */
    asm("cpsid i\n");

    /* these FLASH settings enable opertion at 48 MHz */
    __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
    __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_1);

    /* setup the system clock */
    clock_setup();

    /* enable peripheral clocks */
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_USART2_CLK_ENABLE();
    __HAL_RCC_CAN1_CLK_ENABLE();
    __HAL_RCC_TIM17_CLK_ENABLE();

    /* setup pinmux */
    GPIO_InitTypeDef gpio_init;

    /* USART2 pinmux on PA2 and PA3 */
    gpio_init.Mode = GPIO_MODE_AF_PP;
    gpio_init.Pull = GPIO_PULLUP;
    gpio_init.Speed = GPIO_SPEED_FREQ_HIGH;
    gpio_init.Alternate = GPIO_AF7_USART2;
    gpio_init.Pin = GPIO_PIN_2;
    HAL_GPIO_Init(GPIOA, &gpio_init);
    gpio_init.Pin = GPIO_PIN_3;
    HAL_GPIO_Init(GPIOA, &gpio_init);

    /* CAN pinmux on PB8 and PB9 */
    gpio_init.Mode = GPIO_MODE_AF_PP;
    gpio_init.Pull = GPIO_PULLUP;
    gpio_init.Speed = GPIO_SPEED_FREQ_HIGH;
    gpio_init.Alternate = GPIO_AF9_CAN;
    gpio_init.Pin = GPIO_PIN_8;
    HAL_GPIO_Init(GPIOB, &gpio_init);
    gpio_init.Pin = GPIO_PIN_9;
    HAL_GPIO_Init(GPIOB, &gpio_init);

    GpioInit::hw_init();

    /* Initializes the blinker timer. */
    TIM_HandleTypeDef TimHandle;
    TimHandle.Instance = TIM17;
    TimHandle.Init.Period = configCPU_CLOCK_HZ / 10000 / 8;
    TimHandle.Init.Prescaler = 10000;
    TimHandle.Init.ClockDivision = 0;
    TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
    TimHandle.Init.RepetitionCounter = 0;
    if (HAL_TIM_Base_Init(&TimHandle) != HAL_OK)
    {
        /* Initialization Error */
        HASSERT(0);
    }
    if (HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK)
    {
        /* Starting Error */
        HASSERT(0);
    }
    NVIC_SetPriority(TIM17_IRQn, 0);
    NVIC_EnableIRQ(TIM17_IRQn);
}

void usart2_interrupt_handler(void)
{
    Stm32Uart::interrupt_handler(1);
}

}
<commit_msg>Fixes clock initialization routine.<commit_after>/** \copyright
 * Copyright (c) 2012, Stuart W Baker
 * 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file HwInit.cxx
 * This file represents the hardware initialization for the TI Tiva MCU.
 *
 * @author Stuart W. Baker
 * @date 5 January 2013
 */

#include <new>
#include <cstdint>

#include "stm32f3xx_hal_conf.h"

#include "os/OS.hxx"
#include "Stm32Uart.hxx"
#include "Stm32Can.hxx"
#include "Stm32EEPROMEmulation.hxx"
#include "hardware.hxx"

/** override stdin */
const char *STDIN_DEVICE = "/dev/ser0";

/** override stdout */
const char *STDOUT_DEVICE = "/dev/ser0";

/** override stderr */
const char *STDERR_DEVICE = "/dev/ser0";

/** UART 0 serial driver instance */
static Stm32Uart uart0("/dev/ser0", USART2, USART2_IRQn);

/** CAN 0 CAN driver instance */
static Stm32Can can0("/dev/can0");

/** EEPROM emulation driver. The file size might be made bigger. */
static Stm32EEPROMEmulation eeprom0("/dev/eeprom", 512);

const size_t EEPROMEmulation::SECTOR_SIZE = 2048;

extern "C" {

/** Blink LED */
uint32_t blinker_pattern = 0;
static uint32_t rest_pattern = 0;

void hw_set_to_safe(void)
{
}

void resetblink(uint32_t pattern)
{
    blinker_pattern = pattern;
    rest_pattern = pattern ? 1 : 0;
    BLINKER_RAW_Pin::set(pattern ? true : false);
    /* make a timer event trigger immediately */
}

void setblink(uint32_t pattern)
{
    resetblink(pattern);
}

/// TIM17 shares this interrupt with certain features of timer1
void tim1_trg_com_interrupt_handler(void)
{
    //
    // Clear the timer interrupt.
    //
    TIM17->SR = ~TIM_IT_UPDATE;

    // Set output LED.
    BLINKER_RAW_Pin::set(rest_pattern & 1);

    // Shift and maybe reset pattern.
    rest_pattern >>= 1;
    if (!rest_pattern)
    {
        rest_pattern = blinker_pattern;
    }
}

void diewith(uint32_t pattern)
{
    // vPortClearInterruptMask(0x20);
    asm("cpsie i\n");

    resetblink(pattern);
    while (1)
        ;
}

/** CPU clock speed. */
const unsigned long cm3_cpu_clock_hz = 72000000;
uint32_t SystemCoreClock;
const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
const uint8_t APBPrescTable[8]  = {0, 0, 0, 0, 1, 2, 3, 4};

/**
  * @brief  System Clock Configuration
  *         The system Clock is configured as follow :
  *            System Clock source            = PLL (HSE)
  *            SYSCLK(Hz)                     = 72000000
  *            HCLK(Hz)                       = 72000000
  *            AHB Prescaler                  = 1
  *            APB1 Prescaler                 = 2
  *            APB2 Prescaler                 = 1
  *            HSE Frequency(Hz)              = 8000000
  *            HSE PREDIV                     = 1
  *            PLLMUL                         = 9
  *            Flash Latency(WS)              = 2
  * @param  None
  * @retval None
  */
static void clock_setup(void)
{
    HAL_RCC_DeInit();

    RCC_ClkInitTypeDef RCC_ClkInitStruct;
    RCC_OscInitTypeDef RCC_OscInitStruct;

    /* Enable HSE Oscillator and activate PLL with HSE as source on bypass
     * mode. This allows using the MCO clock output from the ST_Link part of
     * the nucleo board and freeing up the other clock pin for GPIO. */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
    RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;

    HAL_RCC_OscConfig(&RCC_OscInitStruct);

    /* Select PLL as system clock source and configure the HCLK, PCLK1 and
     * PCLK2 clocks dividers
     */
    RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK |
                                   RCC_CLOCKTYPE_PCLK1  | RCC_CLOCKTYPE_PCLK2);
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

    HASSERT(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) == HAL_OK);

    // This will fail if the clocks are somehow misconfigured.
    HASSERT(SystemCoreClock == cm3_cpu_clock_hz);
}

/** Initialize the processor hardware.
 */
void hw_preinit(void)
{
    /* Globally disables interrupts until the FreeRTOS scheduler is up. */
    asm("cpsid i\n");

    /* these FLASH settings enable opertion at 72 MHz */
    __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
    __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_2);

    /* setup the system clock */
    clock_setup();

    /* enable peripheral clocks */
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_USART2_CLK_ENABLE();
    __HAL_RCC_CAN1_CLK_ENABLE();
    __HAL_RCC_TIM17_CLK_ENABLE();

    /* setup pinmux */
    GPIO_InitTypeDef gpio_init;

    /* USART2 pinmux on PA2 and PA3 */
    gpio_init.Mode = GPIO_MODE_AF_PP;
    gpio_init.Pull = GPIO_PULLUP;
    gpio_init.Speed = GPIO_SPEED_FREQ_HIGH;
    gpio_init.Alternate = GPIO_AF7_USART2;
    gpio_init.Pin = GPIO_PIN_2;
    HAL_GPIO_Init(GPIOA, &gpio_init);
    gpio_init.Pin = GPIO_PIN_3;
    HAL_GPIO_Init(GPIOA, &gpio_init);

    /* CAN pinmux on PB8 and PB9 */
    gpio_init.Mode = GPIO_MODE_AF_PP;
    gpio_init.Pull = GPIO_PULLUP;
    gpio_init.Speed = GPIO_SPEED_FREQ_HIGH;
    gpio_init.Alternate = GPIO_AF9_CAN;
    gpio_init.Pin = GPIO_PIN_8;
    HAL_GPIO_Init(GPIOB, &gpio_init);
    gpio_init.Pin = GPIO_PIN_9;
    HAL_GPIO_Init(GPIOB, &gpio_init);

    GpioInit::hw_init();

    /* Initializes the blinker timer. */
    TIM_HandleTypeDef TimHandle;
    TimHandle.Instance = TIM17;
    TimHandle.Init.Period = configCPU_CLOCK_HZ / 10000 / 8;
    TimHandle.Init.Prescaler = 10000;
    TimHandle.Init.ClockDivision = 0;
    TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
    TimHandle.Init.RepetitionCounter = 0;
    if (HAL_TIM_Base_Init(&TimHandle) != HAL_OK)
    {
        /* Initialization Error */
        HASSERT(0);
    }
    if (HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK)
    {
        /* Starting Error */
        HASSERT(0);
    }
    NVIC_SetPriority(TIM17_IRQn, 0);
    NVIC_EnableIRQ(TIM17_IRQn);
}

void usart2_interrupt_handler(void)
{
    Stm32Uart::interrupt_handler(1);
}

}
<|endoftext|>


<commit_before>
#include "loop.h"

#include "config.h"
#include "output.h"
#include "mode.h"
#include "configmonitor.h"
#include "edid.h"

#include <QX11Info>
#include <QtCore/QDebug>
#include <QtCore/QDateTime>

#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>

using namespace KScreen;

Loop::Loop(QObject* parent): QObject(parent)
{
    start();
}

Loop::~Loop()
{

}

void Loop::start()
{
    qDebug() << "START";
    QDateTime date = QDateTime::currentDateTime();
    m_config = Config::current();
    qDebug() << "Took: " << date.secsTo(QDateTime::currentDateTime());
    ConfigMonitor::instance()->addConfig(m_config);
    connect(ConfigMonitor::instance(), SIGNAL(configurationChanged()), SLOT(printConfig()));

    //config->outputs()[65]->setCurrentMode(70);
    //Config::setConfig(config);
}

void Loop::printConfig()
{
//     KScreen *screen = KScreen::self();
//     qDebug() << "Backend: " << screen->backend();

    qDebug() << "\n============================================================\n"
                "============================================================\n"
                "============================================================\n";

    qDebug() << "Screen:";
    qDebug() << "maxSize:" << m_config->screen()->maxSize();
    qDebug() << "minSize:" << m_config->screen()->minSize();
    qDebug() << "currentSize:" << m_config->screen()->currentSize();

    OutputList outputs = m_config->outputs();
    OutputList outputEnabled;
    Q_FOREACH(Output *output, outputs) {
        qDebug() << "Id: " << output->id();
        qDebug() << "Name: " << output->name();
        qDebug() << "Type: " << output->type();
        qDebug() << "Connected: " << output->isConnected();
        qDebug() << "Enabled: " << output->isEnabled();
        qDebug() << "Primary: " << output->isPrimary();
        qDebug() << "Rotation: " << output->rotation();
        qDebug() << "Pos: " << output->pos();
        if (output->currentMode()) {
            qDebug() << "Size: " << output->mode(output->currentMode())->size();
        }
        qDebug() << "Clones: " << output->clones().isEmpty();
        qDebug() << "Mode: " << output->currentMode();
        qDebug() << "Modes: ";

        ModeList modes = output->modes();
        Q_FOREACH(Mode* mode, modes) {
            qDebug() << "\t" << mode->id() << "  " << mode->name() << " " << mode->size() << " " << mode->refreshRate();
        }

        Edid* edid = output->edid();
	qDebug() << "EDID Info: ";
	if (edid != 0) {
	    qDebug() << "\tDevice ID: " << edid->deviceId();
	    qDebug() << "\tName: " << edid->name();
	    qDebug() << "\tVendor: " << edid->vendor();
	    qDebug() << "\tSerial: " << edid->serial();
	    qDebug() << "\tEISA ID: " << edid->eisaId();
	    qDebug() << "\tHash: " << edid->hash();
	    qDebug() << "\tWidth: " << edid->width();
	    qDebug() << "\tHeight: " << edid->height();
	    qDebug() << "\tGamma: " << edid->gamma();
	    qDebug() << "\tRed: " << edid->red();
	    qDebug() << "\tGreen: " << edid->green();
	    qDebug() << "\tBlue: " << edid->blue();
	    qDebug() << "\tWhite: " << edid->white();
	} else {
	    qDebug() << "\tUnavailable";
	}

        if (output->isEnabled()) {
            outputEnabled.insert(output->id(), output);
        }
        qDebug() << "\n-----------------------------------------------------\n";
    }
}
#include <loop.moc><commit_msg>s/tab/spaces/<commit_after>
#include "loop.h"

#include "config.h"
#include "output.h"
#include "mode.h"
#include "configmonitor.h"
#include "edid.h"

#include <QX11Info>
#include <QtCore/QDebug>
#include <QtCore/QDateTime>

#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>

using namespace KScreen;

Loop::Loop(QObject* parent): QObject(parent)
{
    start();
}

Loop::~Loop()
{

}

void Loop::start()
{
    qDebug() << "START";
    QDateTime date = QDateTime::currentDateTime();
    m_config = Config::current();
    qDebug() << "Took: " << date.secsTo(QDateTime::currentDateTime());
    ConfigMonitor::instance()->addConfig(m_config);
    connect(ConfigMonitor::instance(), SIGNAL(configurationChanged()), SLOT(printConfig()));

    //config->outputs()[65]->setCurrentMode(70);
    //Config::setConfig(config);
}

void Loop::printConfig()
{
//     KScreen *screen = KScreen::self();
//     qDebug() << "Backend: " << screen->backend();

    qDebug() << "\n============================================================\n"
                "============================================================\n"
                "============================================================\n";

    qDebug() << "Screen:";
    qDebug() << "maxSize:" << m_config->screen()->maxSize();
    qDebug() << "minSize:" << m_config->screen()->minSize();
    qDebug() << "currentSize:" << m_config->screen()->currentSize();

    OutputList outputs = m_config->outputs();
    OutputList outputEnabled;
    Q_FOREACH(Output *output, outputs) {
        qDebug() << "Id: " << output->id();
        qDebug() << "Name: " << output->name();
        qDebug() << "Type: " << output->type();
        qDebug() << "Connected: " << output->isConnected();
        qDebug() << "Enabled: " << output->isEnabled();
        qDebug() << "Primary: " << output->isPrimary();
        qDebug() << "Rotation: " << output->rotation();
        qDebug() << "Pos: " << output->pos();
        if (output->currentMode()) {
            qDebug() << "Size: " << output->mode(output->currentMode())->size();
        }
        qDebug() << "Clones: " << output->clones().isEmpty();
        qDebug() << "Mode: " << output->currentMode();
        qDebug() << "Modes: ";

        ModeList modes = output->modes();
        Q_FOREACH(Mode* mode, modes) {
            qDebug() << "\t" << mode->id() << "  " << mode->name() << " " << mode->size() << " " << mode->refreshRate();
        }

        Edid* edid = output->edid();
    qDebug() << "EDID Info: ";
    if (edid != 0) {
        qDebug() << "\tDevice ID: " << edid->deviceId();
        qDebug() << "\tName: " << edid->name();
        qDebug() << "\tVendor: " << edid->vendor();
        qDebug() << "\tSerial: " << edid->serial();
        qDebug() << "\tEISA ID: " << edid->eisaId();
        qDebug() << "\tHash: " << edid->hash();
        qDebug() << "\tWidth: " << edid->width();
        qDebug() << "\tHeight: " << edid->height();
        qDebug() << "\tGamma: " << edid->gamma();
        qDebug() << "\tRed: " << edid->red();
        qDebug() << "\tGreen: " << edid->green();
        qDebug() << "\tBlue: " << edid->blue();
        qDebug() << "\tWhite: " << edid->white();
    } else {
        qDebug() << "\tUnavailable";
    }

        if (output->isEnabled()) {
            outputEnabled.insert(output->id(), output);
        }
        qDebug() << "\n-----------------------------------------------------\n";
    }
}
#include <loop.moc><|endoftext|>


<commit_before>/*
 * Copyright (c) 2011. Philipp Wagner <bytefish[at]gmx[dot]de>.
 * Released to public domain under terms of the BSD Simplified license.
 *
 * 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 organization nor the names of its contributors
 *     may be used to endorse or promote products derived from this software
 *     without specific prior written permission.
 *
 *   See <http://www.opensource.org/licenses/bsd-license>
 */

/*#include <cv.h>
#include <face.hpp>
#include <highgui.hpp>
#include <imgproc.hpp>
#include <objdetect.hpp>
*/
#include "opencv2/opencv.hpp"

#include <iostream>
#include <fstream>
#include <sstream>

using namespace cv;
//using namespace cv::face;
using namespace std;

int main(int argc, const char *argv[]) {
    // Check for valid command line arguments, print usage
    // if no arguments were given.
    if (argc != 3) {
        cout << "usage: " << argv[0] << " </path/to/haar_cascade> </path/to/csv.ext> </path/to/device id>" << endl;
        cout << "\t </path/to/haar_cascade> -- Path to the Haar Cascade for face detection." << endl;
        cout << "\t <device id> -- The webcam device id to grab frames from." << endl;
        exit(1);
    }
    // Get the path to your CSV:
    string fn_haar = string(argv[1]);
    int deviceId = atoi(argv[2]);

    int im_width = 480;
    int im_height = 560;

		//Create haar cascade
    CascadeClassifier haar_cascade;
    haar_cascade.load(fn_haar);
    // Get a handle to the Video device:
    VideoCapture cap(deviceId);
    // Check if we can use this device at all:
    if(!cap.isOpened()) {
        cerr << "Capture Device ID " << deviceId << "cannot be opened." << endl;
        return -1;
    }
    // Holds the current frame from the Video device:
    Mat frame;
    for(;;) {
        cap >> frame;
        // Clone the current frame:
        Mat original = frame.clone();
        // Convert the current frame to grayscale:
        Mat gray;
        cvtColor(original, gray, CV_BGR2GRAY);
        // Find the faces in the frame:
        vector< Rect_<int> > faces;
        haar_cascade.detectMultiScale(gray, faces);
        // At this point you have the position of the faces in
        // faces. Now we'll get the faces, make a prediction and
        // annotate it in the video. Cool or what?
        for(int i = 0; i < faces.size(); i++) {
            // Process face by face:
            Rect face_i = faces[i];
            // Crop the face from the image. So simple with OpenCV C++:
            Mat face = gray(face_i);
            // Resizing the face is necessary for Eigenfaces and Fisherfaces. You can easily
            // verify this, by reading through the face recognition tutorial coming with OpenCV.
            // Resizing IS NOT NEEDED for Local Binary Patterns Histograms, so preparing the
            // input data really depends on the algorithm used.
            //
            // I strongly encourage you to play around with the algorithms. See which work best
            // in your scenario, LBPH should always be a contender for robust face recognition.
            //
            // Since I am showing the Fisherfaces algorithm here, I also show how to resize the
            // face you have just found:
            Mat face_resized;
            cv::resize(face, face_resized, Size(im_width, im_height), 1.0, 1.0, INTER_CUBIC);
            // Now perform the prediction, see how easy that is:
            // First of all draw a green rectangle around the detected face:
            rectangle(original, face_i, CV_RGB(0, 255,0), 1);
        }
        // Show the result:
        imshow("face_recognizer", original);
        // And display it:
        char key = (char) waitKey(20);
        // Exit this loop on escape:
        if(key == 27)
            break;
    }
    return 0;
}
<commit_msg>Fix tabs<commit_after>/*
 * Copyright (c) 2011. Philipp Wagner <bytefish[at]gmx[dot]de>.
 * Released to public domain under terms of the BSD Simplified license.
 *
 * 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 organization nor the names of its contributors
 *	 may be used to endorse or promote products derived from this software
 *	 without specific prior written permission.
 *
 *   See <http://www.opensource.org/licenses/bsd-license>
 */

/*#include <cv.h>
#include <face.hpp>
#include <highgui.hpp>
#include <imgproc.hpp>
#include <objdetect.hpp>
*/
#include "opencv2/opencv.hpp"

#include <iostream>
#include <fstream>
#include <sstream>

using namespace cv;
//using namespace cv::face;
using namespace std;

int main(int argc, const char *argv[]) {
	// Check for valid command line arguments, print usage
	// if no arguments were given.
	if (argc != 3) {
		cout << "usage: " << argv[0] << " </path/to/haar_cascade> </path/to/csv.ext> </path/to/device id>" << endl;
		cout << "\t </path/to/haar_cascade> -- Path to the Haar Cascade for face detection." << endl;
		cout << "\t <device id> -- The webcam device id to grab frames from." << endl;
		exit(1);
	}
	// Get the path to your CSV:
	string fn_haar = string(argv[1]);
	int deviceId = atoi(argv[2]);

	int im_width = 480;
	int im_height = 560;

		//Create haar cascade
	CascadeClassifier haar_cascade;
	haar_cascade.load(fn_haar);
	// Get a handle to the Video device:
	VideoCapture cap(deviceId);
	// Check if we can use this device at all:
	if(!cap.isOpened()) {
		cerr << "Capture Device ID " << deviceId << "cannot be opened." << endl;
		return -1;
	}
	// Holds the current frame from the Video device:
	Mat frame;
	for(;;) {
		cap >> frame;
		// Clone the current frame:
		Mat original = frame.clone();
		// Convert the current frame to grayscale:
		Mat gray;
		cvtColor(original, gray, CV_BGR2GRAY);
		// Find the faces in the frame:
		vector< Rect_<int> > faces;
		haar_cascade.detectMultiScale(gray, faces);
		// At this point you have the position of the faces in
		// faces. Now we'll get the faces, make a prediction and
		// annotate it in the video. Cool or what?
		for(int i = 0; i < faces.size(); i++) {
			// Process face by face:
			Rect face_i = faces[i];
			// Crop the face from the image. So simple with OpenCV C++:
			Mat face = gray(face_i);
			// Resizing the face is necessary for Eigenfaces and Fisherfaces. You can easily
			// verify this, by reading through the face recognition tutorial coming with OpenCV.
			// Resizing IS NOT NEEDED for Local Binary Patterns Histograms, so preparing the
			// input data really depends on the algorithm used.
			//
			// I strongly encourage you to play around with the algorithms. See which work best
			// in your scenario, LBPH should always be a contender for robust face recognition.
			//
			// Since I am showing the Fisherfaces algorithm here, I also show how to resize the
			// face you have just found:
			Mat face_resized;
			cv::resize(face, face_resized, Size(im_width, im_height), 1.0, 1.0, INTER_CUBIC);
			// Now perform the prediction, see how easy that is:
			// First of all draw a green rectangle around the detected face:
			rectangle(original, face_i, CV_RGB(0, 255,0), 1);
		}
		// Show the result:
		imshow("face_recognizer", original);
		// And display it:
		char key = (char) waitKey(20);
		// Exit this loop on escape:
		if(key == 27)
			break;
	}
	return 0;
}
<|endoftext|>