<commit_before>////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2005 by Andrei Alexandrescu
// Permission to use, copy, modify, distribute, and sell this software for any
//     purpose is hereby granted without fee, provided that the above copyright
//     notice appear in all copies and that both that copyright notice and this
//     permission notice appear in supporting documentation.
// The author makes no representations about the suitability of this software
//     for any purpose. It is provided "as is" without express or implied
//     warranty.
////////////////////////////////////////////////////////////////////////////////

#include "loki/SafeFormat.h"
#include <iostream>
#include <cassert>
#include <utility>

using namespace std;

template <class Integral1, class Integral2>
Integral2 RandomInt(Integral1 low, Integral2 up)
{
    // From ``Accelerated C++'', page 135:
    // random integer in the range [0, n)
    // We adjust to generate in the range [0, n]
    const Integral2
        low2 = low,
        n = up - low;

    assert(n > 0);

    const unsigned int bucket_size = RAND_MAX / n;
    assert(bucket_size > 0);

    Integral2 r;
    do r = Integral2(rand() / bucket_size);
    while (r > n);

    r += low2;
    assert(r >= low2 && r <= up);
    return r;
}

string RandomString(unsigned int maxSize)
{
    string result(RandomInt(0, maxSize), '\0');
    unsigned int i = 0;
    for (; i != result.size(); ++i) {
        result[i] = RandomInt('a', 'z');
    }
    return result;
}

template <class T>
void TestCase(const string& fmt, T value) {
    char buf[4096];
    std::string s;
    const int i1 = SPrintf(s, fmt.c_str())(value);
#ifdef _MSC_VER
    const int i2 = _snprintf(buf, sizeof(buf), fmt.c_str(), value);
#else
    const int i2 = snprintf(buf, sizeof(buf), fmt.c_str(), value);
#endif

    if (i1 != i2 || s != buf)
    {
        cout << endl
            << "Reference: " << i2 << "; Actual: " << i1 << ",  Difference = " << i2-i1 << endl
            << "V: [" << value << "]" << endl
            << "F: [" << fmt << "]" << endl
            << "R: [" << buf << "]" << endl
            << "A: [" << s.c_str() << "]" << endl;
        assert(false);
    }
}

template <class T, class U>
void TestCase2(const string& fmt, T value, U value2) {
    char buf[4096];
    std::string s;
    const int i1 = SPrintf(s, fmt.c_str())(value)(value2);
    const int i2 = snprintf(buf, sizeof(buf), fmt.c_str(), value, value2);
    assert(i1 == i2);
    assert(s == buf);
}

int main(int argc, char** argv) {
    if (argc == 3) {
        // test speed
        int i = atoi(argv[2]);
        switch (argv[1][0]) {
            case 'p':
                for (; i > 0; --i) {
                    printf("Hey, %u frobnicators and %u twiddlicators\n",
                        i, i);
                }
                break;
            case 's':
                for (; i > 0; --i) {
                    cout << "Hey, " << i << " frobnicators and " << i <<
                        " twiddlicators\n";
                }
                break;
            case 'n':
                for (; i > 0; --i) {
                    Printf("Hey, %u frobnicators and %u twiddlicators\n")
                        (i)(i);
                }
                break;
        }
        return 0;
    }

    //srand(time(0));
    srand(0);
    for (unsigned i = 0; ; ++i) {
        printf("%u\r", i);

        // Generate a random string for the head
        string lead = RandomString(100);
        // This string will hold a random format specification
        string formatSpec(lead + "|%");
        // Generate a random set of flags
        static const string flags("-+0 #");
        unsigned int maxFlags = RandomInt(0u, flags.length() - 1);
        for (unsigned int i = 0; i != maxFlags; ++i) {
            formatSpec += flags[RandomInt(0u, flags.length() - 1)];
        }
        // Generate an optional random width
        if (RandomInt(0, 1)) {
            const unsigned int width = RandomInt(0, 100);
            char buf[4];
            sprintf(buf, "%u", width);
            formatSpec += buf;
        }
        // Generate an optional random precision
        if (RandomInt(0, 1)) {
            const unsigned int prec = RandomInt(0, 100);
            char buf[4];
            sprintf(buf, "%u", prec);
            formatSpec += '.';
            formatSpec += buf;
        }
        // Generate a random type character
        static const string type("cdeEfgGinopsuxX");
        const char typeSpec = type[RandomInt(0, type.size() - 1)];
        // Generate an optional type prefix
        static const string prefix("hl");
        if (typeSpec != 's' && RandomInt(0, 1)) {
            formatSpec += prefix[RandomInt(0, prefix.size() - 1)];
        }
        formatSpec += typeSpec;
        formatSpec += '|';
        formatSpec += RandomString(100);

        switch (typeSpec) {
        case 'c':
            TestCase(formatSpec, RandomInt(1, 127));
            break;
        case 'd': case 'i': case 'o': case 'u': case 'x': case 'X':
            TestCase(formatSpec, RandomInt(-10000, 10000));
            break;
        case 'e': case 'E': case 'f': case 'g': case 'G':
            TestCase(formatSpec,
                RandomInt(-10000, 10000) / double(RandomInt(1, 100)));
            break;
        case 'n':
            break;
        case 'p':
            {
                void * p = malloc(RandomInt(1, 1000));
                TestCase(formatSpec, p);
                free(p);
            }
            break;
        case 's':
            TestCase(formatSpec, RandomString(100).c_str());
            break;
        default:
            assert(false);
            break;
        }
    }
}
<commit_msg>astyle --style=ansi<commit_after>////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2005 by Andrei Alexandrescu
// Permission to use, copy, modify, distribute, and sell this software for any
//     purpose is hereby granted without fee, provided that the above copyright
//     notice appear in all copies and that both that copyright notice and this
//     permission notice appear in supporting documentation.
// The author makes no representations about the suitability of this software
//     for any purpose. It is provided "as is" without express or implied
//     warranty.
////////////////////////////////////////////////////////////////////////////////

#include "loki/SafeFormat.h"
#include <iostream>
#include <cassert>
#include <utility>

using namespace std;

template <class Integral1, class Integral2>
Integral2 RandomInt(Integral1 low, Integral2 up)
{
    // From ``Accelerated C++'', page 135:
    // random integer in the range [0, n)
    // We adjust to generate in the range [0, n]
    const Integral2
    low2 = low,
           n = up - low;

    assert(n > 0);

    const unsigned int bucket_size = RAND_MAX / n;
    assert(bucket_size > 0);

    Integral2 r;
    do
        r = Integral2(rand() / bucket_size);
    while (r > n);

    r += low2;
    assert(r >= low2 && r <= up);
    return r;
}

string RandomString(unsigned int maxSize)
{
    string result(RandomInt(0, maxSize), '\0');
    unsigned int i = 0;
    for (; i != result.size(); ++i)
    {
        result[i] = RandomInt('a', 'z');
    }
    return result;
}

template <class T>
void TestCase(const string& fmt, T value)
{
    char buf[4096];
    std::string s;
    const int i1 = SPrintf(s, fmt.c_str())(value);

#ifdef _MSC_VER
    const int i2 = _snprintf(buf, sizeof(buf), fmt.c_str(), value);
#else
    const int i2 = snprintf(buf, sizeof(buf), fmt.c_str(), value);
#endif

    if (i1 != i2 || s != buf)
    {
        cout << endl
        << "Reference: " << i2 << "; Actual: " << i1 << ",  Difference = " << i2-i1 << endl
        << "V: [" << value << "]" << endl
        << "F: [" << fmt << "]" << endl
        << "R: [" << buf << "]" << endl
        << "A: [" << s.c_str() << "]" << endl;
        assert(false);
    }
}

template <class T, class U>
void TestCase2(const string& fmt, T value, U value2)
{
    char buf[4096];
    std::string s;
    const int i1 = SPrintf(s, fmt.c_str())(value)(value2);
    const int i2 = snprintf(buf, sizeof(buf), fmt.c_str(), value, value2);
    assert(i1 == i2);
    assert(s == buf);
}

int main(int argc, char** argv)
{
    if (argc == 3)
    {
        // test speed
        int i = atoi(argv[2]);
        switch (argv[1][0])
        {
        case 'p':
            for (; i > 0; --i)
            {
                printf("Hey, %u frobnicators and %u twiddlicators\n",
                       i, i);
            }
            break;
        case 's':
            for (; i > 0; --i)
            {
                cout << "Hey, " << i << " frobnicators and " << i <<
                " twiddlicators\n";
            }
            break;
        case 'n':
            for (; i > 0; --i)
            {
                Printf("Hey, %u frobnicators and %u twiddlicators\n")
                (i)(i);
            }
            break;
        }
        return 0;
    }

    //srand(time(0));
    srand(0);
    for (unsigned i = 0; ; ++i)
    {
        printf("%u\r", i);

        // Generate a random string for the head
        string lead = RandomString(100);
        // This string will hold a random format specification
        string formatSpec(lead + "|%");
        // Generate a random set of flags
        static const string flags("-+0 #");
        unsigned int maxFlags = RandomInt(0u, flags.length() - 1);
        for (unsigned int i = 0; i != maxFlags; ++i)
        {
            formatSpec += flags[RandomInt(0u, flags.length() - 1)];
        }
        // Generate an optional random width
        if (RandomInt(0, 1))
        {
            const unsigned int width = RandomInt(0, 100);
            char buf[4];
            sprintf(buf, "%u", width);
            formatSpec += buf;
        }
        // Generate an optional random precision
        if (RandomInt(0, 1))
        {
            const unsigned int prec = RandomInt(0, 100);
            char buf[4];
            sprintf(buf, "%u", prec);
            formatSpec += '.';
            formatSpec += buf;
        }
        // Generate a random type character
        static const string type("cdeEfgGinopsuxX");
        const char typeSpec = type[RandomInt(0, type.size() - 1)];
        // Generate an optional type prefix
        static const string prefix("hl");
        if (typeSpec != 's' && RandomInt(0, 1))
        {
            formatSpec += prefix[RandomInt(0, prefix.size() - 1)];
        }
        formatSpec += typeSpec;
        formatSpec += '|';
        formatSpec += RandomString(100);

        switch (typeSpec)
        {
        case 'c':
            TestCase(formatSpec, RandomInt(1, 127));
            break;
        case 'd':
        case 'i':
        case 'o':
        case 'u':
        case 'x':
        case 'X':
            TestCase(formatSpec, RandomInt(-10000, 10000));
            break;
        case 'e':
        case 'E':
        case 'f':
        case 'g':
        case 'G':
            TestCase(formatSpec,
                     RandomInt(-10000, 10000) / double(RandomInt(1, 100)));
            break;
        case 'n':
            break;
        case 'p':
            {
                void * p = malloc(RandomInt(1, 1000));
                TestCase(formatSpec, p);
                free(p);
            }
            break;
        case 's':
            TestCase(formatSpec, RandomString(100).c_str());
            break;
        default:
            assert(false);
            break;
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>more fixes to PassTArgByValueType; cleanup redundant obsolete sharedptr copies; and related Container cleanups<commit_after><|endoftext|>


<commit_before>#include "../lib/catch.hpp"

extern "C"
{
#include "../inc/AvlTree.h"
}

// TODO: test avl tree<commit_msg>Added unit test for AvlTree.<commit_after>#include "../lib/catch.hpp"

extern "C"
{
#include "../inc/AvlTree.h"
}

int compare(const void *a, const void *b)
{
	return (int)a - (int)b;
}

TEST_CASE("avl tree contains, delete, insert, is empty", "[inc/AvlTree.h/avlContains, inc/AvlTree.h/avlDelete, inc/AvlTree.h/avlInsert, inc/AvlTree.h/avlIsEmpty]")
{
	struct AvlTree tree;

	avlReset(&tree, &compare);
	REQUIRE(avlIsEmpty(&tree));

	for (int i = 0; i < 10; i++)
		REQUIRE(avlInsert(&tree, (void*)i));

	for (int i = 0; i < 10; i++)
		REQUIRE(avlContains(&tree, (void*)i));

	REQUIRE_FALSE(avlIsEmpty(&tree));
	REQUIRE_FALSE(avlInsert(&tree, (void*)2));
	REQUIRE_FALSE(avlContains(&tree, (void*)-1));
	REQUIRE_FALSE(avlDelete(&tree, (void*)-2));

	for (int i = 0; i < 10; i++)
		REQUIRE(avlDelete(&tree, (void*)i));

	REQUIRE(avlIsEmpty(&tree));

	for (int i = 0; i > -10; i--)
		avlInsert(&tree, (void*)i);

	avlReset(&tree, NULL);
	REQUIRE(avlIsEmpty(&tree));
}<|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS ooo19126 (1.2.224); FILE MERGED 2005/09/05 17:05:37 rt 1.2.224.1: #i54170# Change license header: remove SISSL<commit_after><|endoftext|>


<commit_before>/** \file    extract_keywords_for_translation.cc
 *  \brief   A tool for extracting keywords that need to be translated.  The keywords and any possibly pre-existing
 *           translations will be stored in a SQL database.
 *  \author  Dr. Johannes Ruscheinski
 */

/*
    Copyright (C) 2016, Library of the University of Tübingen

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

    This program 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 Affero General Public License for more details.

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

#include <iostream>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>
#include <cstdlib>
#include "Compiler.h"
#include "DbConnection.h"
#include "DbResultSet.h"
#include "DbRow.h"
#include "DirectoryEntry.h"
#include "IniFile.h"
#include "Leader.h"
#include "MarcUtil.h"
#include "StringUtil.h"
#include "Subfields.h"
#include "TranslationUtil.h"
#include "util.h"

void Usage() {
    std::cerr << "Usage: " << progname << " inferior_title_input superior_title_input norm_data_input\n";
    std::exit(EXIT_FAILURE);
}

static std::unordered_set<std::string> *shared_norm_data_control_numbers;

bool RecordKeywordControlNumbers(MarcUtil::Record * const record, XmlWriter * const /*xml_writer*/,
				 std::string * const /* err_msg */)
{
    std::vector<std::string> keyword_tags;
    StringUtil::Split("600:610:611:630:650:653:656", ':', &keyword_tags);
    const std::vector<std::string> &fields(record->getFields());
    const std::vector<DirectoryEntry> &dir_entries(record->getDirEntries());
    for (const auto &keyword_tag : keyword_tags) {
	const ssize_t start_index(record->getFieldIndex(keyword_tag));
	if (start_index == -1)
	    continue;

        for (size_t index(start_index); index < dir_entries.size() and dir_entries[index].getTag() == keyword_tag; ++index) {
            const Subfields subfields(fields[index]);
            const auto begin_end(subfields.getIterators('0'));
            for (auto subfield0(begin_end.first); subfield0 != begin_end.second; ++subfield0) {
                if (not StringUtil::StartsWith(subfield0->second, "(DE-576)"))
                    continue;

                const std::string topic_id(subfield0->second.substr(8));
		shared_norm_data_control_numbers->insert(topic_id);
            }
        }
    }

    return true;
}

void ExtractKeywordNormdataControlNumbers(File * const marc_input,
					  std::unordered_set<std::string> * const norm_data_control_numbers)
{
    const size_t orig_size(norm_data_control_numbers->size());

    shared_norm_data_control_numbers = norm_data_control_numbers;
    std::string err_msg;
    if (not MarcUtil::ProcessRecords(marc_input, RecordKeywordControlNumbers, nullptr, &err_msg))
	Error("error while extracting keyword control numbers for \"" + marc_input->getPath() + "\": " + err_msg);

    std::cerr << "Found " << (norm_data_control_numbers->size() - orig_size) << " new keyword control numbers in "
	      << marc_input->getPath() << '\n';
}

static unsigned keyword_count, translation_count;
static DbConnection *shared_connection;

bool ExtractTranslations(MarcUtil::Record * const record, XmlWriter * const /*xml_writer*/, std::string * const /* err_msg */) {
    const std::vector<std::string> &fields(record->getFields());
    if (shared_norm_data_control_numbers->find(fields[0]) == shared_norm_data_control_numbers->cend())
	return true; // Not one of the records w/ a keyword used in our title data.

    const ssize_t _150_index(record->getFieldIndex("150"));
    if (_150_index == -1)
	return true;
    const Subfields _150_subfields(fields[_150_index]);
    const std::string german_text(_150_subfields.getFirstSubfieldValue('a'));
    if (unlikely(german_text.empty()))
	return true;
    ++keyword_count;

    std::vector<std::pair<std::string, std::string>> text_and_language_codes;
    text_and_language_codes.emplace_back(std::make_pair(german_text, "deu"));

    // Find translations:
    const ssize_t first_750_index(record->getFieldIndex("750"));
    if (first_750_index != -1) {
	const std::vector<DirectoryEntry> &dir_entries(record->getDirEntries());
        for (size_t index(first_750_index); index < dir_entries.size() and dir_entries[index].getTag() == "750"; ++index) {
	    const Subfields _750_subfields(fields[index]);
	    auto start_end(_750_subfields.getIterators('9'));
	    if (start_end.first == start_end.second)
		continue;
	    std::string language_code, association;
	    for (auto code_and_value(start_end.first); code_and_value != start_end.second; ++code_and_value) {
		if (StringUtil::StartsWith(code_and_value->second, "L:"))
		    language_code = code_and_value->second.substr(2);
		else if (StringUtil::StartsWith(code_and_value->second, "Z:"))
		    association = code_and_value->second.substr(2);
	    }
	    if (not language_code.empty()) {
		++translation_count;
		text_and_language_codes.emplace_back(std::make_pair(_750_subfields.getFirstSubfieldValue('a'), language_code));
	    }
        }
    }

    // Update the database.
    const std::string id(TranslationUtil::GetId(shared_connection, german_text));
    for (const auto &text_and_language_code : text_and_language_codes) {
	const std::string REPLACE_STMT("REPLACE INTO translations SET id=" + id + ", language_code=\""
				       + text_and_language_code.second + "\", category=\"keywords\", preexists=TRUE, \", text=\""
				       + shared_connection->escapeString(text_and_language_code.first) + "\"");
	if (not shared_connection->query(REPLACE_STMT))
	    Error("Insert failed: " + REPLACE_STMT + " (" + shared_connection->getLastErrorMessage() + ")");
    }

    return true;
}

void ExtractTranslationTerms(File * const norm_data_input, DbConnection * const connection) {
    shared_connection = connection;

    std::string err_msg;
    if (not MarcUtil::ProcessRecords(norm_data_input, ExtractTranslations, nullptr, &err_msg))
	Error("error while extracting translations from \"" + norm_data_input->getPath() + "\": " + err_msg);

    std::cerr << "Added " << keyword_count << " to the translation database.\n";
    std::cerr << "Found " << translation_count << " translations in the norm data.\n";
}

const std::string CONF_FILE_PATH("/var/lib/tuelib/translations.conf");

int main(int argc, char **argv) {
    progname = argv[0];

    if (argc != 4)
        Usage();

    const std::string inferior_marc_input_filename(argv[1]);
    File inferior_marc_input(inferior_marc_input_filename, "rm");
    if (not inferior_marc_input)
        Error("can't open \"" + inferior_marc_input_filename + "\" for reading!");

    const std::string superior_marc_input_filename(argv[2]);
    File superior_marc_input(superior_marc_input_filename, "rm");
    if (not superior_marc_input)
        Error("can't open \"" + superior_marc_input_filename + "\" for reading!");

    const std::string norm_data_marc_input_filename(argv[3]);
    File norm_data_marc_input(norm_data_marc_input_filename, "rm");
    if (not norm_data_marc_input)
        Error("can't open \"" + norm_data_marc_input_filename + "\" for reading!");

    try {
	const IniFile ini_file(CONF_FILE_PATH);
	const std::string sql_database(ini_file.getString("", "sql_database"));
	const std::string sql_username(ini_file.getString("", "sql_username"));
	const std::string sql_password(ini_file.getString("", "sql_password"));
	DbConnection db_connection(sql_database, sql_username, sql_password);

	std::unordered_set<std::string> norm_data_control_numbers;
	ExtractKeywordNormdataControlNumbers(&inferior_marc_input, &norm_data_control_numbers);
	ExtractKeywordNormdataControlNumbers(&superior_marc_input, &norm_data_control_numbers);
	ExtractTranslationTerms(&norm_data_marc_input, &db_connection);
    } catch (const std::exception &x) {
	Error("caught exception: " + std::string(x.what()));
    }
}
<commit_msg>More bad SQL.<commit_after>/** \file    extract_keywords_for_translation.cc
 *  \brief   A tool for extracting keywords that need to be translated.  The keywords and any possibly pre-existing
 *           translations will be stored in a SQL database.
 *  \author  Dr. Johannes Ruscheinski
 */

/*
    Copyright (C) 2016, Library of the University of Tübingen

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

    This program 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 Affero General Public License for more details.

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

#include <iostream>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>
#include <cstdlib>
#include "Compiler.h"
#include "DbConnection.h"
#include "DbResultSet.h"
#include "DbRow.h"
#include "DirectoryEntry.h"
#include "IniFile.h"
#include "Leader.h"
#include "MarcUtil.h"
#include "StringUtil.h"
#include "Subfields.h"
#include "TranslationUtil.h"
#include "util.h"

void Usage() {
    std::cerr << "Usage: " << progname << " inferior_title_input superior_title_input norm_data_input\n";
    std::exit(EXIT_FAILURE);
}

static std::unordered_set<std::string> *shared_norm_data_control_numbers;

bool RecordKeywordControlNumbers(MarcUtil::Record * const record, XmlWriter * const /*xml_writer*/,
				 std::string * const /* err_msg */)
{
    std::vector<std::string> keyword_tags;
    StringUtil::Split("600:610:611:630:650:653:656", ':', &keyword_tags);
    const std::vector<std::string> &fields(record->getFields());
    const std::vector<DirectoryEntry> &dir_entries(record->getDirEntries());
    for (const auto &keyword_tag : keyword_tags) {
	const ssize_t start_index(record->getFieldIndex(keyword_tag));
	if (start_index == -1)
	    continue;

        for (size_t index(start_index); index < dir_entries.size() and dir_entries[index].getTag() == keyword_tag; ++index) {
            const Subfields subfields(fields[index]);
            const auto begin_end(subfields.getIterators('0'));
            for (auto subfield0(begin_end.first); subfield0 != begin_end.second; ++subfield0) {
                if (not StringUtil::StartsWith(subfield0->second, "(DE-576)"))
                    continue;

                const std::string topic_id(subfield0->second.substr(8));
		shared_norm_data_control_numbers->insert(topic_id);
            }
        }
    }

    return true;
}

void ExtractKeywordNormdataControlNumbers(File * const marc_input,
					  std::unordered_set<std::string> * const norm_data_control_numbers)
{
    const size_t orig_size(norm_data_control_numbers->size());

    shared_norm_data_control_numbers = norm_data_control_numbers;
    std::string err_msg;
    if (not MarcUtil::ProcessRecords(marc_input, RecordKeywordControlNumbers, nullptr, &err_msg))
	Error("error while extracting keyword control numbers for \"" + marc_input->getPath() + "\": " + err_msg);

    std::cerr << "Found " << (norm_data_control_numbers->size() - orig_size) << " new keyword control numbers in "
	      << marc_input->getPath() << '\n';
}

static unsigned keyword_count, translation_count;
static DbConnection *shared_connection;

bool ExtractTranslations(MarcUtil::Record * const record, XmlWriter * const /*xml_writer*/, std::string * const /* err_msg */) {
    const std::vector<std::string> &fields(record->getFields());
    if (shared_norm_data_control_numbers->find(fields[0]) == shared_norm_data_control_numbers->cend())
	return true; // Not one of the records w/ a keyword used in our title data.

    const ssize_t _150_index(record->getFieldIndex("150"));
    if (_150_index == -1)
	return true;
    const Subfields _150_subfields(fields[_150_index]);
    const std::string german_text(_150_subfields.getFirstSubfieldValue('a'));
    if (unlikely(german_text.empty()))
	return true;
    ++keyword_count;

    std::vector<std::pair<std::string, std::string>> text_and_language_codes;
    text_and_language_codes.emplace_back(std::make_pair(german_text, "deu"));

    // Find translations:
    const ssize_t first_750_index(record->getFieldIndex("750"));
    if (first_750_index != -1) {
	const std::vector<DirectoryEntry> &dir_entries(record->getDirEntries());
        for (size_t index(first_750_index); index < dir_entries.size() and dir_entries[index].getTag() == "750"; ++index) {
	    const Subfields _750_subfields(fields[index]);
	    auto start_end(_750_subfields.getIterators('9'));
	    if (start_end.first == start_end.second)
		continue;
	    std::string language_code, association;
	    for (auto code_and_value(start_end.first); code_and_value != start_end.second; ++code_and_value) {
		if (StringUtil::StartsWith(code_and_value->second, "L:"))
		    language_code = code_and_value->second.substr(2);
		else if (StringUtil::StartsWith(code_and_value->second, "Z:"))
		    association = code_and_value->second.substr(2);
	    }
	    if (not language_code.empty()) {
		++translation_count;
		text_and_language_codes.emplace_back(std::make_pair(_750_subfields.getFirstSubfieldValue('a'), language_code));
	    }
        }
    }

    // Update the database.
    const std::string id(TranslationUtil::GetId(shared_connection, german_text));
    for (const auto &text_and_language_code : text_and_language_codes) {
	const std::string REPLACE_STMT("REPLACE INTO translations SET id=" + id + ", language_code=\""
				       + text_and_language_code.second + "\", category=\"keywords\", preexists=TRUE, text=\""
				       + shared_connection->escapeString(text_and_language_code.first) + "\"");
	if (not shared_connection->query(REPLACE_STMT))
	    Error("Insert failed: " + REPLACE_STMT + " (" + shared_connection->getLastErrorMessage() + ")");
    }

    return true;
}

void ExtractTranslationTerms(File * const norm_data_input, DbConnection * const connection) {
    shared_connection = connection;

    std::string err_msg;
    if (not MarcUtil::ProcessRecords(norm_data_input, ExtractTranslations, nullptr, &err_msg))
	Error("error while extracting translations from \"" + norm_data_input->getPath() + "\": " + err_msg);

    std::cerr << "Added " << keyword_count << " to the translation database.\n";
    std::cerr << "Found " << translation_count << " translations in the norm data.\n";
}

const std::string CONF_FILE_PATH("/var/lib/tuelib/translations.conf");

int main(int argc, char **argv) {
    progname = argv[0];

    if (argc != 4)
        Usage();

    const std::string inferior_marc_input_filename(argv[1]);
    File inferior_marc_input(inferior_marc_input_filename, "rm");
    if (not inferior_marc_input)
        Error("can't open \"" + inferior_marc_input_filename + "\" for reading!");

    const std::string superior_marc_input_filename(argv[2]);
    File superior_marc_input(superior_marc_input_filename, "rm");
    if (not superior_marc_input)
        Error("can't open \"" + superior_marc_input_filename + "\" for reading!");

    const std::string norm_data_marc_input_filename(argv[3]);
    File norm_data_marc_input(norm_data_marc_input_filename, "rm");
    if (not norm_data_marc_input)
        Error("can't open \"" + norm_data_marc_input_filename + "\" for reading!");

    try {
	const IniFile ini_file(CONF_FILE_PATH);
	const std::string sql_database(ini_file.getString("", "sql_database"));
	const std::string sql_username(ini_file.getString("", "sql_username"));
	const std::string sql_password(ini_file.getString("", "sql_password"));
	DbConnection db_connection(sql_database, sql_username, sql_password);

	std::unordered_set<std::string> norm_data_control_numbers;
	ExtractKeywordNormdataControlNumbers(&inferior_marc_input, &norm_data_control_numbers);
	ExtractKeywordNormdataControlNumbers(&superior_marc_input, &norm_data_control_numbers);
	ExtractTranslationTerms(&norm_data_marc_input, &db_connection);
    } catch (const std::exception &x) {
	Error("caught exception: " + std::string(x.what()));
    }
}
<|endoftext|>


<commit_before>/*
 * File:   main.cpp
 * Author: dayler
 *
 * Created on May 4, 2015, 4:31 PM
 */

#include <cstdlib>
#include <iostream>
#include <unistd.h>
#include <time.h>
#include <pthread.h>
#include <sys/time.h>
#include <string.h>
#include <string>

#include "Utils.hpp"
#include "Runnable.hpp"
#include "SimpleRunnable.hpp"
#include "Thread.hpp"
#include "SMutex.hpp"
#include "SSynch.hpp"
#include "cqueue.hpp"
#include "timer.hpp"

using namespace std;

//pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int  counter = 0;

/* For safe condition variable usage, must use a boolean predicate and  */
/* a mutex with the condition.                                          */
int                 workToDo = 0;
//pthread_cond_t      cond  = PTHREAD_COND_INITIALIZER;
//pthread_mutex_t     m = PTHREAD_MUTEX_INITIALIZER;

const int COUNT = 5;
int shared = 0;

class Item
{
public:
    string cstr;

    Item(string cstr)
    {
        this->cstr = cstr;
    }

    virtual ~Item()
    {
        // No op
    }
};

Queue<Item>* items;

#define NTHREADS                100
#define WAIT_TIME_SECONDS       15

class SchTask : public Runnable
{
public:
    SchTask(int id)
    {
        this->id = id;
    }

    void* run()
    {
        printf("Hola!!! ID:%d\n", id);
        return reinterpret_cast<void*>(id);
    }
private:
    int id;
};

int main()
{
    cout<<"start..."<<endl;

    Runnable* r1 = new SchTask(10);
    Timer* t1 = new Timer("timer-1");

    t1->scheduleAt(r1, 5000);
    long rc = reinterpret_cast<long>(t1->join());

    cout<<"RESP:"<<rc<<endl;

    delete r1;
    delete t1;

    cout<<"end.."<<endl;
    return 0;
}

/**
 * Producer and consumer.
 */
//// Produccer
//class TH1 : public Runnable
//{
//public:
//    int id;
//
//    TH1(int id)
//    {
//        this->id = id;
//    }
//
//    ~TH1()
//    {
//        // No op
//    }
//
//    bool isRunning()
//    {
//        return shared < COUNT;
//    }
//
//    void* run()
//    {
//        while (isRunning())
//        {
//            printf("AAAA 1\n");
//            string sshared = SSTR(shared);
//            printf("AAAA 2\n");
//            sleep(3);
//            printf("AAAA 3\n");
//            items->push(new Item(sshared));
//            printf("THID:%d Pushed %s\n", id, sshared.c_str());
//            shared++;
//        }
//        return reinterpret_cast<void*>(id);
//    }
//};
//
//// Consummer
//class TH2 : public Runnable
//{
//public:
//    int id;
//
//    TH2(int id)
//    {
//        this->id = id;
//    }
//
//    ~TH2()
//    {
//        // No op
//    }
//
//    bool isRunning()
//    {
//        // If shred is less than MAX or items is not empty.
//        return shared < COUNT || !items->empty();
//    }
//
//    void* run()
//    {
//        while (isRunning())
//        {
//            printf("BBBB\n");
//            sleep(1);
//            Item* val = items->waitAndPop();
//            printf("THID:%d q->waitAndPop() = %s\n", id, val->cstr.c_str());
//            delete val;
//        }
//        return reinterpret_cast<void*>(id);
//    }
//};
//
//int main()
//{
//    cout<<"Start main..."<<endl;
//    items = new Queue<Item>();
//
//    printf("Init runnables.\n");
//    Runnable* r1 = new TH1(111);
//    Runnable* r2 = new TH2(222);
//    Runnable* r3 = new TH2(333);
//
//    Thread* t1 = new Thread(r1, false);
//    Thread* t2 = new Thread(r2, false);
//    Thread* t3 = new Thread(r3, false);
//
//    // Start thread
//    printf("Starting threads...\n");
//    t2->start(); // Consumer
//    t1->start(); // Producer
//    t3->start(); // Consumer
//    printf("Was started threads joining ...\n");
//
//    // Joining threads
//    long res1 = reinterpret_cast<long>(t1->join()); // Producer
//    cout<<"Result t1 = "<<res1<<endl;
//    long res2 = reinterpret_cast<long>(t2->join()); // Consumer
//    cout<<"Result t2 = "<<res2<<endl;
//    long res3 = reinterpret_cast<long>(t3->join()); // Consumer
//    cout<<"Result t2 = "<<res3<<endl;
//
//    // delete
//    delete r1;
//    delete r2;
//    delete r3;
//    delete t1;
//    delete t2;
//    delete t3;
//    delete items;
//
//    cout<<"Finish well main..."<<endl;
//    return 0;
//}

/**
 * Threads basic
 */
//void* functionC(void* arg)
//{
//   CMutex m(&mutex1);
//   // pthread_mutex_lock( &mutex1 );
//   counter++;
//   printf("Counter value: %d\n",counter);
//   // pthread_mutex_unlock( &mutex1 );
//}
//
//int main()
//{
//   int rc1, rc2;
//   pthread_t thread1, thread2;
//
//   // Create independent threads each of which will execute functionC /
//
//   if( (rc1=pthread_create( &thread1, NULL, &functionC, NULL)) )
//   {
//      printf("Thread creation failed: %d\n", rc1);
//   }
//
//   if( (rc2=pthread_create( &thread2, NULL, &functionC, NULL)) )
//   {
//      printf("Thread creation failed: %d\n", rc2);
//   }
//
//   // Wait till threads are complete before main continues. Unless we  /
//   // wait we run the risk of executing an exit which will terminate   /
//   // the process and all threads before the threads have completed.   /
//
//   pthread_join( thread1, NULL);
//   pthread_join( thread2, NULL);
//
//   exit(0);
//}

//int main() {
//    cout<<"Begin main test class..."<<endl;
//
//    Runnable* r1 = new SimpleRunnable(1, 3);
//    Runnable* r2 = new SimpleRunnable(2, 8);
//
//    Thread* t1 = new Thread(r1, false);
//    Thread* t2 = new Thread(r2, false);
//
//    // Start threads
//    t1->start();
//    t2->start();
//
//    // Join threads
//    long res1 = reinterpret_cast<long>(t1->join());
//    long res2 = reinterpret_cast<long>(t2->join());
//
//    cout<<"Result t1 = "<<res1<<endl;
//    cout<<"Result t2 = "<<res2<<endl;
//
//    // Delete objects
//    delete r1;
//    delete t1;
//
//    delete r2;
//    delete t2;
//
//    cout<<"Finish main test class..."<<endl;
//    return 0;
//}

<commit_msg>Make example for scheduled task.<commit_after>/*
 * File:   main.cpp
 * Author: dayler
 *
 * Created on May 4, 2015, 4:31 PM
 */

#include <cstdlib>
#include <iostream>
#include <unistd.h>
#include <time.h>
#include <pthread.h>
#include <sys/time.h>
#include <string.h>
#include <string>

#include "Utils.hpp"
#include "Runnable.hpp"
#include "SimpleRunnable.hpp"
#include "Thread.hpp"
#include "SMutex.hpp"
#include "SSynch.hpp"
#include "cqueue.hpp"
#include "timer.hpp"

using namespace std;

//pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int  counter = 0;

/* For safe condition variable usage, must use a boolean predicate and  */
/* a mutex with the condition.                                          */
int                 workToDo = 0;
//pthread_cond_t      cond  = PTHREAD_COND_INITIALIZER;
//pthread_mutex_t     m = PTHREAD_MUTEX_INITIALIZER;

const int COUNT = 5;
int shared = 0;

class Item
{
public:
    string cstr;

    Item(string cstr)
    {
        this->cstr = cstr;
    }

    virtual ~Item()
    {
        // No op
    }
};

Queue<Item>* items;

#define NTHREADS                100
#define WAIT_TIME_SECONDS       15

class SchTask : public Runnable
{
public:
    SchTask(int id)
    {
        this->id = id;
    }

    void* run()
    {
        printf("Hola!!! ID:%d\n", id);
        return reinterpret_cast<void*>(id);
    }
private:
    int id;
};

int main()
{
    cout<<"start..."<<endl;

    Runnable* r1 = new SchTask(10);
    Timer* t1 = new Timer("timer-1");

    t1->scheduleAtFixedRate(r1, 5000, 2000);
    long rc = reinterpret_cast<long>(t1->join());

    cout<<"RESP:"<<rc<<endl;

    delete r1;
    delete t1;

    cout<<"end.."<<endl;
    return 0;
}

/**
 * Producer and consumer.
 */
//// Produccer
//class TH1 : public Runnable
//{
//public:
//    int id;
//
//    TH1(int id)
//    {
//        this->id = id;
//    }
//
//    ~TH1()
//    {
//        // No op
//    }
//
//    bool isRunning()
//    {
//        return shared < COUNT;
//    }
//
//    void* run()
//    {
//        while (isRunning())
//        {
//            printf("AAAA 1\n");
//            string sshared = SSTR(shared);
//            printf("AAAA 2\n");
//            sleep(3);
//            printf("AAAA 3\n");
//            items->push(new Item(sshared));
//            printf("THID:%d Pushed %s\n", id, sshared.c_str());
//            shared++;
//        }
//        return reinterpret_cast<void*>(id);
//    }
//};
//
//// Consummer
//class TH2 : public Runnable
//{
//public:
//    int id;
//
//    TH2(int id)
//    {
//        this->id = id;
//    }
//
//    ~TH2()
//    {
//        // No op
//    }
//
//    bool isRunning()
//    {
//        // If shred is less than MAX or items is not empty.
//        return shared < COUNT || !items->empty();
//    }
//
//    void* run()
//    {
//        while (isRunning())
//        {
//            printf("BBBB\n");
//            sleep(1);
//            Item* val = items->waitAndPop();
//            printf("THID:%d q->waitAndPop() = %s\n", id, val->cstr.c_str());
//            delete val;
//        }
//        return reinterpret_cast<void*>(id);
//    }
//};
//
//int main()
//{
//    cout<<"Start main..."<<endl;
//    items = new Queue<Item>();
//
//    printf("Init runnables.\n");
//    Runnable* r1 = new TH1(111);
//    Runnable* r2 = new TH2(222);
//    Runnable* r3 = new TH2(333);
//
//    Thread* t1 = new Thread(r1, false);
//    Thread* t2 = new Thread(r2, false);
//    Thread* t3 = new Thread(r3, false);
//
//    // Start thread
//    printf("Starting threads...\n");
//    t2->start(); // Consumer
//    t1->start(); // Producer
//    t3->start(); // Consumer
//    printf("Was started threads joining ...\n");
//
//    // Joining threads
//    long res1 = reinterpret_cast<long>(t1->join()); // Producer
//    cout<<"Result t1 = "<<res1<<endl;
//    long res2 = reinterpret_cast<long>(t2->join()); // Consumer
//    cout<<"Result t2 = "<<res2<<endl;
//    long res3 = reinterpret_cast<long>(t3->join()); // Consumer
//    cout<<"Result t2 = "<<res3<<endl;
//
//    // delete
//    delete r1;
//    delete r2;
//    delete r3;
//    delete t1;
//    delete t2;
//    delete t3;
//    delete items;
//
//    cout<<"Finish well main..."<<endl;
//    return 0;
//}

/**
 * Threads basic
 */
//void* functionC(void* arg)
//{
//   CMutex m(&mutex1);
//   // pthread_mutex_lock( &mutex1 );
//   counter++;
//   printf("Counter value: %d\n",counter);
//   // pthread_mutex_unlock( &mutex1 );
//}
//
//int main()
//{
//   int rc1, rc2;
//   pthread_t thread1, thread2;
//
//   // Create independent threads each of which will execute functionC /
//
//   if( (rc1=pthread_create( &thread1, NULL, &functionC, NULL)) )
//   {
//      printf("Thread creation failed: %d\n", rc1);
//   }
//
//   if( (rc2=pthread_create( &thread2, NULL, &functionC, NULL)) )
//   {
//      printf("Thread creation failed: %d\n", rc2);
//   }
//
//   // Wait till threads are complete before main continues. Unless we  /
//   // wait we run the risk of executing an exit which will terminate   /
//   // the process and all threads before the threads have completed.   /
//
//   pthread_join( thread1, NULL);
//   pthread_join( thread2, NULL);
//
//   exit(0);
//}

//int main() {
//    cout<<"Begin main test class..."<<endl;
//
//    Runnable* r1 = new SimpleRunnable(1, 3);
//    Runnable* r2 = new SimpleRunnable(2, 8);
//
//    Thread* t1 = new Thread(r1, false);
//    Thread* t2 = new Thread(r2, false);
//
//    // Start threads
//    t1->start();
//    t2->start();
//
//    // Join threads
//    long res1 = reinterpret_cast<long>(t1->join());
//    long res2 = reinterpret_cast<long>(t2->join());
//
//    cout<<"Result t1 = "<<res1<<endl;
//    cout<<"Result t2 = "<<res2<<endl;
//
//    // Delete objects
//    delete r1;
//    delete t1;
//
//    delete r2;
//    delete t2;
//
//    cout<<"Finish main test class..."<<endl;
//    return 0;
//}

<|endoftext|>


<commit_before>#include "doctest.h"

#include "header.h"

DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
#include <string>
#include <vector>
#include <list>
#include <sstream>
DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END

// the standard forbids writing in the std namespace but it works on all compilers
namespace std
{
template <typename T>
ostream& operator<<(ostream& stream, const vector<T>& in) {
    stream << "[";
    for(size_t i = 0; i < in.size(); ++i)
        if(i < in.size() - 1)
            stream << in[i] << ", ";
        else
            stream << in[i];
    stream << "]";
    return stream;
}
}

// as an alternative you may write a specialization of doctest::StringMaker
namespace doctest
{
template <typename T>
struct StringMaker<std::list<T> >
{
    static String convert(const std::list<T>& in) {
        std::ostringstream oss;

        oss << "[";
        for(typename std::list<T>::const_iterator it = in.begin(); it != in.end(); ++it)
            oss << *it << ", ";
        oss << "]";

        return oss.str().c_str();
    }
};
}

template <typename T, typename K>
struct MyType
{
    T one;
    K two;
};

template <typename T>
struct MyTypeInherited : MyType<T, float>
{};

template <typename T, typename K>
bool operator==(const MyType<T, K>& lhs, const MyType<T, K>& rhs) {
    return lhs.one == rhs.one && lhs.two == rhs.two;
}

template <typename T, typename K>
std::ostream& operator<<(std::ostream& stream, const MyType<T, K>& in) {
    stream << "[" << in.one << ", " << in.two << "]";
    return stream;
}

namespace Bar
{
struct Foo
{
    friend bool operator==(const Foo&, const Foo&) { return false; }
};

// as a third option you may provide an overload of toString()
inline doctest::String toString(const Foo&) { return "Foo{}"; }
} // namespace Bar

// set an exception translator for MyTypeInherited<int>
REGISTER_EXCEPTION_TRANSLATOR(MyTypeInherited<int>& ex) {
    return doctest::String("MyTypeInherited<int>(") + doctest::toString(ex.one) + ", " +
           doctest::toString(ex.two) + ")";
}

TEST_CASE("all asserts should fail and show how the objects get stringified") {
    MyTypeInherited<int> bla1;
    bla1.one = 5;
    bla1.two = 4.0f;
    MyTypeInherited<int> bla2;
    bla2.one = 5;
    bla2.two = 6.0f;

    Bar::Foo f1;
    Bar::Foo f2;
    CHECK(f1 == f2);

    // std::string already has an operator<< working with std::ostream
    std::string dummy1 = "omg";
    std::string dummy2 = "tralala";

    CHECK(dummy1 == dummy2);

    std::vector<int> vec1;
    vec1.push_back(1);
    vec1.push_back(2);
    vec1.push_back(3);

    std::vector<int> vec2;
    vec2.push_back(1);
    vec2.push_back(2);
    vec2.push_back(4);

    CHECK(vec1 == vec2);

    std::list<int> lst_1;
    lst_1.push_back(1);
    lst_1.push_back(42);
    lst_1.push_back(3);

    std::list<int> lst_2;
    lst_2.push_back(1);
    lst_2.push_back(2);
    lst_2.push_back(666);

    CHECK(lst_1 == lst_2);

    // lets see if this exception gets translated
    throw_if(true, bla1);
}

static doctest::String intTranslator(int ex) {
    return doctest::String("int: ") + doctest::toString(ex);
}

TEST_CASE("a test case that registers an exception translator for int and then throws one") {
    // set an exception translator for int - note that this shouldn't be done in a test case but
    // in main() or somewhere before executing the tests - but here I'm just lazy...
    doctest::registerExceptionTranslator(intTranslator);

    throw_if(true, 5);
}
<commit_msg>silencing 1 more warning for VS 2008/2010 when using /Wall - that a float was getting stored in memory and not in a register... relates #95<commit_after>#include "doctest.h"

#include "header.h"

DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
#include <string>
#include <vector>
#include <list>
#include <sstream>
DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END

// the standard forbids writing in the std namespace but it works on all compilers
namespace std
{
template <typename T>
ostream& operator<<(ostream& stream, const vector<T>& in) {
    stream << "[";
    for(size_t i = 0; i < in.size(); ++i)
        if(i < in.size() - 1)
            stream << in[i] << ", ";
        else
            stream << in[i];
    stream << "]";
    return stream;
}
}

// as an alternative you may write a specialization of doctest::StringMaker
namespace doctest
{
template <typename T>
struct StringMaker<std::list<T> >
{
    static String convert(const std::list<T>& in) {
        std::ostringstream oss;

        oss << "[";
        for(typename std::list<T>::const_iterator it = in.begin(); it != in.end(); ++it)
            oss << *it << ", ";
        oss << "]";

        return oss.str().c_str();
    }
};
}

template <typename T, typename K>
struct MyType
{
    T one;
    K two;
};

template <typename T>
struct MyTypeInherited : MyType<T, unsigned>
{};

template <typename T, typename K>
bool operator==(const MyType<T, K>& lhs, const MyType<T, K>& rhs) {
    return lhs.one == rhs.one && lhs.two == rhs.two;
}

template <typename T, typename K>
std::ostream& operator<<(std::ostream& stream, const MyType<T, K>& in) {
    stream << "[" << in.one << ", " << in.two << "]";
    return stream;
}

namespace Bar
{
struct Foo
{
    friend bool operator==(const Foo&, const Foo&) { return false; }
};

// as a third option you may provide an overload of toString()
inline doctest::String toString(const Foo&) { return "Foo{}"; }
} // namespace Bar

// set an exception translator for MyTypeInherited<int>
REGISTER_EXCEPTION_TRANSLATOR(MyTypeInherited<int>& ex) {
    return doctest::String("MyTypeInherited<int>(") + doctest::toString(ex.one) + ", " +
           doctest::toString(ex.two) + ")";
}

TEST_CASE("all asserts should fail and show how the objects get stringified") {
    MyTypeInherited<int> bla1;
    bla1.one = 5;
    bla1.two = 4u;
    MyTypeInherited<int> bla2;
    bla2.one = 5;
    bla2.two = 6u;

    Bar::Foo f1;
    Bar::Foo f2;
    CHECK(f1 == f2);

    // std::string already has an operator<< working with std::ostream
    std::string dummy1 = "omg";
    std::string dummy2 = "tralala";

    CHECK(dummy1 == dummy2);

    std::vector<int> vec1;
    vec1.push_back(1);
    vec1.push_back(2);
    vec1.push_back(3);

    std::vector<int> vec2;
    vec2.push_back(1);
    vec2.push_back(2);
    vec2.push_back(4);

    CHECK(vec1 == vec2);

    std::list<int> lst_1;
    lst_1.push_back(1);
    lst_1.push_back(42);
    lst_1.push_back(3);

    std::list<int> lst_2;
    lst_2.push_back(1);
    lst_2.push_back(2);
    lst_2.push_back(666);

    CHECK(lst_1 == lst_2);

    // lets see if this exception gets translated
    throw_if(true, bla1);
}

static doctest::String intTranslator(int ex) {
    return doctest::String("int: ") + doctest::toString(ex);
}

TEST_CASE("a test case that registers an exception translator for int and then throws one") {
    // set an exception translator for int - note that this shouldn't be done in a test case but
    // in main() or somewhere before executing the tests - but here I'm just lazy...
    doctest::registerExceptionTranslator(intTranslator);

    throw_if(true, 5);
}
<|endoftext|>


<commit_before>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "reconfigurable_stateserver.h"
#include "sbenv.h"
#include "remote_check.h"
#include <vespa/vespalib/util/host_name.h>
#include <vespa/vespalib/util/exceptions.h>
#include <vespa/vespalib/stllike/asciistream.h>
#include <vespa/fnet/frt/supervisor.h>
#include <vespa/fnet/transport.h>
#include <vespa/config/helper/configfetcher.h>
#include <thread>
#include <sstream>

#include <vespa/log/log.h>
LOG_SETUP(".slobrok.server.sbenv");

using namespace std::chrono_literals;

namespace slobrok {

namespace {

std::string
createSpec(int port)
{
    if (port == 0) {
        return std::string();
    }
    std::ostringstream str;
    str << "tcp/";
    str << vespalib::HostName::get();
    str << ":";
    str << port;
    return str.str();
}

void
discard(std::vector<std::string> &vec, const std::string & val)
{
    uint32_t i = 0;
    uint32_t size = vec.size();
    while (i < size) {
        if (vec[i] == val) {
            std::swap(vec[i], vec[size - 1]);
            vec.pop_back();
            --size;
        } else {
            ++i;
        }
    }
    LOG_ASSERT(size == vec.size());
}

class ConfigTask : public FNET_Task
{
private:
    Configurator& _configurator;

    ConfigTask(const ConfigTask &);
    ConfigTask &operator=(const ConfigTask &);
public:
    ConfigTask(FNET_Scheduler *sched, Configurator& configurator);

    ~ConfigTask();
    void PerformTask() override;
};

ConfigTask::ConfigTask(FNET_Scheduler *sched, Configurator& configurator)
    : FNET_Task(sched),
      _configurator(configurator)
{
    Schedule(1.0);
}

ConfigTask::~ConfigTask()
{
    Kill();
}

void
ConfigTask::PerformTask()
{
    Schedule(1.0);
    LOG(spam, "checking for new config");
    try {
        _configurator.poll();
    } catch (std::exception &e) {
        LOG(warning, "ConfigTask: poll failed: %s", e.what());
        Schedule(10.0);
    }
}

} // namespace slobrok::<unnamed>

SBEnv::SBEnv(const ConfigShim &shim)
    : _transport(std::make_unique<FNET_Transport>(TransportConfig().drop_empty_buffers(true))),
      _supervisor(std::make_unique<FRT_Supervisor>(_transport.get())),
      _configShim(shim),
      _configurator(shim.factory().create(*this)),
      _shuttingDown(false),
      _partnerList(),
      _me(createSpec(_configShim.portNumber())),
      _rpcHooks(*this, _rpcsrvmap, _rpcsrvmanager),
      _remotechecktask(std::make_unique<RemoteCheck>(getSupervisor()->GetScheduler(), _rpcsrvmap, _rpcsrvmanager, _exchanger)),
      _health(),
      _metrics(_rpcHooks, *_transport),
      _components(),
      _localRpcMonitorMap(*_supervisor),
      _rpcsrvmanager(*this),
      _exchanger(*this, _rpcsrvmap),
      _rpcsrvmap()
{
    srandom(time(nullptr) ^ getpid());
    _localMonitorSubscription = MapSubscription::subscribe(_rpcsrvmap.proxy(), _localRpcMonitorMap);
    _consensusSubscription = MapSubscription::subscribe(_localRpcMonitorMap.dispatcher(), _consensusMap);
    // TODO: use consensus as source here:
    _globalHistorySubscription = MapSubscription::subscribe(_rpcsrvmap.proxy(), _globalVisibleHistory);
    _rpcHooks.initRPC(getSupervisor());
}

SBEnv::~SBEnv() = default;

FNET_Scheduler *
SBEnv::getScheduler() {
    return _transport->GetScheduler();
}

void
SBEnv::shutdown()
{
    _shuttingDown = true;
    getTransport()->ShutDown(false);
}

void
SBEnv::resume()
{
    // nop
}

namespace {

vespalib::string
toString(const std::vector<std::string> & v) {
    vespalib::asciistream os;
    os << "[" << '\n';
    for (const std::string & partner : v) {
        os << "    " << partner << '\n';
    }
    os << ']';
    return os.str();
}

} // namespace <unnamed>

int
SBEnv::MainLoop()
{
    if (! getSupervisor()->Listen(_configShim.portNumber())) {
        LOG(error, "unable to listen to port %d", _configShim.portNumber());
        EV_STOPPING("slobrok", "could not listen");
        return 1;
    } else {
        LOG(config, "listening on port %d", _configShim.portNumber());
    }

    std::unique_ptr<ReconfigurableStateServer> stateServer;
    if (_configShim.enableStateServer()) {
        stateServer = std::make_unique<ReconfigurableStateServer>(_configShim.configId(), _health, _metrics, _components);
    }

    try {
        _configurator->poll();
        ConfigTask configTask(getScheduler(), *_configurator);
        LOG(debug, "slobrok: starting main event loop");
        EV_STARTED("slobrok");
        getTransport()->Main();
        LOG(debug, "slobrok: main event loop done");
    } catch (vespalib::Exception &e) {
        LOG(error, "invalid config: %s", e.what());
        EV_STOPPING("slobrok", "invalid config");
        return 1;
    } catch (std::exception &e) {
        LOG(error, "Unexpected std::exception : %s", e.what());
        EV_STOPPING("slobrok", "Unexpected std::exception");
        return 1;
    }
    EV_STOPPING("slobrok", "clean shutdown");
    return 0;
}

void
SBEnv::setup(const std::vector<std::string> &cfg)
{
    _partnerList = cfg;
    std::vector<std::string> oldList = _exchanger.getPartnerList();
    LOG(debug, "(re-)configuring. oldlist size %d, configuration list size %d",
        (int)oldList.size(),
        (int)cfg.size());
    for (uint32_t i = 0; i < cfg.size(); ++i) {
        std::string slobrok = cfg[i];
        discard(oldList, slobrok);
        if (slobrok != mySpec()) {
            OkState res = _rpcsrvmanager.addPeer(slobrok, slobrok.c_str());
            if (!res.ok()) {
                LOG(warning, "could not add peer %s: %s", slobrok.c_str(), res.errorMsg.c_str());
            } else {
                LOG(config, "added peer %s", slobrok.c_str());
            }
        }
    }
    for (uint32_t i = 0; i < oldList.size(); ++i) {
        OkState res = _rpcsrvmanager.removePeer(oldList[i], oldList[i].c_str());
        if (!res.ok()) {
            LOG(warning, "could not remove peer %s: %s", oldList[i].c_str(), res.errorMsg.c_str());
        } else {
            LOG(config, "removed peer %s", oldList[i].c_str());
        }
    }
    int64_t curGen = _configurator->getGeneration();
    vespalib::ComponentConfigProducer::Config current("slobroks", curGen, "ok");
    _components.addConfig(current);
}

OkState
SBEnv::addPeer(const std::string &name, const std::string &spec)
{
    if (spec == mySpec()) {
        return OkState(FRTE_RPC_METHOD_FAILED, "cannot add my own spec as peer");
    }
    if (_partnerList.size() != 0) {
        for (const std::string & partner : _partnerList) {
            if (partner == spec) {
                return OkState(0, "already configured with peer");
            }
        }
        vespalib::string peers = toString(_partnerList);
        LOG(warning, "got addPeer with non-configured peer %s, check config consistency. configured peers = %s",
                     spec.c_str(), peers.c_str());
        _partnerList.push_back(spec);
    }
    return _rpcsrvmanager.addPeer(name, spec.c_str());
}

OkState
SBEnv::removePeer(const std::string &name, const std::string &spec)
{
    if (spec == mySpec()) {
        return OkState(FRTE_RPC_METHOD_FAILED, "cannot remove my own spec as peer");
    }
    for (const std::string & partner : _partnerList) {
        if (partner == spec) {
            return OkState(FRTE_RPC_METHOD_FAILED, "configured partner list contains peer, cannot remove");
        }
    }
    return _rpcsrvmanager.removePeer(name, spec.c_str());
}

} // namespace slobrok
<commit_msg>stop listening to events from the old RpcServerMap, make feedback loop instead<commit_after>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "reconfigurable_stateserver.h"
#include "sbenv.h"
#include "remote_check.h"
#include <vespa/vespalib/util/host_name.h>
#include <vespa/vespalib/util/exceptions.h>
#include <vespa/vespalib/stllike/asciistream.h>
#include <vespa/fnet/frt/supervisor.h>
#include <vespa/fnet/transport.h>
#include <vespa/config/helper/configfetcher.h>
#include <thread>
#include <sstream>

#include <vespa/log/log.h>
LOG_SETUP(".slobrok.server.sbenv");

using namespace std::chrono_literals;

namespace slobrok {

namespace {

std::string
createSpec(int port)
{
    if (port == 0) {
        return std::string();
    }
    std::ostringstream str;
    str << "tcp/";
    str << vespalib::HostName::get();
    str << ":";
    str << port;
    return str.str();
}

void
discard(std::vector<std::string> &vec, const std::string & val)
{
    uint32_t i = 0;
    uint32_t size = vec.size();
    while (i < size) {
        if (vec[i] == val) {
            std::swap(vec[i], vec[size - 1]);
            vec.pop_back();
            --size;
        } else {
            ++i;
        }
    }
    LOG_ASSERT(size == vec.size());
}

class ConfigTask : public FNET_Task
{
private:
    Configurator& _configurator;

    ConfigTask(const ConfigTask &);
    ConfigTask &operator=(const ConfigTask &);
public:
    ConfigTask(FNET_Scheduler *sched, Configurator& configurator);

    ~ConfigTask();
    void PerformTask() override;
};

ConfigTask::ConfigTask(FNET_Scheduler *sched, Configurator& configurator)
    : FNET_Task(sched),
      _configurator(configurator)
{
    Schedule(1.0);
}

ConfigTask::~ConfigTask()
{
    Kill();
}

void
ConfigTask::PerformTask()
{
    Schedule(1.0);
    LOG(spam, "checking for new config");
    try {
        _configurator.poll();
    } catch (std::exception &e) {
        LOG(warning, "ConfigTask: poll failed: %s", e.what());
        Schedule(10.0);
    }
}

} // namespace slobrok::<unnamed>

SBEnv::SBEnv(const ConfigShim &shim)
    : _transport(std::make_unique<FNET_Transport>(TransportConfig().drop_empty_buffers(true))),
      _supervisor(std::make_unique<FRT_Supervisor>(_transport.get())),
      _configShim(shim),
      _configurator(shim.factory().create(*this)),
      _shuttingDown(false),
      _partnerList(),
      _me(createSpec(_configShim.portNumber())),
      _rpcHooks(*this, _rpcsrvmap, _rpcsrvmanager),
      _remotechecktask(std::make_unique<RemoteCheck>(getSupervisor()->GetScheduler(), _rpcsrvmap, _rpcsrvmanager, _exchanger)),
      _health(),
      _metrics(_rpcHooks, *_transport),
      _components(),
      _localRpcMonitorMap(*_supervisor),
      _rpcsrvmanager(*this),
      _exchanger(*this, _rpcsrvmap),
      _rpcsrvmap()
{
    srandom(time(nullptr) ^ getpid());
    // note: feedback loop between these two:
    _localMonitorSubscription = MapSubscription::subscribe(_consensusMap, _localRpcMonitorMap);
    _consensusSubscription = MapSubscription::subscribe(_localRpcMonitorMap.dispatcher(), _consensusMap);
    // TODO: use consensus as source here:
    _globalHistorySubscription = MapSubscription::subscribe(_rpcsrvmap.proxy(), _globalVisibleHistory);
    _rpcHooks.initRPC(getSupervisor());
}

SBEnv::~SBEnv() = default;

FNET_Scheduler *
SBEnv::getScheduler() {
    return _transport->GetScheduler();
}

void
SBEnv::shutdown()
{
    _shuttingDown = true;
    getTransport()->ShutDown(false);
}

void
SBEnv::resume()
{
    // nop
}

namespace {

vespalib::string
toString(const std::vector<std::string> & v) {
    vespalib::asciistream os;
    os << "[" << '\n';
    for (const std::string & partner : v) {
        os << "    " << partner << '\n';
    }
    os << ']';
    return os.str();
}

} // namespace <unnamed>

int
SBEnv::MainLoop()
{
    if (! getSupervisor()->Listen(_configShim.portNumber())) {
        LOG(error, "unable to listen to port %d", _configShim.portNumber());
        EV_STOPPING("slobrok", "could not listen");
        return 1;
    } else {
        LOG(config, "listening on port %d", _configShim.portNumber());
    }

    std::unique_ptr<ReconfigurableStateServer> stateServer;
    if (_configShim.enableStateServer()) {
        stateServer = std::make_unique<ReconfigurableStateServer>(_configShim.configId(), _health, _metrics, _components);
    }

    try {
        _configurator->poll();
        ConfigTask configTask(getScheduler(), *_configurator);
        LOG(debug, "slobrok: starting main event loop");
        EV_STARTED("slobrok");
        getTransport()->Main();
        LOG(debug, "slobrok: main event loop done");
    } catch (vespalib::Exception &e) {
        LOG(error, "invalid config: %s", e.what());
        EV_STOPPING("slobrok", "invalid config");
        return 1;
    } catch (std::exception &e) {
        LOG(error, "Unexpected std::exception : %s", e.what());
        EV_STOPPING("slobrok", "Unexpected std::exception");
        return 1;
    }
    EV_STOPPING("slobrok", "clean shutdown");
    return 0;
}

void
SBEnv::setup(const std::vector<std::string> &cfg)
{
    _partnerList = cfg;
    std::vector<std::string> oldList = _exchanger.getPartnerList();
    LOG(debug, "(re-)configuring. oldlist size %d, configuration list size %d",
        (int)oldList.size(),
        (int)cfg.size());
    for (uint32_t i = 0; i < cfg.size(); ++i) {
        std::string slobrok = cfg[i];
        discard(oldList, slobrok);
        if (slobrok != mySpec()) {
            OkState res = _rpcsrvmanager.addPeer(slobrok, slobrok.c_str());
            if (!res.ok()) {
                LOG(warning, "could not add peer %s: %s", slobrok.c_str(), res.errorMsg.c_str());
            } else {
                LOG(config, "added peer %s", slobrok.c_str());
            }
        }
    }
    for (uint32_t i = 0; i < oldList.size(); ++i) {
        OkState res = _rpcsrvmanager.removePeer(oldList[i], oldList[i].c_str());
        if (!res.ok()) {
            LOG(warning, "could not remove peer %s: %s", oldList[i].c_str(), res.errorMsg.c_str());
        } else {
            LOG(config, "removed peer %s", oldList[i].c_str());
        }
    }
    int64_t curGen = _configurator->getGeneration();
    vespalib::ComponentConfigProducer::Config current("slobroks", curGen, "ok");
    _components.addConfig(current);
}

OkState
SBEnv::addPeer(const std::string &name, const std::string &spec)
{
    if (spec == mySpec()) {
        return OkState(FRTE_RPC_METHOD_FAILED, "cannot add my own spec as peer");
    }
    if (_partnerList.size() != 0) {
        for (const std::string & partner : _partnerList) {
            if (partner == spec) {
                return OkState(0, "already configured with peer");
            }
        }
        vespalib::string peers = toString(_partnerList);
        LOG(warning, "got addPeer with non-configured peer %s, check config consistency. configured peers = %s",
                     spec.c_str(), peers.c_str());
        _partnerList.push_back(spec);
    }
    return _rpcsrvmanager.addPeer(name, spec.c_str());
}

OkState
SBEnv::removePeer(const std::string &name, const std::string &spec)
{
    if (spec == mySpec()) {
        return OkState(FRTE_RPC_METHOD_FAILED, "cannot remove my own spec as peer");
    }
    for (const std::string & partner : _partnerList) {
        if (partner == spec) {
            return OkState(FRTE_RPC_METHOD_FAILED, "configured partner list contains peer, cannot remove");
        }
    }
    return _rpcsrvmanager.removePeer(name, spec.c_str());
}

} // namespace slobrok
<|endoftext|>


<commit_before>/* Async FRPC client.
 * The MIT License (MIT)
 * Copyright (c) 2014 Jan Cermak
 */

#include "frpcdata.h"
#include <frpcmarshaller.h>
#include <frpcwriter.h>
#include <frpcunmarshaller.h>
#include <frpctreefeeder.h>
#include <frpctreebuilder.h>
#include <string.h>
#include <cstdarg>

namespace {

class StringWriter: public FRPC::Writer_t {
    std::string data;
  public:
    StringWriter() {}
    virtual void write(const char *data, unsigned size) {
        this->data.append(data, size);
    }
    virtual void flush() {}

    const std::string &getData() const {
        return data;
    }
};

/// va_list RAII.
struct VaListHolder {
    va_list &args;

    VaListHolder(va_list &args)
        : args(args)
    {}
    ~VaListHolder() {
        va_end(args);
    }
};

}  // anon namespace

namespace frpcdata {

std::string dumps(const char *methodname, va_list args) {
    // TODO configurable from outside
    int useBinary = false;
    unsigned char protocolVersionMajor = 2;
    unsigned char protocolVersionMinor = 1;

    // create writer
    StringWriter writer;
    // create marshaller
    FRPC::Marshaller_t *marshaller = FRPC::Marshaller_t::create((useBinary
        ? FRPC::Marshaller_t::BINARY_RPC
        : FRPC::Marshaller_t::XML_RPC),
        writer, FRPC::ProtocolVersion_t(protocolVersionMajor,
                                        protocolVersionMinor));
    try {
        FRPC::TreeFeeder_t feeder(*marshaller);
        if (methodname) {
            marshaller->packMethodCall(methodname, strlen(methodname));
            // process value pointers varargs until nullptr.
            while (const FRPC::Value_t *value = va_arg(args, FRPC::Value_t*)) {
                feeder.feedValue(*value);
            }
        }

        marshaller->flush();
    } catch (const std::exception &e) {
        throw;
    }

    return writer.getData();
}

std::string dumps(const char *methodname, ...) {
    va_list args;
    va_start(args, methodname);
    VaListHolder _args(args);
    return std::string();
}

/// Read string data (xml) and return it as FRPC Value.
FRPC::Value_t &loads(FRPC::Pool_t &pool, const std::string &data) {
    FRPC::TreeBuilder_t tree(pool);
    FRPC::UnMarshaller_t *xml = FRPC::UnMarshaller_t::create(
            FRPC::UnMarshaller_t::XML_RPC, tree);
    xml->unMarshall(data.c_str(), data.size(), FRPC::UnMarshaller_t::TYPE_METHOD_RESPONSE);
    return tree.getUnMarshaledData();
}

}  // namespace frpcdata

<commit_msg>fix incomplete dumps function (did not passed var args); unmarhsaller error returned as struct.<commit_after>/* Async FRPC client.
 * The MIT License (MIT)
 * Copyright (c) 2014 Jan Cermak
 */

#include "frpcdata.h"
#include <frpcmarshaller.h>
#include <frpcwriter.h>
#include <frpcunmarshaller.h>
#include <frpctreefeeder.h>
#include <frpctreebuilder.h>
#include <string.h>
#include <cstdarg>

namespace {

class StringWriter: public FRPC::Writer_t {
    std::string data;
  public:
    StringWriter() {}
    virtual void write(const char *data, unsigned size) {
        this->data.append(data, size);
    }
    virtual void flush() {}

    const std::string &getData() const {
        return data;
    }
};

/// va_list RAII.
struct VaListHolder {
    va_list &args;

    VaListHolder(va_list &args)
        : args(args)
    {}
    ~VaListHolder() {
        va_end(args);
    }
};

}  // anon namespace

namespace frpcdata {

std::string dumps(const char *methodname, va_list args) {
    // TODO configurable from outside
    int useBinary = false;
    unsigned char protocolVersionMajor = 2;
    unsigned char protocolVersionMinor = 1;

    // create writer
    StringWriter writer;
    // create marshaller
    FRPC::Marshaller_t *marshaller = FRPC::Marshaller_t::create((useBinary
        ? FRPC::Marshaller_t::BINARY_RPC
        : FRPC::Marshaller_t::XML_RPC),
        writer, FRPC::ProtocolVersion_t(protocolVersionMajor,
                                        protocolVersionMinor));
    try {
        FRPC::TreeFeeder_t feeder(*marshaller);
        if (methodname) {
            marshaller->packMethodCall(methodname, strlen(methodname));
            // process value pointers varargs until nullptr.
            while (const FRPC::Value_t *value = va_arg(args, FRPC::Value_t*)) {
                feeder.feedValue(*value);
            }
        }

        marshaller->flush();
    } catch (const std::exception &e) {
        throw;
    }

    return writer.getData();
}

std::string dumps(const char *methodname, ...) {
    va_list args;
    va_start(args, methodname);
    VaListHolder _args(args);
    return dumps(methodname, args);
}

/// Read string data (xml) and return it as FRPC Value.
FRPC::Value_t &loads(FRPC::Pool_t &pool, const std::string &data) {
    FRPC::TreeBuilder_t tree(pool);
    FRPC::UnMarshaller_t *xml = FRPC::UnMarshaller_t::create(
            FRPC::UnMarshaller_t::XML_RPC, tree);
    xml->unMarshall(data.c_str(), data.size(), FRPC::UnMarshaller_t::TYPE_METHOD_RESPONSE);
    FRPC::Value_t *res = tree.getUnMarshaledDataPtr();
    if (res == 0x0) {
        //TODO exception?
        return pool.Struct(
            "status", pool.Int(tree.getUnMarshaledErrorNumber()),
            "statusMessage", pool.String(tree.getUnMarshaledErrorMessage()));
    }
    return *res;
}

}  // namespace frpcdata

<|endoftext|>


<commit_before>// Copyright 2015-2019 Elviss Strazdins. All rights reserved.

#include <cstdlib>
#include <system_error>
#pragma push_macro("WIN32_LEAN_AND_MEAN")
#pragma push_macro("NOMINMAX")
#ifndef WIN32_LEAN_AND_MEAN
#  define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOMINMAX
#  define NOMINMAX
#endif
#include <Windows.h>
#include <shellapi.h>
#pragma pop_macro("WIN32_LEAN_AND_MEAN")
#pragma pop_macro("NOMINMAX")

#include "EngineWin.hpp"
#include "NativeWindowWin.hpp"
#include "input/windows/InputSystemWin.hpp"
#include "utils/Log.hpp"

namespace ouzel
{
    namespace
    {
        class ShellExecuteErrorCategory final: public std::error_category
        {
        public:
            const char* name() const noexcept final
            {
                return "ShellExecute";
            }

            std::string message(int condition) const final
            {
                switch (condition)
                {
                    case 0: return "Out of memory";
                    case ERROR_FILE_NOT_FOUND: return "ERROR_FILE_NOT_FOUND";
                    case ERROR_PATH_NOT_FOUND: return "ERROR_PATH_NOT_FOUND";
                    case ERROR_BAD_FORMAT: return "ERROR_BAD_FORMAT";
                    case SE_ERR_ACCESSDENIED: return "SE_ERR_ACCESSDENIED";
                    case SE_ERR_ASSOCINCOMPLETE: return "SE_ERR_ASSOCINCOMPLETE";
                    case SE_ERR_DDEBUSY: return "SE_ERR_DDEBUSY";
                    case SE_ERR_DDEFAIL: return "SE_ERR_DDEFAIL";
                    case SE_ERR_DDETIMEOUT: return "SE_ERR_DDETIMEOUT";
                    case SE_ERR_DLLNOTFOUND: return "SE_ERR_DLLNOTFOUND";
                    case SE_ERR_NOASSOC: return "SE_ERR_NOASSOC";
                    case SE_ERR_OOM: return "SE_ERR_OOM";
                    case SE_ERR_SHARE: return "SE_ERR_SHARE";
                    default: return "Unknown error (" + std::to_string(condition) + ")";
                }
            }
        };

        const ShellExecuteErrorCategory shellExecuteErrorCategory {};
    }

    EngineWin::EngineWin(int initArgc, LPWSTR* initArgv)
    {
        if (initArgv)
        {
            int bufferSize;
            std::vector<char> buffer;

            for (int i = 0; i < initArgc; ++i)
            {
                bufferSize = WideCharToMultiByte(CP_UTF8, 0, initArgv[i], -1, nullptr, 0, nullptr, nullptr);
                if (bufferSize == 0)
                    throw std::system_error(GetLastError(), std::system_category(), "Failed to convert wide char to UTF-8");

                buffer.resize(bufferSize);
                if (WideCharToMultiByte(CP_UTF8, 0, initArgv[i], -1, buffer.data(), bufferSize, nullptr, nullptr) == 0)
                    throw std::system_error(GetLastError(), std::system_category(), "Failed to convert wide char to UTF-8");

                args.push_back(buffer.data());
            }
        }

        HRESULT hr;
        if (FAILED(hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED)))
            throw std::system_error(hr, std::system_category(), "Failed to initialize COM");

#ifdef DEBUG
        if (!AllocConsole())
            log(Log::Level::Info) << "Attached to console";
#endif
    }

    EngineWin::~EngineWin()
    {
        //CoUninitialize();
    }

    static void translateMessage(HWND window, const std::set<HACCEL>& accelerators, MSG& message)
    {
        bool translate = true;

        for (HACCEL accelerator : accelerators)
        {
            if (TranslateAccelerator(window, accelerator, &message))
                translate = false;
        }

        if (translate)
        {
            TranslateMessage(&message);
            DispatchMessage(&message);
        }
    }

    void EngineWin::run()
    {
        init();
        start();

        input::InputSystemWin* inputWin = static_cast<input::InputSystemWin*>(inputManager->getInputSystem());
        NativeWindowWin* windowWin = static_cast<NativeWindowWin*>(window->getNativeWindow());

        MSG message;

        while (active)
        {
            if (!paused)
            {
                if (PeekMessage(&message, nullptr, 0, 0, PM_REMOVE))
                {
                    translateMessage(windowWin->getNativeWindow(),
                                     windowWin->accelerators, message);

                    if (message.message == WM_QUIT)
                    {
                        exit();
                        break;
                    }
                }
            }
            else
            {
                BOOL ret;
                if ((ret = GetMessage(&message, nullptr, 0, 0)) == -1)
                    throw std::system_error(GetLastError(), std::system_category(), "Failed to get message");

                if (ret == 0)
                {
                    exit();
                    break;
                }
                else
                {
                    translateMessage(windowWin->getNativeWindow(),
                                     windowWin->accelerators, message);
                }
            }

            inputWin->update();
        }

        exit();
    }

    void EngineWin::runOnMainThread(const std::function<void()>& func)
    {
        NativeWindowWin* windowWin = static_cast<NativeWindowWin*>(window->getNativeWindow());

        std::unique_lock<std::mutex> lock(executeMutex);
        executeQueue.push(func);
        lock.unlock();

        if (!PostMessage(windowWin->getNativeWindow(), WM_USER, 0, 0))
            throw std::system_error(GetLastError(), std::system_category(), "Failed to post message");

    }

    void EngineWin::executeAll()
    {
        std::function<void()> func;

        for (;;)
        {
            std::unique_lock<std::mutex> lock(executeMutex);

            if (executeQueue.empty())
                break;

            func = std::move(executeQueue.front());
            executeQueue.pop();
            lock.unlock();

            if (func) func();
        }
    }

    void EngineWin::openURL(const std::string& url)
    {
        const int buferSize = MultiByteToWideChar(CP_UTF8, 0, url.c_str(), -1, nullptr, 0);
        if (buferSize == 0)
            throw std::system_error(GetLastError(), std::system_category(), "Failed to convert UTF-8 to wide char");

        std::vector<WCHAR> buffer(buferSize);
        if (MultiByteToWideChar(CP_UTF8, 0, url.c_str(), -1, buffer.data(), buferSize) == 0)
            throw std::system_error(GetLastError(), std::system_category(), "Failed to convert UTF-8 to wide char");

        // Result of the ShellExecuteW can be cast only to an int (https://docs.microsoft.com/en-us/windows/desktop/api/shellapi/nf-shellapi-shellexecutew)
        // Cast to intptr_t and then to int to avoid warnings 4311 and 4302
        auto result = static_cast<int>(reinterpret_cast<intptr_t>(ShellExecuteW(nullptr, L"open", buffer.data(), nullptr, nullptr, SW_SHOWNORMAL)));
        if (result <= 32)
            throw std::system_error(result, shellExecuteErrorCategory, "Failed to execute open");
    }
}
<commit_msg>Use memcpy to cast the result of ShellExecuteW to int<commit_after>// Copyright 2015-2019 Elviss Strazdins. All rights reserved.

#include <cstdlib>
#include <system_error>
#pragma push_macro("WIN32_LEAN_AND_MEAN")
#pragma push_macro("NOMINMAX")
#ifndef WIN32_LEAN_AND_MEAN
#  define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOMINMAX
#  define NOMINMAX
#endif
#include <Windows.h>
#include <shellapi.h>
#pragma pop_macro("WIN32_LEAN_AND_MEAN")
#pragma pop_macro("NOMINMAX")

#include "EngineWin.hpp"
#include "NativeWindowWin.hpp"
#include "input/windows/InputSystemWin.hpp"
#include "utils/Log.hpp"

namespace ouzel
{
    namespace
    {
        class ShellExecuteErrorCategory final: public std::error_category
        {
        public:
            const char* name() const noexcept final
            {
                return "ShellExecute";
            }

            std::string message(int condition) const final
            {
                switch (condition)
                {
                    case 0: return "Out of memory";
                    case ERROR_FILE_NOT_FOUND: return "ERROR_FILE_NOT_FOUND";
                    case ERROR_PATH_NOT_FOUND: return "ERROR_PATH_NOT_FOUND";
                    case ERROR_BAD_FORMAT: return "ERROR_BAD_FORMAT";
                    case SE_ERR_ACCESSDENIED: return "SE_ERR_ACCESSDENIED";
                    case SE_ERR_ASSOCINCOMPLETE: return "SE_ERR_ASSOCINCOMPLETE";
                    case SE_ERR_DDEBUSY: return "SE_ERR_DDEBUSY";
                    case SE_ERR_DDEFAIL: return "SE_ERR_DDEFAIL";
                    case SE_ERR_DDETIMEOUT: return "SE_ERR_DDETIMEOUT";
                    case SE_ERR_DLLNOTFOUND: return "SE_ERR_DLLNOTFOUND";
                    case SE_ERR_NOASSOC: return "SE_ERR_NOASSOC";
                    case SE_ERR_OOM: return "SE_ERR_OOM";
                    case SE_ERR_SHARE: return "SE_ERR_SHARE";
                    default: return "Unknown error (" + std::to_string(condition) + ")";
                }
            }
        };

        const ShellExecuteErrorCategory shellExecuteErrorCategory {};
    }

    EngineWin::EngineWin(int initArgc, LPWSTR* initArgv)
    {
        if (initArgv)
        {
            int bufferSize;
            std::vector<char> buffer;

            for (int i = 0; i < initArgc; ++i)
            {
                bufferSize = WideCharToMultiByte(CP_UTF8, 0, initArgv[i], -1, nullptr, 0, nullptr, nullptr);
                if (bufferSize == 0)
                    throw std::system_error(GetLastError(), std::system_category(), "Failed to convert wide char to UTF-8");

                buffer.resize(bufferSize);
                if (WideCharToMultiByte(CP_UTF8, 0, initArgv[i], -1, buffer.data(), bufferSize, nullptr, nullptr) == 0)
                    throw std::system_error(GetLastError(), std::system_category(), "Failed to convert wide char to UTF-8");

                args.push_back(buffer.data());
            }
        }

        HRESULT hr;
        if (FAILED(hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED)))
            throw std::system_error(hr, std::system_category(), "Failed to initialize COM");

#ifdef DEBUG
        if (!AllocConsole())
            log(Log::Level::Info) << "Attached to console";
#endif
    }

    EngineWin::~EngineWin()
    {
        //CoUninitialize();
    }

    static void translateMessage(HWND window, const std::set<HACCEL>& accelerators, MSG& message)
    {
        bool translate = true;

        for (HACCEL accelerator : accelerators)
        {
            if (TranslateAccelerator(window, accelerator, &message))
                translate = false;
        }

        if (translate)
        {
            TranslateMessage(&message);
            DispatchMessage(&message);
        }
    }

    void EngineWin::run()
    {
        init();
        start();

        input::InputSystemWin* inputWin = static_cast<input::InputSystemWin*>(inputManager->getInputSystem());
        NativeWindowWin* windowWin = static_cast<NativeWindowWin*>(window->getNativeWindow());

        MSG message;

        while (active)
        {
            if (!paused)
            {
                if (PeekMessage(&message, nullptr, 0, 0, PM_REMOVE))
                {
                    translateMessage(windowWin->getNativeWindow(),
                                     windowWin->accelerators, message);

                    if (message.message == WM_QUIT)
                    {
                        exit();
                        break;
                    }
                }
            }
            else
            {
                BOOL ret;
                if ((ret = GetMessage(&message, nullptr, 0, 0)) == -1)
                    throw std::system_error(GetLastError(), std::system_category(), "Failed to get message");

                if (ret == 0)
                {
                    exit();
                    break;
                }
                else
                {
                    translateMessage(windowWin->getNativeWindow(),
                                     windowWin->accelerators, message);
                }
            }

            inputWin->update();
        }

        exit();
    }

    void EngineWin::runOnMainThread(const std::function<void()>& func)
    {
        NativeWindowWin* windowWin = static_cast<NativeWindowWin*>(window->getNativeWindow());

        std::unique_lock<std::mutex> lock(executeMutex);
        executeQueue.push(func);
        lock.unlock();

        if (!PostMessage(windowWin->getNativeWindow(), WM_USER, 0, 0))
            throw std::system_error(GetLastError(), std::system_category(), "Failed to post message");

    }

    void EngineWin::executeAll()
    {
        std::function<void()> func;

        for (;;)
        {
            std::unique_lock<std::mutex> lock(executeMutex);

            if (executeQueue.empty())
                break;

            func = std::move(executeQueue.front());
            executeQueue.pop();
            lock.unlock();

            if (func) func();
        }
    }

    void EngineWin::openURL(const std::string& url)
    {
        const int buferSize = MultiByteToWideChar(CP_UTF8, 0, url.c_str(), -1, nullptr, 0);
        if (buferSize == 0)
            throw std::system_error(GetLastError(), std::system_category(), "Failed to convert UTF-8 to wide char");

        std::vector<WCHAR> buffer(buferSize);
        if (MultiByteToWideChar(CP_UTF8, 0, url.c_str(), -1, buffer.data(), buferSize) == 0)
            throw std::system_error(GetLastError(), std::system_category(), "Failed to convert UTF-8 to wide char");

        // Result of the ShellExecuteW can be cast only to an int (https://docs.microsoft.com/en-us/windows/desktop/api/shellapi/nf-shellapi-shellexecutew)
        HINSTANCE result = ShellExecuteW(nullptr, L"open", buffer.data(), nullptr, nullptr, SW_SHOWNORMAL);
        int status;
        memcpy(&status, &result, sizeof(status));
        if (status <= 32)
            throw std::system_error(status, shellExecuteErrorCategory, "Failed to execute open");
    }
}
<|endoftext|>


<commit_before>#include <pthread.h>
#include <stdio.h>
#include <dlfcn.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <execinfo.h>
#include <tern/hooks.h>
#include <tern/space.h>
#include <tern/options.h>
#include <tern/runtime/runtime.h>

using namespace tern;

#define __NEED_INPUT_INSID
#define __USE_TERN_RUNTIME
//#define PRINT_DEBUG

/*
#ifdef __USE_TERN_RUNTIME
#define __INSTALL_RUNTIME
#endif

#ifdef __INSTALL_RUNTIME

struct preload_static_block
{
  preload_static_block()
  {
    InstallRuntime();
  }
};

// notice, it doesn't work for functions called in static constructors of program

static preload_static_block preload_initializer;

#endif
*/

#define __SPEC_HOOK___libc_start_main

static void print_stack()
{
#if 0
  void* tracePtrs[500];
  printf("here");
  fflush(stdout);
  int count = backtrace( tracePtrs, 500 );
  printf("here");
  fflush(stdout);
  char** funcNames = backtrace_symbols( tracePtrs, count );

  printf("here");
  fflush(stdout);
  // Print the stack trace
  for( int ii = 0; ii < count; ii++ )
    printf( "%s\n", funcNames[ii] );
  fflush(stdout);

  // Free the string pointers
  free( funcNames );
#endif
}

void *get_eip()
{
  void *tracePtrs[20];
  int i;
  uint64_t ret = 0;
  int count = backtrace(tracePtrs, 20);

  if (options::whole_stack_eip_signature)
  {
    ret = 0;
    for (i = 0; i < count; ++i)
      ret = ret * 97 + (uint64_t) tracePtrs[i];
    return (void*) ret;
    //std::cout << std::hex << tracePtrs[2] << std::dec << std::endl;
    //char** funcNames = backtrace_symbols( tracePtrs, count );
    //printf( "%s\n", funcNames[2] );
    //printf(stderr, "reteip: %p\n", tracePtrs[1]);
  } else
    return tracePtrs[3];  //  this is ret_eip of my caller
}

#define HOOK_MUTEX_COND
#define HOOK_BARRIER
#define HOOK_SEMAPHORE
#define HOOK_BLOCKING_FUNCS

//  notice we have not implemented tern_fork yet. so the
//  hooking code is disabled.
//#define __SPEC_HOOK_fork

#ifndef HOOK_MUTEX_COND
#define __SPEC_HOOK_pthread_mutex_init
#define __SPEC_HOOK_pthread_mutex_lock
#define __SPEC_HOOK_pthread_mutex_unlock
#define __SPEC_HOOK_pthread_mutex_trylock
#define __SPEC_HOOK_pthread_mutex_timedlock
#define __SPEC_HOOK_pthread_cond_wait
#define __SPEC_HOOK_pthread_cond_signal
#define __SPEC_HOOK_pthread_cond_timedwait
#define __SPEC_HOOK_pthread_cond_broadcast
#endif

#ifndef HOOK_BARRIER
#define __SPEC_HOOK_pthread_barrier_wait
#define __SPEC_HOOK_pthread_barrier_init
#define __SPEC_HOOK_pthread_barrier_destroy
#endif

#ifndef HOOK_SEMAPHORE
#define __SPEC_HOOK_sem_wait
#define __SPEC_HOOK_sem_trywait
#define __SPEC_HOOK_sem_timedwait
#define __SPEC_HOOK_sem_post
#endif

#ifndef HOOK_BLOCKING_FUNCS
#define __SPEC_HOOK_recv
#define __SPEC_HOOK_connect
#define __SPEC_HOOK_accept
#define __SPEC_HOOK_accept4
#define __SPEC_HOOK_read
#define __SPEC_HOOK_write
#define __SPEC_HOOK_sigwait
#define __SPEC_HOOK_select
#define __SPEC_HOOK_recvfrom
#define __SPEC_HOOK_recvmsg
#define __SPEC_HOOK_sleep
#define __SPEC_HOOK_usleep
#define __SPEC_HOOK_nanosleep
#define __SPEC_HOOK_epoll_wait
#endif

#include "spec_hooks.cpp"
#include "template.cpp"

<commit_msg>Nits, disable sync builtins in libgomp<commit_after>#include <pthread.h>
#include <stdio.h>
#include <dlfcn.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <execinfo.h>
#include <tern/hooks.h>
#include <tern/space.h>
#include <tern/options.h>
#include <tern/runtime/runtime.h>

using namespace tern;

#define __NEED_INPUT_INSID
#define __USE_TERN_RUNTIME
//#define PRINT_DEBUG

/*
#ifdef __USE_TERN_RUNTIME
#define __INSTALL_RUNTIME
#endif

#ifdef __INSTALL_RUNTIME

struct preload_static_block
{
  preload_static_block()
  {
    InstallRuntime();
  }
};

// notice, it doesn't work for functions called in static constructors of program

static preload_static_block preload_initializer;

#endif
*/

#define __SPEC_HOOK___libc_start_main

static void print_stack()
{
#if 0
  void* tracePtrs[500];
  printf("here");
  fflush(stdout);
  int count = backtrace( tracePtrs, 500 );
  printf("here");
  fflush(stdout);
  char** funcNames = backtrace_symbols( tracePtrs, count );

  printf("here");
  fflush(stdout);
  // Print the stack trace
  for( int ii = 0; ii < count; ii++ )
    printf( "%s\n", funcNames[ii] );
  fflush(stdout);

  // Free the string pointers
  free( funcNames );
#endif
}

void *get_eip()
{
  void *tracePtrs[20];
  int i;
  uint64_t ret = 0;
  int count = backtrace(tracePtrs, 20);

  if (options::whole_stack_eip_signature)
  {
    ret = 0;
    for (i = 0; i < count; ++i)
      ret = ret * 97 + (uint64_t) tracePtrs[i];
    return (void*) ret;
    //std::cout << std::hex << tracePtrs[2] << std::dec << std::endl;
    //char** funcNames = backtrace_symbols( tracePtrs, count );
    //printf( "%s\n", funcNames[2] );
    //printf(stderr, "reteip: %p\n", tracePtrs[1]);
  } else
    return tracePtrs[2];  //  this is ret_eip of my caller
}

#define HOOK_MUTEX_COND
#define HOOK_BARRIER
#define HOOK_SEMAPHORE
#define HOOK_BLOCKING_FUNCS

//  notice we have not implemented tern_fork yet. so the
//  hooking code is disabled.
//#define __SPEC_HOOK_fork

#ifndef HOOK_MUTEX_COND
#define __SPEC_HOOK_pthread_mutex_init
#define __SPEC_HOOK_pthread_mutex_lock
#define __SPEC_HOOK_pthread_mutex_unlock
#define __SPEC_HOOK_pthread_mutex_trylock
#define __SPEC_HOOK_pthread_mutex_timedlock
#define __SPEC_HOOK_pthread_cond_wait
#define __SPEC_HOOK_pthread_cond_signal
#define __SPEC_HOOK_pthread_cond_timedwait
#define __SPEC_HOOK_pthread_cond_broadcast
#endif

#ifndef HOOK_BARRIER
#define __SPEC_HOOK_pthread_barrier_wait
#define __SPEC_HOOK_pthread_barrier_init
#define __SPEC_HOOK_pthread_barrier_destroy
#endif

#ifndef HOOK_SEMAPHORE
#define __SPEC_HOOK_sem_wait
#define __SPEC_HOOK_sem_trywait
#define __SPEC_HOOK_sem_timedwait
#define __SPEC_HOOK_sem_post
#endif

#ifndef HOOK_BLOCKING_FUNCS
#define __SPEC_HOOK_recv
#define __SPEC_HOOK_connect
#define __SPEC_HOOK_accept
#define __SPEC_HOOK_accept4
#define __SPEC_HOOK_read
#define __SPEC_HOOK_write
#define __SPEC_HOOK_sigwait
#define __SPEC_HOOK_select
#define __SPEC_HOOK_recvfrom
#define __SPEC_HOOK_recvmsg
#define __SPEC_HOOK_sleep
#define __SPEC_HOOK_usleep
#define __SPEC_HOOK_nanosleep
#define __SPEC_HOOK_epoll_wait
#endif

#include "spec_hooks.cpp"
#include "template.cpp"

<|endoftext|>


<commit_before><commit_msg>Fix bad change in RenderScriptx86ABIFixups.cpp, forgot to change everything necessary<commit_after><|endoftext|>