use error_handler across json parsers

This commit is contained in:
artemp 2014-09-23 14:58:10 +01:00
parent 1382e57ebe
commit 2f319e92cc
11 changed files with 42 additions and 90 deletions

View file

@ -24,20 +24,20 @@
#define MAPNIK_JSON_ERROR_HANDLER_HPP
#include <string>
#include <mapnik/debug.hpp>
#include <boost/spirit/home/support/info.hpp>
namespace mapnik { namespace json {
struct where_message
template <typename Iterator>
struct error_handler
{
using result_type = std::string;
template <typename Iterator>
std::string operator() (Iterator first, Iterator last, std::size_t size) const
using result_type = void;
void operator() (
Iterator first, Iterator last,
Iterator err_pos, boost::spirit::info const& what) const
{
std::string str(first, last);
if (str.length() > size)
return str.substr(0, size) + "..." ;
return str;
MAPNIK_LOG_ERROR(error_handler) << what << " expected but got: " << std::string(err_pos, std::min(err_pos + 16,last));
}
};

View file

@ -22,6 +22,7 @@
// mapnik
#include <mapnik/json/error_handler.hpp>
#include <mapnik/json/feature_collection_grammar.hpp>
// spirit::qi

View file

@ -31,7 +31,6 @@
#include <mapnik/value.hpp>
#include <mapnik/json/generic_json.hpp>
#include <mapnik/json/value_converters.hpp>
#include <mapnik/debug.hpp>
// spirit::qi
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
@ -89,18 +88,6 @@ struct extract_geometry
}
};
template <typename Iterator>
struct error_handler
{
using result_type = void;
void operator() (
Iterator first, Iterator last,
Iterator err_pos, boost::spirit::info const& what) const
{
MAPNIK_LOG_ERROR(error_handler) << what << " expected but got: " << std::string(err_pos, std::min(err_pos + 16,last));
}
};
template <typename Iterator, typename FeatureType, typename ErrorHandler = error_handler<Iterator> >
struct feature_grammar :
qi::grammar<Iterator, void(FeatureType&),

View file

@ -30,8 +30,7 @@ template <typename Iterator, typename FeatureType, typename ErrorHandler>
feature_grammar<Iterator,FeatureType,ErrorHandler>::feature_grammar(mapnik::transcoder const& tr)
: feature_grammar::base_type(feature,"feature"),
json_(),
put_property_(put_property(tr)),
error_handler(ErrorHandler())
put_property_(put_property(tr))
{
qi::lit_type lit;
qi::long_long_type long_long;

View file

@ -29,7 +29,7 @@
#include <mapnik/make_unique.hpp>
#include <mapnik/json/positions_grammar.hpp>
#include <mapnik/json/geometry_util.hpp>
#include <mapnik/json/error_handler.hpp>
// spirit::qi
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
@ -40,7 +40,7 @@ namespace qi = boost::spirit::qi;
namespace standard_wide = boost::spirit::standard_wide;
using standard_wide::space_type;
template <typename Iterator>
template <typename Iterator, typename ErrorHandler = error_handler<Iterator> >
struct geometry_grammar :
qi::grammar<Iterator,void(mapnik::geometry_container& )
, space_type>
@ -51,8 +51,9 @@ struct geometry_grammar :
qi::symbols<char, int> geometry_type_dispatch;
qi::rule<Iterator,void(mapnik::geometry_container& ),space_type> geometry_collection;
positions_grammar<Iterator> coordinates;
boost::phoenix::function<where_message> where_message_;
boost::phoenix::function<create_geometry_impl> create_geometry;
// error handler
boost::phoenix::function<ErrorHandler> const error_handler;
};
}}

View file

@ -21,6 +21,7 @@
*****************************************************************************/
// mapnik
#include <mapnik/json/error_handler.hpp>
#include <mapnik/json/geometry_grammar.hpp>
#include <mapnik/json/positions_grammar_impl.hpp>
@ -33,8 +34,8 @@
namespace mapnik { namespace json {
template <typename Iterator>
geometry_grammar<Iterator>::geometry_grammar()
template <typename Iterator, typename ErrorHandler >
geometry_grammar<Iterator, ErrorHandler>::geometry_grammar()
: geometry_grammar::base_type(start,"geometry")
{
@ -83,20 +84,10 @@ geometry_grammar<Iterator>::geometry_grammar()
// give some rules names
geometry.name("Geometry");
geometry_collection.name("GeometryCollection");
geometry_type_dispatch.name("Geometry dispatch");
geometry_type_dispatch.name("Geometry type");
coordinates.name("Coordinates");
// error handler
on_error<fail>
(
start
, std::clog
<< boost::phoenix::val("Error! Expecting ")
<< _4 // what failed?
<< boost::phoenix::val(" here: \"")
<< where_message_(_3, _2, 16) // max 16 chars
<< boost::phoenix::val("\"")
<< std::endl
);
on_error<fail>(start, error_handler(_1, _2, _3, _4));
}
}}

View file

@ -62,7 +62,7 @@ struct push_position_impl
}
};
template <typename Iterator>
template <typename Iterator, typename ErrorHandler = error_handler<Iterator> >
struct positions_grammar :
qi::grammar<Iterator,coordinates(),space_type>
{
@ -74,7 +74,8 @@ struct positions_grammar :
qi::rule<Iterator, std::vector<std::vector<positions> >(), space_type> rings_array;
boost::phoenix::function<set_position_impl> set_position;
boost::phoenix::function<push_position_impl> push_position;
boost::phoenix::function<where_message> message;
// error handler
boost::phoenix::function<ErrorHandler> const error_handler;
};
}}

View file

@ -34,8 +34,8 @@
namespace mapnik { namespace json {
template <typename Iterator>
positions_grammar<Iterator>::positions_grammar()
template <typename Iterator, typename ErrorHandler>
positions_grammar<Iterator, ErrorHandler>::positions_grammar()
: positions_grammar::base_type(coords,"coordinates")
{
qi::lit_type lit;
@ -60,18 +60,13 @@ positions_grammar<Iterator>::positions_grammar()
rings_array = lit('[') >> rings % lit(',') >> lit(']')
;
coords.name("Coordinates");
pos.name("Position");
ring.name("Ring");
rings.name("Rings");
rings_array.name("Rings array");
// error handler
on_error<fail>
(
coords,
std::clog
<< boost::phoenix::val("Error! Expecting ")
<< _4 // what failed?
<< boost::phoenix::val(" here: \"")
<< message(_3, _2, 16) // max 16 chars
<< boost::phoenix::val("\"")
<< std::endl
);
on_error<fail>(coords, error_handler(_1, _2, _3, _4));
}
}}

View file

@ -31,6 +31,7 @@
#include <mapnik/util/variant.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/symbolizer_utils.hpp>
#include <mapnik/json/error_handler.hpp>
#include <mapnik/json/generic_json.hpp>
namespace mapnik { namespace json {
@ -113,7 +114,7 @@ struct put_property
}
};
template <typename Iterator>
template <typename Iterator, typename ErrorHandler = error_handler<Iterator>>
struct symbolizer_grammar : qi::grammar<Iterator, space_type, symbolizer()>
{
using json_value_type = util::variant<value_null,value_bool,value_integer,value_double, std::string>;
@ -210,7 +211,7 @@ struct symbolizer_grammar : qi::grammar<Iterator, space_type, symbolizer()>
phoenix::function<put_property> put_property_;
// error
//boost::phoenix::function<where_message> where_message_;
on_error<fail>(sym, error_handler(_1, _2, _3, _4));
};

View file

@ -25,6 +25,7 @@
// mapnik
#include <mapnik/value.hpp>
#include <mapnik/json/error_handler.hpp>
#include <mapnik/json/generic_json.hpp>
#include <mapnik/json/topology.hpp>
#include <mapnik/json/value_converters.hpp>
@ -44,21 +45,7 @@ namespace fusion = boost::fusion;
namespace standard_wide = boost::spirit::standard_wide;
using standard_wide::space_type;
struct where_message
{
using result_type = std::string;
template <typename Iterator>
std::string operator() (Iterator first, Iterator last, std::size_t size) const
{
std::string str(first, last);
if (str.length() > size)
return str.substr(0, size) + "..." ;
return str;
}
};
template <typename Iterator>
template <typename Iterator, typename ErrorHandler = json::error_handler<Iterator> >
struct topojson_grammar : qi::grammar<Iterator, space_type, topology()>
{
@ -91,8 +78,8 @@ private:
qi::rule<Iterator, space_type, mapnik::json::json_value()> attribute_value;
// id
qi::rule<Iterator,space_type> id;
// error
boost::phoenix::function<where_message> where_message_;
// error handler
boost::phoenix::function<ErrorHandler> const error_handler;
};
}}

View file

@ -30,8 +30,8 @@ namespace fusion = boost::fusion;
namespace standard_wide = boost::spirit::standard_wide;
using standard_wide::space_type;
template <typename Iterator>
topojson_grammar<Iterator>::topojson_grammar()
template <typename Iterator, typename ErrorHandler>
topojson_grammar<Iterator, ErrorHandler>::topojson_grammar()
: topojson_grammar::base_type(topology, "topojson")
{
qi::lit_type lit;
@ -220,19 +220,8 @@ topojson_grammar<Iterator>::topojson_grammar()
polygon.name("polygon");
multi_polygon.name("multi_polygon");
geometry_collection.name("geometry_collection");
on_error<fail>
(
topology
, std::clog
<< phoenix::val("Error! Expecting ")
<< _4 // what failed?
<< phoenix::val(" here: \"")
<< where_message_(_3, _2, 16) // where? 16 is max chars to output
<< phoenix::val("\"")
<< std::endl
);
// error handler
on_error<fail>(topology, error_handler(_1, _2, _3, _4));
}
}}