<commit_before>#include <assert.h>
#include <iostream>
#include <stack>
#include <string>
#include <sys/time.h>

#include "ast.h"
#include "cell.h"
#include "number.h"

typedef void (*Thunk)(std::stack<Variant> &stack, void *func);

static std::map<std::string, std::pair<Thunk, void *> > Functions;

namespace rtl {

Number abs(Number x)
{
    return number_abs(x);
}

std::string chr(Number x)
{
    assert(number_is_integer(x));
    return std::string(1, static_cast<char>(number_to_uint32(x)));
}

std::string concat(const std::string &a, const std::string &b)
{
    return a + b;
}

std::string input(const std::string &prompt)
{
    std::cout << prompt;
    std::string r;
    std::getline(std::cin, r);
    return r;
}

Number max(Number a, Number b)
{
    if (number_is_greater(a, b)) {
        return a;
    } else {
        return b;
    }
}

Number min(Number a, Number b)
{
    if (number_is_less(a, b)) {
        return a;
    } else {
        return b;
    }
}

Number num(const std::string &s)
{
    return number_from_string(s.c_str());
}

Number ord(const std::string &s)
{
    assert(s.length() == 1);
    return number_from_uint32(s.at(0));
}

void print(const std::string &s)
{
    std::cout << s << "\n";
}

std::string splice(const std::string &t, const std::string &s, Number offset, Number length)
{
    uint32_t o = number_to_uint32(offset);
    return s.substr(0, o) + t + s.substr(o + number_to_uint32(length));
}

std::string str(Number x)
{
    return number_to_string(x);
}

std::string strb(bool x)
{
    return x ? "TRUE" : "FALSE";
}

std::string substring(const std::string &s, Number offset, Number length)
{
    assert(number_is_integer(offset));
    assert(number_is_integer(length));
    return s.substr(number_to_uint32(offset), number_to_uint32(length));
}

Number math$acos(Number x)
{
    return number_acos(x);
}

Number math$asin(Number x)
{
    return number_asin(x);
}

Number math$atan(Number x)
{
    return number_atan(x);
}

Number math$ceil(Number x)
{
    return number_ceil(x);
}

Number math$cos(Number x)
{
    return number_cos(x);
}

Number math$exp(Number x)
{
    return number_exp(x);
}

Number math$floor(Number x)
{
    return number_floor(x);
}

Number math$log(Number x)
{
    return number_log(x);
}

Number math$sin(Number x)
{
    return number_sin(x);
}

Number math$sqrt(Number x)
{
    return number_sqrt(x);
}

Number math$tan(Number x)
{
    return number_tan(x);
}

Number time$now()
{
    struct timeval tv;
    if (gettimeofday(&tv, NULL) != 0) {
        return number_from_uint32(0);
    }
    return number_add(number_from_uint32(tv.tv_sec), number_divide(number_from_uint32(tv.tv_usec), number_from_uint32(1e6)));
}

} // namespace rtl

#include "thunks.inc"
#include "functions.inc"

void rtl_init(Scope *scope)
{
    for (auto f: BuiltinFunctions) {
        std::vector<const ParameterType *> params;
        for (auto p: f.params) {
            if (p == nullptr) {
                break;
            }
            params.push_back(new ParameterType(ParameterType::IN, p));
        }
        scope->names[f.name] = new PredefinedFunction(f.name, new TypeFunction(f.returntype, params));
        Functions[f.name] = std::make_pair(f.thunk, f.func);
    }
}

void rtl_import(Scope *scope, const std::string &name)
{
    std::string prefix = name + "$";
    Module *module = new Module(scope, name);
    for (auto f: BuiltinFunctions) {
        std::string qualified_name(f.name);
        if (qualified_name.substr(0, prefix.length()) == prefix) {
            std::vector<const ParameterType *> params;
            for (auto p: f.params) {
                if (p == nullptr) {
                    break;
                }
                params.push_back(new ParameterType(ParameterType::IN, p));
            }
            module->scope->names[qualified_name.substr(prefix.length())] = new PredefinedFunction(f.name, new TypeFunction(f.returntype, params));
        }
    }
    scope->names[name] = module;
}

void rtl_call(std::stack<Variant> &stack, const std::string &name)
{
    auto f = Functions.find(name);
    if (f == Functions.end()) {
        fprintf(stderr, "simple: function not found: %s\n", name.c_str());
        abort();
    }
    f->second.first(stack, f->second.second);
}
<commit_msg>remove .c_str() redundancy<commit_after>#include <assert.h>
#include <iostream>
#include <stack>
#include <string>
#include <sys/time.h>

#include "ast.h"
#include "cell.h"
#include "number.h"

typedef void (*Thunk)(std::stack<Variant> &stack, void *func);

static std::map<std::string, std::pair<Thunk, void *> > Functions;

namespace rtl {

Number abs(Number x)
{
    return number_abs(x);
}

std::string chr(Number x)
{
    assert(number_is_integer(x));
    return std::string(1, static_cast<char>(number_to_uint32(x)));
}

std::string concat(const std::string &a, const std::string &b)
{
    return a + b;
}

std::string input(const std::string &prompt)
{
    std::cout << prompt;
    std::string r;
    std::getline(std::cin, r);
    return r;
}

Number max(Number a, Number b)
{
    if (number_is_greater(a, b)) {
        return a;
    } else {
        return b;
    }
}

Number min(Number a, Number b)
{
    if (number_is_less(a, b)) {
        return a;
    } else {
        return b;
    }
}

Number num(const std::string &s)
{
    return number_from_string(s);
}

Number ord(const std::string &s)
{
    assert(s.length() == 1);
    return number_from_uint32(s.at(0));
}

void print(const std::string &s)
{
    std::cout << s << "\n";
}

std::string splice(const std::string &t, const std::string &s, Number offset, Number length)
{
    uint32_t o = number_to_uint32(offset);
    return s.substr(0, o) + t + s.substr(o + number_to_uint32(length));
}

std::string str(Number x)
{
    return number_to_string(x);
}

std::string strb(bool x)
{
    return x ? "TRUE" : "FALSE";
}

std::string substring(const std::string &s, Number offset, Number length)
{
    assert(number_is_integer(offset));
    assert(number_is_integer(length));
    return s.substr(number_to_uint32(offset), number_to_uint32(length));
}

Number math$acos(Number x)
{
    return number_acos(x);
}

Number math$asin(Number x)
{
    return number_asin(x);
}

Number math$atan(Number x)
{
    return number_atan(x);
}

Number math$ceil(Number x)
{
    return number_ceil(x);
}

Number math$cos(Number x)
{
    return number_cos(x);
}

Number math$exp(Number x)
{
    return number_exp(x);
}

Number math$floor(Number x)
{
    return number_floor(x);
}

Number math$log(Number x)
{
    return number_log(x);
}

Number math$sin(Number x)
{
    return number_sin(x);
}

Number math$sqrt(Number x)
{
    return number_sqrt(x);
}

Number math$tan(Number x)
{
    return number_tan(x);
}

Number time$now()
{
    struct timeval tv;
    if (gettimeofday(&tv, NULL) != 0) {
        return number_from_uint32(0);
    }
    return number_add(number_from_uint32(tv.tv_sec), number_divide(number_from_uint32(tv.tv_usec), number_from_uint32(1e6)));
}

} // namespace rtl

#include "thunks.inc"
#include "functions.inc"

void rtl_init(Scope *scope)
{
    for (auto f: BuiltinFunctions) {
        std::vector<const ParameterType *> params;
        for (auto p: f.params) {
            if (p == nullptr) {
                break;
            }
            params.push_back(new ParameterType(ParameterType::IN, p));
        }
        scope->names[f.name] = new PredefinedFunction(f.name, new TypeFunction(f.returntype, params));
        Functions[f.name] = std::make_pair(f.thunk, f.func);
    }
}

void rtl_import(Scope *scope, const std::string &name)
{
    std::string prefix = name + "$";
    Module *module = new Module(scope, name);
    for (auto f: BuiltinFunctions) {
        std::string qualified_name(f.name);
        if (qualified_name.substr(0, prefix.length()) == prefix) {
            std::vector<const ParameterType *> params;
            for (auto p: f.params) {
                if (p == nullptr) {
                    break;
                }
                params.push_back(new ParameterType(ParameterType::IN, p));
            }
            module->scope->names[qualified_name.substr(prefix.length())] = new PredefinedFunction(f.name, new TypeFunction(f.returntype, params));
        }
    }
    scope->names[name] = module;
}

void rtl_call(std::stack<Variant> &stack, const std::string &name)
{
    auto f = Functions.find(name);
    if (f == Functions.end()) {
        fprintf(stderr, "simple: function not found: %s\n", name.c_str());
        abort();
    }
    f->second.first(stack, f->second.second);
}
<|endoftext|>


<commit_before>/*
 * project collectd_edit
 * ing. Carlo Capelli
 * Brescia 2015
 * Copyright 2015 Sputnik7
 */

#include "join.h"
#include "settings.h"
#include "ui_structure.h"

#include <gtkmmconfig.h>
#include <fstream>

settings::settings() {
    auto path = store_path();
    struct stat buffer;
    if (stat(path.c_str(), &buffer) == 0) {
        Glib::KeyFile kf;
        kf.load_from_file(path);
        for (auto f: kf.get_string_list("servers", "name"))
            servers[f] = server{
                    f,
                    kf.get_string(f, "address"),
                    kf.get_string(f, "alias"),
                    kf.get_string(f, "folder")
            };
    }
    if (servers.empty())
        initialize();
}

settings::~settings() {
    std::vector<std::string> v;
    if (GTKMM_MAJOR_VERSION >= 3 || (GTKMM_MAJOR_VERSION == 3 && GTKMM_MINOR_VERSION >= 10)) {
        Glib::KeyFile kf;
        for (auto s: servers) {
            auto n = s.first;
            v.push_back(n);
            kf.set_string(n, "address", s.second.address);
            kf.set_string(n, "alias", s.second.alias);
            kf.set_string(n, "folder", s.second.folder);
        }
        kf.set_string_list("servers", "name", v);
        kf.save_to_file(store_path());
    }
    else {
        // CentOS 7 have GTKMM_MINOR_VERSION == 8, missing save_to_file
        std::ofstream kf(store_path());
        for (auto s: servers) {
            auto n = s.first;
            kf << '[' << n << ']' << std::endl;
            v.push_back(n);
            kf << "address" << '=' << s.second.address << std::endl;
            kf << "alias" << '=' << s.second.alias << std::endl;
            kf << "folder" << '=' << s.second.folder << std::endl;
        }
        kf << '[' << join(v) << ']' << std::endl;
    }
}

/**
 * @brief initialize
 *  setup some defaults - assume localhost and collectd installed
 */
void settings::initialize() {
    g_assert(servers.empty());
    servers["localhost"] = server{"localhost", "127.0.0.1", "computer", "/etc/collectd"};
}

std::string settings::store_path() const {
    return ui_structure::get_resource_path("settings", "ini");
}
<commit_msg>version check x CentOS 7<commit_after>/*
 * project collectd_edit
 * ing. Carlo Capelli
 * Brescia 2015
 * Copyright 2015 Sputnik7
 */

#include "join.h"
#include "settings.h"
#include "ui_structure.h"

#include <gtkmmconfig.h>
#include <fstream>

settings::settings() {
    auto path = store_path();
    struct stat buffer;
    if (stat(path.c_str(), &buffer) == 0) {
        Glib::KeyFile kf;
        kf.load_from_file(path);
        for (auto f: kf.get_string_list("servers", "name"))
            servers[f] = server{
                    f,
                    kf.get_string(f, "address"),
                    kf.get_string(f, "alias"),
                    kf.get_string(f, "folder")
            };
    }
    if (servers.empty())
        initialize();
}

settings::~settings() {
    std::vector<std::string> v;
    if (GTKMM_MAJOR_VERSION >= 3 && GTKMM_MINOR_VERSION >= 10) {
        Glib::KeyFile kf;
        for (auto s: servers) {
            auto n = s.first;
            v.push_back(n);
            kf.set_string(n, "address", s.second.address);
            kf.set_string(n, "alias", s.second.alias);
            kf.set_string(n, "folder", s.second.folder);
        }
        kf.set_string_list("servers", "name", v);
        kf.save_to_file(store_path());
    }
    else {
        // CentOS 7 have GTKMM_MINOR_VERSION == 8, missing save_to_file
        std::ofstream kf(store_path());
        for (auto s: servers) {
            auto n = s.first;
            kf << '[' << n << ']' << std::endl;
            v.push_back(n);
            kf << "address" << '=' << s.second.address << std::endl;
            kf << "alias" << '=' << s.second.alias << std::endl;
            kf << "folder" << '=' << s.second.folder << std::endl;
        }
        kf << '[' << join(v) << ']' << std::endl;
    }
}

/**
 * @brief initialize
 *  setup some defaults - assume localhost and collectd installed
 */
void settings::initialize() {
    g_assert(servers.empty());
    servers["localhost"] = server{"localhost", "127.0.0.1", "computer", "/etc/collectd"};
}

std::string settings::store_path() const {
    return ui_structure::get_resource_path("settings", "ini");
}
<|endoftext|>


<commit_before>// SlitClient.cc for fluxbox
// Copyright (c) 2003 Henrik Kinnunen (fluxgen 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: SlitClient.cc,v 1.2 2003/06/22 12:30:59 fluxgen Exp $

#include "SlitClient.hh"

#include "Screen.hh"
#include "App.hh"
#include "Xutil.hh"

#include <X11/Xutil.h>
#include <X11/Xatom.h>

SlitClient::SlitClient(BScreen *screen, Window win) {
    initialize(screen, win);
}

SlitClient::SlitClient(const char *name):m_match_name(name == 0 ? "" : name) {
    initialize();
}

void SlitClient::initialize(BScreen *screen, Window win) {
    // Now we pre-initialize a list of slit clients with names for
    // comparison with incoming client windows.  This allows the slit
    // to maintain a sorted order based on a saved window name list.
    // Incoming windows not found in the list are appended.  Matching
    // duplicates are inserted after the last found instance of the
    // matching name.

    m_client_window = win;
    m_window = m_icon_window = None;
    move(0, 0);
    resize(0, 0);

    if (matchName().empty())
        m_match_name = Xutil::getWMName(clientWindow());
    m_visible = true;
}

void SlitClient::disableEvents() {
    if (window() == 0)
        return;
    Display *disp = FbTk::App::instance()->display();
    XSelectInput(disp, window(), NoEventMask);
}

void SlitClient::enableEvents() {
    if (window() == 0)
        return;
    Display *disp = FbTk::App::instance()->display();
    XSelectInput(disp, window(), StructureNotifyMask |
                 SubstructureNotifyMask | EnterWindowMask);
}

void SlitClient::hide() {
    XUnmapWindow(FbTk::App::instance()->display(), window());
}

void SlitClient::show() {
    XMapWindow(FbTk::App::instance()->display(), window());
}
<commit_msg>fix small oversight with slitlist fixes<commit_after>// SlitClient.cc for fluxbox
// Copyright (c) 2003 Henrik Kinnunen (fluxgen 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: SlitClient.cc,v 1.3 2004/01/31 11:39:32 rathnor Exp $

#include "SlitClient.hh"

#include "Screen.hh"
#include "App.hh"
#include "Xutil.hh"

#include <X11/Xutil.h>
#include <X11/Xatom.h>

SlitClient::SlitClient(BScreen *screen, Window win) {
    initialize(screen, win);
}

SlitClient::SlitClient(const char *name):m_match_name(name == 0 ? "" : name) {
    initialize();
}

void SlitClient::initialize(BScreen *screen, Window win) {
    // Now we pre-initialize a list of slit clients with names for
    // comparison with incoming client windows.  This allows the slit
    // to maintain a sorted order based on a saved window name list.
    // Incoming windows not found in the list are appended.  Matching
    // duplicates are inserted after the last found instance of the
    // matching name.

    m_client_window = win;
    m_window = m_icon_window = None;
    move(0, 0);
    resize(0, 0);

    if (matchName().empty())
        m_match_name = Xutil::getWMClassName(clientWindow());
    m_visible = true;
}

void SlitClient::disableEvents() {
    if (window() == 0)
        return;
    Display *disp = FbTk::App::instance()->display();
    XSelectInput(disp, window(), NoEventMask);
}

void SlitClient::enableEvents() {
    if (window() == 0)
        return;
    Display *disp = FbTk::App::instance()->display();
    XSelectInput(disp, window(), StructureNotifyMask |
                 SubstructureNotifyMask | EnterWindowMask);
}

void SlitClient::hide() {
    XUnmapWindow(FbTk::App::instance()->display(), window());
}

void SlitClient::show() {
    XMapWindow(FbTk::App::instance()->display(), window());
}
<|endoftext|>


<commit_before>#include "ast.hpp"

#include <sstream>
#include <iostream>

extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}

namespace lua {

struct environment {
  lua_State* state;

  environment(): state(luaL_newstate()) {
    luaL_openlibs(state);

    const int error = luaL_dofile(state, find("prelude.lua").c_str());
    check(error);
  }

  void check(int error) const {
    if(error) {
      std::string what = lua_tostring(state, -1);
      lua_pop(state, 1);
      throw std::runtime_error(what);
    }
  }

  std::string find(std::string filename) const {
    return SLIP_DIR + std::string("/") + filename;
  }

  void run(std::string code) {
    const int error = luaL_dostring(state, code.c_str());
    check(error);
  }

  ~environment() {
    lua_close(state);
  }
};

std::shared_ptr<environment> make_environment() {
  return std::make_shared<environment>();
}

struct ret;
struct def;
struct local;
struct call;
struct thunk;
struct cond;

struct var;
struct lit;
struct func;
struct table;
struct getattr;

struct term: variant<ret, local, def, call, cond> {
  using term::variant::variant;
};

struct expr: variant<var, lit, call, func, thunk, table, getattr> {
  using expr::variant::variant;
};

struct lit: variant<bool, long, double, std::string> {
  using lit::variant::variant;
};

struct call {
  expr func;
  list<expr> args;
};

struct func {
  list<symbol> args;
  list<term> body;
};

struct thunk {
  list<term> body;
};

struct ret {
  expr value;
};

struct local {
  symbol name;
};

struct var {
  symbol name;
};

struct def {
  symbol name;
  expr value;
};

struct cond {
  expr pred;
  list<term> conseq, alt;
};

struct table {
  list<def> attrs;
};

struct getattr {
  expr arg;
  symbol attr;
};

class state {
  std::ostream& out;
  std::size_t indent = 0;

public:
  state(std::ostream& out): out(out) { }

  template<class T>
  state& operator<<(const T& value) {
    out << value;
    return *this;
  }

  state& newline() {
    (out << "\n" << std::string(2 * indent, ' '));;
    return *this;
  }

  state& operator<<(std::ostream& (*func)(std::ostream&)) {
    out << func;
    return *this;
  }

  template<class Cont>
  void with_indent(Cont cont) {
    const std::size_t old = indent++;
    cont();
    indent = old;
  }

};

namespace alt {

template<class T>
static expr compile(T) {
  throw std::runtime_error("unimplemented");
}

static expr compile(ast::expr self);

static expr compile(ast::lit self) {
  return match(self, [](auto self) -> expr {
    return lit{self};
  });
}

static expr compile(ast::app self) {
  return call{compile(self.func), map(self.args, [](auto arg) {
    return compile(arg);
  })};
}

static expr compile(ast::abs self) {
  const term body = ret{compile(self.body)};
  return func{map(self.args, [](auto arg) {
    return arg.name;
  }), body %= list<term>() };
}

static expr compile(ast::var self) {
  return var{self.name};
}

static expr compile(ast::cond self) {
  const expr pred = compile(self.pred);
  const term conseq = ret{compile(self.conseq)};
  const term alt = ret{compile(self.alt)};

  const term body = cond{pred,
    conseq %= list<term>(),
    alt %= list<term>()};

  return thunk{body %= list<term>()};
}

static expr compile(ast::let self) {
  const list<term> decls = map(self.defs, [](ast::def self) -> term {
    return local{self.name};
  });

  const list<term> defs = map(self.defs, [](ast::def self) -> term {
    return def{self.name, compile(self.value)};
  });

  const term body = ret{compile(self.body)};

  return thunk{concat(concat(decls, defs),
                      body %= list<term>())};
}

static expr compile(ast::record self) {
  return table{map(self.attrs, [](auto attr) {
    return def{attr.name, compile(attr.value)};
  })};
}

static expr compile(ast::attr self) {
  return getattr{compile(self.arg), self.name};
}

static expr compile(ast::expr self) {
  return match(self, [](auto self) {
    return compile(self);
  });
}

static void format(expr self, state& ss);

template<class T>
static void format(T self, state& ss) {
  throw std::runtime_error("unimplemented");
}

static void format(lit self, state& ss) {
  return match(self,
               [&](bool self) { ss << (self ? "true" : "false"); },
               [&](std::string self) { ss << '"' << self << '"'; },
               [&](auto self) { ss << self; });
}

} // namespace alt

template<class T>
static void compile(const T& self, state&) {
  throw std::runtime_error("unimplemented");
}

static void compile(const ast::expr& self, state& ss);

static void compile(const ast::lit& self, state& ss) {
  return match(self,
               [&](bool self) { ss << (self ? "true" : "false"); },
               [&](std::string self) { ss << '"' << self << '"'; },
               [&](auto self) { ss << self; });
}

static void compile(const ast::var& self, state& ss) {
  ss << self.name.repr;
}

static void compile(const ast::app& self, state& ss) {
  compile(self.func, ss);
  ss << "(";
  unsigned sep = 0;
  for(auto arg: self.args) {
    if(sep++) {
      ss << ", ";
    }
    compile(arg, ss);
  }
  ss << ")";
}

static const auto thunk = [](auto expr) {
  return [=](state& ss) {
    ss << "(function()";
    ss.with_indent([&] {
      expr(ss.newline());
    });
    ss.newline() << "end)()";
  };
};

static void compile(const ast::record& self, state& ss) {
  ss << "{";

  int sep = 0;
  for(ast::def def: self.attrs) {
    if(sep++) {
      ss << ", ";
    }

    ss << def.name.repr << " = ";
    compile(def.value, ss);
  }
  ss << "}";
}

static void compile(const ast::attr& self, state& ss) {
  ss << "(";
  compile(self.arg, ss);
  ss << ").";
  ss << self.name.repr;
}

static void compile(const ast::abs& self, state& ss, const char* name) {
  ss << "function";

  if(name) {
    ss << " " << name;
  }

  ss << "(";

  unsigned sep = 0;
  for(auto arg: self.args) {
    if(sep++) {
      ss << ", ";
    }
    ss << arg.name.repr;
  }

  ss << ")";
  ss.with_indent([&] {
    ss.newline() << "return ";
    compile(self.body, ss);
  });
  ss.newline() << "end";
}

static void compile(const ast::abs& self, state& ss) {
  ss << "(";
  compile(self, ss, nullptr);
  ss << ")";
}

static void compile(const ast::cond& self, state& ss) {
  return thunk([=](auto& ss) {
    ss << "if ";
    compile(self.pred, ss);
    ss.newline() << "then return ";
    compile(self.conseq, ss);
    ss.newline() << "else return ";
    compile(self.alt, ss);
    ss.newline() << "end";
  })(ss);
}

static void compile(const ast::let& self, state& ss) {
  return thunk([=](state& ss) {
    int sep = 0;
    for(auto def: self.defs) {
      if(sep++) {
        ss.newline();
      }
      if(auto fun = def.value.cast<ast::abs>()) {
        compile(*fun, ss, def.name.repr);
      } else {
        ss << "local " << def.name.repr << " = ";
        compile(def.value, ss);
      }
    }

    ss.newline() << "return ";
    compile(self.body, ss);
  })(ss);
}

static void compile(const ast::expr& self, state& ss) {
  return match(self, [&](auto self) {
    return compile(self, ss);
  });
}

std::string run(std::shared_ptr<environment> env, const ast::expr& self) {
  std::stringstream buffer;
  state ss(buffer);

  ss << "return ";

  compile(self, ss);
  ss << std::flush;

  std::clog << buffer.str() << std::endl;

  env->run(buffer.str());

  std::string result = luaL_tolstring(env->state, -1, nullptr);
  lua_pop(env->state, 1);
  return result;
}

}
<commit_msg>whole new lua backend<commit_after>#include "ast.hpp"

#include <sstream>
#include <iostream>

extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}

namespace lua {

struct environment {
  lua_State* state;

  environment(): state(luaL_newstate()) {
    luaL_openlibs(state);

    const int error = luaL_dofile(state, find("prelude.lua").c_str());
    check(error);
  }

  void check(int error) const {
    if(error) {
      std::string what = lua_tostring(state, -1);
      lua_pop(state, 1);
      throw std::runtime_error(what);
    }
  }

  std::string find(std::string filename) const {
    return SLIP_DIR + std::string("/") + filename;
  }

  void run(std::string code) {
    const int error = luaL_dostring(state, code.c_str());
    check(error);
  }

  ~environment() {
    lua_close(state);
  }
};

std::shared_ptr<environment> make_environment() {
  return std::make_shared<environment>();
}

struct ret;
struct def;
struct local;
struct call;
struct thunk;
struct cond;

struct var;
struct lit;
struct func;
struct table;
struct getattr;

struct term: variant<ret, local, def, call, cond> {
  using term::variant::variant;
};

struct expr: variant<var, lit, call, func, thunk, table, getattr> {
  using expr::variant::variant;
};

struct lit: variant<bool, long, double, std::string> {
  using lit::variant::variant;
};

struct call {
  expr func;
  list<expr> args;
};

struct func {
  list<symbol> args;
  list<term> body;
};

struct thunk {
  list<term> body;
};

struct ret {
  expr value;
};

struct local {
  symbol name;
};

struct var {
  symbol name;
};

struct def {
  symbol name;
  expr value;
};

struct cond {
  expr pred;
  list<term> conseq, alt;
};

struct table {
  list<def> attrs;
};

struct getattr {
  expr arg;
  symbol name;
};

class state {
  std::ostream& out;
  std::size_t indent = 0;

public:
  state(std::ostream& out): out(out) { }

  template<class T>
  state& operator<<(const T& value) {
    out << value;
    return *this;
  }

  state& newline() {
    (out << "\n" << std::string(2 * indent, ' '));;
    return *this;
  }

  state& operator<<(std::ostream& (*func)(std::ostream&)) {
    out << func;
    return *this;
  }

  template<class Cont>
  void with_indent(Cont cont) {
    const std::size_t old = indent++;
    cont();
    indent = old;
  }

};

template<class T>
static expr compile(T) {
  throw std::runtime_error("unimplemented compile: " +
                           std::string(typeid(T).name()));
}

static expr compile(ast::expr self);

static expr compile(ast::lit self) {
  return match(self, [](auto self) -> expr {
    return lit{self};
  });
}

static expr compile(ast::app self) {
  return call{compile(self.func), map(self.args, [](auto arg) {
    return compile(arg);
  })};
}

static expr compile(ast::abs self) {
  const term body = ret{compile(self.body)};
  return func{map(self.args, [](auto arg) {
    return arg.name;
  }), body %= list<term>() };
}

static expr compile(ast::var self) {
  return var{self.name};
}

static expr compile(ast::cond self) {
  const expr pred = compile(self.pred);
  const term conseq = ret{compile(self.conseq)};
  const term alt = ret{compile(self.alt)};

  const term body = cond{pred,
    conseq %= list<term>(),
    alt %= list<term>()};

  return thunk{body %= list<term>()};
}

static expr compile(ast::let self) {
  const list<term> decls = map(self.defs, [](ast::def self) -> term {
    return local{self.name};
  });

  const list<term> defs = map(self.defs, [](ast::def self) -> term {
    return def{self.name, compile(self.value)};
  });

  const term body = ret{compile(self.body)};

  return thunk{concat(concat(decls, defs),
                      body %= list<term>())};
}

static expr compile(ast::record self) {
  return table{map(self.attrs, [](auto attr) {
    return def{attr.name, compile(attr.value)};
  })};
}

static expr compile(ast::attr self) {
  return getattr{compile(self.arg), self.name};
}

static expr compile(ast::expr self) {
  return match(self, [](auto self) {
    return compile(self);
  });
}

////////////////////////////////////////////////////////////////////////////////
static void format(expr self, state& ss);
static void format(term self, state& ss);

template<class T>
static void format(T self, state& ss) {
  throw std::runtime_error("unimplemented format: " +
                           std::string(typeid(T).name()));
}

static void format(lit self, state& ss) {
  return match(self,
               [&](bool self) { ss << (self ? "true" : "false"); },
               [&](std::string self) { ss << '"' << self << '"'; },
               [&](auto self) { ss << self; });
}

static void format(var self, state& ss) {
  ss << self.name.repr;
}

static void format(ret self, state& ss) {
  format(self.value, ss << "return ");
}

static void format(local self, state& ss) {
  ss << "local " << self.name;
}

static void format(def self, state& ss) {
  ss << self.name << " = ";
  format(self.value, ss);
}

static void format(call self, state& ss) {
  format(self.func, ss);
  ss << "(";
  unsigned sep = 0;
  for(auto arg: self.args) {
    if(sep++) {
      ss << ", ";
    }
    format(arg, ss);
  }
  ss << ")";
}

static void format(thunk self, state& ss) {
  ss << "(function()";
  ss.with_indent([&] {
    for(term t: self.body) {
      format(t, ss.newline());
    }
  });
  ss.newline() << "end)()";
}

static void format(table self, state& ss) {
  ss << "{";

  int sep = 0;
  for(auto def: self.attrs) {
    if(sep++) {
      ss << ", ";
    }

    ss << def.name.repr << " = ";
    format(def.value, ss);
  }
  ss << "}";
}

static void format(getattr self, state& ss) {
  ss << "(";
  format(self.arg, ss);
  ss << ").";
  ss << self.name.repr;
}

static void format(func self, state& ss) {
  ss << "function(";

  unsigned sep = 0;
  for(auto arg: self.args) {
    if(sep++) {
      ss << ", ";
    }
    ss << arg.repr;
  }

  ss << ")";
  ss.with_indent([&] {
    for(term t: self.body) {
      format(t, ss.newline());
    }
  });
  ss.newline() << "end";
}

static void format(cond self, state& ss) {
  format(self.pred, ss << "if ");

  ss.newline() << "then";
  ss.with_indent([&] {
    for(term t: self.conseq) {
      format(t, ss.newline());
    }
  });
  ss.newline() << "else";
  ss.with_indent([&] {
    for(term t: self.alt) {
      format(t, ss.newline());
    }
  });
  ss.newline() << "end";
}

////////////////////////////////////////////////////////////////////////////////

static void format(expr self, state& ss) {
  return match(self, [&](auto self) {
    return format(self, ss);
  });
}

static void format(term self, state& ss) {
  return match(self, [&](auto self) {
    return format(self, ss);
  });
}

////////////////////////////////////////////////////////////////////////////////
// TODO optimization

std::string run(std::shared_ptr<environment> env, const ast::expr& self) {
  std::stringstream buffer;
  state ss(buffer);

  const term code = ret{compile(self)};
  format(code, ss);

  std::clog << buffer.str() << std::endl;

  env->run(buffer.str());

  std::string result = luaL_tolstring(env->state, -1, nullptr);
  lua_pop(env->state, 1);
  return result;
}

}
<|endoftext|>


<commit_before>#include <jansson.h>

#include <vector>

#include "utils/translate-commit-desc.h"

#include "event.h"

namespace {

QString getStringFromJson(const json_t *json, const char* key)
{
    return QString::fromUtf8(json_string_value(json_object_get(json, key)));
}

const char *kEventTypeRepoCreate = "repo-create";
const char *kEventTypeRepoDelete = "repo-delete";

} // namespace

SeafEvent SeafEvent::fromJSON(const json_t *json, json_error_t */* error */)
{
    SeafEvent event;

    event.author = getStringFromJson(json, "author");
    if (event.author.isEmpty()) {
        event.author = "anonymous";
        event.anonymous = true;
    }
    event.nick = getStringFromJson(json, "nick");
    if (event.nick.isEmpty()) {
        event.nick = "anonymous";
    }

    event.repo_id = getStringFromJson(json, "repo_id");
    event.repo_name = getStringFromJson(json, "repo_name");

    event.commit_id = getStringFromJson(json, "commit_id");
    event.etype = getStringFromJson(json, "etype");
    event.desc = getStringFromJson(json, "desc");

    event.timestamp = json_integer_value(json_object_get(json, "time"));

    if (event.etype == kEventTypeRepoCreate) {
        event.desc = QObject::tr("Created library \"%1\"").arg(event.repo_name);
    } else if (event.etype == kEventTypeRepoDelete) {
        event.desc = QObject::tr("Deleted library \"%1\"").arg(event.repo_name);
    }

    event.desc = translateCommitDesc(event.desc);

    return event;
}

std::vector<SeafEvent> SeafEvent::listFromJSON(const json_t *json, json_error_t *error)
{
    std::vector<SeafEvent> events;

    for (size_t i = 0; i < json_array_size(json); i++) {
        SeafEvent event = fromJSON(json_array_get(json, i), error);
        events.push_back(event);
    }

    return events;
}

QString SeafEvent::toString() const
{
    return QString("type=\"%1\",author=\"%2\",repo_name=\"%3\",desc=\"%4\",commit=\"%5\"")
        .arg(etype).arg(author).arg(repo_name).arg(desc).arg(commit_id);
}

bool SeafEvent::isDetailsDisplayable() const
{
    if (commit_id.isEmpty()) {
        return false;
    }
    // TODO: determine if there are files change in this commit
    return true;
}
<commit_msg>fix a bug caused by using uninitialized value<commit_after>#include <jansson.h>

#include <vector>

#include "utils/translate-commit-desc.h"

#include "event.h"

namespace {

QString getStringFromJson(const json_t *json, const char* key)
{
    return QString::fromUtf8(json_string_value(json_object_get(json, key)));
}

const char *kEventTypeRepoCreate = "repo-create";
const char *kEventTypeRepoDelete = "repo-delete";

} // namespace

SeafEvent SeafEvent::fromJSON(const json_t *json, json_error_t */* error */)
{
    SeafEvent event;

    event.author = getStringFromJson(json, "author");
    if (event.author.isEmpty()) {
        event.author = "anonymous";
        event.anonymous = true;
    } else {
        event.anonymous = false;
    }

    event.nick = getStringFromJson(json, "nick");
    if (event.nick.isEmpty()) {
        event.nick = "anonymous";
    }

    event.repo_id = getStringFromJson(json, "repo_id");
    event.repo_name = getStringFromJson(json, "repo_name");

    event.commit_id = getStringFromJson(json, "commit_id");
    event.etype = getStringFromJson(json, "etype");
    event.desc = getStringFromJson(json, "desc");

    event.timestamp = json_integer_value(json_object_get(json, "time"));

    if (event.etype == kEventTypeRepoCreate) {
        event.desc = QObject::tr("Created library \"%1\"").arg(event.repo_name);
    } else if (event.etype == kEventTypeRepoDelete) {
        event.desc = QObject::tr("Deleted library \"%1\"").arg(event.repo_name);
    }

    event.desc = translateCommitDesc(event.desc);

    return event;
}

std::vector<SeafEvent> SeafEvent::listFromJSON(const json_t *json, json_error_t *error)
{
    std::vector<SeafEvent> events;

    for (size_t i = 0; i < json_array_size(json); i++) {
        SeafEvent event = fromJSON(json_array_get(json, i), error);
        events.push_back(event);
    }

    return events;
}

QString SeafEvent::toString() const
{
    return QString("type=\"%1\",author=\"%2\",repo_name=\"%3\",desc=\"%4\",commit=\"%5\"")
        .arg(etype).arg(author).arg(repo_name).arg(desc).arg(commit_id);
}

bool SeafEvent::isDetailsDisplayable() const
{
    if (commit_id.isEmpty()) {
        return false;
    }
    // TODO: determine if there are files change in this commit
    return true;
}
<|endoftext|>


<commit_before>#include <app/Scene.hpp>
#include <app/ModuleBrowser.hpp>
#include <app.hpp>
#include <system.hpp>
#include <network.hpp>
#include <history.hpp>
#include <settings.hpp>
#include <patch.hpp>
#include <asset.hpp>
#include <osdialog.h>
#include <thread>

namespace rack {
namespace app {

Scene::Scene() {
	rackScroll = new RackScrollWidget;
	addChild(rackScroll);

	rack = rackScroll->rackWidget;

	menuBar = createMenuBar();
	addChild(menuBar);
	rackScroll->box.pos.y = menuBar->box.size.y;

	moduleBrowser = moduleBrowserCreate();
	moduleBrowser->hide();
	addChild(moduleBrowser);
}

Scene::~Scene() {
}

void Scene::step() {
	// Resize owned descendants
	menuBar->box.size.x = box.size.x;
	rackScroll->box.size = box.size.minus(rackScroll->box.pos);

	// Autosave every 15 seconds
	if (settings::autosavePeriod > 0.0) {
		double time = glfwGetTime();
		if (time - lastAutosaveTime >= settings::autosavePeriod) {
			lastAutosaveTime = time;
			APP->patch->save(asset::autosavePath);
			settings::save(asset::settingsPath);
		}
	}

	Widget::step();
}

void Scene::draw(const DrawArgs &args) {
	Widget::draw(args);
}

void Scene::onHoverKey(const event::HoverKey &e) {
	OpaqueWidget::onHoverKey(e);
	if (e.isConsumed())
		return;

	if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) {
		switch (e.key) {
			case GLFW_KEY_N: {
				if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
					APP->patch->resetDialog();
					e.consume(this);
				}
			} break;
			case GLFW_KEY_Q: {
				if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
					APP->window->close();
					e.consume(this);
				}
			} break;
			case GLFW_KEY_O: {
				if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
					APP->patch->loadDialog();
					e.consume(this);
				}
				if ((e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) {
					APP->patch->revertDialog();
					e.consume(this);
				}
			} break;
			case GLFW_KEY_S: {
				if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
					APP->patch->saveDialog();
					e.consume(this);
				}
				if ((e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) {
					APP->patch->saveAsDialog();
					e.consume(this);
				}
			} break;
			case GLFW_KEY_Z: {
				if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
					APP->history->undo();
					e.consume(this);
				}
				if ((e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) {
					APP->history->redo();
					e.consume(this);
				}
			} break;
			case GLFW_KEY_MINUS: {
				if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
					float zoom = settings::zoom;
					zoom *= 2;
					zoom = std::ceil(zoom - 0.01) - 1;
					zoom /= 2;
					settings::zoom = zoom;
					e.consume(this);
				}
			} break;
			case GLFW_KEY_EQUAL: {
				if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
					float zoom = settings::zoom;
					zoom *= 2;
					zoom = std::floor(zoom + 0.01) + 1;
					zoom /= 2;
					settings::zoom = zoom;
					e.consume(this);
				}
			} break;
			case GLFW_KEY_ENTER: {
				if ((e.mods & RACK_MOD_MASK) == 0) {
					moduleBrowser->show();
				}
				e.consume(this);
			} break;
			case GLFW_KEY_F1: {
				if ((e.mods & RACK_MOD_MASK) == 0) {
					std::thread t([] {
						system::openBrowser("https://vcvrack.com/manual/");
					});
					t.detach();
					e.consume(this);
				}
			} break;
			case GLFW_KEY_F11: {
				if ((e.mods & RACK_MOD_MASK) == 0) {
					APP->window->setFullScreen(!APP->window->isFullScreen());
					e.consume(this);
				}
			} break;
		}
	}
}

void Scene::onPathDrop(const event::PathDrop &e) {
	OpaqueWidget::onPathDrop(e);
	if (e.isConsumed())
		return;

	if (e.paths.size() >= 1) {
		const std::string &path = e.paths[0];
		if (string::filenameExtension(string::filename(path)) == "vcv") {
			APP->patch->load(path);
			e.consume(this);
		}
	}
}

} // namespace app
} // namespace rack
<commit_msg>Add Ctrl-0 key command for resetting zoom.<commit_after>#include <app/Scene.hpp>
#include <app/ModuleBrowser.hpp>
#include <app.hpp>
#include <system.hpp>
#include <network.hpp>
#include <history.hpp>
#include <settings.hpp>
#include <patch.hpp>
#include <asset.hpp>
#include <osdialog.h>
#include <thread>

namespace rack {
namespace app {

Scene::Scene() {
	rackScroll = new RackScrollWidget;
	addChild(rackScroll);

	rack = rackScroll->rackWidget;

	menuBar = createMenuBar();
	addChild(menuBar);
	rackScroll->box.pos.y = menuBar->box.size.y;

	moduleBrowser = moduleBrowserCreate();
	moduleBrowser->hide();
	addChild(moduleBrowser);
}

Scene::~Scene() {
}

void Scene::step() {
	// Resize owned descendants
	menuBar->box.size.x = box.size.x;
	rackScroll->box.size = box.size.minus(rackScroll->box.pos);

	// Autosave every 15 seconds
	if (settings::autosavePeriod > 0.0) {
		double time = glfwGetTime();
		if (time - lastAutosaveTime >= settings::autosavePeriod) {
			lastAutosaveTime = time;
			APP->patch->save(asset::autosavePath);
			settings::save(asset::settingsPath);
		}
	}

	Widget::step();
}

void Scene::draw(const DrawArgs &args) {
	Widget::draw(args);
}

void Scene::onHoverKey(const event::HoverKey &e) {
	OpaqueWidget::onHoverKey(e);
	if (e.isConsumed())
		return;

	if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) {
		switch (e.key) {
			case GLFW_KEY_N: {
				if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
					APP->patch->resetDialog();
					e.consume(this);
				}
			} break;
			case GLFW_KEY_Q: {
				if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
					APP->window->close();
					e.consume(this);
				}
			} break;
			case GLFW_KEY_O: {
				if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
					APP->patch->loadDialog();
					e.consume(this);
				}
				if ((e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) {
					APP->patch->revertDialog();
					e.consume(this);
				}
			} break;
			case GLFW_KEY_S: {
				if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
					APP->patch->saveDialog();
					e.consume(this);
				}
				if ((e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) {
					APP->patch->saveAsDialog();
					e.consume(this);
				}
			} break;
			case GLFW_KEY_Z: {
				if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
					APP->history->undo();
					e.consume(this);
				}
				if ((e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) {
					APP->history->redo();
					e.consume(this);
				}
			} break;
			case GLFW_KEY_MINUS: {
				if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
					float zoom = settings::zoom;
					zoom *= 2;
					zoom = std::ceil(zoom - 0.01f) - 1;
					zoom /= 2;
					settings::zoom = zoom;
					e.consume(this);
				}
			} break;
			case GLFW_KEY_EQUAL: {
				if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
					float zoom = settings::zoom;
					zoom *= 2;
					zoom = std::floor(zoom + 0.01f) + 1;
					zoom /= 2;
					settings::zoom = zoom;
					e.consume(this);
				}
			} break;
			case GLFW_KEY_0: {
				if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
					settings::zoom = 0.f;
					e.consume(this);
				}
			} break;
			case GLFW_KEY_ENTER: {
				if ((e.mods & RACK_MOD_MASK) == 0) {
					moduleBrowser->show();
				}
				e.consume(this);
			} break;
			case GLFW_KEY_F1: {
				if ((e.mods & RACK_MOD_MASK) == 0) {
					std::thread t([] {
						system::openBrowser("https://vcvrack.com/manual/");
					});
					t.detach();
					e.consume(this);
				}
			} break;
			case GLFW_KEY_F11: {
				if ((e.mods & RACK_MOD_MASK) == 0) {
					APP->window->setFullScreen(!APP->window->isFullScreen());
					e.consume(this);
				}
			} break;
		}
	}
}

void Scene::onPathDrop(const event::PathDrop &e) {
	OpaqueWidget::onPathDrop(e);
	if (e.isConsumed())
		return;

	if (e.paths.size() >= 1) {
		const std::string &path = e.paths[0];
		if (string::filenameExtension(string::filename(path)) == "vcv") {
			APP->patch->load(path);
			e.consume(this);
		}
	}
}

} // namespace app
} // namespace rack
<|endoftext|>


<commit_before>#include <ros/ros.h>
#include <sensor_msgs/Image.h>
#include <image_transport/image_transport.h>
#include <visualization_msgs/Marker.h>
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <cv_bridge/CvBridge.h>

#include <AprilTags/TagDetector.h>
#include <AprilTags/Tag16h5.h>
#include <AprilTags/Tag25h7.h>
#include <AprilTags/Tag25h9.h>
#include <AprilTags/Tag36h9.h>
#include <AprilTags/Tag36h11.h>

#include <visualization_msgs/MarkerArray.h>
#include "yaml-cpp/yaml.h"
#include <sstream>
#include <fstream>

#include <boost/unordered_map.hpp>

using namespace std;

#define DEFAULT_TAG_FAMILY string("36h11")

class AprilTagsNode {
    ros::NodeHandle node_;
    image_transport::ImageTransport image_;
    ros::Publisher marker_publisher_;
    ros::ServiceServer detect_enable_;

    AprilTags::TagDetector* tag_detector_;
    AprilTags::TagCodes tag_codes_;

    sensor_msgs::CameraInfo camera_info_;

    int viewer_;
    string tag_family_name_;
    boost::unordered_map<size_t, double> tag_sizes_;
    double default_tag_size_;
    string frame_;

    ros::Subscriber image_subscriber;
    ros::Subscriber info_subscriber;

    int enabled_;

public:
    AprilTagsNode() : node_("~"),
                      image_(node_),
                      tag_codes_(AprilTags::tagCodes36h11){

        string camera_topic_name = "/Image"; // "/head_kinect/rgb/image_color";
        string output_marker_list_topic_name = "/marker_array";
        string enable_service_name = "/Enable";
        string tag_data;

        // Get Parameters
        node_.param("/viewer", viewer_, 1);
        node_.param("/tag_family", tag_family_name_, DEFAULT_TAG_FAMILY);
        node_.param("/tag_data", tag_data, string(""));

        double small_tag_size = 0.0358968; //0.0378968; // (~1.5" tags)
        double med_tag_size = 0.0630174; // (~2.5" tags)
        double page_tag_size = 0.165;
        node_.param("/default_tag_size", default_tag_size_, med_tag_size);
        node_.param("/tf_frame", frame_, /*string("/prosilica_cam"));*/ string("/head_kinect_rgb_frame"));

        // Start the viewer if speficified
        if(viewer_){
            cvNamedWindow("AprilTags");
            cvStartWindowThread();
        }

        // Tag Detector
        SetTagCodeFromString(tag_family_name_);
        tag_detector_ = new AprilTags::TagDetector(tag_codes_);

        // Publisher
        marker_publisher_ = node_.advertise<visualization_msgs::MarkerArray>(
                output_marker_list_topic_name, 0);

        // Subscriber
        //image_transport::CameraSubscriber sub = image_.subscribeCamera(
        //        camera_topic_name, 1, &AprilTagsNode::ImageCallback, this);

        image_subscriber = node_.subscribe(camera_topic_name, 10, &AprilTagsNode::ImageCallback, this);

        info_subscriber = node_.subscribe("/camera_info", 10, &AprilTagsNode::InfoCallback, this);

        // Store Tag Sizes
        StoreTagSizes(tag_data);
    }

    ~AprilTagsNode(){
        cvDestroyWindow("AprilTags");
        delete tag_detector_;
    }

    void SetTagCodeFromString(string code_string){
        if(code_string == "16h5"){
            tag_codes_ = AprilTags::tagCodes16h5;
        }
        else if(code_string == "25h7"){
            tag_codes_ = AprilTags::tagCodes25h7;
        }
        else if(code_string == "25h9"){
            tag_codes_ = AprilTags::tagCodes25h9;
        }
        else if(code_string == "36h9"){
            tag_codes_ = AprilTags::tagCodes36h9;
        }
        else if(code_string == "36h11"){
            tag_codes_ = AprilTags::tagCodes36h11;
        }
        else{
            cout << "Invalid tag family specified : " << code_string << endl;
            exit(1);
        }
    }

    void StoreTagSizes(string tag_data){
        stringstream tag_ss;
        tag_ss << tag_data;
        YAML::Parser parser(tag_ss);
        YAML::Node doc;
        parser.GetNextDocument(doc);

        for(YAML::Iterator field = doc.begin(); field != doc.end(); ++field){
            //string index_str;
            //field.first() >> index_str;
            //size_t index = atoi(index_str.c_str());

            int index;
            field.first() >> index;

            const YAML::Node& value = field.second();
            for(YAML::Iterator sub_field = value.begin();
                    sub_field != value.end(); ++sub_field){

                string key;
                sub_field.first() >> key;

                if(key == "size"){
                    sub_field.second() >> tag_sizes_[index];
                }
            }
        }
    }

    void InfoCallback(
            const sensor_msgs::CameraInfoConstPtr& camera_info){
        //std::cout << "INFO CALLBACK" << endl;
        camera_info_ = (*camera_info);
    }

    void ImageCallback(
            const sensor_msgs::ImageConstPtr& msg )//,
           // const sensor_msgs::CameraInfoConstPtr& camera_info)
    {

        //std::cout << "IMAGE CALLBACK" << endl;

        sensor_msgs::CvBridge bridge;
        cv::Mat subscribed_image;
        try{
            subscribed_image = bridge.imgMsgToCv(msg, "bgr8");
        }
        catch(sensor_msgs::CvBridgeException& e){
            ROS_ERROR("Could not convert from '%s' to 'bgr8'.",
                      msg->encoding.c_str());
            return;
        }

        cv::Mat subscribed_gray;
        cv::cvtColor(subscribed_image, subscribed_gray, CV_BGR2GRAY);
        vector<AprilTags::TagDetection> detections =
                tag_detector_->extractTags(subscribed_gray);

        //cout << "Found " << detections.size() << endl;

        visualization_msgs::MarkerArray marker_transforms;

        for(unsigned int i = 0; i < detections.size(); ++i){
            double tag_size = default_tag_size_;
            boost::unordered_map<size_t, double>::iterator tag_size_it =
                    tag_sizes_.find(detections[i].id);

            if(tag_size_it != tag_sizes_.end()){
                tag_size = (*tag_size_it).second;
            }

            detections[i].draw(subscribed_image);
            Eigen::Matrix4d pose;
            pose = detections[i].getRelativeTransform(
                    tag_size,
                    (camera_info_).K[0], (camera_info_).K[4],
                    (camera_info_).K[2], (camera_info_).K[5]);
            Eigen::Matrix3d R = pose.block<3,3>(0,0);
            Eigen::Quaternion<double> q(R);

            visualization_msgs::Marker marker_transform;
            marker_transform.header.frame_id = frame_;
            marker_transform.header.stamp = ros::Time::now();
            stringstream convert;
            convert << "tag" << detections[i].id;
            marker_transform.ns = convert.str().c_str();
            marker_transform.id = detections[i].id;
            marker_transform.type = visualization_msgs::Marker::CUBE;
            marker_transform.action = visualization_msgs::Marker::ADD;
            marker_transform.pose.position.x = pose(0,3);
            marker_transform.pose.position.y = pose(1,3);
            marker_transform.pose.position.z = pose(2,3);
            marker_transform.pose.orientation.x = q.x();
            marker_transform.pose.orientation.y = q.y();
            marker_transform.pose.orientation.z = q.z();
            marker_transform.pose.orientation.w = q.w();
            marker_transform.scale.x = tag_size;
            marker_transform.scale.y = tag_size;
            marker_transform.scale.z = 0.05 * tag_size;
            marker_transform.color.r = 0.5;
            marker_transform.color.g = 0.5;
            marker_transform.color.b = 0.5;
            marker_transform.color.a = 1.0;
            marker_transforms.markers.push_back(marker_transform);
        }

        marker_publisher_.publish(marker_transforms);

        if(viewer_){
            cv::imshow("AprilTags", subscribed_image);
        }
    }
};

int main(int argc, char **argv){
    ros::init(argc, argv, "apriltags");

    AprilTagsNode detector;
    ros::spin();

    return EXIT_SUCCESS;
}
<commit_msg>cleaning up<commit_after>#include <ros/ros.h>
#include <sensor_msgs/Image.h>
//#include <image_transport/image_transport.h>
#include <visualization_msgs/Marker.h>
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <cv_bridge/CvBridge.h>

#include <AprilTags/TagDetector.h>
#include <AprilTags/Tag16h5.h>
#include <AprilTags/Tag25h7.h>
#include <AprilTags/Tag25h9.h>
#include <AprilTags/Tag36h9.h>
#include <AprilTags/Tag36h11.h>

#include <visualization_msgs/MarkerArray.h>
#include "yaml-cpp/yaml.h"
#include <sstream>
#include <fstream>

#include <boost/unordered_map.hpp>

using namespace std;

#define SMALL_TAG_SIZE = 0.0358968; //0.0378968; // (~1.5" tags)
#define MED_TAG_SIZE = 0.0630174; // (~2.5" tags)
#define PAGE_TAG_SIZE = 0.165;

#define DEFAULT_TAG_FAMILY string("36h11")

class AprilTagsNode {
    ros::NodeHandle node_;
    //image_transport::ImageTransport image_;
    ros::Publisher marker_publisher_;
    ros::ServiceServer detect_enable_;

    AprilTags::TagDetector* tag_detector_;
    AprilTags::TagCodes tag_codes_;
    string tag_family_name_;

    sensor_msgs::CameraInfo camera_info_;

    int viewer_;
    boost::unordered_map<size_t, double> tag_sizes_;
    double default_tag_size_;
    string frame_;

    ros::Subscriber image_subscriber;
    ros::Subscriber info_subscriber;

    int enabled_;

public:
    AprilTagsNode() : node_("~"),
                      image_(node_),
                      tag_codes_(AprilTags::tagCodes36h11){

        string camera_topic_name = "/Image";
        string output_marker_list_topic_name = "/marker_array";
        string enable_service_name = "/Enable";
        string tag_data;

        // Get Parameters
        node_.param("/viewer", viewer_, 0);
        node_.param("/tag_family", tag_family_name_, DEFAULT_TAG_FAMILY);
        node_.param("/tag_data", tag_data, string(""));

        node_.param("/default_tag_size", default_tag_size_, SMALL_TAG_SIZE);
        node_.param("/tf_frame", frame_, string("/head_kinect_rgb_frame"));

        // Start the viewer if speficified
        if(viewer_){
            cvNamedWindow("AprilTags");
            cvStartWindowThread();
        }

        // Tag Detector
        SetTagCodeFromString(tag_family_name_);
        tag_detector_ = new AprilTags::TagDetector(tag_codes_);

        // Publisher
        marker_publisher_ = node_.advertise<visualization_msgs::MarkerArray>(
                output_marker_list_topic_name, 0);

        // Subscriber
        //image_transport::CameraSubscriber sub = image_.subscribeCamera(
        //        camera_topic_name, 1, &AprilTagsNode::ImageCallback, this);

        image_subscriber = node_.subscribe(camera_topic_name, 10, &AprilTagsNode::ImageCallback, this);

        info_subscriber = node_.subscribe("/camera_info", 10, &AprilTagsNode::InfoCallback, this);

        // Store Tag Sizes
        StoreTagSizes(tag_data);
    }

    ~AprilTagsNode(){
        cvDestroyWindow("AprilTags");
        delete tag_detector_;
    }

    void SetTagCodeFromString(string code_string){
        if(code_string == "16h5"){
            tag_codes_ = AprilTags::tagCodes16h5;
        }
        else if(code_string == "25h7"){
            tag_codes_ = AprilTags::tagCodes25h7;
        }
        else if(code_string == "25h9"){
            tag_codes_ = AprilTags::tagCodes25h9;
        }
        else if(code_string == "36h9"){
            tag_codes_ = AprilTags::tagCodes36h9;
        }
        else if(code_string == "36h11"){
            tag_codes_ = AprilTags::tagCodes36h11;
        }
        else{
            cout << "Invalid tag family specified : " << code_string << endl;
            exit(1);
        }
    }

    void StoreTagSizes(string tag_data){
        stringstream tag_ss;
        tag_ss << tag_data;
        YAML::Parser parser(tag_ss);
        YAML::Node doc;
        parser.GetNextDocument(doc);

        for(YAML::Iterator field = doc.begin(); field != doc.end(); ++field){
            //string index_str;
            //field.first() >> index_str;
            //size_t index = atoi(index_str.c_str());

            int index;
            field.first() >> index;

            const YAML::Node& value = field.second();
            for(YAML::Iterator sub_field = value.begin();
                    sub_field != value.end(); ++sub_field){

                string key;
                sub_field.first() >> key;

                if(key == "size"){
                    sub_field.second() >> tag_sizes_[index];
                }
            }
        }
    }

    void InfoCallback(
            const sensor_msgs::CameraInfoConstPtr& camera_info){
        camera_info_ = (*camera_info);
    }

    void ImageCallback(
            const sensor_msgs::ImageConstPtr& msg )//,
           // const sensor_msgs::CameraInfoConstPtr& camera_info)
    {

        sensor_msgs::CvBridge bridge;
        cv::Mat subscribed_image;
        try{
            subscribed_image = bridge.imgMsgToCv(msg, "bgr8");
        }
        catch(sensor_msgs::CvBridgeException& e){
            ROS_ERROR("Could not convert from '%s' to 'bgr8'.",
                      msg->encoding.c_str());
            return;
        }

        cv::Mat subscribed_gray;
        cv::cvtColor(subscribed_image, subscribed_gray, CV_BGR2GRAY);
        vector<AprilTags::TagDetection> detections =
                tag_detector_->extractTags(subscribed_gray);

        visualization_msgs::MarkerArray marker_transforms;

        for(unsigned int i = 0; i < detections.size(); ++i){
            double tag_size = default_tag_size_;
            boost::unordered_map<size_t, double>::iterator tag_size_it =
                    tag_sizes_.find(detections[i].id);

            if(tag_size_it != tag_sizes_.end()){
                tag_size = (*tag_size_it).second;
            }

            if(viewer_){
                detections[i].draw(subscribed_image);
            }

            Eigen::Matrix4d pose;
            pose = detections[i].getRelativeTransform(
                    tag_size,
                    (camera_info_).K[0], (camera_info_).K[4],
                    (camera_info_).K[2], (camera_info_).K[5]);
            Eigen::Matrix3d R = pose.block<3,3>(0,0);
            Eigen::Quaternion<double> q(R);

            visualization_msgs::Marker marker_transform;
            marker_transform.header.frame_id = frame_;
            marker_transform.header.stamp = ros::Time::now();
            stringstream convert;
            convert << "tag" << detections[i].id;
            marker_transform.ns = convert.str().c_str();
            marker_transform.id = detections[i].id;
            marker_transform.type = visualization_msgs::Marker::CUBE;
            marker_transform.action = visualization_msgs::Marker::ADD;
            marker_transform.pose.position.x = pose(0,3);
            marker_transform.pose.position.y = pose(1,3);
            marker_transform.pose.position.z = pose(2,3);
            marker_transform.pose.orientation.x = q.x();
            marker_transform.pose.orientation.y = q.y();
            marker_transform.pose.orientation.z = q.z();
            marker_transform.pose.orientation.w = q.w();
            marker_transform.scale.x = tag_size;
            marker_transform.scale.y = tag_size;
            marker_transform.scale.z = 0.05 * tag_size;
            marker_transform.color.r = 0.5;
            marker_transform.color.g = 0.5;
            marker_transform.color.b = 0.5;
            marker_transform.color.a = 1.0;
            marker_transforms.markers.push_back(marker_transform);
        }

        marker_publisher_.publish(marker_transforms);

        if(viewer_){
            cv::imshow("AprilTags", subscribed_image);
        }
    }
};

int main(int argc, char **argv){
    ros::init(argc, argv, "apriltags");

    AprilTagsNode detector;
    ros::spin();

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#include "CLog.hpp"

#include <amx/amx.h>

void CDebugInfoManager::Update(AMX * const amx, const char *func)
{
	m_Amx = amx;
	m_NativeName = func;

	m_Available =
		samplog::GetLastAmxLine(amx, m_Info.line) &&
		samplog::GetLastAmxFile(amx, m_Info.file) &&
		samplog::GetLastAmxFunction(amx, m_Info.function);
}

void CDebugInfoManager::Clear()
{
	m_Amx = nullptr;
	m_NativeName = nullptr;
	m_Available = false;
	m_Info.line = 0;
	m_Info.function = nullptr;
	m_Info.file = nullptr;
}

CScopedDebugInfo::CScopedDebugInfo(AMX * const amx, const char *func,
								   const char *params_format /* = ""*/)
{
	uint16_t amx_flags = 0;
	amx_Flags(amx, &amx_flags);
	m_HasAmxDebugSymbols = (amx_flags & AMX_FLAG_DEBUG) == AMX_FLAG_DEBUG;

	if (m_HasAmxDebugSymbols)
		CDebugInfoManager::Get()->Update(amx, func);

	auto &logger = CLog::Get()->m_Logger;
	if (logger.IsLogLevel(LogLevel::DEBUG))
		logger.LogNativeCall(amx, func, params_format);
}
<commit_msg>bug-fix: log calls from natives don't work when PAWN debug informations aren't available<commit_after>#include "CLog.hpp"

#include <amx/amx.h>

void CDebugInfoManager::Update(AMX * const amx, const char *func)
{
	m_Amx = amx;
	m_NativeName = func;

	m_Available =
		samplog::GetLastAmxLine(amx, m_Info.line) &&
		samplog::GetLastAmxFile(amx, m_Info.file) &&
		samplog::GetLastAmxFunction(amx, m_Info.function);
}

void CDebugInfoManager::Clear()
{
	m_Amx = nullptr;
	m_NativeName = nullptr;
	m_Available = false;
	m_Info.line = 0;
	m_Info.function = nullptr;
	m_Info.file = nullptr;
}

CScopedDebugInfo::CScopedDebugInfo(AMX * const amx, const char *func,
								   const char *params_format /* = ""*/)
{
	CDebugInfoManager::Get()->Update(amx, func);

	auto &logger = CLog::Get()->m_Logger;
	if (logger.IsLogLevel(LogLevel::DEBUG))
		logger.LogNativeCall(amx, func, params_format);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <cassert>

#include <QChar>
#include <QTextStream>
#include <QString>

#include "StreamIterator"
#include "TokenRule"
#include "OptionalRule"
#include "DiscardRule"
#include "MultipleRule"
#include "PredicateRule"
#include "ProxyRule"
#include "AlternativeRule"
#include "ReduceRule"
#include "config.h"

#include <QRegExp>
#include <QElapsedTimer>

#ifdef HAVE_BOOST
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#endif

#include "rules.hpp"

using namespace sprout;

const int RUNS = 1e5;

template <class Runner>
void runBenchmark(const char* name, Runner runner)
{
    QElapsedTimer timer;
    timer.start();

    for (int i = 0; i < RUNS; ++i) {
        runner();
    }

    std::cout << name << " took " << timer.elapsed() << " ms\n";
}

int main()
{
    using namespace make;

    auto fastWhitespace = rule::whitespace<QString>();

    auto whitespace = discard(
        multiple(predicate<QChar, QString>([](const QChar& input, QString&) {
            return input.isSpace();
        }))
    );

    auto name = aggregate<QString>(
        multiple(simplePredicate<QChar>([](const QChar& input) {
            return input.isLetter() || input == '_';
        })),
        [](QString& aggregate, const QChar& c) {
            aggregate += c;
        }
    );

    auto fastName = [](Cursor<QChar>& orig, Result<QString>& result) {
        auto iter = orig;
        QString aggr;
        while (iter) {
            auto input = *iter++;
            if (input.isLetter() || input == '_') {
                aggr += input;
            } else {
                break;
            }
        }
        if (aggr.isNull()) {
            return false;
        }
        result.insert(aggr);
        orig = iter;
        return true;
    };

    std::cout << "Running " << RUNS << " iteration" << (RUNS == 1 ? "" : "s") << "\n";

    std::cout << std::endl;
    std::cout << "=== Parser Benchmarks ===\n";

    const QString inputString("var bar");
    const QString targetString("bar");

    {
        QRegExp re("^var\\s+(\\w+)");
        runBenchmark("RegExp", [&]() {
            assert(re.indexIn(inputString, 0) == 0);
            assert(re.cap(1) == targetString);
        });
    }

    {
        auto benchmark = proxySequence<QChar, QString>(
            discard(OrderedTokenRule<QChar, QString>("var")),
            whitespace,
            name
        );
        runBenchmark("Sprout", [&]() {
            auto cursor = makeCursor<QChar>(&inputString);
            Result<QString> results;

            assert(benchmark(cursor, results));
            assert(targetString == *results);
        });
    }

    {
        auto benchmark = proxySequence<QChar, QString>(
            discard(OrderedTokenRule<QChar, QString>("var")),
            fastWhitespace,
            fastName
        );
        runBenchmark("Spfast", [&]() {
            auto cursor = makeCursor<QChar>(&inputString);
            Result<QString> results;

            assert(benchmark(cursor, results));
            assert(targetString == *results);
        });
    }

    {
        runBenchmark("Inline", [&]() {
            QString result;

            if (!inputString.startsWith("var")) {
                assert(false);
            }
            int mark = 3;
            while (mark < inputString.size() && inputString.at(mark).isSpace()) {
                ++mark;
            }
            QString aggr;
            while (mark < inputString.size() && inputString.at(mark).isLetter()) {
                aggr += inputString.at(mark++);
            }
            assert(aggr == targetString);
        });
    }

    std::cout << std::endl;
    std::cout << "=== Direct Match Benchmarks ===\n";

    const QString simpleTarget("var");

    {
        QRegExp re("^var");
        runBenchmark("RegExp", [&]() {
            assert(re.indexIn(inputString, 0) == 0);
            assert(re.cap(0) == simpleTarget);
        });
    }

    {
        auto benchmark = OrderedTokenRule<QChar, QString>("var", "var");
        runBenchmark("Sprout", [&]() {
            auto cursor = makeCursor<QChar>(&inputString);
            Result<QString> results;

            assert(benchmark(cursor, results));
            assert(*results == simpleTarget);
        });
    }

    {
        QString varStr("var");
        auto benchmark = [&](Cursor<QChar>& orig, Result<QString>& results) {
            auto iter = orig;
            for (int i = 0; i < varStr.size(); ++i) {
                if (!iter || *iter++ != varStr.at(i)) {
                    return false;
                }
            }
            orig = iter;
            results.insert(varStr);
            return true;
        };
        runBenchmark("Spfast", [&]() {
            auto cursor = makeCursor<QChar>(&inputString);
            Result<QString> results;

            assert(benchmark(cursor, results));
            assert(*results == simpleTarget);
        });
    }

    #ifdef HAVE_BOOST
    {
        std::string input("varbar");
        std::string target("bar");
        runBenchmark("Booost", [&]() {
            namespace qi = boost::spirit::qi;
            namespace ascii = boost::spirit::ascii;
            namespace phoenix = boost::phoenix;

            using qi::_1;

            std::string word;
            auto result = qi::phrase_parse(
                input.begin(),
                input.end(),
                (
                    "var" >> qi::string("bar")[phoenix::ref(word) = "bar"]
                ),
                ascii::space
            );

            assert(result);
            assert(word == target);
        });
    }
    #endif

    std::cout << std::endl;
    std::cout << "=== Aggregating Match Benchmarks ===\n";

    {
        const QString inputString("varbar");
        const QString targetString("bar");

        {
            QRegExp re("^var(\\w+)");
            runBenchmark("RegExp", [&]() {
                assert(re.indexIn(inputString, 0) == 0);
                assert(re.cap(1) == targetString);
            });
        }

        {
            auto benchmark = proxySequence<QChar, QString>(
                discard(OrderedTokenRule<QChar, QString>("var")),
                name
            );

            runBenchmark("Sprout", [&]() {
                auto cursor = makeCursor<QChar>(&inputString);
                Result<QString> results;

                assert(benchmark(cursor, results));
                assert(*results == targetString);
            });
        }

        {
            auto benchmark = proxySequence<QChar, QString>(
                discard(OrderedTokenRule<QChar, QString>("var")),
                fastName
            );

            runBenchmark("Spfast", [&]() {
                auto cursor = makeCursor<QChar>(&inputString);
                Result<QString> results;

                assert(benchmark(cursor, results));
                assert(*results == targetString);
            });
        }

        #ifdef HAVE_BOOST
        {
            std::string inputString = "varbar";
            std::string targetString = "bar";
            runBenchmark("Booost", [&]() {
                namespace qi = boost::spirit::qi;
                namespace ascii = boost::spirit::ascii;
                namespace phoenix = boost::phoenix;

                using qi::double_;
                using qi::_1;

                std::vector<char> letters;
                auto result = qi::phrase_parse(
                    inputString.begin(),
                    inputString.end(),
                    (
                        "var" >> (+ascii::char_)[phoenix::ref(letters) = _1]
                    ),
                    ascii::space
                );
                std::string word(letters.begin(), letters.end());

                assert(result);
                assert(word == targetString);
            });
        }
        #endif
    }

    std::cout << std::endl;
    std::cout << "=== Whitespace Match Benchmarks ===\n";

    {
        const QString inputString(" foo");
        const QString targetString("foo");

        {
            QRegExp re("^\\s+(foo)");
            runBenchmark("RegExp", [&]() {
                assert(re.indexIn(inputString, 0) == 0);
                assert(re.cap(1) == targetString);
            });
        }

        {
            auto benchmark = proxySequence<QChar, QString>(
                whitespace,
                OrderedTokenRule<QChar, QString>("foo", "foo")
            );

            runBenchmark("Sprout", [&]() {
                auto cursor = makeCursor<QChar>(&inputString);
                Result<QString> results;

                assert(benchmark(cursor, results));
                assert(*results == targetString);
            });
        }

        {
            auto benchmark = proxySequence<QChar, QString>(
                fastWhitespace,
                OrderedTokenRule<QChar, QString>("foo", "foo")
            );

            runBenchmark("Spfast", [&]() {
                auto cursor = makeCursor<QChar>(&inputString);
                Result<QString> results;

                assert(benchmark(cursor, results));
                assert(*results == targetString);
            });
        }

        #ifdef HAVE_BOOST
        {
            std::string input(" foo");
            std::string target("foo");
            runBenchmark("Booost", [&]() {
                namespace qi = boost::spirit::qi;
                namespace ascii = boost::spirit::ascii;
                namespace phoenix = boost::phoenix;

                using qi::_1;

                std::string word;
                auto result = qi::phrase_parse(
                    input.begin(),
                    input.end(),
                    (
                        *ascii::space >> qi::string("foo")[phoenix::ref(word) = "foo"]
                    ),
                    ascii::space
                );

                assert(result);
                assert(word == target);
            });
        }
        #endif
    }

    std::cout << std::endl;
    std::cout << "=== Lazy Match Benchmarks ===\n";

    {
        const QString inputString("foo #notime");
        const QString targetString("foo");

        {
            QRegExp re("^(foo)\\s*(#.*)?$");
            runBenchmark("RegExp", [&]() {
                assert(re.indexIn(inputString, 0) == 0);
                assert(re.cap(1) == targetString);
            });
        }

        {
            auto benchmark = proxySequence<QChar, QString>(
                OrderedTokenRule<QChar, QString>("foo", "foo"),
                discard(rule::whitespace<QString>()),
                discard(proxySequence<QChar, QString>(
                    OrderedTokenRule<QChar, QString>("#"),
                    proxyLazy<QChar, QString>(
                        any<QChar, QString>(),
                        proxyAlternative<QChar, QString>(
                            OrderedTokenRule<QChar, QString>("\n"),
                            make::end<QChar, QString>()
                        )
                    )
                ))
            );

            runBenchmark("Sprout", [&]() {
                auto cursor = makeCursor<QChar>(&inputString);
                Result<QString> results;

                assert(benchmark(cursor, results));
                assert(*results == targetString);
            });
        }

        {
            auto benchmark = proxySequence<QChar, QString>(
                OrderedTokenRule<QChar, QString>("foo", "foo"),
                discard(optional(fastWhitespace)),
                [](Cursor<QChar>& iter, Result<QString>& result) {
                    if (!iter || *iter != '#') {
                        return false;
                    }
                    while (iter && *iter != '\n') {
                        // Skip commented characters
                        ++iter;
                    }
                    return true;
                }
            );

            runBenchmark("Spfast", [&]() {
                auto cursor = makeCursor<QChar>(&inputString);
                Result<QString> results;

                assert(benchmark(cursor, results));
                assert(*results == targetString);
            });
        }

        #ifdef HAVE_BOOST
        {
            auto input = inputString.toStdString();
            auto target = targetString.toStdString();
            runBenchmark("Booost", [&]() {
                namespace qi = boost::spirit::qi;
                namespace ascii = boost::spirit::ascii;
                namespace phoenix = boost::phoenix;

                using qi::double_;
                using qi::_1;

                std::string word;
                auto result = qi::phrase_parse(
                    input.begin(),
                    input.end(),
                    (
                        qi::string("foo")[phoenix::ref(word) = "foo"] >> *ascii::space >> -("#" >> *ascii::char_)
                    ),
                    ascii::space
                );

                assert(result);
                assert(word == target);
            });
        }
        #endif
    }

    std::cout << std::endl;
    std::cout << "=== Cursor Benchmarks ===\n";

    {
        QString target("var foo");
        QString str("var foo");
        runBenchmark("Sprout", [&]() {
            auto cursor = makeCursor<QChar>(&str);
            for (int j = 0; j < target.size(); ++j) {
                if (target.at(j) != *cursor++) {
                    assert(false);
                }
            }
        });
    }

    {
        QString target("var foo");
        QString str("var foo");
        runBenchmark("Inline", [&]() {
            QString result;
            auto cursor = makeCursor<QChar>(&str);
            result = "foo";
            for (int j = 0; j < target.size(); ++j) {
                if (target.at(j) != str.at(j)) {
                    result = "";
                }
            }
        });
    }

    return 0;
}

// vim: set ts=4 sw=4 :
<commit_msg>Fixed inconsistent indentation in benchmark<commit_after>#include <iostream>
#include <cassert>

#include <QChar>
#include <QTextStream>
#include <QString>

#include "StreamIterator"
#include "TokenRule"
#include "OptionalRule"
#include "DiscardRule"
#include "MultipleRule"
#include "PredicateRule"
#include "ProxyRule"
#include "AlternativeRule"
#include "ReduceRule"
#include "config.h"

#include <QRegExp>
#include <QElapsedTimer>

#ifdef HAVE_BOOST
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#endif

#include "rules.hpp"

using namespace sprout;

const int RUNS = 1e5;

template <class Runner>
void runBenchmark(const char* name, Runner runner)
{
    QElapsedTimer timer;
    timer.start();

    for (int i = 0; i < RUNS; ++i) {
        runner();
    }

    std::cout << name << " took " << timer.elapsed() << " ms\n";
}

int main()
{
    using namespace make;

    auto fastWhitespace = rule::whitespace<QString>();

    auto whitespace = discard(
        multiple(predicate<QChar, QString>([](const QChar& input, QString&) {
            return input.isSpace();
        }))
    );

    auto name = aggregate<QString>(
        multiple(simplePredicate<QChar>([](const QChar& input) {
            return input.isLetter() || input == '_';
        })),
        [](QString& aggregate, const QChar& c) {
            aggregate += c;
        }
    );

    auto fastName = [](Cursor<QChar>& orig, Result<QString>& result) {
        auto iter = orig;
        QString aggr;
        while (iter) {
            auto input = *iter++;
            if (input.isLetter() || input == '_') {
                aggr += input;
            } else {
                break;
            }
        }
        if (aggr.isNull()) {
            return false;
        }
        result.insert(aggr);
        orig = iter;
        return true;
    };

    std::cout << "Running " << RUNS << " iteration" << (RUNS == 1 ? "" : "s") << "\n";
    std::cout << std::endl;

    {
        std::cout << "=== Parser Benchmarks ===\n";

        const QString inputString("var bar");
        const QString targetString("bar");

        {
            QRegExp re("^var\\s+(\\w+)");
            runBenchmark("RegExp", [&]() {
                assert(re.indexIn(inputString, 0) == 0);
                assert(re.cap(1) == targetString);
            });
        }

        {
            auto benchmark = proxySequence<QChar, QString>(
                discard(OrderedTokenRule<QChar, QString>("var")),
                whitespace,
                name
            );
            runBenchmark("Sprout", [&]() {
                auto cursor = makeCursor<QChar>(&inputString);
                Result<QString> results;

                assert(benchmark(cursor, results));
                assert(targetString == *results);
            });
        }

        {
            auto benchmark = proxySequence<QChar, QString>(
                discard(OrderedTokenRule<QChar, QString>("var")),
                fastWhitespace,
                fastName
            );
            runBenchmark("Spfast", [&]() {
                auto cursor = makeCursor<QChar>(&inputString);
                Result<QString> results;

                assert(benchmark(cursor, results));
                assert(targetString == *results);
            });
        }

        {
            runBenchmark("Inline", [&]() {
                QString result;

                if (!inputString.startsWith("var")) {
                    assert(false);
                }
                int mark = 3;
                while (mark < inputString.size() && inputString.at(mark).isSpace()) {
                    ++mark;
                }
                QString aggr;
                while (mark < inputString.size() && inputString.at(mark).isLetter()) {
                    aggr += inputString.at(mark++);
                }
                assert(aggr == targetString);
            });
        }

        std::cout << std::endl;
    }

    {
        std::cout << "=== Direct Match Benchmarks ===\n";

        const QString inputString("var");
        const QString targetString("var");

        {
            QRegExp re("^var");
            runBenchmark("RegExp", [&]() {
                assert(re.indexIn(inputString, 0) == 0);
                assert(re.cap(0) == targetString);
            });
        }

        {
            auto benchmark = OrderedTokenRule<QChar, QString>("var", "var");
            runBenchmark("Sprout", [&]() {
                auto cursor = makeCursor<QChar>(&inputString);
                Result<QString> results;

                assert(benchmark(cursor, results));
                assert(*results == targetString);
            });
        }

        {
            QString varStr("var");
            auto benchmark = [&](Cursor<QChar>& orig, Result<QString>& results) {
                auto iter = orig;
                for (int i = 0; i < varStr.size(); ++i) {
                    if (!iter || *iter++ != varStr.at(i)) {
                        return false;
                    }
                }
                orig = iter;
                results.insert(varStr);
                return true;
            };
            runBenchmark("Spfast", [&]() {
                auto cursor = makeCursor<QChar>(&inputString);
                Result<QString> results;

                assert(benchmark(cursor, results));
                assert(*results == targetString);
            });
        }

        #ifdef HAVE_BOOST
        {
            std::string input("varbar");
            std::string target("bar");
            runBenchmark("Booost", [&]() {
                namespace qi = boost::spirit::qi;
                namespace ascii = boost::spirit::ascii;
                namespace phoenix = boost::phoenix;

                using qi::_1;

                std::string word;
                auto result = qi::phrase_parse(
                    input.begin(),
                    input.end(),
                    (
                        "var" >> qi::string("bar")[phoenix::ref(word) = "bar"]
                    ),
                    ascii::space
                );

                assert(result);
                assert(word == target);
            });
        }
        #endif

        std::cout << std::endl;
    }

    {
        std::cout << "=== Aggregating Match Benchmarks ===\n";

        const QString inputString("varbar");
        const QString targetString("bar");

        {
            QRegExp re("^var(\\w+)");
            runBenchmark("RegExp", [&]() {
                assert(re.indexIn(inputString, 0) == 0);
                assert(re.cap(1) == targetString);
            });
        }

        {
            auto benchmark = proxySequence<QChar, QString>(
                discard(OrderedTokenRule<QChar, QString>("var")),
                name
            );

            runBenchmark("Sprout", [&]() {
                auto cursor = makeCursor<QChar>(&inputString);
                Result<QString> results;

                assert(benchmark(cursor, results));
                assert(*results == targetString);
            });
        }

        {
            auto benchmark = proxySequence<QChar, QString>(
                discard(OrderedTokenRule<QChar, QString>("var")),
                fastName
            );

            runBenchmark("Spfast", [&]() {
                auto cursor = makeCursor<QChar>(&inputString);
                Result<QString> results;

                assert(benchmark(cursor, results));
                assert(*results == targetString);
            });
        }

        #ifdef HAVE_BOOST
        {
            std::string inputString = "varbar";
            std::string targetString = "bar";
            runBenchmark("Booost", [&]() {
                namespace qi = boost::spirit::qi;
                namespace ascii = boost::spirit::ascii;
                namespace phoenix = boost::phoenix;

                using qi::double_;
                using qi::_1;

                std::vector<char> letters;
                auto result = qi::phrase_parse(
                    inputString.begin(),
                    inputString.end(),
                    (
                        "var" >> (+ascii::char_)[phoenix::ref(letters) = _1]
                    ),
                    ascii::space
                );
                std::string word(letters.begin(), letters.end());

                assert(result);
                assert(word == targetString);
            });
        }
        #endif

        std::cout << std::endl;
    }

    {
        std::cout << "=== Whitespace Match Benchmarks ===\n";

        const QString inputString(" foo");
        const QString targetString("foo");

        {
            QRegExp re("^\\s+(foo)");
            runBenchmark("RegExp", [&]() {
                assert(re.indexIn(inputString, 0) == 0);
                assert(re.cap(1) == targetString);
            });
        }

        {
            auto benchmark = proxySequence<QChar, QString>(
                whitespace,
                OrderedTokenRule<QChar, QString>("foo", "foo")
            );

            runBenchmark("Sprout", [&]() {
                auto cursor = makeCursor<QChar>(&inputString);
                Result<QString> results;

                assert(benchmark(cursor, results));
                assert(*results == targetString);
            });
        }

        {
            auto benchmark = proxySequence<QChar, QString>(
                fastWhitespace,
                OrderedTokenRule<QChar, QString>("foo", "foo")
            );

            runBenchmark("Spfast", [&]() {
                auto cursor = makeCursor<QChar>(&inputString);
                Result<QString> results;

                assert(benchmark(cursor, results));
                assert(*results == targetString);
            });
        }

        #ifdef HAVE_BOOST
        {
            std::string input(" foo");
            std::string target("foo");
            runBenchmark("Booost", [&]() {
                namespace qi = boost::spirit::qi;
                namespace ascii = boost::spirit::ascii;
                namespace phoenix = boost::phoenix;

                using qi::_1;

                std::string word;
                auto result = qi::phrase_parse(
                    input.begin(),
                    input.end(),
                    (
                        *ascii::space >> qi::string("foo")[phoenix::ref(word) = "foo"]
                    ),
                    ascii::space
                );

                assert(result);
                assert(word == target);
            });
        }
        #endif

        std::cout << std::endl;
    }

    {
        std::cout << "=== Lazy Match Benchmarks ===\n";

        const QString inputString("foo #notime");
        const QString targetString("foo");

        {
            QRegExp re("^(foo)\\s*(#.*)?$");
            runBenchmark("RegExp", [&]() {
                assert(re.indexIn(inputString, 0) == 0);
                assert(re.cap(1) == targetString);
            });
        }

        {
            auto benchmark = proxySequence<QChar, QString>(
                OrderedTokenRule<QChar, QString>("foo", "foo"),
                discard(rule::whitespace<QString>()),
                discard(proxySequence<QChar, QString>(
                    OrderedTokenRule<QChar, QString>("#"),
                    proxyLazy<QChar, QString>(
                        any<QChar, QString>(),
                        proxyAlternative<QChar, QString>(
                            OrderedTokenRule<QChar, QString>("\n"),
                            make::end<QChar, QString>()
                        )
                    )
                ))
            );

            runBenchmark("Sprout", [&]() {
                auto cursor = makeCursor<QChar>(&inputString);
                Result<QString> results;

                assert(benchmark(cursor, results));
                assert(*results == targetString);
            });
        }

        {
            auto benchmark = proxySequence<QChar, QString>(
                OrderedTokenRule<QChar, QString>("foo", "foo"),
                discard(optional(fastWhitespace)),
                [](Cursor<QChar>& iter, Result<QString>& result) {
                    if (!iter || *iter != '#') {
                        return false;
                    }
                    while (iter && *iter != '\n') {
                        // Skip commented characters
                        ++iter;
                    }
                    return true;
                }
            );

            runBenchmark("Spfast", [&]() {
                auto cursor = makeCursor<QChar>(&inputString);
                Result<QString> results;

                assert(benchmark(cursor, results));
                assert(*results == targetString);
            });
        }

        #ifdef HAVE_BOOST
        {
            auto input = inputString.toStdString();
            auto target = targetString.toStdString();
            runBenchmark("Booost", [&]() {
                namespace qi = boost::spirit::qi;
                namespace ascii = boost::spirit::ascii;
                namespace phoenix = boost::phoenix;

                using qi::double_;
                using qi::_1;

                std::string word;
                auto result = qi::phrase_parse(
                    input.begin(),
                    input.end(),
                    (
                        qi::string("foo")[phoenix::ref(word) = "foo"] >> *ascii::space >> -("#" >> *ascii::char_)
                    ),
                    ascii::space
                );

                assert(result);
                assert(word == target);
            });
        }
        #endif

        std::cout << std::endl;
    }

    {
        std::cout << "=== Cursor Benchmarks ===\n";

        {
            QString target("var foo");
            QString str("var foo");
            runBenchmark("Sprout", [&]() {
                auto cursor = makeCursor<QChar>(&str);
                for (int j = 0; j < target.size(); ++j) {
                    if (target.at(j) != *cursor++) {
                        assert(false);
                    }
                }
            });
        }

        {
            QString target("var foo");
            QString str("var foo");
            runBenchmark("Inline", [&]() {
                QString result;
                auto cursor = makeCursor<QChar>(&str);
                result = "foo";
                for (int j = 0; j < target.size(); ++j) {
                    if (target.at(j) != str.at(j)) {
                        result = "";
                    }
                }
            });
        }
    }

    return 0;
}

// vim: set ts=4 sw=4 :
<|endoftext|>