nokogiri 1.3.3 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of nokogiri might be problematic. Click here for more details.

Files changed (201) hide show
  1. data/CHANGELOG.ja.rdoc +48 -3
  2. data/CHANGELOG.rdoc +42 -0
  3. data/Manifest.txt +44 -29
  4. data/README.ja.rdoc +0 -2
  5. data/README.rdoc +4 -7
  6. data/Rakefile +42 -6
  7. data/bin/nokogiri +7 -5
  8. data/ext/nokogiri/extconf.rb +5 -21
  9. data/ext/nokogiri/html_document.c +14 -50
  10. data/ext/nokogiri/html_element_description.c +7 -7
  11. data/ext/nokogiri/html_entity_lookup.c +6 -4
  12. data/ext/nokogiri/html_sax_parser_context.c +92 -0
  13. data/ext/nokogiri/html_sax_parser_context.h +11 -0
  14. data/ext/nokogiri/nokogiri.c +9 -3
  15. data/ext/nokogiri/nokogiri.h +16 -20
  16. data/ext/nokogiri/xml_attr.c +1 -1
  17. data/ext/nokogiri/xml_attribute_decl.c +67 -0
  18. data/ext/nokogiri/xml_attribute_decl.h +9 -0
  19. data/ext/nokogiri/xml_cdata.c +6 -5
  20. data/ext/nokogiri/xml_comment.c +3 -2
  21. data/ext/nokogiri/xml_document.c +93 -23
  22. data/ext/nokogiri/xml_document_fragment.c +1 -3
  23. data/ext/nokogiri/xml_dtd.c +63 -6
  24. data/ext/nokogiri/xml_element_content.c +123 -0
  25. data/ext/nokogiri/xml_element_content.h +10 -0
  26. data/ext/nokogiri/xml_element_decl.c +69 -0
  27. data/ext/nokogiri/xml_element_decl.h +9 -0
  28. data/ext/nokogiri/xml_entity_decl.c +97 -0
  29. data/ext/nokogiri/xml_entity_decl.h +10 -0
  30. data/ext/nokogiri/xml_entity_reference.c +1 -1
  31. data/ext/nokogiri/xml_io.c +10 -3
  32. data/ext/nokogiri/xml_io.h +1 -0
  33. data/ext/nokogiri/xml_namespace.c +2 -2
  34. data/ext/nokogiri/xml_node.c +139 -34
  35. data/ext/nokogiri/xml_node.h +0 -1
  36. data/ext/nokogiri/xml_node_set.c +23 -16
  37. data/ext/nokogiri/xml_processing_instruction.c +1 -1
  38. data/ext/nokogiri/xml_reader.c +78 -50
  39. data/ext/nokogiri/xml_sax_parser.c +109 -168
  40. data/ext/nokogiri/xml_sax_parser.h +33 -0
  41. data/ext/nokogiri/xml_sax_parser_context.c +155 -0
  42. data/ext/nokogiri/xml_sax_parser_context.h +10 -0
  43. data/ext/nokogiri/xml_sax_push_parser.c +11 -6
  44. data/ext/nokogiri/xml_syntax_error.c +63 -12
  45. data/ext/nokogiri/xml_text.c +4 -3
  46. data/ext/nokogiri/xml_xpath.c +1 -1
  47. data/ext/nokogiri/xml_xpath_context.c +12 -25
  48. data/ext/nokogiri/xslt_stylesheet.c +3 -3
  49. data/lib/nokogiri.rb +4 -4
  50. data/lib/nokogiri/css/generated_tokenizer.rb +1 -0
  51. data/lib/nokogiri/css/node.rb +1 -9
  52. data/lib/nokogiri/css/xpath_visitor.rb +11 -21
  53. data/lib/nokogiri/ffi/html/document.rb +0 -9
  54. data/lib/nokogiri/ffi/html/sax/parser_context.rb +38 -0
  55. data/lib/nokogiri/ffi/io_callbacks.rb +4 -2
  56. data/lib/nokogiri/ffi/libxml.rb +44 -10
  57. data/lib/nokogiri/ffi/structs/common_node.rb +1 -1
  58. data/lib/nokogiri/ffi/structs/xml_attribute.rb +27 -0
  59. data/lib/nokogiri/ffi/structs/xml_dtd.rb +3 -1
  60. data/lib/nokogiri/ffi/structs/xml_element.rb +26 -0
  61. data/lib/nokogiri/ffi/structs/xml_element_content.rb +17 -0
  62. data/lib/nokogiri/ffi/structs/xml_entity.rb +32 -0
  63. data/lib/nokogiri/ffi/structs/xml_enumeration.rb +12 -0
  64. data/lib/nokogiri/ffi/structs/xml_parser_context.rb +19 -0
  65. data/lib/nokogiri/ffi/structs/xml_sax_push_parser_context.rb +4 -3
  66. data/lib/nokogiri/ffi/structs/xml_syntax_error.rb +1 -1
  67. data/lib/nokogiri/ffi/xml/attribute_decl.rb +27 -0
  68. data/lib/nokogiri/ffi/xml/comment.rb +2 -2
  69. data/lib/nokogiri/ffi/xml/document.rb +29 -12
  70. data/lib/nokogiri/ffi/xml/document_fragment.rb +0 -5
  71. data/lib/nokogiri/ffi/xml/dtd.rb +14 -3
  72. data/lib/nokogiri/ffi/xml/element_content.rb +43 -0
  73. data/lib/nokogiri/ffi/xml/element_decl.rb +19 -0
  74. data/lib/nokogiri/ffi/xml/entity_decl.rb +27 -0
  75. data/lib/nokogiri/ffi/xml/node.rb +45 -5
  76. data/lib/nokogiri/ffi/xml/node_set.rb +1 -1
  77. data/lib/nokogiri/ffi/xml/reader.rb +45 -24
  78. data/lib/nokogiri/ffi/xml/sax/parser.rb +27 -34
  79. data/lib/nokogiri/ffi/xml/sax/parser_context.rb +67 -0
  80. data/lib/nokogiri/ffi/xml/sax/push_parser.rb +5 -4
  81. data/lib/nokogiri/ffi/xml/syntax_error.rb +31 -16
  82. data/lib/nokogiri/ffi/xml/text.rb +2 -2
  83. data/lib/nokogiri/html.rb +1 -0
  84. data/lib/nokogiri/html/document.rb +39 -24
  85. data/lib/nokogiri/html/sax/parser.rb +2 -2
  86. data/lib/nokogiri/html/sax/parser_context.rb +16 -0
  87. data/lib/nokogiri/version.rb +1 -1
  88. data/lib/nokogiri/xml.rb +6 -1
  89. data/lib/nokogiri/xml/attr.rb +5 -0
  90. data/lib/nokogiri/xml/attribute_decl.rb +18 -0
  91. data/lib/nokogiri/xml/builder.rb +121 -13
  92. data/lib/nokogiri/xml/character_data.rb +7 -0
  93. data/lib/nokogiri/xml/document.rb +43 -29
  94. data/lib/nokogiri/xml/document_fragment.rb +26 -6
  95. data/lib/nokogiri/xml/dtd.rb +5 -5
  96. data/lib/nokogiri/xml/element_content.rb +36 -0
  97. data/lib/nokogiri/xml/element_decl.rb +13 -0
  98. data/lib/nokogiri/xml/entity_decl.rb +15 -0
  99. data/lib/nokogiri/xml/fragment_handler.rb +22 -11
  100. data/lib/nokogiri/xml/namespace.rb +6 -0
  101. data/lib/nokogiri/xml/node.rb +33 -15
  102. data/lib/nokogiri/xml/node_set.rb +66 -44
  103. data/lib/nokogiri/xml/pp.rb +2 -0
  104. data/lib/nokogiri/xml/pp/character_data.rb +18 -0
  105. data/lib/nokogiri/xml/pp/node.rb +56 -0
  106. data/lib/nokogiri/xml/reader.rb +8 -0
  107. data/lib/nokogiri/xml/sax.rb +1 -1
  108. data/lib/nokogiri/xml/sax/document.rb +18 -1
  109. data/lib/nokogiri/xml/sax/parser.rb +15 -8
  110. data/lib/nokogiri/xml/sax/parser_context.rb +16 -0
  111. data/lib/nokogiri/xml/sax/push_parser.rb +0 -3
  112. data/lib/nokogiri/xml/syntax_error.rb +4 -0
  113. data/lib/nokogiri/xslt/stylesheet.rb +1 -1
  114. data/test/css/test_nthiness.rb +1 -1
  115. data/test/css/test_parser.rb +1 -1
  116. data/test/css/test_tokenizer.rb +1 -1
  117. data/test/css/test_xpath_visitor.rb +1 -1
  118. data/test/ffi/test_document.rb +1 -1
  119. data/test/files/shift_jis.html +10 -0
  120. data/test/files/staff.dtd +10 -0
  121. data/test/helper.rb +12 -3
  122. data/test/html/sax/test_parser.rb +1 -1
  123. data/test/html/sax/test_parser_context.rb +48 -0
  124. data/test/html/test_builder.rb +8 -2
  125. data/test/html/test_document.rb +23 -1
  126. data/test/html/test_document_encoding.rb +15 -1
  127. data/test/html/test_document_fragment.rb +10 -1
  128. data/test/html/test_element_description.rb +1 -2
  129. data/test/html/test_named_characters.rb +1 -1
  130. data/test/html/test_node.rb +61 -1
  131. data/test/html/test_node_encoding.rb +27 -0
  132. data/test/test_convert_xpath.rb +1 -3
  133. data/test/test_css_cache.rb +1 -1
  134. data/test/test_gc.rb +1 -1
  135. data/test/test_memory_leak.rb +1 -1
  136. data/test/test_nokogiri.rb +3 -3
  137. data/test/test_reader.rb +29 -1
  138. data/test/test_xslt_transforms.rb +1 -1
  139. data/test/xml/node/test_save_options.rb +1 -1
  140. data/test/xml/node/test_subclass.rb +1 -1
  141. data/test/xml/sax/test_parser.rb +64 -3
  142. data/test/xml/sax/test_parser_context.rb +56 -0
  143. data/test/xml/sax/test_push_parser.rb +11 -1
  144. data/test/xml/test_attr.rb +1 -1
  145. data/test/xml/test_attribute_decl.rb +82 -0
  146. data/test/xml/test_builder.rb +95 -1
  147. data/test/xml/test_cdata.rb +1 -1
  148. data/test/xml/test_comment.rb +7 -1
  149. data/test/xml/test_document.rb +147 -6
  150. data/test/xml/test_document_encoding.rb +1 -1
  151. data/test/xml/test_document_fragment.rb +55 -5
  152. data/test/xml/test_dtd.rb +40 -5
  153. data/test/xml/test_dtd_encoding.rb +3 -1
  154. data/test/xml/test_element_content.rb +56 -0
  155. data/test/xml/test_element_decl.rb +73 -0
  156. data/test/xml/test_entity_decl.rb +83 -0
  157. data/test/xml/test_entity_reference.rb +1 -1
  158. data/test/xml/test_namespace.rb +21 -1
  159. data/test/xml/test_node.rb +70 -4
  160. data/test/xml/test_node_attributes.rb +1 -1
  161. data/test/xml/test_node_encoding.rb +1 -1
  162. data/test/xml/test_node_set.rb +136 -2
  163. data/test/xml/test_parse_options.rb +1 -1
  164. data/test/xml/test_processing_instruction.rb +1 -1
  165. data/test/xml/test_reader_encoding.rb +1 -1
  166. data/test/xml/test_relax_ng.rb +1 -1
  167. data/test/xml/test_schema.rb +1 -1
  168. data/test/xml/test_syntax_error.rb +27 -0
  169. data/test/xml/test_text.rb +13 -1
  170. data/test/xml/test_unparented_node.rb +1 -1
  171. data/test/xml/test_xpath.rb +1 -1
  172. metadata +57 -40
  173. data/ext/nokogiri/html_sax_parser.c +0 -57
  174. data/ext/nokogiri/html_sax_parser.h +0 -11
  175. data/lib/action-nokogiri.rb +0 -38
  176. data/lib/nokogiri/decorators.rb +0 -2
  177. data/lib/nokogiri/decorators/hpricot.rb +0 -3
  178. data/lib/nokogiri/decorators/hpricot/node.rb +0 -56
  179. data/lib/nokogiri/decorators/hpricot/node_set.rb +0 -54
  180. data/lib/nokogiri/decorators/hpricot/xpath_visitor.rb +0 -30
  181. data/lib/nokogiri/ffi/html/sax/parser.rb +0 -21
  182. data/lib/nokogiri/hpricot.rb +0 -92
  183. data/lib/nokogiri/xml/entity_declaration.rb +0 -11
  184. data/lib/nokogiri/xml/sax/legacy_handlers.rb +0 -65
  185. data/test/hpricot/files/basic.xhtml +0 -17
  186. data/test/hpricot/files/boingboing.html +0 -2266
  187. data/test/hpricot/files/cy0.html +0 -3653
  188. data/test/hpricot/files/immob.html +0 -400
  189. data/test/hpricot/files/pace_application.html +0 -1320
  190. data/test/hpricot/files/tenderlove.html +0 -16
  191. data/test/hpricot/files/uswebgen.html +0 -220
  192. data/test/hpricot/files/utf8.html +0 -1054
  193. data/test/hpricot/files/week9.html +0 -1723
  194. data/test/hpricot/files/why.xml +0 -19
  195. data/test/hpricot/load_files.rb +0 -11
  196. data/test/hpricot/test_alter.rb +0 -68
  197. data/test/hpricot/test_builder.rb +0 -20
  198. data/test/hpricot/test_parser.rb +0 -350
  199. data/test/hpricot/test_paths.rb +0 -15
  200. data/test/hpricot/test_preserved.rb +0 -77
  201. data/test/hpricot/test_xml.rb +0 -30
@@ -6,5 +6,38 @@
6
6
  void init_xml_sax_parser();
7
7
 
8
8
  extern VALUE cNokogiriXmlSaxParser ;
9
+
10
+ typedef struct _nokogiriSAXTuple {
11
+ xmlParserCtxtPtr ctxt;
12
+ VALUE self;
13
+ } nokogiriSAXTuple;
14
+
15
+ typedef nokogiriSAXTuple * nokogiriSAXTuplePtr;
16
+
17
+ #define NOKOGIRI_SAX_SELF(_ctxt) \
18
+ ({ \
19
+ nokogiriSAXTuplePtr _tuple = (nokogiriSAXTuplePtr)(_ctxt); \
20
+ _tuple->self; \
21
+ })
22
+
23
+ #define NOKOGIRI_SAX_CTXT(_ctxt) \
24
+ ({ \
25
+ nokogiriSAXTuplePtr _tuple = (nokogiriSAXTuplePtr)(_ctxt); \
26
+ _tuple->ctxt; \
27
+ })
28
+
29
+ #define NOKOGIRI_SAX_TUPLE_NEW(_ctxt, _self) \
30
+ ({ \
31
+ nokogiriSAXTuplePtr _tuple = malloc(sizeof(nokogiriSAXTuple)); \
32
+ _tuple->self = _self; \
33
+ _tuple->ctxt = _ctxt; \
34
+ _tuple; \
35
+ })
36
+
37
+ #define NOKOGIRI_SAX_TUPLE_DESTROY(_tuple) \
38
+ ({ \
39
+ free(_tuple); \
40
+ })
41
+
9
42
  #endif
10
43
 
@@ -0,0 +1,155 @@
1
+ #include <xml_sax_parser_context.h>
2
+
3
+ VALUE cNokogiriXmlSaxParserContext ;
4
+
5
+ static void deallocate(xmlParserCtxtPtr ctxt)
6
+ {
7
+ NOKOGIRI_DEBUG_START(handler);
8
+
9
+ ctxt->sax = NULL;
10
+
11
+ xmlFreeParserCtxt(ctxt);
12
+
13
+ NOKOGIRI_DEBUG_END(handler);
14
+ }
15
+
16
+ /*
17
+ * call-seq:
18
+ * parse_io(io, encoding)
19
+ *
20
+ * Parse +io+ object with +encoding+
21
+ */
22
+ static VALUE parse_io(VALUE klass, VALUE io, VALUE encoding)
23
+ {
24
+ xmlCharEncoding enc = (xmlCharEncoding)NUM2INT(encoding);
25
+
26
+ xmlParserCtxtPtr ctxt = xmlCreateIOParserCtxt(
27
+ NULL,
28
+ NULL,
29
+ (xmlInputReadCallback)io_read_callback,
30
+ (xmlInputCloseCallback)io_close_callback,
31
+ (void *)io,
32
+ enc
33
+ );
34
+
35
+ return Data_Wrap_Struct(klass, NULL, deallocate, ctxt);
36
+ }
37
+
38
+ /*
39
+ * call-seq:
40
+ * parse_file(filename)
41
+ *
42
+ * Parse file given +filename+
43
+ */
44
+ static VALUE parse_file(VALUE klass, VALUE filename)
45
+ {
46
+ xmlParserCtxtPtr ctxt = xmlCreateFileParserCtxt(StringValuePtr(filename));
47
+ return Data_Wrap_Struct(klass, NULL, deallocate, ctxt);
48
+ }
49
+
50
+ /*
51
+ * call-seq:
52
+ * parse_memory(data)
53
+ *
54
+ * Parse the XML stored in memory in +data+
55
+ */
56
+ static VALUE parse_memory(VALUE klass, VALUE data)
57
+ {
58
+ if(NIL_P(data)) rb_raise(rb_eArgError, "data cannot be nil");
59
+ if(!(int)RSTRING_LEN(data))
60
+ rb_raise(rb_eRuntimeError, "data cannot be empty");
61
+
62
+ xmlParserCtxtPtr ctxt = xmlCreateMemoryParserCtxt(
63
+ StringValuePtr(data),
64
+ (int)RSTRING_LEN(data)
65
+ );
66
+
67
+ return Data_Wrap_Struct(klass, NULL, deallocate, ctxt);
68
+ }
69
+
70
+ /*
71
+ * call-seq:
72
+ * parse_with(sax_handler)
73
+ *
74
+ * Use +sax_handler+ and parse the current document
75
+ */
76
+ static VALUE parse_with(VALUE self, VALUE sax_handler)
77
+ {
78
+ if(!rb_obj_is_kind_of(sax_handler, cNokogiriXmlSaxParser))
79
+ rb_raise(rb_eArgError, "argument must be a Nokogiri::XML::SAX::Parser");
80
+
81
+ xmlParserCtxtPtr ctxt;
82
+ Data_Get_Struct(self, xmlParserCtxt, ctxt);
83
+
84
+ xmlSAXHandlerPtr sax;
85
+ Data_Get_Struct(sax_handler, xmlSAXHandler, sax);
86
+
87
+ // Free the sax handler since we'll assign our own
88
+ if(ctxt->sax && ctxt->sax != (xmlSAXHandlerPtr)&xmlDefaultSAXHandler)
89
+ xmlFree(ctxt->sax);
90
+
91
+ ctxt->sax = sax;
92
+ ctxt->userData = (void *)NOKOGIRI_SAX_TUPLE_NEW(ctxt, sax_handler);
93
+
94
+ xmlParseDocument(ctxt);
95
+
96
+ if(NULL != ctxt->myDoc) xmlFreeDoc(ctxt->myDoc);
97
+
98
+ NOKOGIRI_SAX_TUPLE_DESTROY(ctxt->userData);
99
+ }
100
+
101
+ /*
102
+ * call-seq:
103
+ * replace_entities=(boolean)
104
+ *
105
+ * Should this parser replace entities? &amp; will get converted to '&' if
106
+ * set to true
107
+ */
108
+ static VALUE set_replace_entities(VALUE self, VALUE value)
109
+ {
110
+ xmlParserCtxtPtr ctxt;
111
+ Data_Get_Struct(self, xmlParserCtxt, ctxt);
112
+
113
+ if(Qfalse == value)
114
+ ctxt->replaceEntities = 0;
115
+ else
116
+ ctxt->replaceEntities = 1;
117
+
118
+ return value;
119
+ }
120
+
121
+ /*
122
+ * call-seq:
123
+ * replace_entities
124
+ *
125
+ * Should this parser replace entities? &amp; will get converted to '&' if
126
+ * set to true
127
+ */
128
+ static VALUE get_replace_entities(VALUE self)
129
+ {
130
+ xmlParserCtxtPtr ctxt;
131
+ Data_Get_Struct(self, xmlParserCtxt, ctxt);
132
+
133
+ if(0 == ctxt->replaceEntities)
134
+ return Qfalse;
135
+ else
136
+ return Qtrue;
137
+ }
138
+
139
+ void init_xml_sax_parser_context()
140
+ {
141
+ VALUE nokogiri = rb_define_module("Nokogiri");
142
+ VALUE xml = rb_define_module_under(nokogiri, "XML");
143
+ VALUE sax = rb_define_module_under(xml, "SAX");
144
+ VALUE klass = rb_define_class_under(sax, "ParserContext", rb_cObject);
145
+
146
+ cNokogiriXmlSaxParserContext = klass;
147
+
148
+ rb_define_singleton_method(klass, "io", parse_io, 2);
149
+ rb_define_singleton_method(klass, "memory", parse_memory, 1);
150
+ rb_define_singleton_method(klass, "file", parse_file, 1);
151
+
152
+ rb_define_method(klass, "parse_with", parse_with, 1);
153
+ rb_define_method(klass, "replace_entities=", set_replace_entities, 1);
154
+ rb_define_method(klass, "replace_entities", get_replace_entities, 0);
155
+ }
@@ -0,0 +1,10 @@
1
+ #ifndef NOKOGIRI_XML_SAX_PARSER_CONTEXT
2
+ #define NOKOGIRI_XML_SAX_PARSER_CONTEXT
3
+
4
+ #include <nokogiri.h>
5
+
6
+ extern VALUE cNokogiriXmlSaxParserContext;
7
+
8
+ void init_xml_sax_parser_context();
9
+
10
+ #endif
@@ -3,7 +3,10 @@
3
3
  static void deallocate(xmlParserCtxtPtr ctx)
4
4
  {
5
5
  NOKOGIRI_DEBUG_START(ctx);
6
- if(ctx != NULL) xmlFreeParserCtxt(ctx);
6
+ if(ctx != NULL) {
7
+ NOKOGIRI_SAX_TUPLE_DESTROY(ctx->userData);
8
+ xmlFreeParserCtxt(ctx);
9
+ }
7
10
  NOKOGIRI_DEBUG_END(ctx);
8
11
  }
9
12
 
@@ -24,17 +27,17 @@ static VALUE native_write(VALUE self, VALUE _chunk, VALUE _last_chunk)
24
27
  Data_Get_Struct(self, xmlParserCtxt, ctx);
25
28
 
26
29
  const char * chunk = NULL;
27
- int last_chunk = 0;
28
30
  int size = 0;
29
31
 
30
32
  if(Qnil != _chunk) {
31
33
  chunk = StringValuePtr(_chunk);
32
34
  size = RSTRING_LEN(_chunk);
33
35
  }
34
- if(Qtrue == _last_chunk) last_chunk = 1;
35
36
 
36
- if(xmlParseChunk(ctx, chunk, size, last_chunk))
37
- rb_raise(rb_eRuntimeError, "Couldn't parse chunk");
37
+ if(xmlParseChunk(ctx, chunk, size, Qtrue == _last_chunk ? 1 : 0)) {
38
+ xmlErrorPtr e = xmlCtxtGetLastError(ctx);
39
+ Nokogiri_error_raise(NULL, e);
40
+ }
38
41
 
39
42
  return self;
40
43
  }
@@ -57,7 +60,7 @@ static VALUE initialize_native(VALUE self, VALUE _xml_sax, VALUE _filename)
57
60
 
58
61
  xmlParserCtxtPtr ctx = xmlCreatePushParserCtxt(
59
62
  sax,
60
- (void *)self,
63
+ NULL,
61
64
  NULL,
62
65
  0,
63
66
  filename
@@ -65,6 +68,8 @@ static VALUE initialize_native(VALUE self, VALUE _xml_sax, VALUE _filename)
65
68
  if(ctx == NULL)
66
69
  rb_raise(rb_eRuntimeError, "Could not create a parser context");
67
70
 
71
+ ctx->userData = NOKOGIRI_SAX_TUPLE_NEW(ctx, self);
72
+
68
73
  ctx->sax2 = 1;
69
74
  DATA_PTR(self) = ctx;
70
75
  return self;
@@ -8,6 +8,13 @@ static void dealloc(xmlErrorPtr ptr)
8
8
  NOKOGIRI_DEBUG_END(ptr);
9
9
  }
10
10
 
11
+ static VALUE allocate(VALUE klass)
12
+ {
13
+ xmlErrorPtr error = xmlMalloc(sizeof(xmlError));
14
+ memset(error, 0, sizeof(xmlError));
15
+ return Data_Wrap_Struct(klass, NULL, dealloc, error);
16
+ }
17
+
11
18
  /*
12
19
  * call-seq:
13
20
  * column
@@ -44,8 +51,7 @@ static VALUE str3(VALUE self)
44
51
  {
45
52
  xmlErrorPtr error;
46
53
  Data_Get_Struct(self, xmlError, error);
47
- if(error->str3)
48
- return NOKOGIRI_STR_NEW2(error->str3, "UTF-8");
54
+ if(error->str3) return NOKOGIRI_STR_NEW2(error->str3);
49
55
  return Qnil;
50
56
  }
51
57
 
@@ -59,8 +65,7 @@ static VALUE str2(VALUE self)
59
65
  {
60
66
  xmlErrorPtr error;
61
67
  Data_Get_Struct(self, xmlError, error);
62
- if(error->str2)
63
- return NOKOGIRI_STR_NEW2(error->str2, "UTF-8");
68
+ if(error->str2) return NOKOGIRI_STR_NEW2(error->str2);
64
69
  return Qnil;
65
70
  }
66
71
 
@@ -74,8 +79,7 @@ static VALUE str1(VALUE self)
74
79
  {
75
80
  xmlErrorPtr error;
76
81
  Data_Get_Struct(self, xmlError, error);
77
- if(error->str1)
78
- return NOKOGIRI_STR_NEW2(error->str1, "UTF-8");
82
+ if(error->str1) return NOKOGIRI_STR_NEW2(error->str1);
79
83
  return Qnil;
80
84
  }
81
85
 
@@ -102,8 +106,7 @@ static VALUE file(VALUE self)
102
106
  {
103
107
  xmlErrorPtr error;
104
108
  Data_Get_Struct(self, xmlError, error);
105
- if(error->file)
106
- return NOKOGIRI_STR_NEW2(error->file, "UTF-8");
109
+ if(error->file) return NOKOGIRI_STR_NEW2(error->file);
107
110
 
108
111
  return Qnil;
109
112
  }
@@ -157,7 +160,53 @@ static VALUE message(VALUE self)
157
160
  {
158
161
  xmlErrorPtr error;
159
162
  Data_Get_Struct(self, xmlError, error);
160
- return NOKOGIRI_STR_NEW2(error->message, "UTF-8");
163
+ if(error->message) return NOKOGIRI_STR_NEW2(error->message);
164
+ return Qnil;
165
+ }
166
+
167
+ /*
168
+ * call-seq:
169
+ * message=
170
+ *
171
+ * Set the human readable message.
172
+ */
173
+ static VALUE set_message(VALUE self, VALUE _message)
174
+ {
175
+ xmlErrorPtr error;
176
+ Data_Get_Struct(self, xmlError, error);
177
+
178
+ if(error->message) {
179
+ xmlFree(error->message);
180
+ error->message = 0;
181
+ }
182
+
183
+ if(RTEST(_message)) {
184
+ error->message = xmlMalloc(RSTRING_LEN(_message) + 1);
185
+ memset(error->message, 0, RSTRING_LEN(_message) + 1);
186
+ memcpy(error->message, StringValuePtr(_message), RSTRING_LEN(_message));
187
+ }
188
+
189
+ return message;
190
+ }
191
+
192
+ /*
193
+ * call-seq:
194
+ * initialize_copy(old_copy)
195
+ *
196
+ * Initialize a copy of the +old_copy+
197
+ */
198
+ static VALUE initialize_copy(VALUE self, VALUE _old_copy)
199
+ {
200
+ if(!rb_obj_is_kind_of(_old_copy, cNokogiriXmlSyntaxError))
201
+ rb_raise(rb_eArgError, "node must be a Nokogiri::XML::SyntaxError");
202
+
203
+ xmlErrorPtr error, old_error;
204
+ Data_Get_Struct(self, xmlError, error);
205
+ Data_Get_Struct(_old_copy, xmlError, old_error);
206
+
207
+ xmlCopyError(old_error, error);
208
+
209
+ return message;
161
210
  }
162
211
 
163
212
  void Nokogiri_error_array_pusher(void * ctx, xmlErrorPtr error)
@@ -168,9 +217,7 @@ void Nokogiri_error_array_pusher(void * ctx, xmlErrorPtr error)
168
217
 
169
218
  void Nokogiri_error_raise(void * ctx, xmlErrorPtr error)
170
219
  {
171
- rb_funcall(rb_mKernel, rb_intern("raise"), 1,
172
- Nokogiri_wrap_xml_syntax_error((VALUE)NULL, error)
173
- );
220
+ rb_exc_raise(Nokogiri_wrap_xml_syntax_error((VALUE)NULL, error));
174
221
  }
175
222
 
176
223
  VALUE Nokogiri_wrap_xml_syntax_error(VALUE klass, xmlErrorPtr error)
@@ -196,7 +243,11 @@ void init_xml_syntax_error()
196
243
  VALUE klass = rb_define_class_under(xml, "SyntaxError", syntax_error_mommy);
197
244
  cNokogiriXmlSyntaxError = klass;
198
245
 
246
+ rb_define_alloc_func(klass, allocate);
247
+
199
248
  rb_define_method(klass, "message", message, 0);
249
+ rb_define_method(klass, "message=", set_message, 1);
250
+ rb_define_method(klass, "initialize_copy", initialize_copy, 1);
200
251
  rb_define_method(klass, "domain", domain, 0);
201
252
  rb_define_method(klass, "code", code, 0);
202
253
  rb_define_method(klass, "level", level, 0);
@@ -18,10 +18,10 @@ static VALUE new(int argc, VALUE *argv, VALUE klass)
18
18
  Data_Get_Struct(document, xmlDoc, doc);
19
19
 
20
20
  xmlNodePtr node = xmlNewText((xmlChar *)StringValuePtr(string));
21
- node->doc = doc;
21
+ node->doc = doc->doc;
22
22
 
23
23
  VALUE rb_node = Nokogiri_wrap_xml_node(klass, node) ;
24
- rb_funcall2(rb_node, rb_intern("initialize"), argc, argv);
24
+ rb_obj_call_init(rb_node, argc, argv);
25
25
 
26
26
  if(rb_block_given_p()) rb_yield(rb_node);
27
27
 
@@ -35,11 +35,12 @@ void init_xml_text()
35
35
  VALUE xml = rb_define_module_under(nokogiri, "XML");
36
36
  /* */
37
37
  VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
38
+ VALUE char_data = rb_define_class_under(xml, "CharacterData", node);
38
39
 
39
40
  /*
40
41
  * Wraps Text nodes.
41
42
  */
42
- VALUE klass = rb_define_class_under(xml, "Text", node);
43
+ VALUE klass = rb_define_class_under(xml, "Text", char_data);
43
44
 
44
45
  cNokogiriXmlText = klass;
45
46
 
@@ -28,7 +28,7 @@ static VALUE node_set(VALUE self)
28
28
  if (xpath->nodesetval)
29
29
  node_set = Nokogiri_wrap_xml_node_set(xpath->nodesetval);
30
30
 
31
- if(Qnil == node_set)
31
+ if(NIL_P(node_set))
32
32
  node_set = Nokogiri_wrap_xml_node_set(xmlXPathNodeSetCreate(NULL));
33
33
 
34
34
  rb_funcall(node_set, rb_intern("document="), 1, rb_iv_get(self, "@document"));
@@ -46,7 +46,7 @@ static void ruby_funcall(xmlXPathParserContextPtr ctx, int nargs)
46
46
  obj = valuePop(ctx);
47
47
  switch(obj->type) {
48
48
  case XPATH_STRING:
49
- argv[i] = NOKOGIRI_STR_NEW2(obj->stringval, ctx->context->doc->encoding);
49
+ argv[i] = NOKOGIRI_STR_NEW2(obj->stringval);
50
50
  break;
51
51
  case XPATH_BOOLEAN:
52
52
  argv[i] = obj->boolval == 1 ? Qtrue : Qfalse;
@@ -58,9 +58,7 @@ static void ruby_funcall(xmlXPathParserContextPtr ctx, int nargs)
58
58
  argv[i] = Nokogiri_wrap_xml_node_set(obj->nodesetval);
59
59
  break;
60
60
  default:
61
- argv[i] = NOKOGIRI_STR_NEW2(
62
- xmlXPathCastToString(obj), ctx->context->doc->encoding
63
- );
61
+ argv[i] = NOKOGIRI_STR_NEW2(xmlXPathCastToString(obj));
64
62
  }
65
63
  xmlXPathFreeNodeSetList(obj);
66
64
  } while(i-- > 0);
@@ -97,18 +95,15 @@ static void ruby_funcall(xmlXPathParserContextPtr ctx, int nargs)
97
95
  case T_NIL:
98
96
  break;
99
97
  case T_ARRAY:
100
- node_set = rb_funcall(
101
- cNokogiriXmlNodeSet,
102
- rb_intern("new"),
103
- 2,
104
- doc,
105
- result
106
- );
107
- Data_Get_Struct(node_set, xmlNodeSet, xml_node_set);
108
- xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set));
98
+ {
99
+ VALUE args[2] = {doc, result};
100
+ node_set = rb_class_new_instance(2, args, cNokogiriXmlNodeSet);
101
+ Data_Get_Struct(node_set, xmlNodeSet, xml_node_set);
102
+ xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set));
103
+ }
109
104
  break;
110
105
  case T_DATA:
111
- if(rb_funcall(result, rb_intern("is_a?"), 1, cNokogiriXmlNodeSet)) {
106
+ if(rb_obj_is_kind_of(result, cNokogiriXmlNodeSet)) {
112
107
  Data_Get_Struct(result, xmlNodeSet, xml_node_set);
113
108
  // Copy the node set, otherwise it will get GC'd.
114
109
  xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set));
@@ -135,9 +130,7 @@ static void xpath_exception_handler(void * ctx, xmlErrorPtr error)
135
130
  VALUE xpath = rb_const_get(mNokogiriXml, rb_intern("XPath"));
136
131
  VALUE klass = rb_const_get(xpath, rb_intern("SyntaxError"));
137
132
 
138
- rb_funcall(rb_mKernel, rb_intern("raise"), 1,
139
- Nokogiri_wrap_xml_syntax_error(klass, error)
140
- );
133
+ rb_exc_raise(Nokogiri_wrap_xml_syntax_error(klass, error));
141
134
  }
142
135
 
143
136
  static void xpath_generic_exception_handler(void * ctx, const char *msg, ...)
@@ -191,9 +184,7 @@ static VALUE evaluate(int argc, VALUE *argv, VALUE self)
191
184
  VALUE klass = rb_const_get(xpath, rb_intern("SyntaxError"));
192
185
 
193
186
  xmlErrorPtr error = xmlGetLastError();
194
- rb_funcall(rb_mKernel, rb_intern("raise"), 1,
195
- Nokogiri_wrap_xml_syntax_error(klass, error)
196
- );
187
+ rb_exc_raise(Nokogiri_wrap_xml_syntax_error(klass, error));
197
188
  }
198
189
 
199
190
  VALUE xpath_object = Nokogiri_wrap_xml_xpath(xpath);
@@ -201,11 +192,7 @@ static VALUE evaluate(int argc, VALUE *argv, VALUE self)
201
192
  assert(ctx->doc);
202
193
  assert(DOC_RUBY_OBJECT_TEST(ctx->doc));
203
194
 
204
- rb_funcall( xpath_object,
205
- rb_intern("document="),
206
- 1,
207
- DOC_RUBY_OBJECT(ctx->doc)
208
- );
195
+ rb_iv_set(xpath_object, "@document", DOC_RUBY_OBJECT(ctx->doc));
209
196
  return xpath_object;
210
197
  }
211
198