tags:

views:

406

answers:

2

I'm writing a small wrapper around libxml2 in C++, and I'm trying to work out how to handle errors. For now, let's say I just want to print them out. Here's what I've got at present:

My error handling function:

void foo(void *ctx, const char *msg, ...) {
  cout << msg << endl;
  return;
}

Initialised like this:

xmlGenericErrorFunc handler = (xmlGenericErrorFunc)foo;
initGenericErrorDefaultFunc(&handler);

However, if I parse a bad XPath, I get this output:

%s

Without the error handling code, I get this:

XPath error : Invalid expression
//.@foobar
    ^

Obviously eventually my error handling will do more than just print out the error message (it'll log it to a database or something), but for now - how can I get that error string?

+1  A: 

The three dots at the end of the argument list for you function foo() means it takes a variable amount of arguments. To be able to print those you could do something like this (not tested):

#include <stdarg.h>

#define TMP_BUF_SIZE 256
void foo(void *ctx, const char *msg, ...) {
   char string[TMP_BUF_SIZE];
   va_list arg_ptr;

   va_start(arg_ptr, msg);
   vsnprintf(string, TMP_BUF_SIZE, msg, arg_ptr);
   va_end(arg_ptr);
   cout << string << endl;
   return;
}
Puppe
That's nearly there - it gets me "Invalid expression", but not the rest.
Dominic Rodger
That's probably all the message contains, you said you got %s when you only printed msg, that indicates that there is only one more argument given to foo() and that's a string to be printed. Maybe the information here can help you? http://xmlsoft.org/html/libxml-xmlerror.html#xmlGenericErrorFunc
Puppe
@Puppe - that makes sense. Sadly the documentation isn't all that forthcoming about what gets passed in to the `xmlGenericErrorFunc`. What you've got is good enough for my purposes though. Thanks!
Dominic Rodger
A: 

As already pointed out if this is your handling function:

#define TMP_BUF_SIZE 256
void err(void *ctx, const char *msg, ...) {
   char string[TMP_BUF_SIZE];
   va_list arg_ptr;
   va_start(arg_ptr, msg);
   vsnprintf(string, TMP_BUF_SIZE, msg, arg_ptr);
   va_end(arg_ptr);
   cout << string << endl;
   return;
}

you can set it with this libxml2 function

xmlSetGenericErrorFunc(NULL,gemXmlGenericErrorFunc);

if you have a context to pass, i.e. some struct,data,class whatever pointer casted to void*, you can put it as first argument.

Note that foo will be called a lot, for instance if you have a parse error each time libxml adds a line to the error message.

Trismegisto