<commit_before>/** feature-selection.cc ---
 *
 * Copyright (C) 2011 OpenCog Foundation
 *
 * Author: Nil Geisweiller
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <iostream>
#include <fstream>
#include <memory>
#include <stdio.h>

#include <boost/assign/std/vector.hpp> // for 'operator+=()'
#include <boost/range/algorithm/find.hpp>
#include <boost/range/algorithm/adjacent_find.hpp>
#include <boost/range/algorithm/set_algorithm.hpp>
#include <boost/range/irange.hpp>

#include <opencog/util/mt19937ar.h>
#include <opencog/util/Logger.h>
#include <opencog/util/lru_cache.h>
#include <opencog/util/algorithm.h>
#include <opencog/util/iostreamContainer.h>
#include <opencog/util/oc_omp.h>

#include <opencog/comboreduct/combo/table.h>
#include <opencog/comboreduct/combo/table_io.h>

#include <opencog/learning/moses/optimization/optimization.h>

#include "feature-selection.h"
#include "../feature_optimization.h"
#include "../feature_scorer.h"

namespace opencog {

using namespace combo;
using namespace std;
using namespace boost::assign; // bring 'operator+=()' into scope

void err_empty_features(const string& outfile)
{
    // If the dataset is degenerate, it can happen that feature
    // selection will fail to find any features.  Rather than just
    // crashing as a result, write out an empty file, which at least
    // allows downstream processes to infer what happened (i.e. to tell
    // apart this case from an outright crash.)
    logger().warn() << "No features have been selected.";
    std::cerr << "No features have been selected." << std::endl;
    if (!outfile.empty()) {
        ofstream out(outfile.c_str());
        out << "# No features have been selected." << std::endl;
    }
    exit(0);
}

// Score all individual features of Table
vector<double> score_individual_features(const Table& table,
                                         const feature_selection_parameters& fs_params)
{
    typedef set<arity_t> FS;
    CTable ctable = table.compressed();
    fs_scorer<FS> fs_sc(ctable, fs_params);
    vector<double> res;
    boost::transform(boost::irange(0, table.get_arity()), back_inserter(res),
                     [&](arity_t idx) { FS fs = {idx}; return fs_sc(fs); });
    return res;
}

// log the set of features and its number
void log_selected_features(arity_t old_arity, const Table& ftable,
                           const feature_selection_parameters& fs_params)
{
    // log the number selected features
    logger().info("%d out of %d have been selected",
                  ftable.get_arity(), old_arity);
    // log set of selected feature set
    {
        stringstream ss;
        ss << "The following features have been selected: ";
        ostreamContainer(ss, ftable.itable.get_labels(), ",");
        logger().info(ss.str());
    }
    // log the score of each feature individually
    {
        stringstream ss;
        ss << "With the following scores (individually): ";
        ostreamContainer(ss, score_individual_features(ftable, fs_params), ",");
        logger().info(ss.str());
    }
}

Table add_force_features(const Table& table,
                         const feature_selection_parameters& fs_params)
{
    const ITable& itable = table.itable;
    // get forced features that have not been selected
    std::vector<std::string> fnsel;
    const auto& ilabels = itable.get_labels();
    foreach(const std::string& fn, fs_params.force_features_str)
        if (boost::find(ilabels, fn) == ilabels.cend())
            fnsel.push_back(fn);

    // get their positions
    std::vector<int> fnsel_pos =
        find_features_positions(fs_params.input_file, fnsel);
    boost::sort(fnsel_pos);

    // get the complementary of their positions
    std::vector<int> fnsel_pos_comp;
    auto ir = boost::irange(0, dataFileArity(fs_params.input_file) + 1);
    boost::set_difference(ir, fnsel_pos, back_inserter(fnsel_pos_comp));

    // get header of the input table
    auto header = loadHeader(fs_params.input_file);

    // load the table with force_non_selected features with all
    // selected features with types definite_object (i.e. string) that
    // way the content is unchanged (convenient when the data contains
    // stuff that loadITable does not know how to interpret)
    ITable fns_itable;          // ITable from fnsel (+ output)
    type_tree tt = gen_signature(id::definite_object_type, fnsel.size());
    loadITable(fs_params.input_file, fns_itable, tt, fnsel_pos_comp);

    // Find the positions of the selected features
    std::vector<int> fsel_pos =
        find_features_positions(fs_params.input_file, ilabels);

    // insert the forced features in the right order
    Table new_table;
    new_table.otable = table.otable;
    new_table.itable = itable;
    // insert missing columns from fns_itable to new_table.itable
    for (auto lit = fnsel_pos.cbegin(), rit = fsel_pos.cbegin();
         lit != fnsel_pos.cend(); ++lit) {
        int lpos = distance(fnsel_pos.cbegin(), lit);
        auto lc = fns_itable.get_col(lpos);
        while(rit != fsel_pos.cend() && *lit > *rit) ++rit;
        int rpos = rit != fsel_pos.cend() ?
            distance(fsel_pos.cbegin(), rit) + lpos : -1;
        new_table.itable.insert_col(lc.first, lc.second, rpos);
    }

    return new_table;
}

int update_target_feature(const Table& table,
                          const feature_selection_parameters& fs_params)
{
    int tfp = table.get_target_column();
    if (tfp <= 0)               // it is either first or last
        return tfp;
    else {
        // Find the positions of the selected features
        std::vector<int> fsel_pos =
            find_features_positions(fs_params.input_file,
                                    table.itable.get_labels());
        if (tfp < fsel_pos.front()) // it is first
            return 0;
        else if (tfp > fsel_pos.back()) // it is last
            return -1;
        else {                  // it is somewhere in between
            auto it = boost::adjacent_find(fsel_pos, [tfp](int l, int r) {
                    return l < tfp && tfp < r; });
            return distance(fsel_pos.begin(), ++it);
        }
    }
}

void write_results(const Table& table,
                   const feature_selection_parameters& fs_params)
{
    Table table_wff = add_force_features(table, fs_params);
    int tfp = update_target_feature(table_wff, fs_params);
    if (fs_params.output_file.empty())
        ostreamTable(std::cout, table_wff, tfp);
    else
        saveTable(fs_params.output_file, table_wff, tfp);
}

instance initial_instance(const feature_selection_parameters& fs_params,
                          const field_set& fields,
                          const vector<string>& labels)
{
    vector<std::string> vif; // valid initial features, used for logging
    instance res(fields.packed_width());

    foreach(const std::string& f, fs_params.hc_initial_features) {
        size_t idx = std::distance(labels.begin(), boost::find(labels, f));
        if(idx < labels.size()) { // feature found
            *(fields.begin_bit(res) + idx) = true;
            // for logging
            vif += f;
        }
        else // feature not found
            logger().warn("No such a feature #%s in file %s. It will be ignored as initial feature.", f.c_str(), fs_params.input_file.c_str());
    }
    // Logger
    if(vif.empty())
        logger().info("The search will start with the empty feature set");
    else {
        stringstream ss;
        ss << "The search will start with the following feature set: ";
        ostreamContainer(ss, vif, ",");
        logger().info(ss.str());
    }
    // ~Logger
    return res;
}

feature_set incremental_select_features(const CTable& ctable,
                                        const feature_selection_parameters& fs_params)
{
    auto ir = boost::irange(0, ctable.get_arity());
    feature_set all_features(ir.begin(), ir.end());
    if (fs_params.threshold > 0 || fs_params.target_size > 0) {
        typedef MutualInformation<feature_set> FeatureScorer;
        FeatureScorer fsc(ctable);
        return fs_params.target_size > 0?
            cached_adaptive_incremental_selection(all_features, fsc,
                                                  fs_params.target_size,
                                                  fs_params.inc_interaction_terms,
                                                  fs_params.inc_red_intensity,
                                                  0, 1,
                                                  fs_params.inc_target_size_epsilon)
            : cached_incremental_selection(all_features, fsc,
                                           fs_params.threshold,
                                           fs_params.inc_interaction_terms,
                                           fs_params.inc_red_intensity);
    } else {
        // Nothing happened, return all features by default
        return all_features;
    }
}

feature_set max_mi_select_features(const CTable& ctable,
                                   const feature_selection_parameters& fs_params)
{
    auto ir = boost::irange(0, ctable.get_arity());
    feature_set all_features(ir.begin(), ir.end());
    if (fs_params.target_size > 0) {
        typedef MutualInformation<feature_set> FeatureScorer;
        FeatureScorer fsc(ctable);
        return max_mi_selection(all_features, fsc,
                                (unsigned) fs_params.target_size,
                                fs_params.threshold);
    } else {
        // Nothing happened, return the all features by default
        return all_features;
    }
}

feature_set select_features(const CTable& ctable,
                            const feature_selection_parameters& fs_params) {
    if (fs_params.algorithm == moses::hc) {
        // setting moses optimization parameters
        double pop_size_ratio = 20;
        size_t max_dist = 4;
        score_t min_score_improv = 0.0;
        optim_parameters op_params;
        op_params.opt_algo = moses::hc;
        op_params.pop_size_ratio = pop_size_ratio;
        op_params.terminate_if_gte = fs_params.hc_max_score;
        op_params.max_dist = max_dist;
        op_params.set_min_score_improv(min_score_improv);
        op_params.hc_params.widen_search = true;
        op_params.hc_params.single_step = false;
        op_params.hc_params.crossover = false;
        hill_climbing hc(op_params);
        return moses_select_features(ctable, hc, fs_params);
    } else if (fs_params.algorithm == inc) {
        return incremental_select_features(ctable, fs_params);
    } else if (fs_params.algorithm == mmi) {
        return max_mi_select_features(ctable, fs_params);
    } else {
        std::cerr << "Fatal Error: Algorithm '" << fs_params.algorithm
                  << "' is unknown, please consult the help for the "
                     "list of algorithms." << std::endl;
        exit(1);
        return feature_set(); // to please Mr compiler
    }
}

feature_set select_features(const Table& table,
                            const feature_selection_parameters& fs_params) {
    CTable ctable = table.compressed();
    return select_features(ctable, fs_params);
}

void feature_selection(const Table& table,
                       const feature_selection_parameters& fs_params)
{
    feature_set selected_features = select_features(table, fs_params);
    if (selected_features.empty())
        err_empty_features(fs_params.output_file);
    else {
        Table ftable = table.filtered(selected_features);
        log_selected_features(table.get_arity(), ftable, fs_params);
        write_results(ftable, fs_params);
    }
}

} // ~namespace opencog
<commit_msg>feature selectction: add a needed argument to the call stack.<commit_after>/** feature-selection.cc ---
 *
 * Copyright (C) 2011 OpenCog Foundation
 *
 * Author: Nil Geisweiller
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <iostream>
#include <fstream>
#include <memory>
#include <stdio.h>

#include <boost/assign/std/vector.hpp> // for 'operator+=()'
#include <boost/range/algorithm/find.hpp>
#include <boost/range/algorithm/adjacent_find.hpp>
#include <boost/range/algorithm/set_algorithm.hpp>
#include <boost/range/irange.hpp>

#include <opencog/util/mt19937ar.h>
#include <opencog/util/Logger.h>
#include <opencog/util/lru_cache.h>
#include <opencog/util/algorithm.h>
#include <opencog/util/iostreamContainer.h>
#include <opencog/util/oc_omp.h>

#include <opencog/comboreduct/combo/table.h>
#include <opencog/comboreduct/combo/table_io.h>

#include <opencog/learning/moses/optimization/optimization.h>

#include "feature-selection.h"
#include "../feature_optimization.h"
#include "../feature_scorer.h"

namespace opencog {

using namespace combo;
using namespace std;
using namespace boost::assign; // bring 'operator+=()' into scope

void err_empty_features(const string& outfile)
{
    // If the dataset is degenerate, it can happen that feature
    // selection will fail to find any features.  Rather than just
    // crashing as a result, write out an empty file, which at least
    // allows downstream processes to infer what happened (i.e. to tell
    // apart this case from an outright crash.)
    logger().warn() << "No features have been selected.";
    std::cerr << "No features have been selected." << std::endl;
    if (!outfile.empty()) {
        ofstream out(outfile.c_str());
        out << "# No features have been selected." << std::endl;
    }
    exit(0);
}

// Score all individual features of Table
vector<double> score_individual_features(const Table& table,
                                         const feature_selection_parameters& fs_params)
{
    typedef set<arity_t> FS;
    CTable ctable = table.compressed();
    fs_scorer<FS> fs_sc(ctable, fs_params);
    vector<double> res;
    boost::transform(boost::irange(0, table.get_arity()), back_inserter(res),
                     [&](arity_t idx) { FS fs = {idx}; return fs_sc(fs); });
    return res;
}

// log the set of features and its number
void log_selected_features(arity_t old_arity, const Table& ftable,
                           const feature_selection_parameters& fs_params)
{
    // log the number selected features
    logger().info("%d out of %d have been selected",
                  ftable.get_arity(), old_arity);
    // log set of selected feature set
    {
        stringstream ss;
        ss << "The following features have been selected: ";
        ostreamContainer(ss, ftable.itable.get_labels(), ",");
        logger().info(ss.str());
    }
    // log the score of each feature individually
    {
        stringstream ss;
        ss << "With the following scores (individually): ";
        ostreamContainer(ss, score_individual_features(ftable, fs_params), ",");
        logger().info(ss.str());
    }
}

/// Add back in any required features that were not selected.
///
/// 'selected_table' is the table of features that were selected.
///     (it is a filtered version of the full table, holding only the
///     selected features.)
/// 'full_table' is the original input table (with all features in it)
//
Table add_force_features(const Table& selected_table,
                         const Table& full_table,
                         const feature_selection_parameters& fs_params)
{
    const ITable& itable = selected_table.itable;
    // get forced features that have not been selected
    std::vector<std::string> fnsel;
    const auto& ilabels = itable.get_labels();
    foreach(const std::string& fn, fs_params.force_features_str)
        if (boost::find(ilabels, fn) == ilabels.cend())
            fnsel.push_back(fn);

    // get their positions
    std::vector<int> fnsel_pos =
        find_features_positions(fs_params.input_file, fnsel);
    boost::sort(fnsel_pos);

    // get the complementary of their positions
    std::vector<int> fnsel_pos_comp;
    auto ir = boost::irange(0, dataFileArity(fs_params.input_file) + 1);
    boost::set_difference(ir, fnsel_pos, back_inserter(fnsel_pos_comp));

    // get header of the input table
    auto header = loadHeader(fs_params.input_file);

    // load the table with force_non_selected features with all
    // selected features with types definite_object (i.e. string) that
    // way the content is unchanged (convenient when the data contains
    // stuff that loadITable does not know how to interpret)
    ITable fns_itable;          // ITable from fnsel (+ output)
    type_tree tt = gen_signature(id::definite_object_type, fnsel.size());
    loadITable(fs_params.input_file, fns_itable, tt, fnsel_pos_comp);

    // Find the positions of the selected features
    std::vector<int> fsel_pos =
        find_features_positions(fs_params.input_file, ilabels);

    // insert the forced features in the right order
    Table new_table;
    new_table.otable = selected_table.otable;
    new_table.itable = itable;
    // insert missing columns from fns_itable to new_table.itable
    for (auto lit = fnsel_pos.cbegin(), rit = fsel_pos.cbegin();
         lit != fnsel_pos.cend(); ++lit) {
        int lpos = distance(fnsel_pos.cbegin(), lit);
        auto lc = fns_itable.get_col(lpos);
        while(rit != fsel_pos.cend() && *lit > *rit) ++rit;
        int rpos = rit != fsel_pos.cend() ?
            distance(fsel_pos.cbegin(), rit) + lpos : -1;
        new_table.itable.insert_col(lc.first, lc.second, rpos);
    }

    return new_table;
}

int update_target_feature(const Table& table,
                          const feature_selection_parameters& fs_params)
{
    int tfp = table.get_target_column();
    if (tfp <= 0)               // it is either first or last
        return tfp;
    else {
        // Find the positions of the selected features
        std::vector<int> fsel_pos =
            find_features_positions(fs_params.input_file,
                                    table.itable.get_labels());
        if (tfp < fsel_pos.front()) // it is first
            return 0;
        else if (tfp > fsel_pos.back()) // it is last
            return -1;
        else {                  // it is somewhere in between
            auto it = boost::adjacent_find(fsel_pos, [tfp](int l, int r) {
                    return l < tfp && tfp < r; });
            return distance(fsel_pos.begin(), ++it);
        }
    }
}

void write_results(const Table& selected_table,
                   const Table& full_table,
                   const feature_selection_parameters& fs_params)
{
    Table table_wff = add_force_features(selected_table, full_table, fs_params);
    int tfp = update_target_feature(table_wff, fs_params);
    if (fs_params.output_file.empty())
        ostreamTable(std::cout, table_wff, tfp);
    else
        saveTable(fs_params.output_file, table_wff, tfp);
}

instance initial_instance(const feature_selection_parameters& fs_params,
                          const field_set& fields,
                          const vector<string>& labels)
{
    vector<std::string> vif; // valid initial features, used for logging
    instance res(fields.packed_width());

    foreach(const std::string& f, fs_params.hc_initial_features) {
        size_t idx = std::distance(labels.begin(), boost::find(labels, f));
        if(idx < labels.size()) { // feature found
            *(fields.begin_bit(res) + idx) = true;
            // for logging
            vif += f;
        }
        else // feature not found
            logger().warn("No such a feature #%s in file %s. It will be ignored as initial feature.", f.c_str(), fs_params.input_file.c_str());
    }
    // Logger
    if(vif.empty())
        logger().info("The search will start with the empty feature set");
    else {
        stringstream ss;
        ss << "The search will start with the following feature set: ";
        ostreamContainer(ss, vif, ",");
        logger().info(ss.str());
    }
    // ~Logger
    return res;
}

feature_set incremental_select_features(const CTable& ctable,
                                        const feature_selection_parameters& fs_params)
{
    auto ir = boost::irange(0, ctable.get_arity());
    feature_set all_features(ir.begin(), ir.end());
    if (fs_params.threshold > 0 || fs_params.target_size > 0) {
        typedef MutualInformation<feature_set> FeatureScorer;
        FeatureScorer fsc(ctable);
        return fs_params.target_size > 0?
            cached_adaptive_incremental_selection(all_features, fsc,
                                                  fs_params.target_size,
                                                  fs_params.inc_interaction_terms,
                                                  fs_params.inc_red_intensity,
                                                  0, 1,
                                                  fs_params.inc_target_size_epsilon)
            : cached_incremental_selection(all_features, fsc,
                                           fs_params.threshold,
                                           fs_params.inc_interaction_terms,
                                           fs_params.inc_red_intensity);
    } else {
        // Nothing happened, return all features by default
        return all_features;
    }
}

feature_set max_mi_select_features(const CTable& ctable,
                                   const feature_selection_parameters& fs_params)
{
    auto ir = boost::irange(0, ctable.get_arity());
    feature_set all_features(ir.begin(), ir.end());
    if (fs_params.target_size > 0) {
        typedef MutualInformation<feature_set> FeatureScorer;
        FeatureScorer fsc(ctable);
        return max_mi_selection(all_features, fsc,
                                (unsigned) fs_params.target_size,
                                fs_params.threshold);
    } else {
        // Nothing happened, return the all features by default
        return all_features;
    }
}

feature_set select_features(const CTable& ctable,
                            const feature_selection_parameters& fs_params) {
    if (fs_params.algorithm == moses::hc) {
        // setting moses optimization parameters
        double pop_size_ratio = 20;
        size_t max_dist = 4;
        score_t min_score_improv = 0.0;
        optim_parameters op_params;
        op_params.opt_algo = moses::hc;
        op_params.pop_size_ratio = pop_size_ratio;
        op_params.terminate_if_gte = fs_params.hc_max_score;
        op_params.max_dist = max_dist;
        op_params.set_min_score_improv(min_score_improv);
        op_params.hc_params.widen_search = true;
        op_params.hc_params.single_step = false;
        op_params.hc_params.crossover = false;
        hill_climbing hc(op_params);
        return moses_select_features(ctable, hc, fs_params);
    } else if (fs_params.algorithm == inc) {
        return incremental_select_features(ctable, fs_params);
    } else if (fs_params.algorithm == mmi) {
        return max_mi_select_features(ctable, fs_params);
    } else {
        std::cerr << "Fatal Error: Algorithm '" << fs_params.algorithm
                  << "' is unknown, please consult the help for the "
                     "list of algorithms." << std::endl;
        exit(1);
        return feature_set(); // to please Mr compiler
    }
}

feature_set select_features(const Table& table,
                            const feature_selection_parameters& fs_params) {
    CTable ctable = table.compressed();
    return select_features(ctable, fs_params);
}

void feature_selection(const Table& table,
                       const feature_selection_parameters& fs_params)
{
    feature_set selected_features = select_features(table, fs_params);
    if (selected_features.empty())
        err_empty_features(fs_params.output_file);
    else {
        Table filt_table = table.filtered(selected_features);
        log_selected_features(table.get_arity(), filt_table, fs_params);
        write_results(filt_table, table, fs_params);
    }
}

} // ~namespace opencog
<|endoftext|>


<commit_before>//===- CheckerDocumentation.cpp - Documentation checker ---------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This checker lists all the checker callbacks and provides documentation for
// checker writers.
//
//===----------------------------------------------------------------------===//

#include "ClangSACheckers.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"

using namespace clang;
using namespace ento;

// All checkers should be placed into anonymous namespace.
// We place the CheckerDocumentation inside ento namespace to make the
// it visible in doxygen.
namespace clang {
namespace ento {

/// This checker documents the callback functions checkers can use to implement
/// the custom handling of the specific events during path exploration as well
/// as reporting bugs. Most of the callbacks are targeted at path-sensitive
/// checking.
///
/// \sa CheckerContext
class CheckerDocumentation : public Checker< check::PreStmt<ReturnStmt>,
                                       check::PostStmt<DeclStmt>,
                                       check::PreObjCMessage,
                                       check::PostObjCMessage,
                                       check::ObjCMessageNil,
                                       check::PreCall,
                                       check::PostCall,
                                       check::BranchCondition,
                                       check::Location,
                                       check::Bind,
                                       check::DeadSymbols,
                                       check::EndFunction,
                                       check::EndAnalysis,
                                       check::EndOfTranslationUnit,
                                       eval::Call,
                                       eval::Assume,
                                       check::LiveSymbols,
                                       check::RegionChanges,
                                       check::PointerEscape,
                                       check::ConstPointerEscape,
                                       check::Event<ImplicitNullDerefEvent>,
                                       check::ASTDecl<FunctionDecl> > {
public:
  /// \brief Pre-visit the Statement.
  ///
  /// The method will be called before the analyzer core processes the
  /// statement. The notification is performed for every explored CFGElement,
  /// which does not include the control flow statements such as IfStmt. The
  /// callback can be specialized to be called with any subclass of Stmt.
  ///
  /// See checkBranchCondition() callback for performing custom processing of
  /// the branching statements.
  ///
  /// check::PreStmt<ReturnStmt>
  void checkPreStmt(const ReturnStmt *DS, CheckerContext &C) const {}

  /// \brief Post-visit the Statement.
  ///
  /// The method will be called after the analyzer core processes the
  /// statement. The notification is performed for every explored CFGElement,
  /// which does not include the control flow statements such as IfStmt. The
  /// callback can be specialized to be called with any subclass of Stmt.
  ///
  /// check::PostStmt<DeclStmt>
  void checkPostStmt(const DeclStmt *DS, CheckerContext &C) const;

  /// \brief Pre-visit the Objective C message.
  ///
  /// This will be called before the analyzer core processes the method call.
  /// This is called for any action which produces an Objective-C message send,
  /// including explicit message syntax and property access.
  ///
  /// check::PreObjCMessage
  void checkPreObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const {}

  /// \brief Post-visit the Objective C message.
  /// \sa checkPreObjCMessage()
  ///
  /// check::PostObjCMessage
  void checkPostObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const {}

  /// \brief Visit an Objective-C message whose receiver is nil.
  ///
  /// This will be called when the analyzer core processes a method call whose
  /// receiver is definitely nil. In this case, check{Pre/Post}ObjCMessage and
  /// check{Pre/Post}Call will not be called.
  ///
  /// check::ObjCMessageNil
  void checkObjCMessageNil(const ObjCMethodCall &M, CheckerContext &C) const {}

  /// \brief Pre-visit an abstract "call" event.
  ///
  /// This is used for checkers that want to check arguments or attributed
  /// behavior for functions and methods no matter how they are being invoked.
  ///
  /// Note that this includes ALL cross-body invocations, so if you want to
  /// limit your checks to, say, function calls, you should test for that at the
  /// beginning of your callback function.
  ///
  /// check::PreCall
  void checkPreCall(const CallEvent &Call, CheckerContext &C) const {}

  /// \brief Post-visit an abstract "call" event.
  /// \sa checkPreObjCMessage()
  ///
  /// check::PostCall
  void checkPostCall(const CallEvent &Call, CheckerContext &C) const {}

  /// \brief Pre-visit of the condition statement of a branch (such as IfStmt).
  void checkBranchCondition(const Stmt *Condition, CheckerContext &Ctx) const {}

  /// \brief Called on a load from and a store to a location.
  ///
  /// The method will be called each time a location (pointer) value is
  /// accessed.
  /// \param Loc    The value of the location (pointer).
  /// \param IsLoad The flag specifying if the location is a store or a load.
  /// \param S      The load is performed while processing the statement.
  ///
  /// check::Location
  void checkLocation(SVal Loc, bool IsLoad, const Stmt *S,
                     CheckerContext &) const {}

  /// \brief Called on binding of a value to a location.
  ///
  /// \param Loc The value of the location (pointer).
  /// \param Val The value which will be stored at the location Loc.
  /// \param S   The bind is performed while processing the statement S.
  ///
  /// check::Bind
  void checkBind(SVal Loc, SVal Val, const Stmt *S, CheckerContext &) const {}

  /// \brief Called whenever a symbol becomes dead.
  ///
  /// This callback should be used by the checkers to aggressively clean
  /// up/reduce the checker state, which is important for reducing the overall
  /// memory usage. Specifically, if a checker keeps symbol specific information
  /// in the sate, it can and should be dropped after the symbol becomes dead.
  /// In addition, reporting a bug as soon as the checker becomes dead leads to
  /// more precise diagnostics. (For example, one should report that a malloced
  /// variable is not freed right after it goes out of scope.)
  ///
  /// \param SR The SymbolReaper object can be queried to determine which
  ///           symbols are dead.
  ///
  /// check::DeadSymbols
  void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const {}

  /// \brief Called when the analyzer core starts analyzing a function,
  /// regardless of whether it is analyzed at the top level or is inlined.
  ///
  /// check::BeginFunction
  void checkBeginFunction(CheckerContext &Ctx) const {}

  /// \brief Called when the analyzer core reaches the end of a
  /// function being analyzed regardless of whether it is analyzed at the top
  /// level or is inlined.
  ///
  /// check::EndFunction
  void checkEndFunction(CheckerContext &Ctx) const {}

  /// \brief Called after all the paths in the ExplodedGraph reach end of path
  /// - the symbolic execution graph is fully explored.
  ///
  /// This callback should be used in cases when a checker needs to have a
  /// global view of the information generated on all paths. For example, to
  /// compare execution summary/result several paths.
  /// See IdempotentOperationChecker for a usage example.
  ///
  /// check::EndAnalysis
  void checkEndAnalysis(ExplodedGraph &G,
                        BugReporter &BR,
                        ExprEngine &Eng) const {}

  /// \brief Called after analysis of a TranslationUnit is complete.
  ///
  /// check::EndOfTranslationUnit
  void checkEndOfTranslationUnit(const TranslationUnitDecl *TU,
                                 AnalysisManager &Mgr,
                                 BugReporter &BR) const {}

  /// \brief Evaluates function call.
  ///
  /// The analysis core threats all function calls in the same way. However, some
  /// functions have special meaning, which should be reflected in the program
  /// state. This callback allows a checker to provide domain specific knowledge
  /// about the particular functions it knows about.
  ///
  /// \returns true if the call has been successfully evaluated
  /// and false otherwise. Note, that only one checker can evaluate a call. If
  /// more than one checker claims that they can evaluate the same call the
  /// first one wins.
  ///
  /// eval::Call
  bool evalCall(const CallExpr *CE, CheckerContext &C) const { return true; }

  /// \brief Handles assumptions on symbolic values.
  ///
  /// This method is called when a symbolic expression is assumed to be true or
  /// false. For example, the assumptions are performed when evaluating a
  /// condition at a branch. The callback allows checkers track the assumptions
  /// performed on the symbols of interest and change the state accordingly.
  ///
  /// eval::Assume
  ProgramStateRef evalAssume(ProgramStateRef State,
                                 SVal Cond,
                                 bool Assumption) const { return State; }

  /// Allows modifying SymbolReaper object. For example, checkers can explicitly
  /// register symbols of interest as live. These symbols will not be marked
  /// dead and removed.
  ///
  /// check::LiveSymbols
  void checkLiveSymbols(ProgramStateRef State, SymbolReaper &SR) const {}

  /// \brief Called to determine if the checker currently needs to know if when
  /// contents of any regions change.
  ///
  /// Since it is not necessarily cheap to compute which regions are being
  /// changed, this allows the analyzer core to skip the more expensive
  /// #checkRegionChanges when no checkers are tracking any state.
  bool wantsRegionChangeUpdate(ProgramStateRef St) const { return true; }

  /// \brief Called when the contents of one or more regions change.
  ///
  /// This can occur in many different ways: an explicit bind, a blanket
  /// invalidation of the region contents, or by passing a region to a function
  /// call whose behavior the analyzer cannot model perfectly.
  ///
  /// \param State The current program state.
  /// \param Invalidated A set of all symbols potentially touched by the change.
  /// \param ExplicitRegions The regions explicitly requested for invalidation.
  ///        For a function call, this would be the arguments. For a bind, this
  ///        would be the region being bound to.
  /// \param Regions The transitive closure of regions accessible from,
  ///        \p ExplicitRegions, i.e. all regions that may have been touched
  ///        by this change. For a simple bind, this list will be the same as
  ///        \p ExplicitRegions, since a bind does not affect the contents of
  ///        anything accessible through the base region.
  /// \param Call The opaque call triggering this invalidation. Will be 0 if the
  ///        change was not triggered by a call.
  ///
  /// Note that this callback will not be invoked unless
  /// #wantsRegionChangeUpdate returns \c true.
  ///
  /// check::RegionChanges
  ProgramStateRef
    checkRegionChanges(ProgramStateRef State,
                       const InvalidatedSymbols *Invalidated,
                       ArrayRef<const MemRegion *> ExplicitRegions,
                       ArrayRef<const MemRegion *> Regions,
                       const CallEvent *Call) const {
    return State;
  }

  /// \brief Called when pointers escape.
  ///
  /// This notifies the checkers about pointer escape, which occurs whenever
  /// the analyzer cannot track the symbol any more. For example, as a
  /// result of assigning a pointer into a global or when it's passed to a
  /// function call the analyzer cannot model.
  ///
  /// \param State The state at the point of escape.
  /// \param Escaped The list of escaped symbols.
  /// \param Call The corresponding CallEvent, if the symbols escape as
  /// parameters to the given call.
  /// \param Kind How the symbols have escaped.
  /// \returns Checkers can modify the state by returning a new state.
  ProgramStateRef checkPointerEscape(ProgramStateRef State,
                                     const InvalidatedSymbols &Escaped,
                                     const CallEvent *Call,
                                     PointerEscapeKind Kind) const {
    return State;
  }

  /// \brief Called when const pointers escape.
  ///
  /// Note: in most cases checkPointerEscape callback is sufficient.
  /// \sa checkPointerEscape
  ProgramStateRef checkConstPointerEscape(ProgramStateRef State,
                                     const InvalidatedSymbols &Escaped,
                                     const CallEvent *Call,
                                     PointerEscapeKind Kind) const {
    return State;
  }

  /// check::Event<ImplicitNullDerefEvent>
  void checkEvent(ImplicitNullDerefEvent Event) const {}

  /// \brief Check every declaration in the AST.
  ///
  /// An AST traversal callback, which should only be used when the checker is
  /// not path sensitive. It will be called for every Declaration in the AST and
  /// can be specialized to only be called on subclasses of Decl, for example,
  /// FunctionDecl.
  ///
  /// check::ASTDecl<FunctionDecl>
  void checkASTDecl(const FunctionDecl *D,
                    AnalysisManager &Mgr,
                    BugReporter &BR) const {}
};

void CheckerDocumentation::checkPostStmt(const DeclStmt *DS,
                                         CheckerContext &C) const {
}

} // end namespace ento
} // end namespace clang
<commit_msg>[analyzer] Add check::BeginFunction to CheckerDocumentation checks. NFC.<commit_after>//===- CheckerDocumentation.cpp - Documentation checker ---------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This checker lists all the checker callbacks and provides documentation for
// checker writers.
//
//===----------------------------------------------------------------------===//

#include "ClangSACheckers.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"

using namespace clang;
using namespace ento;

// All checkers should be placed into anonymous namespace.
// We place the CheckerDocumentation inside ento namespace to make the
// it visible in doxygen.
namespace clang {
namespace ento {

/// This checker documents the callback functions checkers can use to implement
/// the custom handling of the specific events during path exploration as well
/// as reporting bugs. Most of the callbacks are targeted at path-sensitive
/// checking.
///
/// \sa CheckerContext
class CheckerDocumentation : public Checker< check::PreStmt<ReturnStmt>,
                                       check::PostStmt<DeclStmt>,
                                       check::PreObjCMessage,
                                       check::PostObjCMessage,
                                       check::ObjCMessageNil,
                                       check::PreCall,
                                       check::PostCall,
                                       check::BranchCondition,
                                       check::Location,
                                       check::Bind,
                                       check::DeadSymbols,
                                       check::BeginFunction,
                                       check::EndFunction,
                                       check::EndAnalysis,
                                       check::EndOfTranslationUnit,
                                       eval::Call,
                                       eval::Assume,
                                       check::LiveSymbols,
                                       check::RegionChanges,
                                       check::PointerEscape,
                                       check::ConstPointerEscape,
                                       check::Event<ImplicitNullDerefEvent>,
                                       check::ASTDecl<FunctionDecl> > {
public:
  /// \brief Pre-visit the Statement.
  ///
  /// The method will be called before the analyzer core processes the
  /// statement. The notification is performed for every explored CFGElement,
  /// which does not include the control flow statements such as IfStmt. The
  /// callback can be specialized to be called with any subclass of Stmt.
  ///
  /// See checkBranchCondition() callback for performing custom processing of
  /// the branching statements.
  ///
  /// check::PreStmt<ReturnStmt>
  void checkPreStmt(const ReturnStmt *DS, CheckerContext &C) const {}

  /// \brief Post-visit the Statement.
  ///
  /// The method will be called after the analyzer core processes the
  /// statement. The notification is performed for every explored CFGElement,
  /// which does not include the control flow statements such as IfStmt. The
  /// callback can be specialized to be called with any subclass of Stmt.
  ///
  /// check::PostStmt<DeclStmt>
  void checkPostStmt(const DeclStmt *DS, CheckerContext &C) const;

  /// \brief Pre-visit the Objective C message.
  ///
  /// This will be called before the analyzer core processes the method call.
  /// This is called for any action which produces an Objective-C message send,
  /// including explicit message syntax and property access.
  ///
  /// check::PreObjCMessage
  void checkPreObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const {}

  /// \brief Post-visit the Objective C message.
  /// \sa checkPreObjCMessage()
  ///
  /// check::PostObjCMessage
  void checkPostObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const {}

  /// \brief Visit an Objective-C message whose receiver is nil.
  ///
  /// This will be called when the analyzer core processes a method call whose
  /// receiver is definitely nil. In this case, check{Pre/Post}ObjCMessage and
  /// check{Pre/Post}Call will not be called.
  ///
  /// check::ObjCMessageNil
  void checkObjCMessageNil(const ObjCMethodCall &M, CheckerContext &C) const {}

  /// \brief Pre-visit an abstract "call" event.
  ///
  /// This is used for checkers that want to check arguments or attributed
  /// behavior for functions and methods no matter how they are being invoked.
  ///
  /// Note that this includes ALL cross-body invocations, so if you want to
  /// limit your checks to, say, function calls, you should test for that at the
  /// beginning of your callback function.
  ///
  /// check::PreCall
  void checkPreCall(const CallEvent &Call, CheckerContext &C) const {}

  /// \brief Post-visit an abstract "call" event.
  /// \sa checkPreObjCMessage()
  ///
  /// check::PostCall
  void checkPostCall(const CallEvent &Call, CheckerContext &C) const {}

  /// \brief Pre-visit of the condition statement of a branch (such as IfStmt).
  void checkBranchCondition(const Stmt *Condition, CheckerContext &Ctx) const {}

  /// \brief Called on a load from and a store to a location.
  ///
  /// The method will be called each time a location (pointer) value is
  /// accessed.
  /// \param Loc    The value of the location (pointer).
  /// \param IsLoad The flag specifying if the location is a store or a load.
  /// \param S      The load is performed while processing the statement.
  ///
  /// check::Location
  void checkLocation(SVal Loc, bool IsLoad, const Stmt *S,
                     CheckerContext &) const {}

  /// \brief Called on binding of a value to a location.
  ///
  /// \param Loc The value of the location (pointer).
  /// \param Val The value which will be stored at the location Loc.
  /// \param S   The bind is performed while processing the statement S.
  ///
  /// check::Bind
  void checkBind(SVal Loc, SVal Val, const Stmt *S, CheckerContext &) const {}

  /// \brief Called whenever a symbol becomes dead.
  ///
  /// This callback should be used by the checkers to aggressively clean
  /// up/reduce the checker state, which is important for reducing the overall
  /// memory usage. Specifically, if a checker keeps symbol specific information
  /// in the sate, it can and should be dropped after the symbol becomes dead.
  /// In addition, reporting a bug as soon as the checker becomes dead leads to
  /// more precise diagnostics. (For example, one should report that a malloced
  /// variable is not freed right after it goes out of scope.)
  ///
  /// \param SR The SymbolReaper object can be queried to determine which
  ///           symbols are dead.
  ///
  /// check::DeadSymbols
  void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const {}

  /// \brief Called when the analyzer core starts analyzing a function,
  /// regardless of whether it is analyzed at the top level or is inlined.
  ///
  /// check::BeginFunction
  void checkBeginFunction(CheckerContext &Ctx) const {}

  /// \brief Called when the analyzer core reaches the end of a
  /// function being analyzed regardless of whether it is analyzed at the top
  /// level or is inlined.
  ///
  /// check::EndFunction
  void checkEndFunction(CheckerContext &Ctx) const {}

  /// \brief Called after all the paths in the ExplodedGraph reach end of path
  /// - the symbolic execution graph is fully explored.
  ///
  /// This callback should be used in cases when a checker needs to have a
  /// global view of the information generated on all paths. For example, to
  /// compare execution summary/result several paths.
  /// See IdempotentOperationChecker for a usage example.
  ///
  /// check::EndAnalysis
  void checkEndAnalysis(ExplodedGraph &G,
                        BugReporter &BR,
                        ExprEngine &Eng) const {}

  /// \brief Called after analysis of a TranslationUnit is complete.
  ///
  /// check::EndOfTranslationUnit
  void checkEndOfTranslationUnit(const TranslationUnitDecl *TU,
                                 AnalysisManager &Mgr,
                                 BugReporter &BR) const {}

  /// \brief Evaluates function call.
  ///
  /// The analysis core threats all function calls in the same way. However, some
  /// functions have special meaning, which should be reflected in the program
  /// state. This callback allows a checker to provide domain specific knowledge
  /// about the particular functions it knows about.
  ///
  /// \returns true if the call has been successfully evaluated
  /// and false otherwise. Note, that only one checker can evaluate a call. If
  /// more than one checker claims that they can evaluate the same call the
  /// first one wins.
  ///
  /// eval::Call
  bool evalCall(const CallExpr *CE, CheckerContext &C) const { return true; }

  /// \brief Handles assumptions on symbolic values.
  ///
  /// This method is called when a symbolic expression is assumed to be true or
  /// false. For example, the assumptions are performed when evaluating a
  /// condition at a branch. The callback allows checkers track the assumptions
  /// performed on the symbols of interest and change the state accordingly.
  ///
  /// eval::Assume
  ProgramStateRef evalAssume(ProgramStateRef State,
                                 SVal Cond,
                                 bool Assumption) const { return State; }

  /// Allows modifying SymbolReaper object. For example, checkers can explicitly
  /// register symbols of interest as live. These symbols will not be marked
  /// dead and removed.
  ///
  /// check::LiveSymbols
  void checkLiveSymbols(ProgramStateRef State, SymbolReaper &SR) const {}

  /// \brief Called to determine if the checker currently needs to know if when
  /// contents of any regions change.
  ///
  /// Since it is not necessarily cheap to compute which regions are being
  /// changed, this allows the analyzer core to skip the more expensive
  /// #checkRegionChanges when no checkers are tracking any state.
  bool wantsRegionChangeUpdate(ProgramStateRef St) const { return true; }

  /// \brief Called when the contents of one or more regions change.
  ///
  /// This can occur in many different ways: an explicit bind, a blanket
  /// invalidation of the region contents, or by passing a region to a function
  /// call whose behavior the analyzer cannot model perfectly.
  ///
  /// \param State The current program state.
  /// \param Invalidated A set of all symbols potentially touched by the change.
  /// \param ExplicitRegions The regions explicitly requested for invalidation.
  ///        For a function call, this would be the arguments. For a bind, this
  ///        would be the region being bound to.
  /// \param Regions The transitive closure of regions accessible from,
  ///        \p ExplicitRegions, i.e. all regions that may have been touched
  ///        by this change. For a simple bind, this list will be the same as
  ///        \p ExplicitRegions, since a bind does not affect the contents of
  ///        anything accessible through the base region.
  /// \param Call The opaque call triggering this invalidation. Will be 0 if the
  ///        change was not triggered by a call.
  ///
  /// Note that this callback will not be invoked unless
  /// #wantsRegionChangeUpdate returns \c true.
  ///
  /// check::RegionChanges
  ProgramStateRef
    checkRegionChanges(ProgramStateRef State,
                       const InvalidatedSymbols *Invalidated,
                       ArrayRef<const MemRegion *> ExplicitRegions,
                       ArrayRef<const MemRegion *> Regions,
                       const CallEvent *Call) const {
    return State;
  }

  /// \brief Called when pointers escape.
  ///
  /// This notifies the checkers about pointer escape, which occurs whenever
  /// the analyzer cannot track the symbol any more. For example, as a
  /// result of assigning a pointer into a global or when it's passed to a
  /// function call the analyzer cannot model.
  ///
  /// \param State The state at the point of escape.
  /// \param Escaped The list of escaped symbols.
  /// \param Call The corresponding CallEvent, if the symbols escape as
  /// parameters to the given call.
  /// \param Kind How the symbols have escaped.
  /// \returns Checkers can modify the state by returning a new state.
  ProgramStateRef checkPointerEscape(ProgramStateRef State,
                                     const InvalidatedSymbols &Escaped,
                                     const CallEvent *Call,
                                     PointerEscapeKind Kind) const {
    return State;
  }

  /// \brief Called when const pointers escape.
  ///
  /// Note: in most cases checkPointerEscape callback is sufficient.
  /// \sa checkPointerEscape
  ProgramStateRef checkConstPointerEscape(ProgramStateRef State,
                                     const InvalidatedSymbols &Escaped,
                                     const CallEvent *Call,
                                     PointerEscapeKind Kind) const {
    return State;
  }

  /// check::Event<ImplicitNullDerefEvent>
  void checkEvent(ImplicitNullDerefEvent Event) const {}

  /// \brief Check every declaration in the AST.
  ///
  /// An AST traversal callback, which should only be used when the checker is
  /// not path sensitive. It will be called for every Declaration in the AST and
  /// can be specialized to only be called on subclasses of Decl, for example,
  /// FunctionDecl.
  ///
  /// check::ASTDecl<FunctionDecl>
  void checkASTDecl(const FunctionDecl *D,
                    AnalysisManager &Mgr,
                    BugReporter &BR) const {}
};

void CheckerDocumentation::checkPostStmt(const DeclStmt *DS,
                                         CheckerContext &C) const {
}

} // end namespace ento
} // end namespace clang
<|endoftext|>


<commit_before>#include <initializer_list>
#include <map>
#include <string>

#include <gtk/gtk.h>

/// List of unit types we handle.
enum class ConversionUnit
{
    Inch,
    Point,
    Twip,

    M,
    Cm,
    Mm,
    Mm100,

    Emu
};

/// Hold references to all data needed to perform a conversion.
class Conversion
{
  public:
    GtkEntry* _amount;
    GtkComboBox* _from;
    GtkComboBox* _to;
    GtkLabel* _result;

    Conversion();
};

Conversion::Conversion()
    : _amount(nullptr), _from(nullptr), _to(nullptr), _result(nullptr)
{
}

namespace
{

void initAmount(GtkWidget* grid, Conversion& conversion)
{
    GtkWidget* amount = gtk_entry_new();
    conversion._amount = GTK_ENTRY(amount);
    gtk_grid_attach(GTK_GRID(grid), amount, 0, 0, 1, 1);
}

GtkComboBox* initUnit(GtkWidget* grid, int active, int top)
{
    GtkWidget* unitCombo = gtk_combo_box_text_new();
    std::initializer_list<std::string> units = {"inch",  "point", "twip",

                                                "m",     "cm",    "mm",
                                                "mm100",

                                                "emu"};
    for (const auto& unit : units)
        gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(unitCombo), nullptr,
                                  unit.c_str());
    gtk_combo_box_set_active(GTK_COMBO_BOX(unitCombo), active);
    gtk_grid_attach(GTK_GRID(grid), unitCombo, 1, top, 1, 1);
    return GTK_COMBO_BOX(unitCombo);
}

void initResult(GtkWidget* grid, Conversion& conversion)
{
    GtkWidget* result = gtk_label_new("");
    conversion._result = GTK_LABEL(result);
    gtk_label_set_selectable(conversion._result, TRUE);
    gtk_grid_attach(GTK_GRID(grid), result, 0, 1, 1, 1);
}

void convert(GtkWidget* /*widget*/, gpointer userData)
{
    Conversion* conversion = static_cast<Conversion*>(userData);
    static std::map<ConversionUnit, double> units;
    if (units.empty())
    {
        units[ConversionUnit::Inch] = 914400.0;
        units[ConversionUnit::Point] = 914400.0 / 72;
        units[ConversionUnit::Twip] = 914400.0 / 72 / 20;

        units[ConversionUnit::M] = 360 * 100000;
        units[ConversionUnit::Cm] = 360 * 1000;
        units[ConversionUnit::Mm] = 360 * 100;
        units[ConversionUnit::Mm100] = 360;

        units[ConversionUnit::Emu] = 1;
    }

    // Convert to EMU.
    double amount = std::stod(gtk_entry_get_text(conversion->_amount));
    auto from = static_cast<ConversionUnit>(
        gtk_combo_box_get_active(conversion->_from));
    double emu = amount * units[from];

    auto to =
        static_cast<ConversionUnit>(gtk_combo_box_get_active(conversion->_to));
    double ret = emu / units[to];

    gtk_label_set_text(conversion->_result, std::to_string(ret).c_str());
}

void initConvert(GtkWidget* grid, Conversion& conversion)
{
    GtkWidget* convertButton = gtk_button_new_with_label("Convert");
    gtk_grid_attach(GTK_GRID(grid), convertButton, 0, 2, 1, 1);
    g_signal_connect(convertButton, "clicked", G_CALLBACK(convert),
                     &conversion);
}

void initQuit(GtkWidget* grid)
{
    GtkWidget* quit = gtk_button_new_with_label("Quit");
    g_signal_connect(quit, "clicked", G_CALLBACK(gtk_main_quit), nullptr);
    gtk_grid_attach(GTK_GRID(grid), quit, 1, 2, 1, 1);
}

void initControls(GtkWidget* window, Conversion& conversion)
{
    GtkWidget* grid = gtk_grid_new();
    initAmount(grid, conversion);
    conversion._from = initUnit(grid, 0, 0);
    conversion._to = initUnit(grid, 1, 1);
    initResult(grid, conversion);
    initConvert(grid, conversion);
    initQuit(grid);
    gtk_container_add(GTK_CONTAINER(window), grid);
}

} // anonymous namespace

int main(int argc, char** argv)
{
    gtk_init(&argc, &argv);
    GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "gtktpconv");
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), nullptr);

    Conversion conversion;
    initControls(window, conversion);

    gtk_widget_show_all(window);

    gtk_main();

    return 0;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>gtktpconv: error handling<commit_after>#include <initializer_list>
#include <map>
#include <sstream>
#include <string>

#include <gtk/gtk.h>

/// List of unit types we handle.
enum class ConversionUnit
{
    Inch,
    Point,
    Twip,

    M,
    Cm,
    Mm,
    Mm100,

    Emu
};

/// Hold references to all data needed to perform a conversion.
class Conversion
{
  public:
    GtkEntry* _amount;
    GtkComboBox* _from;
    GtkComboBox* _to;
    GtkLabel* _result;

    Conversion();
};

Conversion::Conversion()
    : _amount(nullptr), _from(nullptr), _to(nullptr), _result(nullptr)
{
}

namespace
{

void initAmount(GtkWidget* grid, Conversion& conversion)
{
    GtkWidget* amount = gtk_entry_new();
    conversion._amount = GTK_ENTRY(amount);
    gtk_grid_attach(GTK_GRID(grid), amount, 0, 0, 1, 1);
}

GtkComboBox* initUnit(GtkWidget* grid, int active, int top)
{
    GtkWidget* unitCombo = gtk_combo_box_text_new();
    std::initializer_list<std::string> units = {"inch",  "point", "twip",

                                                "m",     "cm",    "mm",
                                                "mm100",

                                                "emu"};
    for (const auto& unit : units)
        gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(unitCombo), nullptr,
                                  unit.c_str());
    gtk_combo_box_set_active(GTK_COMBO_BOX(unitCombo), active);
    gtk_grid_attach(GTK_GRID(grid), unitCombo, 1, top, 1, 1);
    return GTK_COMBO_BOX(unitCombo);
}

void initResult(GtkWidget* grid, Conversion& conversion)
{
    GtkWidget* result = gtk_label_new("");
    conversion._result = GTK_LABEL(result);
    gtk_label_set_selectable(conversion._result, TRUE);
    gtk_grid_attach(GTK_GRID(grid), result, 0, 1, 1, 1);
}

void convert(GtkWidget* /*widget*/, gpointer userData)
{
    Conversion* conversion = static_cast<Conversion*>(userData);
    static std::map<ConversionUnit, double> units;
    if (units.empty())
    {
        units[ConversionUnit::Inch] = 914400.0;
        units[ConversionUnit::Point] = 914400.0 / 72;
        units[ConversionUnit::Twip] = 914400.0 / 72 / 20;

        units[ConversionUnit::M] = 360 * 100000;
        units[ConversionUnit::Cm] = 360 * 1000;
        units[ConversionUnit::Mm] = 360 * 100;
        units[ConversionUnit::Mm100] = 360;

        units[ConversionUnit::Emu] = 1;
    }

    std::string text;
    // Convert to EMU.
    try
    {
        double amount = std::stod(gtk_entry_get_text(conversion->_amount));
        auto from = static_cast<ConversionUnit>(
            gtk_combo_box_get_active(conversion->_from));
        double emu = amount * units[from];

        auto to = static_cast<ConversionUnit>(
            gtk_combo_box_get_active(conversion->_to));
        double ret = emu / units[to];
        text = std::to_string(ret);
    }
    catch (const std::invalid_argument& exception)
    {
        std::stringstream ss;
        ss << "invalid argument: " << exception.what();
        text = ss.str();
    }

    gtk_label_set_text(conversion->_result, text.c_str());
}

void initConvert(GtkWidget* grid, Conversion& conversion)
{
    GtkWidget* convertButton = gtk_button_new_with_label("Convert");
    gtk_grid_attach(GTK_GRID(grid), convertButton, 0, 2, 1, 1);
    g_signal_connect(convertButton, "clicked", G_CALLBACK(convert),
                     &conversion);
}

void initQuit(GtkWidget* grid)
{
    GtkWidget* quit = gtk_button_new_with_label("Quit");
    g_signal_connect(quit, "clicked", G_CALLBACK(gtk_main_quit), nullptr);
    gtk_grid_attach(GTK_GRID(grid), quit, 1, 2, 1, 1);
}

void initControls(GtkWidget* window, Conversion& conversion)
{
    GtkWidget* grid = gtk_grid_new();
    initAmount(grid, conversion);
    conversion._from = initUnit(grid, 0, 0);
    conversion._to = initUnit(grid, 1, 1);
    initResult(grid, conversion);
    initConvert(grid, conversion);
    initQuit(grid);
    gtk_container_add(GTK_CONTAINER(window), grid);
}

} // anonymous namespace

int main(int argc, char** argv)
{
    gtk_init(&argc, &argv);
    GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "gtktpconv");
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), nullptr);

    Conversion conversion;
    initControls(window, conversion);

    gtk_widget_show_all(window);

    gtk_main();

    return 0;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// RUN: cat %s | %cling -Xclang -verify 2>&1 | FileCheck %s
// Test blockComments

(/*
   1
   2
   3 */
  8
  // single line 1
  /* single line 2*/
)
// CHECK: (int) 8

// Check nested indentation works
/*
 {
  (
   [
   ]
  )
 }
*/

// Check nested indentation doesn't error on mismatched closures
/*
  {
    [
      (
      }
    )
  ]
*/

( 5
  /*
   + 1
   + 2
   + 3 */
  + 4
  // single line 1
  /* single line 2*/
)
// CHECK-NEXT: (int) 9

/*
  This should work
  // As should this // */

/*
  This will warn
  // /* */ // expected-warning {{within block comment}}

.rawInput 1
*/ // expected-error {{expected unqualified-id}}
.rawInput 0

// This is a side effect of wrapping, expression is compiled as */; so 2 errors
*/ // expected-error@2 {{expected expression}} expected-error@3 {{expected expression}}

// Check preprocessor blocked out
/*
#if 1

#else er
#we not gonna terminate this
  #include "stop messing around.h"
#finished

*/

// Check meta-commands are blocked out
/*
  .L SomeStuff
  .x some more
  .q
*/

( 5
  /*
   + 10
   + 20 */
  /*
    + 30
  */
  + 4
  // single line 1
  + 10
  /* single line 2*/
  /* ) */
)
// CHECK-NEXT: (int) 19

/* 8 + */ 9 /* = 20 */
// CHECK-NEXT: (int) 9

/*
// Check inline asteriks
*******************************************************
*    Row   * Instance *   fEvents.fEventNo * fShowers *
*******************************************************
*        0 *        0 *                  0 *       10 *
*        0 *        1 *                  0 *       20 *
*        0 *        2 *                  2 *       30 *
*******************************************************
*/

32
// CHECK-NEXT: (int) 32

/* Check inline asteriks ****/
62
// CHECK-NEXT: (int) 62

.q
<commit_msg>Test ROOT-8529.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// RUN: cat %s | %cling -Xclang -verify 2>&1 | FileCheck %s
// Test blockComments

(/*
   1
   2
   3 */
  8
  // single line 1
  /* single line 2*/
)
// CHECK: (int) 8

// Check nested indentation works
/*
 {
  (
   [
   ]
  )
 }
*/

// Check nested indentation doesn't error on mismatched closures
/*
  {
    [
      (
      }
    )
  ]
*/

( 5
  /*
   + 1
   + 2
   + 3 */
  + 4
  // single line 1
  /* single line 2*/
)
// CHECK-NEXT: (int) 9

/*
  This should work
  // As should this // */

/*
  This will warn
  // /* */ // expected-warning {{within block comment}}

.rawInput 1
*/ // expected-error {{expected unqualified-id}}
.rawInput 0

// This is a side effect of wrapping, expression is compiled as */; so 2 errors
*/ // expected-error@2 {{expected expression}} expected-error@3 {{expected expression}}

// Check preprocessor blocked out
/*
#if 1

#else er
#we not gonna terminate this
  #include "stop messing around.h"
#finished

*/

// Check meta-commands are blocked out
/*
  .L SomeStuff
  .x some more
  .q
*/

( 5
  /*
   + 10
   + 20 */
  /*
    + 30
  */
  + 4
  // single line 1
  + 10
  /* single line 2*/
  /* ) */
)
// CHECK-NEXT: (int) 19

/* 8 + */ 9 /* = 20 */
// CHECK-NEXT: (int) 9

/*
// Check inline asteriks
*******************************************************
*    Row   * Instance *   fEvents.fEventNo * fShowers *
*******************************************************
*        0 *        0 *                  0 *       10 *
*        0 *        1 *                  0 *       20 *
*        0 *        2 *                  2 *       30 *
*******************************************************
*/

32
// CHECK-NEXT: (int) 32

/* Check inline asteriks ****/
62
// CHECK-NEXT: (int) 62

// ROOT-8529
12/3*4
// CHECK-NEXT: (int) 16

.q
<|endoftext|>


<commit_before>/**
 * \file
 * \brief TestCaseRangeRange class header
 *
 * \author Copyright (C) 2014 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2014-08-24
 */

#ifndef TEST_TESTCASERANGERANGE_HPP_
#define TEST_TESTCASERANGERANGE_HPP_

#include "TestCaseRange.hpp"

namespace distortos
{

namespace test
{

/// range of references to TestCaseRange objects
using TestCaseRangeRange = estd::ContiguousRange<const estd::ReferenceHolder<const TestCaseRange>>;

}	// namespace test

}	// namespace distortos

#endif	// TEST_TESTCASERANGERANGE_HPP_
<commit_msg>test: remove TestCaseRangeRange type alias<commit_after><|endoftext|>


<commit_before>//===--- EpilogueReleaseMatcherDumper.cpp - Find Epilogue Releases  -------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This pass finds the epilogue releases matched to each argument of the
/// function.
///
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "sil-epilogue-release-dumper"
#include "swift/SILOptimizer/PassManager/Passes.h"
#include "swift/SIL/SILArgument.h"
#include "swift/SIL/SILFunction.h"
#include "swift/SIL/SILValue.h"
#include "swift/SILOptimizer/Analysis/AliasAnalysis.h"
#include "swift/SILOptimizer/Analysis/ARCAnalysis.h"
#include "swift/SILOptimizer/Analysis/Analysis.h"
#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h"
#include "swift/SILOptimizer/PassManager/Transforms.h"

using namespace swift;

//===----------------------------------------------------------------------===//
//                              Top Level Driver
//===----------------------------------------------------------------------===//

namespace {

/// Find and dump the epilogue release instructions for the arguments.
class SILEpilogueRetainReleaseMatcherDumper : public SILModuleTransform {

  void run() override {
    auto *AA = PM->getAnalysis<AliasAnalysis>();
    auto *RCIA = getAnalysis<RCIdentityAnalysis>();
    for (auto &Fn: *getModule()) {
      // Function is not definition.
      if (!Fn.isDefinition())
        continue;

      llvm::outs() << "START: sil @" << Fn.getName() << "\n";

      // Handle @owned return value.
      ConsumedReturnValueToEpilogueRetainMatcher RetMap(RCIA->get(&Fn), AA, &Fn);
      for (auto &RI : RetMap)
        llvm::outs() << *RI;

      // Handle @owned function arguments.
      ConsumedArgToEpilogueReleaseMatcher RelMap(RCIA->get(&Fn), &Fn);
      // Iterate over arguments and dump their epilogue releases.
      for (auto Arg : Fn.getArguments()) {
        llvm::outs() << *Arg;
        // Can not find an epilogue release instruction for the argument.
        for (auto &RI : RelMap.getReleasesForArgument(Arg))
          llvm::outs() << *RI;
      }

      llvm::outs() << "END: sil @" << Fn.getName() << "\n";
    }
  }

  StringRef getName() override { return "Epilogue Retain/Release Matcher Dumper"; }
};

} // end anonymous namespace

SILTransform *swift::createEpilogueRetainReleaseMatcherDumper() {
  return new SILEpilogueRetainReleaseMatcherDumper();
}
<commit_msg>[gardening] Fix incorrect file name in file header<commit_after>//===--- EpilogueRetainReleaseMatcherDumper.cpp - Find Epilogue Releases --===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This pass finds the epilogue releases matched to each argument of the
/// function.
///
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "sil-epilogue-release-dumper"
#include "swift/SILOptimizer/PassManager/Passes.h"
#include "swift/SIL/SILArgument.h"
#include "swift/SIL/SILFunction.h"
#include "swift/SIL/SILValue.h"
#include "swift/SILOptimizer/Analysis/AliasAnalysis.h"
#include "swift/SILOptimizer/Analysis/ARCAnalysis.h"
#include "swift/SILOptimizer/Analysis/Analysis.h"
#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h"
#include "swift/SILOptimizer/PassManager/Transforms.h"

using namespace swift;

//===----------------------------------------------------------------------===//
//                              Top Level Driver
//===----------------------------------------------------------------------===//

namespace {

/// Find and dump the epilogue release instructions for the arguments.
class SILEpilogueRetainReleaseMatcherDumper : public SILModuleTransform {

  void run() override {
    auto *AA = PM->getAnalysis<AliasAnalysis>();
    auto *RCIA = getAnalysis<RCIdentityAnalysis>();
    for (auto &Fn: *getModule()) {
      // Function is not definition.
      if (!Fn.isDefinition())
        continue;

      llvm::outs() << "START: sil @" << Fn.getName() << "\n";

      // Handle @owned return value.
      ConsumedReturnValueToEpilogueRetainMatcher RetMap(RCIA->get(&Fn), AA, &Fn);
      for (auto &RI : RetMap)
        llvm::outs() << *RI;

      // Handle @owned function arguments.
      ConsumedArgToEpilogueReleaseMatcher RelMap(RCIA->get(&Fn), &Fn);
      // Iterate over arguments and dump their epilogue releases.
      for (auto Arg : Fn.getArguments()) {
        llvm::outs() << *Arg;
        // Can not find an epilogue release instruction for the argument.
        for (auto &RI : RelMap.getReleasesForArgument(Arg))
          llvm::outs() << *RI;
      }

      llvm::outs() << "END: sil @" << Fn.getName() << "\n";
    }
  }

  StringRef getName() override { return "Epilogue Retain/Release Matcher Dumper"; }
};

} // end anonymous namespace

SILTransform *swift::createEpilogueRetainReleaseMatcherDumper() {
  return new SILEpilogueRetainReleaseMatcherDumper();
}
<|endoftext|>


<commit_before>/* Jim Viebke
Feb 16 2015 */

#include "parse.h"

map<string, string> Parse::dict; // first string maps to second string

void Parse::initialize()
{
	// map various possible user-input strings to the constant ID used throughout the engine

	if (dict.size() == 0)
	{
		cout << "\nLoading parse dictionary...";

		// test commands
		P::dict["recipe"] = P::dict["recipes"] = C::PRINT_RECIPES_COMMAND;

		// verbs
		P::dict["help"] = P::dict["h"] = P::dict["q"] = P::dict["?"] = P::dict["assist"] = C::HELP_COMMAND;
		// P::dict["login"] = C::LOGIN_COMMAND; // not used yet
		P::dict["logout"] = P::dict["quit"] = P::dict["leave"] = P::dict["exit"] = C::LOGOUT_COMMAND;
		P::dict["move"] = P::dict["m"] = P::dict["walk"] = P::dict["run"] = P::dict["head"] = P::dict["go"] = P::dict["continue"] = P::dict["work"] = C::MOVE_COMMAND;
		P::dict["take"] = P::dict["get"] = P::dict["pick"] = P::dict["choose"] = P::dict["grab"] = P::dict["acquire"] = C::TAKE_COMMAND;
		P::dict["equip"] = P::dict["equipped"] = P::dict["weild"] = P::dict["wield"] = P::dict["ready"] = P::dict["draw"] = C::EQUIP_COMMAND;
		P::dict["item"] = C::ITEM_COMMAND; // viewing equipped item
		P::dict["dequip"] = P::dict["deequip"] = P::dict["unequip"] = P::dict["unwield"] = P::dict["unweild"] = P::dict["store"] = P::dict["sheathe"] = P::dict["sheath"] = C::DEQUIP_COMMAND;
		P::dict["craft"] = P::dict["make"] = P::dict["create"] = P::dict["fashion"] = C::CRAFT_COMMAND;
		P::dict["drop"] = P::dict["release"] = P::dict["unhand"] = P::dict["add"] = P::dict["place"] = P::dict["put"] = C::DROP_COMMAND;
		P::dict["into"] = P::dict["in"] = P::dict["to"] = C::INSERT_COMMAND;
		P::dict["from"] = P::dict["form"] = C::FROM_COMMAND;
		P::dict["wait"] = P::dict["pause"] = P::dict["consider"] = P::dict["delay"] = C::WAIT_COMMAND;
		P::dict["with"] = C::WITH_COMMAND;
		P::dict["construct"] = P::dict["build"] = P::dict["erect"] = C::CONSTRUCT_COMMAND;
		P::dict["attack"] = P::dict["smash"] = P::dict["strike"] = P::dict["bash"] = P::dict["break"] = P::dict["damage"] = P::dict["stab"] = P::dict["slash"] = C::ATTACK_COMMAND;

		// items

		// items -> other
		P::dict["smelter"] = C::SMELTER_ID;
		P::dict["forge"] = C::FORGE_ID;
		P::dict["anvil"] = C::ANVIL_ID;
		P::dict["tree"] = C::TREE_ID;
		P::dict["chest"] = P::dict["crate"] = C::CHEST_ID;

		// items -> materials
		P::dict["stone"] = P::dict["rock"] = C::STONE_ID;
		P::dict["branch"] = P::dict["branches"] = C::BRANCH_ID;
		P::dict["stick"] = C::STICK_ID;
		P::dict["vine"] = C::VINE_ID;
		P::dict["arrow"] = C::ARROW_ID;
		P::dict["arrowhead"] = C::ARROWHEAD_ID;
		P::dict["board"] = P::dict["boards"] = P::dict["plank"] = P::dict["planks"] = C::BOARD_ID;

		// items -> tools
		P::dict["bow"] = C::BOW_ID;
		P::dict["staff"] = C::STAFF_ID;
		P::dict["axe"] = C::AXE_ID;
		P::dict["sword"] = C::SWORD_ID;
		P::dict["hammer"] = C::HAMMER_ID;

		// directions
		P::dict["n"] = P::dict["north"] = C::NORTH;
		P::dict["ne"] = P::dict["northeast"] = C::NORTH_EAST;
		P::dict["e"] = P::dict["east"] = C::EAST;
		P::dict["se"] = P::dict["southeast"] = C::SOUTH_EAST;
		P::dict["s"] = P::dict["south"] = C::SOUTH;
		P::dict["sw"] = P::dict["southwest"] = C::SOUTH_WEST;
		P::dict["w"] = P::dict["west"] = C::WEST;
		P::dict["nw"] = P::dict["northwest"] = C::NORTH_WEST;
		P::dict["u"] = P::dict["up"] = P::dict["upward"] = P::dict["upwards"] = P::dict["upstairs"] = C::UP;
		P::dict["d"] = P::dict["down"] = P::dict["downward"] = P::dict["downwards"] = P::dict["downstairs"] = C::UP;

		// surfaces not already in directions
		P::dict["floor"] = P::dict["ground"] = C::FLOOR;
		P::dict["ceiling"] = C::CEILING;

		// Look Mr. Frodo! A
		P::dict["door"] = C::DOOR;
		P::dict["wall"] = P::dict["surface"] = C::WALL;
	}
}

vector<string> Parse::tokenize(const string & s)
{
	// converts an input string to vector of "engine official" keywords/commands

	cout << "\nDEBUG inside parse.tokenize: "; // debugging

	// convert the space-delimited user input to a vector of strings (one word per string)
	stringstream ss(s);
	const istream_iterator<string> begin(ss);
	vector<string> strings(begin, istream_iterator<string>());

	R::print(strings); // debugging

	for (string & word : strings) // for each word
	{
		// convert the word to lowercase
		R::to_lower_case(word);

		// replace the word with the engine keyword, or C::BAD_COMMAND
		word = (dict.find(word) != dict.end()) ? dict.find(word)->second : C::BAD_COMMAND;
	}

	return strings;
}
<commit_msg>add "advance" as a synonym for the wait command<commit_after>/* Jim Viebke
Feb 16 2015 */

#include "parse.h"

map<string, string> Parse::dict; // first string maps to second string

void Parse::initialize()
{
	// map various possible user-input strings to the constant ID used throughout the engine

	if (dict.size() == 0)
	{
		cout << "\nLoading parse dictionary...";

		// test commands
		P::dict["recipe"] = P::dict["recipes"] = C::PRINT_RECIPES_COMMAND;

		// verbs
		P::dict["help"] = P::dict["h"] = P::dict["q"] = P::dict["?"] = P::dict["assist"] = C::HELP_COMMAND;
		// P::dict["login"] = C::LOGIN_COMMAND; // not used yet
		P::dict["logout"] = P::dict["quit"] = P::dict["leave"] = P::dict["exit"] = C::LOGOUT_COMMAND;
		P::dict["move"] = P::dict["m"] = P::dict["walk"] = P::dict["run"] = P::dict["head"] = P::dict["go"] = P::dict["continue"] = P::dict["work"] = C::MOVE_COMMAND;
		P::dict["take"] = P::dict["get"] = P::dict["pick"] = P::dict["choose"] = P::dict["grab"] = P::dict["acquire"] = C::TAKE_COMMAND;
		P::dict["equip"] = P::dict["equipped"] = P::dict["weild"] = P::dict["wield"] = P::dict["ready"] = P::dict["draw"] = C::EQUIP_COMMAND;
		P::dict["item"] = C::ITEM_COMMAND; // viewing equipped item
		P::dict["dequip"] = P::dict["deequip"] = P::dict["unequip"] = P::dict["unwield"] = P::dict["unweild"] = P::dict["store"] = P::dict["sheathe"] = P::dict["sheath"] = C::DEQUIP_COMMAND;
		P::dict["craft"] = P::dict["make"] = P::dict["create"] = P::dict["fashion"] = C::CRAFT_COMMAND;
		P::dict["drop"] = P::dict["release"] = P::dict["unhand"] = P::dict["add"] = P::dict["place"] = P::dict["put"] = C::DROP_COMMAND;
		P::dict["into"] = P::dict["in"] = P::dict["to"] = C::INSERT_COMMAND;
		P::dict["from"] = P::dict["form"] = C::FROM_COMMAND;
		P::dict["wait"] = P::dict["pause"] = P::dict["consider"] = P::dict["delay"] = P::dict["advance"] = C::WAIT_COMMAND;
		P::dict["with"] = C::WITH_COMMAND;
		P::dict["construct"] = P::dict["build"] = P::dict["erect"] = C::CONSTRUCT_COMMAND;
		P::dict["attack"] = P::dict["smash"] = P::dict["strike"] = P::dict["bash"] = P::dict["break"] = P::dict["damage"] = P::dict["stab"] = P::dict["slash"] = C::ATTACK_COMMAND;

		// items

		// items -> other
		P::dict["smelter"] = C::SMELTER_ID;
		P::dict["forge"] = C::FORGE_ID;
		P::dict["anvil"] = C::ANVIL_ID;
		P::dict["tree"] = C::TREE_ID;
		P::dict["chest"] = P::dict["crate"] = C::CHEST_ID;

		// items -> materials
		P::dict["stone"] = P::dict["rock"] = C::STONE_ID;
		P::dict["branch"] = P::dict["branches"] = C::BRANCH_ID;
		P::dict["stick"] = C::STICK_ID;
		P::dict["vine"] = C::VINE_ID;
		P::dict["arrow"] = C::ARROW_ID;
		P::dict["arrowhead"] = C::ARROWHEAD_ID;
		P::dict["board"] = P::dict["boards"] = P::dict["plank"] = P::dict["planks"] = C::BOARD_ID;

		// items -> tools
		P::dict["bow"] = C::BOW_ID;
		P::dict["staff"] = C::STAFF_ID;
		P::dict["axe"] = C::AXE_ID;
		P::dict["sword"] = C::SWORD_ID;
		P::dict["hammer"] = C::HAMMER_ID;

		// directions
		P::dict["n"] = P::dict["north"] = C::NORTH;
		P::dict["ne"] = P::dict["northeast"] = C::NORTH_EAST;
		P::dict["e"] = P::dict["east"] = C::EAST;
		P::dict["se"] = P::dict["southeast"] = C::SOUTH_EAST;
		P::dict["s"] = P::dict["south"] = C::SOUTH;
		P::dict["sw"] = P::dict["southwest"] = C::SOUTH_WEST;
		P::dict["w"] = P::dict["west"] = C::WEST;
		P::dict["nw"] = P::dict["northwest"] = C::NORTH_WEST;
		P::dict["u"] = P::dict["up"] = P::dict["upward"] = P::dict["upwards"] = P::dict["upstairs"] = C::UP;
		P::dict["d"] = P::dict["down"] = P::dict["downward"] = P::dict["downwards"] = P::dict["downstairs"] = C::UP;

		// surfaces not already in directions
		P::dict["floor"] = P::dict["ground"] = C::FLOOR;
		P::dict["ceiling"] = C::CEILING;

		// Look Mr. Frodo! A
		P::dict["door"] = C::DOOR;
		P::dict["wall"] = P::dict["surface"] = C::WALL;
	}
}

vector<string> Parse::tokenize(const string & s)
{
	// converts an input string to vector of "engine official" keywords/commands

	cout << "\nDEBUG inside parse.tokenize: "; // debugging

	// convert the space-delimited user input to a vector of strings (one word per string)
	stringstream ss(s);
	const istream_iterator<string> begin(ss);
	vector<string> strings(begin, istream_iterator<string>());

	R::print(strings); // debugging

	for (string & word : strings) // for each word
	{
		// convert the word to lowercase
		R::to_lower_case(word);

		// replace the word with the engine keyword, or C::BAD_COMMAND
		word = (dict.find(word) != dict.end()) ? dict.find(word)->second : C::BAD_COMMAND;
	}

	return strings;
}
<|endoftext|>


<commit_before>/*
    Copyright (C) 2012  Lasath Fernando <kde@lasath.org>

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

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

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "filters.h"

#include <QImageReader>

#include <KProtocolInfo>
#include <KDebug>

UrlFilter::UrlFilter(QObject *parent)
    : AbstractMessageFilter(parent)
{
}

void UrlFilter::filterMessage(Message &info) {
    QString message = info.mainMessagePart();
    //FIXME: make "Urls" into a constant
    QStringList urls = info.property("Urls").toStringList();

    // link detection
    QRegExp link(QLatin1String("\\b(?:(\\w+)://|(www\\.))([^\\s]+)"));
    int fromIndex = 0;

    while ((fromIndex = message.indexOf(link, fromIndex)) != -1) {
        QString realUrl = link.cap(0);
        QString protocol = link.cap(1);

        //if cap(1) is empty cap(2) was matched -> starts with www.
        const bool startsWithWWW = link.cap(1).isEmpty();

        kDebug() << "Found URL " << realUrl << "with protocol : " << (startsWithWWW ? QLatin1String("http") : protocol);

        // if url has a supported protocol
        if (startsWithWWW || KProtocolInfo::protocols().contains(protocol, Qt::CaseInsensitive)) {

            // text not wanted in a link ( <,> )
            QRegExp unwanted(QLatin1String("(<|>)"));

            if (!realUrl.contains(unwanted)) {
                // string to show to user
                QString shownUrl = realUrl;

                // check for newline and cut link when found
                if (realUrl.contains(QLatin1String(("
")))) {
                    int findIndex = realUrl.indexOf(QLatin1String("
"));
                    realUrl.truncate(findIndex);
                    shownUrl.truncate(findIndex);
                }

                // check prefix
                if (startsWithWWW) {
                    realUrl.prepend(QLatin1String("http://"));
                }

                // if the url is changed, show in chat what the user typed in
                QString link = QLatin1String("") + shownUrl + QLatin1String("");

                message.replace(fromIndex, shownUrl.length(), link);
                // advance position otherwise I end up parsing the same link
                fromIndex += link.length();
            } else {
                fromIndex += realUrl.length();
            }

            urls.append(realUrl);
        } else {
            fromIndex += link.matchedLength();
        }
    }

    info.setProperty("Urls", urls);
    info.setMainMessagePart(message);
}

<commit_msg>Credit David for the code stolen from AdiumThemeView<commit_after>/*
    Copyright (C) 2012  Lasath Fernando <kde@lasath.org>
    Copyright (C) 2012  David Edmundson <kde@davidedmundson.co.uk>

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

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

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "filters.h"

#include <QImageReader>

#include <KProtocolInfo>
#include <KDebug>

UrlFilter::UrlFilter(QObject *parent)
    : AbstractMessageFilter(parent)
{
}

void UrlFilter::filterMessage(Message &info) {
    QString message = info.mainMessagePart();
    //FIXME: make "Urls" into a constant
    QStringList urls = info.property("Urls").toStringList();

    // link detection
    QRegExp link(QLatin1String("\\b(?:(\\w+)://|(www\\.))([^\\s]+)"));
    int fromIndex = 0;

    while ((fromIndex = message.indexOf(link, fromIndex)) != -1) {
        QString realUrl = link.cap(0);
        QString protocol = link.cap(1);

        //if cap(1) is empty cap(2) was matched -> starts with www.
        const bool startsWithWWW = link.cap(1).isEmpty();

        kDebug() << "Found URL " << realUrl << "with protocol : " << (startsWithWWW ? QLatin1String("http") : protocol);

        // if url has a supported protocol
        if (startsWithWWW || KProtocolInfo::protocols().contains(protocol, Qt::CaseInsensitive)) {

            // text not wanted in a link ( <,> )
            QRegExp unwanted(QLatin1String("(<|>)"));

            if (!realUrl.contains(unwanted)) {
                // string to show to user
                QString shownUrl = realUrl;

                // check for newline and cut link when found
                if (realUrl.contains(QLatin1String(("
")))) {
                    int findIndex = realUrl.indexOf(QLatin1String("
"));
                    realUrl.truncate(findIndex);
                    shownUrl.truncate(findIndex);
                }

                // check prefix
                if (startsWithWWW) {
                    realUrl.prepend(QLatin1String("http://"));
                }

                // if the url is changed, show in chat what the user typed in
                QString link = QLatin1String("") + shownUrl + QLatin1String("");

                message.replace(fromIndex, shownUrl.length(), link);
                // advance position otherwise I end up parsing the same link
                fromIndex += link.length();
            } else {
                fromIndex += realUrl.length();
            }

            urls.append(realUrl);
        } else {
            fromIndex += link.matchedLength();
        }
    }

    info.setProperty("Urls", urls);
    info.setMainMessagePart(message);
}

<|endoftext|>


<commit_before>#include <Windows.h>
#include <stdio.h>
#include <string>
#include "Label.h"

using namespace std;

int main(VOID) {

	//non touchable cant react tp mouse and keyboard.
	//light green on a black background
	//located in someplace.
	//Label newLabel1 = Label(15, 10, "LABEL 1");
	//newLabel1.draw();
	IController *newLabel2 = new Label(30, 20, "LABEL 2");
	newLabel2->draw();
	getchar();
	return 0;
}<commit_msg>try team vc<commit_after>#include <Windows.h>
#include <stdio.h>
#include <string>
#include "Label.h"

using namespace std;

int main(VOID) {

	//non touchable cant react tp mouse and keyboard.
	//light green on a black background
	//located in someplace.
	//Label newLabel1 = Label(15, 10, "LABEL 1");
	//newLabel1.draw();
	IController *newLabel2 = new Label(30, 20, "LABEL 121212");
	newLabel2->draw();
	getchar();
	return 0;
}<|endoftext|>