<commit_before>/** \brief Utility for validating and fixing up records harvested by zts_harvester
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2018-2020 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  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 <algorithm>
#include <iostream>
#include <map>
#include <unordered_set>
#include <cstdio>
#include <cstdlib>
#include "Compiler.h"
#include "DbConnection.h"
#include "DbResultSet.h"
#include "DnsUtil.h"
#include "EmailSender.h"
#include "IniFile.h"
#include "MARC.h"
#include "UBTools.h"
#include "util.h"

namespace {

[[noreturn]] void Usage() {
   ::Usage("(marc_input marc_output missed_expectations_file email_address)|(update_db journal_name field_name field_presence)\n"
           "\tThis tool has two operating modes 1) checking MARC data for missed expectations and 2) altering these expectations.\n"
           "\tin the \"update_db\" mode, \"field_name\" must be a 3-character MARC tag and \"field_presence\" must be one of\n"
           "\tALWAYS, SOMETIMES, IGNORE.  Please note that only existing entries can be changed!");
}

enum FieldPresence { ALWAYS, SOMETIMES, IGNORE };

bool StringToFieldPresence(const std::string &field_presence_str, FieldPresence * const field_presence) {
    if (field_presence_str == "ALWAYS") {
        *field_presence = ALWAYS;
        return true;
    }

    if (field_presence_str == "SOMETIMES") {
        *field_presence = SOMETIMES;
        return true;
    }

    if (field_presence_str == "IGNORE") {
        *field_presence = IGNORE;
        return true;
    }

    return false;
}

struct FieldInfo {
    std::string name_;
    FieldPresence presence_;
public:
    FieldInfo(const std::string &name, const FieldPresence presence): name_(name), presence_(presence) { }
};

class JournalInfo {
    bool not_in_database_yet_;
    std::vector<FieldInfo> field_infos_;
public:
    using const_iterator = std::vector<FieldInfo>::const_iterator;
    using iterator = std::vector<FieldInfo>::iterator;
public:
    explicit JournalInfo(const bool not_in_database_yet): not_in_database_yet_(not_in_database_yet) { }
    JournalInfo() = default;
    JournalInfo(const JournalInfo &rhs) = default;

    size_t size() const { return field_infos_.size(); }
    bool isInDatabase() const { return not not_in_database_yet_; }
    void addField(const std::string &field_name, const FieldPresence field_presence)
        { field_infos_.emplace_back(field_name, field_presence); }
    const_iterator begin() const { return field_infos_.cbegin(); }
    const_iterator end() const { return field_infos_.cend(); }
    iterator begin() { return field_infos_.begin(); }
    iterator end() { return field_infos_.end(); }
    iterator find(const std::string &field_name) {
        return std::find_if(field_infos_.begin(), field_infos_.end(),
                            [&field_name](const FieldInfo &field_info){ return field_name == field_info.name_; });
    }
};

FieldPresence StringToFieldPresence(const std::string &s) {
    if (s == "always")
        return ALWAYS;
    if (s == "sometimes")
        return SOMETIMES;
    if (s == "ignore")
        return IGNORE;
    LOG_ERROR("unknown enumerated value \"" + s + "\"!");
}

std::string FieldPresenceToString(const FieldPresence field_presence) {
    switch (field_presence) {
    case ALWAYS:
        return "always";
    case SOMETIMES:
        return "sometimes";
    case IGNORE:
        return "ignore";
    default:
        LOG_ERROR("we should *never get here!");
    }
}

void LoadFromDatabaseOrCreateFromScratch(DbConnection * const db_connection, const std::string &journal_name,
                                         JournalInfo * const journal_info)
{
    db_connection->queryOrDie("SELECT metadata_field_name,field_presence FROM metadata_presence_tracer WHERE journal_name='"
                              + db_connection->escapeString(journal_name) + "'");
    DbResultSet result_set(db_connection->getLastResultSet());
    if (result_set.empty()) {
        LOG_INFO("\"" + journal_name + "\" was not yet in the database.");
        *journal_info = JournalInfo(/* not_in_database_yet = */true);
        return;
    }

    *journal_info = JournalInfo(/* not_in_database_yet = */false);
    while (auto row = result_set.getNextRow())
        journal_info->addField(row["metadata_field_name"], StringToFieldPresence(row["field_presence"]));
}

// Two-way mapping required as the map is uni-directional
const std::map<std::string, std::string> EQUIVALENT_TAGS_MAP{
    { "700", "100" }, { "100", "700" }
};

void AnalyseNewJournalRecord(const MARC::Record &record, const bool first_record, JournalInfo * const journal_info) {
    std::unordered_set<std::string> seen_tags;
    MARC::Tag last_tag;
    for (const auto &field : record) {
        auto current_tag(field.getTag());
        if (current_tag == last_tag)
            continue;

        seen_tags.emplace(current_tag.toString());

        if (first_record)
            journal_info->addField(current_tag.toString(), ALWAYS);
        else if (journal_info->find(current_tag.toString()) == journal_info->end())
            journal_info->addField(current_tag.toString(), SOMETIMES);

        last_tag = current_tag;
    }

    for (auto &field_info : *journal_info) {
        if (seen_tags.find(field_info.name_) == seen_tags.end())
            field_info.presence_ = SOMETIMES;
    }
}

bool RecordMeetsExpectations(const MARC::Record &record, const std::string &journal_name, const JournalInfo &journal_info) {
    std::unordered_set<std::string> seen_tags;
    MARC::Tag last_tag;
    for (const auto &field : record) {
        const auto current_tag(field.getTag());
        if (current_tag == last_tag)
            continue;
        seen_tags.emplace(current_tag.toString());
        last_tag = current_tag;
    }

    bool missed_at_least_one_expectation(false);
    for (const auto &field_info : journal_info) {
        if (field_info.presence_ != ALWAYS)
            continue;   // we only care about required fields that are missing

        const auto equivalent_tag(EQUIVALENT_TAGS_MAP.find(field_info.name_));
        if (seen_tags.find(field_info.name_) != seen_tags.end())
            ;// required tag found
        else if (equivalent_tag != EQUIVALENT_TAGS_MAP.end() and seen_tags.find(equivalent_tag->second) != seen_tags.end())
            ;// equivalent tag found
        else {
            LOG_WARNING("Record w/ control number " + record.getControlNumber() + " in \"" + journal_name
                     + "\" is missing the always expected " + field_info.name_ + " field.");
            missed_at_least_one_expectation = true;
        }
    }

    return not missed_at_least_one_expectation;
}

void WriteToDatabase(DbConnection * const db_connection, const std::string &journal_name, const JournalInfo &journal_info) {
    for (const auto &field_info : journal_info)
        db_connection->queryOrDie("INSERT INTO metadata_presence_tracer SET journal_name='" + journal_name
                                  + "', metadata_field_name='" + db_connection->escapeString(field_info.name_)
                                  + "', field_presence='" + FieldPresenceToString(field_info.presence_) + "'");
}

void SendEmail(const std::string &email_address, const std::string &message_subject, const std::string &message_body) {
    const auto reply_code(EmailSender::SendEmail("zts_harvester_delivery_pipeline@uni-tuebingen.de",
                          email_address, message_subject, message_body,
                          EmailSender::MEDIUM, EmailSender::PLAIN_TEXT, /* reply_to = */ "",
                          /* use_ssl = */ true, /* use_authentication = */ true));

    if (reply_code >= 300)
        LOG_WARNING("failed to send email, the response code was: " + std::to_string(reply_code));
}

void UpdateDB(DbConnection * const db_connection, const std::string &journal_name, const std::string &field_name, const std::string &field_presence_str) {
    FieldPresence field_presence;
    if (not StringToFieldPresence(field_presence_str, &field_presence))
        LOG_ERROR("\"" + field_presence_str + "\" is not a valid field_presence!");
    if (field_name.length() != MARC::Record::TAG_LENGTH)
        LOG_ERROR("\"" + field_name + "\" is not a valid field name!");

    DbTransaction transcation(db_connection);
    db_connection->queryOrDie("SELECT field_presence FROM metadata_presence_tracer WHERE journal_name="
                              + db_connection->escapeAndQuoteString(journal_name) + " AND field_name='" + field_name + "'");
    const DbResultSet result_set(db_connection->getLastResultSet());
    if (result_set.empty())
        LOG_ERROR("can't update non-existent database entry!");
    db_connection->queryOrDie("UPDATE metadata_presence_tracer SET field_presence='" + field_presence_str + "' WHERE journal_name="
                              + db_connection->escapeAndQuoteString(journal_name) + " AND field_name='" + field_name + "'");
}

bool IsRecordValid(DbConnection * const db_connection, const MARC::Record &record,
                   std::map<std::string, JournalInfo> * const journal_name_to_info_map,
                   unsigned * const new_record_count, unsigned * const missed_expectation_count)
{
    const auto journal_name(record.getSuperiorTitle());
    if (journal_name.empty()) {
        LOG_WARNING("Record w/ control number \"" + record.getControlNumber() + "\" is missing a superior title!");
        ++(*missed_expectation_count);
        return false;
    }

    auto journal_name_and_info(journal_name_to_info_map->find(journal_name));
    bool first_record(false); // True if the current record is the first encounter of a journal
    if (journal_name_and_info == journal_name_to_info_map->end()) {
        first_record = true;
        JournalInfo new_journal_info;
        LoadFromDatabaseOrCreateFromScratch(db_connection, journal_name, &new_journal_info);
        (*journal_name_to_info_map)[journal_name] = new_journal_info;
        journal_name_and_info = journal_name_to_info_map->find(journal_name);
    }

    if (journal_name_and_info->second.isInDatabase()) {
        if (not RecordMeetsExpectations(record, journal_name_and_info->first, journal_name_and_info->second)) {
            ++(*missed_expectation_count);
            return false;
        }
    } else {
        AnalyseNewJournalRecord(record, first_record, &journal_name_and_info->second);
        ++(*new_record_count);
    }

    return true;
}

} // unnamed namespace

int Main(int argc, char *argv[]) {
    if (argc != 5)
        Usage();

    DbConnection db_connection;

    if (std::strcmp(argv[1], "update_db") == 0) {
        UpdateDB(&db_connection, argv[2], argv[3], argv[4]);
        return EXIT_SUCCESS;
    }

    auto reader(MARC::Reader::Factory(argv[1]));
    auto valid_records_writer(MARC::Writer::Factory(argv[2]));
    auto delinquent_records_writer(MARC::Writer::Factory(argv[3]));
    std::map<std::string, JournalInfo> journal_name_to_info_map;
    const std::string email_address(argv[4]);

    unsigned total_record_count(0), new_record_count(0), missed_expectation_count(0);
    while (const auto record = reader->read()) {
        ++total_record_count;
        if (IsRecordValid(&db_connection, record, &journal_name_to_info_map,
                          &new_record_count, &missed_expectation_count))
            valid_records_writer->write(record);
        else
            delinquent_records_writer->write(record);
    }

    for (const auto &journal_name_and_info : journal_name_to_info_map) {
        if (not journal_name_and_info.second.isInDatabase())
            WriteToDatabase(&db_connection, journal_name_and_info.first, journal_name_and_info.second);
    }

    if (missed_expectation_count > 0) {
        // send notification to the email address
        SendEmail(email_address, "validate_harvested_records encountered warnings (from: " + DnsUtil::GetHostname() + ")",
                  "Some records missed expectations with respect to MARC fields. "
                  "Check the log at '/usr/local/var/log/tuefind/zts_harvester_delivery_pipeline.log' for details.");
    }

    LOG_INFO("Processed " + std::to_string(total_record_count) + " record(s) of which " + std::to_string(new_record_count)
             + " was/were (a) record(s) of new journals and " + std::to_string(missed_expectation_count)
             + " record(s) missed expectations.");

    return EXIT_SUCCESS;
}
<commit_msg>validate_harvested_records.cc: Replaced SQL transaction by a single SQL query<commit_after>/** \brief Utility for validating and fixing up records harvested by zts_harvester
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2018-2020 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  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 <algorithm>
#include <iostream>
#include <map>
#include <unordered_set>
#include <cstdio>
#include <cstdlib>
#include "Compiler.h"
#include "DbConnection.h"
#include "DbResultSet.h"
#include "DnsUtil.h"
#include "EmailSender.h"
#include "IniFile.h"
#include "MARC.h"
#include "UBTools.h"
#include "util.h"

namespace {

[[noreturn]] void Usage() {
   ::Usage("(marc_input marc_output missed_expectations_file email_address)|(update_db journal_name field_name field_presence)\n"
           "\tThis tool has two operating modes 1) checking MARC data for missed expectations and 2) altering these expectations.\n"
           "\tin the \"update_db\" mode, \"field_name\" must be a 3-character MARC tag and \"field_presence\" must be one of\n"
           "\tALWAYS, SOMETIMES, IGNORE.  Please note that only existing entries can be changed!");
}

enum FieldPresence { ALWAYS, SOMETIMES, IGNORE };

bool StringToFieldPresence(const std::string &field_presence_str, FieldPresence * const field_presence) {
    if (field_presence_str == "ALWAYS") {
        *field_presence = ALWAYS;
        return true;
    }

    if (field_presence_str == "SOMETIMES") {
        *field_presence = SOMETIMES;
        return true;
    }

    if (field_presence_str == "IGNORE") {
        *field_presence = IGNORE;
        return true;
    }

    return false;
}

struct FieldInfo {
    std::string name_;
    FieldPresence presence_;
public:
    FieldInfo(const std::string &name, const FieldPresence presence): name_(name), presence_(presence) { }
};

class JournalInfo {
    bool not_in_database_yet_;
    std::vector<FieldInfo> field_infos_;
public:
    using const_iterator = std::vector<FieldInfo>::const_iterator;
    using iterator = std::vector<FieldInfo>::iterator;
public:
    explicit JournalInfo(const bool not_in_database_yet): not_in_database_yet_(not_in_database_yet) { }
    JournalInfo() = default;
    JournalInfo(const JournalInfo &rhs) = default;

    size_t size() const { return field_infos_.size(); }
    bool isInDatabase() const { return not not_in_database_yet_; }
    void addField(const std::string &field_name, const FieldPresence field_presence)
        { field_infos_.emplace_back(field_name, field_presence); }
    const_iterator begin() const { return field_infos_.cbegin(); }
    const_iterator end() const { return field_infos_.cend(); }
    iterator begin() { return field_infos_.begin(); }
    iterator end() { return field_infos_.end(); }
    iterator find(const std::string &field_name) {
        return std::find_if(field_infos_.begin(), field_infos_.end(),
                            [&field_name](const FieldInfo &field_info){ return field_name == field_info.name_; });
    }
};

FieldPresence StringToFieldPresence(const std::string &s) {
    if (s == "always")
        return ALWAYS;
    if (s == "sometimes")
        return SOMETIMES;
    if (s == "ignore")
        return IGNORE;
    LOG_ERROR("unknown enumerated value \"" + s + "\"!");
}

std::string FieldPresenceToString(const FieldPresence field_presence) {
    switch (field_presence) {
    case ALWAYS:
        return "always";
    case SOMETIMES:
        return "sometimes";
    case IGNORE:
        return "ignore";
    default:
        LOG_ERROR("we should *never get here!");
    }
}

void LoadFromDatabaseOrCreateFromScratch(DbConnection * const db_connection, const std::string &journal_name,
                                         JournalInfo * const journal_info)
{
    db_connection->queryOrDie("SELECT metadata_field_name,field_presence FROM metadata_presence_tracer WHERE journal_name='"
                              + db_connection->escapeString(journal_name) + "'");
    DbResultSet result_set(db_connection->getLastResultSet());
    if (result_set.empty()) {
        LOG_INFO("\"" + journal_name + "\" was not yet in the database.");
        *journal_info = JournalInfo(/* not_in_database_yet = */true);
        return;
    }

    *journal_info = JournalInfo(/* not_in_database_yet = */false);
    while (auto row = result_set.getNextRow())
        journal_info->addField(row["metadata_field_name"], StringToFieldPresence(row["field_presence"]));
}

// Two-way mapping required as the map is uni-directional
const std::map<std::string, std::string> EQUIVALENT_TAGS_MAP{
    { "700", "100" }, { "100", "700" }
};

void AnalyseNewJournalRecord(const MARC::Record &record, const bool first_record, JournalInfo * const journal_info) {
    std::unordered_set<std::string> seen_tags;
    MARC::Tag last_tag;
    for (const auto &field : record) {
        auto current_tag(field.getTag());
        if (current_tag == last_tag)
            continue;

        seen_tags.emplace(current_tag.toString());

        if (first_record)
            journal_info->addField(current_tag.toString(), ALWAYS);
        else if (journal_info->find(current_tag.toString()) == journal_info->end())
            journal_info->addField(current_tag.toString(), SOMETIMES);

        last_tag = current_tag;
    }

    for (auto &field_info : *journal_info) {
        if (seen_tags.find(field_info.name_) == seen_tags.end())
            field_info.presence_ = SOMETIMES;
    }
}

bool RecordMeetsExpectations(const MARC::Record &record, const std::string &journal_name, const JournalInfo &journal_info) {
    std::unordered_set<std::string> seen_tags;
    MARC::Tag last_tag;
    for (const auto &field : record) {
        const auto current_tag(field.getTag());
        if (current_tag == last_tag)
            continue;
        seen_tags.emplace(current_tag.toString());
        last_tag = current_tag;
    }

    bool missed_at_least_one_expectation(false);
    for (const auto &field_info : journal_info) {
        if (field_info.presence_ != ALWAYS)
            continue;   // we only care about required fields that are missing

        const auto equivalent_tag(EQUIVALENT_TAGS_MAP.find(field_info.name_));
        if (seen_tags.find(field_info.name_) != seen_tags.end())
            ;// required tag found
        else if (equivalent_tag != EQUIVALENT_TAGS_MAP.end() and seen_tags.find(equivalent_tag->second) != seen_tags.end())
            ;// equivalent tag found
        else {
            LOG_WARNING("Record w/ control number " + record.getControlNumber() + " in \"" + journal_name
                     + "\" is missing the always expected " + field_info.name_ + " field.");
            missed_at_least_one_expectation = true;
        }
    }

    return not missed_at_least_one_expectation;
}

void WriteToDatabase(DbConnection * const db_connection, const std::string &journal_name, const JournalInfo &journal_info) {
    for (const auto &field_info : journal_info)
        db_connection->queryOrDie("INSERT INTO metadata_presence_tracer SET journal_name='" + journal_name
                                  + "', metadata_field_name='" + db_connection->escapeString(field_info.name_)
                                  + "', field_presence='" + FieldPresenceToString(field_info.presence_) + "'");
}

void SendEmail(const std::string &email_address, const std::string &message_subject, const std::string &message_body) {
    const auto reply_code(EmailSender::SendEmail("zts_harvester_delivery_pipeline@uni-tuebingen.de",
                          email_address, message_subject, message_body,
                          EmailSender::MEDIUM, EmailSender::PLAIN_TEXT, /* reply_to = */ "",
                          /* use_ssl = */ true, /* use_authentication = */ true));

    if (reply_code >= 300)
        LOG_WARNING("failed to send email, the response code was: " + std::to_string(reply_code));
}

void UpdateDB(DbConnection * const db_connection, const std::string &journal_name, const std::string &field_name, const std::string &field_presence_str) {
    FieldPresence field_presence;
    if (not StringToFieldPresence(field_presence_str, &field_presence))
        LOG_ERROR("\"" + field_presence_str + "\" is not a valid field_presence!");
    if (field_name.length() != MARC::Record::TAG_LENGTH)
        LOG_ERROR("\"" + field_name + "\" is not a valid field name!");

    db_connection->queryOrDie("UPDATE metadata_presence_tracer SET field_presence='" + field_presence_str + "' WHERE journal_name="
                              + db_connection->escapeAndQuoteString(journal_name) + " AND field_name='" + field_name + "'");
    if (db_connection->getNoOfAffectedRows() == 0)
        LOG_ERROR("can't update non-existent database entry! (journal_name: \"" + journal_name + "\""
                  + ", field_name: \"" + field_name + "\"");
}

bool IsRecordValid(DbConnection * const db_connection, const MARC::Record &record,
                   std::map<std::string, JournalInfo> * const journal_name_to_info_map,
                   unsigned * const new_record_count, unsigned * const missed_expectation_count)
{
    const auto journal_name(record.getSuperiorTitle());
    if (journal_name.empty()) {
        LOG_WARNING("Record w/ control number \"" + record.getControlNumber() + "\" is missing a superior title!");
        ++(*missed_expectation_count);
        return false;
    }

    auto journal_name_and_info(journal_name_to_info_map->find(journal_name));
    bool first_record(false); // True if the current record is the first encounter of a journal
    if (journal_name_and_info == journal_name_to_info_map->end()) {
        first_record = true;
        JournalInfo new_journal_info;
        LoadFromDatabaseOrCreateFromScratch(db_connection, journal_name, &new_journal_info);
        (*journal_name_to_info_map)[journal_name] = new_journal_info;
        journal_name_and_info = journal_name_to_info_map->find(journal_name);
    }

    if (journal_name_and_info->second.isInDatabase()) {
        if (not RecordMeetsExpectations(record, journal_name_and_info->first, journal_name_and_info->second)) {
            ++(*missed_expectation_count);
            return false;
        }
    } else {
        AnalyseNewJournalRecord(record, first_record, &journal_name_and_info->second);
        ++(*new_record_count);
    }

    return true;
}

} // unnamed namespace

int Main(int argc, char *argv[]) {
    if (argc != 5)
        Usage();

    DbConnection db_connection;

    if (std::strcmp(argv[1], "update_db") == 0) {
        UpdateDB(&db_connection, argv[2], argv[3], argv[4]);
        return EXIT_SUCCESS;
    }

    auto reader(MARC::Reader::Factory(argv[1]));
    auto valid_records_writer(MARC::Writer::Factory(argv[2]));
    auto delinquent_records_writer(MARC::Writer::Factory(argv[3]));
    std::map<std::string, JournalInfo> journal_name_to_info_map;
    const std::string email_address(argv[4]);

    unsigned total_record_count(0), new_record_count(0), missed_expectation_count(0);
    while (const auto record = reader->read()) {
        ++total_record_count;
        if (IsRecordValid(&db_connection, record, &journal_name_to_info_map,
                          &new_record_count, &missed_expectation_count))
            valid_records_writer->write(record);
        else
            delinquent_records_writer->write(record);
    }

    for (const auto &journal_name_and_info : journal_name_to_info_map) {
        if (not journal_name_and_info.second.isInDatabase())
            WriteToDatabase(&db_connection, journal_name_and_info.first, journal_name_and_info.second);
    }

    if (missed_expectation_count > 0) {
        // send notification to the email address
        SendEmail(email_address, "validate_harvested_records encountered warnings (from: " + DnsUtil::GetHostname() + ")",
                  "Some records missed expectations with respect to MARC fields. "
                  "Check the log at '/usr/local/var/log/tuefind/zts_harvester_delivery_pipeline.log' for details.");
    }

    LOG_INFO("Processed " + std::to_string(total_record_count) + " record(s) of which " + std::to_string(new_record_count)
             + " was/were (a) record(s) of new journals and " + std::to_string(missed_expectation_count)
             + " record(s) missed expectations.");

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#include <rang.hpp>
#include <cstdlib>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
#include <regex>
#include <date.h>

#include "Tools/Display/Terminal/Terminal.hpp"

#ifdef ENABLE_MPI
#include <mpi.h>
#endif

#include "Tools/general_utils.h"
#include "Tools/system_functions.h"
#include "Tools/Display/rang_format/rang_format.h"
#include "Tools/Exception/exception.hpp"

#include "Factory/Module/Source/Source.hpp"
#include "Factory/Module/CRC/CRC.hpp"
#include "Factory/Module/Encoder/Encoder.hpp"
#include "Factory/Module/Puncturer/Puncturer.hpp"
#include "Factory/Module/Interleaver/Interleaver.hpp"
#include "Factory/Module/Modem/Modem.hpp"
#include "Factory/Module/Channel/Channel.hpp"
#include "Factory/Module/Quantizer/Quantizer.hpp"
#include "Factory/Module/Decoder/Decoder.hpp"
#include "Factory/Module/Monitor/Monitor.hpp"
#include "Factory/Tools/Display/Terminal/Terminal.hpp"

#include "Launcher.hpp"

using namespace aff3ct;
using namespace aff3ct::launcher;

Launcher::Launcher(const int argc, const char **argv, factory::Simulation::parameters &params_common,
                   std::ostream &stream)
: simu(nullptr), ah(argc, argv), params_common(params_common), stream(stream)
{
	cmd_line += std::string(argv[0]) + std::string(" ");
	for (auto i = 1; i < argc; i++)
	{
		if (argv[i][0] == '-')
			cmd_line += std::string(argv[i]);
		else
			cmd_line += std::string("\"") + std::string(argv[i]) + std::string("\"");

		cmd_line += std::string(" ");
	}
}

Launcher::~Launcher()
{
}

void Launcher::get_description_args()
{
}

void Launcher::store_args()
{
}

int Launcher::read_arguments()
{
	this->get_description_args();

	std::vector<std::string> cmd_error;

	this->arg_vals = ah.parse_arguments(this->args, this->cmd_warn, cmd_error);

	try
	{
		this->store_args();
	}
	catch(const std::exception& e)
	{
		auto save = tools::exception::no_backtrace;
		tools::exception::no_backtrace = true;
		cmd_error.emplace_back(e.what());
		tools::exception::no_backtrace = save;
	}

#ifdef ENABLE_MPI
	if (this->params_common.mpi_rank == 0)
	{
#endif
		if (params_common.display_help)
		{
			auto grps = factory::Factory::create_groups({&params_common});
			ah.print_help(this->args, grps, params_common.display_adv_help);
		}

		// print usage
		if (!cmd_error.empty() && !params_common.display_help)
			ah.print_usage(this->args);

		// print the errors
		if (!cmd_error.empty()) std::cerr << std::endl;
		for (unsigned e = 0; e < cmd_error.size(); e++)
			std::cerr << rang::tag::error << cmd_error[e] << std::endl;

		// print the help tags
		if (!cmd_error.empty() && !params_common.display_help)
		{
			tools::Argument_tag help_tag = {"help", "h"};

			std::string message = "For more information please display the help (\"";
			message += tools::Argument_handler::print_tag(help_tag) += "\").";

			std::cerr << std::endl << rang::tag::info << message << std::endl;
		}
#ifdef ENABLE_MPI
	}
#endif

	return (!cmd_error.empty() || params_common.display_help) ? EXIT_FAILURE : EXIT_SUCCESS;
}

void Launcher::print_header()
{
	// display configuration and simulation parameters
	stream << rang::tag::comment << rang::style::bold << "----------------------------------------------------" << std::endl;
	stream << rang::tag::comment << rang::style::bold << "---- A FAST FORWARD ERROR CORRECTION TOOLBOX >> ----" << std::endl;
	stream << rang::tag::comment << rang::style::bold << "----------------------------------------------------" << std::endl;
	stream << rang::tag::comment << rang::style::bold << rang::style::underline << "Parameters :"<< rang::style::reset << std::endl;
	factory::Header::print_parameters({&params_common}, false, this->stream);
	this->stream << rang::tag::comment << std::endl;
}

std::string remove_sim_meta(const std::string& cmd)
{
	const std::string simmeta = " --sim-meta ";
	auto pos_arg = cmd.find(simmeta);

	if (pos_arg == std::string::npos)
		return cmd;

	auto pos_start = cmd.find("\"", pos_arg + simmeta.size());
	auto pos_end   = cmd.find("\"", pos_start + 1);

	return cmd.substr(0, pos_arg) + cmd.substr(pos_end + 1);
}

int Launcher::launch()
{
	int exit_code = EXIT_SUCCESS;

	std::srand((unsigned)this->params_common.global_seed);

	// in case of the user call launch multiple times
	if (simu != nullptr)
	{
		delete simu;
		simu = nullptr;
	}

	if (this->read_arguments() == EXIT_FAILURE)
	{
		// print the warnings
#ifdef ENABLE_MPI
		if (this->params_common.mpi_rank == 0)
#endif
			for (unsigned w = 0; w < this->cmd_warn.size(); w++)
				std::clog << rang::tag::warning << this->cmd_warn[w] << std::endl;
		return EXIT_FAILURE;
	}

	// write the command and he curve name in the PyBER format
#ifdef ENABLE_MPI
	if (this->params_common.mpi_rank == 0)
#endif
	if (!this->params_common.meta.empty())
	{
		stream << "[metadata]" << std::endl;
		stream << "command=" << remove_sim_meta(cmd_line) << std::endl;
		stream << "title=" << this->params_common.meta << std::endl;
		stream << std::endl << "[trace]" << std::endl;
	}

	if (this->params_common.display_legend)
#ifdef ENABLE_MPI
		if (this->params_common.mpi_rank == 0)
#endif
			this->print_header();

	// print the warnings
#ifdef ENABLE_MPI
	if (this->params_common.mpi_rank == 0)
#endif
		for (unsigned w = 0; w < this->cmd_warn.size(); w++)
			std::clog << rang::tag::warning << this->cmd_warn[w] << std::endl;

	try
	{
		simu = this->build_simu();
	}
	catch(const std::exception& e)
	{
		rang::format_on_each_line(std::cerr, std::string(e.what()) + "\n", rang::tag::error);
		exit_code = EXIT_FAILURE;
	}

	if (simu != nullptr)
	{
		// launch the simulation
		if (this->params_common.display_legend)
#ifdef ENABLE_MPI
			if (this->params_common.mpi_rank == 0)
#endif
				stream << rang::tag::comment << "The simulation is running..." << std::endl;

		try
		{
			simu->launch();
			if (simu->is_error())
				exit_code = EXIT_FAILURE;
		}
		catch(const std::exception& e)
		{
			rang::format_on_each_line(std::cerr, std::string(e.what()) + "\n", rang::tag::error);
			exit_code = EXIT_FAILURE;
		}
	}

	if (this->params_common.display_legend)
#ifdef ENABLE_MPI
		if (this->params_common.mpi_rank == 0)
#endif
			stream << rang::tag::comment << "End of the simulation." << std::endl;

	if (simu != nullptr)
	{
		delete simu;
		simu = nullptr;
	}

	return exit_code;
}
<commit_msg>Put back regex if the compiler support it.<commit_after>#include <rang.hpp>
#include <cstdlib>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
#include <regex>
#include <date.h>

#include "Tools/Display/Terminal/Terminal.hpp"

#ifdef ENABLE_MPI
#include <mpi.h>
#endif

#include "Tools/general_utils.h"
#include "Tools/system_functions.h"
#include "Tools/Display/rang_format/rang_format.h"
#include "Tools/Exception/exception.hpp"

#include "Factory/Module/Source/Source.hpp"
#include "Factory/Module/CRC/CRC.hpp"
#include "Factory/Module/Encoder/Encoder.hpp"
#include "Factory/Module/Puncturer/Puncturer.hpp"
#include "Factory/Module/Interleaver/Interleaver.hpp"
#include "Factory/Module/Modem/Modem.hpp"
#include "Factory/Module/Channel/Channel.hpp"
#include "Factory/Module/Quantizer/Quantizer.hpp"
#include "Factory/Module/Decoder/Decoder.hpp"
#include "Factory/Module/Monitor/Monitor.hpp"
#include "Factory/Tools/Display/Terminal/Terminal.hpp"

#include "Launcher.hpp"

using namespace aff3ct;
using namespace aff3ct::launcher;

Launcher::Launcher(const int argc, const char **argv, factory::Simulation::parameters &params_common,
                   std::ostream &stream)
: simu(nullptr), ah(argc, argv), params_common(params_common), stream(stream)
{
	cmd_line += std::string(argv[0]) + std::string(" ");
	for (auto i = 1; i < argc; i++)
	{
		if (argv[i][0] == '-')
			cmd_line += std::string(argv[i]);
		else
			cmd_line += std::string("\"") + std::string(argv[i]) + std::string("\"");

		cmd_line += std::string(" ");
	}
}

Launcher::~Launcher()
{
}

void Launcher::get_description_args()
{
}

void Launcher::store_args()
{
}

int Launcher::read_arguments()
{
	this->get_description_args();

	std::vector<std::string> cmd_error;

	this->arg_vals = ah.parse_arguments(this->args, this->cmd_warn, cmd_error);

	try
	{
		this->store_args();
	}
	catch(const std::exception& e)
	{
		auto save = tools::exception::no_backtrace;
		tools::exception::no_backtrace = true;
		cmd_error.emplace_back(e.what());
		tools::exception::no_backtrace = save;
	}

#ifdef ENABLE_MPI
	if (this->params_common.mpi_rank == 0)
	{
#endif
		if (params_common.display_help)
		{
			auto grps = factory::Factory::create_groups({&params_common});
			ah.print_help(this->args, grps, params_common.display_adv_help);
		}

		// print usage
		if (!cmd_error.empty() && !params_common.display_help)
			ah.print_usage(this->args);

		// print the errors
		if (!cmd_error.empty()) std::cerr << std::endl;
		for (unsigned e = 0; e < cmd_error.size(); e++)
			std::cerr << rang::tag::error << cmd_error[e] << std::endl;

		// print the help tags
		if (!cmd_error.empty() && !params_common.display_help)
		{
			tools::Argument_tag help_tag = {"help", "h"};

			std::string message = "For more information please display the help (\"";
			message += tools::Argument_handler::print_tag(help_tag) += "\").";

			std::cerr << std::endl << rang::tag::info << message << std::endl;
		}
#ifdef ENABLE_MPI
	}
#endif

	return (!cmd_error.empty() || params_common.display_help) ? EXIT_FAILURE : EXIT_SUCCESS;
}

void Launcher::print_header()
{
	// display configuration and simulation parameters
	stream << rang::tag::comment << rang::style::bold << "----------------------------------------------------" << std::endl;
	stream << rang::tag::comment << rang::style::bold << "---- A FAST FORWARD ERROR CORRECTION TOOLBOX >> ----" << std::endl;
	stream << rang::tag::comment << rang::style::bold << "----------------------------------------------------" << std::endl;
	stream << rang::tag::comment << rang::style::bold << rang::style::underline << "Parameters :"<< rang::style::reset << std::endl;
	factory::Header::print_parameters({&params_common}, false, this->stream);
	this->stream << rang::tag::comment << std::endl;
}

std::string remove_sim_meta(const std::string& cmd)
{
#if !defined(__clang__) && !defined(__llvm__) && defined(__GNUC__) && defined(__cplusplus) && __GNUC__ < 5
	const std::string simmeta = " --sim-meta ";
	auto pos_arg = cmd.find(simmeta);

	if (pos_arg == std::string::npos)
		return cmd;

	auto pos_start = cmd.find("\"", pos_arg + simmeta.size());
	auto pos_end   = cmd.find("\"", pos_start + 1);

	return cmd.substr(0, pos_arg) + cmd.substr(pos_end + 1);
#else
	return std::regex_replace(cmd, std::regex("( --sim-meta \"[^\"]*\")"), "");
#endif
}

int Launcher::launch()
{
	int exit_code = EXIT_SUCCESS;

	std::srand((unsigned)this->params_common.global_seed);

	// in case of the user call launch multiple times
	if (simu != nullptr)
	{
		delete simu;
		simu = nullptr;
	}

	if (this->read_arguments() == EXIT_FAILURE)
	{
		// print the warnings
#ifdef ENABLE_MPI
		if (this->params_common.mpi_rank == 0)
#endif
			for (unsigned w = 0; w < this->cmd_warn.size(); w++)
				std::clog << rang::tag::warning << this->cmd_warn[w] << std::endl;
		return EXIT_FAILURE;
	}

	// write the command and he curve name in the PyBER format
#ifdef ENABLE_MPI
	if (this->params_common.mpi_rank == 0)
#endif
	if (!this->params_common.meta.empty())
	{
		stream << "[metadata]" << std::endl;
		stream << "command=" << remove_sim_meta(cmd_line) << std::endl;
		stream << "title=" << this->params_common.meta << std::endl;
		stream << std::endl << "[trace]" << std::endl;
	}

	if (this->params_common.display_legend)
#ifdef ENABLE_MPI
		if (this->params_common.mpi_rank == 0)
#endif
			this->print_header();

	// print the warnings
#ifdef ENABLE_MPI
	if (this->params_common.mpi_rank == 0)
#endif
		for (unsigned w = 0; w < this->cmd_warn.size(); w++)
			std::clog << rang::tag::warning << this->cmd_warn[w] << std::endl;

	try
	{
		simu = this->build_simu();
	}
	catch(const std::exception& e)
	{
		rang::format_on_each_line(std::cerr, std::string(e.what()) + "\n", rang::tag::error);
		exit_code = EXIT_FAILURE;
	}

	if (simu != nullptr)
	{
		// launch the simulation
		if (this->params_common.display_legend)
#ifdef ENABLE_MPI
			if (this->params_common.mpi_rank == 0)
#endif
				stream << rang::tag::comment << "The simulation is running..." << std::endl;

		try
		{
			simu->launch();
			if (simu->is_error())
				exit_code = EXIT_FAILURE;
		}
		catch(const std::exception& e)
		{
			rang::format_on_each_line(std::cerr, std::string(e.what()) + "\n", rang::tag::error);
			exit_code = EXIT_FAILURE;
		}
	}

	if (this->params_common.display_legend)
#ifdef ENABLE_MPI
		if (this->params_common.mpi_rank == 0)
#endif
			stream << rang::tag::comment << "End of the simulation." << std::endl;

	if (simu != nullptr)
	{
		delete simu;
		simu = nullptr;
	}

	return exit_code;
}
<|endoftext|>


<commit_before><commit_msg>related fdo#63230: Fix unit test for fdo#44286 to run in all locales<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: ofaitem.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: kz $ $Date: 2005-01-21 15:01:33 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _OFF_OFAITEM_HXX
#define _OFF_OFAITEM_HXX

// include ----------------------------------------------------------------

#ifndef _SFXPOOLITEM_HXX
#include <svtools/poolitem.hxx>
#endif

#ifndef INCLUDED_SVXDLLAPI_H
#include "svx/svxdllapi.h"
#endif

// class OfaPtrItem ------------------------------------------------------

class SVX_DLLPUBLIC OfaPtrItem : public SfxPoolItem
{
private:
    void* pPtr;

public:
                             OfaPtrItem( USHORT nWhich, void *pPtr );
                             OfaPtrItem( const OfaPtrItem& );

    virtual int              operator==( const SfxPoolItem& ) const;
    virtual SfxPoolItem*     Clone( SfxItemPool *pPool = 0 ) const;

    void*                    GetValue() const { return pPtr; }
    void                     SetValue( void* pNewPtr ) { pPtr = pNewPtr; }
};
/*
class SvxDashListPtrItem : public OfaPtrItem
{
    public:
                             TYPEINFO();

                             SvxDashListPtrItem( USHORT nWhich, SvxDashListItem* pPtr );
                             SvxDashListPtrItem( const DashListPtrItem& );

    virtual int              operator==( const SfxPoolItem& ) const;
    virtual SfxPoolItem*     Clone( SfxItemPool *pPool = 0 ) const;

    virtual sal_Bool         QueryValue( com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 ) const;
    virtual sal_Bool         PutValue( const com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 );

    SvxDashListPtrItem*      GetValue() const { return OfaPtrItem::GetValue(); }
};
*/
#endif
<commit_msg>INTEGRATION: CWS ooo19126 (1.4.430); FILE MERGED 2005/09/05 14:15:51 rt 1.4.430.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ofaitem.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 18:09:48 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _OFF_OFAITEM_HXX
#define _OFF_OFAITEM_HXX

// include ----------------------------------------------------------------

#ifndef _SFXPOOLITEM_HXX
#include <svtools/poolitem.hxx>
#endif

#ifndef INCLUDED_SVXDLLAPI_H
#include "svx/svxdllapi.h"
#endif

// class OfaPtrItem ------------------------------------------------------

class SVX_DLLPUBLIC OfaPtrItem : public SfxPoolItem
{
private:
    void* pPtr;

public:
                             OfaPtrItem( USHORT nWhich, void *pPtr );
                             OfaPtrItem( const OfaPtrItem& );

    virtual int              operator==( const SfxPoolItem& ) const;
    virtual SfxPoolItem*     Clone( SfxItemPool *pPool = 0 ) const;

    void*                    GetValue() const { return pPtr; }
    void                     SetValue( void* pNewPtr ) { pPtr = pNewPtr; }
};
/*
class SvxDashListPtrItem : public OfaPtrItem
{
    public:
                             TYPEINFO();

                             SvxDashListPtrItem( USHORT nWhich, SvxDashListItem* pPtr );
                             SvxDashListPtrItem( const DashListPtrItem& );

    virtual int              operator==( const SfxPoolItem& ) const;
    virtual SfxPoolItem*     Clone( SfxItemPool *pPool = 0 ) const;

    virtual sal_Bool         QueryValue( com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 ) const;
    virtual sal_Bool         PutValue( const com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 );

    SvxDashListPtrItem*      GetValue() const { return OfaPtrItem::GetValue(); }
};
*/
#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: optgrid.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: hr $ $Date: 2003-03-27 14:59:46 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SVX_OPTGRID_HXX
#define _SVX_OPTGRID_HXX

// include ---------------------------------------------------------------

#ifndef _SFXTABDLG_HXX //autogen
#include <sfx2/tabdlg.hxx>
#endif
#ifndef _SFXENUMITEM_HXX //autogen
#include <svtools/eitem.hxx>
#endif
#ifndef _SV_GROUP_HXX //autogen
#include <vcl/group.hxx>
#endif
#ifndef _SV_FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif
#ifndef _SV_FIELD_HXX //autogen
#include <vcl/field.hxx>
#endif

class SvxGridTabPage;

// class SvxOptionsGrid --------------------------------------------------

class SvxOptionsGrid
{
protected:
    UINT32  nFldDrawX;
    UINT32  nFldDivisionX;
    UINT32  nFldDrawY;
    UINT32  nFldDivisionY;
    UINT32  nFldSnapX;
    UINT32  nFldSnapY;
    BOOL    bUseGridsnap:1;
    BOOL    bSynchronize:1;
    BOOL    bGridVisible:1;
    BOOL    bEqualGrid:  1;

public:
    SvxOptionsGrid();
    ~SvxOptionsGrid();

    void    SetFldDrawX(    UINT32 nSet){nFldDrawX      = nSet;}
    void    SetFldDivisionX(UINT32 nSet){nFldDivisionX  = nSet;}
    void    SetFldDrawY   ( UINT32 nSet){nFldDrawY      = nSet;}
    void    SetFldDivisionY(UINT32 nSet){nFldDivisionY  = nSet;}
    void    SetFldSnapX(    UINT32 nSet){nFldSnapX      = nSet;}
    void    SetFldSnapY   ( UINT32 nSet){nFldSnapY      = nSet;}
    void    SetUseGridSnap( BOOL bSet ) {bUseGridsnap   = bSet;}
    void    SetSynchronize( BOOL bSet ) {bSynchronize   = bSet;}
    void    SetGridVisible( BOOL bSet ) {bGridVisible   = bSet;}
    void    SetEqualGrid( BOOL bSet )   {bEqualGrid     = bSet;}

    UINT32  GetFldDrawX(    ) const {  return nFldDrawX;    }
    UINT32  GetFldDivisionX() const {  return nFldDivisionX;}
    UINT32  GetFldDrawY   ( ) const {  return nFldDrawY;    }
    UINT32  GetFldDivisionY() const {  return nFldDivisionY;}
    UINT32  GetFldSnapX(    ) const {  return nFldSnapX;    }
    UINT32  GetFldSnapY   ( ) const {  return nFldSnapY;    }
    BOOL    GetUseGridSnap( ) const {  return bUseGridsnap; }
    BOOL    GetSynchronize( ) const {  return bSynchronize; }
    BOOL    GetGridVisible( ) const {  return bGridVisible; }
    BOOL    GetEqualGrid()    const {  return bEqualGrid;   }
};

// class SvxGridItem -----------------------------------------------------

class SvxGridItem : public SvxOptionsGrid, public SfxPoolItem
{
    // #i9076#
    friend class SvxGridTabPage;

public:
    SvxGridItem( USHORT nWhich) : SfxPoolItem(nWhich){};
    SvxGridItem( const SvxGridItem& pTestItem );

    virtual SfxPoolItem*    Clone( SfxItemPool *pPool = 0 ) const;
    virtual int             operator==( const SfxPoolItem& ) const;

    virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres,
                                    SfxMapUnit eCoreMetric,
                                    SfxMapUnit ePresMetric,
                                    String &rText, const IntlWrapper * = 0 ) const;

};

// class SvxGridTabPage --------------------------------------------------

class SvxGridTabPage : public SfxTabPage
{
public:
    SvxGridTabPage( Window* pParent, const SfxItemSet& rSet );

    static SfxTabPage*  Create( Window* pParent, const SfxItemSet& rAttrSet );

    virtual BOOL        FillItemSet( SfxItemSet& rSet );
    virtual void        Reset( const SfxItemSet& rSet );

    virtual void        ActivatePage( const SfxItemSet& rSet );
    virtual int         DeactivatePage( SfxItemSet* pSet );

private:
    CheckBox            aCbxUseGridsnap;
    CheckBox            aCbxGridVisible;

    FixedLine           aFlResolution;
    FixedText           aFtDrawX;
    MetricField         aMtrFldDrawX;
    FixedText           aFtDrawY;
    MetricField         aMtrFldDrawY;

    FixedLine           aFlDivision;
    FixedText           aFtDivisionX;
    NumericField        aNumFldDivisionX;
    FixedText           aDivisionPointX;

    FixedText           aFtDivisionY;
    NumericField        aNumFldDivisionY;
    FixedText           aDivisionPointY;

    CheckBox            aCbxSynchronize;
    FixedLine           aGrpDrawGrid; // Neu

protected:
    //these controls are used in draw and impress
    FixedLine       aGrpSnap;
    CheckBox        aCbxSnapHelplines;
    CheckBox        aCbxSnapBorder;
    CheckBox        aCbxSnapFrame;
    CheckBox        aCbxSnapPoints;
    FixedText       aFtSnapArea;
    MetricField     aMtrFldSnapArea;

    FixedLine       aSeparatorFL;

    FixedLine       aGrpOrtho;
    CheckBox        aCbxOrtho;
    CheckBox        aCbxBigOrtho;
    CheckBox        aCbxRotate;
    MetricField     aMtrFldAngle;
    FixedText       aFtBezAngle;
    MetricField     aMtrFldBezAngle;

private:
    BOOL                bAttrModified;
    BOOL                bEqualGrid; // Neu

#ifdef _SVX_OPTGRID_CXX
    DECL_LINK( ClickRotateHdl_Impl, void * );
    DECL_LINK( ChangeDrawHdl_Impl, MetricField * );
    DECL_LINK( ChangeGridsnapHdl_Impl, void * );
    DECL_LINK( ChangeDivisionHdl_Impl, NumericField * );

#endif
};

#endif

<commit_msg>INTEGRATION: CWS visibility01 (1.9.854); FILE MERGED 2004/12/06 08:10:31 mnicel 1.9.854.2: Part of symbol visibility markup - #i35758# 2004/11/19 12:54:20 mmeeks 1.9.854.1: Issue number: #i35758# Submitted by: mnicel Reviewed by:  mmeeks<commit_after>/*************************************************************************
 *
 *  $RCSfile: optgrid.hxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: kz $ $Date: 2005-01-21 15:02:36 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SVX_OPTGRID_HXX
#define _SVX_OPTGRID_HXX

// include ---------------------------------------------------------------

#ifndef _SFXTABDLG_HXX //autogen
#include <sfx2/tabdlg.hxx>
#endif
#ifndef _SFXENUMITEM_HXX //autogen
#include <svtools/eitem.hxx>
#endif
#ifndef _SV_GROUP_HXX //autogen
#include <vcl/group.hxx>
#endif
#ifndef _SV_FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif
#ifndef _SV_FIELD_HXX //autogen
#include <vcl/field.hxx>
#endif

#ifndef INCLUDED_SVXDLLAPI_H
#include "svx/svxdllapi.h"
#endif

class SvxGridTabPage;

// class SvxOptionsGrid --------------------------------------------------

class SVX_DLLPUBLIC SvxOptionsGrid
{
protected:
    UINT32  nFldDrawX;
    UINT32  nFldDivisionX;
    UINT32  nFldDrawY;
    UINT32  nFldDivisionY;
    UINT32  nFldSnapX;
    UINT32  nFldSnapY;
    BOOL    bUseGridsnap:1;
    BOOL    bSynchronize:1;
    BOOL    bGridVisible:1;
    BOOL    bEqualGrid:  1;

public:
    SvxOptionsGrid();
    ~SvxOptionsGrid();

    void    SetFldDrawX(    UINT32 nSet){nFldDrawX      = nSet;}
    void    SetFldDivisionX(UINT32 nSet){nFldDivisionX  = nSet;}
    void    SetFldDrawY   ( UINT32 nSet){nFldDrawY      = nSet;}
    void    SetFldDivisionY(UINT32 nSet){nFldDivisionY  = nSet;}
    void    SetFldSnapX(    UINT32 nSet){nFldSnapX      = nSet;}
    void    SetFldSnapY   ( UINT32 nSet){nFldSnapY      = nSet;}
    void    SetUseGridSnap( BOOL bSet ) {bUseGridsnap   = bSet;}
    void    SetSynchronize( BOOL bSet ) {bSynchronize   = bSet;}
    void    SetGridVisible( BOOL bSet ) {bGridVisible   = bSet;}
    void    SetEqualGrid( BOOL bSet )   {bEqualGrid     = bSet;}

    UINT32  GetFldDrawX(    ) const {  return nFldDrawX;    }
    UINT32  GetFldDivisionX() const {  return nFldDivisionX;}
    UINT32  GetFldDrawY   ( ) const {  return nFldDrawY;    }
    UINT32  GetFldDivisionY() const {  return nFldDivisionY;}
    UINT32  GetFldSnapX(    ) const {  return nFldSnapX;    }
    UINT32  GetFldSnapY   ( ) const {  return nFldSnapY;    }
    BOOL    GetUseGridSnap( ) const {  return bUseGridsnap; }
    BOOL    GetSynchronize( ) const {  return bSynchronize; }
    BOOL    GetGridVisible( ) const {  return bGridVisible; }
    BOOL    GetEqualGrid()    const {  return bEqualGrid;   }
};

// class SvxGridItem -----------------------------------------------------

class SVX_DLLPUBLIC SvxGridItem : public SvxOptionsGrid, public SfxPoolItem
{
    // #i9076#
    friend class SvxGridTabPage;

public:
    SvxGridItem( USHORT nWhich) : SfxPoolItem(nWhich){};
    SvxGridItem( const SvxGridItem& pTestItem );

    virtual SfxPoolItem*    Clone( SfxItemPool *pPool = 0 ) const;
    virtual int             operator==( const SfxPoolItem& ) const;

    virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres,
                                    SfxMapUnit eCoreMetric,
                                    SfxMapUnit ePresMetric,
                                    String &rText, const IntlWrapper * = 0 ) const;

};

// class SvxGridTabPage --------------------------------------------------

class SVX_DLLPUBLIC SvxGridTabPage : public SfxTabPage
{
public:
    SvxGridTabPage( Window* pParent, const SfxItemSet& rSet );

    static SfxTabPage*  Create( Window* pParent, const SfxItemSet& rAttrSet );

    virtual BOOL        FillItemSet( SfxItemSet& rSet );
    virtual void        Reset( const SfxItemSet& rSet );

    virtual void        ActivatePage( const SfxItemSet& rSet );
    virtual int         DeactivatePage( SfxItemSet* pSet );

private:
    CheckBox            aCbxUseGridsnap;
    CheckBox            aCbxGridVisible;

    FixedLine           aFlResolution;
    FixedText           aFtDrawX;
    MetricField         aMtrFldDrawX;
    FixedText           aFtDrawY;
    MetricField         aMtrFldDrawY;

    FixedLine           aFlDivision;
    FixedText           aFtDivisionX;
    NumericField        aNumFldDivisionX;
    FixedText           aDivisionPointX;

    FixedText           aFtDivisionY;
    NumericField        aNumFldDivisionY;
    FixedText           aDivisionPointY;

    CheckBox            aCbxSynchronize;
    FixedLine           aGrpDrawGrid; // Neu

protected:
    //these controls are used in draw and impress
    FixedLine       aGrpSnap;
    CheckBox        aCbxSnapHelplines;
    CheckBox        aCbxSnapBorder;
    CheckBox        aCbxSnapFrame;
    CheckBox        aCbxSnapPoints;
    FixedText       aFtSnapArea;
    MetricField     aMtrFldSnapArea;

    FixedLine       aSeparatorFL;

    FixedLine       aGrpOrtho;
    CheckBox        aCbxOrtho;
    CheckBox        aCbxBigOrtho;
    CheckBox        aCbxRotate;
    MetricField     aMtrFldAngle;
    FixedText       aFtBezAngle;
    MetricField     aMtrFldBezAngle;

private:
    BOOL                bAttrModified;
    BOOL                bEqualGrid; // Neu

#ifdef _SVX_OPTGRID_CXX
    DECL_LINK( ClickRotateHdl_Impl, void * );
    DECL_LINK( ChangeDrawHdl_Impl, MetricField * );
    DECL_LINK( ChangeGridsnapHdl_Impl, void * );
    DECL_LINK( ChangeDivisionHdl_Impl, NumericField * );

#endif
};

#endif

<|endoftext|>


<commit_before>//
//  riscv-disasm.cc
//

#include <cstdio>
#include <cstring>
#include <map>
#include <algorithm>
#include <functional>
#include <vector>
#include <string>

#include "riscv-types.h"
#include "riscv-format.h"
#include "riscv-opcodes.h"
#include "riscv-imm.h"
#include "riscv-regs.h"
#include "riscv-decode.h"
#include "riscv-csr.h"
#include "riscv-processor.h"
#include "riscv-compression.h"
#include "riscv-format.h"
#include "riscv-disasm.h"

const char* riscv_null_symbol_lookup(riscv_ptr) { return nullptr; }
const char* riscv_null_symbol_colorize(const char *type) { return ""; }

const void print_add(size_t &offset, const char *str)
{
	printf("%s", str);
	offset += strlen(str);
}

const void print_pad(size_t &offset, size_t pad_to)
{
	static const char *space32 = "                                        ";
	printf("%s", space32 + strlen(space32) - std::max((pad_to - offset), 0UL));
	offset += std::max((pad_to - offset), 0UL);
}

const void print_fmt(size_t &offset, const char* fmt, ...)
{
    std::vector<char> buf(32);
    va_list ap;

    va_start(ap, fmt);
    int len = vsnprintf(buf.data(), buf.capacity(), fmt, ap);
    va_end(ap);

    std::string str;
    if (len >= (int)buf.capacity()) {
        buf.resize(len + 1);
        va_start(ap, fmt);
        vsnprintf(buf.data(), buf.capacity(), fmt, ap);
        va_end(ap);
    }
    printf("%s", buf.data());
    offset += strlen(buf.data());
}

const void print_pad(size_t &offset, size_t pad_to, const char *str)
{
	print_add(offset, str);
	print_pad(offset, pad_to);
}

const void print_addr(size_t &offset, uint64_t addr,
	riscv_symbol_name_fn symlookup, riscv_symbol_colorize_fn colorize)
{
	print_pad(offset, 90);
	printf("%s", colorize("address"));
	print_add(offset, "# ");
	print_fmt(offset, "0x%016tx", addr);
	printf("%s", colorize("reset"));
	const char* symbol_name = symlookup((riscv_ptr)addr);
	if (symbol_name) {
		printf("%s", colorize("symbol"));
		print_fmt(offset, " <%s>", symbol_name);
		printf("%s", colorize("reset"));
	}
}

void riscv_disasm_instruction(riscv_decode &dec, riscv_decode &last_dec,
	riscv_proc_state *proc, riscv_ptr pc, riscv_ptr next_pc, riscv_ptr pc_offset,
	riscv_symbol_name_fn symlookup, riscv_symbol_colorize_fn colorize)
{
	// decompress opcode if compressed
	const riscv_inst_comp_metadata *comp = riscv_lookup_comp_metadata((riscv_op)dec.op);
	if (comp) {
		dec.op = comp->op;
		dec.type = comp->type;
	}

	size_t offset = 0;
	const rvf *fmt = riscv_instruction_format[dec.op];
	const uint64_t addr = (pc - pc_offset);
	const char* symbol_name = symlookup((riscv_ptr)addr);

	// print symbol name if present
	if (symbol_name) {
		printf("%s", colorize("symbol"));
		print_fmt(offset, "%30s", symbol_name);
		print_add(offset, ": ");
		printf("%s", colorize("reset"));
	} else {
		print_fmt(offset, "%30s", "");
		print_add(offset, "  ");
	}

	// print address
	printf("%s", colorize("address"));
	print_fmt(offset, "%016tx:   ", addr);
	printf("%s", colorize("reset"));

	// print instruction bytes
	switch (next_pc - pc) {
		case 2: print_fmt(offset, "%04x", *(riscv_hu*)pc); break;
		case 4: print_fmt(offset, "%08x", *(riscv_wu*)pc); break;
	}
	print_pad(offset, 64);

	// print opcode
	printf("%s", colorize("opcode"));
	print_pad(offset, 74, riscv_instruction_name[dec.op]);
	printf("%s", colorize("reset"));

	// print arguments
	while (*fmt != rvf_z) {
		switch (*fmt) {
			case rvf_b:    print_add(offset, "("); break;
			case rvf_c:    print_add(offset, ","); break;
			case rvf_d:    print_add(offset, ")"); break;
			case rvf_rd:   print_add(offset, riscv_i_registers[dec.rd]); break;
			case rvf_rs1:  print_add(offset, riscv_i_registers[dec.rs1]); break;
			case rvf_rs2:  print_add(offset, riscv_i_registers[dec.rs2]); break;
			case rvf_frd:  print_add(offset, riscv_f_registers[dec.rd]); break;
			case rvf_frs1: print_add(offset, riscv_f_registers[dec.rs1]); break;
			case rvf_frs2: print_add(offset, riscv_f_registers[dec.rs2]); break;
			case rvf_frs3: print_add(offset, riscv_f_registers[dec.rs3]); break;
			case rvf_irs1: print_fmt(offset, "%d", dec.rs1); break;
			case rvf_imm:  print_fmt(offset, "%lld", dec.imm); break;
			case rvf_ipc:
			{
				uint64_t addr = pc - pc_offset + dec.imm;
				print_fmt(offset, "%lld", dec.imm);
				print_addr(offset, addr, symlookup, colorize);
				break;
			}
			case rvf_csr:
			{
				const riscv_csr_metadata *csr = riscv_lookup_csr_metadata(dec.imm);
				if (csr) print_fmt(offset, "%s", csr->csr_name);
				else print_fmt(offset, "%llu", dec.imm);
				break;
			}
			case rvf_z: break;
		}
		fmt++;
	}

	// handle lui and auipc combos
	switch (last_dec.op) {
		case riscv_op_lui:
			switch (dec.op) {
				case riscv_op_addi:
					if (last_dec.rd == dec.rd && last_dec.rd == dec.rs1) {
						uint64_t addr = last_dec.imm + dec.imm;
						print_addr(offset, addr, symlookup, colorize);
					}
					break;
			}
			break;
		case riscv_op_auipc:
			switch (dec.op) {
				case riscv_op_addi:
					if (last_dec.rd == dec.rd && last_dec.rd == dec.rs1) {
						uint64_t addr = pc - pc_offset + last_dec.imm + dec.imm - 4;
						print_addr(offset, addr, symlookup, colorize);
					}
					break;
				case riscv_op_jalr:
					if (last_dec.rd == dec.rs1) {
						uint64_t addr = pc - pc_offset + last_dec.imm + dec.imm - 4;
						print_addr(offset, addr, symlookup, colorize);
					}
					break;
			}
			break;
	}

	printf("\n");
}
<commit_msg>Add #include <cstdlib> to riscv-disasm.cc<commit_after>//
//  riscv-disasm.cc
//

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <map>
#include <algorithm>
#include <functional>
#include <vector>
#include <string>

#include "riscv-types.h"
#include "riscv-format.h"
#include "riscv-opcodes.h"
#include "riscv-imm.h"
#include "riscv-regs.h"
#include "riscv-decode.h"
#include "riscv-csr.h"
#include "riscv-processor.h"
#include "riscv-compression.h"
#include "riscv-format.h"
#include "riscv-disasm.h"

const char* riscv_null_symbol_lookup(riscv_ptr) { return nullptr; }
const char* riscv_null_symbol_colorize(const char *type) { return ""; }

const void print_add(size_t &offset, const char *str)
{
	printf("%s", str);
	offset += strlen(str);
}

const void print_pad(size_t &offset, size_t pad_to)
{
	static const char *space32 = "                                        ";
	printf("%s", space32 + strlen(space32) - std::max((pad_to - offset), 0UL));
	offset += std::max((pad_to - offset), 0UL);
}

const void print_fmt(size_t &offset, const char* fmt, ...)
{
    std::vector<char> buf(32);
    va_list ap;

    va_start(ap, fmt);
    int len = vsnprintf(buf.data(), buf.capacity(), fmt, ap);
    va_end(ap);

    std::string str;
    if (len >= (int)buf.capacity()) {
        buf.resize(len + 1);
        va_start(ap, fmt);
        vsnprintf(buf.data(), buf.capacity(), fmt, ap);
        va_end(ap);
    }
    printf("%s", buf.data());
    offset += strlen(buf.data());
}

const void print_pad(size_t &offset, size_t pad_to, const char *str)
{
	print_add(offset, str);
	print_pad(offset, pad_to);
}

const void print_addr(size_t &offset, uint64_t addr,
	riscv_symbol_name_fn symlookup, riscv_symbol_colorize_fn colorize)
{
	print_pad(offset, 90);
	printf("%s", colorize("address"));
	print_add(offset, "# ");
	print_fmt(offset, "0x%016tx", addr);
	printf("%s", colorize("reset"));
	const char* symbol_name = symlookup((riscv_ptr)addr);
	if (symbol_name) {
		printf("%s", colorize("symbol"));
		print_fmt(offset, " <%s>", symbol_name);
		printf("%s", colorize("reset"));
	}
}

void riscv_disasm_instruction(riscv_decode &dec, riscv_decode &last_dec,
	riscv_proc_state *proc, riscv_ptr pc, riscv_ptr next_pc, riscv_ptr pc_offset,
	riscv_symbol_name_fn symlookup, riscv_symbol_colorize_fn colorize)
{
	// decompress opcode if compressed
	const riscv_inst_comp_metadata *comp = riscv_lookup_comp_metadata((riscv_op)dec.op);
	if (comp) {
		dec.op = comp->op;
		dec.type = comp->type;
	}

	size_t offset = 0;
	const rvf *fmt = riscv_instruction_format[dec.op];
	const uint64_t addr = (pc - pc_offset);
	const char* symbol_name = symlookup((riscv_ptr)addr);

	// print symbol name if present
	if (symbol_name) {
		printf("%s", colorize("symbol"));
		print_fmt(offset, "%30s", symbol_name);
		print_add(offset, ": ");
		printf("%s", colorize("reset"));
	} else {
		print_fmt(offset, "%30s", "");
		print_add(offset, "  ");
	}

	// print address
	printf("%s", colorize("address"));
	print_fmt(offset, "%016tx:   ", addr);
	printf("%s", colorize("reset"));

	// print instruction bytes
	switch (next_pc - pc) {
		case 2: print_fmt(offset, "%04x", *(riscv_hu*)pc); break;
		case 4: print_fmt(offset, "%08x", *(riscv_wu*)pc); break;
	}
	print_pad(offset, 64);

	// print opcode
	printf("%s", colorize("opcode"));
	print_pad(offset, 74, riscv_instruction_name[dec.op]);
	printf("%s", colorize("reset"));

	// print arguments
	while (*fmt != rvf_z) {
		switch (*fmt) {
			case rvf_b:    print_add(offset, "("); break;
			case rvf_c:    print_add(offset, ","); break;
			case rvf_d:    print_add(offset, ")"); break;
			case rvf_rd:   print_add(offset, riscv_i_registers[dec.rd]); break;
			case rvf_rs1:  print_add(offset, riscv_i_registers[dec.rs1]); break;
			case rvf_rs2:  print_add(offset, riscv_i_registers[dec.rs2]); break;
			case rvf_frd:  print_add(offset, riscv_f_registers[dec.rd]); break;
			case rvf_frs1: print_add(offset, riscv_f_registers[dec.rs1]); break;
			case rvf_frs2: print_add(offset, riscv_f_registers[dec.rs2]); break;
			case rvf_frs3: print_add(offset, riscv_f_registers[dec.rs3]); break;
			case rvf_irs1: print_fmt(offset, "%d", dec.rs1); break;
			case rvf_imm:  print_fmt(offset, "%lld", dec.imm); break;
			case rvf_ipc:
			{
				uint64_t addr = pc - pc_offset + dec.imm;
				print_fmt(offset, "%lld", dec.imm);
				print_addr(offset, addr, symlookup, colorize);
				break;
			}
			case rvf_csr:
			{
				const riscv_csr_metadata *csr = riscv_lookup_csr_metadata(dec.imm);
				if (csr) print_fmt(offset, "%s", csr->csr_name);
				else print_fmt(offset, "%llu", dec.imm);
				break;
			}
			case rvf_z: break;
		}
		fmt++;
	}

	// handle lui and auipc combos
	switch (last_dec.op) {
		case riscv_op_lui:
			switch (dec.op) {
				case riscv_op_addi:
					if (last_dec.rd == dec.rd && last_dec.rd == dec.rs1) {
						uint64_t addr = last_dec.imm + dec.imm;
						print_addr(offset, addr, symlookup, colorize);
					}
					break;
			}
			break;
		case riscv_op_auipc:
			switch (dec.op) {
				case riscv_op_addi:
					if (last_dec.rd == dec.rd && last_dec.rd == dec.rs1) {
						uint64_t addr = pc - pc_offset + last_dec.imm + dec.imm - 4;
						print_addr(offset, addr, symlookup, colorize);
					}
					break;
				case riscv_op_jalr:
					if (last_dec.rd == dec.rs1) {
						uint64_t addr = pc - pc_offset + last_dec.imm + dec.imm - 4;
						print_addr(offset, addr, symlookup, colorize);
					}
					break;
			}
			break;
	}

	printf("\n");
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: swcalwrp.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: vg $ $Date: 2006-04-07 15:07:20 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SWCALWRP_HXX
#define _SWCALWRP_HXX

#ifndef INCLUDED_I18NPOOL_LANG_H
#include <i18npool/lang.h>
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif
#ifndef _UNOTOOLS_CALENDARWRAPPER_HXX
#include <unotools/calendarwrapper.hxx>
#endif

class SwCalendarWrapper : public CalendarWrapper
{
    String sUniqueId;
    USHORT nLang;

public:
    SwCalendarWrapper( const ::com::sun::star::uno::Reference<
                    ::com::sun::star::lang::XMultiServiceFactory > & xMSF )
        : CalendarWrapper( xMSF ), nLang( LANGUAGE_SYSTEM )
    {}

    void LoadDefaultCalendar( USHORT nLang );
};

extern SwCalendarWrapper* pCalendarWrapper;

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.4.934); FILE MERGED 2008/04/01 15:56:20 thb 1.4.934.2: #i85898# Stripping all external header guards 2008/03/31 16:52:42 rt 1.4.934.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: swcalwrp.hxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _SWCALWRP_HXX
#define _SWCALWRP_HXX

#include <i18npool/lang.h>
#include <tools/string.hxx>
#include <unotools/calendarwrapper.hxx>

class SwCalendarWrapper : public CalendarWrapper
{
    String sUniqueId;
    USHORT nLang;

public:
    SwCalendarWrapper( const ::com::sun::star::uno::Reference<
                    ::com::sun::star::lang::XMultiServiceFactory > & xMSF )
        : CalendarWrapper( xMSF ), nLang( LANGUAGE_SYSTEM )
    {}

    void LoadDefaultCalendar( USHORT nLang );
};

extern SwCalendarWrapper* pCalendarWrapper;

#endif

<|endoftext|>


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

#pragma once
#ifndef HW_PCI_HPP
#define HW_PCI_HPP

#include <cstdint>
#include <arch.hpp>

namespace hw {

  static inline uint8_t inp(uint16_t port)
  {
    uint8_t ret;
#if defined(ARCH_x86)
    asm volatile("inb %w1,%b0" : "=a"(ret) : "Nd"(port));
#else
#error "inp() not implemented for selected arch"
#endif
    return ret;
  }

  static inline uint16_t inpw(uint16_t port)
  {
    uint16_t ret;
#if defined(ARCH_x86)
    asm volatile("inw %w1,%w0" : "=a"(ret) : "Nd"(port));
#else
#error "inpw() not implemented for selected arch"
#endif
    return ret;
  }

  static inline uint32_t inpd(uint16_t port)
  {
    uint32_t ret;
#if defined(ARCH_x86)
    asm volatile("inl %w1,%d0" : "=a"(ret) : "Nd"(port));
#else
#error "inpd() not implemented for selected arch"
#endif
    return ret;
  }

  static inline void outp(uint16_t port, uint8_t data)
  {
#if defined(ARCH_x86)
    asm volatile ("outb %b0,%w1" :: "a"(data), "Nd"(port));
#else
#error "outp() not implemented for selected arch"
#endif
  }
  static inline void outpw(uint16_t port, uint16_t data)
  {
#if defined(ARCH_x86)
    asm volatile ("outw %w0,%w1" :: "a" (data), "Nd"(port));
#else
#error "outpw() not implemented for selected arch"
#endif
  }
  static inline void outpd(uint16_t port, uint32_t data)
  {
#if defined(ARCH_x86)
    asm volatile ("outl %d0,%w1" :: "a" (data), "Nd"(port));
#else
#error "outpd() not implemented for selected arch"
#endif
  }

} //< namespace hw

#endif
<commit_msg>pci: Work-around for inline asm in clang<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once
#ifndef HW_PCI_HPP
#define HW_PCI_HPP

#include <cstdint>
#include <arch.hpp>

namespace hw {

  static inline uint8_t inp(uint16_t port)
  {
    uint8_t ret;
#if defined(ARCH_x86)
    asm volatile("inb %1,%0" : "=a"(ret) : "Nd"(port));
#else
#error "inp() not implemented for selected arch"
#endif
    return ret;
  }

  static inline uint16_t inpw(uint16_t port)
  {
    uint16_t ret;
#if defined(ARCH_x86)
    asm volatile("inw %1,%0" : "=a"(ret) : "Nd"(port));
#else
#error "inpw() not implemented for selected arch"
#endif
    return ret;
  }

  static inline uint32_t inpd(uint16_t port)
  {
    uint32_t ret;
#if defined(ARCH_x86)
    asm volatile("inl %1,%0" : "=a"(ret) : "Nd"(port));
#else
#error "inpd() not implemented for selected arch"
#endif
    return ret;
  }

  static inline void outp(uint16_t port, uint8_t data)
  {
#if defined(ARCH_x86)
    asm volatile ("outb %0,%1" :: "a"(data), "Nd"(port));
#else
#error "outp() not implemented for selected arch"
#endif
  }
  static inline void outpw(uint16_t port, uint16_t data)
  {
#if defined(ARCH_x86)
    asm volatile ("outw %0,%1" :: "a" (data), "Nd"(port));
#else
#error "outpw() not implemented for selected arch"
#endif
  }
  static inline void outpd(uint16_t port, uint32_t data)
  {
#if defined(ARCH_x86)
    asm volatile ("outl %0,%1" :: "a" (data), "Nd"(port));
#else
#error "outpd() not implemented for selected arch"
#endif
  }

} //< namespace hw

#endif
<|endoftext|>


<commit_before>// Copyright 2011 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: nadavs@google.com <Nadav Samet>

#include "rpcz/reactor.hpp"
#include <signal.h>
#include <vector>
#include "rpcz/callback.hpp"
#include "rpcz/clock.hpp"
#include "rpcz/logging.hpp"
#include "rpcz/macros.hpp"
#include "zmq.hpp"

namespace rpcz {
namespace {
static bool g_interrupted = false;
void signal_handler(int signal_value) {
  g_interrupted = true;
}
}  // unnamed namespace

reactor::reactor() : should_quit_(false) {
};

reactor::~reactor() {
  delete_container_pair_pointers(sockets_.begin(), sockets_.end());
  for (closure_run_map::const_iterator it = closure_run_map_.begin();
       it != closure_run_map_.end(); ++it) {
    delete_container_pointers(it->second.begin(), it->second.end());
  }
}

void reactor::add_socket(zmq::socket_t* socket, closure* closure) {
  sockets_.push_back(std::make_pair(socket, closure));
  is_dirty_ = true;
}

namespace {
void rebuild_poll_items(
    const std::vector<std::pair<zmq::socket_t*, closure*> >& sockets,
    std::vector<zmq::pollitem_t>* pollitems) {
  pollitems->resize(sockets.size());
  for (size_t i = 0; i < sockets.size(); ++i) {
    zmq::socket_t& socket = *sockets[i].first;
    zmq::pollitem_t pollitem = {socket, 0, ZMQ_POLLIN, 0};
    (*pollitems)[i] = pollitem;
  }
}
}  // namespace

void reactor::run_closure_at(uint64 timestamp, closure* closure) {
  closure_run_map_[timestamp].push_back(closure);
}

int reactor::loop() {
  while (!should_quit_) {
    if (is_dirty_) {
      rebuild_poll_items(sockets_, &pollitems_);
      is_dirty_ = false;
    }
    long poll_timeout = process_closure_run_map();
    int rc = zmq_poll(&pollitems_[0], pollitems_.size(), poll_timeout);

    if (rc == -1) {
      int zmq_err = zmq_errno();
      CHECK_NE(zmq_err, EFAULT);
      if (zmq_err == ETERM) {
        return -1;
      }
    }
    for (size_t i = 0; i < pollitems_.size(); ++i) {
      if (!pollitems_[i].revents & ZMQ_POLLIN) {
        continue;
      }
      pollitems_[i].revents = 0;
      sockets_[i].second->run();
    }
  }
  if (g_interrupted) {
    return -1;
  } else {
    return 0;
  }
}

long reactor::process_closure_run_map() {
  uint64 now = zclock_time();
  closure_run_map::iterator ub(closure_run_map_.upper_bound(now));
  for (closure_run_map::const_iterator it = closure_run_map_.begin();
       it != ub;
       ++it) {
    for (std::vector<closure*>::const_iterator vit = it->second.begin();
         vit != it->second.end(); ++vit) {
      (*vit)->run();
    }
  }
  long poll_timeout = -1;
  if (ub != closure_run_map_.end()) {
    poll_timeout = 1000 * (ub->first - now);
  }
  closure_run_map_.erase(closure_run_map_.begin(), ub);
  return poll_timeout;
}

void reactor::set_should_quit() {
  should_quit_ = true;
}

void install_signal_handler() {
  struct sigaction action;
  action.sa_handler = signal_handler;
  action.sa_flags = 0;
  sigemptyset(&action.sa_mask);
  sigaction(SIGINT, &action, NULL);
  sigaction(SIGTERM, &action, NULL);
}
}  // namespace rpcz
<commit_msg>update timeout units to work with zeromq 3+<commit_after>// Copyright 2011 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: nadavs@google.com <Nadav Samet>

#include "rpcz/reactor.hpp"
#include <signal.h>
#include <vector>
#include "rpcz/callback.hpp"
#include "rpcz/clock.hpp"
#include "rpcz/logging.hpp"
#include "rpcz/macros.hpp"
#include "zmq.hpp"

namespace rpcz {
namespace {
static bool g_interrupted = false;
void signal_handler(int signal_value) {
  g_interrupted = true;
}
}  // unnamed namespace

reactor::reactor() : should_quit_(false) {
};

reactor::~reactor() {
  delete_container_pair_pointers(sockets_.begin(), sockets_.end());
  for (closure_run_map::const_iterator it = closure_run_map_.begin();
       it != closure_run_map_.end(); ++it) {
    delete_container_pointers(it->second.begin(), it->second.end());
  }
}

void reactor::add_socket(zmq::socket_t* socket, closure* closure) {
  sockets_.push_back(std::make_pair(socket, closure));
  is_dirty_ = true;
}

namespace {
void rebuild_poll_items(
    const std::vector<std::pair<zmq::socket_t*, closure*> >& sockets,
    std::vector<zmq::pollitem_t>* pollitems) {
  pollitems->resize(sockets.size());
  for (size_t i = 0; i < sockets.size(); ++i) {
    zmq::socket_t& socket = *sockets[i].first;
    zmq::pollitem_t pollitem = {socket, 0, ZMQ_POLLIN, 0};
    (*pollitems)[i] = pollitem;
  }
}
}  // namespace

void reactor::run_closure_at(uint64 timestamp, closure* closure) {
  closure_run_map_[timestamp].push_back(closure);
}

int reactor::loop() {
  while (!should_quit_) {
    if (is_dirty_) {
      rebuild_poll_items(sockets_, &pollitems_);
      is_dirty_ = false;
    }
    long poll_timeout = process_closure_run_map();
    int rc = zmq_poll(&pollitems_[0], pollitems_.size(), poll_timeout);

    if (rc == -1) {
      int zmq_err = zmq_errno();
      CHECK_NE(zmq_err, EFAULT);
      if (zmq_err == ETERM) {
        return -1;
      }
    }
    for (size_t i = 0; i < pollitems_.size(); ++i) {
      if (!pollitems_[i].revents & ZMQ_POLLIN) {
        continue;
      }
      pollitems_[i].revents = 0;
      sockets_[i].second->run();
    }
  }
  if (g_interrupted) {
    return -1;
  } else {
    return 0;
  }
}

long reactor::process_closure_run_map() {
  uint64 now = zclock_time();
  closure_run_map::iterator ub(closure_run_map_.upper_bound(now));
  for (closure_run_map::const_iterator it = closure_run_map_.begin();
       it != ub;
       ++it) {
    for (std::vector<closure*>::const_iterator vit = it->second.begin();
         vit != it->second.end(); ++vit) {
      (*vit)->run();
    }
  }
  long poll_timeout = -1;
  if (ub != closure_run_map_.end()) {
    poll_timeout = ub->first - now;
  }
  closure_run_map_.erase(closure_run_map_.begin(), ub);
  return poll_timeout;
}

void reactor::set_should_quit() {
  should_quit_ = true;
}

void install_signal_handler() {
  struct sigaction action;
  action.sa_handler = signal_handler;
  action.sa_flags = 0;
  sigemptyset(&action.sa_mask);
  sigaction(SIGINT, &action, NULL);
  sigaction(SIGTERM, &action, NULL);
}
}  // namespace rpcz
<|endoftext|>


<commit_before>
#include "Flare.h"
#include "FlareGame.h"
#include "FlareCompany.h"
#include "../Player/FlarePlayerController.h"
#include "../Spacecrafts/FlareSpacecraft.h"

#define LOCTEXT_NAMESPACE "FlareCompany"

/*----------------------------------------------------
	Constructor
----------------------------------------------------*/

UFlareCompany::UFlareCompany(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
}

/*----------------------------------------------------
	Save
----------------------------------------------------*/

void UFlareCompany::Load(const FFlareCompanySave& Data)
{
	CompanyData = Data;
	CompanyData.Identifier = FName(*GetName());
	CompanyDescription = NULL;

	// Player description ID is -1
	if (Data.CatalogIdentifier >= 0)
	{
		CompanyDescription = GetGame()->GetCompanyDescription(Data.CatalogIdentifier);
	}
	else
	{
		CompanyDescription = GetGame()->GetPlayerCompanyDescription();
	}
}

FFlareCompanySave* UFlareCompany::Save()
{
	return &CompanyData;
}

void UFlareCompany::Register(IFlareSpacecraftInterface* Ship)
{
	if (Ship->IsStation())
	{
		CompanyStations.AddUnique(Ship);
	}
	else
	{
		CompanyShips.AddUnique(Ship);
	}
}

void UFlareCompany::Unregister(IFlareSpacecraftInterface* Ship)
{
	if (Ship->IsStation())
	{
		CompanyStations.Remove(Ship);
	}
	else
	{
		CompanyShips.Remove(Ship);
	}
}

/*----------------------------------------------------
	Gameplay
----------------------------------------------------*/

EFlareHostility::Type UFlareCompany::GetPlayerHostility() const
{
	AFlarePlayerController* PC = Cast<AFlarePlayerController>(GetOuter()->GetWorld()->GetFirstPlayerController());

	if (PC)
	{
		return PC->GetCompany()->GetHostility(this);
	}

	return EFlareHostility::Neutral;
}

EFlareHostility::Type UFlareCompany::GetHostility(const UFlareCompany* TargetCompany) const
{
	if (TargetCompany == this)
	{
		return EFlareHostility::Owned;
	}
	else if (TargetCompany && CompanyData.HostileCompanies.Contains(TargetCompany->GetIdentifier()))
	{
		return EFlareHostility::Hostile;
	}

	return EFlareHostility::Neutral;
}

void UFlareCompany::SetHostilityTo(const UFlareCompany* TargetCompany, bool Hostile)
{
	if (TargetCompany && TargetCompany != this)
	{
		if(Hostile)
		{
			CompanyData.HostileCompanies.AddUnique(TargetCompany->GetIdentifier());
		}
		else
		{
			CompanyData.HostileCompanies.Remove(TargetCompany->GetIdentifier());
		}
	}
}

FText UFlareCompany::GetInfoText(bool Minimized)
{
	// Static text
	FText ShipText = LOCTEXT("Ship", "ship");
	FText ShipsText = LOCTEXT("Ships", "ships");
	FText StationText = LOCTEXT("Station", "station");
	FText StationsText = LOCTEXT("Stations", "stations");
	FText MoneyText = LOCTEXT("Money", "credits");

	// Dynamic data
	int32 ShipCount = GetCompanyShips().Num();
	int32 StationCount = GetCompanyStations().Num();
	FString MoneyDescriptionString = FString::FromInt(GetMoney()) + " " + MoneyText.ToString();
	FString ShipDescriptionString = FString::FromInt(ShipCount) + " " + (ShipCount != 1 ? ShipsText : ShipText).ToString();
	FString StationDescriptionString = FString::FromInt(StationCount) + " " + (StationCount != 1 ? StationsText : StationText).ToString();

	// Build
	if (Minimized)
	{
		return FText::FromString(GetCompanyName() + " (" + MoneyDescriptionString + ", " + ShipDescriptionString + ")");
	}
	else
	{
		return FText::FromString(MoneyDescriptionString + "\n" + ShipDescriptionString + "\n" + StationDescriptionString);
	}
}

/*----------------------------------------------------
	Customization
----------------------------------------------------*/

void UFlareCompany::UpdateCompanyCustomization()
{
	// Update ships
	for (int32 i = 0; i < CompanyShips.Num(); i++)
	{
		AFlareSpacecraft* Ship = Cast<AFlareSpacecraft>(CompanyShips[i]);
		if (Ship)
		{
			Ship->UpdateCustomization();
		}
	}

	// Update stations
	for (int32 i = 0; i < CompanyStations.Num(); i++)
	{
		AFlareSpacecraft* Station = Cast<AFlareSpacecraft>(CompanyStations[i]);
		if (Station)
		{
			Station->UpdateCustomization();
		}
	}
}

void UFlareCompany::CustomizeComponentMaterial(UMaterialInstanceDynamic* Mat)
{
	// Get data from storage
	FLinearColor BasePaintColor = GetGame()->GetCustomizationCatalog()->GetColor(GetBasePaintColorIndex());
	FLinearColor PaintColor = GetGame()->GetCustomizationCatalog()->GetColor(GetPaintColorIndex());
	FLinearColor OverlayColor = GetGame()->GetCustomizationCatalog()->GetColor(GetOverlayColorIndex());
	FLinearColor LightColor = GetGame()->GetCustomizationCatalog()->GetColor(GetLightColorIndex());
	UTexture2D* Pattern = GetGame()->GetCustomizationCatalog()->GetPattern(GetPatternIndex());

	// Apply settings to the material instance
	Mat->SetVectorParameterValue("BasePaintColor", BasePaintColor);
	Mat->SetVectorParameterValue("PaintColor", PaintColor);
	Mat->SetVectorParameterValue("OverlayColor", OverlayColor);
	Mat->SetVectorParameterValue("GlowColor", NormalizeColor(LightColor));
	Mat->SetTextureParameterValue("PaintPattern", Pattern);
}

void UFlareCompany::CustomizeEffectMaterial(UMaterialInstanceDynamic* Mat)
{
}

FLinearColor UFlareCompany::NormalizeColor(FLinearColor Col) const
{
	return FLinearColor(FVector(Col.R, Col.G, Col.B) / Col.GetLuminance());
}

#undef LOCTEXT_NAMESPACE
<commit_msg>Added dynamic company emblems to ship hulls<commit_after>
#include "Flare.h"
#include "FlareGame.h"
#include "FlareCompany.h"
#include "../Player/FlarePlayerController.h"
#include "../Spacecrafts/FlareSpacecraft.h"

#define LOCTEXT_NAMESPACE "FlareCompany"

/*----------------------------------------------------
	Constructor
----------------------------------------------------*/

UFlareCompany::UFlareCompany(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
}

/*----------------------------------------------------
	Save
----------------------------------------------------*/

void UFlareCompany::Load(const FFlareCompanySave& Data)
{
	CompanyData = Data;
	CompanyData.Identifier = FName(*GetName());
	CompanyDescription = NULL;

	// Player description ID is -1
	if (Data.CatalogIdentifier >= 0)
	{
		CompanyDescription = GetGame()->GetCompanyDescription(Data.CatalogIdentifier);
	}
	else
	{
		CompanyDescription = GetGame()->GetPlayerCompanyDescription();
	}
}

FFlareCompanySave* UFlareCompany::Save()
{
	return &CompanyData;
}

void UFlareCompany::Register(IFlareSpacecraftInterface* Ship)
{
	if (Ship->IsStation())
	{
		CompanyStations.AddUnique(Ship);
	}
	else
	{
		CompanyShips.AddUnique(Ship);
	}
}

void UFlareCompany::Unregister(IFlareSpacecraftInterface* Ship)
{
	if (Ship->IsStation())
	{
		CompanyStations.Remove(Ship);
	}
	else
	{
		CompanyShips.Remove(Ship);
	}
}

/*----------------------------------------------------
	Gameplay
----------------------------------------------------*/

EFlareHostility::Type UFlareCompany::GetPlayerHostility() const
{
	AFlarePlayerController* PC = Cast<AFlarePlayerController>(GetOuter()->GetWorld()->GetFirstPlayerController());

	if (PC)
	{
		return PC->GetCompany()->GetHostility(this);
	}

	return EFlareHostility::Neutral;
}

EFlareHostility::Type UFlareCompany::GetHostility(const UFlareCompany* TargetCompany) const
{
	if (TargetCompany == this)
	{
		return EFlareHostility::Owned;
	}
	else if (TargetCompany && CompanyData.HostileCompanies.Contains(TargetCompany->GetIdentifier()))
	{
		return EFlareHostility::Hostile;
	}

	return EFlareHostility::Neutral;
}

void UFlareCompany::SetHostilityTo(const UFlareCompany* TargetCompany, bool Hostile)
{
	if (TargetCompany && TargetCompany != this)
	{
		if(Hostile)
		{
			CompanyData.HostileCompanies.AddUnique(TargetCompany->GetIdentifier());
		}
		else
		{
			CompanyData.HostileCompanies.Remove(TargetCompany->GetIdentifier());
		}
	}
}

FText UFlareCompany::GetInfoText(bool Minimized)
{
	// Static text
	FText ShipText = LOCTEXT("Ship", "ship");
	FText ShipsText = LOCTEXT("Ships", "ships");
	FText StationText = LOCTEXT("Station", "station");
	FText StationsText = LOCTEXT("Stations", "stations");
	FText MoneyText = LOCTEXT("Money", "credits");

	// Dynamic data
	int32 ShipCount = GetCompanyShips().Num();
	int32 StationCount = GetCompanyStations().Num();
	FString MoneyDescriptionString = FString::FromInt(GetMoney()) + " " + MoneyText.ToString();
	FString ShipDescriptionString = FString::FromInt(ShipCount) + " " + (ShipCount != 1 ? ShipsText : ShipText).ToString();
	FString StationDescriptionString = FString::FromInt(StationCount) + " " + (StationCount != 1 ? StationsText : StationText).ToString();

	// Build
	if (Minimized)
	{
		return FText::FromString(GetCompanyName() + " (" + MoneyDescriptionString + ", " + ShipDescriptionString + ")");
	}
	else
	{
		return FText::FromString(MoneyDescriptionString + "\n" + ShipDescriptionString + "\n" + StationDescriptionString);
	}
}

/*----------------------------------------------------
	Customization
----------------------------------------------------*/

void UFlareCompany::UpdateCompanyCustomization()
{
	// Update ships
	for (int32 i = 0; i < CompanyShips.Num(); i++)
	{
		AFlareSpacecraft* Ship = Cast<AFlareSpacecraft>(CompanyShips[i]);
		if (Ship)
		{
			Ship->UpdateCustomization();
		}
	}

	// Update stations
	for (int32 i = 0; i < CompanyStations.Num(); i++)
	{
		AFlareSpacecraft* Station = Cast<AFlareSpacecraft>(CompanyStations[i]);
		if (Station)
		{
			Station->UpdateCustomization();
		}
	}
}

void UFlareCompany::CustomizeComponentMaterial(UMaterialInstanceDynamic* Mat)
{
	// Get data from storage
	FLinearColor BasePaintColor = GetGame()->GetCustomizationCatalog()->GetColor(GetBasePaintColorIndex());
	FLinearColor PaintColor = GetGame()->GetCustomizationCatalog()->GetColor(GetPaintColorIndex());
	FLinearColor OverlayColor = GetGame()->GetCustomizationCatalog()->GetColor(GetOverlayColorIndex());
	FLinearColor LightColor = GetGame()->GetCustomizationCatalog()->GetColor(GetLightColorIndex());
	UTexture2D* Pattern = GetGame()->GetCustomizationCatalog()->GetPattern(GetPatternIndex());
	UTexture2D* Emblem = CompanyDescription->Emblem;

	// Apply settings to the material instance
	Mat->SetVectorParameterValue("BasePaintColor", BasePaintColor);
	Mat->SetVectorParameterValue("PaintColor", PaintColor);
	Mat->SetVectorParameterValue("OverlayColor", OverlayColor);
	Mat->SetVectorParameterValue("GlowColor", NormalizeColor(LightColor));
	Mat->SetTextureParameterValue("PaintPattern", Pattern);
	Mat->SetTextureParameterValue("Emblem", Emblem);
}

void UFlareCompany::CustomizeEffectMaterial(UMaterialInstanceDynamic* Mat)
{
}

FLinearColor UFlareCompany::NormalizeColor(FLinearColor Col) const
{
	return FLinearColor(FVector(Col.R, Col.G, Col.B) / Col.GetLuminance());
}

#undef LOCTEXT_NAMESPACE
<|endoftext|>