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

#include <boost/foreach.hpp>
#include <boost/python.hpp>
#include <boost/python/raw_function.hpp>
#include <boost/python/iterator.hpp>
#include <boost/python/slice.hpp>
#include <boost/python/stl_iterator.hpp>

#include <ecto/python/std_map_indexing_suite.hpp>
#include <ecto/python/raw_constructor.hpp>
#include <ecto/python/repr.hpp>
#include <string>
namespace bp = boost::python;
#include "tendril_spec.hpp"

namespace ecto
{
  void inspect_impl(ecto::cell_ptr m, const boost::python::tuple& args,
                    const boost::python::dict& kwargs);

  namespace py
  {

    struct cellwrap: cell, bp::wrapper<cell>
    {
      cellwrap():initialized_(false){}

      void dispatch_start()
      {
        ecto::py::scoped_call_back_to_python scb;
        if (bp::override start = this->get_override("start"))
          start();
      }

      void dispatch_stop()
      {
        ecto::py::scoped_call_back_to_python scb;
        if (bp::override stop = this->get_override("stop"))
          stop();
      }

      void dispatch_declare_params(tendrils& params)
      {
        ecto::py::scoped_call_back_to_python scb;
        if (bp::override init = this->get_override("declare_params"))
          init(boost::ref(params));
      }

      void dispatch_declare_io(const tendrils&params, tendrils& inputs, tendrils& outputs)
      {
        ecto::py::scoped_call_back_to_python scb;
        if (bp::override declare_io = this->get_override("declare_io"))
          declare_io(boost::ref(params), boost::ref(inputs), boost::ref(outputs));
      }

      void dispatch_configure(const tendrils& params, const tendrils& inputs, const tendrils& outputs)
      {
        ecto::py::scoped_call_back_to_python scb;
        if (bp::override config = this->get_override("configure"))
          config(boost::ref(params));
      }

      struct YouveBeenServed
      {
        void operator()(const tendrils::value_type& t)
        {
          t.second->notify();
        }
      };

      ReturnCode dispatch_process(const tendrils& inputs, const tendrils& outputs)
      {
        ecto::py::scoped_call_back_to_python scb;
        int value = OK;
        std::for_each(inputs.begin(),inputs.end(), YouveBeenServed());
        if (bp::override proc = this->get_override("process"))
          {
            value = proc(boost::ref(inputs), boost::ref(outputs));
          }
        std::for_each(outputs.begin(),outputs.end(),YouveBeenServed());
        return ReturnCode(value);
      }

      bool init()
      {
        bool initialized = initialized_;
        initialized_ = false;
        return initialized;
      }

      std::string dispatch_name() const
      {
        bp::reference_existing_object::apply<cellwrap*>::type converter;
        PyObject* obj = converter(this);
        bp::object real_obj = bp::object(bp::handle<>(obj));
        bp::object n = real_obj.attr("__class__").attr("__name__");
        std::string nm = bp::extract<std::string>(n);
        return nm;
      }

      static std::string doc(cellwrap* mod)
      {
        bp::reference_existing_object::apply<cellwrap*>::type converter;
        PyObject* obj = converter(mod);
        bp::object real_obj = bp::object(bp::handle<>(obj));
        bp::object n = real_obj.attr("__class__").attr("__doc__");
        bp::extract<std::string> get_str(n);
        if (get_str.check())
          return get_str();
        return "No Doc str.";
      }

      cell_ptr dispatch_clone() const
      {
        throw std::logic_error("Clone is not implemented!");
        return cell_ptr();
      }
      bool initialized_;
    };

    const tendrils& inputs(cell& mod)
    {
      return mod.inputs;
    }
    tendrils& outputs(cell& mod)
    {
      return mod.outputs;
    }
    tendrils& params(cell& mod)
    {
      return mod.parameters;
    }

    void wrapModule()
    {
      //use private names so that python people know these are internal
      bp::class_<cell, boost::shared_ptr<cell>, boost::noncopyable>("_cell_cpp", bp::no_init)
        .def("type", &cell::type)
        .def("configure", ((void(cell::*)()) &cell::configure))
        ;

      bp::class_<cellwrap, boost::shared_ptr<cellwrap>, boost::noncopyable> ("_cell_base" /*bp::no_init*/)
        .def("_set_strand", &cell::set_strand)
        .def("_reset_strand", &cell::reset_strand)
        .def("construct", &inspect_impl)
        .def("declare_params", &cell::declare_params)
        .def("declare_io", ((void(cell::*)()) &cell::declare_io))
        .def("configure", ((void(cell::*)()) &cell::configure))
        .def("process", (void(cell::*)()) &cell::process)
        .def("start", (void(cell::*)()) &cell::start)
        .def("stop", (void(cell::*)()) &cell::stop)
        .def("verify_params", &cell::verify_params)
        .def("verify_inputs", &cell::verify_inputs)

        .add_property("inputs", make_function(&inputs, bp::return_internal_reference<>()))
        .add_property("outputs", make_function(outputs, bp::return_internal_reference<>()))
        .add_property("params", make_function(params, bp::return_internal_reference<>()))
        .def("typename", &cell::type)
        .def("name",(((std::string(cell::*)() const) &cell::name)))
        .def("name",(((void(cell::*)(const std::string&)) &cell::name)))

        .def("doc", &cellwrap::doc)
        .def("short_doc",(std::string(cell::*)() const) &cell::short_doc)
        .def("gen_doc", &cell::gen_doc)
        .def("__getitem__", getitem_str)
        .def("__getitem__", getitem_tuple)
        .def("__getitem__", getitem_list)
        .def("__getitem__", getitem_slice)
        ;

      bp::def("__getitem_str__", getitem_str);
      bp::def("__getitem_slice__", getitem_slice);
      bp::def("__getitem_tuple__", getitem_tuple);
      bp::def("__getitem_list__", getitem_list);

      bp::class_<TendrilSpecification>("TendrilSpecification")
        .def_readwrite("module_input", &TendrilSpecification::mod_input)
        .def_readwrite("module_output", &TendrilSpecification::mod_output)
        .def_readwrite("key", &TendrilSpecification::key)
        .def("to_tendril",&TendrilSpecification::toTendril)
        ;

      bp::class_<TendrilSpecifications>("TendrilSpecifications", bp::init<bp::list>())
        .def("to_tendrils", &TendrilSpecifications::toTendrils)
        .staticmethod("to_tendrils")
        .def("to_spec", &TendrilSpecifications::toSpec)
        .def("__rshift__", rshift_spec)
        .def("__rshift__", rshift_spec_tuples)
        ;

      bp::enum_<tendril_type>("tendril_type")
        .value("INPUT",INPUT)
        .value("OUTPUT",OUTPUT)
        .value("PARAMETER",PARAMETER)
        .export_values()
        ;
      bp::enum_<ecto::ReturnCode>("ReturnCode")
        .value("OK",OK)
        .value("QUIT",QUIT)
        .export_values()
        ;
    }
  }

  void inspect_impl(ecto::cell_ptr m, const boost::python::tuple& args,
                    const boost::python::dict& kwargs)
  {

    if (bp::len(args) > 1)
      throw std::runtime_error("Only one non-keyword argument allowed, this will specify instance name");

    if (bp::len(args) == 0)
      {
        // generate default name == type
        m->name(m->type());
      }
    else
      {
        bp::extract<std::string> e(args[0]);
        if (! e.check())
          throw std::runtime_error("Non-keyword argument (instance name) not convertible to string.");
        m->name(e());
      }
    m->declare_params();

    ECTO_LOG_DEBUG("inspect_impl %s", m->name());

    bp::list l = kwargs.items();
    for (int j = 0; j < bp::len(l); ++j)
      {
        bp::object key = l[j][0];
        bp::object value = l[j][1];
        std::string keystring = bp::extract<std::string>(key);
        if (keystring == "strand")
          {
            ecto::strand s = bp::extract<ecto::strand>(value);
            m->strand_ = s;
            ECTO_LOG_DEBUG("Found a strand for cell %s, id=%p", m->name() % s.id());
          }
        else
          {
            tendril_ptr tp = m->parameters[keystring];
            try{
              *tp << value;
            }catch(ecto::except::TypeMismatch& e)
              {
                e << except::tendril_key(keystring);
                e << except::cell_name(m->name());
                throw;
              }
            tp->user_supplied(true);
            tp->dirty(true);
          }
      }
    m->declare_io();
  }
}

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

#include <boost/foreach.hpp>
#include <boost/python.hpp>
#include <boost/python/raw_function.hpp>
#include <boost/python/iterator.hpp>
#include <boost/python/slice.hpp>
#include <boost/python/stl_iterator.hpp>

#include <ecto/python/std_map_indexing_suite.hpp>
#include <ecto/python/raw_constructor.hpp>
#include <ecto/python/repr.hpp>
#include <string>
namespace bp = boost::python;
#include "tendril_spec.hpp"

namespace ecto
{
  void inspect_impl(ecto::cell_ptr m, const boost::python::tuple& args,
                    const boost::python::dict& kwargs);

  namespace py
  {

    struct cellwrap: cell, bp::wrapper<cell>
    {
      cellwrap():initialized_(false){}

      void dispatch_start()
      {
        ecto::py::scoped_call_back_to_python scb;
        if (bp::override start = this->get_override("start"))
          start();
      }

      void dispatch_stop()
      {
        ecto::py::scoped_call_back_to_python scb;
        if (bp::override stop = this->get_override("stop"))
          stop();
      }

      void dispatch_declare_params(tendrils& params)
      {
        ecto::py::scoped_call_back_to_python scb;
        if (bp::override init = this->get_override("declare_params"))
          init(boost::ref(params));
      }

      void dispatch_declare_io(const tendrils&params, tendrils& inputs, tendrils& outputs)
      {
        ecto::py::scoped_call_back_to_python scb;
        if (bp::override declare_io = this->get_override("declare_io"))
          declare_io(boost::ref(params), boost::ref(inputs), boost::ref(outputs));
      }

      void dispatch_configure(const tendrils& params, const tendrils& inputs, const tendrils& outputs)
      {
        ecto::py::scoped_call_back_to_python scb;
        if (bp::override config = this->get_override("configure"))
          config(boost::ref(params));
      }

      struct YouveBeenServed
      {
        void operator()(const tendrils::value_type& t)
        {
          t.second->notify();
        }
      };

      ReturnCode dispatch_process(const tendrils& inputs, const tendrils& outputs)
      {
        ecto::py::scoped_call_back_to_python scb;
        int value = OK;
        std::for_each(inputs.begin(),inputs.end(), YouveBeenServed());
        if (bp::override proc = this->get_override("process"))
          {
            bp::object rval = proc(boost::ref(inputs), boost::ref(outputs));
            bp::extract<int> x(rval);
            if(x.check()){
              value = x();
            }
          }
        std::for_each(outputs.begin(),outputs.end(),YouveBeenServed());
        return ReturnCode(value);
      }

      bool init()
      {
        bool initialized = initialized_;
        initialized_ = false;
        return initialized;
      }

      std::string dispatch_name() const
      {
        bp::reference_existing_object::apply<cellwrap*>::type converter;
        PyObject* obj = converter(this);
        bp::object real_obj = bp::object(bp::handle<>(obj));
        bp::object n = real_obj.attr("__class__").attr("__name__");
        std::string nm = bp::extract<std::string>(n);
        return nm;
      }

      static std::string doc(cellwrap* mod)
      {
        bp::reference_existing_object::apply<cellwrap*>::type converter;
        PyObject* obj = converter(mod);
        bp::object real_obj = bp::object(bp::handle<>(obj));
        bp::object n = real_obj.attr("__class__").attr("__doc__");
        bp::extract<std::string> get_str(n);
        if (get_str.check())
          return get_str();
        return "No Doc str.";
      }

      cell_ptr dispatch_clone() const
      {
        throw std::logic_error("Clone is not implemented!");
        return cell_ptr();
      }
      bool initialized_;
    };

    const tendrils& inputs(cell& mod)
    {
      return mod.inputs;
    }
    tendrils& outputs(cell& mod)
    {
      return mod.outputs;
    }
    tendrils& params(cell& mod)
    {
      return mod.parameters;
    }

    void wrapModule()
    {
      //use private names so that python people know these are internal
      bp::class_<cell, boost::shared_ptr<cell>, boost::noncopyable>("_cell_cpp", bp::no_init)
        .def("type", &cell::type)
        .def("configure", ((void(cell::*)()) &cell::configure))
        ;

      bp::class_<cellwrap, boost::shared_ptr<cellwrap>, boost::noncopyable> ("_cell_base" /*bp::no_init*/)
        .def("_set_strand", &cell::set_strand)
        .def("_reset_strand", &cell::reset_strand)
        .def("construct", &inspect_impl)
        .def("declare_params", &cell::declare_params)
        .def("declare_io", ((void(cell::*)()) &cell::declare_io))
        .def("configure", ((void(cell::*)()) &cell::configure))
        .def("process", (void(cell::*)()) &cell::process)
        .def("start", (void(cell::*)()) &cell::start)
        .def("stop", (void(cell::*)()) &cell::stop)
        .def("verify_params", &cell::verify_params)
        .def("verify_inputs", &cell::verify_inputs)

        .add_property("inputs", make_function(&inputs, bp::return_internal_reference<>()))
        .add_property("outputs", make_function(outputs, bp::return_internal_reference<>()))
        .add_property("params", make_function(params, bp::return_internal_reference<>()))
        .def("typename", &cell::type)
        .def("name",(((std::string(cell::*)() const) &cell::name)))
        .def("name",(((void(cell::*)(const std::string&)) &cell::name)))

        .def("doc", &cellwrap::doc)
        .def("short_doc",(std::string(cell::*)() const) &cell::short_doc)
        .def("gen_doc", &cell::gen_doc)
        .def("__getitem__", getitem_str)
        .def("__getitem__", getitem_tuple)
        .def("__getitem__", getitem_list)
        .def("__getitem__", getitem_slice)
        ;

      bp::def("__getitem_str__", getitem_str);
      bp::def("__getitem_slice__", getitem_slice);
      bp::def("__getitem_tuple__", getitem_tuple);
      bp::def("__getitem_list__", getitem_list);

      bp::class_<TendrilSpecification>("TendrilSpecification")
        .def_readwrite("module_input", &TendrilSpecification::mod_input)
        .def_readwrite("module_output", &TendrilSpecification::mod_output)
        .def_readwrite("key", &TendrilSpecification::key)
        .def("to_tendril",&TendrilSpecification::toTendril)
        ;

      bp::class_<TendrilSpecifications>("TendrilSpecifications", bp::init<bp::list>())
        .def("to_tendrils", &TendrilSpecifications::toTendrils)
        .staticmethod("to_tendrils")
        .def("to_spec", &TendrilSpecifications::toSpec)
        .def("__rshift__", rshift_spec)
        .def("__rshift__", rshift_spec_tuples)
        ;

      bp::enum_<tendril_type>("tendril_type")
        .value("INPUT",INPUT)
        .value("OUTPUT",OUTPUT)
        .value("PARAMETER",PARAMETER)
        .export_values()
        ;
      bp::enum_<ecto::ReturnCode>("ReturnCode")
        .value("OK",OK)
        .value("QUIT",QUIT)
        .export_values()
        ;
    }
  }

  void inspect_impl(ecto::cell_ptr m, const boost::python::tuple& args,
                    const boost::python::dict& kwargs)
  {

    if (bp::len(args) > 1)
      throw std::runtime_error("Only one non-keyword argument allowed, this will specify instance name");

    if (bp::len(args) == 0)
      {
        // generate default name == type
        m->name(m->type());
      }
    else
      {
        bp::extract<std::string> e(args[0]);
        if (! e.check())
          throw std::runtime_error("Non-keyword argument (instance name) not convertible to string.");
        m->name(e());
      }
    m->declare_params();

    ECTO_LOG_DEBUG("inspect_impl %s", m->name());

    bp::list l = kwargs.items();
    for (int j = 0; j < bp::len(l); ++j)
      {
        bp::object key = l[j][0];
        bp::object value = l[j][1];
        std::string keystring = bp::extract<std::string>(key);
        if (keystring == "strand")
          {
            ecto::strand s = bp::extract<ecto::strand>(value);
            m->strand_ = s;
            ECTO_LOG_DEBUG("Found a strand for cell %s, id=%p", m->name() % s.id());
          }
        else
          {
            tendril_ptr tp = m->parameters[keystring];
            try{
              *tp << value;
            }catch(ecto::except::TypeMismatch& e)
              {
                e << except::tendril_key(keystring);
                e << except::cell_name(m->name());
                throw;
              }
            tp->user_supplied(true);
            tp->dirty(true);
          }
      }
    m->declare_io();
  }
}

<|endoftext|>


<commit_before>#include "DBase3File.h"

#include "utf8.h"

#include <cstring>
#include <cassert>
#include <shapefil.h>
#include <iostream>

using namespace std;
using namespace table;

class table::DBase3Handle {
public:
  DBase3Handle() { }
  ~DBase3Handle() {
    if (h) {
      DBFClose(h);
    }
  }

  void open(const std::string & fn) {
    h = DBFOpen(fn.c_str(), "rb");
    if (!h) {
      cerr << "failed to open DBF " << fn << endl;
    }
  }

  int readIntegerAttribute(int rec, int field) { return DBFReadIntegerAttribute(h, rec, field); }
  double readDoubleAttribute(int rec, int field) { return DBFReadDoubleAttribute(h, rec, field); }
  std::string readStringAttribute(int rec, int field) {
    const char * tmp = DBFReadStringAttribute(h, rec, field);
    if (tmp) {
      string output;
      while (!tmp) {
	utf8::append((unsigned char)*tmp, back_inserter(output));
	tmp++;
      }
      return output;
    }
    return "";
  }
  bool readBoolAttribute(int rec, int field) { return DBFReadLogicalAttribute(h, rec, field); }
  bool isNull(int rec, int field) { return DBFIsAttributeNULL(h, rec, field); }
  unsigned int getRecordCount() { return h ? DBFGetRecordCount(h) : 0; }
  unsigned int getFieldCount() { return h ? DBFGetFieldCount(h) : 0; }
  string getFieldName(int field) {
    char fieldname[255];
    DBFFieldType type = DBFGetFieldInfo(h, field, fieldname, 0, 0);
    return fieldname;
  }

private:
  DBFHandle h = 0;
};

DBase3File::DBase3File(const string & filename) {
  record_count = 0;
  openDBF(filename);
}

bool
DBase3File::openDBF(const string & filename) {
  dbf = std::make_shared<DBase3Handle>();
  dbf->open(filename);
  record_count = dbf->getRecordCount();
  unsigned int field_count = dbf->getFieldCount();
  for (unsigned int i = 0; i < field_count; i++) {
    string name = dbf->getFieldName(i);
    columns.push_back(std::make_shared<DBase3Column>(dbf, i, record_count, name));
  }
  return true;
}

DBase3Column::DBase3Column(const std::shared_ptr<DBase3Handle> _dbf,
			   int _column_index,
			   int _num_rows,
			   const std::string & _name)
: ColumnBase(_name),
  dbf(_dbf),
  column_index(_column_index),
  num_rows(_num_rows)
{

}

long long
DBase3Column::getInt64(int i) const {
  if (i >= 0 && i < num_rows) {
    return dbf->readIntegerAttribute(i, column_index);
  } else {
    return 0;
  }
}

std::string
DBase3Column::getText(int i) const {
  if (i >= 0 && i < num_rows) {
    return dbf->readStringAttribute(i, column_index);
  } else {
    return "";
  }
}

double
DBase3Column::getDouble(int i) const {
  if (i >= 0 && i < num_rows) {
    return dbf->readIntegerAttribute(i, column_index);
  } else {
    return 0;
  }
}

int
DBase3Column::getInt(int i) const {
  if (i >= 0 && i < num_rows) {
    return dbf->readIntegerAttribute(i, column_index);
  } else {
    return 0;
  }
}
<commit_msg>remove name from Column<commit_after>#include "DBase3File.h"

#include "utf8.h"

#include <cstring>
#include <cassert>
#include <shapefil.h>
#include <iostream>

using namespace std;
using namespace table;

class table::DBase3Handle {
public:
  DBase3Handle() { }
  ~DBase3Handle() {
    if (h) {
      DBFClose(h);
    }
  }

  void open(const std::string & fn) {
    h = DBFOpen(fn.c_str(), "rb");
    if (!h) {
      cerr << "failed to open DBF " << fn << endl;
    }
  }

  int readIntegerAttribute(int rec, int field) { return DBFReadIntegerAttribute(h, rec, field); }
  double readDoubleAttribute(int rec, int field) { return DBFReadDoubleAttribute(h, rec, field); }
  std::string readStringAttribute(int rec, int field) {
    const char * tmp = DBFReadStringAttribute(h, rec, field);
    if (tmp) {
      string output;
      while (!tmp) {
	utf8::append((unsigned char)*tmp, back_inserter(output));
	tmp++;
      }
      return output;
    }
    return "";
  }
  bool readBoolAttribute(int rec, int field) { return DBFReadLogicalAttribute(h, rec, field); }
  bool isNull(int rec, int field) { return DBFIsAttributeNULL(h, rec, field); }
  unsigned int getRecordCount() { return h ? DBFGetRecordCount(h) : 0; }
  unsigned int getFieldCount() { return h ? DBFGetFieldCount(h) : 0; }
  string getFieldName(int field) {
    char fieldname[255];
    DBFFieldType type = DBFGetFieldInfo(h, field, fieldname, 0, 0);
    return fieldname;
  }

private:
  DBFHandle h = 0;
};

DBase3File::DBase3File(const string & filename) {
  record_count = 0;
  openDBF(filename);
}

bool
DBase3File::openDBF(const string & filename) {
  dbf = std::make_shared<DBase3Handle>();
  dbf->open(filename);
  record_count = dbf->getRecordCount();
  unsigned int field_count = dbf->getFieldCount();
  for (unsigned int i = 0; i < field_count; i++) {
    string name = dbf->getFieldName(i);
    columns[name] = std::make_shared<DBase3Column>(dbf, i, record_count);
  }
  return true;
}

DBase3Column::DBase3Column(const std::shared_ptr<DBase3Handle> _dbf,
			   int _column_index,
			   int _num_rows)
: dbf(_dbf),
  column_index(_column_index),
  num_rows(_num_rows)
{

}

long long
DBase3Column::getInt64(int i) const {
  if (i >= 0 && i < num_rows) {
    return dbf->readIntegerAttribute(i, column_index);
  } else {
    return 0;
  }
}

std::string
DBase3Column::getText(int i) const {
  if (i >= 0 && i < num_rows) {
    return dbf->readStringAttribute(i, column_index);
  } else {
    return "";
  }
}

double
DBase3Column::getDouble(int i) const {
  if (i >= 0 && i < num_rows) {
    return dbf->readIntegerAttribute(i, column_index);
  } else {
    return 0;
  }
}

int
DBase3Column::getInt(int i) const {
  if (i >= 0 && i < num_rows) {
    return dbf->readIntegerAttribute(i, column_index);
  } else {
    return 0;
  }
}
<|endoftext|>


<commit_before>#include "DeviceList.h"
#include "WProgram.h"
#undef min // Arduino libraries define max and min macros which mess with <vector>
#undef max
#include <vector>
#include <cstdint>
#include "Device.h"
#include "config.h"
#include "DigitalInput.h"
#include "DigitalOutput.h"
#include "AnalogInput.h"
#include "AnalogOutput.h"
#include "Motor.h"
#include "Encoder.h"
#include "Gyro.h"
#include "Color.h"
#include "Servo.h"

namespace tamproxy {

// Handles a packet request to it
// Capable of adding to, removing from, and clearing the devices
std::vector<uint8_t> DeviceList::handleRequest(std::vector<uint8_t> &request) {
    if (request.size() == 0) { return {REQUEST_LENGTH_INVALID_CODE}; }
    switch(request[0]) {
    case DEVICELIST_ADD_CODE:
        return add(request);
    case DEVICELIST_REMOVE_CODE:
        if (request.size() == 2) {
            return remove(request[1]);
        } else { return {REQUEST_LENGTH_INVALID_CODE}; }
    case DEVICELIST_CLEAR_CODE:
        if (request.size() == 1) {
            clear();
            return {OK_CODE};
        } else { return {REQUEST_LENGTH_INVALID_CODE}; }
    case DEVICELIST_HELLO_CODE:
        // A HELLO request that just responds with a constant
        // Useful when establishing the connection
        return {DEVICELIST_HELLO_CODE};
    default:
        return {REQUEST_BODY_INVALID_CODE};
    }
}

// Gets a device pointer at a certain index of the list.
Device* DeviceList::get(uint8_t idx) {
    if (idx < _devices.size()) {
        return _devices[idx];
    }
    else {
        return nullptr;
    }
}

// Removes a device at a certain index of the list. Returns a status response
std::vector<uint8_t> DeviceList::remove(uint8_t idx) {
    if (idx < _devices.size()) {
        delete _devices[idx];
        _devices[idx] = nullptr;
        return {OK_CODE};
    } else { return {DEVICE_OOR_CODE}; }
}

// Adds a new device to the end of the list. Returns a status response.
// If successful, the response also includes the index of the added device.
std::vector<uint8_t> DeviceList::add(std::vector<uint8_t>& request) {
    Device* d;
    switch(request[1]) {
        case DIGITAL_INPUT_CODE:
            if (request.size() == 4) {
                d = new DigitalInput(request[2], request[3]);
            } else { return {REQUEST_LENGTH_INVALID_CODE}; };
            break;
        case DIGITAL_OUTPUT_CODE:
            if (request.size() == 3) {
                d = new DigitalOutput(request[2]);
            } else { return {REQUEST_LENGTH_INVALID_CODE}; };
            break;
        case ANALOG_INPUT_CODE:
            if (request.size() == 3) {
                d = new AnalogInput(request[2]);
            } else { return {REQUEST_LENGTH_INVALID_CODE}; };
            break;
        case ANALOG_OUTPUT_CODE:
            if (request.size() == 3) {
                d = new AnalogOutput(request[2]);
            } else { return {REQUEST_LENGTH_INVALID_CODE}; };
            break;
        case MOTOR_CODE:
            if (request.size() == 4) {
                d = new Motor(request[2], request[3]);
            } else { return {REQUEST_LENGTH_INVALID_CODE}; };
            break;
        case ENCODER_CODE:
            if (request.size() == 4) {
                d = new Encoder(request[2], request[3]);
            } else { return {REQUEST_LENGTH_INVALID_CODE}; };
            break;
        case GYRO_CODE:
            if (request.size() == 3) {
                d = new Gyro(request[2]);
            } else { return {REQUEST_LENGTH_INVALID_CODE}; };
            break;
        case COLOR_CODE:
            if (request.size() == 4) {
                d = new Color(request[2], request[3]);
            } else { return {REQUEST_LENGTH_INVALID_CODE}; };
            break;
	    case SERVO_CODE:
		    if (request.size() == 3) {
                d = new Servo(request[2]);
            } else { return {REQUEST_LENGTH_INVALID_CODE}; };
            break;
        default:
            return {DEVICE_INVALID_CODE};
    }
    _devices.push_back(d);
    return {OK_CODE, static_cast<uint8_t>(_devices.size()-1)};
}

// Clears the device list and resets all pins, makin sure that the devices get deallocated
void DeviceList::clear() {
    for (uint8_t i = 0; i < NUM_PINS; i++) {
        pinMode(i, INPUT);
    }
    for (uint8_t i = 0; i < _devices.size(); i++) {
        delete _devices[i];
    }
    _devices.clear();
}

}
<commit_msg>If a remove device request was sent, this entry will be null!<commit_after>#include "DeviceList.h"
#include "WProgram.h"
#undef min // Arduino libraries define max and min macros which mess with <vector>
#undef max
#include <vector>
#include <cstdint>
#include "Device.h"
#include "config.h"
#include "DigitalInput.h"
#include "DigitalOutput.h"
#include "AnalogInput.h"
#include "AnalogOutput.h"
#include "Motor.h"
#include "Encoder.h"
#include "Gyro.h"
#include "Color.h"
#include "Servo.h"

namespace tamproxy {

// Handles a packet request to it
// Capable of adding to, removing from, and clearing the devices
std::vector<uint8_t> DeviceList::handleRequest(std::vector<uint8_t> &request) {
    if (request.size() == 0) { return {REQUEST_LENGTH_INVALID_CODE}; }
    switch(request[0]) {
    case DEVICELIST_ADD_CODE:
        return add(request);
    case DEVICELIST_REMOVE_CODE:
        if (request.size() == 2) {
            return remove(request[1]);
        } else { return {REQUEST_LENGTH_INVALID_CODE}; }
    case DEVICELIST_CLEAR_CODE:
        if (request.size() == 1) {
            clear();
            return {OK_CODE};
        } else { return {REQUEST_LENGTH_INVALID_CODE}; }
    case DEVICELIST_HELLO_CODE:
        // A HELLO request that just responds with a constant
        // Useful when establishing the connection
        return {DEVICELIST_HELLO_CODE};
    default:
        return {REQUEST_BODY_INVALID_CODE};
    }
}

// Gets a device pointer at a certain index of the list.
Device* DeviceList::get(uint8_t idx) {
    if (idx < _devices.size()) {
        return _devices[idx];
    }
    else {
        return nullptr;
    }
}

// Removes a device at a certain index of the list. Returns a status response
std::vector<uint8_t> DeviceList::remove(uint8_t idx) {
    if (idx < _devices.size()) {
        delete _devices[idx];
        _devices[idx] = nullptr;
        return {OK_CODE};
    } else { return {DEVICE_OOR_CODE}; }
}

// Adds a new device to the end of the list. Returns a status response.
// If successful, the response also includes the index of the added device.
std::vector<uint8_t> DeviceList::add(std::vector<uint8_t>& request) {
    Device* d;
    switch(request[1]) {
        case DIGITAL_INPUT_CODE:
            if (request.size() == 4) {
                d = new DigitalInput(request[2], request[3]);
            } else { return {REQUEST_LENGTH_INVALID_CODE}; };
            break;
        case DIGITAL_OUTPUT_CODE:
            if (request.size() == 3) {
                d = new DigitalOutput(request[2]);
            } else { return {REQUEST_LENGTH_INVALID_CODE}; };
            break;
        case ANALOG_INPUT_CODE:
            if (request.size() == 3) {
                d = new AnalogInput(request[2]);
            } else { return {REQUEST_LENGTH_INVALID_CODE}; };
            break;
        case ANALOG_OUTPUT_CODE:
            if (request.size() == 3) {
                d = new AnalogOutput(request[2]);
            } else { return {REQUEST_LENGTH_INVALID_CODE}; };
            break;
        case MOTOR_CODE:
            if (request.size() == 4) {
                d = new Motor(request[2], request[3]);
            } else { return {REQUEST_LENGTH_INVALID_CODE}; };
            break;
        case ENCODER_CODE:
            if (request.size() == 4) {
                d = new Encoder(request[2], request[3]);
            } else { return {REQUEST_LENGTH_INVALID_CODE}; };
            break;
        case GYRO_CODE:
            if (request.size() == 3) {
                d = new Gyro(request[2]);
            } else { return {REQUEST_LENGTH_INVALID_CODE}; };
            break;
        case COLOR_CODE:
            if (request.size() == 4) {
                d = new Color(request[2], request[3]);
            } else { return {REQUEST_LENGTH_INVALID_CODE}; };
            break;
	    case SERVO_CODE:
		    if (request.size() == 3) {
                d = new Servo(request[2]);
            } else { return {REQUEST_LENGTH_INVALID_CODE}; };
            break;
        default:
            return {DEVICE_INVALID_CODE};
    }
    _devices.push_back(d);
    return {OK_CODE, static_cast<uint8_t>(_devices.size()-1)};
}

// Clears the device list and resets all pins, making sure that the devices get deallocated
void DeviceList::clear() {
    for (uint8_t i = 0; i < NUM_PINS; i++) {
        pinMode(i, INPUT);
    }
    for (Device* d : _devices) {
        if(d != nullptr)
            delete d;
    }
    _devices.clear();
}

}
<|endoftext|>


<commit_before>#include "GlslParams.h"
#include "cinder/Utilities.h"

using namespace reza::glsl;
using namespace cinder;
using namespace std;

GlslParams::GlslParams() { }

GlslParams::GlslParams( const string& source ) {
    parseUniforms( source );
}

GlslParams::~GlslParams() {
    clearUniforms();
}

GlslParams::GlslParams( const GlslParams &copy ) {

    for( auto& it : copy.mParamOrder ) { mParamOrder[ it.first ] = it.second; }

    for( auto& it : copy.mTypeMap ) { mTypeMap[ it.first ] = it.second; }
    for( auto& it : copy.mBoolParams ) { mBoolParams[ it.first ] = it.second; }

    for( auto& it : copy.mIntParams ) { mIntParams[ it.first ] = it.second; }
    for( auto& it : copy.mIntRanges ) { mIntRanges[ it.first ] = it.second; }

    for( auto& it : copy.mFloatParams ) { mFloatParams[ it.first ] = it.second; }
    for( auto& it : copy.mFloatRanges ) { mFloatRanges[ it.first ] = it.second; }

    for( auto& it : copy.mVec2Params ) { mVec2Params[ it.first ] = it.second; }
    for( auto& it : copy.mVec2Ranges ) { mVec2Ranges[ it.first ] = it.second; }

    for( auto& it : copy.mVec3Params ) { mVec3Params[ it.first ] = it.second; }
    for( auto& it : copy.mVec3Ranges ) { mVec3Ranges[ it.first ] = it.second; }

    for( auto& it : copy.mVec4Params ) { mVec4Params[ it.first ] = it.second; }
    for( auto& it : copy.mVec4Ranges ) { mVec4Ranges[ it.first ] = it.second; }

    for( auto& it : copy.mColorParams ) { mColorParams[ it.first ] = it.second; }
}

void GlslParams::clearUniforms() {
    mParamOrder.clear();
    mTypeMap.clear();
    mBoolParams.clear();
    mIntParams.clear();     mIntRanges.clear();
    mFloatParams.clear();   mFloatRanges.clear();
    mVec2Params.clear();    mVec2Ranges.clear();
    mVec3Params.clear();    mVec3Ranges.clear();
    mVec4Params.clear();    mVec4Ranges.clear();
    mColorParams.clear();
}

void GlslParams::applyUniforms( const ci::gl::GlslProgRef& glslRef ) {
    for( auto& it : mBoolParams ) { glslRef->uniform( it.first, it.second ); }
    for( auto& it : mIntParams ) { glslRef->uniform( it.first, it.second ); }
    for( auto& it : mFloatParams ) { glslRef->uniform( it.first, it.second ); }
    for( auto& it : mVec2Params ) { glslRef->uniform( it.first, it.second ); }
    for( auto& it : mVec3Params ) { glslRef->uniform( it.first, it.second ); }
    for( auto& it : mVec4Params ) { glslRef->uniform( it.first, it.second ); }
    for( auto& it : mColorParams ) { glslRef->uniform( it.first, it.second ); }
}

void GlslParams::parseUniforms( const vector<string>& sources ) {
    clearUniforms();
    for( auto& it : sources ) { parse( it ); }
}

void GlslParams::parseUniforms( const string& source ) {
    clearUniforms();
    parse( source );
}

void GlslParams::parse( const string& source ) {
    auto trim = [] ( const string& input, const string& key ) {
        string temp = input;
        size_t foundKey = temp.find( key );
        while( foundKey != string::npos ) {
            temp  = temp.replace( foundKey, key.length(), "" );
            foundKey = temp.find( key );
        }
        return temp;
    };

    multimap<string, string> uiTypeMap  = {
        { "int" , "slider" },
        { "int" , "dialer" },

        { "float" , "ui" },
        { "float" , "slider" },
        { "float" , "dialer" },

        { "vec2" , "pad" },
        { "vec2" , "range" },
        { "vec2" , "ui" },

        { "vec3" , "ui" },
        { "vec4" , "ui" },
        { "vec4" , "color" },

        { "bool" , "button" },
        { "bool" , "toggle" }
    };

    vector<string> lines = split( source, '\n' );
    for( auto& it : lines ) {
        string line = it;
        std::transform( line.begin(), line.end(), line.begin(), ::tolower );
        string uniform( "uniform " );
        string semicolon( ";" );
        string colon( ":" );
        string space( " " );
        string comment( "//" );
        string comma( "," );
        string newLine( "/n" );

        size_t foundUniform = line.find( uniform ); if( foundUniform == string::npos ) { continue; }
        size_t foundComment = line.find( comment ); if( foundComment == string::npos || foundUniform > foundComment ) { continue; }
        size_t foundType = string::npos;
        size_t foundUIType = string::npos;
        string type;
        string uitype;
        string key;

        bool valid = false;
        for( auto& ui : uiTypeMap ) {
            foundType = line.find( ui.first );
            string tempkey = comment + ui.second + colon;
            foundUIType = line.find( tempkey );
            if( foundType != string::npos && foundUIType != string::npos ) {
                valid = true;
                type = ui.first;
                uitype = ui.second;
                key = tempkey;
                break;
            }
        }

        if( !valid ) { continue; }

        string uniformName = line;
        size_t foundSemicolon = uniformName.find( semicolon );
        uniformName = uniformName.substr( 0, foundSemicolon );
        uniformName = uniformName.replace( foundType, type.length(), "" );
        uniformName = uniformName.replace( foundUniform, uniform.length(), "" );
        uniformName = trim( uniformName, " " );

        string uiParams = line.substr( foundUIType + key.length() );
        size_t lastspace = line.rfind( space );
        if( lastspace != string::npos ) {
            uiParams = uiParams.substr( 0, lastspace );
        }

        vector<string> params = split( uiParams, "," );
        if( params.size() == 0 ) { continue; }

        if( type == "bool" ) {
            mBoolParams[ uniformName ] = stoi( params[ 0 ] ) > 0 ? true : false;
        }
        else if( type == "int" ) {
            mIntParams[ uniformName ] = stoi( params[ 2 ] );
            mIntRanges[ uniformName ] = { stoi( params[ 0 ] ), stoi( params[ 1 ] ) };
        }
        else if( type == "float" ) {
            mFloatParams[ uniformName ] = stof( params[ 2 ] );
            mFloatRanges[ uniformName ] = { stof( params[ 0 ] ), stof( params[ 1 ] ) };
        }
        else if( type == "vec2" ) {
            if( uitype == "range" && params.size() > 3 ) {
                mVec2Params[ uniformName ] = vec2( stof( params[ 2 ] ), stof( params[ 3 ] ) );
            }
            else{
                mVec2Params[ uniformName ] = vec2( stof( params[ 2 ] ) );
            }
            mVec2Ranges[ uniformName ] = { stof( params[ 0 ] ), stof( params[ 1 ] ) };
        }
        else if( type == "vec3" ) {
            mVec3Params[ uniformName ] = vec3( stof( params[ 2 ] ) );
            mVec3Ranges[ uniformName ] = { stof( params[ 0 ] ), stof( params[ 1 ] ) };
        }
        else if( type == "vec4" ) {
            if( uitype == "color" && params.size() > 3 ) {
                ColorA clr;
                clr.set( ColorModel::CM_RGB, vec4( stof( params[ 0 ] ), stof( params[ 1 ] ), stof( params[ 2 ] ), stof( params[ 3 ] ) ) );
                mColorParams[ uniformName ] = clr;
            }
            else {
                mVec4Params[ uniformName ] = vec4( stof( params[ 2 ] ) );
                mVec4Ranges[ uniformName ] = { stof( params[ 0 ] ), stof( params[ 1 ] ) };
            }
        }

        mTypeMap.insert( { uniformName, { type, uitype } } );
        mParamOrder[ mParamOrder.size() ] = uniformName;
    }
}

const map<int, string>& GlslParams::getParamOrder() { return mParamOrder; }

const map<string, pair<string, string>>& GlslParams::getTypeMap() { return mTypeMap; }

map<string, bool>& GlslParams::getBoolParams() { return mBoolParams; }

map<string, int>& GlslParams::getIntParams() { return mIntParams; }
map<string, pair<int, int>>& GlslParams::getIntRanges() { return mIntRanges; }

map<string, float>& GlslParams::getFloatParams() { return mFloatParams; }
map<string, pair<float, float>>& GlslParams::getFloatRanges() { return mFloatRanges; }

map<string, vec2>& GlslParams::getVec2Params() { return mVec2Params; }
map<string, pair<float, float>>& GlslParams::getVec2Ranges() { return mVec2Ranges; }

map<string, vec3>& GlslParams::getVec3Params() { return mVec3Params; }
map<string, pair<float, float>>& GlslParams::getVec3Ranges() { return mVec3Ranges; }

map<string, vec4>& GlslParams::getVec4Params() { return mVec4Params; }
map<string, pair<float, float>>& GlslParams::getVec4Ranges() { return mVec4Ranges; }

map<string, ColorA>& GlslParams::getColorParams() { return mColorParams; }<commit_msg>checked for comments<commit_after>#include "GlslParams.h"
#include "cinder/Utilities.h"

using namespace reza::glsl;
using namespace cinder;
using namespace std;

GlslParams::GlslParams() { }

GlslParams::GlslParams( const string& source ) {
    parseUniforms( source );
}

GlslParams::~GlslParams() {
    clearUniforms();
}

GlslParams::GlslParams( const GlslParams &copy ) {

    for( auto& it : copy.mParamOrder ) { mParamOrder[ it.first ] = it.second; }

    for( auto& it : copy.mTypeMap ) { mTypeMap[ it.first ] = it.second; }
    for( auto& it : copy.mBoolParams ) { mBoolParams[ it.first ] = it.second; }

    for( auto& it : copy.mIntParams ) { mIntParams[ it.first ] = it.second; }
    for( auto& it : copy.mIntRanges ) { mIntRanges[ it.first ] = it.second; }

    for( auto& it : copy.mFloatParams ) { mFloatParams[ it.first ] = it.second; }
    for( auto& it : copy.mFloatRanges ) { mFloatRanges[ it.first ] = it.second; }

    for( auto& it : copy.mVec2Params ) { mVec2Params[ it.first ] = it.second; }
    for( auto& it : copy.mVec2Ranges ) { mVec2Ranges[ it.first ] = it.second; }

    for( auto& it : copy.mVec3Params ) { mVec3Params[ it.first ] = it.second; }
    for( auto& it : copy.mVec3Ranges ) { mVec3Ranges[ it.first ] = it.second; }

    for( auto& it : copy.mVec4Params ) { mVec4Params[ it.first ] = it.second; }
    for( auto& it : copy.mVec4Ranges ) { mVec4Ranges[ it.first ] = it.second; }

    for( auto& it : copy.mColorParams ) { mColorParams[ it.first ] = it.second; }
}

void GlslParams::clearUniforms() {
    mParamOrder.clear();
    mTypeMap.clear();
    mBoolParams.clear();
    mIntParams.clear();     mIntRanges.clear();
    mFloatParams.clear();   mFloatRanges.clear();
    mVec2Params.clear();    mVec2Ranges.clear();
    mVec3Params.clear();    mVec3Ranges.clear();
    mVec4Params.clear();    mVec4Ranges.clear();
    mColorParams.clear();
}

void GlslParams::applyUniforms( const ci::gl::GlslProgRef& glslRef ) {
    for( auto& it : mBoolParams ) { glslRef->uniform( it.first, it.second ); }
    for( auto& it : mIntParams ) { glslRef->uniform( it.first, it.second ); }
    for( auto& it : mFloatParams ) { glslRef->uniform( it.first, it.second ); }
    for( auto& it : mVec2Params ) { glslRef->uniform( it.first, it.second ); }
    for( auto& it : mVec3Params ) { glslRef->uniform( it.first, it.second ); }
    for( auto& it : mVec4Params ) { glslRef->uniform( it.first, it.second ); }
    for( auto& it : mColorParams ) { glslRef->uniform( it.first, it.second ); }
}

void GlslParams::parseUniforms( const vector<string>& sources ) {
    clearUniforms();
    for( auto& it : sources ) { parse( it ); }
}

void GlslParams::parseUniforms( const string& source ) {
    clearUniforms();
    parse( source );
}

void GlslParams::parse( const string& source ) {
    auto trim = [] ( const string& input, const string& key ) {
        string temp = input;
        size_t foundKey = temp.find( key );
        while( foundKey != string::npos ) {
            temp  = temp.replace( foundKey, key.length(), "" );
            foundKey = temp.find( key );
        }
        return temp;
    };

    multimap<string, string> uiTypeMap  = {
        { "int" , "slider" },
        { "int" , "dialer" },

        { "float" , "ui" },
        { "float" , "slider" },
        { "float" , "dialer" },

        { "vec2" , "pad" },
        { "vec2" , "range" },
        { "vec2" , "ui" },

        { "vec3" , "ui" },
        { "vec4" , "ui" },
        { "vec4" , "color" },

        { "bool" , "button" },
        { "bool" , "toggle" }
    };
    bool ignore = false;
    vector<string> lines = split( source, '\n' );
    for( auto& it : lines ) {
        string line = it;

        string ignoreStart( "/*" );
        string ignoreEnd( "*/" );
        if( !ignore && line.find( ignoreStart ) != string::npos ) {
            ignore = true;
        }

        if( ignore && line.find( ignoreEnd ) == string::npos ) {
            continue;
        } else {
            ignore = false;
        }

        std::transform( line.begin(), line.end(), line.begin(), ::tolower );
        string uniform( "uniform " );
        string semicolon( ";" );
        string colon( ":" );
        string space( " " );
        string comment( "//" );
        string comma( "," );
        string newLine( "/n" );

        size_t foundUniform = line.find( uniform ); if( foundUniform == string::npos ) { continue; }
        size_t foundComment = line.find( comment ); if( foundComment == string::npos || foundUniform > foundComment ) { continue; }
        size_t foundType = string::npos;
        size_t foundUIType = string::npos;
        string type;
        string uitype;
        string key;

        bool valid = false;
        for( auto& ui : uiTypeMap ) {
            foundType = line.find( ui.first );
            string tempkey = comment + ui.second + colon;
            foundUIType = line.find( tempkey );
            if( foundType != string::npos && foundUIType != string::npos ) {
                valid = true;
                type = ui.first;
                uitype = ui.second;
                key = tempkey;
                break;
            }
        }

        if( !valid ) { continue; }

        string uniformName = line;
        size_t foundSemicolon = uniformName.find( semicolon );
        uniformName = uniformName.substr( 0, foundSemicolon );
        uniformName = uniformName.replace( foundType, type.length(), "" );
        uniformName = uniformName.replace( foundUniform, uniform.length(), "" );
        uniformName = trim( uniformName, " " );

        string uiParams = line.substr( foundUIType + key.length() );
        size_t lastspace = line.rfind( space );
        if( lastspace != string::npos ) {
            uiParams = uiParams.substr( 0, lastspace );
        }

        vector<string> params = split( uiParams, "," );
        if( params.size() == 0 ) { continue; }

        if( type == "bool" ) {
            mBoolParams[ uniformName ] = stoi( params[ 0 ] ) > 0 ? true : false;
        }
        else if( type == "int" ) {
            mIntParams[ uniformName ] = stoi( params[ 2 ] );
            mIntRanges[ uniformName ] = { stoi( params[ 0 ] ), stoi( params[ 1 ] ) };
        }
        else if( type == "float" ) {
            mFloatParams[ uniformName ] = stof( params[ 2 ] );
            mFloatRanges[ uniformName ] = { stof( params[ 0 ] ), stof( params[ 1 ] ) };
        }
        else if( type == "vec2" ) {
            if( uitype == "range" && params.size() > 3 ) {
                mVec2Params[ uniformName ] = vec2( stof( params[ 2 ] ), stof( params[ 3 ] ) );
            }
            else{
                mVec2Params[ uniformName ] = vec2( stof( params[ 2 ] ) );
            }
            mVec2Ranges[ uniformName ] = { stof( params[ 0 ] ), stof( params[ 1 ] ) };
        }
        else if( type == "vec3" ) {
            mVec3Params[ uniformName ] = vec3( stof( params[ 2 ] ) );
            mVec3Ranges[ uniformName ] = { stof( params[ 0 ] ), stof( params[ 1 ] ) };
        }
        else if( type == "vec4" ) {
            if( uitype == "color" && params.size() > 3 ) {
                ColorA clr;
                clr.set( ColorModel::CM_RGB, vec4( stof( params[ 0 ] ), stof( params[ 1 ] ), stof( params[ 2 ] ), stof( params[ 3 ] ) ) );
                mColorParams[ uniformName ] = clr;
            }
            else {
                mVec4Params[ uniformName ] = vec4( stof( params[ 2 ] ) );
                mVec4Ranges[ uniformName ] = { stof( params[ 0 ] ), stof( params[ 1 ] ) };
            }
        }

        mTypeMap.insert( { uniformName, { type, uitype } } );
        mParamOrder[ mParamOrder.size() ] = uniformName;
    }
}

const map<int, string>& GlslParams::getParamOrder() { return mParamOrder; }

const map<string, pair<string, string>>& GlslParams::getTypeMap() { return mTypeMap; }

map<string, bool>& GlslParams::getBoolParams() { return mBoolParams; }

map<string, int>& GlslParams::getIntParams() { return mIntParams; }
map<string, pair<int, int>>& GlslParams::getIntRanges() { return mIntRanges; }

map<string, float>& GlslParams::getFloatParams() { return mFloatParams; }
map<string, pair<float, float>>& GlslParams::getFloatRanges() { return mFloatRanges; }

map<string, vec2>& GlslParams::getVec2Params() { return mVec2Params; }
map<string, pair<float, float>>& GlslParams::getVec2Ranges() { return mVec2Ranges; }

map<string, vec3>& GlslParams::getVec3Params() { return mVec3Params; }
map<string, pair<float, float>>& GlslParams::getVec3Ranges() { return mVec3Ranges; }

map<string, vec4>& GlslParams::getVec4Params() { return mVec4Params; }
map<string, pair<float, float>>& GlslParams::getVec4Ranges() { return mVec4Ranges; }

map<string, ColorA>& GlslParams::getColorParams() { return mColorParams; }<|endoftext|>


<commit_before>/**
 * \file GraphFrame.cpp
 * \brief Main Windows Class
 */

#include "GraphFrame.h"

BEGIN_EVENT_TABLE(GraphFrame,wxFrame)
    EVT_MENU(ID_NEWWINDOW, GraphFrame::NewStatusWindow)
    EVT_MENU(-1, GraphFrame::SelectDevice)
    EVT_CLOSE(GraphFrame::OnClose)
    EVT_TIMER(UPDATE_TIMER, GraphFrame::OnTimer)
END_EVENT_TABLE()

GraphFrame::GraphFrame(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &position, const wxSize& size, long style)
: wxFrame(parent, id, title, position, size, style) {
    /**
    *   Constructor for the Main frame.
    */
    deviceId = "Please select a device from the menu.";

    view = VIEW_BASIC;

    CreateGUIControls();

    updateTimer = new wxTimer(this, UPDATE_TIMER);
    updateTimer->Start(5000);
}

GraphFrame::~GraphFrame() {
    /**
    *   Destructor for the Main form.
    */
}

void GraphFrame::OnTimer(wxTimerEvent& event) {
    Update();
}

void GraphFrame::Update() {
    /**
     * Updates the GUI with new database information
     */
    wxMenuBar *menubar = new wxMenuBar;
    wxMenu *devices_menu = new wxMenu;
    wxMenu *view_menu = new wxMenu;

    deviceIds = DB_getAllDevices();

    menubar->Append(devices_menu, wxT("&Devices"));

    for(unsigned int i = 0; i < deviceIds.size(); i++) {
        devices_menu->Append(10000+i, deviceIds[i]);
    }

    menubar->Append(view_menu, wxT("&View"));

    view_menu->Append(VIEW_BASIC, wxT("Basic"));
    view_menu->Append(VIEW_ANALOG, wxT("Analog Channels"));

    SetMenuBar(menubar);

    switch(view) {
        case VIEW_ANALOG:
            UpdateAnalogGraphs();
            break;
        case VIEW_BASIC:
            UpdateBasicGraphs();
            break;
        default:
            UpdateBasicGraphs();
            break;
    }
}

void GraphFrame::UpdateGraph(int num, Graph* graph) {
    if(!graphs[num]) {
	    graphs[num] = graph;
        mainSizer->Add(graphs[num]->window, 1, wxEXPAND | wxALL);
    }
    graphs[num]->Update(atoi(deviceId.c_str()));
}

void GraphFrame::UpdateBasicGraphs() {
    /*
	Plot speed = DB_getPlotData("gps","Spd",atoi(deviceId.c_str()));
	Plot altitude = DB_getPlotData("gps","Altitude",atoi(deviceId.c_str()));
	Plot climb = DB_getPlotData("gps","Rate",atoi(deviceId.c_str()));

	if(!graphs[0]) {
	    graphs[i] = new Graph(mainPanel,name,"aip",atoi(deviceId.c_str()),name);
        mainSizer->Add(graphs[i]->window, 1, wxEXPAND | wxALL);
	}

	ReplaceGraph(0, createGraphFromData(wxT("Time"),altitude.time,
	                                    wxT("Altitude"),altitude.data));

	ReplaceGraph(1, createGraphFromData(wxT("Speed"),speed.data,
	                                    wxT("Altitude"),speed.altitude));

	ReplaceGraph(2, createGraphFromData(wxT("Climb"),climb.data,
	                                    wxT("Altitude"),climb.altitude));

    mainSizer->Layout();
    */
}

void GraphFrame::UpdateAnalogGraphs() {
	char name[4];

	for(int i = 0; i<18; i++) {
        name[0] = 'A';
        name[1] = 0x00;
        sprintf(name,"%s%d",name,i+1);
        UpdateGraph(i, new Graph(mainPanel,name,"aip",atoi(deviceId.c_str()),name));
	}

    mainSizer->Layout();
}

void GraphFrame::CreateGUIControls() {
   /**
    *   Creates all of the GUI controls on the main form.
    */

    // Set window properties and title bar
    SetTitle(wxT("Device Graphs"));
    SetIcon(wxNullIcon);

    mainPanel = new wxPanel(this, wxID_ANY);
    mainSizer = new wxGridSizer(3);
    mainPanel->SetSizer(mainSizer);

    for(int i = 0; i < 18; i++) {
        graphs[i] = 0x00;
    }

    Update();
}

void GraphFrame::OnClose(wxCloseEvent& event) {
    /**
    *   Event handler for the form closing event
    *   Exit the ChaosConnect Program
    */
    Destroy();
}

void GraphFrame::SelectDevice( wxCommandEvent& event ) {
    /**
     * Selects a device from the menu
     *
     * This is a catchall menu event handler becasue I couldn't think
     * of a better way to do this because the menu is dynamic
     */

    int id = event.GetId();

    if(id > 10000) {
        /// We're selecting a device
        deviceId = deviceIds[id - 10000];
        ClearGraphs();
    }

    if(id == VIEW_BASIC) {
        ClearGraphs();
        view = VIEW_BASIC;
    }
    if(id == VIEW_ANALOG) {
        ClearGraphs();
        view = VIEW_ANALOG;
    }

    Update();
}

void GraphFrame::ClearGraphs() {
    for(int i = 0; i<18; i++) {
        if(graphs[i]) mainSizer->Remove(graphs[i]->window);
        delete graphs[i];
        graphs[i] = 0x00;
    }
}

void GraphFrame::NewStatusWindow( wxCommandEvent& event ) {
    /**
     * Launches a new status window
     */

    GraphFrame* frame = new GraphFrame(NULL);
    frame->Show();
}

<commit_msg>- added basic graphs again<commit_after>/**
 * \file GraphFrame.cpp
 * \brief Main Windows Class
 */

#include "GraphFrame.h"

BEGIN_EVENT_TABLE(GraphFrame,wxFrame)
    EVT_MENU(ID_NEWWINDOW, GraphFrame::NewStatusWindow)
    EVT_MENU(-1, GraphFrame::SelectDevice)
    EVT_CLOSE(GraphFrame::OnClose)
    EVT_TIMER(UPDATE_TIMER, GraphFrame::OnTimer)
END_EVENT_TABLE()

GraphFrame::GraphFrame(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &position, const wxSize& size, long style)
: wxFrame(parent, id, title, position, size, style) {
    /**
    *   Constructor for the Main frame.
    */
    deviceId = "Please select a device from the menu.";

    view = VIEW_BASIC;

    CreateGUIControls();

    updateTimer = new wxTimer(this, UPDATE_TIMER);
    updateTimer->Start(5000);
}

GraphFrame::~GraphFrame() {
    /**
    *   Destructor for the Main form.
    */
}

void GraphFrame::OnTimer(wxTimerEvent& event) {
    Update();
}

void GraphFrame::Update() {
    /**
     * Updates the GUI with new database information
     */
    wxMenuBar *menubar = new wxMenuBar;
    wxMenu *devices_menu = new wxMenu;
    wxMenu *view_menu = new wxMenu;

    deviceIds = DB_getAllDevices();

    menubar->Append(devices_menu, wxT("&Devices"));

    for(unsigned int i = 0; i < deviceIds.size(); i++) {
        devices_menu->Append(10000+i, deviceIds[i]);
    }

    menubar->Append(view_menu, wxT("&View"));

    view_menu->Append(VIEW_BASIC, wxT("Basic"));
    view_menu->Append(VIEW_ANALOG, wxT("Analog Channels"));

    SetMenuBar(menubar);

    switch(view) {
        case VIEW_ANALOG:
            UpdateAnalogGraphs();
            break;
        case VIEW_BASIC:
            UpdateBasicGraphs();
            break;
        default:
            UpdateBasicGraphs();
            break;
    }

    mainSizer->Layout();
}

void GraphFrame::UpdateGraph(int num, Graph* graph) {
    if(!graphs[num]) {
	    graphs[num] = graph;
        mainSizer->Add(graphs[num]->window, 1, wxEXPAND | wxALL);
    }
    graphs[num]->Update(atoi(deviceId.c_str()));
}

void GraphFrame::UpdateBasicGraphs() {
	UpdateGraph(0, new Graph(mainPanel,"Altitude","gps",atoi(deviceId.c_str()),"Altitude"));
	UpdateGraph(1, new Graph(mainPanel,"Speed","gps",atoi(deviceId.c_str()),"Spd"));
	UpdateGraph(2, new Graph(mainPanel,"Climb","gps",atoi(deviceId.c_str()),"Rate"));
}

void GraphFrame::UpdateAnalogGraphs() {
	char name[4];

	for(int i = 0; i<18; i++) {
        name[0] = 'A';
        name[1] = 0x00;
        sprintf(name,"%s%d",name,i+1);
        UpdateGraph(i, new Graph(mainPanel,name,"aip",atoi(deviceId.c_str()),name));
	}
}

void GraphFrame::CreateGUIControls() {
   /**
    *   Creates all of the GUI controls on the main form.
    */

    // Set window properties and title bar
    SetTitle(wxT("Device Graphs"));
    SetIcon(wxNullIcon);

    mainPanel = new wxPanel(this, wxID_ANY);
    mainSizer = new wxGridSizer(3);
    mainPanel->SetSizer(mainSizer);

    for(int i = 0; i < 18; i++) {
        graphs[i] = 0x00;
    }

    Update();
}

void GraphFrame::OnClose(wxCloseEvent& event) {
    /**
    *   Event handler for the form closing event
    *   Exit the ChaosConnect Program
    */
    Destroy();
}

void GraphFrame::SelectDevice( wxCommandEvent& event ) {
    /**
     * Selects a device from the menu
     *
     * This is a catchall menu event handler becasue I couldn't think
     * of a better way to do this because the menu is dynamic
     */

    int id = event.GetId();

    if(id > 10000) {
        /// We're selecting a device
        deviceId = deviceIds[id - 10000];
        ClearGraphs();
    }

    if(id == VIEW_BASIC) {
        ClearGraphs();
        view = VIEW_BASIC;
    }
    if(id == VIEW_ANALOG) {
        ClearGraphs();
        view = VIEW_ANALOG;
    }

    Update();
}

void GraphFrame::ClearGraphs() {
    for(int i = 0; i<18; i++) {
        if(graphs[i]) mainSizer->Remove(graphs[i]->window);
        delete graphs[i];
        graphs[i] = 0x00;
    }
}

void GraphFrame::NewStatusWindow( wxCommandEvent& event ) {
    /**
     * Launches a new status window
     */

    GraphFrame* frame = new GraphFrame(NULL);
    frame->Show();
}

<|endoftext|>


<commit_before>// Scintilla source code edit control
/** @file LexFortran.cxx
 ** Lexer for Fortran.
 ** Writen by Chuan-jian Shen, Last changed Oct. 2002
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

static inline bool IsAWordChar(const int ch) {
	return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '%');
}

static inline bool IsAWordStart(const int ch) {
	return (ch < 0x80) && (isalnum(ch));
}

inline bool IsABlank(unsigned int ch) {
    return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ;
}
static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
                            Accessor &styler, bool isFixFormat) {

	WordList &keywords = *keywordlists[0];
	WordList &keywords2 = *keywordlists[1];
	WordList &keywords3 = *keywordlists[2];

	unsigned int posLineStart = 0, currentState;
	int endPos = startPos + length;

	// backtrack to the beginning of the document, this may be slow for big documents.
	// initStyle = SCE_F_DEFAULT;
	// StyleContext sc(0, startPos+length, initStyle, styler);

	// backtrack to the nearest keyword
	while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_F_WORD)) {
		startPos--;
	}
	startPos = styler.LineStart(styler.GetLine(startPos));
	initStyle = styler.StyleAt(startPos - 1);
	StyleContext sc(startPos, endPos-startPos, initStyle, styler);

	for (; sc.More(); sc.Forward()) {

		// remember the position of the line
		if (sc.atLineStart) posLineStart = sc.currentPos;

		// Handle line continuation generically.
		if (sc.ch == '&') {
			int chTemp = ' ';
			int j = 1;
			while (IsABlank(chTemp) && j<132) {
				chTemp = sc.GetRelative(j);
				j ++;
			}
			if (chTemp == '!') {
				sc.SetState(SCE_F_CONTINUATION);
				if (sc.chNext == '!') sc.ForwardSetState(SCE_F_COMMENT);
			} else if (chTemp == '\r' || chTemp == '\n') {
				currentState = sc.state;
				sc.SetState(SCE_F_CONTINUATION);
				if (currentState == SCE_F_STRING1 || currentState == SCE_F_STRING2) {
					sc.ForwardSetState(SCE_F_DEFAULT);
					while (IsASpace(sc.ch) && sc.More()) sc.Forward();
					if (sc.ch == '&') {
						sc.SetState(SCE_F_CONTINUATION);
						sc.Forward();
					}
					sc.SetState(currentState);
				}
			}
			continue;
		}

		// Determine if the current state should terminate.
		if (sc.state == SCE_F_OPERATOR) {
			sc.SetState(SCE_F_DEFAULT);
		} else if (sc.state == SCE_F_NUMBER) {
			if (!IsAWordChar(sc.ch)) {
				sc.SetState(SCE_F_DEFAULT);
			}
		} else if (sc.state == SCE_F_IDENTIFIER) {
			if (!IsAWordChar(sc.ch) || (sc.ch == '%')) {
				char s[100];
				sc.GetCurrentLowered(s, sizeof(s));
				if (keywords.InList(s)) {
					sc.ChangeState(SCE_F_WORD);
				} else if (keywords2.InList(s)) {
					sc.ChangeState(SCE_F_WORD2);
				} else if (keywords3.InList(s)) {
					sc.ChangeState(SCE_F_WORD3);
				}
				sc.SetState(SCE_F_DEFAULT);
			}
		} else if (sc.state == SCE_F_COMMENT) {
			if (sc.ch == '\r' || sc.ch == '\n') {
				sc.SetState(SCE_F_DEFAULT);
			}
		} else if (sc.state == SCE_F_STRING1) {
			if (sc.ch == '\'') {
				if (sc.chNext == '\'') {
					sc.Forward();
				} else {
					sc.ForwardSetState(SCE_F_DEFAULT);
				}
			} else if (sc.atLineEnd) {
				sc.ChangeState(SCE_F_STRINGEOL);
				sc.ForwardSetState(SCE_F_DEFAULT);
			}
		} else if (sc.state == SCE_F_STRING2) {
			if (sc.atLineEnd) {
				sc.ChangeState(SCE_F_STRINGEOL);
				sc.ForwardSetState(SCE_F_DEFAULT);
			} else if (sc.ch == '\"') {
				if (sc.chNext == '\"') {
					sc.Forward();
				} else {
					sc.ForwardSetState(SCE_F_DEFAULT);
				}
			}
		} else if (sc.state == SCE_F_OPERATOR2) {
			if (sc.ch == '.') {
				sc.ForwardSetState(SCE_F_DEFAULT);
			}
		} else if (sc.state == SCE_F_CONTINUATION) {
			sc.SetState(SCE_F_DEFAULT);
		} else if (sc.state == SCE_F_LABEL) {
			if (sc.currentPos >= posLineStart+5) {
				sc.SetState(SCE_F_DEFAULT);
			}
		}

		// Determine if a new state should be entered.
		if (sc.state == SCE_F_DEFAULT) {
			int toLineStart = sc.currentPos - posLineStart;
			if (isFixFormat && (toLineStart < 6 || toLineStart > 72)) {
				if (sc.atLineStart && (tolower(sc.ch) == 'c' || sc.ch == '*')) {
					sc.SetState(SCE_F_COMMENT);
				} else if (toLineStart > 72) {
					sc.SetState(SCE_F_COMMENT);
				} else if (toLineStart < 5 && !IsASpace(sc.ch)) {
					sc.SetState(SCE_F_LABEL);
				} else if (toLineStart == 5 && (!IsASpace(sc.ch) && sc.ch != '0')) {
					sc.SetState(SCE_F_CONTINUATION);
				}
			} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
				sc.SetState(SCE_F_NUMBER);
			} else if (sc.ch == '.' && isalpha(sc.chNext)) {
				sc.SetState(SCE_F_OPERATOR2);
			} else if (IsAWordStart(sc.ch)) {
				sc.SetState(SCE_F_IDENTIFIER);
			} else if (sc.ch == '!') {
				sc.SetState(SCE_F_COMMENT);
			} else if (sc.ch == '\"') {
				sc.SetState(SCE_F_STRING2);
			} else if (sc.ch == '\'') {
				sc.SetState(SCE_F_STRING1);
			} else if (isoperator(static_cast<char>(sc.ch))) {
				sc.SetState(SCE_F_OPERATOR);
			}
		}
	}
	sc.Complete();
}

// The folding depends on the mercy of the programer.
static int classifyFoldPointFortran(const char* s, const char* prevWord) {
	int lev = 0;
	if (strcmp(prevWord, "end") == 0) return lev;
	if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0)
		return -1;
	if (strcmp(s, "associate") == 0 || strcmp(s, "block") == 0
	    || strcmp(s, "blockdata") == 0 || strcmp(s, "case") == 0
	    || strcmp(s, "do") == 0 || strcmp(s, "enum") ==0
	    || strcmp(s, "forall") == 0 || strcmp(s, "function") == 0
	    || strcmp(s, "interface") == 0 || strcmp(s, "module") == 0
	    || strcmp(s, "program") == 0 || strcmp(s, "subroutine") == 0
	    || strcmp(s, "then") == 0 || strcmp(s, "type") == 0
	    || strcmp(s, "where") == 0) {
		lev = 1;
	} else if (strcmp(s, "end") == 0 || strcmp(s, "continue") == 0
	    || strcmp(s, "endassociate") == 0 || strcmp(s, "endblock") == 0
	    || strcmp(s, "endblockdata") == 0 || strcmp(s, "endselect") == 0
	    || strcmp(s, "enddo") == 0 || strcmp(s, "endenum") ==0
	    || strcmp(s, "endif") == 0
	    || strcmp(s, "endforall") == 0 || strcmp(s, "endfunction") == 0
	    || strcmp(s, "endinterface") == 0 || strcmp(s, "endmodule") == 0
	    || strcmp(s, "endprogram") == 0 || strcmp(s, "endsubroutine") == 0
	    || strcmp(s, "endtype") == 0 || strcmp(s, "endwhere") == 0
            || strcmp(s, "procedure") == 0 ) {
		lev = -1;
	}
	return lev;
}
static void FoldFortranDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) {
	//~ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
	// Do not know how to fold the comment at the moment.
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
	unsigned int endPos = startPos + length;
	int visibleChars = 0;
	int lineCurrent = styler.GetLine(startPos);
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
	int levelCurrent = levelPrev;
	char chNext = styler[startPos];
	int styleNext = styler.StyleAt(startPos);
	int style = initStyle;

	int lastStart = 0;
	char prevWord[32] = "";

	for (unsigned int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);
		int stylePrev = style;
		style = styleNext;
		styleNext = styler.StyleAt(i + 1);
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');

		if (stylePrev == SCE_F_DEFAULT && style == SCE_F_WORD)
		{
			// Store last word start point.
			lastStart = i;
		}

		if (style == SCE_F_WORD) {
			if(iswordchar(ch) && !iswordchar(chNext)) {
				char s[32];
				unsigned int j;
				for(j = 0; ( j < 31 ) && ( j < i-lastStart+1 ); j++) {
					s[j] = static_cast<char>(tolower(styler[lastStart + j]));
				}
				s[j] = '\0';
				levelCurrent += classifyFoldPointFortran(s, prevWord);
				strcpy(prevWord, s);
			}
		}
		if (atEOL) {
			int lev = levelPrev;
			if (visibleChars == 0 && foldCompact)
				lev |= SC_FOLDLEVELWHITEFLAG;
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
				lev |= SC_FOLDLEVELHEADERFLAG;
			if (lev != styler.LevelAt(lineCurrent)) {
				styler.SetLevel(lineCurrent, lev);
			}
			lineCurrent++;
			levelPrev = levelCurrent;
			visibleChars = 0;
			strcpy(prevWord, "");
		}

		if (!isspacechar(ch))
			visibleChars++;
	}

	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}

static const char * const FortranWordLists[] = {
	"Primary keywords and identifiers",
	"Intrinsic functions",
	"Extended and user defined functions",
	0,
};

static void ColouriseFortranDocFreeFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
                            Accessor &styler) {
	ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, false);
}

static void ColouriseFortranDocFixFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
                            Accessor &styler) {
	ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, true);
}

LexerModule lmFortran(SCLEX_FORTRAN, ColouriseFortranDocFreeFormat, "fortran", FoldFortranDoc, FortranWordLists);
LexerModule lmF77(SCLEX_F77, ColouriseFortranDocFixFormat, "f77", FoldFortranDoc, FortranWordLists);
<commit_msg>Update from Shen to fix the wrong folding with TYPE defining and wrong color highlighting with continucated lines in some cases.<commit_after>// Scintilla source code edit control
/** @file LexFortran.cxx
 ** Lexer for Fortran.
 ** Writen by Chuan-jian Shen, Last changed Nov. 2002
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

static inline bool IsAWordChar(const int ch) {
	return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '%');
}

static inline bool IsAWordStart(const int ch) {
	return (ch < 0x80) && (isalnum(ch));
}

inline bool IsABlank(unsigned int ch) {
    return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ;
}
static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
                            Accessor &styler, bool isFixFormat) {

	WordList &keywords = *keywordlists[0];
	WordList &keywords2 = *keywordlists[1];
	WordList &keywords3 = *keywordlists[2];

	int posLineStart = 0, prevState = 0;
	int endPos = startPos + length;

	// backtrack to the beginning of the document, this may be slow for big documents.
	// initStyle = SCE_F_DEFAULT;
	// StyleContext sc(0, startPos+length, initStyle, styler);

	// backtrack to the nearest keyword
	while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_F_WORD)) {
		startPos--;
	}
	startPos = styler.LineStart(styler.GetLine(startPos));
	initStyle = styler.StyleAt(startPos - 1);
	StyleContext sc(startPos, endPos-startPos, initStyle, styler);

	for (; sc.More(); sc.Forward()) {

		// remember the position of the line
		if (sc.atLineStart) {
			posLineStart = sc.currentPos;
			sc.SetState(SCE_F_DEFAULT);
		}

		// Handle line continuation generically.
		if (sc.ch == '&') {
			char chTemp = ' ';
			int j = 1;
			while (IsABlank(chTemp) && j<132) {
				chTemp = static_cast<char>(sc.GetRelative(j));
				j ++;
			}
			if (chTemp == '!') {
				sc.SetState(SCE_F_CONTINUATION);
				if (sc.chNext == '!') sc.ForwardSetState(SCE_F_COMMENT);
			} else if (chTemp == '\r' || chTemp == '\n') {
				int currentState = sc.state;
				sc.SetState(SCE_F_CONTINUATION);
				if (currentState == SCE_F_STRING1 || currentState == SCE_F_STRING2) {
					sc.ForwardSetState(SCE_F_DEFAULT);
					while (IsASpace(sc.ch) && sc.More()) sc.Forward();
					if (sc.ch == '&') {
						sc.SetState(SCE_F_CONTINUATION);
						sc.Forward();
					}
					sc.SetState(currentState);
				}
			}
			continue;
		}

		// Determine if the current state should terminate.
		if (sc.state == SCE_F_OPERATOR) {
			sc.SetState(SCE_F_DEFAULT);
		} else if (sc.state == SCE_F_NUMBER) {
			if (!IsAWordChar(sc.ch)) {
				sc.SetState(SCE_F_DEFAULT);
			}
		} else if (sc.state == SCE_F_IDENTIFIER) {
			if (!IsAWordChar(sc.ch) || (sc.ch == '%')) {
				char s[100];
				sc.GetCurrentLowered(s, sizeof(s));
				if (keywords.InList(s)) {
					sc.ChangeState(SCE_F_WORD);
				} else if (keywords2.InList(s)) {
					sc.ChangeState(SCE_F_WORD2);
				} else if (keywords3.InList(s)) {
					sc.ChangeState(SCE_F_WORD3);
				}
				sc.SetState(SCE_F_DEFAULT);
			}
		} else if (sc.state == SCE_F_COMMENT) {
			if (sc.ch == '\r' || sc.ch == '\n') {
				sc.SetState(SCE_F_DEFAULT);
			}
		} else if (sc.state == SCE_F_STRING1) {
			prevState = sc.state;
			if (sc.ch == '\'') {
				if (sc.chNext == '\'') {
					sc.Forward();
				} else {
					sc.ForwardSetState(SCE_F_DEFAULT);
					prevState = SCE_F_DEFAULT;
				}
			} else if (sc.atLineEnd) {
				if (isFixFormat) {
					sc.ForwardSetState(SCE_F_DEFAULT);
					posLineStart = sc.currentPos;
				} else {
					sc.ChangeState(SCE_F_STRINGEOL);
					sc.ForwardSetState(SCE_F_DEFAULT);
				}
			}
		} else if (sc.state == SCE_F_STRING2) {
			prevState = sc.state;
			if (sc.atLineEnd) {
				if (isFixFormat) {
					sc.ForwardSetState(SCE_F_DEFAULT);
					posLineStart = sc.currentPos;
				} else {
					sc.ChangeState(SCE_F_STRINGEOL);
					sc.ForwardSetState(SCE_F_DEFAULT);
				}
			} else if (sc.ch == '\"') {
				if (sc.chNext == '\"') {
					sc.Forward();
				} else {
					sc.ForwardSetState(SCE_F_DEFAULT);
					prevState = SCE_F_DEFAULT;
				}
			}
		} else if (sc.state == SCE_F_OPERATOR2) {
			if (sc.ch == '.') {
				sc.ForwardSetState(SCE_F_DEFAULT);
			}
		} else if (sc.state == SCE_F_CONTINUATION) {
			sc.SetState(SCE_F_DEFAULT);
		} else if (sc.state == SCE_F_LABEL) {
			if (sc.currentPos >= static_cast<unsigned int>(posLineStart+5)) {
				sc.SetState(SCE_F_DEFAULT);
			}
		}

		// Determine if a new state should be entered.
		if (sc.state == SCE_F_DEFAULT) {
			int toLineStart = sc.currentPos - posLineStart;
			if (isFixFormat && (toLineStart < 6 || toLineStart > 72)) {
				if (sc.atLineStart && (tolower(sc.ch) == 'c' || sc.ch == '*') || sc.ch == '!') {
					sc.SetState(SCE_F_COMMENT);
				} else if (toLineStart > 72) {
					sc.SetState(SCE_F_COMMENT);
				} else if (toLineStart < 5 && !IsASpace(sc.ch)) {
					sc.SetState(SCE_F_LABEL);
				} else if (toLineStart == 5 && (!IsASpace(sc.ch) && sc.ch != '0')) {
					sc.SetState(SCE_F_CONTINUATION);
					sc.ForwardSetState(prevState);
				}
			} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
				sc.SetState(SCE_F_NUMBER);
			} else if (sc.ch == '.' && isalpha(sc.chNext)) {
				sc.SetState(SCE_F_OPERATOR2);
			} else if (IsAWordStart(sc.ch)) {
				sc.SetState(SCE_F_IDENTIFIER);
			} else if (sc.ch == '!') {
				sc.SetState(SCE_F_COMMENT);
			} else if (sc.ch == '\"') {
				sc.SetState(SCE_F_STRING2);
			} else if (sc.ch == '\'') {
				sc.SetState(SCE_F_STRING1);
			} else if (isoperator(static_cast<char>(sc.ch))) {
				sc.SetState(SCE_F_OPERATOR);
			}
		}
	}
	sc.Complete();
}

// The folding depends on the mercy of the programer.
static int classifyFoldPointFortran(const char* s, const char* prevWord) {
	int lev = 0;
	if (strcmp(prevWord, "end") == 0) return lev;
	if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0)
		return -1;
	if (strcmp(s, "associate") == 0 || strcmp(s, "block") == 0
	    || strcmp(s, "blockdata") == 0 || strcmp(s, "select") == 0
	    || strcmp(s, "do") == 0 || strcmp(s, "enum") ==0
	    || strcmp(s, "forall") == 0 || strcmp(s, "function") == 0
	    || strcmp(s, "interface") == 0 || strcmp(s, "module") == 0
	    || strcmp(s, "program") == 0 || strcmp(s, "subroutine") == 0
	    || strcmp(s, "then") == 0 || strcmp(s, "where") == 0) {
		lev = 1;
	} else if (strcmp(s, "end") == 0 || strcmp(s, "continue") == 0
	    || strcmp(s, "endassociate") == 0 || strcmp(s, "endblock") == 0
	    || strcmp(s, "endblockdata") == 0 || strcmp(s, "endselect") == 0
	    || strcmp(s, "enddo") == 0 || strcmp(s, "endenum") ==0
	    || strcmp(s, "endif") == 0
	    || strcmp(s, "endforall") == 0 || strcmp(s, "endfunction") == 0
	    || strcmp(s, "endinterface") == 0 || strcmp(s, "endmodule") == 0
	    || strcmp(s, "endprogram") == 0 || strcmp(s, "endsubroutine") == 0
	    || strcmp(s, "endwhere") == 0 || strcmp(s, "procedure") == 0 ) {
		lev = -1;
	}
	return lev;
}
static void FoldFortranDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) {
	//~ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
	// Do not know how to fold the comment at the moment.
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
	unsigned int endPos = startPos + length;
	int visibleChars = 0;
	int lineCurrent = styler.GetLine(startPos);
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
	int levelCurrent = levelPrev;
	char chNext = styler[startPos];
	int styleNext = styler.StyleAt(startPos);
	int style = initStyle;

	int lastStart = 0;
	char prevWord[32] = "";

	for (unsigned int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);
		int stylePrev = style;
		style = styleNext;
		styleNext = styler.StyleAt(i + 1);
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');

		if (stylePrev == SCE_F_DEFAULT && style == SCE_F_WORD)
		{
			// Store last word start point.
			lastStart = i;
		}

		if (style == SCE_F_WORD) {
			if(iswordchar(ch) && !iswordchar(chNext)) {
				char s[32];
				unsigned int j;
				for(j = 0; ( j < 31 ) && ( j < i-lastStart+1 ); j++) {
					s[j] = static_cast<char>(tolower(styler[lastStart + j]));
				}
				s[j] = '\0';
				levelCurrent += classifyFoldPointFortran(s, prevWord);
				strcpy(prevWord, s);
			}
		}
		if (atEOL) {
			int lev = levelPrev;
			if (visibleChars == 0 && foldCompact)
				lev |= SC_FOLDLEVELWHITEFLAG;
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
				lev |= SC_FOLDLEVELHEADERFLAG;
			if (lev != styler.LevelAt(lineCurrent)) {
				styler.SetLevel(lineCurrent, lev);
			}
			lineCurrent++;
			levelPrev = levelCurrent;
			visibleChars = 0;
			strcpy(prevWord, "");
		}

		if (!isspacechar(ch))
			visibleChars++;
	}

	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}

static const char * const FortranWordLists[] = {
	"Primary keywords and identifiers",
	"Intrinsic functions",
	"Extended and user defined functions",
	0,
};

static void ColouriseFortranDocFreeFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
                            Accessor &styler) {
	ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, false);
}

static void ColouriseFortranDocFixFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
                            Accessor &styler) {
	ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, true);
}

LexerModule lmFortran(SCLEX_FORTRAN, ColouriseFortranDocFreeFormat, "fortran", FoldFortranDoc, FortranWordLists);
LexerModule lmF77(SCLEX_F77, ColouriseFortranDocFixFormat, "f77", FoldFortranDoc, FortranWordLists);
<|endoftext|>


<commit_before>#include "MainWindow.h"
#include "ui_MainWindow.h"

#include "CuteNode.h"
#include "NodeScene.h"

#include <QDebug>
#include <QFileDialog>
#include <QJsonDocument>
#include <QJsonObject>

namespace
{
    const QJsonObject kNewSceneAttributes
    {
        {"name",    QObject::tr("New Scene")},
        {"width",   3000},
        {"height",  3000},
        {"centerx", 1500},
        {"centery", 1500}
    };
}

MainWindow::MainWindow(const QString& sceneToOpen, QWidget* parent)
    : QMainWindow(parent)
    , _scene{nullptr}
    , _sceneFileName{sceneToOpen}
    , _ui{std::make_unique<Ui::MainWindow>()}
{
    _ui->setupUi(this);

    LoadSceneFromFile();
}

MainWindow::~MainWindow()
{
}

void MainWindow::on_actionExit_triggered()
{
    QApplication::quit();
}

void MainWindow::on_actionNewScene_triggered()
{
    _sceneFileName.clear();

    QJsonObject newSceneDescription
    {
        {"scene", kNewSceneAttributes}
    };

    CreateScene(newSceneDescription);
}

void MainWindow::on_actionLoadScene_triggered()
{
    _sceneFileName = QFileDialog::getOpenFileName(this, tr("Open Scene"), "..", "JSON (*.json)");
    if (_sceneFileName.isNull())
        return;

    LoadSceneFromFile();
}

void MainWindow::on_actionSaveScene_triggered()
{
    QFile sceneFile{_sceneFileName};

    if (!_sceneFileName.isEmpty() && sceneFile.open(QIODevice::WriteOnly))
    {
        SaveSceneToFile(sceneFile);
    }
    else
    {
        on_actionSaveSceneAs_triggered();
    }
}

void MainWindow::on_actionSaveSceneAs_triggered()
{
    _sceneFileName = QFileDialog::getSaveFileName(this, tr("Save Scene"), "..", "JSON (*.json)");
    QFile sceneFile(_sceneFileName);
    if (!sceneFile.open(QIODevice::WriteOnly))
        return;

    SaveSceneToFile(sceneFile);
}

void MainWindow::LoadSceneFromFile()
{
    QFile sceneFile(_sceneFileName);
    if (!sceneFile.exists() || !sceneFile.open(QIODevice::ReadOnly))
    {
        _sceneFileName = "";
        return;
    }

    const auto content = sceneFile.readAll();
    QJsonParseError parseError;
    const auto document = QJsonDocument::fromJson(content, &parseError);
    if (parseError.error != QJsonParseError::NoError)
    {
        qDebug() << parseError.errorString() << " at " << parseError.offset;
        return;
    }

    CreateScene(document.object());
}

void MainWindow::CreateScene(const QJsonObject& json)
{
    if (_scene)
    {
        disconnect(_ui->actionToggleGrid,    &QAction::triggered, _scene.get(), &NodeScene::toggleGridVisibility);
        disconnect(_ui->actionToggleSnap,    &QAction::triggered, _scene.get(), &NodeScene::toggleGridSnapping);
        disconnect(_ui->actionToggleOverlap, &QAction::triggered, _scene.get(), &NodeScene::toggleNodeOverlap);
    }

    _scene = std::make_unique<NodeScene>();
    _scene->read(json);

    _ui->nodeView->setScene(_scene.get());
    const auto centerx = json["scene"].toObject()["centerx"].toDouble();
    const auto centery = json["scene"].toObject()["centery"].toDouble();
    _ui->nodeView->centerOn(centerx, centery);

    connect(_ui->actionToggleGrid,    &QAction::triggered, _scene.get(), &NodeScene::toggleGridVisibility);
    connect(_ui->actionToggleSnap,    &QAction::triggered, _scene.get(), &NodeScene::toggleGridSnapping);
    connect(_ui->actionToggleOverlap, &QAction::triggered, _scene.get(), &NodeScene::toggleNodeOverlap);

    setWindowTitle(_sceneFileName.isEmpty() ? json["scene"].toObject()["name"].toString() : _sceneFileName);
}

void MainWindow::SaveSceneToFile(QFile& sceneFile)
{
    auto json = QJsonObject();
    const auto center = _ui->nodeView->getCenterOfViewport();
    QJsonObject sceneObject
    {
        {"centerx", center.x()},
        {"centery", center.y()}
    };
    json.insert("scene", sceneObject);
    _scene->write(json);

    const auto document = QJsonDocument(json);
    sceneFile.write(document.toJson());

    setWindowTitle(_sceneFileName);
}
<commit_msg>Starting with new empty scene when no scene is specified on cmd line<commit_after>#include "MainWindow.h"
#include "ui_MainWindow.h"

#include "CuteNode.h"
#include "NodeScene.h"

#include <QDebug>
#include <QFileDialog>
#include <QJsonDocument>
#include <QJsonObject>

namespace
{
    const QJsonObject kNewSceneAttributes
    {
        {"name",    QObject::tr("New Scene")},
        {"width",   3000},
        {"height",  3000},
        {"centerx", 1500},
        {"centery", 1500}
    };
}

MainWindow::MainWindow(const QString& sceneToOpen, QWidget* parent)
    : QMainWindow(parent)
    , _scene{nullptr}
    , _sceneFileName{sceneToOpen}
    , _ui{std::make_unique<Ui::MainWindow>()}
{
    _ui->setupUi(this);

    if (_sceneFileName.isEmpty())
    {
        on_actionNewScene_triggered();
    }
    else
    {
        LoadSceneFromFile();
    }
}

MainWindow::~MainWindow()
{
}

void MainWindow::on_actionExit_triggered()
{
    QApplication::quit();
}

void MainWindow::on_actionNewScene_triggered()
{
    _sceneFileName.clear();

    QJsonObject newSceneDescription
    {
        {"scene", kNewSceneAttributes}
    };

    CreateScene(newSceneDescription);
}

void MainWindow::on_actionLoadScene_triggered()
{
    _sceneFileName = QFileDialog::getOpenFileName(this, tr("Open Scene"), "..", "JSON (*.json)");
    if (_sceneFileName.isNull())
        return;

    LoadSceneFromFile();
}

void MainWindow::on_actionSaveScene_triggered()
{
    QFile sceneFile{_sceneFileName};

    if (!_sceneFileName.isEmpty() && sceneFile.open(QIODevice::WriteOnly))
    {
        SaveSceneToFile(sceneFile);
    }
    else
    {
        on_actionSaveSceneAs_triggered();
    }
}

void MainWindow::on_actionSaveSceneAs_triggered()
{
    _sceneFileName = QFileDialog::getSaveFileName(this, tr("Save Scene"), "..", "JSON (*.json)");
    QFile sceneFile(_sceneFileName);
    if (!sceneFile.open(QIODevice::WriteOnly))
        return;

    SaveSceneToFile(sceneFile);
}

void MainWindow::LoadSceneFromFile()
{
    QFile sceneFile(_sceneFileName);
    if (!sceneFile.exists() || !sceneFile.open(QIODevice::ReadOnly))
    {
        _sceneFileName = "";
        return;
    }

    const auto content = sceneFile.readAll();
    QJsonParseError parseError;
    const auto document = QJsonDocument::fromJson(content, &parseError);
    if (parseError.error != QJsonParseError::NoError)
    {
        qDebug() << parseError.errorString() << " at " << parseError.offset;
        return;
    }

    CreateScene(document.object());
}

void MainWindow::CreateScene(const QJsonObject& json)
{
    if (_scene)
    {
        disconnect(_ui->actionToggleGrid,    &QAction::triggered, _scene.get(), &NodeScene::toggleGridVisibility);
        disconnect(_ui->actionToggleSnap,    &QAction::triggered, _scene.get(), &NodeScene::toggleGridSnapping);
        disconnect(_ui->actionToggleOverlap, &QAction::triggered, _scene.get(), &NodeScene::toggleNodeOverlap);
    }

    _scene = std::make_unique<NodeScene>();
    _scene->read(json);

    _ui->nodeView->setScene(_scene.get());
    const auto centerx = json["scene"].toObject()["centerx"].toDouble();
    const auto centery = json["scene"].toObject()["centery"].toDouble();
    _ui->nodeView->centerOn(centerx, centery);

    connect(_ui->actionToggleGrid,    &QAction::triggered, _scene.get(), &NodeScene::toggleGridVisibility);
    connect(_ui->actionToggleSnap,    &QAction::triggered, _scene.get(), &NodeScene::toggleGridSnapping);
    connect(_ui->actionToggleOverlap, &QAction::triggered, _scene.get(), &NodeScene::toggleNodeOverlap);

    setWindowTitle(_sceneFileName.isEmpty() ? json["scene"].toObject()["name"].toString() : _sceneFileName);
}

void MainWindow::SaveSceneToFile(QFile& sceneFile)
{
    auto json = QJsonObject();
    const auto center = _ui->nodeView->getCenterOfViewport();
    QJsonObject sceneObject
    {
        {"centerx", center.x()},
        {"centery", center.y()}
    };
    json.insert("scene", sceneObject);
    _scene->write(json);

    const auto document = QJsonDocument(json);
    sceneFile.write(document.toJson());

    setWindowTitle(_sceneFileName);
}
<|endoftext|>