<commit_before>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <algorithm>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include "fnord-base/io/fileutil.h"
#include "fnord-base/application.h"
#include "fnord-base/logging.h"
#include "fnord-base/Language.h"
#include "fnord-base/cli/flagparser.h"
#include "fnord-base/util/SimpleRateLimit.h"
#include "fnord-base/InternMap.h"
#include "fnord-json/json.h"
#include "fnord-mdb/MDB.h"
#include "fnord-mdb/MDBUtil.h"
#include "fnord-sstable/sstablereader.h"
#include "fnord-sstable/sstablewriter.h"
#include "fnord-sstable/SSTableColumnSchema.h"
#include "fnord-sstable/SSTableColumnReader.h"
#include "fnord-sstable/SSTableColumnWriter.h"
#include <fnord-fts/fts.h>
#include <fnord-fts/fts_common.h>
#include "fnord-eventdb/TableReader.h"
#include "common.h"
#include "schemas.h"
#include "CustomerNamespace.h"
#include "FeatureSchema.h"
#include "JoinedQuery.h"
#include "CTRCounter.h"
#include "IndexReader.h"
#include "analytics/ReportBuilder.h"
#include "analytics/AnalyticsTableScanSource.h"
#include "analytics/JoinedQueryTableSource.h"
#include "analytics/CTRByPositionMapper.h"
#include "analytics/CTRByPageMapper.h"
#include "analytics/CTRBySearchQueryMapper.h"
#include "analytics/CTRByQueryAttributeMapper.h"
#include "analytics/CTRBySearchTermCrossCategoryMapper.h"
#include "analytics/CTRStatsMapper.h"
#include "analytics/CTRCounterMergeReducer.h"
#include "analytics/CTRCounterTableSink.h"
#include "analytics/CTRCounterTableSource.h"
#include "analytics/RelatedTermsMapper.h"
#include "analytics/TopCategoriesByTermMapper.h"
#include "analytics/TermInfoMergeReducer.h"

using namespace fnord;
using namespace cm;

int main(int argc, const char** argv) {
  fnord::Application::init();
  fnord::Application::logToStderr();

  fnord::cli::FlagParser flags;

  //flags.defineFlag(
  //    "conf",
  //    cli::FlagParser::T_STRING,
  //    false,
  //    NULL,
  //    "./conf",
  //    "conf directory",
  //    "<path>");

  flags.defineFlag(
      "index",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "index directory",
      "<path>");

  flags.defineFlag(
      "replica",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "replica id",
      "<id>");

  flags.defineFlag(
      "datadir",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "artifact directory",
      "<path>");

  flags.defineFlag(
      "tempdir",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "artifact directory",
      "<path>");

  flags.defineFlag(
      "loglevel",
      fnord::cli::FlagParser::T_STRING,
      false,
      NULL,
      "INFO",
      "loglevel",
      "<level>");

  flags.parseArgv(argc, argv);

  Logger::get()->setMinimumLogLevel(
      strToLogLevel(flags.getString("loglevel")));

  auto index_path = flags.getString("index");
  //auto conf_path = flags.getString("conf");
  auto tempdir = flags.getString("tempdir");
  auto datadir = flags.getString("datadir");

  /* open index */
  auto index_reader = cm::IndexReader::openIndex(index_path);
  //auto analyzer = RefPtr<fts::Analyzer>(new fts::Analyzer(conf_path));

  /* set up reportbuilder */
  cm::ReportBuilder report_builder;

  auto buildid = 0;

  auto table = eventdb::TableReader::open(
      "dawanda_joined_sessions",
      flags.getString("replica"),
      flags.getString("datadir"),
      joinedSessionsSchema());

  auto snap = table->getSnapshot();

  Set<String> searchterm_x_e1_tables;
  Set<String> related_terms_tables;

  for (const auto& c : snap->head->chunks) {
    auto input_table = StringUtil::format(
        "$0/$1.$2.$3.cst",
        datadir,
        "dawanda_joined_sessions",
        c.replica_id,
        c.chunk_id);

    /* map related terms */
    auto related_terms_table = StringUtil::format(
        "$0/dawanda_related_terms.$1.$2.sst",
        tempdir,
        c.replica_id,
        c.chunk_id);

    related_terms_tables.emplace(related_terms_table);
    report_builder.addReport(
        new RelatedTermsMapper(
            new AnalyticsTableScanSource(input_table),
            new CTRCounterTableSink(0, 0, related_terms_table)));

    /* map serchterm x e1 */
    auto searchterm_x_e1_table = StringUtil::format(
        "$0/dawanda_ctr_by_searchterm_cross_e1.$1.$2.sst",
        tempdir,
        c.replica_id,
        c.chunk_id);

    searchterm_x_e1_tables.emplace(searchterm_x_e1_table);
    report_builder.addReport(
        new CTRBySearchTermCrossCategoryMapper(
            new AnalyticsTableScanSource(input_table),
            new CTRCounterTableSink(0, 0, searchterm_x_e1_table),
            "category1",
            index_reader));
  }

  report_builder.addReport(
      new TermInfoMergeReducer(
          new TermInfoTableSource(related_terms_tables),
          new TermInfoTableSink(
              StringUtil::format(
                  "$0/dawanda_related_terms.$1.sstable",
                  tempdir,
                  buildid))));

  report_builder.addReport(
      new TermInfoMergeReducer(
          new TermInfoTableSource(searchterm_x_e1_tables),
          new TermInfoTableSink(
              StringUtil::format(
                  "$0/dawanda_top_cats_by_searchterm_e1.$1.sstable",
                  tempdir,
                  buildid))));

  report_builder.addReport(
      new TermInfoMergeReducer(
          new TermInfoTableSource(Set<String> {
            StringUtil::format(
                  "$0/dawanda_related_terms.$1.sstable",
                  tempdir,
                  buildid),
            StringUtil::format(
                  "$0/dawanda_top_cats_by_searchterm_e1.$1.sstable",
                  tempdir,
                  buildid)
          }),
          new TermInfoTableSink(
              StringUtil::format(
                  "$0/dawanda_termstats.$1.sstable",
                  tempdir,
                  buildid))));

  report_builder.buildAll();

  fnord::logInfo(
      "cm.reportbuild",
      "Build completed: dawanda_termstats.$0.sstable",
      buildid);

  return 0;
}

<commit_msg>RelatedTermsMapper...<commit_after>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <algorithm>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include "fnord-base/io/fileutil.h"
#include "fnord-base/application.h"
#include "fnord-base/logging.h"
#include "fnord-base/Language.h"
#include "fnord-base/cli/flagparser.h"
#include "fnord-base/util/SimpleRateLimit.h"
#include "fnord-base/InternMap.h"
#include "fnord-json/json.h"
#include "fnord-mdb/MDB.h"
#include "fnord-mdb/MDBUtil.h"
#include "fnord-sstable/sstablereader.h"
#include "fnord-sstable/sstablewriter.h"
#include "fnord-sstable/SSTableColumnSchema.h"
#include "fnord-sstable/SSTableColumnReader.h"
#include "fnord-sstable/SSTableColumnWriter.h"
#include <fnord-fts/fts.h>
#include <fnord-fts/fts_common.h>
#include "fnord-eventdb/TableReader.h"
#include "common.h"
#include "schemas.h"
#include "CustomerNamespace.h"
#include "FeatureSchema.h"
#include "JoinedQuery.h"
#include "CTRCounter.h"
#include "IndexReader.h"
#include "analytics/ReportBuilder.h"
#include "analytics/AnalyticsTableScanSource.h"
#include "analytics/JoinedQueryTableSource.h"
#include "analytics/CTRByPositionMapper.h"
#include "analytics/CTRByPageMapper.h"
#include "analytics/CTRBySearchQueryMapper.h"
#include "analytics/CTRByQueryAttributeMapper.h"
#include "analytics/CTRBySearchTermCrossCategoryMapper.h"
#include "analytics/CTRStatsMapper.h"
#include "analytics/CTRCounterMergeReducer.h"
#include "analytics/CTRCounterTableSink.h"
#include "analytics/CTRCounterTableSource.h"
#include "analytics/RelatedTermsMapper.h"
#include "analytics/TopCategoriesByTermMapper.h"
#include "analytics/TermInfoMergeReducer.h"

using namespace fnord;
using namespace cm;

int main(int argc, const char** argv) {
  fnord::Application::init();
  fnord::Application::logToStderr();

  fnord::cli::FlagParser flags;

  //flags.defineFlag(
  //    "conf",
  //    cli::FlagParser::T_STRING,
  //    false,
  //    NULL,
  //    "./conf",
  //    "conf directory",
  //    "<path>");

  flags.defineFlag(
      "index",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "index directory",
      "<path>");

  flags.defineFlag(
      "replica",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "replica id",
      "<id>");

  flags.defineFlag(
      "datadir",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "artifact directory",
      "<path>");

  flags.defineFlag(
      "tempdir",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "artifact directory",
      "<path>");

  flags.defineFlag(
      "loglevel",
      fnord::cli::FlagParser::T_STRING,
      false,
      NULL,
      "INFO",
      "loglevel",
      "<level>");

  flags.parseArgv(argc, argv);

  Logger::get()->setMinimumLogLevel(
      strToLogLevel(flags.getString("loglevel")));

  auto index_path = flags.getString("index");
  //auto conf_path = flags.getString("conf");
  auto tempdir = flags.getString("tempdir");
  auto datadir = flags.getString("datadir");

  /* open index */
  auto index_reader = cm::IndexReader::openIndex(index_path);
  //auto analyzer = RefPtr<fts::Analyzer>(new fts::Analyzer(conf_path));

  /* set up reportbuilder */
  cm::ReportBuilder report_builder;

  auto buildid = 0;

  auto table = eventdb::TableReader::open(
      "dawanda_joined_sessions",
      flags.getString("replica"),
      flags.getString("datadir"),
      joinedSessionsSchema());

  auto snap = table->getSnapshot();

  Set<String> searchterm_x_e1_tables;
  Set<String> related_terms_tables;

  for (const auto& c : snap->head->chunks) {
    auto input_table = StringUtil::format(
        "$0/$1.$2.$3.cst",
        datadir,
        "dawanda_joined_sessions",
        c.replica_id,
        c.chunk_id);

    /* map related terms */
    auto related_terms_table = StringUtil::format(
        "$0/dawanda_related_terms.$1.$2.sst",
        tempdir,
        c.replica_id,
        c.chunk_id);

    related_terms_tables.emplace(related_terms_table);
    report_builder.addReport(
        new RelatedTermsMapper(
            new AnalyticsTableScanSource(input_table),
            new TermInfoTableSink(related_terms_table)));

    /* map serchterm x e1 */
    auto searchterm_x_e1_table = StringUtil::format(
        "$0/dawanda_ctr_by_searchterm_cross_e1.$1.$2.sst",
        tempdir,
        c.replica_id,
        c.chunk_id);

    searchterm_x_e1_tables.emplace(searchterm_x_e1_table);
    report_builder.addReport(
        new CTRBySearchTermCrossCategoryMapper(
            new AnalyticsTableScanSource(input_table),
            new CTRCounterTableSink(0, 0, searchterm_x_e1_table),
            "category1",
            index_reader));
  }

  report_builder.addReport(
      new TermInfoMergeReducer(
          new TermInfoTableSource(related_terms_tables),
          new TermInfoTableSink(
              StringUtil::format(
                  "$0/dawanda_related_terms.$1.sstable",
                  tempdir,
                  buildid))));

  report_builder.addReport(
      new TopCategoriesByTermMapper(
          new CTRCounterTableSource(searchterm_x_e1_tables),
          new TermInfoTableSink(
              StringUtil::format(
                  "$0/dawanda_top_cats_by_searchterm_e1.$1.sstable",
                  tempdir,
                  buildid)),
          "e1-"));

  report_builder.addReport(
      new TermInfoMergeReducer(
          new TermInfoTableSource(Set<String> {
            StringUtil::format(
                  "$0/dawanda_related_terms.$1.sstable",
                  tempdir,
                  buildid),
            StringUtil::format(
                  "$0/dawanda_top_cats_by_searchterm_e1.$1.sstable",
                  tempdir,
                  buildid)
          }),
          new TermInfoTableSink(
              StringUtil::format(
                  "$0/dawanda_termstats.$1.sstable",
                  tempdir,
                  buildid))));

  report_builder.buildAll();

  fnord::logInfo(
      "cm.reportbuild",
      "Build completed: dawanda_termstats.$0.sstable",
      buildid);

  return 0;
}

<|endoftext|>


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

#include "config.h"

#include "file_handler.hpp"
#include "firmware_handler.hpp"
#include "flags.hpp"
#include "image_handler.hpp"
#include "lpc_aspeed.hpp"
#include "lpc_handler.hpp"
#include "lpc_nuvoton.hpp"
#include "pci_handler.hpp"
#include "prepare_systemd.hpp"
#include "status.hpp"
#include "update_systemd.hpp"
#include "util.hpp"
#include "verify_systemd.hpp"

#include <cstdint>
#include <memory>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/bus.hpp>
#include <unordered_map>

namespace ipmi_flash
{
namespace
{

/* The maximum external buffer size we expect is 64KB. */
static constexpr std::size_t memoryRegionSize = 64 * 1024UL;

#ifdef ENABLE_LPC_BRIDGE
#if defined(ASPEED_LPC)
LpcDataHandler lpcDataHandler(
    LpcMapperAspeed::createAspeedMapper(MAPPED_ADDRESS, memoryRegionSize));
#elif defined(NUVOTON_LPC)
LpcDataHandler lpcDataHandler(
    LpcMapperNuvoton::createNuvotonMapper(MAPPED_ADDRESS, memoryRegionSize));
#else
#error "You must specify a hardware implementation."
#endif
#endif

#ifdef ENABLE_PCI_BRIDGE
#if defined(ASPEED_P2A)
PciDataHandler pciDataHandler(MAPPED_ADDRESS, memoryRegionSize);
#else
#error "You must specify a hardware implementation."
#endif
#endif

std::vector<DataHandlerPack> supportedTransports = {
    {FirmwareFlags::UpdateFlags::ipmi, nullptr},
#ifdef ENABLE_PCI_BRIDGE
    {FirmwareFlags::UpdateFlags::p2a, &pciDataHandler},
#endif
#ifdef ENABLE_LPC_BRIDGE
    {FirmwareFlags::UpdateFlags::lpc, &lpcDataHandler},
#endif
};

} // namespace
} // namespace ipmi_flash

extern "C" {
std::unique_ptr<blobs::GenericBlobInterface> createHandler();
}

std::unique_ptr<blobs::GenericBlobInterface> createHandler()
{
    ipmi_flash::ActionMap actionPacks = {};

#ifdef ENABLE_REBOOT_UPDATE
    static constexpr auto rebootTarget = "reboot.target";
    static constexpr auto rebootMode = "replace-irreversibly";

    auto updater = ipmi_flash::SystemdUpdateMechanism::CreateSystemdUpdate(
        sdbusplus::bus::new_default(), rebootTarget, rebootMode);
#else
    auto updater = ipmi_flash::SystemdUpdateMechanism::CreateSystemdUpdate(
        sdbusplus::bus::new_default(), UPDATE_DBUS_SERVICE);
#endif

    auto prepare = ipmi_flash::SystemdPreparation::CreatePreparation(
        sdbusplus::bus::new_default(), PREPARATION_DBUS_SERVICE);

    auto verifier = ipmi_flash::SystemdVerification::CreateVerification(
        sdbusplus::bus::new_default(), VERIFY_STATUS_FILENAME,
        VERIFY_DBUS_SERVICE);

    /* TODO: for bios should the name be, bios or /flash/bios?, these are
     * /flash/... and it simplifies a few other things later (open/etc)
     */
    std::string bmcName;
#ifdef ENABLE_STATIC_LAYOUT
    bmcName = ipmi_flash::staticLayoutBlobId;
#endif
#ifdef ENABLE_TARBALL_UBI
    bmcName = ipmi_flash::ubiTarballBlobId;
#endif

    auto bmcPack = std::make_unique<ipmi_flash::ActionPack>();
    bmcPack->preparation = std::move(prepare);
    bmcPack->verification = std::move(verifier);
    bmcPack->update = std::move(updater);
    actionPacks[bmcName] = std::move(bmcPack);

#ifdef ENABLE_HOST_BIOS
    {
        auto biosPack = std::make_unique<ipmi_flash::ActionPack>();

        biosPack->preparation =
            ipmi_flash::SystemdPreparation::CreatePreparation(
                sdbusplus::bus::new_default(), PREPARATION_BIOS_TARGET);

        biosPack->verification =
            ipmi_flash::SystemdVerification::CreateVerification(
                sdbusplus::bus::new_default(), BIOS_VERIFY_STATUS_FILENAME,
                VERIFY_BIOS_TARGET);

        biosPack->update =
            ipmi_flash::SystemdUpdateMechanism::CreateSystemdUpdate(
                sdbusplus::bus::new_default(), UPDATE_BIOS_TARGET);

        actionPacks[ipmi_flash::biosBlobId] = std::move(biosPack);
    }
#endif

    std::vector<ipmi_flash::HandlerPack> supportedFirmware;

    supportedFirmware.push_back(std::move(ipmi_flash::HandlerPack(
        ipmi_flash::hashBlobId,
        std::make_unique<ipmi_flash::FileHandler>(HASH_FILENAME))));

#ifdef ENABLE_STATIC_LAYOUT
    supportedFirmware.push_back(std::move(
        ipmi_flash::HandlerPack(ipmi_flash::staticLayoutBlobId,
                                std::make_unique<ipmi_flash::FileHandler>(
                                    STATIC_HANDLER_STAGED_NAME))));
#endif
#ifdef ENABLE_TARBALL_UBI
    supportedFirmware.push_back(std::move(ipmi_flash::HandlerPack(
        ipmi_flash::ubiTarballBlobId,
        std::make_unique<ipmi_flash::FileHandler>(TARBALL_STAGED_NAME))));
#endif
#ifdef ENABLE_HOST_BIOS
    supportedFirmware.push_back(std::move(ipmi_flash::HandlerPack(
        ipmi_flash::biosBlobId,
        std::make_unique<ipmi_flash::FileHandler>(BIOS_STAGED_NAME))));
#endif

    auto handler = ipmi_flash::FirmwareBlobHandler::CreateFirmwareBlobHandler(
        std::move(supportedFirmware), ipmi_flash::supportedTransports,
        std::move(actionPacks));

    if (!handler)
    {
        using namespace phosphor::logging;

        log<level::ERR>("Firmware Handler has invalid configuration");
        return nullptr;
    }

    return handler;
}
<commit_msg>bmc: consolidate action pack code slightly<commit_after>/*
 * Copyright 2018 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "config.h"

#include "file_handler.hpp"
#include "firmware_handler.hpp"
#include "flags.hpp"
#include "image_handler.hpp"
#include "lpc_aspeed.hpp"
#include "lpc_handler.hpp"
#include "lpc_nuvoton.hpp"
#include "pci_handler.hpp"
#include "prepare_systemd.hpp"
#include "status.hpp"
#include "update_systemd.hpp"
#include "util.hpp"
#include "verify_systemd.hpp"

#include <cstdint>
#include <memory>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/bus.hpp>
#include <unordered_map>

namespace ipmi_flash
{
namespace
{

/* The maximum external buffer size we expect is 64KB. */
static constexpr std::size_t memoryRegionSize = 64 * 1024UL;

#ifdef ENABLE_LPC_BRIDGE
#if defined(ASPEED_LPC)
LpcDataHandler lpcDataHandler(
    LpcMapperAspeed::createAspeedMapper(MAPPED_ADDRESS, memoryRegionSize));
#elif defined(NUVOTON_LPC)
LpcDataHandler lpcDataHandler(
    LpcMapperNuvoton::createNuvotonMapper(MAPPED_ADDRESS, memoryRegionSize));
#else
#error "You must specify a hardware implementation."
#endif
#endif

#ifdef ENABLE_PCI_BRIDGE
#if defined(ASPEED_P2A)
PciDataHandler pciDataHandler(MAPPED_ADDRESS, memoryRegionSize);
#else
#error "You must specify a hardware implementation."
#endif
#endif

std::vector<DataHandlerPack> supportedTransports = {
    {FirmwareFlags::UpdateFlags::ipmi, nullptr},
#ifdef ENABLE_PCI_BRIDGE
    {FirmwareFlags::UpdateFlags::p2a, &pciDataHandler},
#endif
#ifdef ENABLE_LPC_BRIDGE
    {FirmwareFlags::UpdateFlags::lpc, &lpcDataHandler},
#endif
};

/**
 * Given a name and path, create a HandlerPack.
 *
 * @param[in] name - the blob id path for this
 * @param[in] path - the file path to write the contents.
 * @return the HandlerPack.
 */
HandlerPack CreateFileHandlerPack(const std::string& name,
                                  const std::string& path)
{
    return HandlerPack(name, std::make_unique<FileHandler>(path));
}

} // namespace
} // namespace ipmi_flash

extern "C" {
std::unique_ptr<blobs::GenericBlobInterface> createHandler();
}

std::unique_ptr<blobs::GenericBlobInterface> createHandler()
{
    ipmi_flash::ActionMap actionPacks = {};

    {
        auto bmcPack = std::make_unique<ipmi_flash::ActionPack>();

#ifdef ENABLE_REBOOT_UPDATE
        static constexpr auto rebootTarget = "reboot.target";
        static constexpr auto rebootMode = "replace-irreversibly";

        bmcPack->update =
            ipmi_flash::SystemdUpdateMechanism::CreateSystemdUpdate(
                sdbusplus::bus::new_default(), rebootTarget, rebootMode);
#else
        bmcPack->update =
            ipmi_flash::SystemdUpdateMechanism::CreateSystemdUpdate(
                sdbusplus::bus::new_default(), UPDATE_DBUS_SERVICE);
#endif

        bmcPack->preparation =
            ipmi_flash::SystemdPreparation::CreatePreparation(
                sdbusplus::bus::new_default(), PREPARATION_DBUS_SERVICE);

        bmcPack->verification =
            ipmi_flash::SystemdVerification::CreateVerification(
                sdbusplus::bus::new_default(), VERIFY_STATUS_FILENAME,
                VERIFY_DBUS_SERVICE);

        std::string bmcName;
#ifdef ENABLE_STATIC_LAYOUT
        bmcName = ipmi_flash::staticLayoutBlobId;
#endif
#ifdef ENABLE_TARBALL_UBI
        bmcName = ipmi_flash::ubiTarballBlobId;
#endif

        actionPacks[bmcName] = std::move(bmcPack);
    }

#ifdef ENABLE_HOST_BIOS
    {
        auto biosPack = std::make_unique<ipmi_flash::ActionPack>();

        biosPack->preparation =
            ipmi_flash::SystemdPreparation::CreatePreparation(
                sdbusplus::bus::new_default(), PREPARATION_BIOS_TARGET);

        biosPack->verification =
            ipmi_flash::SystemdVerification::CreateVerification(
                sdbusplus::bus::new_default(), BIOS_VERIFY_STATUS_FILENAME,
                VERIFY_BIOS_TARGET);

        biosPack->update =
            ipmi_flash::SystemdUpdateMechanism::CreateSystemdUpdate(
                sdbusplus::bus::new_default(), UPDATE_BIOS_TARGET);

        actionPacks[ipmi_flash::biosBlobId] = std::move(biosPack);
    }
#endif

    std::vector<ipmi_flash::HandlerPack> supportedFirmware;

    supportedFirmware.push_back(std::move(ipmi_flash::CreateFileHandlerPack(
        ipmi_flash::hashBlobId, HASH_FILENAME)));

#ifdef ENABLE_STATIC_LAYOUT
    supportedFirmware.push_back(std::move(ipmi_flash::CreateFileHandlerPack(
        ipmi_flash::staticLayoutBlobId, STATIC_HANDLER_STAGED_NAME)));
#endif
#ifdef ENABLE_TARBALL_UBI
    supportedFirmware.push_back(std::move(ipmi_flash::CreateFileHandlerPack(
        ipmi_flash::ubiTarballBlobId, TARBALL_STAGED_NAME)));
#endif
#ifdef ENABLE_HOST_BIOS
    supportedFirmware.push_back(std::move(ipmi_flash::CreateFileHandlerPack(
        ipmi_flash::biosBlobId, BIOS_STAGED_NAME)));
#endif

    auto handler = ipmi_flash::FirmwareBlobHandler::CreateFirmwareBlobHandler(
        std::move(supportedFirmware), ipmi_flash::supportedTransports,
        std::move(actionPacks));

    if (!handler)
    {
        using namespace phosphor::logging;

        log<level::ERR>("Firmware Handler has invalid configuration");
        return nullptr;
    }

    return handler;
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2021-2022 ArangoDB GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Lars Maier
////////////////////////////////////////////////////////////////////////////////
#include "Logger/LogMacros.h"
#include "UpdateReplicatedState.h"
#include "Replication2/ReplicatedState/StateCommon.h"
#include "Basics/voc-errors.h"
#include "Logger/LogContextKeys.h"

using namespace arangodb::replication2;
using namespace arangodb::replication2::replicated_state;

auto algorithms::updateReplicatedState(
    StateActionContext& ctx, std::string const& serverId, LogId id,
    replicated_state::agency::Plan const* spec,
    replicated_state::agency::Current const* current) -> arangodb::Result {
  if (spec == nullptr) {
    return ctx.dropReplicatedState(id);
  }

  TRI_ASSERT(id == spec->id);
  TRI_ASSERT(spec->participants.contains(serverId));
  auto expectedGeneration = spec->participants.at(serverId).generation;

  auto logCtx =
      LoggerContext(Logger::REPLICATED_STATE).with<logContextKeyLogId>(id);

  LOG_CTX("b089c", TRACE, logCtx) << "Update replicated log" << id
                                  << " for generation " << expectedGeneration;

  auto state = ctx.getReplicatedStateById(id);
  if (state == nullptr) {
    // TODO use user data instead of non-slice
    auto result =
        ctx.createReplicatedState(id, spec->properties.implementation.type,
                                  velocypack::Slice::noneSlice());
    if (result.fail()) {
      return result.result();
    }

    state = result.get();

    auto token = std::invoke([&] {
      if (current) {
        if (auto const p = current->participants.find(serverId);
            p != std::end(current->participants)) {
          if (p->second.generation == expectedGeneration) {
            LOG_CTX("19d00", DEBUG, logCtx)
                << "Using existing snapshot information from current";
            // we are allowed to use the information stored here
            return std::make_unique<ReplicatedStateToken>(
                ReplicatedStateToken::withExplicitSnapshotStatus(
                    expectedGeneration, p->second.snapshot));
          } else {
            LOG_CTX("6d8c9", DEBUG, logCtx)
                << "Must not use existing information, generation is "
                   "different. "
                << "Plan = " << expectedGeneration
                << " but Current = " << p->second.generation;
          }
        } else {
          LOG_CTX("cef1a", DEBUG, logCtx)
              << "No snapshot information available for this server "
              << serverId;
        }
      } else {
        LOG_CTX("d4fd8", DEBUG, logCtx)
            << "no current available to read snapshot information from. "
               "Assuming no snapshot available";
      }

      return std::make_unique<ReplicatedStateToken>(expectedGeneration);
    });
    // now start the replicated state
    state->start(std::move(token));
    return {TRI_ERROR_NO_ERROR};
  } else {
    auto status = state->getStatus();
    if (status.has_value()) {
      auto generation = status.value().getGeneration();
      if (generation != expectedGeneration) {
        state->flush(expectedGeneration);
      }
    } else if (!spec->participants.contains(serverId)) {
      ctx.dropReplicatedState(id);
    }
    return {TRI_ERROR_NO_ERROR};
  }
}
<commit_msg>Removed dead code (#16088)<commit_after>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2021-2022 ArangoDB GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Lars Maier
////////////////////////////////////////////////////////////////////////////////
#include "Logger/LogMacros.h"
#include "UpdateReplicatedState.h"
#include "Replication2/ReplicatedState/StateCommon.h"
#include "Basics/voc-errors.h"
#include "Logger/LogContextKeys.h"

using namespace arangodb::replication2;
using namespace arangodb::replication2::replicated_state;

auto algorithms::updateReplicatedState(
    StateActionContext& ctx, std::string const& serverId, LogId id,
    replicated_state::agency::Plan const* spec,
    replicated_state::agency::Current const* current) -> arangodb::Result {
  if (spec == nullptr) {
    return ctx.dropReplicatedState(id);
  }

  TRI_ASSERT(id == spec->id);
  TRI_ASSERT(spec->participants.contains(serverId));
  auto expectedGeneration = spec->participants.at(serverId).generation;

  auto logCtx =
      LoggerContext(Logger::REPLICATED_STATE).with<logContextKeyLogId>(id);

  LOG_CTX("b089c", TRACE, logCtx) << "Update replicated log" << id
                                  << " for generation " << expectedGeneration;

  auto state = ctx.getReplicatedStateById(id);
  if (state == nullptr) {
    // TODO use user data instead of non-slice
    auto result =
        ctx.createReplicatedState(id, spec->properties.implementation.type,
                                  velocypack::Slice::noneSlice());
    if (result.fail()) {
      return result.result();
    }

    state = result.get();

    auto token = std::invoke([&] {
      if (current) {
        if (auto const p = current->participants.find(serverId);
            p != std::end(current->participants)) {
          if (p->second.generation == expectedGeneration) {
            LOG_CTX("19d00", DEBUG, logCtx)
                << "Using existing snapshot information from current";
            // we are allowed to use the information stored here
            return std::make_unique<ReplicatedStateToken>(
                ReplicatedStateToken::withExplicitSnapshotStatus(
                    expectedGeneration, p->second.snapshot));
          } else {
            LOG_CTX("6d8c9", DEBUG, logCtx)
                << "Must not use existing information, generation is "
                   "different. "
                << "Plan = " << expectedGeneration
                << " but Current = " << p->second.generation;
          }
        } else {
          LOG_CTX("cef1a", DEBUG, logCtx)
              << "No snapshot information available for this server "
              << serverId;
        }
      } else {
        LOG_CTX("d4fd8", DEBUG, logCtx)
            << "no current available to read snapshot information from. "
               "Assuming no snapshot available";
      }

      return std::make_unique<ReplicatedStateToken>(expectedGeneration);
    });
    // now start the replicated state
    state->start(std::move(token));
    return {TRI_ERROR_NO_ERROR};
  } else {
    auto status = state->getStatus();
    if (status.has_value()) {
      auto generation = status.value().getGeneration();
      if (generation != expectedGeneration) {
        state->flush(expectedGeneration);
      }
    }
    return {TRI_ERROR_NO_ERROR};
  }
}
<|endoftext|>


<commit_before><commit_msg>document with unit test rather odd embedded null handling<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: Ref.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 01:35:34 $
 *
 *  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 _CONNECTIVITY_JAVA_SQL_REF_HXX_
#include "java/sql/Ref.hxx"
#endif
#ifndef _CONNECTIVITY_JAVA_TOOLS_HXX_
#include "java/tools.hxx"
#endif
using namespace connectivity;
//**************************************************************
//************ Class: java.sql.Ref
//**************************************************************

jclass java_sql_Ref::theClass = 0;
java_sql_Ref::java_sql_Ref( JNIEnv * pEnv, jobject myObj )
: java_lang_Object( pEnv, myObj )
{
    SDBThreadAttach::addRef();
}
java_sql_Ref::~java_sql_Ref()
{
    SDBThreadAttach::releaseRef();
}

jclass java_sql_Ref::getMyClass()
{
    // die Klasse muss nur einmal geholt werden, daher statisch
    if( !theClass ){
        SDBThreadAttach t;
        if( !t.pEnv ) return (jclass)NULL;
        jclass tempClass = t.pEnv->FindClass( "java/sql/Ref" );
        jclass globClass = (jclass)t.pEnv->NewGlobalRef( tempClass );
        t.pEnv->DeleteLocalRef( tempClass );
        saveClassRef( globClass );
    }
    return theClass;
}

void java_sql_Ref::saveClassRef( jclass pClass )
{
    if( pClass==NULL  )
        return;
    // der uebergebe Klassen-Handle ist schon global, daher einfach speichern
    theClass = pClass;
}

::rtl::OUString SAL_CALL java_sql_Ref::getBaseTypeName(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
{
    SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!");
    ::rtl::OUString aStr;
    if( t.pEnv ){
        // temporaere Variable initialisieren
        static const char * cSignature = "()Ljava/lang/String;";
        static const char * cMethodName = "getBaseTypeName";
        // Java-Call absetzen
        static jmethodID mID = NULL;
        if ( !mID  )
            mID  = t.pEnv->GetMethodID( getMyClass(), cMethodName, cSignature );OSL_ENSURE(mID,"Unknown method id!");
        if( mID ){
            jstring out = (jstring)t.pEnv->CallObjectMethod( object, mID);
            ThrowSQLException(t.pEnv,*this);
            aStr = JavaString2String(t.pEnv,out);
            // und aufraeumen
        } //mID
    } //t.pEnv
    // ACHTUNG: der Aufrufer wird Eigentuemer des zurueckgelieferten Zeigers !!!
    return  aStr;
}

<commit_msg>INTEGRATION: CWS pchfix02 (1.8.60); FILE MERGED 2006/09/01 17:22:21 kaib 1.8.60.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: Ref.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 02:48:17 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_connectivity.hxx"

#ifndef _CONNECTIVITY_JAVA_SQL_REF_HXX_
#include "java/sql/Ref.hxx"
#endif
#ifndef _CONNECTIVITY_JAVA_TOOLS_HXX_
#include "java/tools.hxx"
#endif
using namespace connectivity;
//**************************************************************
//************ Class: java.sql.Ref
//**************************************************************

jclass java_sql_Ref::theClass = 0;
java_sql_Ref::java_sql_Ref( JNIEnv * pEnv, jobject myObj )
: java_lang_Object( pEnv, myObj )
{
    SDBThreadAttach::addRef();
}
java_sql_Ref::~java_sql_Ref()
{
    SDBThreadAttach::releaseRef();
}

jclass java_sql_Ref::getMyClass()
{
    // die Klasse muss nur einmal geholt werden, daher statisch
    if( !theClass ){
        SDBThreadAttach t;
        if( !t.pEnv ) return (jclass)NULL;
        jclass tempClass = t.pEnv->FindClass( "java/sql/Ref" );
        jclass globClass = (jclass)t.pEnv->NewGlobalRef( tempClass );
        t.pEnv->DeleteLocalRef( tempClass );
        saveClassRef( globClass );
    }
    return theClass;
}

void java_sql_Ref::saveClassRef( jclass pClass )
{
    if( pClass==NULL  )
        return;
    // der uebergebe Klassen-Handle ist schon global, daher einfach speichern
    theClass = pClass;
}

::rtl::OUString SAL_CALL java_sql_Ref::getBaseTypeName(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
{
    SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!");
    ::rtl::OUString aStr;
    if( t.pEnv ){
        // temporaere Variable initialisieren
        static const char * cSignature = "()Ljava/lang/String;";
        static const char * cMethodName = "getBaseTypeName";
        // Java-Call absetzen
        static jmethodID mID = NULL;
        if ( !mID  )
            mID  = t.pEnv->GetMethodID( getMyClass(), cMethodName, cSignature );OSL_ENSURE(mID,"Unknown method id!");
        if( mID ){
            jstring out = (jstring)t.pEnv->CallObjectMethod( object, mID);
            ThrowSQLException(t.pEnv,*this);
            aStr = JavaString2String(t.pEnv,out);
            // und aufraeumen
        } //mID
    } //t.pEnv
    // ACHTUNG: der Aufrufer wird Eigentuemer des zurueckgelieferten Zeigers !!!
    return  aStr;
}

<|endoftext|>


<commit_before>
#include "OptFossilCollManagerFactory.h"
#include "ChebyFossilCollManager.h"
#include "SimulationConfiguration.h"
#include "TimeWarpConfigurationManager.h"
#include "ThreadedTimeWarpSimulationManager.h"
#include "ThreadedChebyFossilCollManager.h"
#include <WarpedDebug.h>

OptFossilCollManagerFactory::OptFossilCollManagerFactory(){}

OptFossilCollManagerFactory::~OptFossilCollManagerFactory(){
  // myFossilManager will be deleted by the end user - the
  // TimeWarpSimulationManager
}

Configurable *
OptFossilCollManagerFactory::allocate(SimulationConfiguration &configuration,
		Configurable *parent) const {
	Configurable *retval = NULL;
	TimeWarpSimulationManager *mySimulationManager =
			dynamic_cast<TimeWarpSimulationManager *> (parent);
	ThreadedTimeWarpSimulationManager *myThreadedSimulationManager =
			dynamic_cast<ThreadedTimeWarpSimulationManager *> (parent);

	ASSERT( mySimulationManager != NULL );
	// the following cases are possible:

	// (1) Manager is Cheby.
	// (2) None is used.

    std::string optFossilCollManagerType = configuration.get_string(
    	{"TimeWarp", "OptFossilCollManager", "Type"}, "None");
    std::string simulationType = configuration.get_string({"Simulation"}, "Sequential");
	if (optFossilCollManagerType == "Cheby") {
		unsigned int checkpointPeriod = 1000;
		unsigned int minSamples = 64;
		unsigned int maxSamples = 100;
		unsigned int defaultLength = 2000;
		double riskFactor = 0.99;
		configuration.getOptFossilCollPeriod(checkpointPeriod);
		configuration.getOptFossilCollMinSamples(minSamples);
		configuration.getOptFossilCollMaxSamples(maxSamples);
		configuration.getOptFossilCollDefaultLength(defaultLength);
		configuration.getOptFossilCollRiskFactor(riskFactor);
		if (simulationType == "ThreadedTimeWarp") {
			retval = new ThreadedChebyFossilCollManager(myThreadedSimulationManager,
					checkpointPeriod, minSamples, maxSamples, defaultLength,
					riskFactor);
			myThreadedSimulationManager->setOptFossilColl(true);

		} else {
			retval = new ChebyFossilCollManager(mySimulationManager,
					checkpointPeriod, minSamples, maxSamples, defaultLength,
					riskFactor);
			mySimulationManager->setOptFossilColl(true);
			debug::debugout << "("
					<< mySimulationManager->getSimulationManagerID()
					<< ") configured a Cheby Optimistic Fossil Collection Manager "
					<< "with checkpoint interval: " << checkpointPeriod
					<< ", and risk factor: " << riskFactor << endl;
		}
	} else if (optFossilCollManagerType == "None") {
		retval = NULL;
	} else {
		mySimulationManager->shutdown(
				"Unknown FossilManager choice \""
						+ configuration.getGVTManagerType() + "\"");
	}

	return retval;
}

const OptFossilCollManagerFactory *
OptFossilCollManagerFactory::instance(){
  static OptFossilCollManagerFactory *singleton = new OptFossilCollManagerFactory();

  return singleton;
}
<commit_msg>Removed getOptFossilCollPeriod usage<commit_after>
#include "OptFossilCollManagerFactory.h"
#include "ChebyFossilCollManager.h"
#include "SimulationConfiguration.h"
#include "TimeWarpConfigurationManager.h"
#include "ThreadedTimeWarpSimulationManager.h"
#include "ThreadedChebyFossilCollManager.h"
#include <WarpedDebug.h>

OptFossilCollManagerFactory::OptFossilCollManagerFactory(){}

OptFossilCollManagerFactory::~OptFossilCollManagerFactory(){
  // myFossilManager will be deleted by the end user - the
  // TimeWarpSimulationManager
}

Configurable *
OptFossilCollManagerFactory::allocate(SimulationConfiguration &configuration,
		Configurable *parent) const {
	Configurable *retval = NULL;
	TimeWarpSimulationManager *mySimulationManager =
			dynamic_cast<TimeWarpSimulationManager *> (parent);
	ThreadedTimeWarpSimulationManager *myThreadedSimulationManager =
			dynamic_cast<ThreadedTimeWarpSimulationManager *> (parent);

	ASSERT( mySimulationManager != NULL );
	// the following cases are possible:

	// (1) Manager is Cheby.
	// (2) None is used.

    std::string optFossilCollManagerType = configuration.get_string(
    	{"TimeWarp", "OptFossilCollManager", "Type"}, "None");
    std::string simulationType = configuration.get_string({"Simulation"}, "Sequential");
	if (optFossilCollManagerType == "Cheby") {
		int checkpointPeriod = configuration.get_int({"TimeWarp", "OptFossilCollManager", "CheckpointTime"},
													1000);
		unsigned int minSamples = 64;
		unsigned int maxSamples = 100;
		unsigned int defaultLength = 2000;
		double riskFactor = 0.99;
		configuration.getOptFossilCollMinSamples(minSamples);
		configuration.getOptFossilCollMaxSamples(maxSamples);
		configuration.getOptFossilCollDefaultLength(defaultLength);
		configuration.getOptFossilCollRiskFactor(riskFactor);
		if (simulationType == "ThreadedTimeWarp") {
			retval = new ThreadedChebyFossilCollManager(myThreadedSimulationManager,
					checkpointPeriod, minSamples, maxSamples, defaultLength,
					riskFactor);
			myThreadedSimulationManager->setOptFossilColl(true);

		} else {
			retval = new ChebyFossilCollManager(mySimulationManager,
					checkpointPeriod, minSamples, maxSamples, defaultLength,
					riskFactor);
			mySimulationManager->setOptFossilColl(true);
			debug::debugout << "("
					<< mySimulationManager->getSimulationManagerID()
					<< ") configured a Cheby Optimistic Fossil Collection Manager "
					<< "with checkpoint interval: " << checkpointPeriod
					<< ", and risk factor: " << riskFactor << endl;
		}
	} else if (optFossilCollManagerType == "None") {
		retval = NULL;
	} else {
		mySimulationManager->shutdown(
				"Unknown FossilManager choice \""
						+ configuration.getGVTManagerType() + "\"");
	}

	return retval;
}

const OptFossilCollManagerFactory *
OptFossilCollManagerFactory::instance(){
  static OptFossilCollManagerFactory *singleton = new OptFossilCollManagerFactory();

  return singleton;
}
<|endoftext|>


<commit_before>/* RTcmix - Copyright (C) 2005 The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/
// The set_option function, called from a script, lets the user override
// default options (and those stored in the .rtcmixrc file).  The options
// are kept in the <options> object.  See Option.h for advice on how to add
// new options.
//
// Please keep the items created in the steps above in the same order that they
// appear in Option.h -- makes this file easier to maintain.
//
// -JGG, 6/30/04, rev. 4/10/05

#include <RTcmix.h>
#include <ugens.h>		// for die()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <Option.h>

enum ParamType {
	AUDIO,
	PLAY,
	RECORD,
	CLOBBER,
	PRINT,
	REPORT_CLIPPING,
	CHECK_PEAKS,
	FULL_DUPLEX,
	EXIT_ON_ERROR,
	AUTO_LOAD,
	FAST_UPDATE,
	BUFFER_FRAMES,
	BUFFER_COUNT,
	DEVICE,
	INDEVICE,
	OUTDEVICE,
	MIDI_INDEVICE,
	MIDI_OUTDEVICE,
	DSOPATH,
	RCNAME
};

#define OPT_STRLEN 128

struct Param {
	char arg[OPT_STRLEN];
	ParamType type;
	bool value;		// use false if not relevant, i.e. for key=value style
};

static Param _param_list[] = {
	// These are key=value option strings.  Please list these in the order in
	// which they appear in Option.h, to make it easier to compare.
	{ kOptionAudio, AUDIO, false},
	{ kOptionPlay, PLAY, false},
	{ kOptionRecord, RECORD, false},
	{ kOptionClobber, CLOBBER, false},
	{ kOptionPrint, PRINT, false},
	{ kOptionReportClipping, REPORT_CLIPPING, false},
	{ kOptionCheckPeaks, CHECK_PEAKS, false},
	{ kOptionExitOnError, EXIT_ON_ERROR, false},
	{ kOptionAutoLoad, AUTO_LOAD, false},
	{ kOptionFastUpdate, FAST_UPDATE, false},

	{ kOptionBufferFrames, BUFFER_FRAMES, false},
	{ kOptionBufferCount, BUFFER_COUNT, false},

	{ kOptionDevice, DEVICE, false},
	{ kOptionInDevice, INDEVICE, false},
	{ kOptionOutDevice, OUTDEVICE, false},
	{ kOptionMidiInDevice, MIDI_INDEVICE, false},
	{ kOptionMidiOutDevice, MIDI_OUTDEVICE, false},
	{ kOptionDSOPath, DSOPATH, false},
	{ kOptionRCName, RCNAME, false},

	// These are the deprecated single-value option strings.
	// Please don't add more.
	{ "AUDIO_ON", AUDIO, true},
	{ "AUDIO_OFF", AUDIO, false},
	{ "RECORD_ON", RECORD, true},
	{ "RECORD_OFF", RECORD, false},
	{ "PLAY_ON", AUDIO, true},
	{ "PLAY_OFF", AUDIO, false},
	{ "CLOBBER_ON", CLOBBER, true},
	{ "CLOBBER_OFF", CLOBBER, false},
	{ "REPORT_CLIPPING_ON", REPORT_CLIPPING, true},
	{ "REPORT_CLIPPING_OFF", REPORT_CLIPPING, false},
	{ "CHECK_PEAKS_ON", CHECK_PEAKS, true},
	{ "CHECK_PEAKS_OFF", CHECK_PEAKS, false},
	{ "FULL_DUPLEX_ON", FULL_DUPLEX, true},
	{ "FULL_DUPLEX_OFF", FULL_DUPLEX, false},
};
static int _num_params = sizeof(_param_list) / sizeof(Param);

//-------------------------------- _str_to_bool, _str_to_int, _str_to_double ---
static int _str_to_bool(const char *str, bool &val)
{
	if (strcasecmp(str, "yes") == 0 || strcasecmp(str, "true") == 0
			|| strcasecmp(str, "on") == 0 || strcmp(str, "1") == 0)
		val = true;
	else if (strcasecmp(str, "no") == 0 || strcasecmp(str, "false") == 0
			|| strcasecmp(str, "off") == 0 || strcmp(str, "0") == 0)
		val = false;
	else {
		val = false;
		return -1;
	}
	return 0;
}

static int _str_to_int(const char *str, int &val)
{
	char *pos = NULL;
	long num = strtol(str, &pos, 10);
	if (*pos != 0)
		return -1;
	val = num;
	return 0;
}

static int _str_to_double(const char *str, double &val)
{
	char *pos = NULL;
	errno = 0;
	val = strtod(str, &pos);
	if (errno != 0 || (val == 0.0 && pos == str))
		return -1;
	return 0;
}

//--------------------------------------------------------- _set_full_duplex ---
// The full duplex state has now been broken up into the <play> and <record>
// options, used during audio setup.  rtsetparams() checks <record>.
static int _set_full_duplex(const bool full_duplex,
	const bool rtsetparams_called)
{
	if (full_duplex && rtsetparams_called)
		return die("set_option",
					"Turn on full duplex BEFORE calling rtsetparams.");

	if (full_duplex)
		Option::record(true);
	else {
		// If not play, then record.
		bool state = Option::record() && !Option::play();
		Option::record(state);
	}
	// Same check as above, for record.
	if (Option::record() && rtsetparams_called)
		return die("set_option",
					"Turn on record BEFORE calling rtsetparams.");
	return 0;
}

//---------------------------------------------------- _set_key_value_option ---
static int _set_key_value_option(const char *key, const char *sval,
	const bool rtsetparams_called)
{
	int type = -1;
	for (int j = 0; j < _num_params; j++) {
		if (strcasecmp(_param_list[j].arg, key) == 0) {
			type = _param_list[j].type;
			break;
		}
	}
	if (type == -1)
		return -1;
	if (sval == NULL)
		return die("set_option", "No value for \"%s\"", key);

	int status = 0;
	bool bval = false;
	int ival = 0;
	double dval = 0.0;

	switch (type) {
		case AUDIO:
			status = _str_to_bool(sval, bval);
			Option::audio(bval);
			break;
		case PLAY:
			status = _str_to_bool(sval, bval);
			Option::play(bval);
			break;
		case RECORD:
			status = _str_to_bool(sval, bval);
			Option::record(bval);
			if (Option::record() && rtsetparams_called)
				return die("set_option",
							"Turn on record BEFORE calling rtsetparams.");
			break;
		case CLOBBER:
			status = _str_to_bool(sval, bval);
			Option::clobber(bval);
			break;
		case PRINT:
			status = _str_to_bool(sval, bval);
			Option::print(bval);
			break;
		case REPORT_CLIPPING:
			status = _str_to_bool(sval, bval);
			Option::reportClipping(bval);
			break;
		case CHECK_PEAKS:
			status = _str_to_bool(sval, bval);
			Option::checkPeaks(bval);
			break;
		case EXIT_ON_ERROR:
			status = _str_to_bool(sval, bval);
			Option::exitOnError(bval);
			break;
		case AUTO_LOAD:
			status = _str_to_bool(sval, bval);
			Option::autoLoad(bval);
			break;
		case FAST_UPDATE:
			status = _str_to_bool(sval, bval);
			Option::fastUpdate(bval);
			if (bval)
				warn("set_option", "With \"%s\" on, certain instruments run "
					"faster at the expense of reduced capabilities.\n", key);
			break;
		case BUFFER_FRAMES:
			status = _str_to_int(sval, ival);
			if (status == 0) {
				if (ival <= 0)
					return die("set_option", "\"%s\" value must be > 0", key);
				Option::bufferFrames(ival);
			}
			break;
		case BUFFER_COUNT:
			status = _str_to_int(sval, ival);
			if (status == 0) {
				if (ival <= 0)
					return die("set_option", "\"%s\" value must be > 0", key);
				Option::bufferCount(ival);
			}
			break;
		case DEVICE:
			Option::device(sval);
			break;
		case INDEVICE:
			Option::inDevice(sval);
			break;
		case OUTDEVICE:
			Option::outDevice(sval);
			break;
		case MIDI_INDEVICE:
			Option::midiInDevice(sval);
			break;
		case MIDI_OUTDEVICE:
			Option::midiOutDevice(sval);
			break;
		case DSOPATH:
			Option::dsoPath(sval);
			break;
		case RCNAME:
			Option::rcName(sval);
			break;
		default:
			break;
	}

	if (status == -1)
		return die("set_option", "Trouble parsing value \"%s\"", sval);
	return status;
}

//-------------------------------------------------------- _set_value_option ---
// This way of setting options is deprecated, in favor of the new key=value way.
// Do not handle new options in this function; use _set_key_value_option.
static int _set_value_option(const char *sval, const bool rtsetparams_called)
{
	int type = -1;
	bool bval = false;
	for (int j = 0; j < _num_params; j++) {
		if (strcasecmp(_param_list[j].arg, sval) == 0) {
			type = _param_list[j].type;
			bval = _param_list[j].value;
			break;
		}
	}
	if (type == -1)
		return -1;

	switch (type) {
		case AUDIO:
			Option::play(bval);
			break;
		case RECORD:
			Option::record(bval);
			if (Option::record() && rtsetparams_called)
				return die("set_option",
							"Turn on record BEFORE calling rtsetparams.");
			break;
		case CLOBBER:
			Option::clobber(bval);
			break;
		case REPORT_CLIPPING:
			Option::reportClipping(bval);
			break;
		case CHECK_PEAKS:
			Option::checkPeaks(bval);
			break;
		case FULL_DUPLEX:
			if (_set_full_duplex(bval, rtsetparams_called) == -1)
				return -1;
			break;
		default:
			break;
	}

	return 0;
}

//--------------------------------------------------------------- _parse_arg ---
static int _parse_arg(const char *arg, const bool rtsetparams_called)
{
	// Strip white-space chars from text to the left of any '=' and between
	// the '=' and the next non-white space.  The reason we don't strip the
	// whole string is to preserve options that must include spaces, such
	// as "MOTU 828".  Store result into <opt>.

	int len = arg ? strlen(arg) : 0;
	if (len > OPT_STRLEN - 1)
		len = OPT_STRLEN - 1;

	char opt[OPT_STRLEN];
	char *p = opt;
	int space_state = 0;
	for (int j = 0; j < len; j++) {
		if (space_state > 1)
			*p++ = arg[j];
		else if (!isspace(arg[j])) {
			if (space_state == 1)
				space_state++;
			else if (arg[j] == '=')
				space_state = 1;
			*p++ = arg[j];
		}
	}
	*p = '\0';

	// Two styles of option string: a single "value" and a "key=value" pair.
	int status = 0;
	p = strchr(opt, '=');				// check for "key=value"
	if (p) {
		*p++ = '\0';						// <opt> is now key only
		if (*p == '\0')					// p now points to value string
			return die("set_option", "Missing value for key \"%s\"", opt);
		status = _set_key_value_option(opt, p, rtsetparams_called);
	}
	else										// check for single "value"
		status = _set_value_option(opt, rtsetparams_called);

	if (status == -1)
		return die("set_option", "Unrecognized option \"%s\"", opt);
	return 0;
}

//--------------------------------------------------------------- set_option ---
double RTcmix::set_option(float *p, int nargs, double pp[])
{
	// Because options can be set in any order, we need to check certain state
	// at the starting point and compare it to the finished state to determine if
	// a legal change has been made.

	bool playWasOn = Option::play();

	for (int i = 0; i < nargs; i++) {
		char *arg = (char *) ((int) pp[i]);		// cast pfield to string

		if (_parse_arg(arg, rtsetparams_was_called()) == -1)
			return -1.0;
	}

	// Now we check the finished state

	if (rtsetparams_was_called() && playWasOn && !Option::play()) {
		return die("set_option", "Turn off audio/play BEFORE calling rtsetparams.");
	}
	return 0.0;
}

<commit_msg>Removed unneeded logic.<commit_after>/* RTcmix - Copyright (C) 2005 The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/
// The set_option function, called from a script, lets the user override
// default options (and those stored in the .rtcmixrc file).  The options
// are kept in the <options> object.  See Option.h for advice on how to add
// new options.
//
// Please keep the items created in the steps above in the same order that they
// appear in Option.h -- makes this file easier to maintain.
//
// -JGG, 6/30/04, rev. 4/10/05

#include <RTcmix.h>
#include <ugens.h>		// for die()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <Option.h>

enum ParamType {
	AUDIO,
	PLAY,
	RECORD,
	CLOBBER,
	PRINT,
	REPORT_CLIPPING,
	CHECK_PEAKS,
	FULL_DUPLEX,
	EXIT_ON_ERROR,
	AUTO_LOAD,
	FAST_UPDATE,
	BUFFER_FRAMES,
	BUFFER_COUNT,
	DEVICE,
	INDEVICE,
	OUTDEVICE,
	MIDI_INDEVICE,
	MIDI_OUTDEVICE,
	DSOPATH,
	RCNAME
};

#define OPT_STRLEN 128

struct Param {
	char arg[OPT_STRLEN];
	ParamType type;
	bool value;		// use false if not relevant, i.e. for key=value style
};

static Param _param_list[] = {
	// These are key=value option strings.  Please list these in the order in
	// which they appear in Option.h, to make it easier to compare.
	{ kOptionAudio, AUDIO, false},
	{ kOptionPlay, PLAY, false},
	{ kOptionRecord, RECORD, false},
	{ kOptionClobber, CLOBBER, false},
	{ kOptionPrint, PRINT, false},
	{ kOptionReportClipping, REPORT_CLIPPING, false},
	{ kOptionCheckPeaks, CHECK_PEAKS, false},
	{ kOptionExitOnError, EXIT_ON_ERROR, false},
	{ kOptionAutoLoad, AUTO_LOAD, false},
	{ kOptionFastUpdate, FAST_UPDATE, false},

	{ kOptionBufferFrames, BUFFER_FRAMES, false},
	{ kOptionBufferCount, BUFFER_COUNT, false},

	{ kOptionDevice, DEVICE, false},
	{ kOptionInDevice, INDEVICE, false},
	{ kOptionOutDevice, OUTDEVICE, false},
	{ kOptionMidiInDevice, MIDI_INDEVICE, false},
	{ kOptionMidiOutDevice, MIDI_OUTDEVICE, false},
	{ kOptionDSOPath, DSOPATH, false},
	{ kOptionRCName, RCNAME, false},

	// These are the deprecated single-value option strings.
	// Please don't add more.
	{ "AUDIO_ON", AUDIO, true},
	{ "AUDIO_OFF", AUDIO, false},
	{ "RECORD_ON", RECORD, true},
	{ "RECORD_OFF", RECORD, false},
	{ "PLAY_ON", AUDIO, true},
	{ "PLAY_OFF", AUDIO, false},
	{ "CLOBBER_ON", CLOBBER, true},
	{ "CLOBBER_OFF", CLOBBER, false},
	{ "REPORT_CLIPPING_ON", REPORT_CLIPPING, true},
	{ "REPORT_CLIPPING_OFF", REPORT_CLIPPING, false},
	{ "CHECK_PEAKS_ON", CHECK_PEAKS, true},
	{ "CHECK_PEAKS_OFF", CHECK_PEAKS, false},
	{ "FULL_DUPLEX_ON", FULL_DUPLEX, true},
	{ "FULL_DUPLEX_OFF", FULL_DUPLEX, false},
};
static int _num_params = sizeof(_param_list) / sizeof(Param);

//-------------------------------- _str_to_bool, _str_to_int, _str_to_double ---
static int _str_to_bool(const char *str, bool &val)
{
	if (strcasecmp(str, "yes") == 0 || strcasecmp(str, "true") == 0
			|| strcasecmp(str, "on") == 0 || strcmp(str, "1") == 0)
		val = true;
	else if (strcasecmp(str, "no") == 0 || strcasecmp(str, "false") == 0
			|| strcasecmp(str, "off") == 0 || strcmp(str, "0") == 0)
		val = false;
	else {
		val = false;
		return -1;
	}
	return 0;
}

static int _str_to_int(const char *str, int &val)
{
	char *pos = NULL;
	long num = strtol(str, &pos, 10);
	if (*pos != 0)
		return -1;
	val = num;
	return 0;
}

static int _str_to_double(const char *str, double &val)
{
	char *pos = NULL;
	errno = 0;
	val = strtod(str, &pos);
	if (errno != 0 || (val == 0.0 && pos == str))
		return -1;
	return 0;
}

//--------------------------------------------------------- _set_full_duplex ---
// The full duplex state has now been broken up into the <play> and <record>
// options, used during audio setup.  rtsetparams() checks <record>.
static int _set_full_duplex(const bool full_duplex,
	const bool rtsetparams_called)
{
	if (full_duplex && rtsetparams_called)
		return die("set_option",
					"Turn on full duplex BEFORE calling rtsetparams.");

	if (full_duplex)
		Option::record(true);
	else {
		// If not play, then record.
		bool state = Option::record() && !Option::play();
		Option::record(state);
	}
	// Same check as above, for record.
	if (Option::record() && rtsetparams_called)
		return die("set_option",
					"Turn on record BEFORE calling rtsetparams.");
	return 0;
}

//---------------------------------------------------- _set_key_value_option ---
static int _set_key_value_option(const char *key, const char *sval,
	const bool rtsetparams_called)
{
	int type = -1;
	for (int j = 0; j < _num_params; j++) {
		if (strcasecmp(_param_list[j].arg, key) == 0) {
			type = _param_list[j].type;
			break;
		}
	}
	if (type == -1)
		return -1;
	if (sval == NULL)
		return die("set_option", "No value for \"%s\"", key);

	int status = 0;
	bool bval = false;
	int ival = 0;
	double dval = 0.0;

	switch (type) {
		case AUDIO:
			status = _str_to_bool(sval, bval);
			Option::audio(bval);
			break;
		case PLAY:
			status = _str_to_bool(sval, bval);
			Option::play(bval);
			break;
		case RECORD:
			status = _str_to_bool(sval, bval);
			Option::record(bval);
			if (Option::record() && rtsetparams_called)
				return die("set_option",
							"Turn on record BEFORE calling rtsetparams.");
			break;
		case CLOBBER:
			status = _str_to_bool(sval, bval);
			Option::clobber(bval);
			break;
		case PRINT:
			status = _str_to_bool(sval, bval);
			Option::print(bval);
			break;
		case REPORT_CLIPPING:
			status = _str_to_bool(sval, bval);
			Option::reportClipping(bval);
			break;
		case CHECK_PEAKS:
			status = _str_to_bool(sval, bval);
			Option::checkPeaks(bval);
			break;
		case EXIT_ON_ERROR:
			status = _str_to_bool(sval, bval);
			Option::exitOnError(bval);
			break;
		case AUTO_LOAD:
			status = _str_to_bool(sval, bval);
			Option::autoLoad(bval);
			break;
		case FAST_UPDATE:
			status = _str_to_bool(sval, bval);
			Option::fastUpdate(bval);
			if (bval)
				warn("set_option", "With \"%s\" on, certain instruments run "
					"faster at the expense of reduced capabilities.\n", key);
			break;
		case BUFFER_FRAMES:
			status = _str_to_int(sval, ival);
			if (status == 0) {
				if (ival <= 0)
					return die("set_option", "\"%s\" value must be > 0", key);
				Option::bufferFrames(ival);
			}
			break;
		case BUFFER_COUNT:
			status = _str_to_int(sval, ival);
			if (status == 0) {
				if (ival <= 0)
					return die("set_option", "\"%s\" value must be > 0", key);
				Option::bufferCount(ival);
			}
			break;
		case DEVICE:
			Option::device(sval);
			break;
		case INDEVICE:
			Option::inDevice(sval);
			break;
		case OUTDEVICE:
			Option::outDevice(sval);
			break;
		case MIDI_INDEVICE:
			Option::midiInDevice(sval);
			break;
		case MIDI_OUTDEVICE:
			Option::midiOutDevice(sval);
			break;
		case DSOPATH:
			Option::dsoPath(sval);
			break;
		case RCNAME:
			Option::rcName(sval);
			break;
		default:
			break;
	}

	if (status == -1)
		return die("set_option", "Trouble parsing value \"%s\"", sval);
	return status;
}

//-------------------------------------------------------- _set_value_option ---
// This way of setting options is deprecated, in favor of the new key=value way.
// Do not handle new options in this function; use _set_key_value_option.
static int _set_value_option(const char *sval, const bool rtsetparams_called)
{
	int type = -1;
	bool bval = false;
	for (int j = 0; j < _num_params; j++) {
		if (strcasecmp(_param_list[j].arg, sval) == 0) {
			type = _param_list[j].type;
			bval = _param_list[j].value;
			break;
		}
	}
	if (type == -1)
		return -1;

	switch (type) {
		case AUDIO:
			Option::play(bval);
			break;
		case RECORD:
			Option::record(bval);
			if (Option::record() && rtsetparams_called)
				return die("set_option",
							"Turn on record BEFORE calling rtsetparams.");
			break;
		case CLOBBER:
			Option::clobber(bval);
			break;
		case REPORT_CLIPPING:
			Option::reportClipping(bval);
			break;
		case CHECK_PEAKS:
			Option::checkPeaks(bval);
			break;
		case FULL_DUPLEX:
			if (_set_full_duplex(bval, rtsetparams_called) == -1)
				return -1;
			break;
		default:
			break;
	}

	return 0;
}

//--------------------------------------------------------------- _parse_arg ---
static int _parse_arg(const char *arg, const bool rtsetparams_called)
{
	// Strip white-space chars from text to the left of any '=' and between
	// the '=' and the next non-white space.  The reason we don't strip the
	// whole string is to preserve options that must include spaces, such
	// as "MOTU 828".  Store result into <opt>.

	int len = arg ? strlen(arg) : 0;
	if (len > OPT_STRLEN - 1)
		len = OPT_STRLEN - 1;

	char opt[OPT_STRLEN];
	char *p = opt;
	int space_state = 0;
	for (int j = 0; j < len; j++) {
		if (space_state > 1)
			*p++ = arg[j];
		else if (!isspace(arg[j])) {
			if (space_state == 1)
				space_state++;
			else if (arg[j] == '=')
				space_state = 1;
			*p++ = arg[j];
		}
	}
	*p = '\0';

	// Two styles of option string: a single "value" and a "key=value" pair.
	int status = 0;
	p = strchr(opt, '=');				// check for "key=value"
	if (p) {
		*p++ = '\0';						// <opt> is now key only
		if (*p == '\0')					// p now points to value string
			return die("set_option", "Missing value for key \"%s\"", opt);
		status = _set_key_value_option(opt, p, rtsetparams_called);
	}
	else										// check for single "value"
		status = _set_value_option(opt, rtsetparams_called);

	if (status == -1)
		return die("set_option", "Unrecognized option \"%s\"", opt);
	return 0;
}

//--------------------------------------------------------------- set_option ---
double RTcmix::set_option(float *p, int nargs, double pp[])
{
	for (int i = 0; i < nargs; i++) {
		char *arg = (char *) ((int) pp[i]);		// cast pfield to string

		if (_parse_arg(arg, rtsetparams_was_called()) == -1)
			return -1.0;
	}
	return 0.0;
}

<|endoftext|>


<commit_before>/*
* Copyright (C) 2008-2013 The Communi Project
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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 General Public License for more details.
*/

#include "themeinfo.h"
#include <QApplication>
#include <QSettings>
#include <QPalette>
#include <QColor>
#include <QFile>
#include <Irc>

QString ThemeInfo::attribute(const QString& key) const
{
    return d.attributes.value(key);
}

QString ThemeInfo::prefix() const
{
    return d.prefix;
}

QString ThemeInfo::docStyleSheet() const
{
    return d.css;
}

QString ThemeInfo::appStyleSheet() const
{
    return d.qss;
}

QMap<int, QString> ThemeInfo::colors() const
{
    return d.colors;
}

QMap<QString, QPalette> ThemeInfo::palettes() const
{
    return d.palettes;
}

static QColor parsePaletteColor(const QString& str)
{
    if (str == "alternate-base")
        return qApp->palette().color(QPalette::AlternateBase);
    else if (str == "base")
        return qApp->palette().color(QPalette::Base);
    else if (str == "bright-text")
        return qApp->palette().color(QPalette::BrightText);
    else if (str == "button")
        return qApp->palette().color(QPalette::Button);
    else if (str == "button-text")
        return qApp->palette().color(QPalette::ButtonText);
    else if (str == "dark")
        return qApp->palette().color(QPalette::Dark);
    else if (str == "highlight")
        return qApp->palette().color(QPalette::Highlight);
    else if (str == "highlighted-text")
        return qApp->palette().color(QPalette::HighlightedText);
    else if (str == "light")
        return qApp->palette().color(QPalette::Light);
    else if (str == "link")
        return qApp->palette().color(QPalette::Link);
    else if (str == "link-visited")
        return qApp->palette().color(QPalette::LinkVisited);
    else if (str == "mid")
        return qApp->palette().color(QPalette::Mid);
    else if (str == "midlight")
        return qApp->palette().color(QPalette::Midlight);
    else if (str == "shadow")
        return qApp->palette().color(QPalette::Shadow);
    else if (str == "text")
        return qApp->palette().color(QPalette::Text);
    else if (str == "window")
        return qApp->palette().color(QPalette::Window);
    else if (str == "window-text")
        return qApp->palette().color(QPalette::WindowText);
    return QColor();
}

static QColor parseRgbColor(const QString& str)
{
    QStringList rgb = str.split(",", QString::SkipEmptyParts);
    if (rgb.count() == 3)
        return qRgb(rgb.first().toInt(), rgb.at(1).toInt(), rgb.last().toInt());
    return QColor();
}

static QColor parseRgbaColor(const QString& str)
{
    QStringList rgba = str.split(",", QString::SkipEmptyParts);
    if (rgba.count() == 4)
        return qRgba(rgba.first().toInt(), rgba.at(1).toInt(), rgba.at(2).toInt(), rgba.last().toInt());
    return QColor();
}

static QColor parseColorValue(const QString& str, const QColor& defaultColor = QColor())
{
    QColor color;
    if (str.startsWith("palette(") && str.endsWith(")"))
        color = parsePaletteColor(str.mid(8, str.length() - 9));
    else if (str.startsWith("rgb(") && str.endsWith(")"))
        color = parseRgbColor(str.mid(4, str.length() - 5));
    else if (str.startsWith("rgba(") && str.endsWith(")"))
        color = parseRgbaColor(str.mid(5, str.length() - 6));
    else if (QColor::isValidColor(str))
        color = QColor(str);
    return color.isValid() ? color : defaultColor;
}

static QString readFile(const QString& filePath)
{
    QFile file(filePath);
    if (file.open(QFile::ReadOnly | QIODevice::Text))
        return QString::fromUtf8(file.readAll());
    return QString();
}

static void fillPalette(const QSettings& settings, QPalette& palette, QPalette::ColorGroup group)
{
    palette.setColor(group, QPalette::AlternateBase, parseColorValue(settings.value("alternate-base").toString(), palette.color(group, QPalette::AlternateBase)));
    palette.setColor(group, QPalette::Base, parseColorValue(settings.value("base").toString(), palette.color(group, QPalette::Base)));
    palette.setColor(group, QPalette::BrightText, parseColorValue(settings.value("bright-text").toString(), palette.color(group, QPalette::BrightText)));
    palette.setColor(group, QPalette::Button, parseColorValue(settings.value("button").toString(), palette.color(group, QPalette::Button)));
    palette.setColor(group, QPalette::ButtonText, parseColorValue(settings.value("button-text").toString(), palette.color(group, QPalette::ButtonText)));
    palette.setColor(group, QPalette::Dark, parseColorValue(settings.value("dark").toString(), palette.color(group, QPalette::Dark)));
    palette.setColor(group, QPalette::Highlight, parseColorValue(settings.value("highlight").toString(), palette.color(group, QPalette::Highlight)));
    palette.setColor(group, QPalette::HighlightedText, parseColorValue(settings.value("highlighted-text").toString(), palette.color(group, QPalette::HighlightedText)));
    palette.setColor(group, QPalette::Light, parseColorValue(settings.value("light").toString(), palette.color(group, QPalette::Light)));
    palette.setColor(group, QPalette::Link, parseColorValue(settings.value("link").toString(), palette.color(group, QPalette::Link)));
    palette.setColor(group, QPalette::LinkVisited, parseColorValue(settings.value("link-visited").toString(), palette.color(group, QPalette::LinkVisited)));
    palette.setColor(group, QPalette::Mid, parseColorValue(settings.value("mid").toString(), palette.color(group, QPalette::Mid)));
    palette.setColor(group, QPalette::Midlight, parseColorValue(settings.value("midlight").toString(), palette.color(group, QPalette::Midlight)));
    palette.setColor(group, QPalette::Shadow, parseColorValue(settings.value("shadow").toString(), palette.color(group, QPalette::Shadow)));
    palette.setColor(group, QPalette::Text, parseColorValue(settings.value("text").toString(), palette.color(group, QPalette::Text)));
    palette.setColor(group, QPalette::Window, parseColorValue(settings.value("window").toString(), palette.color(group, QPalette::Window)));
    palette.setColor(group, QPalette::WindowText, parseColorValue(settings.value("window-text").toString(), palette.color(group, QPalette::WindowText)));
}

static QPalette readPalette(QSettings& settings)
{
    QPalette palette;
    fillPalette(settings, palette, QPalette::Normal);
    settings.beginGroup("normal");
    fillPalette(settings, palette, QPalette::Normal);
    settings.endGroup();
    settings.beginGroup("disabled");
    fillPalette(settings, palette, QPalette::Disabled);
    settings.endGroup();
    settings.beginGroup("inactive");
    fillPalette(settings, palette, QPalette::Inactive);
    settings.endGroup();
    settings.beginGroup("active");
    fillPalette(settings, palette, QPalette::Active);
    return palette;
}

bool ThemeInfo::load(const QString& filePath)
{
    QSettings settings(filePath, QSettings::IniFormat);

    QStringList groups = settings.childGroups();
    if (groups.contains("Theme")) {
        settings.beginGroup("Theme");
        foreach (const QString& key, settings.childKeys())
            d.attributes.insert(key, settings.value(key).toString());
        settings.endGroup();
    }

    if (groups.contains("Resources")) {
        settings.beginGroup("Resources");
        d.prefix = settings.value("prefix").toString();
        settings.endGroup();
    }

    if (groups.contains("StyleSheets")) {
        settings.beginGroup("StyleSheets");
        d.css = readFile(settings.value("document").toString());
        d.qss = readFile(settings.value("application").toString());
        settings.endGroup();
    }

    if (groups.contains("QPalette")) {
        settings.beginGroup("QPalette");
        foreach (const QString& group, settings.childGroups()) {
            settings.beginGroup(group);
            d.palettes.insert(group, readPalette(settings));
            settings.endGroup();
        }
        settings.endGroup();
    }

    if (groups.contains("IrcPalette")) {
        settings.beginGroup("IrcPalette");
        const QStringList colorNames = QStringList() << "white" << "black" << "blue" << "green"
                                                     << "red" << "brown" << "purple" << "orange"
                                                     << "yellow" << "lightgreen" << "cyan" << "lightcyan"
                                                     << "lightblue" << "pink" << "gray" << "lightgray";
        for (int i = 0; i < colorNames.count(); ++i) {
            const QColor color = parseColorValue(settings.value(colorNames.at(i)).toString(), colorNames.at(i));
            if (color.isValid())
                d.colors.insert(i, color.name());
        }
        settings.endGroup();
    }

    return !d.attributes.value("name").isEmpty();
}
<commit_msg>Themes: add "background" & "foreground"<commit_after>/*
* Copyright (C) 2008-2013 The Communi Project
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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 General Public License for more details.
*/

#include "themeinfo.h"
#include <QApplication>
#include <QSettings>
#include <QPalette>
#include <QColor>
#include <QFile>
#include <Irc>

QString ThemeInfo::attribute(const QString& key) const
{
    return d.attributes.value(key);
}

QString ThemeInfo::prefix() const
{
    return d.prefix;
}

QString ThemeInfo::docStyleSheet() const
{
    return d.css;
}

QString ThemeInfo::appStyleSheet() const
{
    return d.qss;
}

QMap<int, QString> ThemeInfo::colors() const
{
    return d.colors;
}

QMap<QString, QPalette> ThemeInfo::palettes() const
{
    return d.palettes;
}

static QColor parsePaletteColor(const QString& str)
{
    if (str == "alternate-base")
        return qApp->palette().color(QPalette::AlternateBase);
    else if (str == "background")
        return qApp->palette().color(QPalette::Background);
    else if (str == "base")
        return qApp->palette().color(QPalette::Base);
    else if (str == "bright-text")
        return qApp->palette().color(QPalette::BrightText);
    else if (str == "button")
        return qApp->palette().color(QPalette::Button);
    else if (str == "button-text")
        return qApp->palette().color(QPalette::ButtonText);
    else if (str == "dark")
        return qApp->palette().color(QPalette::Dark);
    else if (str == "foreground")
        return qApp->palette().color(QPalette::Foreground);
    else if (str == "highlight")
        return qApp->palette().color(QPalette::Highlight);
    else if (str == "highlighted-text")
        return qApp->palette().color(QPalette::HighlightedText);
    else if (str == "light")
        return qApp->palette().color(QPalette::Light);
    else if (str == "link")
        return qApp->palette().color(QPalette::Link);
    else if (str == "link-visited")
        return qApp->palette().color(QPalette::LinkVisited);
    else if (str == "mid")
        return qApp->palette().color(QPalette::Mid);
    else if (str == "midlight")
        return qApp->palette().color(QPalette::Midlight);
    else if (str == "shadow")
        return qApp->palette().color(QPalette::Shadow);
    else if (str == "text")
        return qApp->palette().color(QPalette::Text);
    else if (str == "window")
        return qApp->palette().color(QPalette::Window);
    else if (str == "window-text")
        return qApp->palette().color(QPalette::WindowText);
    return QColor();
}

static QColor parseRgbColor(const QString& str)
{
    QStringList rgb = str.split(",", QString::SkipEmptyParts);
    if (rgb.count() == 3)
        return qRgb(rgb.first().toInt(), rgb.at(1).toInt(), rgb.last().toInt());
    return QColor();
}

static QColor parseRgbaColor(const QString& str)
{
    QStringList rgba = str.split(",", QString::SkipEmptyParts);
    if (rgba.count() == 4)
        return qRgba(rgba.first().toInt(), rgba.at(1).toInt(), rgba.at(2).toInt(), rgba.last().toInt());
    return QColor();
}

static QColor parseColorValue(const QString& str, const QColor& defaultColor = QColor())
{
    QColor color;
    if (str.startsWith("palette(") && str.endsWith(")"))
        color = parsePaletteColor(str.mid(8, str.length() - 9));
    else if (str.startsWith("rgb(") && str.endsWith(")"))
        color = parseRgbColor(str.mid(4, str.length() - 5));
    else if (str.startsWith("rgba(") && str.endsWith(")"))
        color = parseRgbaColor(str.mid(5, str.length() - 6));
    else if (QColor::isValidColor(str))
        color = QColor(str);
    return color.isValid() ? color : defaultColor;
}

static QString readFile(const QString& filePath)
{
    QFile file(filePath);
    if (file.open(QFile::ReadOnly | QIODevice::Text))
        return QString::fromUtf8(file.readAll());
    return QString();
}

static void fillPalette(const QSettings& settings, QPalette& palette, QPalette::ColorGroup group)
{
    palette.setColor(group, QPalette::AlternateBase, parseColorValue(settings.value("alternate-base").toString(), palette.color(group, QPalette::AlternateBase)));
    palette.setColor(group, QPalette::Base, parseColorValue(settings.value("base").toString(), palette.color(group, QPalette::Base)));
    palette.setColor(group, QPalette::BrightText, parseColorValue(settings.value("bright-text").toString(), palette.color(group, QPalette::BrightText)));
    palette.setColor(group, QPalette::Button, parseColorValue(settings.value("button").toString(), palette.color(group, QPalette::Button)));
    palette.setColor(group, QPalette::ButtonText, parseColorValue(settings.value("button-text").toString(), palette.color(group, QPalette::ButtonText)));
    palette.setColor(group, QPalette::Dark, parseColorValue(settings.value("dark").toString(), palette.color(group, QPalette::Dark)));
    palette.setColor(group, QPalette::Highlight, parseColorValue(settings.value("highlight").toString(), palette.color(group, QPalette::Highlight)));
    palette.setColor(group, QPalette::HighlightedText, parseColorValue(settings.value("highlighted-text").toString(), palette.color(group, QPalette::HighlightedText)));
    palette.setColor(group, QPalette::Light, parseColorValue(settings.value("light").toString(), palette.color(group, QPalette::Light)));
    palette.setColor(group, QPalette::Link, parseColorValue(settings.value("link").toString(), palette.color(group, QPalette::Link)));
    palette.setColor(group, QPalette::LinkVisited, parseColorValue(settings.value("link-visited").toString(), palette.color(group, QPalette::LinkVisited)));
    palette.setColor(group, QPalette::Mid, parseColorValue(settings.value("mid").toString(), palette.color(group, QPalette::Mid)));
    palette.setColor(group, QPalette::Midlight, parseColorValue(settings.value("midlight").toString(), palette.color(group, QPalette::Midlight)));
    palette.setColor(group, QPalette::Shadow, parseColorValue(settings.value("shadow").toString(), palette.color(group, QPalette::Shadow)));
    palette.setColor(group, QPalette::Text, parseColorValue(settings.value("text").toString(), palette.color(group, QPalette::Text)));
    palette.setColor(group, QPalette::Window, parseColorValue(settings.value("window").toString(), palette.color(group, QPalette::Window)));
    palette.setColor(group, QPalette::WindowText, parseColorValue(settings.value("window-text").toString(), palette.color(group, QPalette::WindowText)));
}

static QPalette readPalette(QSettings& settings)
{
    QPalette palette;
    fillPalette(settings, palette, QPalette::Normal);
    settings.beginGroup("normal");
    fillPalette(settings, palette, QPalette::Normal);
    settings.endGroup();
    settings.beginGroup("disabled");
    fillPalette(settings, palette, QPalette::Disabled);
    settings.endGroup();
    settings.beginGroup("inactive");
    fillPalette(settings, palette, QPalette::Inactive);
    settings.endGroup();
    settings.beginGroup("active");
    fillPalette(settings, palette, QPalette::Active);
    return palette;
}

bool ThemeInfo::load(const QString& filePath)
{
    QSettings settings(filePath, QSettings::IniFormat);

    QStringList groups = settings.childGroups();
    if (groups.contains("Theme")) {
        settings.beginGroup("Theme");
        foreach (const QString& key, settings.childKeys())
            d.attributes.insert(key, settings.value(key).toString());
        settings.endGroup();
    }

    if (groups.contains("Resources")) {
        settings.beginGroup("Resources");
        d.prefix = settings.value("prefix").toString();
        settings.endGroup();
    }

    if (groups.contains("StyleSheets")) {
        settings.beginGroup("StyleSheets");
        d.css = readFile(settings.value("document").toString());
        d.qss = readFile(settings.value("application").toString());
        settings.endGroup();
    }

    if (groups.contains("QPalette")) {
        settings.beginGroup("QPalette");
        foreach (const QString& group, settings.childGroups()) {
            settings.beginGroup(group);
            d.palettes.insert(group, readPalette(settings));
            settings.endGroup();
        }
        settings.endGroup();
    }

    if (groups.contains("IrcPalette")) {
        settings.beginGroup("IrcPalette");
        const QStringList colorNames = QStringList() << "white" << "black" << "blue" << "green"
                                                     << "red" << "brown" << "purple" << "orange"
                                                     << "yellow" << "lightgreen" << "cyan" << "lightcyan"
                                                     << "lightblue" << "pink" << "gray" << "lightgray";
        for (int i = 0; i < colorNames.count(); ++i) {
            const QColor color = parseColorValue(settings.value(colorNames.at(i)).toString(), colorNames.at(i));
            if (color.isValid())
                d.colors.insert(i, color.name());
        }
        settings.endGroup();
    }

    return !d.attributes.value("name").isEmpty();
}
<|endoftext|>