1

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?

2 Answers 2

8

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;
}
Sign up to request clarification or add additional context in comments.

3 Comments

That's nearly there - it gets me "Invalid expression", but not the rest.
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? xmlsoft.org/html/libxml-xmlerror.html#xmlGenericErrorFunc
@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!
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.