<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 2015 Cloudius Systems
 *
 * Modified by Cloudius Systems
 */

#pragma once

#include "cql3/statements/schema_altering_statement.hh"
#include "cql3/statements/cf_prop_defs.hh"
#include "cql3/statements/cf_statement.hh"
#include "cql3/cql3_type.hh"

#include "service/migration_manager.hh"
#include "schema.hh"

#include "core/shared_ptr.hh"

#include <unordered_map>
#include <utility>
#include <vector>
#include <set>

namespace cql3 {

namespace statements {

/** A CREATE TABLE parsed from a CQL query statement. */
class create_table_statement : public schema_altering_statement {
#if 0
    private AbstractType<?> defaultValidator;
#endif
    std::vector<data_type> _partition_key_types;
    std::vector<data_type> _clustering_key_types;
    std::vector<bytes> _key_aliases;
    std::vector<bytes> _column_aliases;
#if 0
    private ByteBuffer valueAlias;

    private boolean isDense;
#endif
    using column_map_type =
        std::unordered_map<::shared_ptr<column_identifier>,
                           data_type,
                           shared_ptr_value_hash<column_identifier>,
                           shared_ptr_equal_by_value<column_identifier>>;
    using column_set_type =
        std::unordered_set<::shared_ptr<column_identifier>,
                           shared_ptr_value_hash<column_identifier>,
                           shared_ptr_equal_by_value<column_identifier>>;
    column_map_type _columns;
    column_set_type _static_columns;
    const ::shared_ptr<cf_prop_defs> _properties;
    const bool _if_not_exists;
public:
    create_table_statement(::shared_ptr<cf_name> name,
                           ::shared_ptr<cf_prop_defs> properties,
                           bool if_not_exists,
                           column_set_type static_columns);

    virtual void check_access(const service::client_state& state) override;

    virtual void validate(distributed<service::storage_proxy>&, const service::client_state& state) override;

    virtual future<bool> announce_migration(distributed<service::storage_proxy>& proxy, bool is_local_only) override;

    virtual shared_ptr<transport::event::schema_change> change_event() override;

    schema_ptr get_cf_meta_data();

    class raw_statement;

    friend raw_statement;
private:
    std::vector<column_definition> get_columns();

    void apply_properties_to(schema_builder& builder);

    void add_column_metadata_from_aliases(schema_builder& builder, std::vector<bytes> aliases, const std::vector<data_type>& types, column_kind kind);
};

class create_table_statement::raw_statement : public cf_statement {
private:
    std::unordered_map<::shared_ptr<column_identifier>, ::shared_ptr<cql3_type::raw>> _definitions;
public:
    const ::shared_ptr<cf_prop_defs> properties = ::make_shared<cf_prop_defs>();
private:
    std::vector<std::vector<::shared_ptr<column_identifier>>> _key_aliases;
    std::vector<::shared_ptr<column_identifier>> _column_aliases;
    std::vector<std::pair<::shared_ptr<column_identifier>, bool>> defined_ordering; // Insertion ordering is important
    create_table_statement::column_set_type _static_columns;

    bool _use_compact_storage = false;
    std::multiset<::shared_ptr<column_identifier>> _defined_names;
    bool _if_not_exists;
public:
    raw_statement(::shared_ptr<cf_name> name, bool if_not_exists);

    virtual ::shared_ptr<prepared> prepare(database& db) override;

    data_type get_type_and_remove(column_map_type& columns, ::shared_ptr<column_identifier> t);

    void add_definition(::shared_ptr<column_identifier> def, ::shared_ptr<cql3_type::raw> type, bool is_static);

    void add_key_aliases(const std::vector<::shared_ptr<column_identifier>> aliases);

    void add_column_alias(::shared_ptr<column_identifier> alias);

    void set_ordering(::shared_ptr<column_identifier> alias, bool reversed);

    void set_compact_storage();
};

}

}
<commit_msg>cql3: Fix create_table_statement::raw_statement definition lookup<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 2015 Cloudius Systems
 *
 * Modified by Cloudius Systems
 */

#pragma once

#include "cql3/statements/schema_altering_statement.hh"
#include "cql3/statements/cf_prop_defs.hh"
#include "cql3/statements/cf_statement.hh"
#include "cql3/cql3_type.hh"

#include "service/migration_manager.hh"
#include "schema.hh"

#include "core/shared_ptr.hh"

#include <unordered_map>
#include <utility>
#include <vector>
#include <set>

namespace cql3 {

namespace statements {

/** A CREATE TABLE parsed from a CQL query statement. */
class create_table_statement : public schema_altering_statement {
#if 0
    private AbstractType<?> defaultValidator;
#endif
    std::vector<data_type> _partition_key_types;
    std::vector<data_type> _clustering_key_types;
    std::vector<bytes> _key_aliases;
    std::vector<bytes> _column_aliases;
#if 0
    private ByteBuffer valueAlias;

    private boolean isDense;
#endif
    using column_map_type =
        std::unordered_map<::shared_ptr<column_identifier>,
                           data_type,
                           shared_ptr_value_hash<column_identifier>,
                           shared_ptr_equal_by_value<column_identifier>>;
    using column_set_type =
        std::unordered_set<::shared_ptr<column_identifier>,
                           shared_ptr_value_hash<column_identifier>,
                           shared_ptr_equal_by_value<column_identifier>>;
    column_map_type _columns;
    column_set_type _static_columns;
    const ::shared_ptr<cf_prop_defs> _properties;
    const bool _if_not_exists;
public:
    create_table_statement(::shared_ptr<cf_name> name,
                           ::shared_ptr<cf_prop_defs> properties,
                           bool if_not_exists,
                           column_set_type static_columns);

    virtual void check_access(const service::client_state& state) override;

    virtual void validate(distributed<service::storage_proxy>&, const service::client_state& state) override;

    virtual future<bool> announce_migration(distributed<service::storage_proxy>& proxy, bool is_local_only) override;

    virtual shared_ptr<transport::event::schema_change> change_event() override;

    schema_ptr get_cf_meta_data();

    class raw_statement;

    friend raw_statement;
private:
    std::vector<column_definition> get_columns();

    void apply_properties_to(schema_builder& builder);

    void add_column_metadata_from_aliases(schema_builder& builder, std::vector<bytes> aliases, const std::vector<data_type>& types, column_kind kind);
};

class create_table_statement::raw_statement : public cf_statement {
private:
    using defs_type = std::unordered_map<::shared_ptr<column_identifier>,
                                         ::shared_ptr<cql3_type::raw>,
                                         shared_ptr_value_hash<column_identifier>,
                                         shared_ptr_equal_by_value<column_identifier>>;
    defs_type _definitions;
public:
    const ::shared_ptr<cf_prop_defs> properties = ::make_shared<cf_prop_defs>();
private:
    std::vector<std::vector<::shared_ptr<column_identifier>>> _key_aliases;
    std::vector<::shared_ptr<column_identifier>> _column_aliases;
    std::vector<std::pair<::shared_ptr<column_identifier>, bool>> defined_ordering; // Insertion ordering is important
    create_table_statement::column_set_type _static_columns;

    bool _use_compact_storage = false;
    std::multiset<::shared_ptr<column_identifier>> _defined_names;
    bool _if_not_exists;
public:
    raw_statement(::shared_ptr<cf_name> name, bool if_not_exists);

    virtual ::shared_ptr<prepared> prepare(database& db) override;

    data_type get_type_and_remove(column_map_type& columns, ::shared_ptr<column_identifier> t);

    void add_definition(::shared_ptr<column_identifier> def, ::shared_ptr<cql3_type::raw> type, bool is_static);

    void add_key_aliases(const std::vector<::shared_ptr<column_identifier>> aliases);

    void add_column_alias(::shared_ptr<column_identifier> alias);

    void set_ordering(::shared_ptr<column_identifier> alias, bool reversed);

    void set_compact_storage();
};

}

}
<|endoftext|>


<commit_before>/** \brief A MARC-21 filter utility that can remove characters from a set of subfields.
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2016 Universitätsbiblothek 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 <iostream>
#include <memory>
#include <unordered_set>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "DirectoryEntry.h"
#include "FileUtil.h"
#include "Leader.h"
#include "MarcUtil.h"
#include "MarcXmlWriter.h"
#include "MediaTypeUtil.h"
#include "RegexMatcher.h"
#include "StringUtil.h"
#include "Subfields.h"
#include "util.h"

void Usage() {
    std::cerr << "usage: " << progname << " marc_input marc_output subfield_spec1:subfield_spec2:...:subfield_specN "
              << " characters_to_delete\n"
              << "       where \"subfieldspec\" must be a MARC tag followed by a single-character\n"
              << "       subfield code and \"characters_to_delete\" is list of characters that will be removed\n"
              << "       from the contents of the specified subfields.\n\n";

    std::exit(EXIT_FAILURE);
}

std::string GetSubfieldCodes(const std::string &tag, const std::vector<std::string> &subfield_specs) {
    std::string subfield_codes;

    for (const auto &subfield_spec : subfield_specs) {
        if (subfield_spec.substr(0, DirectoryEntry::TAG_LENGTH) == tag)
            subfield_codes += subfield_spec[DirectoryEntry::TAG_LENGTH];
    }

    return subfield_codes;
}

void Filter(File * const input, File * const output, const std::vector<std::string> &subfield_specs,
            const std::string &filter_chars)
{
    MarcXmlWriter xml_writer(output);

    unsigned total_count(0), modified_record_count(0), modified_field_count(0);
    while (MarcUtil::Record record = MarcUtil::Record::XmlFactory(input)) {
        ++total_count;
        record.setRecordWillBeWrittenAsXml(true);

        const std::vector<DirectoryEntry> &dir_entries(record.getDirEntries());
        const std::vector<std::string> &fields(record.getFields());

        for (std::vector<DirectoryEntry>::const_iterator dir_entry(dir_entries.cbegin());
             dir_entry != dir_entries.cend(); ++dir_entry)
        {
            const std::string subfield_codes(GetSubfieldCodes(dir_entry->getTag(), subfield_specs));
            if (subfield_codes.empty()) {
                record.write(&xml_writer);
                continue;
            }

            bool modified_at_least_one(false);
            const auto field_index(dir_entry - dir_entries.cbegin());
            Subfields subfields(fields[field_index]);
            for (const auto subfield_code : subfield_codes) {
                const auto begin_end(subfields.getIterators(subfield_code));
                for (auto subfield(begin_end.first); subfield != begin_end.second; ++subfield) {
                    const auto old_length(subfield->second.length());
                    StringUtil::RemoveChars(filter_chars, &(subfield->second));
                    if (subfield->second.length() != old_length) {
                        ++modified_field_count;
                        modified_at_least_one = true;
                    }
                }
            }

            if (modified_at_least_one) {
                record.replaceField(field_index, subfields.toString());
                ++modified_record_count;
            }

            record.write(&xml_writer);
        }
    }

    std::cerr << "Mofified " << modified_record_count << " (" << modified_field_count << " fields) of "
              << total_count << " record(s).\n";
}

// Sanity check.
bool ArePlausibleSubfieldSpecs(const std::vector<std::string> &subfield_specs) {
    if (subfield_specs.empty())
        return false;

    for (const auto &subfield_spec : subfield_specs) {
        if (subfield_spec.length() != (DirectoryEntry::TAG_LENGTH + 1))
            return false;
    }

    return true;
}

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

    if (argc != 5)
        Usage();

    std::unique_ptr<File> input(FileUtil::OpenInputFileOrDie(argv[1]));
    std::unique_ptr<File> output(FileUtil::OpenOutputFileOrDie(argv[2]));

    std::vector<std::string> subfield_specs;
    StringUtil::Split(argv[3], ':', &subfield_specs);
    if (not ArePlausibleSubfieldSpecs(subfield_specs))
        Error("bad subfield specifications!");

    const std::string filter_chars(argv[4]);
    if (filter_chars.empty())
        Error("");

    try {
        Filter(input.get(), output.get(), subfield_specs, filter_chars);
    } catch (const std::exception &x) {
        Error("caught exception: " + std::string(x.what()));
    }
}
<commit_msg>Added a missing error message.<commit_after>/** \brief A MARC-21 filter utility that can remove characters from a set of subfields.
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2016 Universitätsbiblothek 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 <iostream>
#include <memory>
#include <unordered_set>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "DirectoryEntry.h"
#include "FileUtil.h"
#include "Leader.h"
#include "MarcUtil.h"
#include "MarcXmlWriter.h"
#include "MediaTypeUtil.h"
#include "RegexMatcher.h"
#include "StringUtil.h"
#include "Subfields.h"
#include "util.h"

void Usage() {
    std::cerr << "usage: " << progname << " marc_input marc_output subfield_spec1:subfield_spec2:...:subfield_specN "
              << " characters_to_delete\n"
              << "       where \"subfieldspec\" must be a MARC tag followed by a single-character\n"
              << "       subfield code and \"characters_to_delete\" is list of characters that will be removed\n"
              << "       from the contents of the specified subfields.\n\n";

    std::exit(EXIT_FAILURE);
}

std::string GetSubfieldCodes(const std::string &tag, const std::vector<std::string> &subfield_specs) {
    std::string subfield_codes;

    for (const auto &subfield_spec : subfield_specs) {
        if (subfield_spec.substr(0, DirectoryEntry::TAG_LENGTH) == tag)
            subfield_codes += subfield_spec[DirectoryEntry::TAG_LENGTH];
    }

    return subfield_codes;
}

void Filter(File * const input, File * const output, const std::vector<std::string> &subfield_specs,
            const std::string &filter_chars)
{
    MarcXmlWriter xml_writer(output);

    unsigned total_count(0), modified_record_count(0), modified_field_count(0);
    while (MarcUtil::Record record = MarcUtil::Record::XmlFactory(input)) {
        ++total_count;
        record.setRecordWillBeWrittenAsXml(true);

        const std::vector<DirectoryEntry> &dir_entries(record.getDirEntries());
        const std::vector<std::string> &fields(record.getFields());

        for (std::vector<DirectoryEntry>::const_iterator dir_entry(dir_entries.cbegin());
             dir_entry != dir_entries.cend(); ++dir_entry)
        {
            const std::string subfield_codes(GetSubfieldCodes(dir_entry->getTag(), subfield_specs));
            if (subfield_codes.empty()) {
                record.write(&xml_writer);
                continue;
            }

            bool modified_at_least_one(false);
            const auto field_index(dir_entry - dir_entries.cbegin());
            Subfields subfields(fields[field_index]);
            for (const auto subfield_code : subfield_codes) {
                const auto begin_end(subfields.getIterators(subfield_code));
                for (auto subfield(begin_end.first); subfield != begin_end.second; ++subfield) {
                    const auto old_length(subfield->second.length());
                    StringUtil::RemoveChars(filter_chars, &(subfield->second));
                    if (subfield->second.length() != old_length) {
                        ++modified_field_count;
                        modified_at_least_one = true;
                    }
                }
            }

            if (modified_at_least_one) {
                record.replaceField(field_index, subfields.toString());
                ++modified_record_count;
            }

            record.write(&xml_writer);
        }
    }

    std::cerr << "Mofified " << modified_record_count << " (" << modified_field_count << " fields) of "
              << total_count << " record(s).\n";
}

// Sanity check.
bool ArePlausibleSubfieldSpecs(const std::vector<std::string> &subfield_specs) {
    if (subfield_specs.empty())
        return false;

    for (const auto &subfield_spec : subfield_specs) {
        if (subfield_spec.length() != (DirectoryEntry::TAG_LENGTH + 1))
            return false;
    }

    return true;
}

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

    if (argc != 5)
        Usage();

    std::unique_ptr<File> input(FileUtil::OpenInputFileOrDie(argv[1]));
    std::unique_ptr<File> output(FileUtil::OpenOutputFileOrDie(argv[2]));

    std::vector<std::string> subfield_specs;
    StringUtil::Split(argv[3], ':', &subfield_specs);
    if (not ArePlausibleSubfieldSpecs(subfield_specs))
        Error("bad subfield specifications!");

    const std::string filter_chars(argv[4]);
    if (filter_chars.empty())
        Error("missing characters to be filtered!");

    try {
        Filter(input.get(), output.get(), subfield_specs, filter_chars);
    } catch (const std::exception &x) {
        Error("caught exception: " + std::string(x.what()));
    }
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <ctime>
#include <cstdio>
#include <boost/filesystem.hpp>

#include "gflags/gflags.h"
#include "jsoncons/json.hpp"
#include "utils/protocol.h"
#include "utils/connection.h"
#include "bots/bot_interface.h"
#include "bots/raw_bot.h"
#include "bots/basic/bot.h"
#include "bots/tomek/bot.h"
#include "bots/piotr/bot.h"
#include "bots/greedy/bot.h"
#include "bots/stepping/bot.h"
#include "bots/constant/bot.h"
#include "bots/kamikaze/bot.h"
#include "bots/wojtek/bot.h"
#include "game/simulator.h"

DECLARE_string(race_id);

std::string random_race_id() {
  char buffer[80];
  sprintf (buffer, "%d", rand());
  return std::string(buffer);
}

int main(int argc, char** argv) {
  gflags::ParseCommandLineFlags(&argc, &argv, true);
  srand (time(NULL));

  if (FLAGS_race_id.empty()) {
    FLAGS_race_id = random_race_id();
  }
  boost::filesystem::create_directories("bin/" + FLAGS_race_id);

  std::unique_ptr<bots::RawBot> bot(new bots::RawBot(new bots::wojtek::Bot()));
  std::unique_ptr<game::Simulator> simulator(new game::Simulator());

  auto result = simulator->Run(bot.get());

  std::cout << "BEST LAP: " << result.best_lap_time_in_ticks << std::endl;
  if (result.crashed) {
    std::cout << "CRASHED !!!!!!!!!!!!!" << std::endl;
  }

  return 0;
}
<commit_msg>Print best lap as last line<commit_after>#include <iostream>
#include <string>
#include <ctime>
#include <cstdio>
#include <boost/filesystem.hpp>

#include "gflags/gflags.h"
#include "jsoncons/json.hpp"
#include "utils/protocol.h"
#include "utils/connection.h"
#include "bots/bot_interface.h"
#include "bots/raw_bot.h"
#include "bots/basic/bot.h"
#include "bots/tomek/bot.h"
#include "bots/piotr/bot.h"
#include "bots/greedy/bot.h"
#include "bots/stepping/bot.h"
#include "bots/constant/bot.h"
#include "bots/kamikaze/bot.h"
#include "bots/wojtek/bot.h"
#include "game/simulator.h"

DECLARE_string(race_id);

std::string random_race_id() {
  char buffer[80];
  sprintf (buffer, "%d", rand());
  return std::string(buffer);
}

int main(int argc, char** argv) {
  gflags::ParseCommandLineFlags(&argc, &argv, true);
  srand (time(NULL));

  if (FLAGS_race_id.empty()) {
    FLAGS_race_id = random_race_id();
  }
  boost::filesystem::create_directories("bin/" + FLAGS_race_id);

  game::Simulator::Result result;
  {
    std::unique_ptr<bots::RawBot> bot(new bots::RawBot(new bots::wojtek::Bot()));
    std::unique_ptr<game::Simulator> simulator(new game::Simulator());

    result = simulator->Run(bot.get());
  }

  std::cout << "BEST LAP: " << result.best_lap_time_in_ticks << std::endl;
  if (result.crashed) {
    std::cout << "CRASHED !!!!!!!!!!!!!" << std::endl;
  }

  return 0;
}
<|endoftext|>


<commit_before>#include <string>

#pragma GCC diagnostic push
#include "acmacs-base/boost-diagnostics.hh"
#include "boost/program_options.hpp"
#include <boost/filesystem.hpp>
#pragma GCC diagnostic pop

#include "acmacs-chart/ace.hh"

namespace fs = boost::filesystem;

// ----------------------------------------------------------------------

void scan(const fs::path& source_dir, std::vector<fs::path>& ace_files);

// ----------------------------------------------------------------------

class Options
{
 public:
    std::string source_dir;
};

static int get_args(int argc, const char *argv[], Options& aOptions);

int main(int argc, const char *argv[])
{
    Options options;
    int exit_code = get_args(argc, argv, options);
    if (exit_code == 0) {
        try {
            std::vector<fs::path> ace_files;
            scan(fs::path(options.source_dir), ace_files);
            std::cout << ace_files.size() << std::endl;
            for (const auto& p: ace_files)
                std::cout << p << std::endl;
        }
        catch (std::exception& err) {
            std::cerr << err.what() << std::endl;
            exit_code = 1;
        }
    }
    return exit_code;
}

static int get_args(int argc, const char *argv[], Options& aOptions)
{
    using namespace boost::program_options;
    options_description desc("Options");
    desc.add_options()
            ("help", "Print help messages")
            ("source,s", value<std::string>(&aOptions.source_dir)->required(), "directory to scan for ace files (recursively)")
            ;
    positional_options_description pos_opt;
    pos_opt.add("source", 1);

    variables_map vm;
    try {
        store(command_line_parser(argc, argv).options(desc).positional(pos_opt).run(), vm);
        if (vm.count("help")) {
            std::cerr << desc << std::endl;
            return 1;
        }
        notify(vm);
        return 0;
    }
    catch(required_option& e) {
        std::cerr << "ERROR: " << e.what() << std::endl;
        std::cerr << desc << std::endl;
          // std::cerr << "Usage: " << argv[0] << " <tree.json> <output.pdf>" << std::endl;
        return 2;
    }
    catch(error& e) {
        std::cerr << "ERROR: " << e.what() << std::endl;
        std::cerr << desc << std::endl;
        return 3;
    }

} // get_args

// ----------------------------------------------------------------------

void scan(const fs::path& source_dir, std::vector<fs::path>& ace_files)
{
    if (!fs::is_directory(source_dir))
        throw std::runtime_error(source_dir.string() + " is not a directory");
    for (fs::directory_entry& dirent: fs::directory_iterator(source_dir)) {
        if (fs::is_directory(dirent.status()))
            scan(dirent.path(), ace_files);
        else if (is_regular_file(dirent.status()) && dirent.path().extension().string() == ".ace")
            ace_files.push_back(dirent.path());
    }

} // scan

// ----------------------------------------------------------------------

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>whocc-scan-titers<commit_after>#include <string>

#pragma GCC diagnostic push
#include "acmacs-base/boost-diagnostics.hh"
#include "boost/program_options.hpp"
#include <boost/filesystem.hpp>
#pragma GCC diagnostic pop

#include "acmacs-chart/ace.hh"

namespace fs = boost::filesystem;

// ----------------------------------------------------------------------

void find_ace_files(const fs::path& source_dir, std::vector<fs::path>& ace_files);
void scan_titers(const fs::path& filename, std::set<Titer>& titers);

// ----------------------------------------------------------------------

class Options
{
 public:
    std::string source_dir;
};

static int get_args(int argc, const char *argv[], Options& aOptions);

int main(int argc, const char *argv[])
{
    Options options;
    int exit_code = get_args(argc, argv, options);
    if (exit_code == 0) {
        try {
            std::vector<fs::path> ace_files;
            find_ace_files(fs::path(options.source_dir), ace_files);
            std::cout << "Total .ace files found: " << ace_files.size() << std::endl;
            std::set<Titer> titers;
            for (const auto& filename: ace_files)
                scan_titers(filename, titers);
            std::cout << titers << std::endl;
        }
        catch (std::exception& err) {
            std::cerr << err.what() << std::endl;
            exit_code = 1;
        }
    }
    return exit_code;
}

static int get_args(int argc, const char *argv[], Options& aOptions)
{
    using namespace boost::program_options;
    options_description desc("Options");
    desc.add_options()
            ("help", "Print help messages")
            ("source,s", value<std::string>(&aOptions.source_dir)->required(), "directory to scan for ace files (recursively)")
            ;
    positional_options_description pos_opt;
    pos_opt.add("source", 1);

    variables_map vm;
    try {
        store(command_line_parser(argc, argv).options(desc).positional(pos_opt).run(), vm);
        if (vm.count("help")) {
            std::cerr << desc << std::endl;
            return 1;
        }
        notify(vm);
        return 0;
    }
    catch(required_option& e) {
        std::cerr << "ERROR: " << e.what() << std::endl;
        std::cerr << desc << std::endl;
          // std::cerr << "Usage: " << argv[0] << " <tree.json> <output.pdf>" << std::endl;
        return 2;
    }
    catch(error& e) {
        std::cerr << "ERROR: " << e.what() << std::endl;
        std::cerr << desc << std::endl;
        return 3;
    }

} // get_args

// ----------------------------------------------------------------------

void find_ace_files(const fs::path& source_dir, std::vector<fs::path>& ace_files)
{
    if (!fs::is_directory(source_dir))
        throw std::runtime_error(source_dir.string() + " is not a directory");
    for (fs::directory_entry& dirent: fs::directory_iterator(source_dir)) {
        if (fs::is_directory(dirent.status()))
            find_ace_files(dirent.path(), ace_files);
        else if (is_regular_file(dirent.status()) && dirent.path().extension().string() == ".ace")
            ace_files.push_back(dirent.path());
    }

} // find_ace_files

// ----------------------------------------------------------------------

void scan_titers(const fs::path& filename, std::set<Titer>& titers)
{
    std::unique_ptr<Chart> chart{import_chart(filename.string())};
    for (size_t antigen_no = 0; antigen_no < chart->antigens().size(); ++antigen_no) {
        for (size_t serum_no = 0; serum_no < chart->sera().size(); ++serum_no) {
            titers.insert(chart->titers().get(antigen_no, serum_no));
        }
    }

} // scan_titers

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before>#include "app.hpp"
#include "config.h"
#include <windows.h>
#include <iostream>
#include <stdexcept>
#include <memory>
#include <getopt.h>
#include "cmd/register.hpp"
#include "cmd/exec.hpp"
#include "cmd/list.hpp"
#include "util/winerror.hpp"
#include "util/elevated.hpp"
#include "util/strconv.hpp"
#include "util/message.hpp"

namespace cygregext {

/* type of native WinApi GetCommandLineW */
typedef LPWSTR (__stdcall* native_GetCommandLineW)(void);

App::App(const int argc, char* const argv[]) :
	_argc(argc),
	_argv(argv),
	_cmd(Command::NONE),
	_regType(RegisterType::USER),
	_extension(".sh"),
	_iconPath(std::string()),
	_force(false) {
	static const char *opts = "ruaflhV";
	static const struct option longopts[] = {
		{ "register", no_argument, NULL, 'r' },
		{ "unregister", no_argument, NULL, 'u' },
		{ "ext", required_argument, NULL, 'e' },
		{ "icon", required_argument, NULL, 'i' },
		{ "all", no_argument, NULL, 'a' },
		{ "force", no_argument, NULL, 'f' },
		{ "list", no_argument, NULL, 'l' },
		{ "exec", no_argument, NULL, 'E' },
		{ "version", no_argument, NULL, 'V' },
		{ "help", no_argument, NULL, 'h' },
		{ 0, 0, 0, 0 }
	};
	while (1) {
		int opt_index = 0;
		int c = 0;
		c = getopt_long(argc, argv, opts, longopts, &opt_index);
		if (-1 == c) {
			break;
		}
		switch (c) {
		/* --register */
		case 'r':
			_cmd = Command::REGISTER;
			break;
		/* --unregister */
		case 'u':
			_cmd = Command::UNREGISTER;
			break;
		/* --ext */
		case 'e':
			_extension = optarg;
			break;
		/* --icon */
		case 'i':
			_iconPath = optarg;
			break;
		/* --all */
		case 'a':
			_regType = RegisterType::EVERYONE;
			break;
		/* --force */
		case 'f':
			_force = true;
			break;
		/* --list */
		case 'l':
			_cmd = Command::LIST;
			break;
		/* --exec */
		case 'E':
			_cmd = Command::EXEC;
			break;
		/* --version */
		case 'V':
			_printVersion();
			exit(EXIT_SUCCESS);
		/* --help */
		case '?':
		case 'h':
		default:
			_printUsage(argv[0]);
			exit(EXIT_FAILURE);
		}
	}
	if (Command::NONE == _cmd) {
		_printUsage(argv[0]);
		exit(EXIT_FAILURE);
	}
	if ('.' != _extension[0]) {
		_extension.insert(0, ".");
	}
}

int App::run() {
	std::unique_ptr<ICommand> cmd;
	switch (_cmd) {
	/* execute command */
	case Command::EXEC:
		cmd = std::unique_ptr<ExecCommand>(new ExecCommand(_wideArgs()));
		break;
	/* register extension */
	case Command::REGISTER:
		if (_regType == RegisterType::EVERYONE) {
			_checkElevated();
		}
		cmd = std::unique_ptr<RegisterCommand>(
			new RegisterCommand(_extension, _iconPath,
			                    _regType == RegisterType::EVERYONE, _force));
		break;
	/* unregister extension */
	case Command::UNREGISTER:
		if (_regType == RegisterType::EVERYONE) {
			_checkElevated();
		}
		cmd = std::unique_ptr<UnregisterCommand>(
			new UnregisterCommand(_extension,
			                      _regType == RegisterType::EVERYONE));
		break;
	/* list registered extensions */
	case Command::LIST:
		cmd = std::unique_ptr<ListCommand>(new ListCommand());
		break;
	case Command::NONE:
		return 1;
	}
	return cmd->run();
}

WinPathW App::getPath() {
	wchar_t buf[MAX_PATH + 1];
	DWORD ret = GetModuleFileName(NULL, buf, sizeof(buf) / sizeof(buf[0]));
	if (0 == ret) {
		THROW_LAST_ERROR("Failed to get executable path.");
	}
	if (sizeof(buf) / sizeof(buf[0]) == ret &&
	    ERROR_INSUFFICIENT_BUFFER == GetLastError()) {
		throw std::runtime_error("Failed to get executable path.");
	}
	return WinPathW(std::wstring(buf, ret));
}

static char help[] =
	""
	"Options:\n"
	"  -r, --register     Add a file type to the Windows registry.\n"
	"  -u, --unregister   Remove a file type from the Windows registry.\n"
	"      --ext=EXT      Register or unregister files of the given extension.\n"
	"                       Default to .sh.\n"
	"      --icon=PATH,N  Path and index of the icon to register for an extension.\n"
	"                       Default to the icon of this application.\n"
	"  -a, --all          Register or unregister extension for all users.\n"
	"                       Default to current user only.\n"
	"  -f, --force        Overwrite if already registered for another application.\n"
	"  -l, --list         List registered extensions.\n"
	"  -h, --help         Display this help and exit.\n"
	"  -V, --version      Print version and exit.\n";

void App::_printUsage(char *progname) {
	std::stringstream ss;
	ss << "Usage: " << progname << " [OPTION]..." << std::endl;
	ss << "Register a script file type (.sh) to Windows File Explorer."
	   << std::endl << std::endl;
	ss << help;
	show_message(ss.str());
}

void App::_printVersion() {
	std::cout << "cygregext " << VERSION << std::endl;
	std::cout << "Copyright (C) 2017 Joni Eskelinen" << std::endl;
	std::cout << "License MIT: The MIT License" << std::endl;
	std::cout << "Icons: Tango Desktop Project" << std::endl;
}

std::vector<std::wstring> App::_wideArgs() {
	std::vector<std::wstring> args;
	LPWSTR* argv;
	int argc;
	/* use native WinApi GetCommandLineW since Cygwin hooks it */
	native_GetCommandLineW fn = (native_GetCommandLineW)GetProcAddress(
		GetModuleHandle(L"kernel32.dll"), "GetCommandLineW");
	if (NULL == fn) {
		THROW_LAST_ERROR("Failed to import GetCommandLineW");
	}
	argv = CommandLineToArgvW(fn(), &argc);
	/* if Windows command line has less arguments than what was
	   passed to the main(), then application was invoked from Cygwin shell. */
	if (argc < _argc) {
		for (int i = 0; i < _argc; ++i) {
			/* assume utf-8 */
			args.push_back(mb_to_wide(_argv[i], CP_UTF8));
		}
	} else {
		for (int i = 0; i < argc; ++i) {
			args.push_back(argv[i]);
		}
	}
	LocalFree(argv);
	return args;
}

void App::_checkElevated() {
	ElevatedProcess proc;
	if (proc.isAdmin()) {
		return;
	}
	proc.startElevated(_argc, _argv);
	exit(EXIT_SUCCESS);
}

}
<commit_msg>Clarify usage message<commit_after>#include "app.hpp"
#include "config.h"
#include <windows.h>
#include <iostream>
#include <stdexcept>
#include <memory>
#include <getopt.h>
#include "cmd/register.hpp"
#include "cmd/exec.hpp"
#include "cmd/list.hpp"
#include "util/winerror.hpp"
#include "util/elevated.hpp"
#include "util/strconv.hpp"
#include "util/message.hpp"

namespace cygregext {

/* type of native WinApi GetCommandLineW */
typedef LPWSTR (__stdcall* native_GetCommandLineW)(void);

App::App(const int argc, char* const argv[]) :
	_argc(argc),
	_argv(argv),
	_cmd(Command::NONE),
	_regType(RegisterType::USER),
	_extension(".sh"),
	_iconPath(std::string()),
	_force(false) {
	static const char *opts = "ruaflhV";
	static const struct option longopts[] = {
		{ "register", no_argument, NULL, 'r' },
		{ "unregister", no_argument, NULL, 'u' },
		{ "ext", required_argument, NULL, 'e' },
		{ "icon", required_argument, NULL, 'i' },
		{ "all", no_argument, NULL, 'a' },
		{ "force", no_argument, NULL, 'f' },
		{ "list", no_argument, NULL, 'l' },
		{ "exec", no_argument, NULL, 'E' },
		{ "version", no_argument, NULL, 'V' },
		{ "help", no_argument, NULL, 'h' },
		{ 0, 0, 0, 0 }
	};
	while (1) {
		int opt_index = 0;
		int c = 0;
		c = getopt_long(argc, argv, opts, longopts, &opt_index);
		if (-1 == c) {
			break;
		}
		switch (c) {
		/* --register */
		case 'r':
			_cmd = Command::REGISTER;
			break;
		/* --unregister */
		case 'u':
			_cmd = Command::UNREGISTER;
			break;
		/* --ext */
		case 'e':
			_extension = optarg;
			break;
		/* --icon */
		case 'i':
			_iconPath = optarg;
			break;
		/* --all */
		case 'a':
			_regType = RegisterType::EVERYONE;
			break;
		/* --force */
		case 'f':
			_force = true;
			break;
		/* --list */
		case 'l':
			_cmd = Command::LIST;
			break;
		/* --exec */
		case 'E':
			_cmd = Command::EXEC;
			break;
		/* --version */
		case 'V':
			_printVersion();
			exit(EXIT_SUCCESS);
		/* --help */
		case '?':
		case 'h':
		default:
			_printUsage(argv[0]);
			exit(EXIT_FAILURE);
		}
	}
	if (Command::NONE == _cmd) {
		_printUsage(argv[0]);
		exit(EXIT_FAILURE);
	}
	if ('.' != _extension[0]) {
		_extension.insert(0, ".");
	}
}

int App::run() {
	std::unique_ptr<ICommand> cmd;
	switch (_cmd) {
	/* execute command */
	case Command::EXEC:
		cmd = std::unique_ptr<ExecCommand>(new ExecCommand(_wideArgs()));
		break;
	/* register extension */
	case Command::REGISTER:
		if (_regType == RegisterType::EVERYONE) {
			_checkElevated();
		}
		cmd = std::unique_ptr<RegisterCommand>(
			new RegisterCommand(_extension, _iconPath,
			                    _regType == RegisterType::EVERYONE, _force));
		break;
	/* unregister extension */
	case Command::UNREGISTER:
		if (_regType == RegisterType::EVERYONE) {
			_checkElevated();
		}
		cmd = std::unique_ptr<UnregisterCommand>(
			new UnregisterCommand(_extension,
			                      _regType == RegisterType::EVERYONE));
		break;
	/* list registered extensions */
	case Command::LIST:
		cmd = std::unique_ptr<ListCommand>(new ListCommand());
		break;
	case Command::NONE:
		return 1;
	}
	return cmd->run();
}

WinPathW App::getPath() {
	wchar_t buf[MAX_PATH + 1];
	DWORD ret = GetModuleFileName(NULL, buf, sizeof(buf) / sizeof(buf[0]));
	if (0 == ret) {
		THROW_LAST_ERROR("Failed to get executable path.");
	}
	if (sizeof(buf) / sizeof(buf[0]) == ret &&
	    ERROR_INSUFFICIENT_BUFFER == GetLastError()) {
		throw std::runtime_error("Failed to get executable path.");
	}
	return WinPathW(std::wstring(buf, ret));
}

static char help[] =
	""
	"Options:\n"
	"  -r, --register     Add a file type to the Windows registry.\n"
	"  -u, --unregister   Remove a file type from the Windows registry.\n"
	"      --ext=EXT      Register or unregister files of the given extension.\n"
	"                       Default to .sh.\n"
	"      --icon=PATH,N  Path and index of the icon to register for an extension.\n"
	"                       Default to the icon of this application.\n"
	"  -a, --all          Register or unregister extension for all users.\n"
	"                       Default to current user only.\n"
	"  -f, --force        Overwrite if already registered for another application.\n"
	"  -l, --list         List registered extensions.\n"
	"  -h, --help         Display this help and exit.\n"
	"  -V, --version      Print version and exit.\n";

void App::_printUsage(char *progname) {
	std::stringstream ss;
	ss << "Usage: " << progname << " -r|-u|-l [OPTION]..." << std::endl;
	ss << "Register a script file type (.sh) to Windows File Explorer."
	   << std::endl << std::endl;
	ss << help;
	show_message(ss.str());
}

void App::_printVersion() {
	std::cout << "cygregext " << VERSION << std::endl;
	std::cout << "Copyright (C) 2017 Joni Eskelinen" << std::endl;
	std::cout << "License MIT: The MIT License" << std::endl;
	std::cout << "Icons: Tango Desktop Project" << std::endl;
}

std::vector<std::wstring> App::_wideArgs() {
	std::vector<std::wstring> args;
	LPWSTR* argv;
	int argc;
	/* use native WinApi GetCommandLineW since Cygwin hooks it */
	native_GetCommandLineW fn = (native_GetCommandLineW)GetProcAddress(
		GetModuleHandle(L"kernel32.dll"), "GetCommandLineW");
	if (NULL == fn) {
		THROW_LAST_ERROR("Failed to import GetCommandLineW");
	}
	argv = CommandLineToArgvW(fn(), &argc);
	/* if Windows command line has less arguments than what was
	   passed to the main(), then application was invoked from Cygwin shell. */
	if (argc < _argc) {
		for (int i = 0; i < _argc; ++i) {
			/* assume utf-8 */
			args.push_back(mb_to_wide(_argv[i], CP_UTF8));
		}
	} else {
		for (int i = 0; i < argc; ++i) {
			args.push_back(argv[i]);
		}
	}
	LocalFree(argv);
	return args;
}

void App::_checkElevated() {
	ElevatedProcess proc;
	if (proc.isAdmin()) {
		return;
	}
	proc.startElevated(_argc, _argv);
	exit(EXIT_SUCCESS);
}

}
<|endoftext|>


<commit_before>// This file is distributed under the MIT license.
// See the LICENSE file for details.

#include <algorithm>
#include <cctype>
#include <cstddef>
#include <sstream>
#include <vector>

#include "inifile.h"

namespace visionaray
{

//-------------------------------------------------------------------------------------------------
// Helpers
//

std::string trim(std::string str, std::string ws = " \t")
{
    // Remove leading whitespace
    auto first = str.find_first_not_of(ws);

    // No whitespace found
    if (first == std::string::npos)
    {
        first = 0;
    }

    // Remove trailing whitespace
    auto last = str.find_last_not_of(ws);

    // No whitespace found
    if (last == std::string::npos)
    {
        last = str.size() - 1;
    }

    // Skip if empty
    if (first > last)
    {
        return "";
    }

    // Trim
    return str.substr(first, last - first + 1);
}

std::vector<std::string> string_split(std::string s, char delim)
{
    std::vector<std::string> result;

    std::istringstream stream(s);

    for (std::string token; std::getline(stream, token, delim); )
    {
        result.push_back(token);
    }

    return result;
}

size_t count_whitespaces(std::string str)
{
    return std::count_if(
            str.begin(),
            str.end(),
            [](unsigned char c) { return std::isspace(c); }
            );
}

std::string tolower(std::string str)
{
    std::transform(
            str.begin(),
            str.end(),
            str.begin(),
            [](unsigned char c) { return std::tolower(c); }
            );

    return str;
}

template <typename T>
inline bool as_T(std::string in, T& out)
{
    std::istringstream stream(in);
    return static_cast<bool>(stream >> out);
}

template <typename Map>
inline inifile::error_code get_string(Map const& map, std::string key, std::string& value)
{
    if (map.count(key) > 1)
    {
        return inifile::MultipleEntries;
    }

    auto it = map.find(key);

    if (it == map.end())
    {
        return inifile::NonExistent;
    }

    value = trim(it->second.value);

    return inifile::Ok;
}

template <typename Map, typename T>
inline inifile::error_code get_T(Map const& map, std::string key, T& value)
{
    std::string str = "";
    inifile::error_code err = get_string(map, key, str);
    if (err != inifile::Ok)
    {
        return err;
    }

    if (!as_T(str, value))
    {
        return inifile::ParseError;
    }

    return inifile::Ok;
}

template <typename Map, typename T>
inline inifile::error_code get_T3(Map const& map, std::string key, T& x, T& y, T& z)
{
    std::string str = "";
    inifile::error_code err = get_string(map, key, str);
    if (err != inifile::Ok)
    {
        return err;
    }

    // Also remove enclosing parentheses
    str = trim(str, "()");
    str = trim(str, "[]");
    str = trim(str, "{}");

    std::string delims = " ,;|";

    for (auto c : delims)
    {
        auto tokens = string_split(str, c);

        if (tokens.size() >= 3)
        {
            std::string xyz[3];
            int c = 0;
            for (auto t : tokens)
            {
                if (count_whitespaces(t) < t.size())
                {
                    xyz[c++] = t;
                }
            }

            if (c == 3 && as_T(xyz[0], x) && as_T(xyz[1], y) && as_T(xyz[2], z))
            {
                return inifile::Ok;
            }
        }
    }

    return inifile::ParseError;
}

//-------------------------------------------------------------------------------------------------
// Interface
//

inifile::inifile(std::string filename)
    : file_(filename)
{
    if (!file_.good())
    {
        return;
    }

    std::string section = "";

    for (std::string line; std::getline(file_, line); )
    {
        line = trim(line);
        if (line.empty())
        {
            continue;
        }

        // Skip comments
        if (line[0] == ';' || line[0] == '#')
        {
            continue;
        }

        // Section
        if (line[0] == '[' && line[line.size() - 1] == ']')
        {
            section = trim(line.substr(1, line.size() - 2));
            continue;
        }

        // Parse key/value pairs
        auto p = string_split(line, '=');

        if (p.size() != 2)
        {
            // TODO: error handling
            continue;
        }

        std::string key = tolower(trim(p[0]));
        std::string value = tolower(trim(p[1]));

        entries_.emplace(std::make_pair(key, value_type{ section, value }));
    }

    good_ = true;
}

bool inifile::good() const
{
    return good_;
}

inifile::error_code inifile::get_bool(std::string key, bool& value)
{
    std::string str = "";
    inifile::error_code err = visionaray::get_string(entries_, key, str);
    if (err != inifile::Ok)
    {
        return err;
    }

    str = tolower(str);

    if (str == "1" || str == "true" || str == "on")
    {
        value = true;
        return Ok;
    }
    else if (str == "0" || str == "false" || str == "off")
    {
        value = false;
        return Ok;
    }
    else
    {
        return ParseError;
    }
}

inifile::error_code inifile::get_int8(std::string key, int8_t& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_int16(std::string key, int16_t& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_int32(std::string key, int32_t& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_int64(std::string key, int64_t& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_uint8(std::string key, uint8_t& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_uint16(std::string key, uint16_t& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_uint32(std::string key, uint32_t& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_uint64(std::string key, uint64_t& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_float(std::string key, float& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_double(std::string key, double& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_long_double(std::string key, long double& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_string(std::string key, std::string& value, bool remove_quotes)
{
    error_code err = visionaray::get_string(entries_, key, value);

    if (err == Ok && remove_quotes)
    {
        // TODO: check that we removed *2* (and both the same) quotation marks
        value = trim(value, "'");
        value = trim(value, "\"");
    }

    return err;
}

inifile::error_code inifile::get_vec3i(std::string key, int32_t& x, int32_t& y, int32_t& z)
{
    return get_T3(entries_, key, x, y, z);
}

inifile::error_code inifile::get_vec3ui(std::string key, uint32_t& x, uint32_t& y, uint32_t& z)
{
    return get_T3(entries_, key, x, y, z);
}

inifile::error_code inifile::get_vec3f(std::string key, float& x, float& y, float& z)
{
    return get_T3(entries_, key, x, y, z);
}

inifile::error_code inifile::get_vec3d(std::string key, double& x, double& y, double& z)
{
    return get_T3(entries_, key, x, y, z);
}

} // visionaray
<commit_msg>Fix trim()<commit_after>// This file is distributed under the MIT license.
// See the LICENSE file for details.

#include <algorithm>
#include <cctype>
#include <cstddef>
#include <sstream>
#include <vector>

#include "inifile.h"

namespace visionaray
{

//-------------------------------------------------------------------------------------------------
// Helpers
//

std::string trim(std::string str, std::string ws = " \t")
{
    // Remove leading whitespace
    auto first = str.find_first_not_of(ws);

    // Only whitespace found
    if (first == std::string::npos)
    {
        return "";
    }

    // Remove trailing whitespace
    auto last = str.find_last_not_of(ws);

    // No whitespace found
    if (last == std::string::npos)
    {
        last = str.size() - 1;
    }

    // Skip if empty
    if (first > last)
    {
        return "";
    }

    // Trim
    return str.substr(first, last - first + 1);
}

std::vector<std::string> string_split(std::string s, char delim)
{
    std::vector<std::string> result;

    std::istringstream stream(s);

    for (std::string token; std::getline(stream, token, delim); )
    {
        result.push_back(token);
    }

    return result;
}

size_t count_whitespaces(std::string str)
{
    return std::count_if(
            str.begin(),
            str.end(),
            [](unsigned char c) { return std::isspace(c); }
            );
}

std::string tolower(std::string str)
{
    std::transform(
            str.begin(),
            str.end(),
            str.begin(),
            [](unsigned char c) { return std::tolower(c); }
            );

    return str;
}

template <typename T>
inline bool as_T(std::string in, T& out)
{
    std::istringstream stream(in);
    return static_cast<bool>(stream >> out);
}

template <typename Map>
inline inifile::error_code get_string(Map const& map, std::string key, std::string& value)
{
    if (map.count(key) > 1)
    {
        return inifile::MultipleEntries;
    }

    auto it = map.find(key);

    if (it == map.end())
    {
        return inifile::NonExistent;
    }

    value = trim(it->second.value);

    return inifile::Ok;
}

template <typename Map, typename T>
inline inifile::error_code get_T(Map const& map, std::string key, T& value)
{
    std::string str = "";
    inifile::error_code err = get_string(map, key, str);
    if (err != inifile::Ok)
    {
        return err;
    }

    if (!as_T(str, value))
    {
        return inifile::ParseError;
    }

    return inifile::Ok;
}

template <typename Map, typename T>
inline inifile::error_code get_T3(Map const& map, std::string key, T& x, T& y, T& z)
{
    std::string str = "";
    inifile::error_code err = get_string(map, key, str);
    if (err != inifile::Ok)
    {
        return err;
    }

    // Also remove enclosing parentheses
    str = trim(str, "()");
    str = trim(str, "[]");
    str = trim(str, "{}");

    std::string delims = " ,;|";

    for (auto c : delims)
    {
        auto tokens = string_split(str, c);

        if (tokens.size() >= 3)
        {
            std::string xyz[3];
            int c = 0;
            for (auto t : tokens)
            {
                if (count_whitespaces(t) < t.size())
                {
                    xyz[c++] = t;
                }
            }

            if (c == 3 && as_T(xyz[0], x) && as_T(xyz[1], y) && as_T(xyz[2], z))
            {
                return inifile::Ok;
            }
        }
    }

    return inifile::ParseError;
}

//-------------------------------------------------------------------------------------------------
// Interface
//

inifile::inifile(std::string filename)
    : file_(filename)
{
    if (!file_.good())
    {
        return;
    }

    std::string section = "";

    for (std::string line; std::getline(file_, line); )
    {
        line = trim(line);
        if (line.empty())
        {
            continue;
        }

        // Skip comments
        if (line[0] == ';' || line[0] == '#')
        {
            continue;
        }

        // Section
        if (line[0] == '[' && line[line.size() - 1] == ']')
        {
            section = trim(line.substr(1, line.size() - 2));
            continue;
        }

        // Parse key/value pairs
        auto p = string_split(line, '=');

        if (p.size() != 2)
        {
            // TODO: error handling
            continue;
        }

        std::string key = tolower(trim(p[0]));
        std::string value = tolower(trim(p[1]));

        entries_.emplace(std::make_pair(key, value_type{ section, value }));
    }

    good_ = true;
}

bool inifile::good() const
{
    return good_;
}

inifile::error_code inifile::get_bool(std::string key, bool& value)
{
    std::string str = "";
    inifile::error_code err = visionaray::get_string(entries_, key, str);
    if (err != inifile::Ok)
    {
        return err;
    }

    str = tolower(str);

    if (str == "1" || str == "true" || str == "on")
    {
        value = true;
        return Ok;
    }
    else if (str == "0" || str == "false" || str == "off")
    {
        value = false;
        return Ok;
    }
    else
    {
        return ParseError;
    }
}

inifile::error_code inifile::get_int8(std::string key, int8_t& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_int16(std::string key, int16_t& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_int32(std::string key, int32_t& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_int64(std::string key, int64_t& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_uint8(std::string key, uint8_t& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_uint16(std::string key, uint16_t& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_uint32(std::string key, uint32_t& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_uint64(std::string key, uint64_t& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_float(std::string key, float& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_double(std::string key, double& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_long_double(std::string key, long double& value)
{
    return get_T(entries_, key, value);
}

inifile::error_code inifile::get_string(std::string key, std::string& value, bool remove_quotes)
{
    error_code err = visionaray::get_string(entries_, key, value);

    if (err == Ok && remove_quotes)
    {
        // TODO: check that we removed *2* (and both the same) quotation marks
        value = trim(value, "'");
        value = trim(value, "\"");
    }

    return err;
}

inifile::error_code inifile::get_vec3i(std::string key, int32_t& x, int32_t& y, int32_t& z)
{
    return get_T3(entries_, key, x, y, z);
}

inifile::error_code inifile::get_vec3ui(std::string key, uint32_t& x, uint32_t& y, uint32_t& z)
{
    return get_T3(entries_, key, x, y, z);
}

inifile::error_code inifile::get_vec3f(std::string key, float& x, float& y, float& z)
{
    return get_T3(entries_, key, x, y, z);
}

inifile::error_code inifile::get_vec3d(std::string key, double& x, double& y, double& z)
{
    return get_T3(entries_, key, x, y, z);
}

} // visionaray
<|endoftext|>


<commit_before>#ifndef VIENNAGRID_MESH_OPERATIONS_HPP
#define VIENNAGRID_MESH_OPERATIONS_HPP

/* =======================================================================
   Copyright (c) 2011-2013, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.

                            -----------------
                     ViennaGrid - The Vienna Grid Library
                            -----------------

   License:      MIT (X11), see file LICENSE in the base directory
======================================================================= */

#include "viennagrid/forwards.hpp"
#include "viennagrid/mesh/mesh.hpp"
#include "viennagrid/mesh/segmentation.hpp"
//#include "viennagrid/mesh/element_creation.hpp"
#include "viennagrid/mesh/coboundary_iteration.hpp"

/** @file viennagrid/mesh/mesh_operations.hpp
    @brief Helper routines on a mesh
*/

namespace viennagrid
{

  /** @brief Copies a mesh and an associated segmentation over to another mesh and an associated segmentation */
  template<typename SrcMeshT, typename SrcSegmentationT, typename DstMeshT, typename DstSegmentationT>
  void copy_cells(SrcMeshT const & src_mesh_obj,  SrcSegmentationT const & src_segmentation,
                  DstMeshT & dst_mesh_obj,        DstSegmentationT & dst_segmentation )
  {
//     typedef typename src_segment_container_type::value_type src_segment_handle_type;
//     typedef typename dst_segment_container_type::value_type dst_segment_handle_type;
    typedef typename viennagrid::result_of::segment_handle<SrcSegmentationT>::type SrcSegmentHandleType;
    typedef typename viennagrid::result_of::segment_handle<DstSegmentationT>::type DstSegmentHandleType;

    //typedef typename viennagrid::result_of::cell_tag<SrcMeshT>::type  SrcCellTag;
    typedef typename viennagrid::result_of::cell<SrcMeshT>::type      SrcCellType;

    typedef typename viennagrid::result_of::const_vertex_range<SrcMeshT>::type    SrcVertexRangeType;
    typedef typename viennagrid::result_of::iterator<SrcVertexRangeType>::type    SrcVertexRangeIterator;

    typedef typename viennagrid::result_of::const_cell_range<SrcSegmentHandleType>::type  SrcCellRangeType;
    typedef typename viennagrid::result_of::iterator<SrcCellRangeType>::type              SrcCellRangeIterator;

    typedef typename viennagrid::result_of::const_vertex_handle<SrcMeshT>::type   SrcConstVertexHandle;
    typedef typename viennagrid::result_of::vertex_handle<DstMeshT>::type         DstVertexHandleType;

    if (&src_mesh_obj == &dst_mesh_obj)
        return;

    dst_mesh_obj.clear();
    dst_segmentation.clear();

    std::map<SrcConstVertexHandle, DstVertexHandleType> vertex_handle_map;

    SrcVertexRangeType vertices( src_mesh_obj );
    for (SrcVertexRangeIterator it = vertices.begin(); it != vertices.end(); ++it)
      vertex_handle_map[it.handle()] = viennagrid::make_vertex( dst_mesh_obj, viennagrid::point(src_mesh_obj, *it) );

    for (typename SrcSegmentationT::const_iterator seg_it = src_segmentation.begin(); seg_it != src_segmentation.end(); ++seg_it)
    {
//         dst_segments.push_back( viennagrid::make_view<dst_segment_handle_type>(dst_mesh) );
      DstSegmentHandleType & dst_segment = dst_segmentation.get_make_segment( seg_it->id() );

      SrcCellRangeType cells( *seg_it );
      for (SrcCellRangeIterator it = cells.begin(); it != cells.end(); ++it)
      {
        SrcCellType const & cell = *it;

        std::deque<DstVertexHandleType> vertex_handles;

        typedef typename viennagrid::result_of::const_vertex_range<SrcCellType>::type SrcVertexOnSrcCellRangeType;
        typedef typename viennagrid::result_of::iterator<SrcVertexOnSrcCellRangeType>::type SrcVertexOnSrcCellRangeIterator;

        SrcVertexOnSrcCellRangeType cell_vertices(cell);
        for (SrcVertexOnSrcCellRangeIterator jt = cell_vertices.begin(); jt != cell_vertices.end(); ++jt)
          vertex_handles.push_back( vertex_handle_map[jt.handle()] );

        typedef typename viennagrid::result_of::cell<DstMeshT>::type DstCellType;
        viennagrid::make_element<DstCellType>( dst_segment, vertex_handles.begin(), vertex_handles.end() );
      }
    }
  }

  namespace detail
  {
    /** @brief For internal use only */
    template<typename MeshT, typename ToEraseViewT, typename HandleT, typename ReferencingElementTypelist =
        typename viennagrid::result_of::referencing_element_typelist<MeshT, typename viennagrid::detail::result_of::value_type<HandleT>::type >::type >
    struct mark_referencing_elements_impl;

    template<typename MeshT, typename ToEraseViewT, typename HandleT, typename CoboundaryElementT, typename TailT>
    struct mark_referencing_elements_impl<MeshT, ToEraseViewT, HandleT, viennagrid::typelist<CoboundaryElementT, TailT> >
    {
      static void mark(MeshT & mesh_obj, ToEraseViewT & mesh_view, HandleT host_element)
      {
        //typedef viennagrid::typelist<CoboundaryElementT, TailT> ReferencingElementTypelist;
        typedef typename viennagrid::detail::result_of::value_type<HandleT>::type HostElementType;

        //typedef typename viennagrid::result_of::handle<MeshT, CoboundaryElementT>::type CoboundaryElementHandle;
        typedef typename viennagrid::result_of::coboundary_range<MeshT, HostElementType, CoboundaryElementT>::type CoboundaryElementRangeType;
        typedef typename viennagrid::result_of::iterator<CoboundaryElementRangeType>::type CoboundaryElementRangeIterator;

        typedef typename viennagrid::result_of::element_range<ToEraseViewT, CoboundaryElementT>::type CoboundaryElementViewRangeType;

        CoboundaryElementRangeType coboundary_elements = viennagrid::coboundary_elements<HostElementType, CoboundaryElementT>(mesh_obj, host_element);
        for (CoboundaryElementRangeIterator it = coboundary_elements.begin(); it != coboundary_elements.end(); ++it)
        {
          CoboundaryElementViewRangeType view_elements( mesh_view );
          if ( viennagrid::find_by_handle(mesh_view, it.handle()) == view_elements.end() )
          {
            view_elements.insert_unique_handle( it.handle() );
          }
        }

        mark_referencing_elements_impl<MeshT, ToEraseViewT, HandleT, TailT>::mark(mesh_obj, mesh_view, host_element);
      }
    };

    /** @brief For internal use only */
    template<typename MeshT, typename ToEraseViewT, typename HandleT>
    struct mark_referencing_elements_impl<MeshT, ToEraseViewT, HandleT, viennagrid::null_type >
    {
      static void mark(MeshT &, ToEraseViewT &, HandleT) {}
    };

  } //namespace detail

  /** @brief Marks elements which reference a given host element
    *
    * @tparam MeshT                   The mesh type in which the element to erase lives
    * @tparam MeshViewT               The mesh view type for all elements to erase
    * @tparam HandleT                 The handle type of the element to delete
    * @param  mesh_obj                The host mesh object
    * @param  element_view            A mesh view which stores all elements to be marked
    * @param  host_element            A handle object of the host element
    */
  template<typename MeshT, typename MeshViewT, typename HandleT>
  void mark_referencing_elements( MeshT & mesh_obj, MeshViewT & element_view, HandleT host_element )
  {
    detail::mark_referencing_elements_impl<MeshT, MeshViewT, HandleT>::mark(mesh_obj, element_view, host_element);
  }

}

#endif
<commit_msg>added copy_vertex_map<commit_after>#ifndef VIENNAGRID_MESH_OPERATIONS_HPP
#define VIENNAGRID_MESH_OPERATIONS_HPP

/* =======================================================================
   Copyright (c) 2011-2013, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.

                            -----------------
                     ViennaGrid - The Vienna Grid Library
                            -----------------

   License:      MIT (X11), see file LICENSE in the base directory
======================================================================= */

#include "viennagrid/forwards.hpp"
#include "viennagrid/mesh/mesh.hpp"
#include "viennagrid/mesh/segmentation.hpp"
#include "viennagrid/mesh/element_creation.hpp"
#include "viennagrid/mesh/coboundary_iteration.hpp"

/** @file viennagrid/mesh/mesh_operations.hpp
    @brief Helper routines on a mesh
*/

namespace viennagrid
{

  template<typename SrcMeshT, typename DstMeshT>
  class vertex_copy_map
  {
  public:
    vertex_copy_map( DstMeshT & dst_mesh_ ) : dst_mesh(dst_mesh_) {}

    typedef typename viennagrid::result_of::vertex<SrcMeshT>::type SrcVertexType;
    typedef typename viennagrid::result_of::vertex_id<SrcMeshT>::type SrcVertexIDType;

    typedef typename viennagrid::result_of::vertex<DstMeshT>::type DstVertexType;
    typedef typename viennagrid::result_of::vertex_handle<DstMeshT>::type DstVertexHandleType;

    DstVertexHandleType operator()( SrcVertexType const & src_vertex )
    {
      typename std::map<SrcVertexIDType, DstVertexHandleType>::iterator vit = vertex_map.find( src_vertex.id() );
      if (vit != vertex_map.end())
        return vit->second;
      else
      {
        DstVertexHandleType vh = viennagrid::make_vertex( dst_mesh, viennagrid::point(src_vertex) );
        vertex_map[src_vertex.id()] = vh;
        return vh;
      }
    }

  private:

    DstMeshT & dst_mesh;
    std::map<SrcVertexIDType, DstVertexHandleType> vertex_map;
  };

  /** @brief Copies a mesh and an associated segmentation over to another mesh and an associated segmentation */
  template<typename SrcMeshT, typename SrcSegmentationT, typename DstMeshT, typename DstSegmentationT>
  void copy_cells(SrcMeshT const & src_mesh_obj,  SrcSegmentationT const & src_segmentation,
                  DstMeshT & dst_mesh_obj,        DstSegmentationT & dst_segmentation )
  {
//     typedef typename src_segment_container_type::value_type src_segment_handle_type;
//     typedef typename dst_segment_container_type::value_type dst_segment_handle_type;
    typedef typename viennagrid::result_of::segment_handle<SrcSegmentationT>::type SrcSegmentHandleType;
    typedef typename viennagrid::result_of::segment_handle<DstSegmentationT>::type DstSegmentHandleType;

    //typedef typename viennagrid::result_of::cell_tag<SrcMeshT>::type  SrcCellTag;
    typedef typename viennagrid::result_of::cell<SrcMeshT>::type      SrcCellType;

    typedef typename viennagrid::result_of::const_vertex_range<SrcMeshT>::type    SrcVertexRangeType;
    typedef typename viennagrid::result_of::iterator<SrcVertexRangeType>::type    SrcVertexRangeIterator;

    typedef typename viennagrid::result_of::const_cell_range<SrcSegmentHandleType>::type  SrcCellRangeType;
    typedef typename viennagrid::result_of::iterator<SrcCellRangeType>::type              SrcCellRangeIterator;

    typedef typename viennagrid::result_of::const_vertex_handle<SrcMeshT>::type   SrcConstVertexHandle;
    typedef typename viennagrid::result_of::vertex_handle<DstMeshT>::type         DstVertexHandleType;

    if (&src_mesh_obj == &dst_mesh_obj)
        return;

    dst_mesh_obj.clear();
    dst_segmentation.clear();

    std::map<SrcConstVertexHandle, DstVertexHandleType> vertex_handle_map;

    SrcVertexRangeType vertices( src_mesh_obj );
    for (SrcVertexRangeIterator it = vertices.begin(); it != vertices.end(); ++it)
      vertex_handle_map[it.handle()] = viennagrid::make_vertex( dst_mesh_obj, viennagrid::point(src_mesh_obj, *it) );

    for (typename SrcSegmentationT::const_iterator seg_it = src_segmentation.begin(); seg_it != src_segmentation.end(); ++seg_it)
    {
//         dst_segments.push_back( viennagrid::make_view<dst_segment_handle_type>(dst_mesh) );
      DstSegmentHandleType & dst_segment = dst_segmentation.get_make_segment( seg_it->id() );

      SrcCellRangeType cells( *seg_it );
      for (SrcCellRangeIterator it = cells.begin(); it != cells.end(); ++it)
      {
        SrcCellType const & cell = *it;

        std::deque<DstVertexHandleType> vertex_handles;

        typedef typename viennagrid::result_of::const_vertex_range<SrcCellType>::type SrcVertexOnSrcCellRangeType;
        typedef typename viennagrid::result_of::iterator<SrcVertexOnSrcCellRangeType>::type SrcVertexOnSrcCellRangeIterator;

        SrcVertexOnSrcCellRangeType cell_vertices(cell);
        for (SrcVertexOnSrcCellRangeIterator jt = cell_vertices.begin(); jt != cell_vertices.end(); ++jt)
          vertex_handles.push_back( vertex_handle_map[jt.handle()] );

        typedef typename viennagrid::result_of::cell<DstMeshT>::type DstCellType;
        viennagrid::make_element<DstCellType>( dst_segment, vertex_handles.begin(), vertex_handles.end() );
      }
    }
  }

  namespace detail
  {
    /** @brief For internal use only */
    template<typename MeshT, typename ToEraseViewT, typename HandleT, typename ReferencingElementTypelist =
        typename viennagrid::result_of::referencing_element_typelist<MeshT, typename viennagrid::detail::result_of::value_type<HandleT>::type >::type >
    struct mark_referencing_elements_impl;

    template<typename MeshT, typename ToEraseViewT, typename HandleT, typename CoboundaryElementT, typename TailT>
    struct mark_referencing_elements_impl<MeshT, ToEraseViewT, HandleT, viennagrid::typelist<CoboundaryElementT, TailT> >
    {
      static void mark(MeshT & mesh_obj, ToEraseViewT & mesh_view, HandleT host_element)
      {
        //typedef viennagrid::typelist<CoboundaryElementT, TailT> ReferencingElementTypelist;
        typedef typename viennagrid::detail::result_of::value_type<HandleT>::type HostElementType;

        //typedef typename viennagrid::result_of::handle<MeshT, CoboundaryElementT>::type CoboundaryElementHandle;
        typedef typename viennagrid::result_of::coboundary_range<MeshT, HostElementType, CoboundaryElementT>::type CoboundaryElementRangeType;
        typedef typename viennagrid::result_of::iterator<CoboundaryElementRangeType>::type CoboundaryElementRangeIterator;

        typedef typename viennagrid::result_of::element_range<ToEraseViewT, CoboundaryElementT>::type CoboundaryElementViewRangeType;

        CoboundaryElementRangeType coboundary_elements = viennagrid::coboundary_elements<HostElementType, CoboundaryElementT>(mesh_obj, host_element);
        for (CoboundaryElementRangeIterator it = coboundary_elements.begin(); it != coboundary_elements.end(); ++it)
        {
          CoboundaryElementViewRangeType view_elements( mesh_view );
          if ( viennagrid::find_by_handle(mesh_view, it.handle()) == view_elements.end() )
          {
            view_elements.insert_unique_handle( it.handle() );
          }
        }

        mark_referencing_elements_impl<MeshT, ToEraseViewT, HandleT, TailT>::mark(mesh_obj, mesh_view, host_element);
      }
    };

    /** @brief For internal use only */
    template<typename MeshT, typename ToEraseViewT, typename HandleT>
    struct mark_referencing_elements_impl<MeshT, ToEraseViewT, HandleT, viennagrid::null_type >
    {
      static void mark(MeshT &, ToEraseViewT &, HandleT) {}
    };

  } //namespace detail

  /** @brief Marks elements which reference a given host element
    *
    * @tparam MeshT                   The mesh type in which the element to erase lives
    * @tparam MeshViewT               The mesh view type for all elements to erase
    * @tparam HandleT                 The handle type of the element to delete
    * @param  mesh_obj                The host mesh object
    * @param  element_view            A mesh view which stores all elements to be marked
    * @param  host_element            A handle object of the host element
    */
  template<typename MeshT, typename MeshViewT, typename HandleT>
  void mark_referencing_elements( MeshT & mesh_obj, MeshViewT & element_view, HandleT host_element )
  {
    detail::mark_referencing_elements_impl<MeshT, MeshViewT, HandleT>::mark(mesh_obj, element_view, host_element);
  }

}

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2010 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>

// language.cc: Subclasses and singletons for google_breakpad::Language.
// See language.h for details.

#include "common/language.h"

namespace google_breakpad {

// C++ language-specific operations.
class CPPLanguage: public Language {
 public:
  string MakeQualifiedName(const string &parent_name,
                           const string &name) const {
    if (parent_name.empty())
      return name;
    else
      return parent_name + "::" + name;
  }
};

const CPPLanguage CPPLanguageSingleton;

// Java language-specific operations.
class JavaLanguage: public Language {
 public:
  string MakeQualifiedName(const string &parent_name,
                           const string &name) const {
    if (parent_name.empty())
      return name;
    else
      return parent_name + "." + name;
  }
};

JavaLanguage JavaLanguageSingleton;

// Assembler language-specific operations.
class AssemblerLanguage: public Language {
  bool HasFunctions() const { return false; }
  string MakeQualifiedName(const string &parent_name,
                           const string &name) const {
    return name;
  }
};

AssemblerLanguage AssemblerLanguageSingleton;

const Language * const Language::CPlusPlus = &CPPLanguageSingleton;
const Language * const Language::Java = &JavaLanguageSingleton;
const Language * const Language::Assembler = &AssemblerLanguageSingleton;

} // namespace google_breakpad
<commit_msg>Add missing constructor to CPPLanguage class to make it compile with CLang. P=rafael.espindola R=jimb at https://bugzilla.mozilla.org/show_bug.cgi?id=623121<commit_after>// Copyright (c) 2010 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>

// language.cc: Subclasses and singletons for google_breakpad::Language.
// See language.h for details.

#include "common/language.h"

namespace google_breakpad {

// C++ language-specific operations.
class CPPLanguage: public Language {
 public:
  CPPLanguage() {}
  string MakeQualifiedName(const string &parent_name,
                           const string &name) const {
    if (parent_name.empty())
      return name;
    else
      return parent_name + "::" + name;
  }
};

const CPPLanguage CPPLanguageSingleton;

// Java language-specific operations.
class JavaLanguage: public Language {
 public:
  string MakeQualifiedName(const string &parent_name,
                           const string &name) const {
    if (parent_name.empty())
      return name;
    else
      return parent_name + "." + name;
  }
};

JavaLanguage JavaLanguageSingleton;

// Assembler language-specific operations.
class AssemblerLanguage: public Language {
  bool HasFunctions() const { return false; }
  string MakeQualifiedName(const string &parent_name,
                           const string &name) const {
    return name;
  }
};

AssemblerLanguage AssemblerLanguageSingleton;

const Language * const Language::CPlusPlus = &CPPLanguageSingleton;
const Language * const Language::Java = &JavaLanguageSingleton;
const Language * const Language::Assembler = &AssemblerLanguageSingleton;

} // namespace google_breakpad
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "views/widget/tooltip_manager_gtk.h"

#include "app/gfx/font.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "views/focus/focus_manager.h"
#include "views/widget/root_view.h"
#include "views/widget/widget_gtk.h"

// WARNING: this implementation is good for a start, but it doesn't give us
// control of tooltip positioning both on mouse events and when showing from
// keyboard. We may need to write our own to give us the control we need.

namespace views {

static gfx::Font* LoadDefaultFont() {
  // Create a tooltip widget and extract the font from it (we have to realize
  // it to make sure the correct font gets set).
  GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP);
  gtk_widget_set_name(window, "gtk-tooltip");
  GtkWidget* label = gtk_label_new("");
  gtk_widget_show(label);

  gtk_container_add(GTK_CONTAINER(window), label);
  gtk_widget_realize(window);

  GtkStyle* style = gtk_widget_get_style(label);
  PangoFontDescription* pfd = style->font_desc;
  gfx::Font* font = new gfx::Font(gfx::Font::CreateFont(pfd));
  pango_font_description_free(pfd);

  gtk_widget_destroy(window);

  return font;
}

// static
int TooltipManager::GetTooltipHeight() {
  // This is only used to position the tooltip, and we don't yet support
  // positioning the tooltip, it isn't worth trying to implement this.
  return 0;
}

// static
gfx::Font TooltipManager::GetDefaultFont() {
  static gfx::Font* font = NULL;
  if (!font)
    font = LoadDefaultFont();

  return *font;
}

// static
const std::wstring& TooltipManager::GetLineSeparator() {
  static std::wstring* line_separator = NULL;
  if (!line_separator)
    line_separator = new std::wstring(L"\n");
  return *line_separator;
}

// Callback from gtk_container_foreach. If |*label_p| is NULL and |widget| is
// a GtkLabel, |*label_p| is set to |widget|. Used to find the first GtkLabel
// in a container.
static void LabelLocatorCallback(GtkWidget* widget,
                                 gpointer label_p) {
  GtkWidget** label = static_cast<GtkWidget**>(label_p);
  if (!*label && GTK_IS_LABEL(widget))
    *label = widget;
}

// By default GtkTooltip wraps at a longish string. We want more control over
// that wrapping. The only way to do that is dig out the label and set
// gtk_label_set_max_width_chars, which is what this code does. I also tried
// setting a custom widget on the tooltip, but there is a bug in Gtk that
// triggers continually hiding/showing the widget in that case.
static void AdjustLabel(GtkTooltip* tooltip) {
  static const char kAdjustedLabelPropertyValue[] = "_adjusted_label_";
  gpointer adjusted_value = g_object_get_data(G_OBJECT(tooltip),
                                              kAdjustedLabelPropertyValue);
  if (adjusted_value)
    return;

  adjusted_value = reinterpret_cast<gpointer>(1);
  g_object_set_data(G_OBJECT(tooltip), kAdjustedLabelPropertyValue,
                    adjusted_value);

  GtkWidget* parent;
  {
    // Create a label so that we can get the parent. The Tooltip ends up taking
    // ownership of the label and deleting it.
    GtkWidget* label = gtk_label_new("");
    gtk_tooltip_set_custom(tooltip, label);
    parent = gtk_widget_get_parent(label);
    gtk_tooltip_set_custom(tooltip, NULL);
  }
  if (parent) {
    // We found the parent, find the first label, which is where the tooltip
    // text ends up going.
    GtkLabel* real_label = NULL;
    gtk_container_foreach(GTK_CONTAINER(parent), LabelLocatorCallback,
                          static_cast<gpointer>(&real_label));
    if (real_label)
      gtk_label_set_max_width_chars(GTK_LABEL(real_label), 3000);
  }
}

TooltipManagerGtk::TooltipManagerGtk(WidgetGtk* widget)
    : widget_(widget),
      keyboard_view_(NULL) {
}

bool TooltipManagerGtk::ShowTooltip(int x, int y, bool for_keyboard,
                                    GtkTooltip* tooltip) {
  View* view = NULL;
  gfx::Point view_loc;
  if (keyboard_view_) {
    view = keyboard_view_;
    view_loc.SetPoint(view->width() / 2, view->height() / 2);
  } else if (!for_keyboard) {
    RootView* root_view = widget_->GetRootView();
    view = root_view->GetViewForPoint(gfx::Point(x, y));
    view_loc.SetPoint(x, y);
    View::ConvertPointFromWidget(view, &view_loc);
  } else {
    FocusManager* focus_manager = widget_->GetFocusManager();
    if (focus_manager) {
      view = focus_manager->GetFocusedView();
      if (view)
        view_loc.SetPoint(view->width() / 2, view->height() / 2);
    }
  }

  if (!view)
    return false;

  std::wstring text;
  if (!view->GetTooltipText(view_loc.x(), view_loc.y(), &text))
    return false;

  AdjustLabel(tooltip);

  // Sets the area of the tooltip. This way if different views in the same
  // widget have tooltips the tooltip doesn't get stuck at the same location.
  gfx::Rect vis_bounds = view->GetVisibleBounds();
  gfx::Point widget_loc(vis_bounds.x(), vis_bounds.y());
  View::ConvertPointToWidget(view, &widget_loc);
  GdkRectangle tip_area = { widget_loc.x(), widget_loc.y(),
                            vis_bounds.width(), vis_bounds.height() };
  gtk_tooltip_set_tip_area(tooltip, &tip_area);

  int max_width, line_count;
  gfx::Point screen_loc(x, y);
  View::ConvertPointToScreen(widget_->GetRootView(), &screen_loc);
  TrimTooltipToFit(&text, &max_width, &line_count, screen_loc.x(),
                   screen_loc.y());
  gtk_tooltip_set_text(tooltip, WideToUTF8(text).c_str());

  return true;
}

void TooltipManagerGtk::UpdateTooltip() {
  // UpdateTooltip may be invoked after the widget has been destroyed.
  GtkWidget* widget = widget_->GetNativeView();
  if (!widget)
    return;

  GdkDisplay* display = gtk_widget_get_display(widget);
  if (display)
    gtk_tooltip_trigger_tooltip_query(display);
}

void TooltipManagerGtk::TooltipTextChanged(View* view) {
  UpdateTooltip();
}

void TooltipManagerGtk::ShowKeyboardTooltip(View* view) {
  if (view == keyboard_view_)
    return;  // We're already showing the tip for the specified view.

  // We have to hide the current tooltip, then show again.
  HideKeyboardTooltip();

  std::wstring tooltip_text;
  if (!view->GetTooltipText(0, 0, &tooltip_text))
    return;  // The view doesn't have a tooltip, nothing to do.

  keyboard_view_ = view;
  if (!SendShowHelpSignal()) {
    keyboard_view_ = NULL;
    return;
  }
}

void TooltipManagerGtk::HideKeyboardTooltip() {
  if (!keyboard_view_)
    return;

  SendShowHelpSignal();
  keyboard_view_ = NULL;
}

bool TooltipManagerGtk::SendShowHelpSignal() {
  GtkWidget* widget = widget_->window_contents();
  GType itype = G_TYPE_FROM_INSTANCE(G_OBJECT(widget));
  guint signal_id;
  GQuark detail;
  if (!g_signal_parse_name("show_help", itype, &signal_id, &detail, FALSE)) {
    NOTREACHED();
    return false;
  }
  gboolean result;
  g_signal_emit(widget, signal_id, 0, GTK_WIDGET_HELP_TOOLTIP, &result);
  return true;
}

}  // namespace views
<commit_msg>Fixes possible crash in tool tip manager.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "views/widget/tooltip_manager_gtk.h"

#include "app/gfx/font.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "views/focus/focus_manager.h"
#include "views/widget/root_view.h"
#include "views/widget/widget_gtk.h"

// WARNING: this implementation is good for a start, but it doesn't give us
// control of tooltip positioning both on mouse events and when showing from
// keyboard. We may need to write our own to give us the control we need.

namespace views {

static gfx::Font* LoadDefaultFont() {
  // Create a tooltip widget and extract the font from it (we have to realize
  // it to make sure the correct font gets set).
  GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP);
  gtk_widget_set_name(window, "gtk-tooltip");
  GtkWidget* label = gtk_label_new("");
  gtk_widget_show(label);

  gtk_container_add(GTK_CONTAINER(window), label);
  gtk_widget_realize(window);

  GtkStyle* style = gtk_widget_get_style(label);
  PangoFontDescription* pfd = style->font_desc;
  gfx::Font* font = new gfx::Font(gfx::Font::CreateFont(pfd));
  pango_font_description_free(pfd);

  gtk_widget_destroy(window);

  return font;
}

// static
int TooltipManager::GetTooltipHeight() {
  // This is only used to position the tooltip, and we don't yet support
  // positioning the tooltip, it isn't worth trying to implement this.
  return 0;
}

// static
gfx::Font TooltipManager::GetDefaultFont() {
  static gfx::Font* font = NULL;
  if (!font)
    font = LoadDefaultFont();

  return *font;
}

// static
const std::wstring& TooltipManager::GetLineSeparator() {
  static std::wstring* line_separator = NULL;
  if (!line_separator)
    line_separator = new std::wstring(L"\n");
  return *line_separator;
}

// Callback from gtk_container_foreach. If |*label_p| is NULL and |widget| is
// a GtkLabel, |*label_p| is set to |widget|. Used to find the first GtkLabel
// in a container.
static void LabelLocatorCallback(GtkWidget* widget,
                                 gpointer label_p) {
  GtkWidget** label = static_cast<GtkWidget**>(label_p);
  if (!*label && GTK_IS_LABEL(widget))
    *label = widget;
}

// By default GtkTooltip wraps at a longish string. We want more control over
// that wrapping. The only way to do that is dig out the label and set
// gtk_label_set_max_width_chars, which is what this code does. I also tried
// setting a custom widget on the tooltip, but there is a bug in Gtk that
// triggers continually hiding/showing the widget in that case.
static void AdjustLabel(GtkTooltip* tooltip) {
  static const char kAdjustedLabelPropertyValue[] = "_adjusted_label_";
  gpointer adjusted_value = g_object_get_data(G_OBJECT(tooltip),
                                              kAdjustedLabelPropertyValue);
  if (adjusted_value)
    return;

  adjusted_value = reinterpret_cast<gpointer>(1);
  g_object_set_data(G_OBJECT(tooltip), kAdjustedLabelPropertyValue,
                    adjusted_value);

  GtkWidget* parent;
  {
    // Create a label so that we can get the parent. The Tooltip ends up taking
    // ownership of the label and deleting it.
    GtkWidget* label = gtk_label_new("");
    gtk_tooltip_set_custom(tooltip, label);
    parent = gtk_widget_get_parent(label);
    gtk_tooltip_set_custom(tooltip, NULL);
  }
  if (parent) {
    // We found the parent, find the first label, which is where the tooltip
    // text ends up going.
    GtkLabel* real_label = NULL;
    gtk_container_foreach(GTK_CONTAINER(parent), LabelLocatorCallback,
                          static_cast<gpointer>(&real_label));
    if (real_label) {
      // For some reason I'm occasionally seeing a crash in trying to get font
      // metrics. Explicitly setting the font avoids this.
      PangoFontDescription* pfd =
          gfx::Font::PangoFontFromGfxFont(gfx::Font());
      gtk_widget_modify_font(GTK_WIDGET(real_label), pfd);
      pango_font_description_free(pfd);
      gtk_label_set_max_width_chars(GTK_LABEL(real_label), 3000);
    }
  }
}

TooltipManagerGtk::TooltipManagerGtk(WidgetGtk* widget)
    : widget_(widget),
      keyboard_view_(NULL) {
}

bool TooltipManagerGtk::ShowTooltip(int x, int y, bool for_keyboard,
                                    GtkTooltip* tooltip) {
  View* view = NULL;
  gfx::Point view_loc;
  if (keyboard_view_) {
    view = keyboard_view_;
    view_loc.SetPoint(view->width() / 2, view->height() / 2);
  } else if (!for_keyboard) {
    RootView* root_view = widget_->GetRootView();
    view = root_view->GetViewForPoint(gfx::Point(x, y));
    view_loc.SetPoint(x, y);
    View::ConvertPointFromWidget(view, &view_loc);
  } else {
    FocusManager* focus_manager = widget_->GetFocusManager();
    if (focus_manager) {
      view = focus_manager->GetFocusedView();
      if (view)
        view_loc.SetPoint(view->width() / 2, view->height() / 2);
    }
  }

  if (!view)
    return false;

  std::wstring text;
  if (!view->GetTooltipText(view_loc.x(), view_loc.y(), &text))
    return false;

  AdjustLabel(tooltip);

  // Sets the area of the tooltip. This way if different views in the same
  // widget have tooltips the tooltip doesn't get stuck at the same location.
  gfx::Rect vis_bounds = view->GetVisibleBounds();
  gfx::Point widget_loc(vis_bounds.x(), vis_bounds.y());
  View::ConvertPointToWidget(view, &widget_loc);
  GdkRectangle tip_area = { widget_loc.x(), widget_loc.y(),
                            vis_bounds.width(), vis_bounds.height() };
  gtk_tooltip_set_tip_area(tooltip, &tip_area);

  int max_width, line_count;
  gfx::Point screen_loc(x, y);
  View::ConvertPointToScreen(widget_->GetRootView(), &screen_loc);
  TrimTooltipToFit(&text, &max_width, &line_count, screen_loc.x(),
                   screen_loc.y());
  gtk_tooltip_set_text(tooltip, WideToUTF8(text).c_str());

  return true;
}

void TooltipManagerGtk::UpdateTooltip() {
  // UpdateTooltip may be invoked after the widget has been destroyed.
  GtkWidget* widget = widget_->GetNativeView();
  if (!widget)
    return;

  GdkDisplay* display = gtk_widget_get_display(widget);
  if (display)
    gtk_tooltip_trigger_tooltip_query(display);
}

void TooltipManagerGtk::TooltipTextChanged(View* view) {
  UpdateTooltip();
}

void TooltipManagerGtk::ShowKeyboardTooltip(View* view) {
  if (view == keyboard_view_)
    return;  // We're already showing the tip for the specified view.

  // We have to hide the current tooltip, then show again.
  HideKeyboardTooltip();

  std::wstring tooltip_text;
  if (!view->GetTooltipText(0, 0, &tooltip_text))
    return;  // The view doesn't have a tooltip, nothing to do.

  keyboard_view_ = view;
  if (!SendShowHelpSignal()) {
    keyboard_view_ = NULL;
    return;
  }
}

void TooltipManagerGtk::HideKeyboardTooltip() {
  if (!keyboard_view_)
    return;

  SendShowHelpSignal();
  keyboard_view_ = NULL;
}

bool TooltipManagerGtk::SendShowHelpSignal() {
  GtkWidget* widget = widget_->window_contents();
  GType itype = G_TYPE_FROM_INSTANCE(G_OBJECT(widget));
  guint signal_id;
  GQuark detail;
  if (!g_signal_parse_name("show_help", itype, &signal_id, &detail, FALSE)) {
    NOTREACHED();
    return false;
  }
  gboolean result;
  g_signal_emit(widget, signal_id, 0, GTK_WIDGET_HELP_TOOLTIP, &result);
  return true;
}

}  // namespace views
<|endoftext|>