<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id: shape_io.cc 26 2005-03-29 19:18:59Z pavlenko $

#include "shape_io.hpp"
#include "shape.hpp"
#include <boost/filesystem/operations.hpp>

using mapnik::datasource_exception;
using mapnik::geometry_type;

const std::string shape_io::SHP = ".shp";
const std::string shape_io::DBF = ".dbf";
const std::string shape_io::INDEX = ".index";

shape_io::shape_io(const std::string& shape_name, bool open_index)
   : type_(shape_null),
     shp_(shape_name + SHP),
     dbf_(shape_name + DBF),
     reclength_(0),
     id_(0)
{
    bool ok = (shp_.is_open() && dbf_.is_open());
    if (!ok)
    {
        throw datasource_exception("Shape Plugin: cannot read shape file '" + shape_name + "'");
    }
    if (open_index)
    {
        try
        {

            if (!boost::filesystem::exists(shape_name + INDEX))
            {
                throw datasource_exception("Shape Plugin: could not open index: '" + shape_name + INDEX + "' does not exist");
            }

            index_= boost::shared_ptr<shape_file>(new shape_file(shape_name + INDEX));
        }
        catch (...)
        {
            std::cerr << "Shape Plugin: warning - could not open index: '" + shape_name + INDEX + "'" << std::endl;
        }
    }
}

shape_io::~shape_io()
{
   shp_.close();
   dbf_.close();
   if (index_) (*index_).close();
}

void shape_io::move_to (int pos)
{
   shp_.seek(pos);
   id_ = shp_.read_xdr_integer();
   reclength_ = shp_.read_xdr_integer();
   type_ = shp_.read_ndr_integer();

   if (shp_.is_eof()) {
       id_ = 0;
       reclength_ = 0;
       type_ = shape_null;
   }

   if (type_!= shape_null && type_ != shape_point && type_ != shape_pointm && type_ != shape_pointz)
   {
      shp_.read_envelope(cur_extent_);
   }
}

int shape_io::type() const
{
   return type_;
}

const box2d<double>& shape_io::current_extent() const
{
   return cur_extent_;
}

shape_file& shape_io::shp()
{
   return shp_;
}

shape_file& shape_io::shx()
{
   return shx_;
}

dbf_file& shape_io::dbf()
{
   return dbf_;
}

geometry_type * shape_io::read_polyline()
{
   shape_file::record_type record(reclength_*2-36);
   shp_.read_record(record);
   int num_parts=record.read_ndr_integer();
   int num_points=record.read_ndr_integer();
   geometry_type * line = new geometry_type(mapnik::LineString);
   line->set_capacity(num_points + num_parts);
   if (num_parts == 1)
   {
      line->set_capacity(num_points + 1);
      record.skip(4);
      double x=record.read_double();
      double y=record.read_double();
      line->move_to(x,y);
      for (int i=1;i<num_points;++i)
      {
         x=record.read_double();
         y=record.read_double();
         line->line_to(x,y);
      }
   }
   else
   {
      std::vector<int> parts(num_parts);
      for (int i=0;i<num_parts;++i)
      {
         parts[i]=record.read_ndr_integer();
      }

      int start,end;
      for (int k=0;k<num_parts;++k)
      {
         start=parts[k];
         if (k==num_parts-1)
            end=num_points;
         else
            end=parts[k+1];

         double x=record.read_double();
         double y=record.read_double();
         line->move_to(x,y);

         for (int j=start+1;j<end;++j)
         {
            x=record.read_double();
            y=record.read_double();
            line->line_to(x,y);
         }
      }
   }
   return line;
}

geometry_type * shape_io::read_polylinem()
{
   shape_file::record_type record(reclength_*2-36);
   shp_.read_record(record);
   int num_parts=record.read_ndr_integer();
   int num_points=record.read_ndr_integer();
   geometry_type * line = new geometry_type(mapnik::LineString);
   line->set_capacity(num_points + num_parts);
   if (num_parts == 1)
   {
      record.skip(4);
      double x=record.read_double();
      double y=record.read_double();
      line->move_to(x,y);
      for (int i=1;i<num_points;++i)
      {
         x=record.read_double();
         y=record.read_double();
         line->line_to(x,y);
      }
   }
   else
   {
      std::vector<int> parts(num_parts);
      for (int i=0;i<num_parts;++i)
      {
         parts[i]=record.read_ndr_integer();
      }

      int start,end;
      for (int k=0;k<num_parts;++k)
      {
         start=parts[k];
         if (k==num_parts-1)
            end=num_points;
         else
            end=parts[k+1];

         double x=record.read_double();
         double y=record.read_double();
         line->move_to(x,y);

         for (int j=start+1;j<end;++j)
         {
            x=record.read_double();
            y=record.read_double();
            line->line_to(x,y);
         }
      }
   }
   // m-range
   //double m0=record.read_double();
   //double m1=record.read_double();

   //for (int i=0;i<num_points;++i)
   //{
   //   double m=record.read_double();
   //}

   return line;
}

geometry_type * shape_io::read_polylinez()
{
   shape_file::record_type record(reclength_*2-36);
   shp_.read_record(record);
   int num_parts=record.read_ndr_integer();
   int num_points=record.read_ndr_integer();
   geometry_type * line = new geometry_type(mapnik::LineString);
   line->set_capacity(num_points + num_parts);
   if (num_parts == 1)
   {
      record.skip(4);
      double x=record.read_double();
      double y=record.read_double();
      line->move_to(x,y);
      for (int i=1;i<num_points;++i)
      {
         x=record.read_double();
         y=record.read_double();
         line->line_to(x,y);
      }
   }
   else
   {
      std::vector<int> parts(num_parts);
      for (int i=0;i<num_parts;++i)
      {
         parts[i]=record.read_ndr_integer();
      }

      int start,end;
      for (int k=0;k<num_parts;++k)
      {
         start=parts[k];
         if (k==num_parts-1)
            end=num_points;
         else
            end=parts[k+1];

         double x=record.read_double();
         double y=record.read_double();
         line->move_to(x,y);

         for (int j=start+1;j<end;++j)
         {
            x=record.read_double();
            y=record.read_double();
            line->line_to(x,y);
         }
      }
   }
   // z-range
   //double z0=record.read_double();
   //double z1=record.read_double();
   //for (int i=0;i<num_points;++i)
   // {
   //	double z=record.read_double();
   // }

   // m-range
   //double m0=record.read_double();
   //double m1=record.read_double();

   //for (int i=0;i<num_points;++i)
   //{
   //   double m=record.read_double();
   //}
   return line;
}

geometry_type * shape_io::read_polygon()
{
   shape_file::record_type record(reclength_*2-36);
   shp_.read_record(record);
   int num_parts=record.read_ndr_integer();
   int num_points=record.read_ndr_integer();
   std::vector<int> parts(num_parts);
   geometry_type * poly = new geometry_type(mapnik::Polygon);
   poly->set_capacity(num_points + num_parts);
   for (int i=0;i<num_parts;++i)
   {
      parts[i]=record.read_ndr_integer();
   }

   for (int k=0;k<num_parts;k++)
   {
      int start=parts[k];
      int end;
      if (k==num_parts-1)
      {
         end=num_points;
      }
      else
      {
         end=parts[k+1];
      }
      double x=record.read_double();
      double y=record.read_double();
      poly->move_to(x,y);

      for (int j=start+1;j<end;j++)
      {
         x=record.read_double();
         y=record.read_double();
         poly->line_to(x,y);
      }
   }
   return poly;
}

geometry_type * shape_io::read_polygonm()
{
   shape_file::record_type record(reclength_*2-36);
   shp_.read_record(record);
   int num_parts=record.read_ndr_integer();
   int num_points=record.read_ndr_integer();
   std::vector<int> parts(num_parts);
   geometry_type * poly = new geometry_type(mapnik::Polygon);
   poly->set_capacity(num_points + num_parts);
   for (int i=0;i<num_parts;++i)
   {
      parts[i]=record.read_ndr_integer();
   }

   for (int k=0;k<num_parts;k++)
   {
      int start=parts[k];
      int end;
      if (k==num_parts-1)
      {
         end=num_points;
      }
      else
      {
         end=parts[k+1];
      }
      double x=record.read_double();
      double y=record.read_double();
      poly->move_to(x,y);

      for (int j=start+1;j<end;j++)
      {
         x=record.read_double();
         y=record.read_double();
         poly->line_to(x,y);
      }
   }
   // m-range
   //double m0=record.read_double();
   //double m1=record.read_double();

   //for (int i=0;i<num_points;++i)
   //{
   //   double m=record.read_double();
   //}
   return poly;
}

geometry_type * shape_io::read_polygonz()
{
   shape_file::record_type record(reclength_*2-36);
   shp_.read_record(record);
   int num_parts=record.read_ndr_integer();
   int num_points=record.read_ndr_integer();
   std::vector<int> parts(num_parts);
   geometry_type * poly=new geometry_type(mapnik::Polygon);
   poly->set_capacity(num_points + num_parts);
   for (int i=0;i<num_parts;++i)
   {
      parts[i]=record.read_ndr_integer();
   }

   for (int k=0;k<num_parts;k++)
   {
      int start=parts[k];
      int end;
      if (k==num_parts-1)
      {
         end=num_points;
      }
      else
      {
         end=parts[k+1];
      }
      double x=record.read_double();
      double y=record.read_double();
      poly->move_to(x,y);

      for (int j=start+1;j<end;j++)
      {
         x=record.read_double();
         y=record.read_double();
         poly->line_to(x,y);
      }
   }
   // z-range
   //double z0=record.read_double();
   //double z1=record.read_double();
   //for (int i=0;i<num_points;++i)
   //{
   //	double z=record.read_double();
   //}

   // m-range
   //double m0=record.read_double();
   //double m1=record.read_double();

   //for (int i=0;i<num_points;++i)
   //{
   //   double m=record.read_double();
   //}
   return poly;
}
<commit_msg>only warn about missing index file in debug mode<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id: shape_io.cc 26 2005-03-29 19:18:59Z pavlenko $

#include "shape_io.hpp"
#include "shape.hpp"
#include <boost/filesystem/operations.hpp>

using mapnik::datasource_exception;
using mapnik::geometry_type;

const std::string shape_io::SHP = ".shp";
const std::string shape_io::DBF = ".dbf";
const std::string shape_io::INDEX = ".index";

shape_io::shape_io(const std::string& shape_name, bool open_index)
   : type_(shape_null),
     shp_(shape_name + SHP),
     dbf_(shape_name + DBF),
     reclength_(0),
     id_(0)
{
    bool ok = (shp_.is_open() && dbf_.is_open());
    if (!ok)
    {
        throw datasource_exception("Shape Plugin: cannot read shape file '" + shape_name + "'");
    }
    if (open_index)
    {
        try
        {

            index_= boost::shared_ptr<shape_file>(new shape_file(shape_name + INDEX));
        }
        catch (...)
        {
#ifdef MAPNIK_DEBUG
            std::clog << "Shape Plugin: warning - could not open index: '" + shape_name + INDEX + "'" << std::endl;
#endif
        }
    }
}

shape_io::~shape_io()
{
   shp_.close();
   dbf_.close();
   if (index_) (*index_).close();
}

void shape_io::move_to (int pos)
{
   shp_.seek(pos);
   id_ = shp_.read_xdr_integer();
   reclength_ = shp_.read_xdr_integer();
   type_ = shp_.read_ndr_integer();

   if (shp_.is_eof()) {
       id_ = 0;
       reclength_ = 0;
       type_ = shape_null;
   }

   if (type_!= shape_null && type_ != shape_point && type_ != shape_pointm && type_ != shape_pointz)
   {
      shp_.read_envelope(cur_extent_);
   }
}

int shape_io::type() const
{
   return type_;
}

const box2d<double>& shape_io::current_extent() const
{
   return cur_extent_;
}

shape_file& shape_io::shp()
{
   return shp_;
}

shape_file& shape_io::shx()
{
   return shx_;
}

dbf_file& shape_io::dbf()
{
   return dbf_;
}

geometry_type * shape_io::read_polyline()
{
   shape_file::record_type record(reclength_*2-36);
   shp_.read_record(record);
   int num_parts=record.read_ndr_integer();
   int num_points=record.read_ndr_integer();
   geometry_type * line = new geometry_type(mapnik::LineString);
   line->set_capacity(num_points + num_parts);
   if (num_parts == 1)
   {
      line->set_capacity(num_points + 1);
      record.skip(4);
      double x=record.read_double();
      double y=record.read_double();
      line->move_to(x,y);
      for (int i=1;i<num_points;++i)
      {
         x=record.read_double();
         y=record.read_double();
         line->line_to(x,y);
      }
   }
   else
   {
      std::vector<int> parts(num_parts);
      for (int i=0;i<num_parts;++i)
      {
         parts[i]=record.read_ndr_integer();
      }

      int start,end;
      for (int k=0;k<num_parts;++k)
      {
         start=parts[k];
         if (k==num_parts-1)
            end=num_points;
         else
            end=parts[k+1];

         double x=record.read_double();
         double y=record.read_double();
         line->move_to(x,y);

         for (int j=start+1;j<end;++j)
         {
            x=record.read_double();
            y=record.read_double();
            line->line_to(x,y);
         }
      }
   }
   return line;
}

geometry_type * shape_io::read_polylinem()
{
   shape_file::record_type record(reclength_*2-36);
   shp_.read_record(record);
   int num_parts=record.read_ndr_integer();
   int num_points=record.read_ndr_integer();
   geometry_type * line = new geometry_type(mapnik::LineString);
   line->set_capacity(num_points + num_parts);
   if (num_parts == 1)
   {
      record.skip(4);
      double x=record.read_double();
      double y=record.read_double();
      line->move_to(x,y);
      for (int i=1;i<num_points;++i)
      {
         x=record.read_double();
         y=record.read_double();
         line->line_to(x,y);
      }
   }
   else
   {
      std::vector<int> parts(num_parts);
      for (int i=0;i<num_parts;++i)
      {
         parts[i]=record.read_ndr_integer();
      }

      int start,end;
      for (int k=0;k<num_parts;++k)
      {
         start=parts[k];
         if (k==num_parts-1)
            end=num_points;
         else
            end=parts[k+1];

         double x=record.read_double();
         double y=record.read_double();
         line->move_to(x,y);

         for (int j=start+1;j<end;++j)
         {
            x=record.read_double();
            y=record.read_double();
            line->line_to(x,y);
         }
      }
   }
   // m-range
   //double m0=record.read_double();
   //double m1=record.read_double();

   //for (int i=0;i<num_points;++i)
   //{
   //   double m=record.read_double();
   //}

   return line;
}

geometry_type * shape_io::read_polylinez()
{
   shape_file::record_type record(reclength_*2-36);
   shp_.read_record(record);
   int num_parts=record.read_ndr_integer();
   int num_points=record.read_ndr_integer();
   geometry_type * line = new geometry_type(mapnik::LineString);
   line->set_capacity(num_points + num_parts);
   if (num_parts == 1)
   {
      record.skip(4);
      double x=record.read_double();
      double y=record.read_double();
      line->move_to(x,y);
      for (int i=1;i<num_points;++i)
      {
         x=record.read_double();
         y=record.read_double();
         line->line_to(x,y);
      }
   }
   else
   {
      std::vector<int> parts(num_parts);
      for (int i=0;i<num_parts;++i)
      {
         parts[i]=record.read_ndr_integer();
      }

      int start,end;
      for (int k=0;k<num_parts;++k)
      {
         start=parts[k];
         if (k==num_parts-1)
            end=num_points;
         else
            end=parts[k+1];

         double x=record.read_double();
         double y=record.read_double();
         line->move_to(x,y);

         for (int j=start+1;j<end;++j)
         {
            x=record.read_double();
            y=record.read_double();
            line->line_to(x,y);
         }
      }
   }
   // z-range
   //double z0=record.read_double();
   //double z1=record.read_double();
   //for (int i=0;i<num_points;++i)
   // {
   //	double z=record.read_double();
   // }

   // m-range
   //double m0=record.read_double();
   //double m1=record.read_double();

   //for (int i=0;i<num_points;++i)
   //{
   //   double m=record.read_double();
   //}
   return line;
}

geometry_type * shape_io::read_polygon()
{
   shape_file::record_type record(reclength_*2-36);
   shp_.read_record(record);
   int num_parts=record.read_ndr_integer();
   int num_points=record.read_ndr_integer();
   std::vector<int> parts(num_parts);
   geometry_type * poly = new geometry_type(mapnik::Polygon);
   poly->set_capacity(num_points + num_parts);
   for (int i=0;i<num_parts;++i)
   {
      parts[i]=record.read_ndr_integer();
   }

   for (int k=0;k<num_parts;k++)
   {
      int start=parts[k];
      int end;
      if (k==num_parts-1)
      {
         end=num_points;
      }
      else
      {
         end=parts[k+1];
      }
      double x=record.read_double();
      double y=record.read_double();
      poly->move_to(x,y);

      for (int j=start+1;j<end;j++)
      {
         x=record.read_double();
         y=record.read_double();
         poly->line_to(x,y);
      }
   }
   return poly;
}

geometry_type * shape_io::read_polygonm()
{
   shape_file::record_type record(reclength_*2-36);
   shp_.read_record(record);
   int num_parts=record.read_ndr_integer();
   int num_points=record.read_ndr_integer();
   std::vector<int> parts(num_parts);
   geometry_type * poly = new geometry_type(mapnik::Polygon);
   poly->set_capacity(num_points + num_parts);
   for (int i=0;i<num_parts;++i)
   {
      parts[i]=record.read_ndr_integer();
   }

   for (int k=0;k<num_parts;k++)
   {
      int start=parts[k];
      int end;
      if (k==num_parts-1)
      {
         end=num_points;
      }
      else
      {
         end=parts[k+1];
      }
      double x=record.read_double();
      double y=record.read_double();
      poly->move_to(x,y);

      for (int j=start+1;j<end;j++)
      {
         x=record.read_double();
         y=record.read_double();
         poly->line_to(x,y);
      }
   }
   // m-range
   //double m0=record.read_double();
   //double m1=record.read_double();

   //for (int i=0;i<num_points;++i)
   //{
   //   double m=record.read_double();
   //}
   return poly;
}

geometry_type * shape_io::read_polygonz()
{
   shape_file::record_type record(reclength_*2-36);
   shp_.read_record(record);
   int num_parts=record.read_ndr_integer();
   int num_points=record.read_ndr_integer();
   std::vector<int> parts(num_parts);
   geometry_type * poly=new geometry_type(mapnik::Polygon);
   poly->set_capacity(num_points + num_parts);
   for (int i=0;i<num_parts;++i)
   {
      parts[i]=record.read_ndr_integer();
   }

   for (int k=0;k<num_parts;k++)
   {
      int start=parts[k];
      int end;
      if (k==num_parts-1)
      {
         end=num_points;
      }
      else
      {
         end=parts[k+1];
      }
      double x=record.read_double();
      double y=record.read_double();
      poly->move_to(x,y);

      for (int j=start+1;j<end;j++)
      {
         x=record.read_double();
         y=record.read_double();
         poly->line_to(x,y);
      }
   }
   // z-range
   //double z0=record.read_double();
   //double z1=record.read_double();
   //for (int i=0;i<num_points;++i)
   //{
   //	double z=record.read_double();
   //}

   // m-range
   //double m0=record.read_double();
   //double m1=record.read_double();

   //for (int i=0;i<num_points;++i)
   //{
   //   double m=record.read_double();
   //}
   return poly;
}
<|endoftext|>


<commit_before>/****************************************************************************
 *
 * Copyright (c) 2015 Mark Charlebois. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 * 3. Neither the name PX4 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.
 *
 ****************************************************************************/

/**
 * @file vdev_posix.cpp
 *
 * POSIX-like API for virtual character device
 */

#include <px4_log.h>
#include <px4_posix.h>
#include <px4_time.h>
#include "device.h"
#include "vfile.h"

#include <hrt_work.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>

using namespace device;

extern "C" {

static void timer_cb(void *data)
{
	sem_t *p_sem = (sem_t *)data;
	sem_post(p_sem);
	PX4_DEBUG("timer_handler: Timer expired");
}

#define PX4_MAX_FD 200
static device::file_t *filemap[PX4_MAX_FD] = {};

int px4_errno;

inline bool valid_fd(int fd)
{
	return (fd < PX4_MAX_FD && fd >= 0 && filemap[fd] != NULL);
}

int px4_open(const char *path, int flags, ...)
{
	PX4_DEBUG("px4_open");
	VDev *dev = VDev::getDev(path);
	int ret = 0;
	int i;
	mode_t mode;

	if (!dev && (flags & (PX4_F_WRONLY|PX4_F_CREAT)) != 0 &&
		strncmp(path, "/obj/", 5) != 0 &&
		strncmp(path, "/dev/", 5) != 0)
	{
		va_list p;
		va_start(p, flags);
 		mode = va_arg(p, mode_t);
		va_end(p);

		// Create the file
		PX4_DEBUG("Creating virtual file %s", path);
		dev = VFile::createFile(path, mode);
	}
	if (dev) {
		for (i=0; i<PX4_MAX_FD; ++i) {
			if (filemap[i] == 0) {
				filemap[i] = new device::file_t(flags,dev,i);
				break;
			}
		}
		if (i < PX4_MAX_FD) {
			ret = dev->open(filemap[i]);
		}
		else {
			PX4_WARN("exceeded maximum number of file descriptors!");
			ret = -ENOENT;
		}
	}
	else {
		ret = -EINVAL;
	}
	if (ret < 0) {
		px4_errno = -ret;
		return -1;
	}
	PX4_DEBUG("px4_open fd = %d", filemap[i]->fd);
	return filemap[i]->fd;
}

int px4_close(int fd)
{
	int ret;
	if (valid_fd(fd)) {
		VDev *dev = (VDev *)(filemap[fd]->vdev);
		PX4_DEBUG("px4_close fd = %d", fd);
		ret = dev->close(filemap[fd]);
		filemap[fd] = NULL;
	}
	else {
                ret = -EINVAL;
        }
	if (ret < 0) {
		px4_errno = -ret;
		ret = PX4_ERROR;
	}
	return ret;
}

ssize_t px4_read(int fd, void *buffer, size_t buflen)
{
	int ret;
	if (valid_fd(fd)) {
		VDev *dev = (VDev *)(filemap[fd]->vdev);
		PX4_DEBUG("px4_read fd = %d", fd);
		ret = dev->read(filemap[fd], (char *)buffer, buflen);
	}
	else {
                ret = -EINVAL;
        }
	if (ret < 0) {
		px4_errno = -ret;
		ret = PX4_ERROR;
	}
	return ret;
}

ssize_t px4_write(int fd, const void *buffer, size_t buflen)
{
	int ret;
        if (valid_fd(fd)) {
		VDev *dev = (VDev *)(filemap[fd]->vdev);
		PX4_DEBUG("px4_write fd = %d", fd);
		ret = dev->write(filemap[fd], (const char *)buffer, buflen);
	}
	else {
                ret = -EINVAL;
        }
	if (ret < 0) {
		px4_errno = -ret;
		ret = PX4_ERROR;
	}
        return ret;
}

int px4_ioctl(int fd, int cmd, unsigned long arg)
{
	PX4_DEBUG("px4_ioctl fd = %d", fd);
	int ret = 0;
        if (valid_fd(fd)) {
		VDev *dev = (VDev *)(filemap[fd]->vdev);
		ret = dev->ioctl(filemap[fd], cmd, arg);
	}
	else {
                ret = -EINVAL;
        }
	if (ret < 0) {
		px4_errno = -ret;
	}

        return ret;
}

int px4_poll(px4_pollfd_struct_t *fds, nfds_t nfds, int timeout)
{
	sem_t sem;
	int count = 0;
	int ret;
	unsigned int i;

	PX4_DEBUG("Called px4_poll timeout = %d", timeout);
	sem_init(&sem, 0, 0);

	// For each fd
	for (i=0; i<nfds; ++i)
	{
		fds[i].sem     = &sem;
		fds[i].revents = 0;
		fds[i].priv    = NULL;

		// If fd is valid
		if (valid_fd(fds[i].fd))
		{
			VDev *dev = (VDev *)(filemap[fds[i].fd]->vdev);;
			PX4_DEBUG("px4_poll: VDev->poll(setup) %d", fds[i].fd);
			ret = dev->poll(filemap[fds[i].fd], &fds[i], true);

			if (ret < 0)
				break;
		}
	}

	if (ret >= 0)
	{
		if (timeout >= 0)
		{
			// Use a work queue task
			work_s _hpwork;

			hrt_work_queue(&_hpwork, (worker_t)&timer_cb, (void *)&sem, 1000*timeout);
			sem_wait(&sem);

			// Make sure timer thread is killed before sem goes
			// out of scope
			hrt_work_cancel(&_hpwork);
        	}
		else
		{
			sem_wait(&sem);
		}

		// For each fd
		for (i=0; i<nfds; ++i)
		{
			// If fd is valid
			if (valid_fd(fds[i].fd))
			{
				VDev *dev = (VDev *)(filemap[fds[i].fd]->vdev);;
				PX4_DEBUG("px4_poll: VDev->poll(teardown) %d", fds[i].fd);
				ret = dev->poll(filemap[fds[i].fd], &fds[i], false);

				if (ret < 0)
					break;

				if (fds[i].revents)
				count += 1;
			}
		}
	}

	sem_destroy(&sem);

	return count;
}

int px4_fsync(int fd)
{
	return 0;
}

int px4_access(const char *pathname, int mode)
{
	if (mode == F_OK) {
		errno = EINVAL;
		return -1;
	}
	VDev *dev = VDev::getDev(pathname);
	return (dev != nullptr) ? 0 : -1;
}

void px4_show_devices()
{
	VDev::showDevices();
}

void px4_show_topics()
{
	VDev::showTopics();
}

void px4_show_files()
{
	VDev::showFiles();
}

const char * px4_get_device_names(unsigned int *handle)
{
	return VDev::devList(handle);
}

const char * px4_get_topic_names(unsigned int *handle)
{
	return VDev::topicList(handle);
}

}

<commit_msg>fix logic in posix access function<commit_after>/****************************************************************************
 *
 * Copyright (c) 2015 Mark Charlebois. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 * 3. Neither the name PX4 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.
 *
 ****************************************************************************/

/**
 * @file vdev_posix.cpp
 *
 * POSIX-like API for virtual character device
 */

#include <px4_log.h>
#include <px4_posix.h>
#include <px4_time.h>
#include "device.h"
#include "vfile.h"

#include <hrt_work.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>

using namespace device;

extern "C" {

static void timer_cb(void *data)
{
	sem_t *p_sem = (sem_t *)data;
	sem_post(p_sem);
	PX4_DEBUG("timer_handler: Timer expired");
}

#define PX4_MAX_FD 200
static device::file_t *filemap[PX4_MAX_FD] = {};

int px4_errno;

inline bool valid_fd(int fd)
{
	return (fd < PX4_MAX_FD && fd >= 0 && filemap[fd] != NULL);
}

int px4_open(const char *path, int flags, ...)
{
	PX4_DEBUG("px4_open");
	VDev *dev = VDev::getDev(path);
	int ret = 0;
	int i;
	mode_t mode;

	if (!dev && (flags & (PX4_F_WRONLY|PX4_F_CREAT)) != 0 &&
		strncmp(path, "/obj/", 5) != 0 &&
		strncmp(path, "/dev/", 5) != 0)
	{
		va_list p;
		va_start(p, flags);
 		mode = va_arg(p, mode_t);
		va_end(p);

		// Create the file
		PX4_DEBUG("Creating virtual file %s", path);
		dev = VFile::createFile(path, mode);
	}
	if (dev) {
		for (i=0; i<PX4_MAX_FD; ++i) {
			if (filemap[i] == 0) {
				filemap[i] = new device::file_t(flags,dev,i);
				break;
			}
		}
		if (i < PX4_MAX_FD) {
			ret = dev->open(filemap[i]);
		}
		else {
			PX4_WARN("exceeded maximum number of file descriptors!");
			ret = -ENOENT;
		}
	}
	else {
		ret = -EINVAL;
	}
	if (ret < 0) {
		px4_errno = -ret;
		return -1;
	}
	PX4_DEBUG("px4_open fd = %d", filemap[i]->fd);
	return filemap[i]->fd;
}

int px4_close(int fd)
{
	int ret;
	if (valid_fd(fd)) {
		VDev *dev = (VDev *)(filemap[fd]->vdev);
		PX4_DEBUG("px4_close fd = %d", fd);
		ret = dev->close(filemap[fd]);
		filemap[fd] = NULL;
	}
	else {
                ret = -EINVAL;
        }
	if (ret < 0) {
		px4_errno = -ret;
		ret = PX4_ERROR;
	}
	return ret;
}

ssize_t px4_read(int fd, void *buffer, size_t buflen)
{
	int ret;
	if (valid_fd(fd)) {
		VDev *dev = (VDev *)(filemap[fd]->vdev);
		PX4_DEBUG("px4_read fd = %d", fd);
		ret = dev->read(filemap[fd], (char *)buffer, buflen);
	}
	else {
                ret = -EINVAL;
        }
	if (ret < 0) {
		px4_errno = -ret;
		ret = PX4_ERROR;
	}
	return ret;
}

ssize_t px4_write(int fd, const void *buffer, size_t buflen)
{
	int ret;
        if (valid_fd(fd)) {
		VDev *dev = (VDev *)(filemap[fd]->vdev);
		PX4_DEBUG("px4_write fd = %d", fd);
		ret = dev->write(filemap[fd], (const char *)buffer, buflen);
	}
	else {
                ret = -EINVAL;
        }
	if (ret < 0) {
		px4_errno = -ret;
		ret = PX4_ERROR;
	}
        return ret;
}

int px4_ioctl(int fd, int cmd, unsigned long arg)
{
	PX4_DEBUG("px4_ioctl fd = %d", fd);
	int ret = 0;
        if (valid_fd(fd)) {
		VDev *dev = (VDev *)(filemap[fd]->vdev);
		ret = dev->ioctl(filemap[fd], cmd, arg);
	}
	else {
                ret = -EINVAL;
        }
	if (ret < 0) {
		px4_errno = -ret;
	}

        return ret;
}

int px4_poll(px4_pollfd_struct_t *fds, nfds_t nfds, int timeout)
{
	sem_t sem;
	int count = 0;
	int ret;
	unsigned int i;

	PX4_DEBUG("Called px4_poll timeout = %d", timeout);
	sem_init(&sem, 0, 0);

	// For each fd
	for (i=0; i<nfds; ++i)
	{
		fds[i].sem     = &sem;
		fds[i].revents = 0;
		fds[i].priv    = NULL;

		// If fd is valid
		if (valid_fd(fds[i].fd))
		{
			VDev *dev = (VDev *)(filemap[fds[i].fd]->vdev);;
			PX4_DEBUG("px4_poll: VDev->poll(setup) %d", fds[i].fd);
			ret = dev->poll(filemap[fds[i].fd], &fds[i], true);

			if (ret < 0)
				break;
		}
	}

	if (ret >= 0)
	{
		if (timeout >= 0)
		{
			// Use a work queue task
			work_s _hpwork;

			hrt_work_queue(&_hpwork, (worker_t)&timer_cb, (void *)&sem, 1000*timeout);
			sem_wait(&sem);

			// Make sure timer thread is killed before sem goes
			// out of scope
			hrt_work_cancel(&_hpwork);
        	}
		else
		{
			sem_wait(&sem);
		}

		// For each fd
		for (i=0; i<nfds; ++i)
		{
			// If fd is valid
			if (valid_fd(fds[i].fd))
			{
				VDev *dev = (VDev *)(filemap[fds[i].fd]->vdev);;
				PX4_DEBUG("px4_poll: VDev->poll(teardown) %d", fds[i].fd);
				ret = dev->poll(filemap[fds[i].fd], &fds[i], false);

				if (ret < 0)
					break;

				if (fds[i].revents)
				count += 1;
			}
		}
	}

	sem_destroy(&sem);

	return count;
}

int px4_fsync(int fd)
{
	return 0;
}

int px4_access(const char *pathname, int mode)
{
	if (mode != F_OK) {
		errno = EINVAL;
		return -1;
	}
	VDev *dev = VDev::getDev(pathname);
	return (dev != nullptr) ? 0 : -1;
}

void px4_show_devices()
{
	VDev::showDevices();
}

void px4_show_topics()
{
	VDev::showTopics();
}

void px4_show_files()
{
	VDev::showFiles();
}

const char * px4_get_device_names(unsigned int *handle)
{
	return VDev::devList(handle);
}

const char * px4_get_topic_names(unsigned int *handle)
{
	return VDev::topicList(handle);
}

}

<|endoftext|>


<commit_before>#include <unistd.h>
#include <cassert>
#include <boost/shared_ptr.hpp>

#include "gen-cpp/DataHub.h"
#include <thrift/transport/THttpClient.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/protocol/TBinaryProtocol.h>

/**
 * Sample DataHub C++ Client
 *
 * @author anantb
 * @author stephentu
 * @date 11/07/2013
 *
 */

using namespace std;
using namespace boost;
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;

using namespace datahub;

int main () {
  try {
    shared_ptr<THttpClient> transport(new THttpClient("datahub.csail.mit.edu", 80, "/service"));
    shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
    DataHubClient client(protocol);

    transport->open();
    double version = client.get_version();
    cout << version << endl;

    ConnectionParams params = ConnectionParams();
    params.__set_user("anantb");
    params.__set_password("anant");

    Connection conn;
    client.open_connection(conn, params);

    ResultSet res;
    client.execute_sql(
      res, conn, "select * from anantb.test.demo", vector<string>());
    for(
        const auto* tuple_it = res.tuples.begin();
        tuple_it != res.tuples.end();
        ++tuple_it) {
      for(
          const auto* cell_it = (*tuple_it).cells.begin();
          cell_it != (*tuple_it).cells.end();
          ++cell_it) {
        std::cout << *cell_it << "\t";
      }
      std::cout << std::endl;
    }

    transport->close();
  } catch (TException &tx) {
    cout << "ERROR: " << tx.what();
  }

  return 0;
}
<commit_msg>cpp sample<commit_after>#include <unistd.h>
#include <cassert>
#include <boost/shared_ptr.hpp>

#include "gen-cpp/DataHub.h"
#include <thrift/transport/THttpClient.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/protocol/TBinaryProtocol.h>

/**
 * Sample DataHub C++ Client
 *
 * @author anantb
 * @author stephentu
 * @date 11/07/2013
 *
 */

using namespace std;
using namespace boost;
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;

using namespace datahub;

int main () {
  try {
    shared_ptr<THttpClient> transport(new THttpClient("datahub.csail.mit.edu", 80, "/service"));
    shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
    DataHubClient client(protocol);

    transport->open();
    double version = client.get_version();
    cout << version << endl;

    ConnectionParams params = ConnectionParams();
    params.__set_user("anantb");
    params.__set_password("anant");

    Connection conn;
    client.open_connection(conn, params);

    ResultSet res;
    client.execute_sql(
      res, conn, "select * from anantb.test.demo", vector<string>());
    for(vector<Tuple>::const_iterator tuple_it = res.tuples.begin();
        tuple_it != res.tuples.end();
        ++tuple_it) {
      for(vector<string>::const_iterator cell_it = (*tuple_it).cells.begin();
          cell_it != (*tuple_it).cells.end();
          ++cell_it) {
        cout << *cell_it << "\t";
      }
      cout << std::endl;
    }

    transport->close();
  } catch (TException &tx) {
    cout << "ERROR: " << tx.what();
  }

  return 0;
}
<|endoftext|>


<commit_before>/* -*- C++ -*- */
/*************************************************************************
 * Copyright(c) 1995~2005  Masaharu Goto (cint@pcroot.cern.ch)
 *
 * For the licensing terms see the file COPYING
 *
 ************************************************************************/

#if defined(interp) && defined(makecint)
#pragma include "test.dll"
#else
#include "t980.h"
#endif
#include <stdio.h>

int main(int,char**) {
  A b ;
  b = A("A part") + " of a whole";
  A a = A("A part") + " of a whole";
  printf("%s. %s.\n",a.val(),b.val());

  f(a,"A part of a whole");
  f("A part of a whole",a);

  if(strcmp(a,"A part of a whole")==0) printf("true\n");
  else printf("false\n");
  if(strcmp(a,"a part of a whole")==0) printf("true\n");
  else printf("false\n");

  if(strcmp(a.val(),"A part of a whole")==0) printf("true\n");
  else printf("false\n");
  if(strcmp(a.val(),"a part of a whole")==0) printf("true\n");
  else printf("false\n");
  return 0;
}

<commit_msg>Fix so it compiles with gcc 4.3.1 (missing includes).<commit_after>/* -*- C++ -*- */
/*************************************************************************
 * Copyright(c) 1995~2005  Masaharu Goto (cint@pcroot.cern.ch)
 *
 * For the licensing terms see the file COPYING
 *
 ************************************************************************/

#if defined(interp) && defined(makecint)
#pragma include "test.dll"
#else
#include "t980.h"
#endif

#include <cstdio>
#include <cstring>

using namespace std;

int main(int, char**)
{
   A b;
   b = A("A part") + " of a whole";
   A a = A("A part") + " of a whole";
   printf("%s. %s.\n", a.val(), b.val());

   f(a, "A part of a whole");
   f("A part of a whole", a);

   if (!strcmp(a, "A part of a whole")) {
      printf("true\n");
   }
   else {
      printf("false\n");
   }
   if (!strcmp(a, "a part of a whole")) {
      printf("true\n");
   }
   else {
      printf("false\n");
   }

   if (!strcmp(a.val(), "A part of a whole")) {
      printf("true\n");
   }
   else {
      printf("false\n");
   }
   if (!strcmp(a.val(), "a part of a whole")) {
      printf("true\n");
   }
   else {
      printf("false\n");
   }
   return 0;
}

<|endoftext|>


<commit_before>#include "Call.h"
#include "Argument.h"
#include "compiler.h"
#include "helper.h"
#include <iostream>
#include <stack>
#include <sstream>

Call::Call(std::string code){
	std::size_t p = code.find('(');
	function_ = code.substr(0, p);
	code = code.substr(p + 1, code.length() - p - 2);

	std::stringstream currentArgument;
	bool isString = false;
	bool isChar = false;
	bool isEscaped = false;
	std::stack<char> keller;

	for (size_t i = 0; i < code.length(); i++) {
		char c = code[i];
		if (!isString && !isChar){
			switch (c) {
			case '(':
			case '{':
				keller.push(c);
				currentArgument << c;
				break;
			case ')':
				if (keller.empty() || pop(keller) != '(')
					throw;
				currentArgument << c;
				break;
			case '}':
				if (keller.empty() || pop(keller) != '{')
					throw;
				currentArgument << c;
				break;
			case ';':
				if (!keller.empty()) {
					currentArgument << c;
				}
				break;
			case '"':
				isString = true;
				currentArgument << c;
				break;
			case '\'':
				isChar = true;
				currentArgument << c;
				break;
			case ' ':
				break;
			case ',':
				if (keller.size() > 0){ //if it isn't a comma that separates parameters of this call
					currentArgument << c;
				}
				break;
			default:
				currentArgument << c;
				break;
			}
		}
		else {
			if (!isEscaped){
				if (c == '"') {
					isString = false;
				}
				else if (c == '\'') {
					isChar = false;
				}
				else if (c == '\\') {
					isEscaped = true;
				}
			}
			else {
				isEscaped = false;
			}
			currentArgument << c;
		}

		if (keller.empty() && !isString && !isChar && (i == code.length() - 1 || code[i + 1] == ',')) {
			arguments_.emplace_back(parseArgument(currentArgument.str()));

			//this clears the stringstream
			currentArgument.str(std::string());
			currentArgument.clear();
		}
	}

	if (!keller.empty()) {
		throw;
	}
}

Type Call::getType() const {
	return CALL;
}

CallSignature Call::signature() const {
	std::vector<Type> params;
	for (auto &a : arguments_) {
		params.push_back(a->getType());
	}
	CallSignature r;
	r.first = getFunction();
	r.second = params;
	return r;
}

bool Call::matches(CallSignature sig) const {
	if (arguments_.size() != sig.second.size() || sig.first != function_) //TODO: Make case-insensitive check here?
		return false;
	//assert: lengths are now equal
	std::vector<Type>::iterator itr = sig.second.begin();
	for (auto& i : arguments_) {
		if (i->getType() != *itr
			&& !(isEvaluatable(*itr) && isEvaluatable(i->getType()))
			&& !(isCallable(*itr) && isCallable(i->getType()))
			)
			return false;
		itr++;
	}
	return true;
}

std::string Call::getFunction() const {
	return function_;
}

unsigned int Call::evaluate(Compiler& compiler) const {
    unsigned int target = compiler.bf().allocCell();
	evaluate(compiler, target);
	return target;
}

void Call::evaluate(Compiler& compiler, unsigned int target) const {
    MfFunction stmt = compiler.getFunction(*this);
	if (stmt != nullptr)
		stmt(compiler, *this, target);
}

void Call::compile(Compiler& cmp) const {
	MfProcedure stmt = cmp.getProcedure(*this);
	if (stmt != nullptr)
		stmt(cmp, *this);
	else
		cmp.warning(this, "Unknown procedure: " + function_);
}
<commit_msg>Added warning for unknown functions.<commit_after>#include "Call.h"
#include "Argument.h"
#include "compiler.h"
#include "helper.h"
#include <iostream>
#include <stack>
#include <sstream>

Call::Call(std::string code){
	std::size_t p = code.find('(');
	function_ = code.substr(0, p);
	code = code.substr(p + 1, code.length() - p - 2);

	std::stringstream currentArgument;
	bool isString = false;
	bool isChar = false;
	bool isEscaped = false;
	std::stack<char> keller;

	for (size_t i = 0; i < code.length(); i++) {
		char c = code[i];
		if (!isString && !isChar){
			switch (c) {
			case '(':
			case '{':
				keller.push(c);
				currentArgument << c;
				break;
			case ')':
				if (keller.empty() || pop(keller) != '(')
					throw;
				currentArgument << c;
				break;
			case '}':
				if (keller.empty() || pop(keller) != '{')
					throw;
				currentArgument << c;
				break;
			case ';':
				if (!keller.empty()) {
					currentArgument << c;
				}
				break;
			case '"':
				isString = true;
				currentArgument << c;
				break;
			case '\'':
				isChar = true;
				currentArgument << c;
				break;
			case ' ':
				break;
			case ',':
				if (keller.size() > 0){ //if it isn't a comma that separates parameters of this call
					currentArgument << c;
				}
				break;
			default:
				currentArgument << c;
				break;
			}
		}
		else {
			if (!isEscaped){
				if (c == '"') {
					isString = false;
				}
				else if (c == '\'') {
					isChar = false;
				}
				else if (c == '\\') {
					isEscaped = true;
				}
			}
			else {
				isEscaped = false;
			}
			currentArgument << c;
		}

		if (keller.empty() && !isString && !isChar && (i == code.length() - 1 || code[i + 1] == ',')) {
			arguments_.emplace_back(parseArgument(currentArgument.str()));

			//this clears the stringstream
			currentArgument.str(std::string());
			currentArgument.clear();
		}
	}

	if (!keller.empty()) {
		throw;
	}
}

Type Call::getType() const {
	return CALL;
}

CallSignature Call::signature() const {
	std::vector<Type> params;
	for (auto &a : arguments_) {
		params.push_back(a->getType());
	}
	CallSignature r;
	r.first = getFunction();
	r.second = params;
	return r;
}

bool Call::matches(CallSignature sig) const {
	if (arguments_.size() != sig.second.size() || sig.first != function_) //TODO: Make case-insensitive check here?
		return false;
	//assert: lengths are now equal
	std::vector<Type>::iterator itr = sig.second.begin();
	for (auto& i : arguments_) {
		if (i->getType() != *itr
			&& !(isEvaluatable(*itr) && isEvaluatable(i->getType()))
			&& !(isCallable(*itr) && isCallable(i->getType()))
			)
			return false;
		itr++;
	}
	return true;
}

std::string Call::getFunction() const {
	return function_;
}

unsigned int Call::evaluate(Compiler& compiler) const {
    unsigned int target = compiler.bf().allocCell();
	evaluate(compiler, target);
	return target;
}

void Call::evaluate(Compiler& cmp, unsigned int target) const {
    MfFunction stmt = cmp.getFunction(*this);
	if (stmt != nullptr)
		stmt(cmp, *this, target);
	else
		cmp.warning(this, "Unknown function: " + function_);
}

void Call::compile(Compiler& cmp) const {
	MfProcedure stmt = cmp.getProcedure(*this);
	if (stmt != nullptr)
		stmt(cmp, *this);
	else
		cmp.warning(this, "Unknown procedure: " + function_);
}
<|endoftext|>


<commit_before><commit_msg>Fix static initialization ordering bug that caused crashes at startup when compiling on Mac with static linking.<commit_after><|endoftext|>


<commit_before>/**************************************************************************
 *
 * Copyright 2012 Jose Fonseca
 * All Rights Reserved.
 *
 * 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.
 *
 **************************************************************************/

#include <string.h>
#include <limits.h> // for CHAR_MAX
#include <getopt.h>

#include "pickle.hpp"

#include "os_binary.hpp"

#include "cli.hpp"
#include "cli_pager.hpp"

#include "trace_parser.hpp"
#include "trace_model.hpp"
#include "trace_callset.hpp"

using namespace trace;

class PickleVisitor : public trace::Visitor
{
protected:
    PickleWriter &writer;
    bool symbolic;

public:
    PickleVisitor(PickleWriter &_writer, bool _symbolic) :
        writer(_writer),
        symbolic(_symbolic) {
    }

    void visit(Null *node) override {
        writer.writeInt(0);
    }

    void visit(Bool *node) override {
        writer.writeBool(node->value);
    }

    void visit(SInt *node) override {
        writer.writeInt(node->value);
    }

    void visit(UInt *node) override {
        writer.writeInt(node->value);
    }

    void visit(Float *node) override {
        writer.writeFloat(node->value);
    }

    void visit(Double *node) override {
        writer.writeFloat(node->value);
    }

    void visit(String *node) override {
        writer.writeString(node->value);
    }

    void visit(WString *node) override {
        writer.writeWString(node->value);
    }

    void visit(Enum *node) override {
        if (symbolic) {
            const EnumValue *it = node->lookup();
            if (it) {
                writer.writeString(it->name);
                return;
            }
        }
        writer.writeInt(node->value);
    }

    void visit(Bitmask *node) override {
        if (symbolic) {
            unsigned long long value = node->value;
            const BitmaskSig *sig = node->sig;
            writer.beginTuple();
            for (const BitmaskFlag *it = sig->flags; it != sig->flags + sig->num_flags; ++it) {
                if ((it->value && (value & it->value) == it->value) ||
                    (!it->value && value == 0)) {
                    writer.writeString(it->name);
                    value &= ~it->value;
                }
                if (value == 0) {
                    break;
                }
            }
            if (value) {
                writer.writeInt(value);
            }
            writer.endTuple();
        } else {
            writer.writeInt(node->value);
        }
    }

    void visit(Struct *node) override {
        if (true) {
            // Structures as dictionaries
            writer.beginDict();
            for (unsigned i = 0; i < node->sig->num_members; ++i) {
                writer.beginItem(node->sig->member_names[i]);
                _visit(node->members[i]);
                writer.endItem();
            }
            writer.endDict();
        } else {
            // Structures as tuples
            unsigned num_members = node->sig->num_members;
            writer.beginTuple(num_members);
            for (unsigned i = 0; i < num_members; ++i) {
                _visit(node->members[i]);
            }
            writer.endTuple(num_members);
        }
    }

    void visit(Array *node) override {
        writer.beginList();
        for (auto & value : node->values) {
            _visit(value);
        }
        writer.endList();
    }

    void visit(Blob *node) override {
        writer.writeBytes(node->buf, node->size);
    }

    void visit(Pointer *node) override {
        writer.writePointer(node->value);
    }

    void visit(Repr *r) override {
        if (symbolic) {
            _visit(r->humanValue);
        } else {
            _visit(r->machineValue);
        }
    }

    void visit(Call *call) {
        writer.beginTuple();

        writer.writeInt(call->no);

        writer.writeString(call->name());

        writer.beginList();
        for (unsigned i = 0; i < call->args.size(); ++i) {
            writer.beginTuple(2);
            if (i < call->sig->num_args) {
                writer.writeString(call->sig->arg_names[i]);
            } else {
                writer.writeNone();
            }
            if (call->args[i].value) {
                _visit(call->args[i].value);
            } else {
                writer.writeNone();
            }
            writer.endTuple(2);
        }
        writer.endList();

        if (call->ret) {
            _visit(call->ret);
        } else {
            writer.writeNone();
        }

        writer.writeInt(call->flags);

        writer.endTuple();
    }
};

static trace::CallSet calls(trace::FREQUENCY_ALL);

static const char *synopsis = "Pickle given trace(s) to standard output.";

static void
usage(void)
{
    std::cout
        << "usage: apitrace pickle [OPTIONS] TRACE_FILE...\n"
        << synopsis << "\n"
        "\n"
        "    -h, --help           show this help message and exit\n"
        "    -s, --symbolic       dump symbolic names\n"
        "    --calls=CALLSET      only dump specified calls\n"
    ;
}

enum {
	CALLS_OPT = CHAR_MAX + 1,
};

const static char *
shortOptions = "hs";

const static struct option
longOptions[] = {
    {"help", no_argument, 0, 'h'},
    {"symbolic", no_argument, 0, 's'},
    {"calls", required_argument, 0, CALLS_OPT},
    {0, 0, 0, 0}
};

static int
command(int argc, char *argv[])
{
    bool symbolic = false;

    int opt;
    while ((opt = getopt_long(argc, argv, shortOptions, longOptions, NULL)) != -1) {
        switch (opt) {
        case 'h':
            usage();
            return 0;
        case 's':
            symbolic = true;
            break;
        case CALLS_OPT:
            calls.merge(optarg);
            break;
        default:
            std::cerr << "error: unexpected option `" << (char)opt << "`\n";
            usage();
            return 1;
        }
    }

    os::setBinaryMode(stdout);

    std::cout.sync_with_stdio(false);

    PickleWriter writer(std::cout);
    PickleVisitor visitor(writer, symbolic);

    for (int i = optind; i < argc; ++i) {
        trace::Parser parser;

        if (!parser.open(argv[i])) {
            return 1;
        }

        trace::Call *call;
        while ((call = parser.parse_call())) {
            if (calls.contains(*call)) {
                writer.begin();
                visitor.visit(call);
                writer.end();
            }
            delete call;
        }
    }

    return 0;
}

const Command pickle_command = {
    "pickle",
    synopsis,
    usage,
    command
};
<commit_msg>cli: Terminate pickling early when possible.<commit_after>/**************************************************************************
 *
 * Copyright 2012 Jose Fonseca
 * All Rights Reserved.
 *
 * 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.
 *
 **************************************************************************/

#include <string.h>
#include <limits.h> // for CHAR_MAX
#include <getopt.h>

#include "pickle.hpp"

#include "os_binary.hpp"

#include "cli.hpp"
#include "cli_pager.hpp"

#include "trace_parser.hpp"
#include "trace_model.hpp"
#include "trace_callset.hpp"

using namespace trace;

class PickleVisitor : public trace::Visitor
{
protected:
    PickleWriter &writer;
    bool symbolic;

public:
    PickleVisitor(PickleWriter &_writer, bool _symbolic) :
        writer(_writer),
        symbolic(_symbolic) {
    }

    void visit(Null *node) override {
        writer.writeInt(0);
    }

    void visit(Bool *node) override {
        writer.writeBool(node->value);
    }

    void visit(SInt *node) override {
        writer.writeInt(node->value);
    }

    void visit(UInt *node) override {
        writer.writeInt(node->value);
    }

    void visit(Float *node) override {
        writer.writeFloat(node->value);
    }

    void visit(Double *node) override {
        writer.writeFloat(node->value);
    }

    void visit(String *node) override {
        writer.writeString(node->value);
    }

    void visit(WString *node) override {
        writer.writeWString(node->value);
    }

    void visit(Enum *node) override {
        if (symbolic) {
            const EnumValue *it = node->lookup();
            if (it) {
                writer.writeString(it->name);
                return;
            }
        }
        writer.writeInt(node->value);
    }

    void visit(Bitmask *node) override {
        if (symbolic) {
            unsigned long long value = node->value;
            const BitmaskSig *sig = node->sig;
            writer.beginTuple();
            for (const BitmaskFlag *it = sig->flags; it != sig->flags + sig->num_flags; ++it) {
                if ((it->value && (value & it->value) == it->value) ||
                    (!it->value && value == 0)) {
                    writer.writeString(it->name);
                    value &= ~it->value;
                }
                if (value == 0) {
                    break;
                }
            }
            if (value) {
                writer.writeInt(value);
            }
            writer.endTuple();
        } else {
            writer.writeInt(node->value);
        }
    }

    void visit(Struct *node) override {
        if (true) {
            // Structures as dictionaries
            writer.beginDict();
            for (unsigned i = 0; i < node->sig->num_members; ++i) {
                writer.beginItem(node->sig->member_names[i]);
                _visit(node->members[i]);
                writer.endItem();
            }
            writer.endDict();
        } else {
            // Structures as tuples
            unsigned num_members = node->sig->num_members;
            writer.beginTuple(num_members);
            for (unsigned i = 0; i < num_members; ++i) {
                _visit(node->members[i]);
            }
            writer.endTuple(num_members);
        }
    }

    void visit(Array *node) override {
        writer.beginList();
        for (auto & value : node->values) {
            _visit(value);
        }
        writer.endList();
    }

    void visit(Blob *node) override {
        writer.writeBytes(node->buf, node->size);
    }

    void visit(Pointer *node) override {
        writer.writePointer(node->value);
    }

    void visit(Repr *r) override {
        if (symbolic) {
            _visit(r->humanValue);
        } else {
            _visit(r->machineValue);
        }
    }

    void visit(Call *call) {
        writer.beginTuple();

        writer.writeInt(call->no);

        writer.writeString(call->name());

        writer.beginList();
        for (unsigned i = 0; i < call->args.size(); ++i) {
            writer.beginTuple(2);
            if (i < call->sig->num_args) {
                writer.writeString(call->sig->arg_names[i]);
            } else {
                writer.writeNone();
            }
            if (call->args[i].value) {
                _visit(call->args[i].value);
            } else {
                writer.writeNone();
            }
            writer.endTuple(2);
        }
        writer.endList();

        if (call->ret) {
            _visit(call->ret);
        } else {
            writer.writeNone();
        }

        writer.writeInt(call->flags);

        writer.endTuple();
    }
};

static trace::CallSet calls(trace::FREQUENCY_ALL);

static const char *synopsis = "Pickle given trace(s) to standard output.";

static void
usage(void)
{
    std::cout
        << "usage: apitrace pickle [OPTIONS] TRACE_FILE...\n"
        << synopsis << "\n"
        "\n"
        "    -h, --help           show this help message and exit\n"
        "    -s, --symbolic       dump symbolic names\n"
        "    --calls=CALLSET      only dump specified calls\n"
    ;
}

enum {
	CALLS_OPT = CHAR_MAX + 1,
};

const static char *
shortOptions = "hs";

const static struct option
longOptions[] = {
    {"help", no_argument, 0, 'h'},
    {"symbolic", no_argument, 0, 's'},
    {"calls", required_argument, 0, CALLS_OPT},
    {0, 0, 0, 0}
};

static int
command(int argc, char *argv[])
{
    bool symbolic = false;

    int opt;
    while ((opt = getopt_long(argc, argv, shortOptions, longOptions, NULL)) != -1) {
        switch (opt) {
        case 'h':
            usage();
            return 0;
        case 's':
            symbolic = true;
            break;
        case CALLS_OPT:
            calls.merge(optarg);
            break;
        default:
            std::cerr << "error: unexpected option `" << (char)opt << "`\n";
            usage();
            return 1;
        }
    }

    os::setBinaryMode(stdout);

    std::cout.sync_with_stdio(false);

    PickleWriter writer(std::cout);
    PickleVisitor visitor(writer, symbolic);

    for (int i = optind; i < argc; ++i) {
        trace::Parser parser;

        if (!parser.open(argv[i])) {
            return 1;
        }

        trace::Call *call;
        while ((call = parser.parse_call())) {
            if (call->no > calls.getLast()) {
                delete call;
                break;
            }
            if (calls.contains(*call)) {
                writer.begin();
                visitor.visit(call);
                writer.end();
            }
            delete call;
        }
    }

    return 0;
}

const Command pickle_command = {
    "pickle",
    synopsis,
    usage,
    command
};
<|endoftext|>


<commit_before>
// QT includes
#include <QCoreApplication>
#include <QImage>

// getoptPlusPLus includes
#include <getoptPlusPlus/getoptpp.h>

#include "protoserver/ProtoConnectionWrapper.h"
#include "X11Wrapper.h"
#include "HyperionConfig.h"
#include "utils/Profiler.h"

using namespace vlofgren;

// save the image as screenshot
void saveScreenshot(const char * filename, const Image<ColorRgb> & image)
{
	// store as PNG
	QImage pngImage((const uint8_t *) image.memptr(), image.width(), image.height(), 3*image.width(), QImage::Format_RGB888);
	pngImage.save(filename);
}

int main(int argc, char ** argv)
{
	 std::cout
		<< "hyperion-x11:" << std::endl
		<< "\tversion   : " << HYPERION_VERSION_ID << std::endl
		<< "\tbuild time: " << __DATE__ << " " << __TIME__ << std::endl;

	QCoreApplication app(argc, argv);

	try
	{
		// create the option parser and initialize all parameters
		OptionsParser optionParser("X11 capture application for Hyperion");
		ParameterSet & parameters = optionParser.getParameters();

		IntParameter           & argFps             = parameters.add<IntParameter>          ('f', "framerate",        "Capture frame rate [default: 10]");
		SwitchParameter<>      & argXGetImage       = parameters.add<SwitchParameter<>>     ('x', "xgetimage",        "Use XGetImage instead of XRender");
		IntParameter           & argCropWidth       = parameters.add<IntParameter>          (0x0, "crop-width",       "Number of pixels to crop from the left and right sides of the picture before decimation [default: 0]");
		IntParameter           & argCropHeight      = parameters.add<IntParameter>          (0x0, "crop-height",      "Number of pixels to crop from the top and the bottom of the picture before decimation [default: 0]");
		IntParameter           & argCropLeft        = parameters.add<IntParameter>          (0x0, "crop-left",        "Number of pixels to crop from the left of the picture before decimation (overrides --crop-width)");
		IntParameter           & argCropRight       = parameters.add<IntParameter>          (0x0, "crop-right",       "Number of pixels to crop from the right of the picture before decimation (overrides --crop-width)");
		IntParameter           & argCropTop         = parameters.add<IntParameter>          (0x0, "crop-top",         "Number of pixels to crop from the top of the picture before decimation (overrides --crop-height)");
		IntParameter           & argCropBottom      = parameters.add<IntParameter>          (0x0, "crop-bottom",      "Number of pixels to crop from the bottom of the picture before decimation (overrides --crop-height)");
		IntParameter           & argSizeDecimation  = parameters.add<IntParameter>          ('s', "size-decimator",   "Decimation factor for the output size [default=8]");
		SwitchParameter<>      & argScreenshot      = parameters.add<SwitchParameter<>>     (0x0, "screenshot",       "Take a single screenshot, save it to file and quit");
		StringParameter        & argAddress         = parameters.add<StringParameter>       ('a', "address",          "Set the address of the hyperion server [default: 127.0.0.1:19445]");
		IntParameter           & argPriority        = parameters.add<IntParameter>          ('p', "priority",         "Use the provided priority channel (the lower the number, the higher the priority) [default: 800]");
		SwitchParameter<>      & argSkipReply       = parameters.add<SwitchParameter<>>     (0x0, "skip-reply",       "Do not receive and check reply messages from Hyperion");
		SwitchParameter<>      & argHelp            = parameters.add<SwitchParameter<>>     ('h', "help",             "Show this help message and exit");

		// set defaults
		argFps.setDefault(10);
		argCropWidth.setDefault(0);
		argCropHeight.setDefault(0);
		argSizeDecimation.setDefault(8);
		argAddress.setDefault("127.0.0.1:19445");
		argPriority.setDefault(800);

		// parse all options
		optionParser.parse(argc, const_cast<const char **>(argv));

		// check if we need to display the usage. exit if we do.
		if (argHelp.isSet())
		{
			optionParser.usage();
			return 0;
		}

		// cropping values if not defined
		if (!argCropLeft.isSet())   argCropLeft.setDefault(argCropWidth.getValue());
		if (!argCropRight.isSet())  argCropRight.setDefault(argCropWidth.getValue());
		if (!argCropTop.isSet())	argCropTop.setDefault(argCropHeight.getValue());
		if (!argCropBottom.isSet()) argCropBottom.setDefault(argCropHeight.getValue());

		// Create the X11 grabbing stuff
		int grabInterval = 1000 / argFps.getValue();
		bool useXGetImage = argXGetImage.isSet();
		X11Wrapper x11Wrapper(
					grabInterval,
					useXGetImage,
					argCropLeft.getValue(),
					argCropRight.getValue(),
					argCropTop.getValue(),
					argCropBottom.getValue(),
					argSizeDecimation.getValue(), // horizontal decimation
					argSizeDecimation.getValue()); // vertical decimation

	if (!x11Wrapper.displayInit())
	  return -1;

		if (argScreenshot.isSet())
		{
			// Capture a single screenshot and finish
			const Image<ColorRgb> & screenshot = x11Wrapper.getScreenshot();
			saveScreenshot("screenshot.png", screenshot);
		}
		else
		{
			// Create the Proto-connection with hyperiond
			ProtoConnectionWrapper protoWrapper(argAddress.getValue(), argPriority.getValue(), 1000, argSkipReply.isSet());

			// Connect the screen capturing to the proto processing
			QObject::connect(&x11Wrapper, SIGNAL(sig_screenshot(const Image<ColorRgb> &)), &protoWrapper, SLOT(receiveImage(Image<ColorRgb>)));

			// Connect the XBMC Video Checker to the proto processing
			QObject::connect(&protoWrapper, SIGNAL(setGrabbingMode(GrabbingMode)), &x11Wrapper, SLOT(setGrabbingMode(GrabbingMode)));
			QObject::connect(&protoWrapper, SIGNAL(setVideoMode(VideoMode)), &x11Wrapper, SLOT(setVideoMode(VideoMode)));

			// Start the capturing
			x11Wrapper.start();

			// Start the application
			app.exec();
		}
	}
	catch (const std::runtime_error & e)
	{
		// An error occured. Display error and quit
		std::cerr << e.what() << std::endl;
		return -1;
	}

	return 0;
}
<commit_msg>rm profiler at x11<commit_after>
// QT includes
#include <QCoreApplication>
#include <QImage>

// getoptPlusPLus includes
#include <getoptPlusPlus/getoptpp.h>

#include "protoserver/ProtoConnectionWrapper.h"
#include "X11Wrapper.h"
#include "HyperionConfig.h"

using namespace vlofgren;

// save the image as screenshot
void saveScreenshot(const char * filename, const Image<ColorRgb> & image)
{
	// store as PNG
	QImage pngImage((const uint8_t *) image.memptr(), image.width(), image.height(), 3*image.width(), QImage::Format_RGB888);
	pngImage.save(filename);
}

int main(int argc, char ** argv)
{
	 std::cout
		<< "hyperion-x11:" << std::endl
		<< "\tversion   : " << HYPERION_VERSION_ID << std::endl
		<< "\tbuild time: " << __DATE__ << " " << __TIME__ << std::endl;

	QCoreApplication app(argc, argv);

	try
	{
		// create the option parser and initialize all parameters
		OptionsParser optionParser("X11 capture application for Hyperion");
		ParameterSet & parameters = optionParser.getParameters();

		IntParameter           & argFps             = parameters.add<IntParameter>          ('f', "framerate",        "Capture frame rate [default: 10]");
		SwitchParameter<>      & argXGetImage       = parameters.add<SwitchParameter<>>     ('x', "xgetimage",        "Use XGetImage instead of XRender");
		IntParameter           & argCropWidth       = parameters.add<IntParameter>          (0x0, "crop-width",       "Number of pixels to crop from the left and right sides of the picture before decimation [default: 0]");
		IntParameter           & argCropHeight      = parameters.add<IntParameter>          (0x0, "crop-height",      "Number of pixels to crop from the top and the bottom of the picture before decimation [default: 0]");
		IntParameter           & argCropLeft        = parameters.add<IntParameter>          (0x0, "crop-left",        "Number of pixels to crop from the left of the picture before decimation (overrides --crop-width)");
		IntParameter           & argCropRight       = parameters.add<IntParameter>          (0x0, "crop-right",       "Number of pixels to crop from the right of the picture before decimation (overrides --crop-width)");
		IntParameter           & argCropTop         = parameters.add<IntParameter>          (0x0, "crop-top",         "Number of pixels to crop from the top of the picture before decimation (overrides --crop-height)");
		IntParameter           & argCropBottom      = parameters.add<IntParameter>          (0x0, "crop-bottom",      "Number of pixels to crop from the bottom of the picture before decimation (overrides --crop-height)");
		IntParameter           & argSizeDecimation  = parameters.add<IntParameter>          ('s', "size-decimator",   "Decimation factor for the output size [default=8]");
		SwitchParameter<>      & argScreenshot      = parameters.add<SwitchParameter<>>     (0x0, "screenshot",       "Take a single screenshot, save it to file and quit");
		StringParameter        & argAddress         = parameters.add<StringParameter>       ('a', "address",          "Set the address of the hyperion server [default: 127.0.0.1:19445]");
		IntParameter           & argPriority        = parameters.add<IntParameter>          ('p', "priority",         "Use the provided priority channel (the lower the number, the higher the priority) [default: 800]");
		SwitchParameter<>      & argSkipReply       = parameters.add<SwitchParameter<>>     (0x0, "skip-reply",       "Do not receive and check reply messages from Hyperion");
		SwitchParameter<>      & argHelp            = parameters.add<SwitchParameter<>>     ('h', "help",             "Show this help message and exit");

		// set defaults
		argFps.setDefault(10);
		argCropWidth.setDefault(0);
		argCropHeight.setDefault(0);
		argSizeDecimation.setDefault(8);
		argAddress.setDefault("127.0.0.1:19445");
		argPriority.setDefault(800);

		// parse all options
		optionParser.parse(argc, const_cast<const char **>(argv));

		// check if we need to display the usage. exit if we do.
		if (argHelp.isSet())
		{
			optionParser.usage();
			return 0;
		}

		// cropping values if not defined
		if (!argCropLeft.isSet())   argCropLeft.setDefault(argCropWidth.getValue());
		if (!argCropRight.isSet())  argCropRight.setDefault(argCropWidth.getValue());
		if (!argCropTop.isSet())	argCropTop.setDefault(argCropHeight.getValue());
		if (!argCropBottom.isSet()) argCropBottom.setDefault(argCropHeight.getValue());

		// Create the X11 grabbing stuff
		int grabInterval = 1000 / argFps.getValue();
		bool useXGetImage = argXGetImage.isSet();
		X11Wrapper x11Wrapper(
					grabInterval,
					useXGetImage,
					argCropLeft.getValue(),
					argCropRight.getValue(),
					argCropTop.getValue(),
					argCropBottom.getValue(),
					argSizeDecimation.getValue(), // horizontal decimation
					argSizeDecimation.getValue()); // vertical decimation

	if (!x11Wrapper.displayInit())
	  return -1;

		if (argScreenshot.isSet())
		{
			// Capture a single screenshot and finish
			const Image<ColorRgb> & screenshot = x11Wrapper.getScreenshot();
			saveScreenshot("screenshot.png", screenshot);
		}
		else
		{
			// Create the Proto-connection with hyperiond
			ProtoConnectionWrapper protoWrapper(argAddress.getValue(), argPriority.getValue(), 1000, argSkipReply.isSet());

			// Connect the screen capturing to the proto processing
			QObject::connect(&x11Wrapper, SIGNAL(sig_screenshot(const Image<ColorRgb> &)), &protoWrapper, SLOT(receiveImage(Image<ColorRgb>)));

			// Connect the XBMC Video Checker to the proto processing
			QObject::connect(&protoWrapper, SIGNAL(setGrabbingMode(GrabbingMode)), &x11Wrapper, SLOT(setGrabbingMode(GrabbingMode)));
			QObject::connect(&protoWrapper, SIGNAL(setVideoMode(VideoMode)), &x11Wrapper, SLOT(setVideoMode(VideoMode)));

			// Start the capturing
			x11Wrapper.start();

			// Start the application
			app.exec();
		}
	}
	catch (const std::runtime_error & e)
	{
		// An error occured. Display error and quit
		std::cerr << e.what() << std::endl;
		return -1;
	}

	return 0;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <vector>
#include <limits>

// Card lookup values
const std::string number_lookup[] = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
const std::string suit_lookup[] = {"D", "C", "H", "S"};
const int face_value[] = { 11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10};

// Test case constants
const int test_case_number[] = {1, 1, 2, 6, 4, 8, 9, 1, 3, 2, 3, 10};
const int test_case_suit[] = {0, 2, 1, 0, 1, 0, 2, 1, 0, 3, 2, 0};
bool test_case = false;
int test_case_int = 0;

class Card {
public:
  int number;
  int suit;

  Card() {
    if (test_case) {
      number = test_case_number[test_case_int];
      suit = test_case_suit[test_case_int];
      test_case_int++;
    }
    else {
      number = (double) rand()/RAND_MAX*13;
      suit = (double) rand()/RAND_MAX*4;
    }
  }

  Card(int n, int s) {
    number = n;
    suit = s;
  }

  std::string getString() {
    std::string s;
    s = number_lookup[number];
    s.append(suit_lookup[suit]);
    return s;
  }

  int getValue() {
    return face_value[number];
  }
};

class Player {
public:
  std::vector<Card> hand;
  int hand_count;

  Player() {
    hand_count = 0;
  }

  int getScore() {
    int score = 0;
    int hasAce = 0;
    for (std::vector<Card>::iterator it = hand.begin() ; it != hand.end(); ++it) {
      if (it->number == 0) {
	hasAce++;
      }
      score += it->getValue();
    }

    while (hasAce && score > 21) {
      hasAce--;
      score -= 10;
    }
    return score;
  }

  std::string getHand(bool ignoreFirst) {
    std::string s = "";
    for (std::vector<Card>::iterator it = hand.begin() ; it != hand.end(); ++it) {
      if (!ignoreFirst) {
	s.append(it->getString());
	s.append(" ");
      }
      ignoreFirst = false;
    }
    return s;
  }

  void drawCard() {
    Card card;
    hand.push_back(card);
    hand_count++;
  }

  bool isSplit() {
    std::vector<Card>::iterator it = hand.begin();
    int i = it->number;
    it++;
    return (i == it->number);
  }
};

class Game {
public:
  int player_bet;
  int player_cash;

  Game() {
    player_cash = 100;
  }

  void newGame() {
    Player player, dealer;
    char ch;

    player_bet = 0; // Reset player bet to known value

    std::cout << "Player: $" << player_cash << "\nRound bet: "; // Get player bet amount and deduct it
    std::cin >> player_bet;

    while (player_cash < player_bet || player_bet == 0) { // Ensure valid bet amount
      std::cin.clear(); // Fix looping error with invalid input
      std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // Clear read buffer
      std::cout << "Invalid bet. Round bet: ";
      std::cin >> player_bet;
    }

    player_cash -= player_bet;

    /*
    std::cout << "Test case? (y/n): ";
    while (true) {
      std::cin >> ch;
      ch = tolower(ch);

      if (ch == 'y') {
	test_case = true;
	break;
      }
      else if (ch == 'n') {
	break;
      }
    }
    */

    player.drawCard(); // Draw cards for player and dealer
    player.drawCard();
    dealer.drawCard();
    dealer.drawCard();

    playRound(player, dealer);
  }

  void playRound(Player player, Player dealer) {
    char ch;

    if (player.getScore() >= 21 || player.hand_count >= 5) { // End game if player gets 21 or over
      endGame(player, dealer);
      return;
    }

    std::cout << "Dealer : * " << dealer.getHand(true) << "\nPlayer : " << player.getHand(false) << "\nDraw? (y/n) ";

    while (true) {
      std::cin >> ch;
      ch = tolower(ch);

      if (ch == 'y') {
	player.drawCard();
	playRound(player, dealer);
	break;
      }
      else if (ch == 'n') {
	endGame(player, dealer);
	break;
      }
    }
  }

  void endGame(Player player, Player dealer) {
    while (dealer.getScore() < 17 && dealer.hand_count < 5) {
      dealer.drawCard();
    }

    std::cout << "Dealer : " << dealer.getHand(false) << "\nPlayer : " << player.getHand(false) // Display hands
	      << "\nDealer: " << dealer.getScore() << "\tPlayer: "  << player.getScore() << "\n"; // Display points

    switch (checkWin(player, dealer)) {
      case 0:
	std::cout << "Dealer wins!\n";
	break;
      case 1:
	std::cout << "Tie game!\n";
	player_cash += player_bet;
	break;
      case 2:
	std::cout << "Player Wins!\n";
	if (player.getScore() == 21) {
	  player_cash += player_bet*2.5;
	}
	else {
	  player_cash += player_bet*2;
	}
	break;
      }
  }

  int checkWin(Player player, Player dealer) { // 0 = loss, 1 = tie, 2 = win
    if (player.getScore() > 21) {
      return 0;
    }
    else if (dealer.getScore() > 21) {
      return 2;
    }
    else if (dealer.getScore() == player.getScore()) {
      return 1;
    }
    else if (dealer.getScore() > player.getScore()) {
      return 0;
    }
    else {
      return 2;
    }
  }
};

int main() {
  Game game;
  char ch;

  srand(time(0));  // initialize random number generator

  game.newGame(); // start new game

  while (true) { // Wait for valid input
    if (game.player_cash <= 0) { // Make sure the player has cash to continue playing
      std::cout << "Sorry, You have no more money left.\n";
      break;
    }
    std::cout << "Again? (y/n): ";
    std::cin >> ch;
    ch = tolower(ch);
    if (ch == 'y') {
      game.newGame(); // Start new game
    }
    else if (ch == 'n') {
      break; // Exit loop
    }
  }
  return 0;
}
<commit_msg>Added splitting code; need to implement split draw<commit_after>#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <vector>
#include <limits>

// Card lookup values
const std::string number_lookup[] = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
const std::string suit_lookup[] = {"D", "C", "H", "S"};
const int face_value[] = { 11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10};

// Test case constants
const int test_case_number[] = {1, 1, 2, 6, 4, 8, 9, 1, 3, 2, 3, 10};
const int test_case_suit[] = {0, 2, 1, 0, 1, 0, 2, 1, 0, 3, 2, 0};
bool test_case = false;
int test_case_int = 0;

class Card {
public:
  int number;
  int suit;

  Card() {
    if (test_case && test_case_int < 12) {
      number = test_case_number[test_case_int];
      suit = test_case_suit[test_case_int];
      test_case_int++;
    }
    else {
      number = (double) rand()/RAND_MAX*13;
      suit = (double) rand()/RAND_MAX*4;
    }
  }

  Card(int n, int s) {
    number = n;
    suit = s;
  }

  std::string getString() {
    std::string s;
    s = number_lookup[number];
    s.append(suit_lookup[suit]);
    return s;
  }

  int getValue() {
    return face_value[number];
  }
};

class Hand {
public:
  std::vector<Card> hand;
  int hand_count;

  Hand() {
    hand_count = 0;
  }

  int getScore() {
    int score = 0;
    int hasAce = 0;
    for (std::vector<Card>::iterator it = hand.begin() ; it != hand.end(); ++it) {
      if (it->number == 0) {
	hasAce++;
      }
      score += it->getValue();
    }

    while (hasAce && score > 21) {
      hasAce--;
      score -= 10;
    }
    return score;
  }

  std::string getHand(bool ignoreFirst) {
    std::string s = "";
    for (std::vector<Card>::iterator it = hand.begin() ; it != hand.end(); ++it) {
      if (!ignoreFirst) {
	s.append(it->getString());
	s.append(" ");
      }
      ignoreFirst = false;
    }
    return s;
  }

  void drawCard() {
    Card card;
    hand.push_back(card);
    hand_count++;
  }

  bool isDoubles() {
    if (hand_count > 0) {
      std::vector<Card>::iterator it = hand.begin();
      int i = it->number;
      it++;
      return (i == it->number);
    }
    else {
      return false;
    }
  }
};

class Player {
public:
  Hand hand;
  Hand split;
  Hand split2;
  Hand split3;
  int splitLevel;

  Player() {
    splitLevel = 0;
  }

  void checkSplit() {
    if (hand.isDoubles() && askSplit()) {
      splitHandler(hand, split);
      splitLevel = 1;
      if (split.isDoubles() && askSplit()) {
	splitHandler(split, split2);
	splitLevel = 2;
	if (split2.isDoubles() && askSplit()) {
	  splitHandler(split2, split3);
	  splitLevel = 3;
	}
      }
    }
  }

  bool askSplit() {
    if (splitLevel < 1) {
      std::cout << "Split? (y/n): ";
    }
    else {
      std::cout << "Split again? (y/n): ";
    }

    char ch;
    while (true) { // Loop input until valid response
      std::cin >> ch;
      ch = tolower(ch);
      if (ch == 'y') {
	return true;
      }
      else if (ch == 'n') {
	return false;
      }
    }
  }

  void splitHandler(Hand& h1, Hand& h2) {
    std::vector<Card>::iterator it = h1.hand.end();
    it--; // Get last card

    Card card (it->number, it-> suit);

    std::cout << card.number << std::endl;
    std::cout << card.suit << std::endl;

    h2.hand.push_back(card); // Push new card to new hand, and delete from old hand
    h1.hand.pop_back();

    h1.drawCard(); // Draw new cards for both split hands
    h2.drawCard();
  }

  void printHand() {
    std::cout << "Player : " << hand.getHand(false) << "\n";
    if (splitLevel >= 1) {
      std::cout << "Split : " << split.getHand(false) << "\n";
    }
    if (splitLevel >= 2) {
      std::cout << "Split 2 : " << split2.getHand(false) << "\n";
    }
    if (splitLevel >= 3) {
      std::cout << "Split 3 : " << split3.getHand(false) << "\n";
    }
  }
};

class Game {
public:
  int player_bet;
  int player_cash;

  Game() {
    player_cash = 100;
  }

  void newGame() {
    Player player;
    Hand dealer;
    char ch;

    player_bet = 0; // Reset player bet to known value

    std::cout << "Player: $" << player_cash << "\nRound bet: "; // Get player bet amount and deduct it
    std::cin >> player_bet;

    while (player_cash < player_bet || player_bet == 0) { // Ensure valid bet amount
      std::cin.clear(); // Fix looping error with invalid input
      std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // Clear read buffer
      std::cout << "Invalid bet. Round bet: ";
      std::cin >> player_bet;
    }

    player_cash -= player_bet;

    std::cout << "Test case? (y/n): ";
    while (true) {
      std::cin >> ch;
      ch = tolower(ch);

      if (ch == 'y') {
	test_case = true;
	break;
      }
      else if (ch == 'n') {
	break;
      }
    }

    player.hand.drawCard(); // Draw cards for player and dealer
    player.hand.drawCard();
    dealer.drawCard();
    dealer.drawCard();

    player.checkSplit();
    playRound(player, dealer);
  }

  void playRound(Player player, Hand dealer) {
    char ch;

    if (player.hand.getScore() >= 21 || player.hand.hand_count >= 5) { // End game if player gets 21 or over
      endGame(player, dealer);
      return;
    }

    std::cout << "Dealer : * " << dealer.getHand(true) << "\n";
    player.printHand();
    std::cout << "Draw? (y/n) ";

    while (true) {
      std::cin >> ch;
      ch = tolower(ch);

      if (ch == 'y') {
	player.hand.drawCard();
	playRound(player, dealer);
	break;
      }
      else if (ch == 'n') {
	endGame(player, dealer);
	break;
      }
    }
  }

  void endGame(Player player, Hand dealer) {

    while (dealer.getScore() < 17 && dealer.hand_count < 5) {
      dealer.drawCard();
    }

    std::cout << "Dealer : " << dealer.getHand(false) << "\nPlayer : " << player.hand.getHand(false) // Display hands
	      << "\nDealer: " << dealer.getScore() << "\tPlayer: "  << player.hand.getScore() << "\n"; // Display points

    switch (checkWin(player.hand, dealer)) {
      case 0:
	std::cout << "Dealer wins!\n";
	break;
      case 1:
	std::cout << "Tie game!\n";
	player_cash += player_bet;
	break;
      case 2:
	std::cout << "Player Wins!\n";
	if (player.hand.getScore() == 21) {
	  player_cash += player_bet*2.5;
	}
	else {
	  player_cash += player_bet*2;
	}
	break;
      }
  }

  int checkWin(Hand player, Hand dealer) { // 0 = loss, 1 = tie, 2 = win
    if (player.getScore() > 21) {
      return 0;
    }
    else if (dealer.getScore() > 21) {
      return 2;
    }
    else if (dealer.getScore() == player.getScore()) {
      return 1;
    }
    else if (dealer.getScore() > player.getScore()) {
      return 0;
    }
    else {
      return 2;
    }
  }
};

int main() {
  Game game;
  char ch;

  srand(time(0));  // initialize random number generator

  game.newGame(); // start new game

  while (true) { // Wait for valid input
    if (game.player_cash <= 0) { // Make sure the player has cash to continue playing
      std::cout << "Sorry, You have no more money left.\n";
      break;
    }
    std::cout << "Again? (y/n): ";
    std::cin >> ch;
    ch = tolower(ch);
    if (ch == 'y') {
      game.newGame(); // Start new game
    }
    else if (ch == 'n') {
      break; // Exit loop
    }
  }
  return 0;
}
<|endoftext|>


<commit_before>//  print.hpp
//  Created by Daniel Illescas Romero on 09/09/2016.

#ifndef print_h
#define print_h

#include <iostream>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <forward_list>

using namespace std;

/* PRINT functions */

template <typename Type>
void print(const Type& value) {
	cout << value << endl;
}

template <typename Type, typename ... Args>
void print(const Type& value, const Args& ...args) {
	cout << value << ' ';
	print(args...);
}

/* TO_STRING functions */

// Stub function (don't use externally) (useful when trying to pass a string to the 'to_string' function, to avoid problems)
string to_string(const string& str) {
	return str;
}

// Convert char to string
string to_string(const char& chr) {
	return string(1,chr);
}

// Return a single or double quoted string IF the data is a string or a char
template <typename Type>
string quotedString(const Type& data) {

	if (typeid(data) == typeid(string)) {
		return ("\"" + to_string(data) + "\"");
	}
	else if (typeid(data) == typeid(char)) {
		return ("\'" + to_string(data) + "\'");
	}
	else {
		return to_string(data);
	}
}

// Return a string given a container (vector, array, list, initializer_list, deque, set, multiset, unordered_set)
template <typename Container>
string to_string(const Container& cont) {

	string str;
	size_t position = 0;

	str += "[";

	for (auto value: cont) {

		str += quotedString(value);

		if (position + 1 < cont.size()) {
			str += ", ";
		}
		position++;
	}

	str += "]";

	return str;
}

// Return a string given a forward list
template <typename Type>
string to_string(const forward_list<Type>& fl) {

	size_t size = distance(fl.begin(), fl.end());
	size_t position = 0;
	string str;

	str += "[";

	for (Type value: fl) {

		str += quotedString(value);

		if (position + 1 < size) {
			str += ", ";
		}
		position++;
	}

	str += "]";

	return str;
}

// Return a string given any map type
template <typename mapType>
string to_stringMAP(const mapType& map) {
	string str;
	size_t position = 0;

	str += "[";

	for (auto value: map) {

		str += quotedString(value.first) + ": " + quotedString(value.second);

		if (position + 1 < map.size()) {
			str += ", ";
		}

		position++;
	}

	str += "]";

	return str;
}

// Return a string given a map
template <typename KeyType, typename ValueType>
string to_string(const map<KeyType,ValueType>& map) {
	return to_stringMAP(map);
}

// Return a string given a multimap
template <typename KeyType, typename ValueType>
string to_string(const multimap<KeyType,ValueType>& map) {
	return to_stringMAP(map);
}

// Return a string given an unordered map
template <typename KeyType, typename ValueType>
string to_string(const unordered_map<KeyType,ValueType>& map) {
	return to_stringMAP(map);
}

// Return a string given an unordered multimap
template <typename KeyType, typename ValueType>
string to_string(const unordered_multimap<KeyType,ValueType>& map) {
	return to_stringMAP(map);
}

// Return a string given a classic array and its size
template <typename Type>
string to_string(const Type * array, size_t size) {

	string str;

	str += "[";

	for (size_t idx = 0; idx < size; idx++) {

		str += quotedString(array[idx]);

		if (idx + 1 < size) {
			str += ", ";
		}
	}

	str += "]";

	return str;
}

// Return a string given a matrix and its size
template <typename Type>
string to_string(const Type& matrix, size_t rows, size_t cols) {

	string str;

	str += "[";

	for (size_t i = 0; i < rows; i++) {
		str += "[";
		for (size_t j = 0; j < cols; j++) {

			str += quotedString(matrix[i][j]);

			if (j + 1 < cols) {
				str += ", ";
			}
		}

		if (i + 1 < rows) {
			str += "], ";
		}
		else {
			str += "]";
		}

	}

	str += "]";

	return str;
}

// Return a string given a queue (creates a copy of the queue)
template <typename Type>
string to_string(queue<Type> queue) {

	string str;
	size_t originalSize = queue.size();

	str += "[";

	for (size_t idx = 0; idx < originalSize; idx++) {

		str += quotedString(queue.front());
		queue.pop();

		if (idx + 1 < originalSize) {
			str += ", ";
		}
	}

	str += "]";

	return str;
}

// Return a string given a priority queue (creates a copy of the queue)
template <typename Type, typename Container, typename Compare>
string to_string(priority_queue<Type,Container,Compare> pqueue) {

	string str;
	size_t originalSize = pqueue.size();

	str += "[";

	for (size_t idx = 0; idx < originalSize; idx++) {

		str += quotedString(pqueue.top());
		pqueue.pop();

		if (idx + 1 < originalSize) {
			str += ", ";
		}
	}

	str += "]";

	return str;
}

// Return a string given a stack (creates a copy of the stack)
template <typename Type>
string to_string(stack<Type> stack) {

	string str;
	size_t originalSize = stack.size();

	str += "[";

	for (size_t idx = 0; idx < originalSize; idx++) {

		str += quotedString(stack.top());
		stack.pop();

		if (idx + 1 < originalSize) {
			str += ", ";
		}
	}

	str += "]";

	return str;
}

#endif /* print_h */
<commit_msg>Changed name from print.h -> print.hpp<commit_after>//  print.hpp
//  Created by Daniel Illescas Romero on 09/09/2016.

#ifndef print_hpp
#define print_hpp

#include <iostream>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <forward_list>

using namespace std;

/* PRINT functions */

template <typename Type>
void print(const Type& value) {
	cout << value << endl;
}

template <typename Type, typename ... Args>
void print(const Type& value, const Args& ...args) {
	cout << value << ' ';
	print(args...);
}

/* TO_STRING functions */

// Stub function (don't use externally) (useful when trying to pass a string to the 'to_string' function, to avoid problems)
string to_string(const string& str) {
	return str;
}

// Convert char to string
string to_string(const char& chr) {
	return string(1,chr);
}

// Return a single or double quoted string IF the data is a string or a char
template <typename Type>
string quotedString(const Type& data) {

	if (typeid(data) == typeid(string)) {
		return ("\"" + to_string(data) + "\"");
	}
	else if (typeid(data) == typeid(char)) {
		return ("\'" + to_string(data) + "\'");
	}
	else {
		return to_string(data);
	}
}

// Return a string given a container (vector, array, list, initializer_list, deque, set, multiset, unordered_set)
template <typename Container>
string to_string(const Container& cont) {

	string str;
	size_t position = 0;

	str += "[";

	for (auto value: cont) {

		str += quotedString(value);

		if (position + 1 < cont.size()) {
			str += ", ";
		}
		position++;
	}

	str += "]";

	return str;
}

// Return a string given a forward list
template <typename Type>
string to_string(const forward_list<Type>& fl) {

	size_t size = distance(fl.begin(), fl.end());
	size_t position = 0;
	string str;

	str += "[";

	for (Type value: fl) {

		str += quotedString(value);

		if (position + 1 < size) {
			str += ", ";
		}
		position++;
	}

	str += "]";

	return str;
}

// Return a string given any map type
template <typename mapType>
string to_stringMAP(const mapType& map) {
	string str;
	size_t position = 0;

	str += "[";

	for (auto value: map) {

		str += quotedString(value.first) + ": " + quotedString(value.second);

		if (position + 1 < map.size()) {
			str += ", ";
		}

		position++;
	}

	str += "]";

	return str;
}

// Return a string given a map
template <typename KeyType, typename ValueType>
string to_string(const map<KeyType,ValueType>& map) {
	return to_stringMAP(map);
}

// Return a string given a multimap
template <typename KeyType, typename ValueType>
string to_string(const multimap<KeyType,ValueType>& map) {
	return to_stringMAP(map);
}

// Return a string given an unordered map
template <typename KeyType, typename ValueType>
string to_string(const unordered_map<KeyType,ValueType>& map) {
	return to_stringMAP(map);
}

// Return a string given an unordered multimap
template <typename KeyType, typename ValueType>
string to_string(const unordered_multimap<KeyType,ValueType>& map) {
	return to_stringMAP(map);
}

// Return a string given a classic array and its size
template <typename Type>
string to_string(const Type * array, size_t size) {

	string str;

	str += "[";

	for (size_t idx = 0; idx < size; idx++) {

		str += quotedString(array[idx]);

		if (idx + 1 < size) {
			str += ", ";
		}
	}

	str += "]";

	return str;
}

// Return a string given a matrix and its size
template <typename Type>
string to_string(const Type& matrix, size_t rows, size_t cols) {

	string str;

	str += "[";

	for (size_t i = 0; i < rows; i++) {
		str += "[";
		for (size_t j = 0; j < cols; j++) {

			str += quotedString(matrix[i][j]);

			if (j + 1 < cols) {
				str += ", ";
			}
		}

		if (i + 1 < rows) {
			str += "], ";
		}
		else {
			str += "]";
		}

	}

	str += "]";

	return str;
}

// Return a string given a queue (creates a copy of the queue)
template <typename Type>
string to_string(queue<Type> queue) {

	string str;
	size_t originalSize = queue.size();

	str += "[";

	for (size_t idx = 0; idx < originalSize; idx++) {

		str += quotedString(queue.front());
		queue.pop();

		if (idx + 1 < originalSize) {
			str += ", ";
		}
	}

	str += "]";

	return str;
}

// Return a string given a priority queue (creates a copy of the queue)
template <typename Type, typename Container, typename Compare>
string to_string(priority_queue<Type,Container,Compare> pqueue) {

	string str;
	size_t originalSize = pqueue.size();

	str += "[";

	for (size_t idx = 0; idx < originalSize; idx++) {

		str += quotedString(pqueue.top());
		pqueue.pop();

		if (idx + 1 < originalSize) {
			str += ", ";
		}
	}

	str += "]";

	return str;
}

// Return a string given a stack (creates a copy of the stack)
template <typename Type>
string to_string(stack<Type> stack) {

	string str;
	size_t originalSize = stack.size();

	str += "[";

	for (size_t idx = 0; idx < originalSize; idx++) {

		str += quotedString(stack.top());
		stack.pop();

		if (idx + 1 < originalSize) {
			str += ", ";
		}
	}

	str += "]";

	return str;
}

#endif /* print_hpp */
<|endoftext|>