[libxml++] Add xmlpp::format_printf_message()



commit 5abab30c22d21130380a9c233d25418698044f4d
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Thu Oct 8 08:53:12 2015 +0200

    Add xmlpp::format_printf_message()
    
    * libxml++/exceptions/exception.[h|cc]: Add format_printf_message().
    * libxml++/parsers/parser.cc:
    * libxml++/parsers/saxparser.cc:
    * libxml++/validators/validator.cc: Call format_printf_message().

 libxml++/exceptions/exception.cc |   20 ++++++++++++++++++++
 libxml++/exceptions/exception.h  |   26 ++++++++++++++++++++++++--
 libxml++/parsers/parser.cc       |    5 +----
 libxml++/parsers/saxparser.cc    |   20 +++++++-------------
 libxml++/validators/validator.cc |   14 +++++---------
 5 files changed, 57 insertions(+), 28 deletions(-)
---
diff --git a/libxml++/exceptions/exception.cc b/libxml++/exceptions/exception.cc
index 3805779..6042c37 100644
--- a/libxml++/exceptions/exception.cc
+++ b/libxml++/exceptions/exception.cc
@@ -1,6 +1,8 @@
 #include "exception.h"
 #include <libxml/xmlerror.h>
 #include <libxml/parser.h>
+#include <cstdio>
+#include <vector>
 
 namespace xmlpp {
   
@@ -92,4 +94,22 @@ Glib::ustring format_xml_parser_error(const _xmlParserCtxt* parser_context)
   return str + format_xml_error(error);
 }
 
+Glib::ustring format_printf_message(const char* fmt, va_list args)
+{
+  // This code was inspired by the example at
+  // http://en.cppreference.com/w/cpp/io/c/vfprintf
+  va_list args2;
+  va_copy(args2, args);
+  // Number of characters (bytes) in the resulting string;
+  // error, if < 0.
+  const int nchar = std::vsnprintf(nullptr, 0, fmt, args2);
+  va_end(args2);
+  if (nchar < 0)
+   return Glib::ustring::format("Error code from std::vsnprintf = ", nchar);
+
+  std::vector<char> buf(nchar+1);
+  std::vsnprintf(buf.data(), buf.size(), fmt, args);
+  return Glib::ustring(buf.data());
+}
+
 } //namespace xmlpp
diff --git a/libxml++/exceptions/exception.h b/libxml++/exceptions/exception.h
index 4510075..cb02717 100644
--- a/libxml++/exceptions/exception.h
+++ b/libxml++/exceptions/exception.h
@@ -21,6 +21,7 @@
 #define __LIBXMLPP_EXCEPTION_H
 
 #include <exception>
+#include <cstdarg> // va_list
 #include <glibmm/ustring.h>
 
 #include <libxml++config.h>
@@ -51,8 +52,8 @@ private:
  *
  * @newin{2,36}
  *
- * @param error Pointer to an _xmlError struct or <tt>0</tt>. If <tt>0</tt>,
- *              the error returned by xmlGetLastError() is used.
+ * @param error Pointer to an _xmlError struct or <tt>nullptr</tt>.
+ *              If <tt>nullptr</tt>, the error returned by xmlGetLastError() is used.
  * @returns A formatted text string. If the error struct does not contain an
  *          error (error->code == XML_ERR_OK), an empty string is returned.
  */
@@ -69,6 +70,27 @@ Glib::ustring format_xml_error(const _xmlError* error = nullptr);
  */
 Glib::ustring format_xml_parser_error(const _xmlParserCtxt* parser_context);
 
+/** Format a message from a function with C-style variadic parameters.
+ *
+ * Helper function that formats a message supplied in the form of a printf-style
+ * format specification and zero or more ... parameters.
+ *
+ * @code
+ * // Typical call:
+ * void f(const char* fmt, ...)
+ * {
+ *   va_list args;
+ *   va_start(args, fmt);
+ *   Glib::ustring msg = xmlpp::format_printf_message(fmt, args);
+ *   va_end(args);
+ *   // ...
+ * }
+ * @endcode
+ *
+ * @newin{3,0}
+ */
+Glib::ustring format_printf_message(const char* fmt, va_list args);
+
 } // namespace xmlpp
 
 #endif // __LIBXMLPP_EXCEPTION_H
diff --git a/libxml++/parsers/parser.cc b/libxml++/parsers/parser.cc
index e45a905..019ffc1 100644
--- a/libxml++/parsers/parser.cc
+++ b/libxml++/parsers/parser.cc
@@ -308,10 +308,7 @@ void Parser::callback_error_or_warning(MsgType msg_type, void* ctx,
         // returns an error message (as it usually does).
 
         //Convert the ... to a string:
-        char buff[1024];
-
-        vsnprintf(buff, sizeof(buff)/sizeof(buff[0]), msg, var_args);
-        ubuff = buff;
+        ubuff = format_printf_message(msg, var_args);
       }
 
       try
diff --git a/libxml++/parsers/saxparser.cc b/libxml++/parsers/saxparser.cc
index bb41549..8a83bf6 100644
--- a/libxml++/parsers/saxparser.cc
+++ b/libxml++/parsers/saxparser.cc
@@ -523,15 +523,13 @@ void SaxParserCallback::warning(void* context, const char* fmt, ...)
   auto parser = static_cast<SaxParser*>(the_context->_private);
 
   va_list arg;
-  char buff[1024]; //TODO: Larger/Shared
-
   va_start(arg, fmt);
-  vsnprintf(buff, sizeof(buff)/sizeof(buff[0]), fmt, arg);
+  const Glib::ustring buff = format_printf_message(fmt, arg);
   va_end(arg);
 
   try
   {
-    parser->on_warning(Glib::ustring(buff));
+    parser->on_warning(buff);
   }
   catch (...)
   {
@@ -544,19 +542,17 @@ void SaxParserCallback::error(void* context, const char* fmt, ...)
   auto the_context = static_cast<_xmlParserCtxt*>(context);
   auto parser = static_cast<SaxParser*>(the_context->_private);
 
-  va_list arg;
-  char buff[1024]; //TODO: Larger/Shared
-
   if (parser->exception_ptr_)
     return;
 
+  va_list arg;
   va_start(arg, fmt);
-  vsnprintf(buff, sizeof(buff)/sizeof(buff[0]), fmt, arg);
+  const Glib::ustring buff = format_printf_message(fmt, arg);
   va_end(arg);
 
   try
   {
-    parser->on_error(Glib::ustring(buff));
+    parser->on_error(buff);
   }
   catch (...)
   {
@@ -570,15 +566,13 @@ void SaxParserCallback::fatal_error(void* context, const char* fmt, ...)
   auto parser = static_cast<SaxParser*>(the_context->_private);
 
   va_list arg;
-  char buff[1024]; //TODO: Larger/Shared
-
   va_start(arg, fmt);
-  vsnprintf(buff, sizeof(buff)/sizeof(buff[0]), fmt, arg);
+  const Glib::ustring buff = format_printf_message(fmt, arg);
   va_end(arg);
 
   try
   {
-    parser->on_fatal_error(Glib::ustring(buff));
+    parser->on_fatal_error(buff);
   }
   catch (...)
   {
diff --git a/libxml++/validators/validator.cc b/libxml++/validators/validator.cc
index cd5d42d..4858cee 100644
--- a/libxml++/validators/validator.cc
+++ b/libxml++/validators/validator.cc
@@ -1,4 +1,4 @@
-/* xml++.cc
+/* validator.cc
  * libxml++ and this file are copyright (C) 2000 by Ari Johnson
  * (C) 2002-2004 by the libxml dev team and
  * are covered by the GNU Lesser General Public License, which should be
@@ -98,15 +98,13 @@ void Validator::callback_validity_error(void* valid_, const char* msg, ...)
   {
     //Convert the ... to a string:
     va_list arg;
-    char buff[1024]; //TODO: Larger/Shared
-
     va_start(arg, msg);
-    vsnprintf(buff, sizeof(buff)/sizeof(buff[0]), msg, arg);
+    const Glib::ustring buff = format_printf_message(msg, arg);
     va_end(arg);
 
     try
     {
-      validator->on_validity_error(Glib::ustring(buff));
+      validator->on_validity_error(buff);
     }
     catch (...)
     {
@@ -123,15 +121,13 @@ void Validator::callback_validity_warning(void* valid_, const char* msg, ...)
   {
     //Convert the ... to a string:
     va_list arg;
-    char buff[1024]; //TODO: Larger/Shared
-
     va_start(arg, msg);
-    vsnprintf(buff, sizeof(buff)/sizeof(buff[0]), msg, arg);
+    const Glib::ustring buff = format_printf_message(msg, arg);
     va_end(arg);
 
     try
     {
-      validator->on_validity_warning(Glib::ustring(buff));
+      validator->on_validity_warning(buff);
     }
     catch (...)
     {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]