nokolexbor 0.2.5 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/nokolexbor/CMakeLists.txt +7 -4
- data/ext/nokolexbor/config.h.cmake.in +2 -0
- data/ext/nokolexbor/extconf.rb +47 -25
- data/ext/nokolexbor/libxml/SAX2.h +4 -4
- data/ext/nokolexbor/libxml/chvalid.h +21 -21
- data/ext/nokolexbor/libxml/dict.h +13 -13
- data/ext/nokolexbor/libxml/globals.h +202 -202
- data/ext/nokolexbor/libxml/hash.h +25 -25
- data/ext/nokolexbor/libxml/parser.h +5 -5
- data/ext/nokolexbor/libxml/parserInternals.h +4 -4
- data/ext/nokolexbor/libxml/pattern.h +14 -14
- data/ext/nokolexbor/libxml/threads.h +15 -15
- data/ext/nokolexbor/libxml/tree.h +5 -5
- data/ext/nokolexbor/libxml/xmlerror.h +5 -5
- data/ext/nokolexbor/libxml/xmlmemory.h +16 -16
- data/ext/nokolexbor/libxml/xmlstring.h +30 -30
- data/ext/nokolexbor/libxml/xpath.h +43 -43
- data/ext/nokolexbor/libxml/xpathInternals.h +128 -128
- data/ext/nokolexbor/memory.c +6 -6
- data/ext/nokolexbor/nl_cdata.c +44 -0
- data/ext/nokolexbor/nl_comment.c +44 -0
- data/ext/nokolexbor/nl_document.c +23 -9
- data/ext/nokolexbor/nl_node.c +191 -178
- data/ext/nokolexbor/nl_node_set.c +38 -73
- data/ext/nokolexbor/nl_text.c +44 -0
- data/ext/nokolexbor/nl_xpath_context.c +33 -42
- data/ext/nokolexbor/nokolexbor.c +7 -3
- data/ext/nokolexbor/nokolexbor.h +9 -7
- data/ext/nokolexbor/private/buf.h +1 -1
- data/ext/nokolexbor/private/error.h +3 -3
- data/ext/nokolexbor/xml_SAX2.c +8 -8
- data/ext/nokolexbor/xml_buf.c +19 -19
- data/ext/nokolexbor/xml_chvalid.c +25 -25
- data/ext/nokolexbor/xml_dict.c +69 -69
- data/ext/nokolexbor/xml_encoding.c +2 -2
- data/ext/nokolexbor/xml_error.c +51 -51
- data/ext/nokolexbor/xml_globals.c +329 -329
- data/ext/nokolexbor/xml_hash.c +131 -131
- data/ext/nokolexbor/xml_memory.c +25 -25
- data/ext/nokolexbor/xml_parser.c +3 -3
- data/ext/nokolexbor/xml_parserInternals.c +15 -15
- data/ext/nokolexbor/xml_pattern.c +103 -103
- data/ext/nokolexbor/xml_string.c +93 -93
- data/ext/nokolexbor/xml_threads.c +61 -61
- data/ext/nokolexbor/xml_tree.c +12 -12
- data/ext/nokolexbor/xml_xpath.c +1194 -1203
- data/lib/nokolexbor/document.rb +92 -1
- data/lib/nokolexbor/node.rb +64 -0
- data/lib/nokolexbor/node_set.rb +6 -5
- data/lib/nokolexbor/version.rb +1 -1
- data/lib/nokolexbor.rb +21 -1
- data/patches/0001-lexbor-support-text-pseudo-element.patch +1 -1
- metadata +7 -4
@@ -6,7 +6,7 @@ VALUE cNokolexborNodeSet;
|
|
6
6
|
extern rb_data_type_t nl_document_type;
|
7
7
|
|
8
8
|
lxb_status_t nl_node_find(VALUE self, VALUE selector, lxb_selectors_cb_f cb, void *ctx);
|
9
|
-
void
|
9
|
+
void nl_sort_nodes_if_necessary(VALUE selector, lxb_dom_document_t *doc, lexbor_array_t *array);
|
10
10
|
lxb_status_t nl_node_at_css_callback(lxb_dom_node_t *node, lxb_css_selector_specificity_t *spec, void *ctx);
|
11
11
|
lxb_status_t nl_node_css_callback(lxb_dom_node_t *node, lxb_css_selector_specificity_t *spec, void *ctx);
|
12
12
|
|
@@ -55,8 +55,7 @@ nl_node_set_allocate(VALUE klass)
|
|
55
55
|
VALUE
|
56
56
|
nl_rb_node_set_create_with_data(lexbor_array_t *array, VALUE rb_document)
|
57
57
|
{
|
58
|
-
if (array == NULL)
|
59
|
-
{
|
58
|
+
if (array == NULL) {
|
60
59
|
array = lexbor_array_create();
|
61
60
|
}
|
62
61
|
VALUE ret = TypedData_Wrap_Struct(cNokolexborNodeSet, &nl_node_set_type, array);
|
@@ -77,8 +76,7 @@ nl_node_set_push(VALUE self, VALUE rb_node)
|
|
77
76
|
lxb_dom_node_t *node = nl_rb_node_unwrap(rb_node);
|
78
77
|
|
79
78
|
lxb_status_t status = lexbor_array_push_unique(array, node);
|
80
|
-
if (status != LXB_STATUS_OK && status != LXB_STATUS_STOPPED)
|
81
|
-
{
|
79
|
+
if (status != LXB_STATUS_OK && status != LXB_STATUS_STOPPED) {
|
82
80
|
nl_raise_lexbor_error(status);
|
83
81
|
}
|
84
82
|
|
@@ -93,13 +91,11 @@ nl_node_set_delete(VALUE self, VALUE rb_node)
|
|
93
91
|
|
94
92
|
size_t i;
|
95
93
|
for (i = 0; i < array->length; i++)
|
96
|
-
if (array->list[i] == node)
|
97
|
-
{
|
94
|
+
if (array->list[i] == node) {
|
98
95
|
break;
|
99
96
|
}
|
100
97
|
|
101
|
-
if (i >= array->length)
|
102
|
-
{
|
98
|
+
if (i >= array->length) {
|
103
99
|
// not found
|
104
100
|
return Qnil;
|
105
101
|
}
|
@@ -114,8 +110,7 @@ nl_node_set_is_include(VALUE self, VALUE rb_node)
|
|
114
110
|
lxb_dom_node_t *node = nl_rb_node_unwrap(rb_node);
|
115
111
|
|
116
112
|
for (size_t i = 0; i < array->length; i++)
|
117
|
-
if (array->list[i] == node)
|
118
|
-
{
|
113
|
+
if (array->list[i] == node) {
|
119
114
|
return Qtrue;
|
120
115
|
}
|
121
116
|
|
@@ -126,13 +121,11 @@ static VALUE
|
|
126
121
|
nl_node_set_index_at(VALUE self, long offset)
|
127
122
|
{
|
128
123
|
lexbor_array_t *array = nl_rb_node_set_unwrap(self);
|
129
|
-
if (offset >= (long)array->length || abs((int)offset) > (long)array->length)
|
130
|
-
{
|
124
|
+
if (offset >= (long)array->length || abs((int)offset) > (long)array->length) {
|
131
125
|
return Qnil;
|
132
126
|
}
|
133
127
|
|
134
|
-
if (offset < 0)
|
135
|
-
{
|
128
|
+
if (offset < 0) {
|
136
129
|
offset += array->length;
|
137
130
|
}
|
138
131
|
|
@@ -145,35 +138,28 @@ nl_node_set_subseq(VALUE self, long beg, long len)
|
|
145
138
|
{
|
146
139
|
lexbor_array_t *old_array = nl_rb_node_set_unwrap(self);
|
147
140
|
|
148
|
-
if (beg > (long)old_array->length)
|
149
|
-
{
|
141
|
+
if (beg > (long)old_array->length) {
|
150
142
|
return Qnil;
|
151
143
|
}
|
152
|
-
if (beg < 0 || len < 0)
|
153
|
-
{
|
144
|
+
if (beg < 0 || len < 0) {
|
154
145
|
return Qnil;
|
155
146
|
}
|
156
147
|
|
157
|
-
if ((beg + len) > (long)old_array->length)
|
158
|
-
{
|
148
|
+
if ((beg + len) > (long)old_array->length) {
|
159
149
|
len = old_array->length - beg;
|
160
150
|
}
|
161
151
|
|
162
152
|
lexbor_array_t *new_array = lexbor_array_create();
|
163
|
-
if (len > 0)
|
164
|
-
{
|
153
|
+
if (len > 0) {
|
165
154
|
lxb_status_t status = lexbor_array_init(new_array, len);
|
166
|
-
if (status != LXB_STATUS_OK)
|
167
|
-
{
|
155
|
+
if (status != LXB_STATUS_OK) {
|
168
156
|
nl_raise_lexbor_error(status);
|
169
157
|
}
|
170
158
|
}
|
171
159
|
|
172
|
-
for (long j = beg; j < beg + len; ++j)
|
173
|
-
{
|
160
|
+
for (long j = beg; j < beg + len; ++j) {
|
174
161
|
lxb_status_t status = lexbor_array_push(new_array, old_array->list[j]);
|
175
|
-
if (status != LXB_STATUS_OK)
|
176
|
-
{
|
162
|
+
if (status != LXB_STATUS_OK) {
|
177
163
|
nl_raise_lexbor_error(status);
|
178
164
|
}
|
179
165
|
}
|
@@ -188,31 +174,26 @@ nl_node_set_slice(int argc, VALUE *argv, VALUE self)
|
|
188
174
|
|
189
175
|
lexbor_array_t *array = nl_rb_node_set_unwrap(self);
|
190
176
|
|
191
|
-
if (argc == 2)
|
192
|
-
{
|
177
|
+
if (argc == 2) {
|
193
178
|
beg = NUM2LONG(argv[0]);
|
194
179
|
len = NUM2LONG(argv[1]);
|
195
|
-
if (beg < 0)
|
196
|
-
{
|
180
|
+
if (beg < 0) {
|
197
181
|
beg += array->length;
|
198
182
|
}
|
199
183
|
return nl_node_set_subseq(self, beg, len);
|
200
184
|
}
|
201
185
|
|
202
|
-
if (argc != 1)
|
203
|
-
{
|
186
|
+
if (argc != 1) {
|
204
187
|
rb_scan_args(argc, argv, "11", NULL, NULL);
|
205
188
|
}
|
206
189
|
arg = argv[0];
|
207
190
|
|
208
|
-
if (FIXNUM_P(arg))
|
209
|
-
{
|
191
|
+
if (FIXNUM_P(arg)) {
|
210
192
|
return nl_node_set_index_at(self, FIX2LONG(arg));
|
211
193
|
}
|
212
194
|
|
213
195
|
/* if arg is Range */
|
214
|
-
switch (rb_range_beg_len(arg, &beg, &len, array->length, 0))
|
215
|
-
{
|
196
|
+
switch (rb_range_beg_len(arg, &beg, &len, array->length, 0)) {
|
216
197
|
case Qfalse:
|
217
198
|
break;
|
218
199
|
case Qnil:
|
@@ -231,8 +212,7 @@ nl_node_set_to_array(VALUE self)
|
|
231
212
|
|
232
213
|
VALUE list = rb_ary_new2(array->length);
|
233
214
|
VALUE doc = nl_rb_document_get(self);
|
234
|
-
for (size_t i = 0; i < array->length; i++)
|
235
|
-
{
|
215
|
+
for (size_t i = 0; i < array->length; i++) {
|
236
216
|
lxb_dom_node_t *node = (lxb_dom_node_t *)array->list[i];
|
237
217
|
VALUE rb_node = nl_rb_node_create(node, doc);
|
238
218
|
rb_ary_push(list, rb_node);
|
@@ -244,31 +224,27 @@ nl_node_set_to_array(VALUE self)
|
|
244
224
|
static VALUE
|
245
225
|
nl_node_set_union(VALUE self, VALUE other)
|
246
226
|
{
|
247
|
-
if (!rb_obj_is_kind_of(other, cNokolexborNodeSet))
|
248
|
-
{
|
227
|
+
if (!rb_obj_is_kind_of(other, cNokolexborNodeSet)) {
|
249
228
|
rb_raise(rb_eArgError, "Parameter must be a Nokolexbor::NodeSet");
|
250
229
|
}
|
251
230
|
|
252
231
|
lexbor_array_t *self_array = nl_rb_node_set_unwrap(self);
|
253
232
|
lexbor_array_t *other_array = nl_rb_node_set_unwrap(other);
|
254
233
|
|
255
|
-
if (self_array->length + other_array->length == 0)
|
256
|
-
{
|
234
|
+
if (self_array->length + other_array->length == 0) {
|
257
235
|
return nl_rb_node_set_create_with_data(NULL, nl_rb_document_get(self));
|
258
236
|
}
|
259
237
|
|
260
238
|
lexbor_array_t *new_array = lexbor_array_create();
|
261
239
|
lxb_status_t status = lexbor_array_init(new_array, self_array->length + other_array->length);
|
262
|
-
if (status != LXB_STATUS_OK)
|
263
|
-
{
|
240
|
+
if (status != LXB_STATUS_OK) {
|
264
241
|
nl_raise_lexbor_error(status);
|
265
242
|
}
|
266
243
|
|
267
244
|
memcpy(new_array->list, self_array->list, sizeof(lxb_dom_node_t *) * self_array->length);
|
268
245
|
new_array->length = self_array->length;
|
269
246
|
|
270
|
-
for (size_t i = 0; i < other_array->length; i++)
|
271
|
-
{
|
247
|
+
for (size_t i = 0; i < other_array->length; i++) {
|
272
248
|
lexbor_array_push_unique(new_array, other_array->list[i]);
|
273
249
|
}
|
274
250
|
|
@@ -279,40 +255,33 @@ static lxb_status_t
|
|
279
255
|
nl_node_set_find(VALUE self, VALUE selector, lxb_selectors_cb_f cb, void *ctx)
|
280
256
|
{
|
281
257
|
lxb_dom_document_t *doc = nl_rb_document_unwrap(nl_rb_document_get(self));
|
282
|
-
if (doc == NULL)
|
283
|
-
{
|
258
|
+
if (doc == NULL) {
|
284
259
|
rb_raise(rb_eRuntimeError, "Error getting document");
|
285
260
|
}
|
286
261
|
// Wrap direct children with a temporary fragment so that they can be searched
|
287
262
|
lxb_dom_document_fragment_t *frag = lxb_dom_document_fragment_interface_create(doc);
|
288
|
-
if (frag == NULL)
|
289
|
-
{
|
263
|
+
if (frag == NULL) {
|
290
264
|
rb_raise(rb_eRuntimeError, "Error creating document fragment");
|
291
265
|
}
|
292
266
|
lexbor_array_t *array = nl_rb_node_set_unwrap(self);
|
293
267
|
|
294
268
|
lexbor_array_t *backup_array = lexbor_array_create();
|
295
|
-
if (array->length > 0)
|
296
|
-
{
|
269
|
+
if (array->length > 0) {
|
297
270
|
lxb_status_t status = lexbor_array_init(backup_array, array->length);
|
298
|
-
if (status != LXB_STATUS_OK)
|
299
|
-
{
|
271
|
+
if (status != LXB_STATUS_OK) {
|
300
272
|
nl_raise_lexbor_error(status);
|
301
273
|
}
|
302
274
|
}
|
303
275
|
// Backup original node data and re-group them into a fragment
|
304
|
-
for (size_t i = 0; i < array->length; i++)
|
305
|
-
{
|
276
|
+
for (size_t i = 0; i < array->length; i++) {
|
306
277
|
lxb_dom_node_t *node = (lxb_dom_node_t *)array->list[i];
|
307
278
|
lxb_dom_node_t *backup_node = malloc(sizeof(lxb_dom_node_t));
|
308
|
-
if (backup_node == NULL)
|
309
|
-
{
|
279
|
+
if (backup_node == NULL) {
|
310
280
|
nl_raise_lexbor_error(LXB_STATUS_ERROR_MEMORY_ALLOCATION);
|
311
281
|
}
|
312
282
|
memcpy(backup_node, node, sizeof(lxb_dom_node_t));
|
313
283
|
lxb_status_t status = lexbor_array_push(backup_array, backup_node);
|
314
|
-
if (status != LXB_STATUS_OK)
|
315
|
-
{
|
284
|
+
if (status != LXB_STATUS_OK) {
|
316
285
|
nl_raise_lexbor_error(LXB_STATUS_ERROR_MEMORY_ALLOCATION);
|
317
286
|
}
|
318
287
|
lxb_dom_node_insert_child(&frag->node, node);
|
@@ -323,8 +292,7 @@ nl_node_set_find(VALUE self, VALUE selector, lxb_selectors_cb_f cb, void *ctx)
|
|
323
292
|
|
324
293
|
lxb_dom_document_fragment_interface_destroy(frag);
|
325
294
|
// Restore original node data
|
326
|
-
for (size_t i = 0; i < array->length; i++)
|
327
|
-
{
|
295
|
+
for (size_t i = 0; i < array->length; i++) {
|
328
296
|
memcpy(array->list[i], backup_array->list[i], sizeof(lxb_dom_node_t));
|
329
297
|
free(backup_array->list[i]);
|
330
298
|
}
|
@@ -341,19 +309,17 @@ nl_node_set_at_css(VALUE self, VALUE selector)
|
|
341
309
|
|
342
310
|
lxb_status_t status = nl_node_set_find(self, selector, nl_node_at_css_callback, array);
|
343
311
|
|
344
|
-
if (status != LXB_STATUS_OK)
|
345
|
-
{
|
312
|
+
if (status != LXB_STATUS_OK) {
|
346
313
|
lexbor_array_destroy(array, true);
|
347
314
|
nl_raise_lexbor_error(status);
|
348
315
|
}
|
349
316
|
|
350
|
-
if (array->length == 0)
|
351
|
-
{
|
317
|
+
if (array->length == 0) {
|
352
318
|
lexbor_array_destroy(array, true);
|
353
319
|
return Qnil;
|
354
320
|
}
|
355
321
|
|
356
|
-
|
322
|
+
nl_sort_nodes_if_necessary(selector, doc, array);
|
357
323
|
|
358
324
|
VALUE ret = nl_rb_node_create(array->list[0], nl_rb_document_get(self));
|
359
325
|
|
@@ -369,13 +335,12 @@ nl_node_set_css(VALUE self, VALUE selector)
|
|
369
335
|
lxb_dom_document_t *doc = nl_rb_document_unwrap(nl_rb_document_get(self));
|
370
336
|
|
371
337
|
lxb_status_t status = nl_node_set_find(self, selector, nl_node_css_callback, array);
|
372
|
-
if (status != LXB_STATUS_OK)
|
373
|
-
{
|
338
|
+
if (status != LXB_STATUS_OK) {
|
374
339
|
lexbor_array_destroy(array, true);
|
375
340
|
nl_raise_lexbor_error(status);
|
376
341
|
}
|
377
342
|
|
378
|
-
|
343
|
+
nl_sort_nodes_if_necessary(selector, doc, array);
|
379
344
|
|
380
345
|
return nl_rb_node_set_create_with_data(array, nl_rb_document_get(self));
|
381
346
|
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#include "nokolexbor.h"
|
2
|
+
|
3
|
+
VALUE cNokolexborText;
|
4
|
+
extern VALUE cNokolexborCharacterData;
|
5
|
+
extern VALUE mNokolexbor;
|
6
|
+
|
7
|
+
static VALUE
|
8
|
+
nl_text_new(int argc, VALUE *argv, VALUE klass)
|
9
|
+
{
|
10
|
+
lxb_dom_document_t *document;
|
11
|
+
VALUE rb_text;
|
12
|
+
VALUE rb_document;
|
13
|
+
VALUE rest;
|
14
|
+
|
15
|
+
rb_scan_args(argc, argv, "2*", &rb_text, &rb_document, &rest);
|
16
|
+
|
17
|
+
if (!rb_obj_is_kind_of(rb_document, cNokolexborDocument)) {
|
18
|
+
rb_raise(rb_eArgError, "Document must be a Nokolexbor::Document");
|
19
|
+
}
|
20
|
+
|
21
|
+
document = nl_rb_document_unwrap(rb_document);
|
22
|
+
|
23
|
+
const char* c_text = StringValuePtr(rb_text);
|
24
|
+
size_t text_len = RSTRING_LEN(rb_text);
|
25
|
+
lxb_dom_text_t *element = lxb_dom_document_create_text_node(document, (const lxb_char_t *)c_text, text_len);
|
26
|
+
if (element == NULL) {
|
27
|
+
rb_raise(rb_eRuntimeError, "Error creating text node");
|
28
|
+
}
|
29
|
+
|
30
|
+
VALUE rb_node = nl_rb_node_create(&element->char_data.node, rb_document);
|
31
|
+
|
32
|
+
if (rb_block_given_p()) {
|
33
|
+
rb_yield(rb_node);
|
34
|
+
}
|
35
|
+
|
36
|
+
return rb_node;
|
37
|
+
}
|
38
|
+
|
39
|
+
void Init_nl_text(void)
|
40
|
+
{
|
41
|
+
cNokolexborText = rb_define_class_under(mNokolexbor, "Text", cNokolexborCharacterData);
|
42
|
+
|
43
|
+
rb_define_singleton_method(cNokolexborText, "new", nl_text_new, -1);
|
44
|
+
}
|
@@ -1,11 +1,11 @@
|
|
1
|
-
#include <ruby.h>
|
2
|
-
#include <ruby/util.h>
|
3
|
-
#include "nokolexbor.h"
|
4
1
|
#include "libxml.h"
|
5
2
|
#include "libxml/globals.h"
|
3
|
+
#include "libxml/parserInternals.h"
|
6
4
|
#include "libxml/xpath.h"
|
7
5
|
#include "libxml/xpathInternals.h"
|
8
|
-
#include "
|
6
|
+
#include "nokolexbor.h"
|
7
|
+
#include <ruby.h>
|
8
|
+
#include <ruby/util.h>
|
9
9
|
|
10
10
|
#define RBSTR_OR_QNIL(_str) (_str ? rb_utf8_str_new_cstr(_str) : Qnil)
|
11
11
|
|
@@ -18,7 +18,7 @@ VALUE cNokolexborXpathSyntaxError;
|
|
18
18
|
static void
|
19
19
|
free_xml_xpath_context(xmlXPathContextPtr ctx)
|
20
20
|
{
|
21
|
-
|
21
|
+
nl_xmlXPathFreeContext(ctx);
|
22
22
|
}
|
23
23
|
|
24
24
|
/*
|
@@ -33,9 +33,9 @@ nl_xpath_context_register_ns(VALUE self, VALUE prefix, VALUE uri)
|
|
33
33
|
xmlXPathContextPtr ctx;
|
34
34
|
Data_Get_Struct(self, xmlXPathContext, ctx);
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
nl_xmlXPathRegisterNs(ctx,
|
37
|
+
(const xmlChar *)StringValueCStr(prefix),
|
38
|
+
(const xmlChar *)StringValueCStr(uri));
|
39
39
|
return self;
|
40
40
|
}
|
41
41
|
|
@@ -52,11 +52,11 @@ nl_xpath_context_register_variable(VALUE self, VALUE name, VALUE value)
|
|
52
52
|
xmlXPathObjectPtr xmlValue;
|
53
53
|
Data_Get_Struct(self, xmlXPathContext, ctx);
|
54
54
|
|
55
|
-
xmlValue =
|
55
|
+
xmlValue = nl_xmlXPathNewCString(StringValueCStr(value));
|
56
56
|
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
nl_xmlXPathRegisterVariable(ctx,
|
58
|
+
(const xmlChar *)StringValueCStr(name),
|
59
|
+
xmlValue);
|
60
60
|
|
61
61
|
return self;
|
62
62
|
}
|
@@ -70,28 +70,23 @@ xpath2ruby(xmlXPathObjectPtr c_xpath_object, xmlXPathContextPtr ctx, VALUE rb_do
|
|
70
70
|
{
|
71
71
|
VALUE rb_retval;
|
72
72
|
|
73
|
-
switch (c_xpath_object->type)
|
74
|
-
{
|
73
|
+
switch (c_xpath_object->type) {
|
75
74
|
case XPATH_STRING:
|
76
75
|
rb_retval = rb_utf8_str_new_cstr((const char *)c_xpath_object->stringval);
|
77
|
-
|
76
|
+
nl_xmlFree(c_xpath_object->stringval);
|
78
77
|
return rb_retval;
|
79
78
|
|
80
|
-
case XPATH_NODESET:
|
81
|
-
|
82
|
-
if (c_xpath_object->nodesetval == NULL)
|
83
|
-
{
|
79
|
+
case XPATH_NODESET: {
|
80
|
+
if (c_xpath_object->nodesetval == NULL) {
|
84
81
|
return nl_rb_node_set_create_with_data(NULL, rb_document);
|
85
82
|
}
|
86
|
-
if (c_xpath_object->nodesetval->nodeNr == 0)
|
87
|
-
{
|
83
|
+
if (c_xpath_object->nodesetval->nodeNr == 0) {
|
88
84
|
return nl_rb_node_set_create_with_data(NULL, rb_document);
|
89
85
|
}
|
90
86
|
|
91
87
|
lexbor_array_t *array = lexbor_array_create();
|
92
88
|
lxb_status_t status = lexbor_array_init(array, c_xpath_object->nodesetval->nodeNr);
|
93
|
-
if (status != LXB_STATUS_OK)
|
94
|
-
{
|
89
|
+
if (status != LXB_STATUS_OK) {
|
95
90
|
nl_raise_lexbor_error(status);
|
96
91
|
}
|
97
92
|
memcpy(array->list, c_xpath_object->nodesetval->nodeTab, sizeof(lxb_dom_node_t *) * c_xpath_object->nodesetval->nodeNr);
|
@@ -122,8 +117,7 @@ nl_xpath_wrap_syntax_error(xmlErrorPtr error)
|
|
122
117
|
&msg,
|
123
118
|
cNokolexborXpathSyntaxError);
|
124
119
|
|
125
|
-
if (error)
|
126
|
-
{
|
120
|
+
if (error) {
|
127
121
|
rb_iv_set(e, "@domain", INT2NUM(error->domain));
|
128
122
|
rb_iv_set(e, "@code", INT2NUM(error->code));
|
129
123
|
rb_iv_set(e, "@level", INT2NUM((short)error->level));
|
@@ -182,8 +176,7 @@ nl_xpath_context_evaluate(int argc, VALUE *argv, VALUE self)
|
|
182
176
|
|
183
177
|
Data_Get_Struct(self, xmlXPathContext, ctx);
|
184
178
|
|
185
|
-
if (rb_scan_args(argc, argv, "11", &search_path, &xpath_handler) == 1)
|
186
|
-
{
|
179
|
+
if (rb_scan_args(argc, argv, "11", &search_path, &xpath_handler) == 1) {
|
187
180
|
xpath_handler = Qnil;
|
188
181
|
}
|
189
182
|
|
@@ -192,30 +185,28 @@ nl_xpath_context_evaluate(int argc, VALUE *argv, VALUE self)
|
|
192
185
|
// if (Qnil != xpath_handler) {
|
193
186
|
// /* FIXME: not sure if this is the correct place to shove private data. */
|
194
187
|
// ctx->userData = (void *)xpath_handler;
|
195
|
-
//
|
188
|
+
// nl_xmlXPathRegisterFuncLookup(ctx, handler_lookup, (void *)xpath_handler);
|
196
189
|
// }
|
197
190
|
|
198
|
-
|
199
|
-
|
191
|
+
nl_xmlSetStructuredErrorFunc((void *)errors, nl_xpath_error_array_pusher);
|
192
|
+
nl_xmlSetGenericErrorFunc((void *)errors, nl_xpath_generic_exception_pusher);
|
200
193
|
|
201
|
-
xpath =
|
194
|
+
xpath = nl_xmlXPathEvalExpression(query, ctx);
|
202
195
|
|
203
|
-
|
204
|
-
|
196
|
+
nl_xmlSetStructuredErrorFunc(NULL, NULL);
|
197
|
+
nl_xmlSetGenericErrorFunc(NULL, NULL);
|
205
198
|
|
206
|
-
if (xpath == NULL)
|
207
|
-
|
208
|
-
xmlXPathFreeObject(xpath);
|
199
|
+
if (xpath == NULL) {
|
200
|
+
nl_xmlXPathFreeObject(xpath);
|
209
201
|
rb_exc_raise(rb_ary_entry(errors, 0));
|
210
202
|
}
|
211
203
|
|
212
204
|
retval = xpath2ruby(xpath, ctx, nl_rb_document_get(self));
|
213
|
-
if (retval == Qundef)
|
214
|
-
{
|
205
|
+
if (retval == Qundef) {
|
215
206
|
retval = rb_funcall(cNokolexborNodeSet, rb_intern("new"), 1, rb_ary_new());
|
216
207
|
}
|
217
208
|
|
218
|
-
|
209
|
+
nl_xmlXPathFreeObject(xpath);
|
219
210
|
|
220
211
|
return retval;
|
221
212
|
}
|
@@ -234,7 +225,7 @@ nl_xpath_context_new(VALUE klass, VALUE rb_node)
|
|
234
225
|
|
235
226
|
lxb_dom_node_t *node = nl_rb_node_unwrap(rb_node);
|
236
227
|
|
237
|
-
ctx =
|
228
|
+
ctx = nl_xmlXPathNewContext(node->owner_document);
|
238
229
|
ctx->node = node;
|
239
230
|
|
240
231
|
self = Data_Wrap_Struct(klass, 0, free_xml_xpath_context, ctx);
|
@@ -246,9 +237,9 @@ nl_xpath_context_new(VALUE klass, VALUE rb_node)
|
|
246
237
|
void Init_nl_xpath_context(void)
|
247
238
|
{
|
248
239
|
#ifndef NOKOLEXBOR_ASAN
|
249
|
-
|
240
|
+
nl_xmlMemSetup((xmlFreeFunc)ruby_xfree, (xmlMallocFunc)ruby_xmalloc, (xmlReallocFunc)ruby_xrealloc, ruby_strdup);
|
250
241
|
#else
|
251
|
-
|
242
|
+
nl_xmlMemSetup((xmlFreeFunc)free, (xmlMallocFunc)malloc, (xmlReallocFunc)realloc, strdup);
|
252
243
|
#endif
|
253
244
|
|
254
245
|
cNokolexborXpathContext = rb_define_class_under(mNokolexbor, "XPathContext", rb_cObject);
|
data/ext/nokolexbor/nokolexbor.c
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
VALUE mNokolexbor;
|
4
4
|
VALUE eLexborError;
|
5
|
+
VALUE eLexborSyntaxError;
|
5
6
|
|
6
7
|
void nl_raise_lexbor_error(lxb_status_t error)
|
7
8
|
{
|
8
|
-
switch (error)
|
9
|
-
{
|
9
|
+
switch (error) {
|
10
10
|
case LXB_STATUS_ERROR:
|
11
11
|
rb_raise(eLexborError, "LXB_STATUS_ERROR");
|
12
12
|
case LXB_STATUS_ERROR_MEMORY_ALLOCATION:
|
@@ -30,7 +30,7 @@ void nl_raise_lexbor_error(lxb_status_t error)
|
|
30
30
|
case LXB_STATUS_ERROR_UNEXPECTED_RESULT:
|
31
31
|
rb_raise(eLexborError, "LXB_STATUS_ERROR_UNEXPECTED_RESULT");
|
32
32
|
case LXB_STATUS_ERROR_UNEXPECTED_DATA:
|
33
|
-
rb_raise(
|
33
|
+
rb_raise(eLexborSyntaxError, "LXB_STATUS_ERROR_UNEXPECTED_DATA");
|
34
34
|
case LXB_STATUS_ERROR_OVERFLOW:
|
35
35
|
rb_raise(eLexborError, "LXB_STATUS_ERROR_OVERFLOW");
|
36
36
|
case LXB_STATUS_CONTINUE:
|
@@ -56,8 +56,12 @@ void Init_nokolexbor(void)
|
|
56
56
|
{
|
57
57
|
mNokolexbor = rb_define_module("Nokolexbor");
|
58
58
|
eLexborError = rb_define_class_under(mNokolexbor, "LexborError", rb_eStandardError);
|
59
|
+
eLexborSyntaxError = rb_define_class_under(mNokolexbor, "LexborSyntaxError", eLexborError);
|
59
60
|
Init_nl_node();
|
60
61
|
Init_nl_document();
|
62
|
+
Init_nl_text();
|
63
|
+
Init_nl_comment();
|
64
|
+
Init_nl_cdata();
|
61
65
|
Init_nl_node_set();
|
62
66
|
Init_nl_xpath_context();
|
63
67
|
}
|
data/ext/nokolexbor/nokolexbor.h
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
|
4
4
|
#include <ruby.h>
|
5
5
|
|
6
|
-
#include <lexbor/html/html.h>
|
7
6
|
#include <lexbor/css/css.h>
|
7
|
+
#include <lexbor/html/html.h>
|
8
8
|
#include <lexbor/selectors/selectors.h>
|
9
9
|
|
10
10
|
extern VALUE cNokolexborDocument;
|
@@ -12,6 +12,9 @@ extern VALUE cNokolexborDocument;
|
|
12
12
|
void Init_nl_document(void);
|
13
13
|
void Init_nl_node(void);
|
14
14
|
void Init_nl_node_set(void);
|
15
|
+
void Init_nl_text(void);
|
16
|
+
void Init_nl_comment(void);
|
17
|
+
void Init_nl_cdata(void);
|
15
18
|
void Init_nl_xpath_context(void);
|
16
19
|
|
17
20
|
void nl_raise_lexbor_error(lxb_status_t error);
|
@@ -21,14 +24,13 @@ VALUE nl_rb_node_set_create_with_data(lexbor_array_t *array, VALUE rb_document);
|
|
21
24
|
|
22
25
|
lxb_inline VALUE nl_rb_document_get(VALUE rb_node_or_doc)
|
23
26
|
{
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
return rb_iv_get(rb_node_or_doc, "@document");
|
27
|
+
if (rb_obj_is_kind_of(rb_node_or_doc, cNokolexborDocument)) {
|
28
|
+
return rb_node_or_doc;
|
29
|
+
}
|
30
|
+
return rb_iv_get(rb_node_or_doc, "@document");
|
29
31
|
}
|
30
32
|
|
31
|
-
lxb_dom_document_t *
|
33
|
+
lxb_dom_document_t *nl_rb_document_unwrap(VALUE rb_doc);
|
32
34
|
|
33
35
|
const lxb_char_t *
|
34
36
|
lxb_dom_node_name_qualified(lxb_dom_node_t *node, size_t *len);
|
@@ -43,7 +43,7 @@ xmlBufIsEmpty(const xmlBufPtr buf);
|
|
43
43
|
XML_HIDDEN int
|
44
44
|
xmlBufAddLen(xmlBufPtr buf, size_t len);
|
45
45
|
|
46
|
-
/* const xmlChar *
|
46
|
+
/* const xmlChar * nl_xmlBufContent(const xmlBuf *buf); */
|
47
47
|
/* const xmlChar * xmlBufEnd(xmlBufPtr buf); */
|
48
48
|
|
49
49
|
XML_HIDDEN xmlChar *
|
@@ -5,17 +5,17 @@
|
|
5
5
|
#include "libxml/xmlversion.h"
|
6
6
|
|
7
7
|
XML_HIDDEN void
|
8
|
-
|
8
|
+
__nl_xmlRaiseError(xmlStructuredErrorFunc schannel,
|
9
9
|
xmlGenericErrorFunc channel, void *data, void *ctx,
|
10
10
|
void *nod, int domain, int code, xmlErrorLevel level,
|
11
11
|
const char *file, int line, const char *str1,
|
12
12
|
const char *str2, const char *str3, int int1, int col,
|
13
13
|
const char *msg, ...) LIBXML_ATTR_FORMAT(16,17);
|
14
14
|
XML_HIDDEN void
|
15
|
-
|
15
|
+
__nl_xmlSimpleError(int domain, int code, lxb_dom_node_t_ptr node,
|
16
16
|
const char *msg, const char *extra) LIBXML_ATTR_FORMAT(4,0);
|
17
17
|
XML_HIDDEN void
|
18
|
-
|
18
|
+
nl_xmlGenericErrorDefaultFunc(void *ctx, const char *msg,
|
19
19
|
...) LIBXML_ATTR_FORMAT(2,3);
|
20
20
|
|
21
21
|
#endif /* XML_ERROR_H_PRIVATE__ */
|
data/ext/nokolexbor/xml_SAX2.c
CHANGED
@@ -16,7 +16,7 @@
|
|
16
16
|
#include "libxml/globals.h"
|
17
17
|
|
18
18
|
/**
|
19
|
-
*
|
19
|
+
* nl_xmlSAX2GetPublicId:
|
20
20
|
* @ctx: the user data (XML parser context)
|
21
21
|
*
|
22
22
|
* Provides the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
|
@@ -24,14 +24,14 @@
|
|
24
24
|
* Returns a xmlChar *
|
25
25
|
*/
|
26
26
|
const xmlChar *
|
27
|
-
|
27
|
+
nl_xmlSAX2GetPublicId(void *ctx ATTRIBUTE_UNUSED)
|
28
28
|
{
|
29
29
|
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
|
30
30
|
return(NULL);
|
31
31
|
}
|
32
32
|
|
33
33
|
/**
|
34
|
-
*
|
34
|
+
* nl_xmlSAX2GetSystemId:
|
35
35
|
* @ctx: the user data (XML parser context)
|
36
36
|
*
|
37
37
|
* Provides the system ID, basically URL or filename e.g.
|
@@ -40,7 +40,7 @@ xmlSAX2GetPublicId(void *ctx ATTRIBUTE_UNUSED)
|
|
40
40
|
* Returns a xmlChar *
|
41
41
|
*/
|
42
42
|
const xmlChar *
|
43
|
-
|
43
|
+
nl_xmlSAX2GetSystemId(void *ctx)
|
44
44
|
{
|
45
45
|
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
46
46
|
if ((ctx == NULL) || (ctxt->input == NULL)) return(NULL);
|
@@ -48,7 +48,7 @@ xmlSAX2GetSystemId(void *ctx)
|
|
48
48
|
}
|
49
49
|
|
50
50
|
/**
|
51
|
-
*
|
51
|
+
* nl_xmlSAX2GetLineNumber:
|
52
52
|
* @ctx: the user data (XML parser context)
|
53
53
|
*
|
54
54
|
* Provide the line number of the current parsing point.
|
@@ -56,7 +56,7 @@ xmlSAX2GetSystemId(void *ctx)
|
|
56
56
|
* Returns an int
|
57
57
|
*/
|
58
58
|
int
|
59
|
-
|
59
|
+
nl_xmlSAX2GetLineNumber(void *ctx)
|
60
60
|
{
|
61
61
|
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
62
62
|
if ((ctx == NULL) || (ctxt->input == NULL)) return(0);
|
@@ -64,7 +64,7 @@ xmlSAX2GetLineNumber(void *ctx)
|
|
64
64
|
}
|
65
65
|
|
66
66
|
/**
|
67
|
-
*
|
67
|
+
* nl_xmlSAX2GetColumnNumber:
|
68
68
|
* @ctx: the user data (XML parser context)
|
69
69
|
*
|
70
70
|
* Provide the column number of the current parsing point.
|
@@ -72,7 +72,7 @@ xmlSAX2GetLineNumber(void *ctx)
|
|
72
72
|
* Returns an int
|
73
73
|
*/
|
74
74
|
int
|
75
|
-
|
75
|
+
nl_xmlSAX2GetColumnNumber(void *ctx)
|
76
76
|
{
|
77
77
|
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
78
78
|
if ((ctx == NULL) || (ctxt->input == NULL)) return(0);
|