Skip to content

Commit b0d1f07

Browse files
committed
Remove usage of deprecated sax handlers.
1 parent d8324b0 commit b0d1f07

4 files changed

Lines changed: 116 additions & 125 deletions

File tree

ext/libxml/ruby_xml_html_parser_context.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -238,13 +238,12 @@ static VALUE rxml_html_parser_context_string(int argc, VALUE* argv, VALUE klass)
238238
VALUE string, options;
239239
rb_scan_args(argc, argv, "11", &string, &options);
240240

241-
htmlParserCtxtPtr ctxt;
242241
Check_Type(string, T_STRING);
243242

244243
if (RSTRING_LEN(string) == 0)
245244
rb_raise(rb_eArgError, "Must specify a string with one or more characters");
246245

247-
ctxt = xmlCreateMemoryParserCtxt(StringValuePtr(string),
246+
htmlParserCtxtPtr ctxt = xmlCreateMemoryParserCtxt(StringValuePtr(string),
248247
(int)RSTRING_LEN(string));
249248
if (!ctxt)
250249
rxml_raise(xmlGetLastError());
@@ -255,8 +254,11 @@ static VALUE rxml_html_parser_context_string(int argc, VALUE* argv, VALUE klass)
255254
sets to 0 and xmlCtxtUseOptionsInternal sets to 1. So we have to call both. */
256255
htmlCtxtUseOptions(ctxt, options == Qnil ? 0 : NUM2INT(options));
257256

258-
if (ctxt->sax != NULL)
259-
memcpy(ctxt->sax, &htmlDefaultSAXHandler, sizeof(xmlSAXHandlerV1));
257+
// Setup sax handler
258+
// TODO - there must be a better way? The sax handler is initialized for XML, but we want
259+
// to use HTML
260+
memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
261+
xmlSAX2InitHtmlDefaultSAXHandler(ctxt->sax);
260262

261263
return rxml_html_parser_context_wrap(ctxt);
262264
}
@@ -300,7 +302,7 @@ static VALUE rxml_html_parser_context_disable_cdata_set(VALUE self, VALUE value)
300302
if (value)
301303
ctxt->sax->cdataBlock = NULL;
302304
else
303-
ctxt->sax->cdataBlock = htmlDefaultSAXHandler.cdataBlock;
305+
ctxt->sax->cdataBlock = xmlSAX2CDataBlock;
304306

305307
return value;
306308
}

ext/libxml/ruby_xml_namespace.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,6 @@ static VALUE rxml_namespace_initialize(VALUE self, VALUE node, VALUE prefix,
5858
xmlPrefix = NIL_P(prefix) ? NULL : (xmlChar *)StringValuePtr(prefix);
5959
xns = xmlNewNs(xnode, (xmlChar*) StringValuePtr(href), xmlPrefix);
6060

61-
if (!xns)
62-
rxml_raise(xmlGetLastError());
63-
6461
DATA_PTR(self) = xns;
6562
return self;
6663
}

ext/libxml/ruby_xml_parser_context.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ static VALUE rxml_parser_context_disable_cdata_set(VALUE self, VALUE value)
311311
if (value)
312312
ctxt->sax->cdataBlock = NULL;
313313
else
314-
ctxt->sax->cdataBlock = xmlDefaultSAXHandler.cdataBlock;
314+
ctxt->sax->cdataBlock = xmlSAX2CDataBlock;
315315

316316
return value;
317317
}

ext/libxml/ruby_xml_sax_parser.c

Lines changed: 108 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,108 @@
1-
/* Please see the LICENSE file for copyright and distribution information */
2-
3-
#include "ruby_libxml.h"
4-
#include "ruby_xml_sax_parser.h"
5-
6-
/*
7-
* Document-class: LibXML::XML::SaxParser
8-
*
9-
* XML::SaxParser provides a callback based API for parsing documents,
10-
* in contrast to XML::Parser's tree based API and XML::Reader's stream
11-
* based API.
12-
*
13-
* The XML::SaxParser API is fairly complex, not well standardized,
14-
* and does not directly support validation making entity, namespace and
15-
* base processing relatively hard.
16-
*
17-
* To use the XML::SaxParser, register a callback class via the
18-
* XML::SaxParser#callbacks=. It is easiest to include the
19-
* XML::SaxParser::Callbacks module in your class and override
20-
* the methods as needed.
21-
*
22-
* Basic example:
23-
*
24-
* class MyCallbacks
25-
* include XML::SaxParser::Callbacks
26-
* def on_start_element(element, attributes)
27-
* puts #Element started: #{element}"
28-
* end
29-
* end
30-
*
31-
* parser = XML::SaxParser.string(my_string)
32-
* parser.callbacks = MyCallbacks.new
33-
* parser.parse
34-
*
35-
* You can also parse strings (see XML::SaxParser.string) and
36-
* io objects (see XML::SaxParser.io).
37-
*/
38-
39-
VALUE cXMLSaxParser;
40-
static ID CALLBACKS_ATTR;
41-
static ID CONTEXT_ATTR;
42-
43-
44-
/* ====== Parser =========== */
45-
46-
/*
47-
* call-seq:
48-
* parser.initialize(context) -> XML::Parser
49-
*
50-
* Creates a new XML::Parser from the specified
51-
* XML::Parser::Context.
52-
*/
53-
static VALUE rxml_sax_parser_initialize(int argc, VALUE *argv, VALUE self)
54-
{
55-
VALUE context = Qnil;
56-
57-
rb_scan_args(argc, argv, "01", &context);
58-
59-
if (context == Qnil)
60-
{
61-
rb_raise(rb_eArgError, "An instance of a XML::Parser::Context must be passed to XML::SaxParser.new");
62-
}
63-
64-
rb_ivar_set(self, CONTEXT_ATTR, context);
65-
return self;
66-
}
67-
68-
/*
69-
* call-seq:
70-
* parser.parse -> (true|false)
71-
*
72-
* Parse the input XML, generating callbacks to the object
73-
* registered via the +callbacks+ attributesibute.
74-
*/
75-
static VALUE rxml_sax_parser_parse(VALUE self)
76-
{
77-
int status;
78-
VALUE context = rb_ivar_get(self, CONTEXT_ATTR);
79-
xmlParserCtxtPtr ctxt;
80-
Data_Get_Struct(context, xmlParserCtxt, ctxt);
81-
82-
ctxt->sax2 = 1;
83-
ctxt->userData = (void*)rb_ivar_get(self, CALLBACKS_ATTR);
84-
85-
if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
86-
xmlFree(ctxt->sax);
87-
88-
ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(rxml_sax_handler));
89-
if (ctxt->sax == NULL)
90-
rb_fatal("Not enough memory.");
91-
memcpy(ctxt->sax, &rxml_sax_handler, sizeof(rxml_sax_handler));
92-
93-
status = xmlParseDocument(ctxt);
94-
95-
/* Now check the parsing result*/
96-
if (status == -1 || !ctxt->wellFormed)
97-
{
98-
rxml_raise(&ctxt->lastError);
99-
}
100-
return Qtrue;
101-
}
102-
103-
void rxml_init_sax_parser(void)
104-
{
105-
/* SaxParser */
106-
cXMLSaxParser = rb_define_class_under(mXML, "SaxParser", rb_cObject);
107-
108-
/* Atributes */
109-
CALLBACKS_ATTR = rb_intern("@callbacks");
110-
CONTEXT_ATTR = rb_intern("@context");
111-
rb_define_attr(cXMLSaxParser, "callbacks", 1, 1);
112-
113-
/* Instance Methods */
114-
rb_define_method(cXMLSaxParser, "initialize", rxml_sax_parser_initialize, -1);
115-
rb_define_method(cXMLSaxParser, "parse", rxml_sax_parser_parse, 0);
116-
}
1+
/* Please see the LICENSE file for copyright and distribution information */
2+
3+
#include "ruby_libxml.h"
4+
#include "ruby_xml_sax_parser.h"
5+
6+
/*
7+
* Document-class: LibXML::XML::SaxParser
8+
*
9+
* XML::SaxParser provides a callback based API for parsing documents,
10+
* in contrast to XML::Parser's tree based API and XML::Reader's stream
11+
* based API.
12+
*
13+
* The XML::SaxParser API is fairly complex, not well standardized,
14+
* and does not directly support validation making entity, namespace and
15+
* base processing relatively hard.
16+
*
17+
* To use the XML::SaxParser, register a callback class via the
18+
* XML::SaxParser#callbacks=. It is easiest to include the
19+
* XML::SaxParser::Callbacks module in your class and override
20+
* the methods as needed.
21+
*
22+
* Basic example:
23+
*
24+
* class MyCallbacks
25+
* include XML::SaxParser::Callbacks
26+
* def on_start_element(element, attributes)
27+
* puts #Element started: #{element}"
28+
* end
29+
* end
30+
*
31+
* parser = XML::SaxParser.string(my_string)
32+
* parser.callbacks = MyCallbacks.new
33+
* parser.parse
34+
*
35+
* You can also parse strings (see XML::SaxParser.string) and
36+
* io objects (see XML::SaxParser.io).
37+
*/
38+
39+
VALUE cXMLSaxParser;
40+
static ID CALLBACKS_ATTR;
41+
static ID CONTEXT_ATTR;
42+
43+
44+
/* ====== Parser =========== */
45+
46+
/*
47+
* call-seq:
48+
* parser.initialize(context) -> XML::Parser
49+
*
50+
* Creates a new XML::Parser from the specified
51+
* XML::Parser::Context.
52+
*/
53+
static VALUE rxml_sax_parser_initialize(int argc, VALUE *argv, VALUE self)
54+
{
55+
VALUE context = Qnil;
56+
57+
rb_scan_args(argc, argv, "01", &context);
58+
59+
if (context == Qnil)
60+
{
61+
rb_raise(rb_eArgError, "An instance of a XML::Parser::Context must be passed to XML::SaxParser.new");
62+
}
63+
64+
rb_ivar_set(self, CONTEXT_ATTR, context);
65+
return self;
66+
}
67+
68+
/*
69+
* call-seq:
70+
* parser.parse -> (true|false)
71+
*
72+
* Parse the input XML, generating callbacks to the object
73+
* registered via the +callbacks+ attributesibute.
74+
*/
75+
static VALUE rxml_sax_parser_parse(VALUE self)
76+
{
77+
VALUE context = rb_ivar_get(self, CONTEXT_ATTR);
78+
xmlParserCtxtPtr ctxt;
79+
Data_Get_Struct(context, xmlParserCtxt, ctxt);
80+
81+
ctxt->sax2 = 1;
82+
ctxt->userData = (void*)rb_ivar_get(self, CALLBACKS_ATTR);
83+
memcpy(ctxt->sax, &rxml_sax_handler, sizeof(rxml_sax_handler));
84+
85+
int status = xmlParseDocument(ctxt);
86+
87+
/* Now check the parsing result*/
88+
if (status == -1 || !ctxt->wellFormed)
89+
{
90+
rxml_raise(&ctxt->lastError);
91+
}
92+
return Qtrue;
93+
}
94+
95+
void rxml_init_sax_parser(void)
96+
{
97+
/* SaxParser */
98+
cXMLSaxParser = rb_define_class_under(mXML, "SaxParser", rb_cObject);
99+
100+
/* Atributes */
101+
CALLBACKS_ATTR = rb_intern("@callbacks");
102+
CONTEXT_ATTR = rb_intern("@context");
103+
rb_define_attr(cXMLSaxParser, "callbacks", 1, 1);
104+
105+
/* Instance Methods */
106+
rb_define_method(cXMLSaxParser, "initialize", rxml_sax_parser_initialize, -1);
107+
rb_define_method(cXMLSaxParser, "parse", rxml_sax_parser_parse, 0);
108+
}

0 commit comments

Comments
 (0)