diff --git a/include/mapnik/xml_node.hpp b/include/mapnik/xml_node.hpp index 6121cbd33..ab352ce6d 100644 --- a/include/mapnik/xml_node.hpp +++ b/include/mapnik/xml_node.hpp @@ -100,6 +100,7 @@ public: void set_processed(bool processed) const; unsigned line() const; + std::string line_to_string() const; const_iterator begin() const; const_iterator end() const; diff --git a/src/config_error.cpp b/src/config_error.cpp index 83943998b..c8889b149 100644 --- a/src/config_error.cpp +++ b/src/config_error.cpp @@ -1,5 +1,6 @@ #include #include +#include namespace mapnik { @@ -38,12 +39,23 @@ config_error::config_error(std::string const& what, char const* config_error::what() const throw() { - std::stringstream s; - s << what_; - if (!node_name_.empty()) s << " in " << node_name_; - if (line_number_ > 0) s << " at line " << line_number_; - if (!file_.empty()) s << " of '" << file_ << "'"; - msg_ = s.str(); //Avoid returning pointer to dead object + msg_ = what_; + if (!node_name_.empty()) + { + msg_ += " in " + node_name_; + } + if (line_number_ > 0) + { + std::string number; + if (util::to_string(number,line_number_)) + { + msg_ += " at line " + number; + } + } + if (!file_.empty()) + { + msg_ += " of '" + file_ + "'"; + } return msg_.c_str(); } diff --git a/src/libxml2_loader.cpp b/src/libxml2_loader.cpp index 64fdaf511..e0f034a98 100644 --- a/src/libxml2_loader.cpp +++ b/src/libxml2_loader.cpp @@ -39,9 +39,6 @@ #include #include -// stl -#include - using namespace std; #define DEFAULT_OPTIONS (XML_PARSE_NOERROR | XML_PARSE_NOENT | XML_PARSE_NOBLANKS | XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA) @@ -88,11 +85,10 @@ public: xmlError * error = xmlCtxtGetLastError(ctx_); if (error) { - std::ostringstream os; - os << "XML document not well formed"; - os << ": " << std::endl << error->message; + std::string msg("XML document not well formed:\n"); + msg += error->message; // remove CR - std::string msg = os.str().substr(0, os.str().size() - 1); + msg = msg.substr(0, msg.size() - 1); throw config_error(msg, error->line, error->file); } } @@ -132,18 +128,18 @@ public: { if (!doc) { + std::string msg("XML document not well formed"); xmlError * error = xmlCtxtGetLastError( ctx_ ); - std::ostringstream os; - os << "XML document not well formed"; - int line=0; - std::string file; if (error) { - os << ": " << std::endl << error->message; - line = error->line; - file = error->file; + msg += ":\n"; + msg += error->message; + throw config_error(msg, error->line, error->file); + } + else + { + throw config_error(msg); } - throw config_error(os.str(), line, file); } int iXIncludeReturn = xmlXIncludeProcessFlags(doc, options_); diff --git a/src/load_map.cpp b/src/load_map.cpp index ef58168ff..89aa84d39 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -63,10 +63,6 @@ // agg #include "agg_trans_affine.h" -// stl -#include -#include - using boost::tokenizer; using std::endl; @@ -113,7 +109,7 @@ private: void ensure_font_face(std::string const& face_name); void find_unused_nodes(xml_node const& root); - void find_unused_nodes_recursive(xml_node const& node, std::stringstream &error_text); + void find_unused_nodes_recursive(xml_node const& node, std::string & error_text); std::string ensure_relative_to_xml(boost::optional opt_path); @@ -222,15 +218,15 @@ void map_parser::parse_map(Map & map, xml_node const& pt, std::string const& bas } else { - std::ostringstream s_err; - s_err << "failed to parse Map maximum-extent '" << *maximum_extent << "'"; + std::string s_err("failed to parse Map maximum-extent '"); + s_err += *maximum_extent + "'"; if (strict_) { - throw config_error(s_err.str()); + throw config_error(s_err); } else { - MAPNIK_LOG_ERROR(load_map) << "map_parser: " << s_err.str(); + MAPNIK_LOG_ERROR(load_map) << "map_parser: " << s_err; } } } @@ -622,15 +618,15 @@ void map_parser::parse_layer(Map & map, xml_node const& node) } else { - std::ostringstream s_err; - s_err << "failed to parse Layer maximum-extent '" << *maximum_extent << "' for '" << name << "'"; + std::string s_err("failed to parse Layer maximum-extent '"); + s_err += *maximum_extent + "' for '" + name + "'"; if (strict_) { - throw config_error(s_err.str()); + throw config_error(s_err); } else { - MAPNIK_LOG_ERROR(load_map) << "map_parser: " << s_err.str(); + MAPNIK_LOG_ERROR(load_map) << "map_parser: " << s_err; } } } @@ -646,15 +642,15 @@ void map_parser::parse_layer(Map & map, xml_node const& node) std::string style_name = child->get_text(); if (style_name.empty()) { - std::ostringstream ss; - ss << "StyleName is empty in Layer: '" << lyr.name() << "'"; + std::string ss("StyleName is empty in Layer: '"); + ss += lyr.name() + "'"; if (strict_) { - throw config_error(ss.str()); + throw config_error(ss); } else { - MAPNIK_LOG_WARN(load_map) << "map_parser: " << ss.str(); + MAPNIK_LOG_WARN(load_map) << "map_parser: " << ss; } } else @@ -854,10 +850,9 @@ void map_parser::parse_symbolizer_base(symbolizer_base &sym, xml_node const &pt) mapnik::transform_list_ptr tl = boost::make_shared(); if (!mapnik::parse_transform(*tl, *geometry_transform_wkt, pt.get_tree().transform_expr_grammar)) { - std::stringstream ss; - ss << "Could not parse transform from '" << *geometry_transform_wkt - << "', expected transform attribute"; - throw config_error(ss.str()); + std::string ss("Could not parse transform from '"); + ss += *geometry_transform_wkt + "', expected transform attribute"; + throw config_error(ss); } sym.set_transform(tl); } @@ -1674,11 +1669,11 @@ void map_parser::ensure_exists(std::string const& file_path) void map_parser::find_unused_nodes(xml_node const& root) { - std::stringstream error_message; + std::string error_message; find_unused_nodes_recursive(root, error_message); - if (!error_message.str().empty()) + if (!error_message.empty()) { - std::string msg("Unable to process some data while parsing '" + filename_ + "':" + error_message.str()); + std::string msg("Unable to process some data while parsing '" + filename_ + "':" + error_message); if (strict_) { throw config_error(msg); @@ -1690,14 +1685,14 @@ void map_parser::find_unused_nodes(xml_node const& root) } } -void map_parser::find_unused_nodes_recursive(xml_node const& node, std::stringstream &error_message) +void map_parser::find_unused_nodes_recursive(xml_node const& node, std::string & error_message) { if (!node.processed()) { if (node.is_text()) { - error_message << "\n* text '" << node.text() << "'"; + error_message += "\n* text '" + node.text() + "'"; } else { - error_message << "\n* node '" << node.name() << "' at line " << node.line(); + error_message += "\n* node '" + node.name() + "' at line " + node.line_to_string(); } return; //All attributes and children are automatically unprocessed, too. } @@ -1708,9 +1703,9 @@ void map_parser::find_unused_nodes_recursive(xml_node const& node, std::stringst { if (!aitr->second.processed) { - error_message << "\n* attribute '" << aitr->first << - "' with value '" << aitr->second.value << - "' at line " << node.line(); + error_message += "\n* attribute '" + aitr->first + + "' with value '" + aitr->second.value + + "' at line " + node.line_to_string(); } } xml_node::const_iterator itr = node.begin(); diff --git a/src/xml_tree.cpp b/src/xml_tree.cpp index ed1b9bc08..fa6cf2945 100644 --- a/src/xml_tree.cpp +++ b/src/xml_tree.cpp @@ -448,6 +448,14 @@ unsigned xml_node::line() const return line_; } +std::string xml_node::line_to_string() const +{ + std::string number; + util::to_string(number,line_); + return number; +} + + #define compile_get_opt_attr(T) template boost::optional xml_node::get_opt_attr(std::string const&) const #define compile_get_attr(T) template T xml_node::get_attr(std::string const&) const; template T xml_node::get_attr(std::string const&, T const&) const #define compile_get_value(T) template T xml_node::get_value() const