#include <cstdarg>
#include <cstdio>
#include <cstring>
#include <libxml/parser.h>
#include <libxml/HTMLparser.h>

class Test
{
	private:
		htmlParserCtxtPtr m_xml;
		static htmlSAXHandler m_sax;

		static void init();
	public:
		Test(const char *txt, size_t l);
		void parse(const char *chunk, size_t s);


		static void start(void *, const xmlChar *, const xmlChar **);
		static void end(void *, const xmlChar *);
		static void warning(void *p, const char *msg, ...);
};


 htmlSAXHandler Test::m_sax;

void Test::init()
{
	if (m_sax.initialized==1)
		return;
	
	m_sax.startElement=start;
	m_sax.endElement=end;
	m_sax.initialized=1;
	m_sax.warning=warning;
	m_sax.error=warning;
	m_sax.fatalError=warning;
}

void Test::warning(void *p, const char *msg, ...)
{
	va_list ap;
	va_start(ap, msg);
	vprintf(msg, ap);
	va_end(ap);
}


Test::Test(const char *txt, size_t split)
{
	init();
	m_xml=htmlCreatePushParserCtxt(&m_sax, this,
		txt, 4, "x", XML_CHAR_ENCODING_UTF8);

	parse(&txt[4], split-4);
	parse(&txt[split], strlen(&txt[split]));
}

void Test::parse(const char *chunk, size_t len)
{
	if (chunk!=NULL)
	{
		char *txt=strndup(chunk, len);
		printf("Parsing: [%s]\n", txt);
		free(txt);
		htmlParseChunk(m_xml, chunk, len, 0);
	}
	else
		htmlParseChunk(m_xml, NULL,  0,	1);
}

void Test::start(void *p, const xmlChar *name, const xmlChar **atts)
{
	printf("<%s", name);
	while (atts!=NULL && *atts!=NULL)
	{
		printf(" %s='%s'", atts[0], atts[1]);
		atts+=2;
	}
	printf(">\n");
}

void Test::end(void *p, const xmlChar *name)
{
	printf("</%s>\n", name);
}


int main(int argc, char *argv)
{
	const char *txt=
		"<HTML><BODY><IMG ALT='Hum>Bug'/></BODY></HTML>";

	// get m;
	size_t i=0;
	for (;txt[i]!='m';i++);

	for (size_t j=i+1;j<i+9;j++)
	{
		Test t(txt, j);
		printf("====\n");
	}
};
