<commit_before>// cfiles, an analysis frontend for the Chemfiles library
// Copyright (C) Guillaume Fraux and contributors -- BSD license

#include <docopt/docopt.h>
#include <sstream>
#include <fstream>

#include "DensityProfile.hpp"
#include "Errors.hpp"
#include "utils.hpp"
#include "geometry.hpp"
#include "warnings.hpp"

using namespace chemfiles;

static const char OPTIONS[] =
R"(Compute the density profile of particles along a given axis or radially.
The output for the radial density profile is normalized by r.
Selections for the particles can be specified using the chemfiles selection
language. It is possible to provide an alternative unit cell or topology for the
trajectory file if they are not defined in the trajectory format. The axis can
be specified using a coordinate vector (e.g. z axis would be (0,0,1)).

It is also possible to compute 2D profiles by specifying 2 axis (see --axis and
--radial options). Other options (--points, --max, --min) may accept two values,
one for each axis. If only one is specified, the same value will be used for
both axis (see Examples). The output is a 2D histogram with the first dimension
being the first axis and the second dimension the second axis. If two axis of
the same type are used (e.g. twice --axis option), the order will be the one the
user gave. If the axis types are different (e.g. --axis and --radial), the
--axis will be first. Two axis of type radial are forbidden.

For more information about chemfiles selection language, please see
http://chemfiles.org/chemfiles/latest/selections.html

Usage:
  cfiles density [options] <trajectory> [--axis=<axis>...] [--radial=<axis>...]
  cfiles density (-h | --help)

Examples:
  cfiles density water.xyz --cell 15:15:25 --guess-bonds --axis=1:1:1
  cfiles density in.pdb --selection="x > 3" --points=500
  cfiles density nt.pdb --radial=Z --max=3 --origin=0:0:2
  cfiles density nt.pdb --profile=Z --radial=Z --max=10:5 --origin=0:0:2

Options:
  -h --help                     show this help
  -o <file>, --output=<file>    write result to <file>. This default to the
                                trajectory file name with the `.density.dat`
                                extension.
  --format=<format>             force the input file format to be <format>
  -t <path>, --topology=<path>  alternative topology file for the input
  --topology-format=<format>    use <format> as format for the topology file
  --guess-bonds                 guess the bonds in the input
  -c <cell>, --cell=<cell>      alternative unit cell. <cell> format is one of
                                <a:b:c:α:β:γ> or <a:b:c> or <a>. 'a', 'b' and
                                'c' are in angstroms, 'α', 'β', and 'γ' are in
                                degrees.
  --steps=<steps>               steps to use from the input. <steps> format
                                is <start>:<end>[:<stride>] with <start>, <end>
                                and <stride> optional. The used steps goes from
                                <start> to <end> (excluded) by steps of
                                <stride>. The default values are 0 for <start>,
                                the number of steps for <end> and 1 for
                                <stride>.
  -s <sel>, --selection=<sel>   selection to use for the particles. This must
                                be a selection of size 1. [default: atoms: all]
  --axis=<axis>...              computes a linear density profile along <axis>.
                                It should be either one of 'X','Y','Z'
                                or a vector defining the axis (e.g. 1:1:1).
  --radial=<axis>...            computes a radial density profile using the
                                distance to <axis>.
                                It should be either one of 'X','Y','Z'
                                or a vector defining the axis (e.g. 1:1:1).
  --origin=<coord>              coordinates for the origin of the axis (only
                                relevant for radial profiles). [default: 0:0:0]
  -p <n>, --points=<n>          number of points in the profile [default: 200]
  --max=<max>                   maximum distance in the profile. [default: 10]
  --min=<min>                   minimum distance in the profile. [default: 0]
                                For radial profiles, <min> must be positive.
)";

Averager<double> DensityProfile::setup(int argc, const char* argv[]) {
    auto options_str = command_header("density", DensityProfile().description()) + "\n";
    options_str += "Laura Scalfi <laura.scalfi@ens.fr>\n";
    options_str += OPTIONS;
    auto args = docopt::docopt(options_str, {argv, argv + argc}, true, "");

    AveCommand::parse_options(args);

    options_.selection = args.at("--selection").asString();
    selection_ = Selection(options_.selection);
    if (selection_.size() != 1) {
        throw CFilesError("Can not use a selection with size different than 1.");
    }

    if (args.at("--output")){
        options_.outfile = args.at("--output").asString();
    } else {
        options_.outfile = AveCommand::options().trajectory + ".density.dat";
    }

    if (args.at("--axis")) {
        for (auto axis: args.at("--axis").asStringList()) {
            axis_.push_back(Axis::parse(axis, Axis::Linear));
        }
    }

    if (args.at("--radial")) {
        for (auto axis: args.at("--radial").asStringList()) {
            axis_.push_back(Axis::parse(axis, Axis::Radial));
        }
    }

    size_t dimension = dimensionality();

    if (dimension == 0 or dimension > 2) {
        throw CFilesError("No axis or too many axis were given");
    }

    if (args.at("--points")) {
        auto splitted = split(args.at("--points").asString(),':');
        if (splitted.size() == 1) {
            options_.npoints[0] = string2long(splitted[0]);
            options_.npoints[1] = string2long(splitted[0]);
        } else if (splitted.size() == 2) {
            if (dimension < 2) {
                throw CFilesError("More --points options than axis");
            }
            options_.npoints[0] = string2long(splitted[0]);
            options_.npoints[1] = string2long(splitted[1]);
        } else {
            throw CFilesError("Too many arguments for --points option");
        }
    }

    if (args.at("--origin")) {
        auto splitted = split(args.at("--origin").asString(),':');
        if (splitted.size() != 3) {
            throw CFilesError("Origin for density profile should be a vector of size 3");
        }
        auto a = string2double(splitted[0]);
        auto b = string2double(splitted[1]);
        auto c = string2double(splitted[2]);
        options_.origin = vector3d(a, b, c);
    }

    if (args.at("--max")) {
        auto splitted = split(args.at("--max").asString(),':');
        if (splitted.size() == 1) {
            options_.max[0] = string2double(splitted[0]);
            options_.max[1] = string2double(splitted[0]);
        } else if (splitted.size() == 2) {
            if (dimension < 2) {
                throw CFilesError("More --max options than axis");
            }
            options_.max[0] = string2double(splitted[0]);
            options_.max[1] = string2double(splitted[1]);
        } else {
            throw CFilesError("Too many arguments for --max option");
        }
    }

    if (args.at("--min")) {
         auto splitted = split(args.at("--min").asString(),':');
         if (splitted.size() == 1) {
             options_.min[0] = string2double(splitted[0]);
             options_.min[1] = string2double(splitted[0]);
         } else if (splitted.size() == 2) {
             if (dimension < 2) {
                 throw CFilesError("More --min options than axis");
             }
             options_.min[0] = string2double(splitted[0]);
             options_.min[1] = string2double(splitted[1]);
         } else {
             throw CFilesError("Too many arguments for --min option");
         }
    }

    if (options_.min[0] > options_.max[0]) {
        throw CFilesError("Min > Max for first dimension");
    }

    if (options_.min[1] > options_.max[1]) {
        throw CFilesError("Min > Max for second dimension");
    }

    if (dimension == 1) {
        if (axis_[0].is_radial()) {
            if (options_.min[0] < 0) {
                throw CFilesError("Min value for radial axis should be positive");
            }
        }
        return Averager<double>(options_.npoints[0], options_.min[0], options_.max[0]);
    } else {
        assert(dimension == 2);
        if (axis_[0].is_radial()) {
            if (options_.min[1] < 0) {
                throw CFilesError("Min value for radial axis should be positive");
            }
        }
        return Averager<double>(options_.npoints[0], options_.min[0], options_.max[0], options_.npoints[1], options_.min[1], options_.max[1]);
    }
}

std::string DensityProfile::description() const {
    return "compute density profiles";
}

void DensityProfile::accumulate(const chemfiles::Frame& frame, Histogram<double>& profile) {
    auto positions = frame.positions();
    auto cell = frame.cell();

    assert(selection_.size() == 1);
    for (auto i: selection_.list(frame)) {
        double x = 0;
        double y = 0;
        if (axis_[0].is_linear()) {
            x = axis_[0].projection(cell.wrap(positions[i]));
        } else {
            assert(axis_[0].is_radial());
            x = axis_[0].projection(cell.wrap(positions[i] - options_.origin));
        }
        if (dimensionality() == 2) {
            if (axis_[1].is_linear()) {
                y = axis_[1].projection(cell.wrap(positions[i]));
            } else {
                assert(axis_[1].is_radial());
                y = axis_[1].projection(cell.wrap(positions[i] - options_.origin));
            }
        }
        try {
            if (dimensionality() == 1) {
                profile.insert(x);
            } else {
                profile.insert(x,y);
            }
        } catch (const OutOfBoundsError& e) {
            warn_once(e.what());
        }
    }
}

void DensityProfile::finish(const Histogram<double>& profile) {
    std::ofstream outfile(options_.outfile, std::ios::out);
    if (outfile.is_open()) {
        outfile << "# Density profile in trajectory " << AveCommand::options().trajectory << std::endl;
        outfile << "# along axis " << axis_[0].str() << std::endl;
        if (dimensionality() == 2) {
            outfile << "# and along axis " << axis_[1].str() << std::endl;
        }
        outfile << "# Selection: " << options_.selection << std::endl;

        if (dimensionality() == 1) {
            for (size_t i = 0; i < profile.size(); i++){
                if (axis_[0].is_linear()) {
                    outfile << profile.first_coord(i) << "  " << profile[i] << "\n";
                } else {
                    assert(axis_[0].is_radial());
                    outfile << profile.first_coord(i) << "  " << profile[i] / profile.first_coord(i) << "\n";
                }
            }
        } else {
            outfile << "# FirstDimension SecondDimension Density" << std::endl;

            for (size_t i = 0; i < profile.first().nbins; i++){
                for (size_t j = 0; j < profile.second().nbins; j++){
                    outfile << profile.first_coord(i) << "\t" << profile.second_coord(j) << "\t";
                    if (axis_[0].is_linear() and axis_[1].is_linear()) {
                        outfile << profile(i,j) << "\n";
                    } else {
                        assert(axis_[0].is_linear() and axis_[1].is_radial());
                        outfile << profile(i,j) / profile.second_coord(j) << "\n";
                    }
                }
            }
        }
    } else {
        throw CFilesError("Could not open the '" + options_.outfile + "' file.");
    }
}
<commit_msg>Add a warning for no matching atoms in density<commit_after>// cfiles, an analysis frontend for the Chemfiles library
// Copyright (C) Guillaume Fraux and contributors -- BSD license

#include <docopt/docopt.h>
#include <sstream>
#include <fstream>

#include "DensityProfile.hpp"
#include "Errors.hpp"
#include "utils.hpp"
#include "geometry.hpp"
#include "warnings.hpp"

using namespace chemfiles;

static const char OPTIONS[] =
R"(Compute the density profile of particles along a given axis or radially.
The output for the radial density profile is normalized by r.
Selections for the particles can be specified using the chemfiles selection
language. It is possible to provide an alternative unit cell or topology for the
trajectory file if they are not defined in the trajectory format. The axis can
be specified using a coordinate vector (e.g. z axis would be (0,0,1)).

It is also possible to compute 2D profiles by specifying 2 axis (see --axis and
--radial options). Other options (--points, --max, --min) may accept two values,
one for each axis. If only one is specified, the same value will be used for
both axis (see Examples). The output is a 2D histogram with the first dimension
being the first axis and the second dimension the second axis. If two axis of
the same type are used (e.g. twice --axis option), the order will be the one the
user gave. If the axis types are different (e.g. --axis and --radial), the
--axis will be first. Two axis of type radial are forbidden.

For more information about chemfiles selection language, please see
http://chemfiles.org/chemfiles/latest/selections.html

Usage:
  cfiles density [options] <trajectory> [--axis=<axis>...] [--radial=<axis>...]
  cfiles density (-h | --help)

Examples:
  cfiles density water.xyz --cell 15:15:25 --guess-bonds --axis=1:1:1
  cfiles density in.pdb --selection="x > 3" --points=500
  cfiles density nt.pdb --radial=Z --max=3 --origin=0:0:2
  cfiles density nt.pdb --profile=Z --radial=Z --max=10:5 --origin=0:0:2

Options:
  -h --help                     show this help
  -o <file>, --output=<file>    write result to <file>. This default to the
                                trajectory file name with the `.density.dat`
                                extension.
  --format=<format>             force the input file format to be <format>
  -t <path>, --topology=<path>  alternative topology file for the input
  --topology-format=<format>    use <format> as format for the topology file
  --guess-bonds                 guess the bonds in the input
  -c <cell>, --cell=<cell>      alternative unit cell. <cell> format is one of
                                <a:b:c:α:β:γ> or <a:b:c> or <a>. 'a', 'b' and
                                'c' are in angstroms, 'α', 'β', and 'γ' are in
                                degrees.
  --steps=<steps>               steps to use from the input. <steps> format
                                is <start>:<end>[:<stride>] with <start>, <end>
                                and <stride> optional. The used steps goes from
                                <start> to <end> (excluded) by steps of
                                <stride>. The default values are 0 for <start>,
                                the number of steps for <end> and 1 for
                                <stride>.
  -s <sel>, --selection=<sel>   selection to use for the particles. This must
                                be a selection of size 1. [default: atoms: all]
  --axis=<axis>...              computes a linear density profile along <axis>.
                                It should be either one of 'X','Y','Z'
                                or a vector defining the axis (e.g. 1:1:1).
  --radial=<axis>...            computes a radial density profile using the
                                distance to <axis>.
                                It should be either one of 'X','Y','Z'
                                or a vector defining the axis (e.g. 1:1:1).
  --origin=<coord>              coordinates for the origin of the axis (only
                                relevant for radial profiles). [default: 0:0:0]
  -p <n>, --points=<n>          number of points in the profile [default: 200]
  --max=<max>                   maximum distance in the profile. [default: 10]
  --min=<min>                   minimum distance in the profile. [default: 0]
                                For radial profiles, <min> must be positive.
)";

Averager<double> DensityProfile::setup(int argc, const char* argv[]) {
    auto options_str = command_header("density", DensityProfile().description()) + "\n";
    options_str += "Laura Scalfi <laura.scalfi@ens.fr>\n";
    options_str += OPTIONS;
    auto args = docopt::docopt(options_str, {argv, argv + argc}, true, "");

    AveCommand::parse_options(args);

    options_.selection = args.at("--selection").asString();
    selection_ = Selection(options_.selection);
    if (selection_.size() != 1) {
        throw CFilesError("Can not use a selection with size different than 1.");
    }

    if (args.at("--output")){
        options_.outfile = args.at("--output").asString();
    } else {
        options_.outfile = AveCommand::options().trajectory + ".density.dat";
    }

    if (args.at("--axis")) {
        for (auto axis: args.at("--axis").asStringList()) {
            axis_.push_back(Axis::parse(axis, Axis::Linear));
        }
    }

    if (args.at("--radial")) {
        for (auto axis: args.at("--radial").asStringList()) {
            axis_.push_back(Axis::parse(axis, Axis::Radial));
        }
    }

    size_t dimension = dimensionality();

    if (dimension == 0 or dimension > 2) {
        throw CFilesError("No axis or too many axis were given");
    }

    if (args.at("--points")) {
        auto splitted = split(args.at("--points").asString(),':');
        if (splitted.size() == 1) {
            options_.npoints[0] = string2long(splitted[0]);
            options_.npoints[1] = string2long(splitted[0]);
        } else if (splitted.size() == 2) {
            if (dimension < 2) {
                throw CFilesError("More --points options than axis");
            }
            options_.npoints[0] = string2long(splitted[0]);
            options_.npoints[1] = string2long(splitted[1]);
        } else {
            throw CFilesError("Too many arguments for --points option");
        }
    }

    if (args.at("--origin")) {
        auto splitted = split(args.at("--origin").asString(),':');
        if (splitted.size() != 3) {
            throw CFilesError("Origin for density profile should be a vector of size 3");
        }
        auto a = string2double(splitted[0]);
        auto b = string2double(splitted[1]);
        auto c = string2double(splitted[2]);
        options_.origin = vector3d(a, b, c);
    }

    if (args.at("--max")) {
        auto splitted = split(args.at("--max").asString(),':');
        if (splitted.size() == 1) {
            options_.max[0] = string2double(splitted[0]);
            options_.max[1] = string2double(splitted[0]);
        } else if (splitted.size() == 2) {
            if (dimension < 2) {
                throw CFilesError("More --max options than axis");
            }
            options_.max[0] = string2double(splitted[0]);
            options_.max[1] = string2double(splitted[1]);
        } else {
            throw CFilesError("Too many arguments for --max option");
        }
    }

    if (args.at("--min")) {
         auto splitted = split(args.at("--min").asString(),':');
         if (splitted.size() == 1) {
             options_.min[0] = string2double(splitted[0]);
             options_.min[1] = string2double(splitted[0]);
         } else if (splitted.size() == 2) {
             if (dimension < 2) {
                 throw CFilesError("More --min options than axis");
             }
             options_.min[0] = string2double(splitted[0]);
             options_.min[1] = string2double(splitted[1]);
         } else {
             throw CFilesError("Too many arguments for --min option");
         }
    }

    if (options_.min[0] > options_.max[0]) {
        throw CFilesError("Min > Max for first dimension");
    }

    if (options_.min[1] > options_.max[1]) {
        throw CFilesError("Min > Max for second dimension");
    }

    if (dimension == 1) {
        if (axis_[0].is_radial()) {
            if (options_.min[0] < 0) {
                throw CFilesError("Min value for radial axis should be positive");
            }
        }
        return Averager<double>(options_.npoints[0], options_.min[0], options_.max[0]);
    } else {
        assert(dimension == 2);
        if (axis_[0].is_radial()) {
            if (options_.min[1] < 0) {
                throw CFilesError("Min value for radial axis should be positive");
            }
        }
        return Averager<double>(options_.npoints[0], options_.min[0], options_.max[0], options_.npoints[1], options_.min[1], options_.max[1]);
    }
}

std::string DensityProfile::description() const {
    return "compute density profiles";
}

void DensityProfile::accumulate(const chemfiles::Frame& frame, Histogram<double>& profile) {
    auto positions = frame.positions();
    auto cell = frame.cell();

    assert(selection_.size() == 1);
    auto selected = selection_.list(frame);
    if (selected.empty()) {
        warn(
            "No matching atom for selection '" + selection_.string() +
            "' at step " + std::to_string(frame.step())
        );
    }

    for (auto i: selected) {
        double x = 0;
        double y = 0;
        if (axis_[0].is_linear()) {
            x = axis_[0].projection(cell.wrap(positions[i]));
        } else {
            assert(axis_[0].is_radial());
            x = axis_[0].projection(cell.wrap(positions[i] - options_.origin));
        }
        if (dimensionality() == 2) {
            if (axis_[1].is_linear()) {
                y = axis_[1].projection(cell.wrap(positions[i]));
            } else {
                assert(axis_[1].is_radial());
                y = axis_[1].projection(cell.wrap(positions[i] - options_.origin));
            }
        }
        try {
            if (dimensionality() == 1) {
                profile.insert(x);
            } else {
                profile.insert(x,y);
            }
        } catch (const OutOfBoundsError& e) {
            warn_once(e.what());
        }
    }
}

void DensityProfile::finish(const Histogram<double>& profile) {
    std::ofstream outfile(options_.outfile, std::ios::out);
    if (outfile.is_open()) {
        outfile << "# Density profile in trajectory " << AveCommand::options().trajectory << std::endl;
        outfile << "# along axis " << axis_[0].str() << std::endl;
        if (dimensionality() == 2) {
            outfile << "# and along axis " << axis_[1].str() << std::endl;
        }
        outfile << "# Selection: " << options_.selection << std::endl;

        if (dimensionality() == 1) {
            for (size_t i = 0; i < profile.size(); i++){
                if (axis_[0].is_linear()) {
                    outfile << profile.first_coord(i) << "  " << profile[i] << "\n";
                } else {
                    assert(axis_[0].is_radial());
                    outfile << profile.first_coord(i) << "  " << profile[i] / profile.first_coord(i) << "\n";
                }
            }
        } else {
            outfile << "# FirstDimension SecondDimension Density" << std::endl;

            for (size_t i = 0; i < profile.first().nbins; i++){
                for (size_t j = 0; j < profile.second().nbins; j++){
                    outfile << profile.first_coord(i) << "\t" << profile.second_coord(j) << "\t";
                    if (axis_[0].is_linear() and axis_[1].is_linear()) {
                        outfile << profile(i,j) << "\n";
                    } else {
                        assert(axis_[0].is_linear() and axis_[1].is_radial());
                        outfile << profile(i,j) / profile.second_coord(j) << "\n";
                    }
                }
            }
        }
    } else {
        throw CFilesError("Could not open the '" + options_.outfile + "' file.");
    }
}
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2006 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifdef _MSC_VER
#pragma warning(4: 4786)
#endif

/* interface header */
#include "TextChunkManager.h"

/* system implementation headers */
#include <fstream>

/******************************************************************************/

TextChunk::TextChunk() :
  fileName(""),
  maxLines(-1),
  maxLineLength(-1)
{
  // for the <map>[] operator
}

TextChunk::TextChunk(const std::string& _fileName, int _maxLines, int _maxLineLength)
{
  fileName = _fileName;
  maxLines = _maxLines;
  maxLineLength = _maxLineLength;
  theVector = parse(_maxLines);
  return;
}

TextChunk::TextChunk(const TextChunk& tc)
{
  fileName = tc.fileName;
  theVector = tc.theVector;
  return;
}

#define PARSE_BUFSIZE 4096
StringVector TextChunk::parse(const int _max_lines)
{
  StringVector strings;
  char buffer[PARSE_BUFSIZE] = {0};
  std::ifstream in;
  int long_lines_encountered = 0;
  int maxMsg = maxLineLength < 0 ? PARSE_BUFSIZE : maxLineLength < PARSE_BUFSIZE ? maxLineLength : PARSE_BUFSIZE;

  in.open(fileName.c_str());
  if (!in || !in.is_open()) {
    snprintf(buffer, maxMsg, "WARNING: unable to open %s", fileName.c_str());
    strings.push_back(buffer);
    return strings;
  }

  for(int i = 0; in.good(); i++) {

    // pull a line from the file
    in.getline(buffer, PARSE_BUFSIZE);

    if (in.fail()) {
      snprintf(buffer, maxMsg, "WARNING: there was a problem reading %s", fileName.c_str());
      strings.push_back(buffer);
      break;
    }

    if (strlen(buffer) > (size_t) maxMsg - 1) {
      // line is too long, say something when we're done
      long_lines_encountered++;
    }
    buffer[maxMsg - 1] = '\0';  // terminate/clamp all lines with/to maxLineLength
    strings.push_back(buffer);

    if ((_max_lines > 0) && (i >= _max_lines)) {
      snprintf(buffer, maxMsg, "WARNING: %s has more than %d lines, truncated.", fileName.c_str(), _max_lines);
      strings.push_back(buffer);
      break;
    }

    // was that the last line?
    if (in.eof()) {
      break;
    }
  } // end parsing for loop

  if (long_lines_encountered) {
    // at least one long line was encountered
    snprintf(buffer, maxMsg, "WARNING: truncated %d long line%s from %s (limit of %d characters)", long_lines_encountered, long_lines_encountered == 1? "" : "s", fileName.c_str(), maxMsg - 1);
    strings.push_back(buffer);
  }

  return strings;
}

bool TextChunk::reload()
{
  StringVector newVec = parse(maxLines);
  if (newVec.size() > 0) {
    theVector = newVec;
  }
  return (theVector.size() > 0);
}

size_t TextChunk::size() const
{
  return theVector.size();
}

const StringVector& TextChunk::getVector() const
{
  return theVector;
}

/******************************************************************************/

bool TextChunkManager::parseFile(const std::string &fileName,
				 const std::string &chunkName,
				 const int maxLines,
				 const int maxLineLength)
{
  TextChunk textChunk(fileName, maxLines, maxLineLength);

  if (textChunk.size() <= 0) {
    return false;
  }

  // add a new chunk name if it isn't already listed
  if (theChunks.find(chunkName) == theChunks.end()) {
    chunkNames.push_back(chunkName);
  }

  // add or replace the chunk
  theChunks[chunkName] = textChunk;

  return true;
}

const StringVector* TextChunkManager::getTextChunk(const std::string &chunkName) const
{
  TextChunkMap::const_iterator it;
  it = theChunks.find(chunkName);
  if (it != theChunks.end()){
    return &it->second.getVector();
  } else {
    return NULL;
  }
}

const StringVector& TextChunkManager::getChunkNames() const
{
  return chunkNames;
}

void TextChunkManager::reload()
{
  TextChunkMap::iterator it;
  for (it = theChunks.begin(); it != theChunks.end(); it++) {
    it->second.reload();
  }
  return;
}

/******************************************************************************/

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<commit_msg>consolidate test<commit_after>/* bzflag
 * Copyright (c) 1993 - 2006 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifdef _MSC_VER
#pragma warning(4: 4786)
#endif

/* interface header */
#include "TextChunkManager.h"

/* system implementation headers */
#include <fstream>

/******************************************************************************/

TextChunk::TextChunk() :
  fileName(""),
  maxLines(-1),
  maxLineLength(-1)
{
  // for the <map>[] operator
}

TextChunk::TextChunk(const std::string& _fileName, int _maxLines, int _maxLineLength)
{
  fileName = _fileName;
  maxLines = _maxLines;
  maxLineLength = _maxLineLength;
  theVector = parse(_maxLines);
  return;
}

TextChunk::TextChunk(const TextChunk& tc)
{
  fileName = tc.fileName;
  theVector = tc.theVector;
  return;
}

#define PARSE_BUFSIZE 4096
StringVector TextChunk::parse(const int _max_lines)
{
  StringVector strings;
  char buffer[PARSE_BUFSIZE] = {0};
  std::ifstream in;
  int long_lines_encountered = 0;
  int maxMsg = maxLineLength < 0 ? PARSE_BUFSIZE : maxLineLength < PARSE_BUFSIZE ? maxLineLength : PARSE_BUFSIZE;

  in.open(fileName.c_str());
  if (!in || !in.is_open()) {
    snprintf(buffer, maxMsg, "WARNING: unable to open %s", fileName.c_str());
    strings.push_back(buffer);
    return strings;
  }

  for(int i = 0; in.good() && !in.eof(); i++) {

    // pull a line from the file
    in.getline(buffer, PARSE_BUFSIZE);

    if (in.fail()) {
      snprintf(buffer, maxMsg, "WARNING: there was a problem reading %s", fileName.c_str());
      strings.push_back(buffer);
      break;
    }

    if (strlen(buffer) > (size_t) maxMsg - 1) {
      // line is too long, say something when we're done
      long_lines_encountered++;
    }
    buffer[maxMsg - 1] = '\0';  // terminate/clamp all lines with/to maxLineLength
    strings.push_back(buffer);

    if ((_max_lines > 0) && (i >= _max_lines)) {
      snprintf(buffer, maxMsg, "WARNING: %s has more than %d lines, truncated.", fileName.c_str(), _max_lines);
      strings.push_back(buffer);
      break;
    }
  } // end parsing for loop

  if (long_lines_encountered) {
    // at least one long line was encountered
    snprintf(buffer, maxMsg, "WARNING: truncated %d long line%s from %s (limit of %d characters)", long_lines_encountered, long_lines_encountered == 1? "" : "s", fileName.c_str(), maxMsg - 1);
    strings.push_back(buffer);
  }

  return strings;
}

bool TextChunk::reload()
{
  StringVector newVec = parse(maxLines);
  if (newVec.size() > 0) {
    theVector = newVec;
  }
  return (theVector.size() > 0);
}

size_t TextChunk::size() const
{
  return theVector.size();
}

const StringVector& TextChunk::getVector() const
{
  return theVector;
}

/******************************************************************************/

bool TextChunkManager::parseFile(const std::string &fileName,
				 const std::string &chunkName,
				 const int maxLines,
				 const int maxLineLength)
{
  TextChunk textChunk(fileName, maxLines, maxLineLength);

  if (textChunk.size() <= 0) {
    return false;
  }

  // add a new chunk name if it isn't already listed
  if (theChunks.find(chunkName) == theChunks.end()) {
    chunkNames.push_back(chunkName);
  }

  // add or replace the chunk
  theChunks[chunkName] = textChunk;

  return true;
}

const StringVector* TextChunkManager::getTextChunk(const std::string &chunkName) const
{
  TextChunkMap::const_iterator it;
  it = theChunks.find(chunkName);
  if (it != theChunks.end()){
    return &it->second.getVector();
  } else {
    return NULL;
  }
}

const StringVector& TextChunkManager::getChunkNames() const
{
  return chunkNames;
}

void TextChunkManager::reload()
{
  TextChunkMap::iterator it;
  for (it = theChunks.begin(); it != theChunks.end(); it++) {
    it->second.reload();
  }
  return;
}

/******************************************************************************/

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<|endoftext|>


<commit_before>#include <iostream>
#include "../sources/table.h"
#include "../sources/columnStoreTable.h"
#include "../sources/rowStoreTable.h"

/* time tracking */

template<typename TimeT = std::chrono::high_resolution_clock>
struct measure
{
    template<typename F, typename ...Args>
    static typename TimeT::rep execution(F func, Args&&... args, int executionTimes)
    {
        auto start = TimeT::now();

		for(auto i = 0; i < executionTimes; ++i)
		{
        	func(std::forward<Args>(args)...);
		}

        auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(TimeT::now() - start).count();
        return duration / executionTimes;
    }
};

/* test methods */

void test_create_column_table(){
	std::cout << "create column table... " << std::endl;
	uint32_t distinct20 [20] = { 14, 16, 15, 8, 14, 13, 12, 11, 1, 13, 17, 17, 12, 3, 16, 6, 17, 20, 3, 13  };

	ColumnStoreTable t = ColumnStoreTable(100, 20);
	t.generateData(20, distinct20);
}

void test_create_row_table(){
	std::cout << "create row table... " << std::endl;
	uint32_t distinct20 [20] = { 14, 16, 15, 8, 14, 13, 12, 11, 1, 13, 17, 17, 12, 3, 16, 6, 17, 20, 3, 13  };

	RowStoreTable t = RowStoreTable(100, 20);
	t.generateData(20, distinct20);
}

int main(int argc, char const * argv[])
{
	/* week 1 tests */
	// data creation sample
	test_create_column_table();
	test_create_row_table();
	// time measuring sample
	std::cout << "create column table: " << std::endl << measure<>::execution(test_create_column_table, 10) << " ns" << std::endl;
	std::cout << "create row table: " << std::endl << measure<>::execution(test_create_row_table, 10) << " ns" << std::endl;

}
<commit_msg>use class structure for timer<commit_after>#include <iostream>
#include "../sources/table.h"
#include "../sources/columnStoreTable.h"
#include "../sources/rowStoreTable.h"

/* time tracking */

template<typename TimeT = std::chrono::nanoseconds, typename ClockT = std::chrono::high_resolution_clock>
class TimeTimer
{
public:
	TimeTimer(int executionTimes)
	: m_executionTimes(executionTimes)
	{

	}

 template<typename F, typename ...Args>
    typename TimeT::rep measure(F func, Args&&... args)
    {
		std::cout << "run " << func << " for " << m_executionTimes << " times..." << std::endl;

		auto start = ClockT::now();

		for(auto i = 0; i < m_executionTimes; ++i)
		{
        	func(std::forward<Args>(args)...);
		}

        auto duration = std::chrono::duration_cast<TimeT>(ClockT::now() - start).count();

        return duration / m_executionTimes;
    }

private:
	int m_executionTimes;

};

/* test methods */

void test_create_column_table(){
	std::cout << "create column table... " << std::endl;
	uint32_t distinct20 [20] = { 14, 16, 15, 8, 14, 13, 12, 11, 1, 13, 17, 17, 12, 3, 16, 6, 17, 20, 3, 13  };

	ColumnStoreTable t = ColumnStoreTable(100, 20);
	t.generateData(20, distinct20);
}

void test_create_row_table(){
	std::cout << "create row table... " << std::endl;
	uint32_t distinct20 [20] = { 14, 16, 15, 8, 14, 13, 12, 11, 1, 13, 17, 17, 12, 3, 16, 6, 17, 20, 3, 13  };

	RowStoreTable t = RowStoreTable(100, 20);
	t.generateData(20, distinct20);
}

int main(int argc, char const * argv[])
{
	/* week 1 tests */
	// data creation sample
	test_create_column_table();
	test_create_row_table();
	// time measuring sample
	TimeTimer<> timer = TimeTimer<>(10);
	std::cout << std::endl << timer.measure(test_create_column_table) << " ns average time per call" << std::endl;
	std::cout << std::endl << timer.measure(test_create_row_table) << " ns average time per call" << std::endl;

}
<|endoftext|>


<commit_before>/*  This file is part of the Vc library.

    Copyright (C) 2009-2012 Matthias Kretz <kretz@kde.org>

    Vc 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 3 of
    the License, or (at your option) any later version.

    Vc 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 Vc.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <Vc/Vc>
#include "unittest.h"
#include <iostream>
#include "vectormemoryhelper.h"

using namespace Vc;

template<typename Vec> void testSort()
{
    typedef typename Vec::EntryType EntryType;
    typedef typename Vec::IndexType IndexType;

    typename Vec::Memory _a;
    const IndexType _ref(IndexesFromZero);
    Vec ref(_ref);
    Vec a;
    int maxPerm = 1;
    for (int x = Vec::Size; x > 0; --x) {
        maxPerm *= x;
    }
    for (int perm = 0; perm < maxPerm; ++perm) {
        int rest = perm;
        for (int i = 0; i < Vec::Size; ++i) {
            _a[i] = 0;
            for (int j = 0; j < i; ++j) {
                if (_a[i] == _a[j]) {
                    ++_a[i];
                    j = -1;
                }
            }
            _a[i] += rest % (Vec::Size - i);
            rest /= (Vec::Size - i);
            for (int j = 0; j < i; ++j) {
                if (_a[i] == _a[j]) {
                    ++_a[i];
                    j = -1;
                }
            }
        }
        a.load(_a);
        //std::cout << a << a.sorted() << std::endl;
        COMPARE(ref, a.sorted()) << ", a: " << a;
    }
}

template<typename T, typename Mem> struct Foo
{
    Foo() : i(0) {}
    void reset() { i = 0; }
    void operator()(T v) { d[i++] = v; }
    Mem d;
    int i;
};

template<typename V> void testCall()
{
    typedef typename V::EntryType T;
    typedef typename V::IndexType I;
    typedef typename V::Mask M;
    typedef typename I::Mask MI;
    const I _indexes(IndexesFromZero);
    const MI _odd = (_indexes & I(One)) > 0;
    const M odd(_odd);
    V a(_indexes);
    Foo<T, typename V::Memory> f;
    a.callWithValuesSorted(f);
    V b(f.d);
    COMPARE(b, a);

    f.reset();
    a(odd) -= 1;
    a.callWithValuesSorted(f);
    V c(f.d);
    for (int i = 0; i < V::Size / 2; ++i) {
        COMPARE(a[i * 2], c[i]);
    }
    for (int i = V::Size / 2; i < V::Size; ++i) {
        COMPARE(b[i], c[i]);
    }
}

template<typename V> void testForeachBit()
{
    typedef typename V::EntryType T;
    typedef typename V::IndexType I;
    typedef typename V::Mask M;
    typedef typename I::Mask MI;
    const I indexes(IndexesFromZero);
    for_all_masks(V, mask) {
        V tmp = V::Zero();
        foreach_bit(int j, mask) {
            tmp[j] = T(1);
        }
        COMPARE(tmp == V::One(), mask);

        int count = 0;
        foreach_bit(int j, mask) {
            ++count;
            if (j >= 0) {
                continue;
            }
        }
        COMPARE(count, mask.count());

        count = 0;
        foreach_bit(int j, mask) {
            if (j >= 0) {
                break;
            }
            ++count;
        }
        COMPARE(count, 0);
    }
}

template<typename V> void copySign()
{
    typedef typename V::EntryType T;
    V v(One);
    V positive(One);
    V negative = -positive;
    COMPARE(v, v.copySign(positive));
    COMPARE(-v, v.copySign(negative));
}

#ifdef VC_MSVC
void bzero(void *p, size_t n) { memset(p, 0, n); }
#else
#include <strings.h>
#endif

template<typename V> void Random()
{
    typedef typename V::EntryType T;
    enum {
        NBits = 3,
        NBins = 1 << NBits,                        // short int
        TotalBits = sizeof(T) * 8,                 //    16  32
        RightShift = TotalBits - NBits,            //    13  29
        NHistograms = TotalBits - NBits + 1,       //    14  30
        LeftShift = (RightShift + 1) / NHistograms,//     1   1
        Mean = 135791,
        MinGood = Mean - Mean/10,
        MaxGood = Mean + Mean/10
    };
    const V mask((1 << NBits) - 1);
    int histogram[NHistograms][NBins];
    bzero(&histogram[0][0], sizeof(histogram));
    for (size_t i = 0; i < NBins * Mean / V::Size; ++i) {
        const V rand = V::Random();
        for (size_t hist = 0; hist < NHistograms; ++hist) {
            const V bin = ((rand << (hist * LeftShift)) >> RightShift) & mask;
            for (size_t k = 0; k < V::Size; ++k) {
                ++histogram[hist][bin[k]];
            }
        }
    }
//#define PRINT_RANDOM_HISTOGRAM
#ifdef PRINT_RANDOM_HISTOGRAM
    for (size_t hist = 0; hist < NHistograms; ++hist) {
        std::cout << "histogram[" << std::setw(2) << hist << "]: ";
        for (size_t bin = 0; bin < NBins; ++bin) {
            std::cout << std::setw(3) << (histogram[hist][bin] - Mean) * 1000 / Mean << "|";
        }
        std::cout << std::endl;
    }
#endif
    for (size_t hist = 0; hist < NHistograms; ++hist) {
        for (size_t bin = 0; bin < NBins; ++bin) {
            VERIFY(histogram[hist][bin] > MinGood)
                << " bin = " << bin << " is " << histogram[0][bin];
            VERIFY(histogram[hist][bin] < MaxGood)
                << " bin = " << bin << " is " << histogram[0][bin];
        }
    }
}

template<typename V, typename I> void FloatRandom()
{
    typedef typename V::EntryType T;
    enum {
        NBins = 64,
        NHistograms = 1,
        Mean = 135791,
        MinGood = Mean - Mean/10,
        MaxGood = Mean + Mean/10
    };
    int histogram[NHistograms][NBins];
    bzero(&histogram[0][0], sizeof(histogram));
    for (size_t i = 0; i < NBins * Mean / V::Size; ++i) {
        const V rand = V::Random();
        const I bin = static_cast<I>(rand * T(NBins));
        for (size_t k = 0; k < V::Size; ++k) {
            ++histogram[0][bin[k]];
        }
    }
#ifdef PRINT_RANDOM_HISTOGRAM
    for (size_t hist = 0; hist < NHistograms; ++hist) {
        std::cout << "histogram[" << std::setw(2) << hist << "]: ";
        for (size_t bin = 0; bin < NBins; ++bin) {
            std::cout << std::setw(3) << (histogram[hist][bin] - Mean) * 1000 / Mean << "|";
        }
        std::cout << std::endl;
    }
#endif
    for (size_t hist = 0; hist < NHistograms; ++hist) {
        for (size_t bin = 0; bin < NBins; ++bin) {
            VERIFY(histogram[hist][bin] > MinGood)
                << " bin = " << bin << " is " << histogram[0][bin];
            VERIFY(histogram[hist][bin] < MaxGood)
                << " bin = " << bin << " is " << histogram[0][bin];
        }
    }
}

template<> void Random<float_v>() { FloatRandom<float_v, int_v>(); }
template<> void Random<double_v>() { FloatRandom<double_v, int_v>(); }
template<> void Random<sfloat_v>() { FloatRandom<sfloat_v, short_v>(); }

template<typename T> T add2(T x) { return x + T(2); }

template<typename T, typename V>
class CallTester
{
    public:
        CallTester() : v(Vc::Zero), i(0) {}

        void operator()(T x) {
            v[i] = x;
            ++i;
        }

        void reset() { v.setZero(); i = 0; }

        int callCount() const { return i; }
        V callValues() const { return v; }

    private:
        V v;
        int i;
};

#if __cplusplus >= 201103 && (!defined(VC_CLANG) || VC_CLANG > 0x30000)
#define DO_LAMBDA_TESTS 1
#endif

template<typename V>
void applyAndCall()
{
    typedef typename V::EntryType T;

    const V two(T(2));
    for (int i = 0; i < 1000; ++i) {
        const V rand = V::Random();
        COMPARE(rand.apply(add2<T>), rand + two);
#ifdef DO_LAMBDA_TESTS
        COMPARE(rand.apply([](T x) { return x + T(2); }), rand + two);
#endif

        CallTester<T, V> callTester;
        rand.call(callTester);
        COMPARE(callTester.callCount(), int(V::Size));
        COMPARE(callTester.callValues(), rand);

        for_all_masks(V, mask) {
            V copy1 = rand;
            V copy2 = rand;
            copy1(mask) += two;

            COMPARE(copy2(mask).apply(add2<T>), copy1) << mask;
            COMPARE(rand.apply(add2<T>, mask), copy1) << mask;
#ifdef DO_LAMBDA_TESTS
            COMPARE(copy2(mask).apply([](T x) { return x + T(2); }), copy1) << mask;
            COMPARE(rand.apply([](T x) { return x + T(2); }, mask), copy1) << mask;
#endif

            callTester.reset();
            copy2(mask).call(callTester);
            COMPARE(callTester.callCount(), mask.count());

            callTester.reset();
            rand.call(callTester, mask);
            COMPARE(callTester.callCount(), mask.count());
        }
    }
}

template<typename T, int value> T returnConstant() { return T(value); }
template<typename T, int value> T returnConstantOffset(int i) { return T(value) + T(i); }
template<typename T, int value> T returnConstantOffset2(unsigned short i) { return T(value) + T(i); }

template<typename V> void fill()
{
    typedef typename V::EntryType T;
    typedef typename V::IndexType I;
    V test = V::Random();
    test.fill(returnConstant<T, 2>);
    COMPARE(test, V(T(2)));

    test = V::Random();
    test.fill(returnConstantOffset<T, 0>);
    COMPARE(test, static_cast<V>(I::IndexesFromZero()));

    test = V::Random();
    test.fill(returnConstantOffset2<T, 0>);
    COMPARE(test, static_cast<V>(I::IndexesFromZero()));
}

int main()
{
    runTest(testCall<int_v>);
    runTest(testCall<uint_v>);
    runTest(testCall<short_v>);
    runTest(testCall<ushort_v>);
    runTest(testCall<float_v>);
    runTest(testCall<sfloat_v>);
    runTest(testCall<double_v>);

    runTest(testForeachBit<int_v>);
    runTest(testForeachBit<uint_v>);
    runTest(testForeachBit<short_v>);
    runTest(testForeachBit<ushort_v>);
    runTest(testForeachBit<float_v>);
    runTest(testForeachBit<sfloat_v>);
    runTest(testForeachBit<double_v>);

    runTest(testSort<int_v>);
    runTest(testSort<uint_v>);
    runTest(testSort<float_v>);
    runTest(testSort<double_v>);
    runTest(testSort<sfloat_v>);
    runTest(testSort<short_v>);
    runTest(testSort<ushort_v>);

    runTest(copySign<float_v>);
    runTest(copySign<sfloat_v>);
    runTest(copySign<double_v>);

    testAllTypes(Random);

    testAllTypes(applyAndCall);
    testAllTypes(fill);

    return 0;
}
<commit_msg>shorten test invocations with helper macros<commit_after>/*  This file is part of the Vc library.

    Copyright (C) 2009-2012 Matthias Kretz <kretz@kde.org>

    Vc 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 3 of
    the License, or (at your option) any later version.

    Vc 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 Vc.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <Vc/Vc>
#include "unittest.h"
#include <iostream>
#include "vectormemoryhelper.h"

using namespace Vc;

template<typename Vec> void testSort()
{
    typedef typename Vec::EntryType EntryType;
    typedef typename Vec::IndexType IndexType;

    typename Vec::Memory _a;
    const IndexType _ref(IndexesFromZero);
    Vec ref(_ref);
    Vec a;
    int maxPerm = 1;
    for (int x = Vec::Size; x > 0; --x) {
        maxPerm *= x;
    }
    for (int perm = 0; perm < maxPerm; ++perm) {
        int rest = perm;
        for (int i = 0; i < Vec::Size; ++i) {
            _a[i] = 0;
            for (int j = 0; j < i; ++j) {
                if (_a[i] == _a[j]) {
                    ++_a[i];
                    j = -1;
                }
            }
            _a[i] += rest % (Vec::Size - i);
            rest /= (Vec::Size - i);
            for (int j = 0; j < i; ++j) {
                if (_a[i] == _a[j]) {
                    ++_a[i];
                    j = -1;
                }
            }
        }
        a.load(_a);
        //std::cout << a << a.sorted() << std::endl;
        COMPARE(ref, a.sorted()) << ", a: " << a;
    }
}

template<typename T, typename Mem> struct Foo
{
    Foo() : i(0) {}
    void reset() { i = 0; }
    void operator()(T v) { d[i++] = v; }
    Mem d;
    int i;
};

template<typename V> void testCall()
{
    typedef typename V::EntryType T;
    typedef typename V::IndexType I;
    typedef typename V::Mask M;
    typedef typename I::Mask MI;
    const I _indexes(IndexesFromZero);
    const MI _odd = (_indexes & I(One)) > 0;
    const M odd(_odd);
    V a(_indexes);
    Foo<T, typename V::Memory> f;
    a.callWithValuesSorted(f);
    V b(f.d);
    COMPARE(b, a);

    f.reset();
    a(odd) -= 1;
    a.callWithValuesSorted(f);
    V c(f.d);
    for (int i = 0; i < V::Size / 2; ++i) {
        COMPARE(a[i * 2], c[i]);
    }
    for (int i = V::Size / 2; i < V::Size; ++i) {
        COMPARE(b[i], c[i]);
    }
}

template<typename V> void testForeachBit()
{
    typedef typename V::EntryType T;
    typedef typename V::IndexType I;
    typedef typename V::Mask M;
    typedef typename I::Mask MI;
    const I indexes(IndexesFromZero);
    for_all_masks(V, mask) {
        V tmp = V::Zero();
        foreach_bit(int j, mask) {
            tmp[j] = T(1);
        }
        COMPARE(tmp == V::One(), mask);

        int count = 0;
        foreach_bit(int j, mask) {
            ++count;
            if (j >= 0) {
                continue;
            }
        }
        COMPARE(count, mask.count());

        count = 0;
        foreach_bit(int j, mask) {
            if (j >= 0) {
                break;
            }
            ++count;
        }
        COMPARE(count, 0);
    }
}

template<typename V> void copySign()
{
    typedef typename V::EntryType T;
    V v(One);
    V positive(One);
    V negative = -positive;
    COMPARE(v, v.copySign(positive));
    COMPARE(-v, v.copySign(negative));
}

#ifdef VC_MSVC
void bzero(void *p, size_t n) { memset(p, 0, n); }
#else
#include <strings.h>
#endif

template<typename V> void Random()
{
    typedef typename V::EntryType T;
    enum {
        NBits = 3,
        NBins = 1 << NBits,                        // short int
        TotalBits = sizeof(T) * 8,                 //    16  32
        RightShift = TotalBits - NBits,            //    13  29
        NHistograms = TotalBits - NBits + 1,       //    14  30
        LeftShift = (RightShift + 1) / NHistograms,//     1   1
        Mean = 135791,
        MinGood = Mean - Mean/10,
        MaxGood = Mean + Mean/10
    };
    const V mask((1 << NBits) - 1);
    int histogram[NHistograms][NBins];
    bzero(&histogram[0][0], sizeof(histogram));
    for (size_t i = 0; i < NBins * Mean / V::Size; ++i) {
        const V rand = V::Random();
        for (size_t hist = 0; hist < NHistograms; ++hist) {
            const V bin = ((rand << (hist * LeftShift)) >> RightShift) & mask;
            for (size_t k = 0; k < V::Size; ++k) {
                ++histogram[hist][bin[k]];
            }
        }
    }
//#define PRINT_RANDOM_HISTOGRAM
#ifdef PRINT_RANDOM_HISTOGRAM
    for (size_t hist = 0; hist < NHistograms; ++hist) {
        std::cout << "histogram[" << std::setw(2) << hist << "]: ";
        for (size_t bin = 0; bin < NBins; ++bin) {
            std::cout << std::setw(3) << (histogram[hist][bin] - Mean) * 1000 / Mean << "|";
        }
        std::cout << std::endl;
    }
#endif
    for (size_t hist = 0; hist < NHistograms; ++hist) {
        for (size_t bin = 0; bin < NBins; ++bin) {
            VERIFY(histogram[hist][bin] > MinGood)
                << " bin = " << bin << " is " << histogram[0][bin];
            VERIFY(histogram[hist][bin] < MaxGood)
                << " bin = " << bin << " is " << histogram[0][bin];
        }
    }
}

template<typename V, typename I> void FloatRandom()
{
    typedef typename V::EntryType T;
    enum {
        NBins = 64,
        NHistograms = 1,
        Mean = 135791,
        MinGood = Mean - Mean/10,
        MaxGood = Mean + Mean/10
    };
    int histogram[NHistograms][NBins];
    bzero(&histogram[0][0], sizeof(histogram));
    for (size_t i = 0; i < NBins * Mean / V::Size; ++i) {
        const V rand = V::Random();
        const I bin = static_cast<I>(rand * T(NBins));
        for (size_t k = 0; k < V::Size; ++k) {
            ++histogram[0][bin[k]];
        }
    }
#ifdef PRINT_RANDOM_HISTOGRAM
    for (size_t hist = 0; hist < NHistograms; ++hist) {
        std::cout << "histogram[" << std::setw(2) << hist << "]: ";
        for (size_t bin = 0; bin < NBins; ++bin) {
            std::cout << std::setw(3) << (histogram[hist][bin] - Mean) * 1000 / Mean << "|";
        }
        std::cout << std::endl;
    }
#endif
    for (size_t hist = 0; hist < NHistograms; ++hist) {
        for (size_t bin = 0; bin < NBins; ++bin) {
            VERIFY(histogram[hist][bin] > MinGood)
                << " bin = " << bin << " is " << histogram[0][bin];
            VERIFY(histogram[hist][bin] < MaxGood)
                << " bin = " << bin << " is " << histogram[0][bin];
        }
    }
}

template<> void Random<float_v>() { FloatRandom<float_v, int_v>(); }
template<> void Random<double_v>() { FloatRandom<double_v, int_v>(); }
template<> void Random<sfloat_v>() { FloatRandom<sfloat_v, short_v>(); }

template<typename T> T add2(T x) { return x + T(2); }

template<typename T, typename V>
class CallTester
{
    public:
        CallTester() : v(Vc::Zero), i(0) {}

        void operator()(T x) {
            v[i] = x;
            ++i;
        }

        void reset() { v.setZero(); i = 0; }

        int callCount() const { return i; }
        V callValues() const { return v; }

    private:
        V v;
        int i;
};

#if __cplusplus >= 201103 && (!defined(VC_CLANG) || VC_CLANG > 0x30000)
#define DO_LAMBDA_TESTS 1
#endif

template<typename V>
void applyAndCall()
{
    typedef typename V::EntryType T;

    const V two(T(2));
    for (int i = 0; i < 1000; ++i) {
        const V rand = V::Random();
        COMPARE(rand.apply(add2<T>), rand + two);
#ifdef DO_LAMBDA_TESTS
        COMPARE(rand.apply([](T x) { return x + T(2); }), rand + two);
#endif

        CallTester<T, V> callTester;
        rand.call(callTester);
        COMPARE(callTester.callCount(), int(V::Size));
        COMPARE(callTester.callValues(), rand);

        for_all_masks(V, mask) {
            V copy1 = rand;
            V copy2 = rand;
            copy1(mask) += two;

            COMPARE(copy2(mask).apply(add2<T>), copy1) << mask;
            COMPARE(rand.apply(add2<T>, mask), copy1) << mask;
#ifdef DO_LAMBDA_TESTS
            COMPARE(copy2(mask).apply([](T x) { return x + T(2); }), copy1) << mask;
            COMPARE(rand.apply([](T x) { return x + T(2); }, mask), copy1) << mask;
#endif

            callTester.reset();
            copy2(mask).call(callTester);
            COMPARE(callTester.callCount(), mask.count());

            callTester.reset();
            rand.call(callTester, mask);
            COMPARE(callTester.callCount(), mask.count());
        }
    }
}

template<typename T, int value> T returnConstant() { return T(value); }
template<typename T, int value> T returnConstantOffset(int i) { return T(value) + T(i); }
template<typename T, int value> T returnConstantOffset2(unsigned short i) { return T(value) + T(i); }

template<typename V> void fill()
{
    typedef typename V::EntryType T;
    typedef typename V::IndexType I;
    V test = V::Random();
    test.fill(returnConstant<T, 2>);
    COMPARE(test, V(T(2)));

    test = V::Random();
    test.fill(returnConstantOffset<T, 0>);
    COMPARE(test, static_cast<V>(I::IndexesFromZero()));

    test = V::Random();
    test.fill(returnConstantOffset2<T, 0>);
    COMPARE(test, static_cast<V>(I::IndexesFromZero()));
}

int main()
{
    testAllTypes(testCall);
    testAllTypes(testForeachBit);
    testAllTypes(testSort);
    testRealTypes(copySign);

    testAllTypes(Random);

    testAllTypes(applyAndCall);
    testAllTypes(fill);

    return 0;
}
<|endoftext|>


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

#include "DeviceInterface.h"

#include "BackendLoader.h"
#include "logging.h"

#include <algorithm>
#include <memory>

using namespace tcam;

std::shared_ptr<DeviceInterface> tcam::openDeviceInterface(const DeviceInfo& device)
{

    try
    {
        auto loader = BackendLoader::get_instance();
        return loader->open_device(device);
    }
    catch (const std::runtime_error& err)
    {
        SPDLOG_ERROR("Encountered Error while creating device interface. {}", err.what());
        return nullptr;
    }
    catch (...)
    {
        SPDLOG_ERROR("Caught unhandled exception while opening device.");
    }
    return nullptr;
}

outcome::result<tcam::framerate_info> DeviceInterface::get_framerate_info(const VideoFormat& fmt)
{
    for (auto&& desc : get_available_video_formats())
    {
        if (desc.get_fourcc() == fmt.get_fourcc())
        {
            return tcam::framerate_info { desc.get_framerates(fmt) };
        }
    }
    return tcam::status::FormatInvalid;
}
<commit_msg>Fix empty framerate list on bad format requests<commit_after>/*
 * Copyright 2014 The Imaging Source Europe GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "DeviceInterface.h"

#include "BackendLoader.h"
#include "logging.h"

#include <algorithm>
#include <memory>

using namespace tcam;

std::shared_ptr<DeviceInterface> tcam::openDeviceInterface(const DeviceInfo& device)
{

    try
    {
        auto loader = BackendLoader::get_instance();
        return loader->open_device(device);
    }
    catch (const std::runtime_error& err)
    {
        SPDLOG_ERROR("Encountered Error while creating device interface. {}", err.what());
        return nullptr;
    }
    catch (...)
    {
        SPDLOG_ERROR("Caught unhandled exception while opening device.");
    }
    return nullptr;
}

outcome::result<tcam::framerate_info> DeviceInterface::get_framerate_info(const VideoFormat& fmt)
{
    for (auto&& desc : get_available_video_formats())
    {
        if (desc.get_fourcc() == fmt.get_fourcc())
        {
            auto lst = desc.get_framerates(fmt);
            if (!lst.empty())
            {
                return tcam::framerate_info { lst };
            }
        }
    }
    return tcam::status::FormatInvalid;
}
<|endoftext|>


<commit_before>// FbCommandFactory.cc for Fluxbox Window manager
// Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
//                and Simon Bowden (rathnor at users.sourceforge.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id: FbCommandFactory.cc,v 1.17 2003/09/29 13:01:01 rathnor Exp $

#include "FbCommandFactory.hh"

#include "CurrentWindowCmd.hh"
#include "FbCommands.hh"
#include "Window.hh"
#include "WorkspaceCmd.hh"
#include "fluxbox.hh"
#include "SimpleCommand.hh"
#include "Screen.hh"

#include <sstream>

// autoregister this module to command parser
FbCommandFactory FbCommandFactory::s_autoreg;

FbCommandFactory::FbCommandFactory() {
    // setup commands that we can handle
    const char* commands[] = {
        "arrangewindows",
        "close",
        "detachclient",
        "exec",
        "execcommand",
        "execute",
        "iconfiy",
        "killwindow",
        "leftworkspace",
        "lower",
        "maximize",
        "maximizehorizontal",
        "maximizevertical",
        "maximizewindow",
        "minimize",
        "minimizewindow",
        "move",
        "movedown",
        "moveleft",
        "moveright",
        "movetableft",
        "movetabright",
        "moveup",
        "nextgroup",
        "nexttab",
        "nextwindow",
        "nextworkspace",
        "prevgroup",
        "prevtab",
        "prevwindow",
        "prevworkspace",
        "quit",
        "raise",
        "reconfigure",
        "resize",
        "resizehorizontal",
        "resizevertical",
        "restart",
        "rightworkspace",
        "rootmenu",
        "saverc",
        "sendtoworkspace",
        "setstyle",
        "setworkspacename",
        "shade",
        "shadewindow",
        "showdesktop",
        "stick",
        "stickwindow",
        "toggledecor",
        "workspace",
        "workspacemenu",
        ""
    };

    for (int i=0;; ++i) {
        if (strcmp(commands[i], "") == 0)
            break;
        addCommand(commands[i]);
    }

}

FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
                                                 const std::string &arguments) {
    using namespace FbCommands;
    //
    // WM commands
    //
    if (command == "restart")
        return new RestartFluxboxCmd(arguments);
    else if (command == "reconfigure")
        return new ReconfigureFluxboxCmd();
    else if (command == "setstyle")
        return new SetStyleCmd(arguments);
    else if (command == "saverc")
        return new SaveResources();
    else if (command == "execcommand" || command == "execute" || command == "exec")
        return new ExecuteCmd(arguments); // execute command on key screen
    else if (command == "quit")
        return new FbTk::SimpleCommand<Fluxbox>(*Fluxbox::instance(), &Fluxbox::shutdown);
    //
    // Current focused window commands
    //
    else if (command == "minimizewindow" || command == "minimize" || command == "iconify")
        return new CurrentWindowCmd(&FluxboxWindow::iconify);
    else if (command == "maximizewindow" || command == "maximize")
        return new CurrentWindowCmd(&FluxboxWindow::maximizeFull);
    else if (command == "maximizevertical")
        return new CurrentWindowCmd(&FluxboxWindow::maximizeVertical);
    else if (command == "maximizehorizontal")
        return new CurrentWindowCmd(&FluxboxWindow::maximizeHorizontal);
    else if (command == "resize") {
        std::istringstream is(arguments);
        int dx = 0, dy = 0;
        is >> dx >> dy;
        return new ResizeCmd(dx, dy);
    }
    else if (command == "resizehorizontal")
        return new ResizeCmd(atoi(arguments.c_str()),0);
    else if (command == "resizevertical")
        return new ResizeCmd(0,atoi(arguments.c_str()));
    else if (command == "move") {
        std::istringstream is(arguments);
        int dx = 0, dy = 0;
        is >> dx >> dy;
        return new MoveCmd(dx, dy);
    }
    else if (command == "moveright")
        return new MoveCmd(atoi(arguments.c_str()),0);
    else if (command == "moveleft")
        return new MoveCmd(-atoi(arguments.c_str()),0);
    else if (command == "moveup")
        return new MoveCmd(0,-atoi(arguments.c_str()));
    else if (command == "movedown")
        return new MoveCmd(0,atoi(arguments.c_str()));
    else if (command == "raise")
        return new CurrentWindowCmd(&FluxboxWindow::raise);
    else if (command == "lower")
        return new CurrentWindowCmd(&FluxboxWindow::lower);
    else if (command == "close")
        return new CurrentWindowCmd(&FluxboxWindow::close);
    else if (command == "shade" || command == "shadewindow")
        return new CurrentWindowCmd(&FluxboxWindow::shade);
    else if (command == "stick" || command == "stickwindow")
        return new CurrentWindowCmd(&FluxboxWindow::stick);
    else if (command == "toggledecor")
        return new CurrentWindowCmd(&FluxboxWindow::toggleDecoration);
    else if (command == "sendtoworkspace")
        return new SendToWorkspaceCmd(atoi(arguments.c_str()) - 1); // make 1-indexed to user
    else if (command == "killwindow")
        return new KillWindowCmd();
     else if (command == "nexttab")
        return new CurrentWindowCmd(&FluxboxWindow::nextClient);
    else if (command == "prevtab")
        return new CurrentWindowCmd(&FluxboxWindow::prevClient);
    else if (command == "movetableft")
        return new CurrentWindowCmd(&FluxboxWindow::moveClientLeft);
    else if (command == "movetabright")
        return new CurrentWindowCmd(&FluxboxWindow::moveClientRight);
    else if (command == "detachclient")
        return new CurrentWindowCmd(&FluxboxWindow::detachCurrentClient);
    //
    // Workspace commands
    //
    else if (command == "nextworkspace" && arguments.size() == 0)
        return new NextWorkspaceCmd();
    else if (command == "prevworkspace" && arguments.size() == 0)
        return new PrevWorkspaceCmd();
    else if (command == "rightworkspace")
        return new RightWorkspaceCmd(atoi(arguments.c_str()));
    else if (command == "leftworkspace")
        return new LeftWorkspaceCmd(atoi(arguments.c_str()));
    else if (command == "workspace") {
        int num = 1; // workspaces appear 1-indexed to the user
        if (!arguments.empty())
            num = atoi(arguments.c_str());
        return new JumpToWorkspaceCmd(num-1);
    } else if (command == "nextwindow")
        return new NextWindowCmd(atoi(arguments.c_str()));
    else if (command == "prevwindow")
        return new PrevWindowCmd(atoi(arguments.c_str()));
    else if (command == "nextgroup")
        return new NextWindowCmd(atoi(arguments.c_str()) ^ BScreen::CYCLEGROUPS);
    else if (command == "prevgroup")
        return new PrevWindowCmd(atoi(arguments.c_str()) ^ BScreen::CYCLEGROUPS);
    else if (command == "arrangewindows")
        return new ArrangeWindowsCmd();
    else if (command == "showdesktop")
        return new ShowDesktopCmd();
    else if (command == "rootmenu")
        return new ShowRootMenuCmd();
    else if (command == "workspacemenu")
        return new ShowWorkspaceMenuCmd();
    else if (command == "setworkspacename")
        return new SetWorkspaceNameCmd();
    return 0;
}
<commit_msg>added MacroCmd action, thanks Mathias Gumz<commit_after>// FbCommandFactory.cc for Fluxbox Window manager
// Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
//                and Simon Bowden (rathnor at users.sourceforge.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id: FbCommandFactory.cc,v 1.18 2003/09/29 14:22:07 fluxgen Exp $

#include "FbCommandFactory.hh"

#include "CurrentWindowCmd.hh"
#include "FbCommands.hh"
#include "Window.hh"
#include "WorkspaceCmd.hh"
#include "fluxbox.hh"
#include "SimpleCommand.hh"
#include "Screen.hh"

#include "FbTk/StringUtil.hh"
#include "FbTk/MacroCommand.hh"

#include <string>
#include <sstream>

// autoregister this module to command parser
FbCommandFactory FbCommandFactory::s_autoreg;

FbCommandFactory::FbCommandFactory() {
    // setup commands that we can handle
    const char* commands[] = {
        "arrangewindows",
        "close",
        "detachclient",
        "exec",
        "execcommand",
        "execute",
        "iconfiy",
        "killwindow",
        "leftworkspace",
        "lower",
        "macrocmd",
        "maximize",
        "maximizehorizontal",
        "maximizevertical",
        "maximizewindow",
        "minimize",
        "minimizewindow",
        "move",
        "movedown",
        "moveleft",
        "moveright",
        "movetableft",
        "movetabright",
        "moveup",
        "nextgroup",
        "nexttab",
        "nextwindow",
        "nextworkspace",
        "prevgroup",
        "prevtab",
        "prevwindow",
        "prevworkspace",
        "quit",
        "raise",
        "reconfigure",
        "resize",
        "resizehorizontal",
        "resizevertical",
        "restart",
        "rightworkspace",
        "rootmenu",
        "saverc",
        "sendtoworkspace",
        "setstyle",
        "setworkspacename",
        "shade",
        "shadewindow",
        "showdesktop",
        "stick",
        "stickwindow",
        "toggledecor",
        "workspace",
        "workspacemenu",
        ""
    };

    for (int i=0;; ++i) {
        if (strcmp(commands[i], "") == 0)
            break;
        addCommand(commands[i]);
    }

}

FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
                                                 const std::string &arguments) {
    using namespace FbCommands;
    //
    // WM commands
    //
    if (command == "restart")
        return new RestartFluxboxCmd(arguments);
    else if (command == "reconfigure")
        return new ReconfigureFluxboxCmd();
    else if (command == "setstyle")
        return new SetStyleCmd(arguments);
    else if (command == "saverc")
        return new SaveResources();
    else if (command == "execcommand" || command == "execute" || command == "exec")
        return new ExecuteCmd(arguments); // execute command on key screen
    else if (command == "quit")
        return new FbTk::SimpleCommand<Fluxbox>(*Fluxbox::instance(), &Fluxbox::shutdown);
    //
    // Current focused window commands
    //
    else if (command == "minimizewindow" || command == "minimize" || command == "iconify")
        return new CurrentWindowCmd(&FluxboxWindow::iconify);
    else if (command == "maximizewindow" || command == "maximize")
        return new CurrentWindowCmd(&FluxboxWindow::maximizeFull);
    else if (command == "maximizevertical")
        return new CurrentWindowCmd(&FluxboxWindow::maximizeVertical);
    else if (command == "maximizehorizontal")
        return new CurrentWindowCmd(&FluxboxWindow::maximizeHorizontal);
    else if (command == "resize") {
        std::istringstream is(arguments);
        int dx = 0, dy = 0;
        is >> dx >> dy;
        return new ResizeCmd(dx, dy);
    }
    else if (command == "resizehorizontal")
        return new ResizeCmd(atoi(arguments.c_str()),0);
    else if (command == "resizevertical")
        return new ResizeCmd(0,atoi(arguments.c_str()));
    else if (command == "move") {
        std::istringstream is(arguments);
        int dx = 0, dy = 0;
        is >> dx >> dy;
        return new MoveCmd(dx, dy);
    }
    else if (command == "moveright")
        return new MoveCmd(atoi(arguments.c_str()),0);
    else if (command == "moveleft")
        return new MoveCmd(-atoi(arguments.c_str()),0);
    else if (command == "moveup")
        return new MoveCmd(0,-atoi(arguments.c_str()));
    else if (command == "movedown")
        return new MoveCmd(0,atoi(arguments.c_str()));
    else if (command == "raise")
        return new CurrentWindowCmd(&FluxboxWindow::raise);
    else if (command == "lower")
        return new CurrentWindowCmd(&FluxboxWindow::lower);
    else if (command == "close")
        return new CurrentWindowCmd(&FluxboxWindow::close);
    else if (command == "shade" || command == "shadewindow")
        return new CurrentWindowCmd(&FluxboxWindow::shade);
    else if (command == "stick" || command == "stickwindow")
        return new CurrentWindowCmd(&FluxboxWindow::stick);
    else if (command == "toggledecor")
        return new CurrentWindowCmd(&FluxboxWindow::toggleDecoration);
    else if (command == "sendtoworkspace")
        return new SendToWorkspaceCmd(atoi(arguments.c_str()) - 1); // make 1-indexed to user
    else if (command == "killwindow")
        return new KillWindowCmd();
     else if (command == "nexttab")
        return new CurrentWindowCmd(&FluxboxWindow::nextClient);
    else if (command == "prevtab")
        return new CurrentWindowCmd(&FluxboxWindow::prevClient);
    else if (command == "movetableft")
        return new CurrentWindowCmd(&FluxboxWindow::moveClientLeft);
    else if (command == "movetabright")
        return new CurrentWindowCmd(&FluxboxWindow::moveClientRight);
    else if (command == "detachclient")
        return new CurrentWindowCmd(&FluxboxWindow::detachCurrentClient);
    //
    // Workspace commands
    //
    else if (command == "nextworkspace" && arguments.size() == 0)
        return new NextWorkspaceCmd();
    else if (command == "prevworkspace" && arguments.size() == 0)
        return new PrevWorkspaceCmd();
    else if (command == "rightworkspace")
        return new RightWorkspaceCmd(atoi(arguments.c_str()));
    else if (command == "leftworkspace")
        return new LeftWorkspaceCmd(atoi(arguments.c_str()));
    else if (command == "workspace") {
        int num = 1; // workspaces appear 1-indexed to the user
        if (!arguments.empty())
            num = atoi(arguments.c_str());
        return new JumpToWorkspaceCmd(num-1);
    } else if (command == "nextwindow")
        return new NextWindowCmd(atoi(arguments.c_str()));
    else if (command == "prevwindow")
        return new PrevWindowCmd(atoi(arguments.c_str()));
    else if (command == "nextgroup")
        return new NextWindowCmd(atoi(arguments.c_str()) ^ BScreen::CYCLEGROUPS);
    else if (command == "prevgroup")
        return new PrevWindowCmd(atoi(arguments.c_str()) ^ BScreen::CYCLEGROUPS);
    else if (command == "arrangewindows")
        return new ArrangeWindowsCmd();
    else if (command == "showdesktop")
        return new ShowDesktopCmd();
    else if (command == "rootmenu")
        return new ShowRootMenuCmd();
    else if (command == "workspacemenu")
        return new ShowWorkspaceMenuCmd();
    else if (command == "setworkspacename")
        return new SetWorkspaceNameCmd();
    //
    // special commands
    //
    else if (command == "macrocmd") {
      std::string cmd;
      int   err= 0;
      int   parse_pos= 0;
      FbTk::MacroCommand* macro= new FbTk::MacroCommand();

      while (true) {
        parse_pos+= err;
        err= FbTk::StringUtil::getStringBetween(cmd, arguments.c_str() + parse_pos,
                                              '{', '}', " \t\n", true);
        if ( err > 0 ) {
          std::string c, a;
          std::string::size_type first_pos = FbTk::StringUtil::removeFirstWhitespace(cmd);
          std::string::size_type second_pos= cmd.find_first_of(" \t", first_pos);
          if (second_pos != std::string::npos) {
            a= cmd.substr(second_pos);
            FbTk::StringUtil::removeFirstWhitespace(a);
            cmd.erase(second_pos);
          }
          c= FbTk::StringUtil::toLower(cmd);

          FbTk::Command* fbcmd= stringToCommand(c,a);
          if ( fbcmd ) {
            FbTk::RefCount<FbTk::Command> rfbcmd(fbcmd);
            macro->add(rfbcmd);
          }
        }
        else
          break;
      }

      if ( macro->size() > 0 )
        return macro;

      delete macro;
    }
    return 0;
}
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2012-2013, John Haddon. All rights reserved.
//  Copyright (c) 2013, Image Engine Design 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 John Haddon nor the names of
//        any other contributors to this software 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.
//
//////////////////////////////////////////////////////////////////////////

#include "boost/bind.hpp"

#include "IECore/Camera.h"
#include "IECore/Transform.h"
#include "IECore/AngleConversion.h"
#include "IECore/MatrixTransform.h"

#include "IECoreGL/Primitive.h"

#include "Gaffer/CompoundPlug.h"
#include "Gaffer/NumericPlug.h"
#include "Gaffer/TypedPlug.h"

#include "GafferUI/View3D.h"

using namespace Imath;
using namespace IECoreGL;
using namespace Gaffer;
using namespace GafferUI;

IE_CORE_DEFINERUNTIMETYPED( View3D );

View3D::View3D( const std::string &name, Gaffer::PlugPtr inPlug )
	:	View( name, inPlug ), m_baseState( new IECoreGL::State( true ) )
{

	// base state setup

	m_baseState->add( new WireframeColorStateComponent( Color4f( 0.2f, 0.2f, 0.2f, 1.0f ) ) );
	m_baseState->add( new PointColorStateComponent( Color4f( 0.9f, 0.9f, 0.9f, 1.0f ) ) );
	m_baseState->add( new IECoreGL::Primitive::PointWidth( 2.0f ) );

	// plugs

	CompoundPlugPtr baseState = new CompoundPlug( "baseState" );
	addChild( baseState );

	CompoundPlugPtr solid = new CompoundPlug( "solid" );
	baseState->addChild( solid );
	solid->addChild( new BoolPlug( "enabled", Plug::In, true ) );
	solid->addChild( new BoolPlug( "override" ) );

	CompoundPlugPtr wireframe = new CompoundPlug( "wireframe" );
	baseState->addChild( wireframe );
	wireframe->addChild( new BoolPlug( "enabled" ) );
	wireframe->addChild( new BoolPlug( "override" ) );

	CompoundPlugPtr points = new CompoundPlug( "points" );
	baseState->addChild( points );
	points->addChild( new BoolPlug( "enabled" ) );
	points->addChild( new BoolPlug( "override" ) );

	CompoundPlugPtr bound = new CompoundPlug( "bound" );
	baseState->addChild( bound );
	bound->addChild( new BoolPlug( "enabled" ) );
	bound->addChild( new BoolPlug( "override" ) );

	plugSetSignal().connect( boost::bind( &View3D::plugSet, this, ::_1 ) );

	// camera

	IECore::CameraPtr camera = new IECore::Camera();

	camera->parameters()["projection"] = new IECore::StringData( "perspective" );
	camera->parameters()["projection:fov"] = new IECore::FloatData( 54.43 ); // 35 mm focal length

	M44f matrix;
	matrix.translate( V3f( 0, 0, 1 ) );
	matrix.rotate( IECore::degreesToRadians( V3f( -25, 45, 0 ) ) );
	camera->setTransform( new IECore::MatrixTransform( matrix ) );

	viewportGadget()->setCamera( camera.get() );
}

View3D::~View3D()
{
}

const IECoreGL::State *View3D::baseState() const
{
	return m_baseState.get();
}

View3D::BaseStateChangedSignal &View3D::baseStateChangedSignal()
{
	return m_baseStateChangedSignal;
}

void View3D::plugSet( const Gaffer::Plug *plug )
{
	if( plug == getChild<Plug>( "baseState" ) )
	{
		updateBaseState();
	}
}

void View3D::updateBaseState()
{
	const CompoundPlug *baseState = getChild<CompoundPlug>( "baseState" );

	const CompoundPlug *solid = baseState->getChild<CompoundPlug>( "solid" );
	m_baseState->add(
		new Primitive::DrawSolid( solid->getChild<BoolPlug>( "enabled" )->getValue() ),
		solid->getChild<BoolPlug>( "override" )->getValue()
	);

	const CompoundPlug *wireframe = baseState->getChild<CompoundPlug>( "wireframe" );
	m_baseState->add(
		new Primitive::DrawWireframe( wireframe->getChild<BoolPlug>( "enabled" )->getValue() ),
		wireframe->getChild<BoolPlug>( "override" )->getValue()
	);

	const CompoundPlug *points = baseState->getChild<CompoundPlug>( "points" );
	m_baseState->add(
		new Primitive::DrawPoints( points->getChild<BoolPlug>( "enabled" )->getValue() ),
		points->getChild<BoolPlug>( "override" )->getValue()
	);

	const CompoundPlug *bound = baseState->getChild<CompoundPlug>( "bound" );
	m_baseState->add(
		new Primitive::DrawBound( bound->getChild<BoolPlug>( "enabled" )->getValue() ),
		bound->getChild<BoolPlug>( "override" )->getValue()
	);

	baseStateChangedSignal()( this );
}
<commit_msg>Fixed compilation without NDEBUG=1 with gcc 4.1.2.<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2012-2013, John Haddon. All rights reserved.
//  Copyright (c) 2013, Image Engine Design 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 John Haddon nor the names of
//        any other contributors to this software 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.
//
//////////////////////////////////////////////////////////////////////////

#include "boost/bind.hpp"

#include "IECore/Camera.h"
#include "IECore/Transform.h"
#include "IECore/AngleConversion.h"
#include "IECore/MatrixTransform.h"

#include "IECoreGL/Primitive.h"

#include "Gaffer/CompoundPlug.h"
#include "Gaffer/NumericPlug.h"
#include "Gaffer/TypedPlug.h"

#include "GafferUI/View3D.h"

using namespace Imath;
using namespace IECoreGL;
using namespace Gaffer;
using namespace GafferUI;

IE_CORE_DEFINERUNTIMETYPED( View3D );

View3D::View3D( const std::string &name, Gaffer::PlugPtr inPlug )
	:	View( name, inPlug ), m_baseState( new IECoreGL::State( true ) )
{

	// base state setup

	m_baseState->add( new WireframeColorStateComponent( Color4f( 0.2f, 0.2f, 0.2f, 1.0f ) ) );
	m_baseState->add( new PointColorStateComponent( Color4f( 0.9f, 0.9f, 0.9f, 1.0f ) ) );
	m_baseState->add( new IECoreGL::Primitive::PointWidth( 2.0f ) );

	// plugs

	CompoundPlugPtr baseState = new CompoundPlug( "baseState" );
	addChild( baseState );

	CompoundPlugPtr solid = new CompoundPlug( "solid" );
	baseState->addChild( solid );
	solid->addChild( new BoolPlug( "enabled", Plug::In, true ) );
	solid->addChild( new BoolPlug( "override" ) );

	CompoundPlugPtr wireframe = new CompoundPlug( "wireframe" );
	baseState->addChild( wireframe );
	wireframe->addChild( new BoolPlug( "enabled" ) );
	wireframe->addChild( new BoolPlug( "override" ) );

	CompoundPlugPtr points = new CompoundPlug( "points" );
	baseState->addChild( points );
	points->addChild( new BoolPlug( "enabled" ) );
	points->addChild( new BoolPlug( "override" ) );

	CompoundPlugPtr bound = new CompoundPlug( "bound" );
	baseState->addChild( bound );
	bound->addChild( new BoolPlug( "enabled" ) );
	bound->addChild( new BoolPlug( "override" ) );

	plugSetSignal().connect( boost::bind( &View3D::plugSet, this, ::_1 ) );

	// camera

	// weird two stage assignment is to work around bogus
	// uninitialised variable warnings in debug builds with
	// gcc 4.1.2.
	IECore::CameraPtr camera; camera = new IECore::Camera();

	camera->parameters()["projection"] = new IECore::StringData( "perspective" );
	camera->parameters()["projection:fov"] = new IECore::FloatData( 54.43 ); // 35 mm focal length

	M44f matrix;
	matrix.translate( V3f( 0, 0, 1 ) );
	matrix.rotate( IECore::degreesToRadians( V3f( -25, 45, 0 ) ) );
	camera->setTransform( new IECore::MatrixTransform( matrix ) );

	viewportGadget()->setCamera( camera.get() );
}

View3D::~View3D()
{
}

const IECoreGL::State *View3D::baseState() const
{
	return m_baseState.get();
}

View3D::BaseStateChangedSignal &View3D::baseStateChangedSignal()
{
	return m_baseStateChangedSignal;
}

void View3D::plugSet( const Gaffer::Plug *plug )
{
	if( plug == getChild<Plug>( "baseState" ) )
	{
		updateBaseState();
	}
}

void View3D::updateBaseState()
{
	const CompoundPlug *baseState = getChild<CompoundPlug>( "baseState" );

	const CompoundPlug *solid = baseState->getChild<CompoundPlug>( "solid" );
	m_baseState->add(
		new Primitive::DrawSolid( solid->getChild<BoolPlug>( "enabled" )->getValue() ),
		solid->getChild<BoolPlug>( "override" )->getValue()
	);

	const CompoundPlug *wireframe = baseState->getChild<CompoundPlug>( "wireframe" );
	m_baseState->add(
		new Primitive::DrawWireframe( wireframe->getChild<BoolPlug>( "enabled" )->getValue() ),
		wireframe->getChild<BoolPlug>( "override" )->getValue()
	);

	const CompoundPlug *points = baseState->getChild<CompoundPlug>( "points" );
	m_baseState->add(
		new Primitive::DrawPoints( points->getChild<BoolPlug>( "enabled" )->getValue() ),
		points->getChild<BoolPlug>( "override" )->getValue()
	);

	const CompoundPlug *bound = baseState->getChild<CompoundPlug>( "bound" );
	m_baseState->add(
		new Primitive::DrawBound( bound->getChild<BoolPlug>( "enabled" )->getValue() ),
		bound->getChild<BoolPlug>( "override" )->getValue()
	);

	baseStateChangedSignal()( this );
}
<|endoftext|>