mini-pro-gem 0.0.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.
Files changed (181) hide show
  1. checksums.yaml +7 -0
  2. data/mini-pro-gem.gemspec +12 -0
  3. data/nokogiri-1.19.4/Gemfile +40 -0
  4. data/nokogiri-1.19.4/LICENSE-DEPENDENCIES.md +2411 -0
  5. data/nokogiri-1.19.4/LICENSE.md +9 -0
  6. data/nokogiri-1.19.4/README.md +308 -0
  7. data/nokogiri-1.19.4/bin/nokogiri +131 -0
  8. data/nokogiri-1.19.4/dependencies.yml +31 -0
  9. data/nokogiri-1.19.4/ext/nokogiri/depend +38 -0
  10. data/nokogiri-1.19.4/ext/nokogiri/extconf.rb +1165 -0
  11. data/nokogiri-1.19.4/ext/nokogiri/gumbo.c +610 -0
  12. data/nokogiri-1.19.4/ext/nokogiri/html4_document.c +171 -0
  13. data/nokogiri-1.19.4/ext/nokogiri/html4_element_description.c +299 -0
  14. data/nokogiri-1.19.4/ext/nokogiri/html4_entity_lookup.c +37 -0
  15. data/nokogiri-1.19.4/ext/nokogiri/html4_sax_parser.c +40 -0
  16. data/nokogiri-1.19.4/ext/nokogiri/html4_sax_parser_context.c +98 -0
  17. data/nokogiri-1.19.4/ext/nokogiri/html4_sax_push_parser.c +96 -0
  18. data/nokogiri-1.19.4/ext/nokogiri/libxml2_polyfill.c +114 -0
  19. data/nokogiri-1.19.4/ext/nokogiri/nokogiri.c +297 -0
  20. data/nokogiri-1.19.4/ext/nokogiri/nokogiri.h +247 -0
  21. data/nokogiri-1.19.4/ext/nokogiri/test_global_handlers.c +40 -0
  22. data/nokogiri-1.19.4/ext/nokogiri/xml_attr.c +108 -0
  23. data/nokogiri-1.19.4/ext/nokogiri/xml_attribute_decl.c +70 -0
  24. data/nokogiri-1.19.4/ext/nokogiri/xml_cdata.c +62 -0
  25. data/nokogiri-1.19.4/ext/nokogiri/xml_comment.c +57 -0
  26. data/nokogiri-1.19.4/ext/nokogiri/xml_document.c +796 -0
  27. data/nokogiri-1.19.4/ext/nokogiri/xml_document_fragment.c +29 -0
  28. data/nokogiri-1.19.4/ext/nokogiri/xml_dtd.c +208 -0
  29. data/nokogiri-1.19.4/ext/nokogiri/xml_element_content.c +131 -0
  30. data/nokogiri-1.19.4/ext/nokogiri/xml_element_decl.c +69 -0
  31. data/nokogiri-1.19.4/ext/nokogiri/xml_encoding_handler.c +112 -0
  32. data/nokogiri-1.19.4/ext/nokogiri/xml_entity_decl.c +112 -0
  33. data/nokogiri-1.19.4/ext/nokogiri/xml_entity_reference.c +50 -0
  34. data/nokogiri-1.19.4/ext/nokogiri/xml_namespace.c +181 -0
  35. data/nokogiri-1.19.4/ext/nokogiri/xml_node.c +2523 -0
  36. data/nokogiri-1.19.4/ext/nokogiri/xml_node_set.c +518 -0
  37. data/nokogiri-1.19.4/ext/nokogiri/xml_processing_instruction.c +54 -0
  38. data/nokogiri-1.19.4/ext/nokogiri/xml_reader.c +777 -0
  39. data/nokogiri-1.19.4/ext/nokogiri/xml_relax_ng.c +149 -0
  40. data/nokogiri-1.19.4/ext/nokogiri/xml_sax_parser.c +403 -0
  41. data/nokogiri-1.19.4/ext/nokogiri/xml_sax_parser_context.c +396 -0
  42. data/nokogiri-1.19.4/ext/nokogiri/xml_sax_push_parser.c +206 -0
  43. data/nokogiri-1.19.4/ext/nokogiri/xml_schema.c +226 -0
  44. data/nokogiri-1.19.4/ext/nokogiri/xml_syntax_error.c +93 -0
  45. data/nokogiri-1.19.4/ext/nokogiri/xml_text.c +59 -0
  46. data/nokogiri-1.19.4/ext/nokogiri/xml_xpath_context.c +496 -0
  47. data/nokogiri-1.19.4/ext/nokogiri/xslt_stylesheet.c +457 -0
  48. data/nokogiri-1.19.4/gumbo-parser/CHANGES.md +63 -0
  49. data/nokogiri-1.19.4/gumbo-parser/Makefile +129 -0
  50. data/nokogiri-1.19.4/gumbo-parser/THANKS +27 -0
  51. data/nokogiri-1.19.4/gumbo-parser/src/Makefile +34 -0
  52. data/nokogiri-1.19.4/gumbo-parser/src/README.md +41 -0
  53. data/nokogiri-1.19.4/gumbo-parser/src/ascii.c +75 -0
  54. data/nokogiri-1.19.4/gumbo-parser/src/ascii.h +115 -0
  55. data/nokogiri-1.19.4/gumbo-parser/src/attribute.c +42 -0
  56. data/nokogiri-1.19.4/gumbo-parser/src/attribute.h +17 -0
  57. data/nokogiri-1.19.4/gumbo-parser/src/char_ref.c +22225 -0
  58. data/nokogiri-1.19.4/gumbo-parser/src/char_ref.h +29 -0
  59. data/nokogiri-1.19.4/gumbo-parser/src/char_ref.rl +2154 -0
  60. data/nokogiri-1.19.4/gumbo-parser/src/error.c +658 -0
  61. data/nokogiri-1.19.4/gumbo-parser/src/error.h +152 -0
  62. data/nokogiri-1.19.4/gumbo-parser/src/foreign_attrs.c +103 -0
  63. data/nokogiri-1.19.4/gumbo-parser/src/foreign_attrs.gperf +27 -0
  64. data/nokogiri-1.19.4/gumbo-parser/src/insertion_mode.h +33 -0
  65. data/nokogiri-1.19.4/gumbo-parser/src/macros.h +91 -0
  66. data/nokogiri-1.19.4/gumbo-parser/src/nokogiri_gumbo.h +953 -0
  67. data/nokogiri-1.19.4/gumbo-parser/src/parser.c +4932 -0
  68. data/nokogiri-1.19.4/gumbo-parser/src/parser.h +41 -0
  69. data/nokogiri-1.19.4/gumbo-parser/src/replacement.h +33 -0
  70. data/nokogiri-1.19.4/gumbo-parser/src/string_buffer.c +103 -0
  71. data/nokogiri-1.19.4/gumbo-parser/src/string_buffer.h +68 -0
  72. data/nokogiri-1.19.4/gumbo-parser/src/string_piece.c +48 -0
  73. data/nokogiri-1.19.4/gumbo-parser/src/svg_attrs.c +174 -0
  74. data/nokogiri-1.19.4/gumbo-parser/src/svg_attrs.gperf +77 -0
  75. data/nokogiri-1.19.4/gumbo-parser/src/svg_tags.c +137 -0
  76. data/nokogiri-1.19.4/gumbo-parser/src/svg_tags.gperf +55 -0
  77. data/nokogiri-1.19.4/gumbo-parser/src/tag.c +223 -0
  78. data/nokogiri-1.19.4/gumbo-parser/src/tag_lookup.c +382 -0
  79. data/nokogiri-1.19.4/gumbo-parser/src/tag_lookup.gperf +170 -0
  80. data/nokogiri-1.19.4/gumbo-parser/src/tag_lookup.h +13 -0
  81. data/nokogiri-1.19.4/gumbo-parser/src/token_buffer.c +79 -0
  82. data/nokogiri-1.19.4/gumbo-parser/src/token_buffer.h +71 -0
  83. data/nokogiri-1.19.4/gumbo-parser/src/token_type.h +17 -0
  84. data/nokogiri-1.19.4/gumbo-parser/src/tokenizer.c +3464 -0
  85. data/nokogiri-1.19.4/gumbo-parser/src/tokenizer.h +112 -0
  86. data/nokogiri-1.19.4/gumbo-parser/src/tokenizer_states.h +339 -0
  87. data/nokogiri-1.19.4/gumbo-parser/src/utf8.c +245 -0
  88. data/nokogiri-1.19.4/gumbo-parser/src/utf8.h +164 -0
  89. data/nokogiri-1.19.4/gumbo-parser/src/util.c +66 -0
  90. data/nokogiri-1.19.4/gumbo-parser/src/util.h +34 -0
  91. data/nokogiri-1.19.4/gumbo-parser/src/vector.c +111 -0
  92. data/nokogiri-1.19.4/gumbo-parser/src/vector.h +45 -0
  93. data/nokogiri-1.19.4/lib/nokogiri/class_resolver.rb +65 -0
  94. data/nokogiri-1.19.4/lib/nokogiri/css/node.rb +58 -0
  95. data/nokogiri-1.19.4/lib/nokogiri/css/parser.rb +772 -0
  96. data/nokogiri-1.19.4/lib/nokogiri/css/parser.y +277 -0
  97. data/nokogiri-1.19.4/lib/nokogiri/css/parser_extras.rb +36 -0
  98. data/nokogiri-1.19.4/lib/nokogiri/css/selector_cache.rb +38 -0
  99. data/nokogiri-1.19.4/lib/nokogiri/css/syntax_error.rb +9 -0
  100. data/nokogiri-1.19.4/lib/nokogiri/css/tokenizer.rb +155 -0
  101. data/nokogiri-1.19.4/lib/nokogiri/css/tokenizer.rex +57 -0
  102. data/nokogiri-1.19.4/lib/nokogiri/css/xpath_visitor.rb +376 -0
  103. data/nokogiri-1.19.4/lib/nokogiri/css.rb +132 -0
  104. data/nokogiri-1.19.4/lib/nokogiri/decorators/slop.rb +42 -0
  105. data/nokogiri-1.19.4/lib/nokogiri/encoding_handler.rb +57 -0
  106. data/nokogiri-1.19.4/lib/nokogiri/extension.rb +32 -0
  107. data/nokogiri-1.19.4/lib/nokogiri/gumbo.rb +15 -0
  108. data/nokogiri-1.19.4/lib/nokogiri/html.rb +48 -0
  109. data/nokogiri-1.19.4/lib/nokogiri/html4/builder.rb +37 -0
  110. data/nokogiri-1.19.4/lib/nokogiri/html4/document.rb +235 -0
  111. data/nokogiri-1.19.4/lib/nokogiri/html4/document_fragment.rb +166 -0
  112. data/nokogiri-1.19.4/lib/nokogiri/html4/element_description.rb +25 -0
  113. data/nokogiri-1.19.4/lib/nokogiri/html4/element_description_defaults.rb +2040 -0
  114. data/nokogiri-1.19.4/lib/nokogiri/html4/encoding_reader.rb +121 -0
  115. data/nokogiri-1.19.4/lib/nokogiri/html4/entity_lookup.rb +15 -0
  116. data/nokogiri-1.19.4/lib/nokogiri/html4/sax/parser.rb +48 -0
  117. data/nokogiri-1.19.4/lib/nokogiri/html4/sax/parser_context.rb +15 -0
  118. data/nokogiri-1.19.4/lib/nokogiri/html4/sax/push_parser.rb +37 -0
  119. data/nokogiri-1.19.4/lib/nokogiri/html4.rb +42 -0
  120. data/nokogiri-1.19.4/lib/nokogiri/html5/builder.rb +40 -0
  121. data/nokogiri-1.19.4/lib/nokogiri/html5/document.rb +199 -0
  122. data/nokogiri-1.19.4/lib/nokogiri/html5/document_fragment.rb +200 -0
  123. data/nokogiri-1.19.4/lib/nokogiri/html5/node.rb +103 -0
  124. data/nokogiri-1.19.4/lib/nokogiri/html5.rb +368 -0
  125. data/nokogiri-1.19.4/lib/nokogiri/jruby/dependencies.rb +3 -0
  126. data/nokogiri-1.19.4/lib/nokogiri/jruby/nokogiri_jars.rb +48 -0
  127. data/nokogiri-1.19.4/lib/nokogiri/syntax_error.rb +6 -0
  128. data/nokogiri-1.19.4/lib/nokogiri/version/constant.rb +6 -0
  129. data/nokogiri-1.19.4/lib/nokogiri/version/info.rb +234 -0
  130. data/nokogiri-1.19.4/lib/nokogiri/version.rb +4 -0
  131. data/nokogiri-1.19.4/lib/nokogiri/xml/attr.rb +66 -0
  132. data/nokogiri-1.19.4/lib/nokogiri/xml/attribute_decl.rb +22 -0
  133. data/nokogiri-1.19.4/lib/nokogiri/xml/builder.rb +494 -0
  134. data/nokogiri-1.19.4/lib/nokogiri/xml/cdata.rb +13 -0
  135. data/nokogiri-1.19.4/lib/nokogiri/xml/character_data.rb +9 -0
  136. data/nokogiri-1.19.4/lib/nokogiri/xml/document.rb +515 -0
  137. data/nokogiri-1.19.4/lib/nokogiri/xml/document_fragment.rb +276 -0
  138. data/nokogiri-1.19.4/lib/nokogiri/xml/dtd.rb +34 -0
  139. data/nokogiri-1.19.4/lib/nokogiri/xml/element_content.rb +46 -0
  140. data/nokogiri-1.19.4/lib/nokogiri/xml/element_decl.rb +17 -0
  141. data/nokogiri-1.19.4/lib/nokogiri/xml/entity_decl.rb +23 -0
  142. data/nokogiri-1.19.4/lib/nokogiri/xml/entity_reference.rb +20 -0
  143. data/nokogiri-1.19.4/lib/nokogiri/xml/namespace.rb +57 -0
  144. data/nokogiri-1.19.4/lib/nokogiri/xml/node/save_options.rb +76 -0
  145. data/nokogiri-1.19.4/lib/nokogiri/xml/node.rb +1701 -0
  146. data/nokogiri-1.19.4/lib/nokogiri/xml/node_set.rb +449 -0
  147. data/nokogiri-1.19.4/lib/nokogiri/xml/notation.rb +19 -0
  148. data/nokogiri-1.19.4/lib/nokogiri/xml/parse_options.rb +217 -0
  149. data/nokogiri-1.19.4/lib/nokogiri/xml/pp/character_data.rb +21 -0
  150. data/nokogiri-1.19.4/lib/nokogiri/xml/pp/node.rb +73 -0
  151. data/nokogiri-1.19.4/lib/nokogiri/xml/pp.rb +4 -0
  152. data/nokogiri-1.19.4/lib/nokogiri/xml/processing_instruction.rb +11 -0
  153. data/nokogiri-1.19.4/lib/nokogiri/xml/reader.rb +139 -0
  154. data/nokogiri-1.19.4/lib/nokogiri/xml/relax_ng.rb +75 -0
  155. data/nokogiri-1.19.4/lib/nokogiri/xml/sax/document.rb +258 -0
  156. data/nokogiri-1.19.4/lib/nokogiri/xml/sax/parser.rb +199 -0
  157. data/nokogiri-1.19.4/lib/nokogiri/xml/sax/parser_context.rb +129 -0
  158. data/nokogiri-1.19.4/lib/nokogiri/xml/sax/push_parser.rb +64 -0
  159. data/nokogiri-1.19.4/lib/nokogiri/xml/sax.rb +54 -0
  160. data/nokogiri-1.19.4/lib/nokogiri/xml/schema.rb +140 -0
  161. data/nokogiri-1.19.4/lib/nokogiri/xml/searchable.rb +274 -0
  162. data/nokogiri-1.19.4/lib/nokogiri/xml/syntax_error.rb +94 -0
  163. data/nokogiri-1.19.4/lib/nokogiri/xml/text.rb +11 -0
  164. data/nokogiri-1.19.4/lib/nokogiri/xml/xpath/syntax_error.rb +13 -0
  165. data/nokogiri-1.19.4/lib/nokogiri/xml/xpath.rb +21 -0
  166. data/nokogiri-1.19.4/lib/nokogiri/xml/xpath_context.rb +27 -0
  167. data/nokogiri-1.19.4/lib/nokogiri/xml.rb +65 -0
  168. data/nokogiri-1.19.4/lib/nokogiri/xslt/stylesheet.rb +54 -0
  169. data/nokogiri-1.19.4/lib/nokogiri/xslt.rb +138 -0
  170. data/nokogiri-1.19.4/lib/nokogiri.rb +128 -0
  171. data/nokogiri-1.19.4/lib/xsd/xmlparser/nokogiri.rb +105 -0
  172. data/nokogiri-1.19.4/patches/libxml2/0001-Remove-script-macro-support.patch +40 -0
  173. data/nokogiri-1.19.4/patches/libxml2/0002-Update-entities-to-remove-handling-of-ssi.patch +44 -0
  174. data/nokogiri-1.19.4/patches/libxml2/0009-allow-wildcard-namespaces.patch +77 -0
  175. data/nokogiri-1.19.4/patches/libxml2/0010-update-config.guess-and-config.sub-for-libxml2.patch +224 -0
  176. data/nokogiri-1.19.4/patches/libxml2/0011-rip-out-libxml2-s-libc_single_threaded-support.patch +30 -0
  177. data/nokogiri-1.19.4/patches/libxml2/0019-xpath-Use-separate-static-hash-table-for-standard-fu.patch +244 -0
  178. data/nokogiri-1.19.4/patches/libxslt/0001-update-config.guess-and-config.sub-for-libxslt.patch +224 -0
  179. data/nokogiri-1.19.4/ports/archives/libxml2-2.13.9.tar.xz +0 -0
  180. data/nokogiri-1.19.4/ports/archives/libxslt-1.1.43.tar.xz +0 -0
  181. metadata +220 -0
@@ -0,0 +1,496 @@
1
+ #include <nokogiri.h>
2
+
3
+ VALUE cNokogiriXmlXpathContext;
4
+
5
+ /*
6
+ * these constants have matching declarations in
7
+ * ext/java/nokogiri/internals/NokogiriNamespaceContext.java
8
+ */
9
+ static const xmlChar *NOKOGIRI_PREFIX = (const xmlChar *)"nokogiri";
10
+ static const xmlChar *NOKOGIRI_URI = (const xmlChar *)"http://www.nokogiri.org/default_ns/ruby/extensions_functions";
11
+ static const xmlChar *NOKOGIRI_BUILTIN_PREFIX = (const xmlChar *)"nokogiri-builtin";
12
+ static const xmlChar *NOKOGIRI_BUILTIN_URI = (const xmlChar *)"https://www.nokogiri.org/default_ns/ruby/builtins";
13
+
14
+ static void
15
+ _noko_xml_xpath_context_dmark(void *data)
16
+ {
17
+ xmlXPathContextPtr c_context = data;
18
+ if (c_context->doc && DOC_RUBY_OBJECT_TEST(c_context->doc)) {
19
+ rb_gc_mark(DOC_RUBY_OBJECT(c_context->doc));
20
+ }
21
+ }
22
+
23
+ static void
24
+ _noko_xml_xpath_context_dfree(void *data)
25
+ {
26
+ xmlXPathContextPtr c_context = data;
27
+ xmlXPathFreeContext(c_context);
28
+ }
29
+
30
+ static const rb_data_type_t _noko_xml_xpath_context_type = {
31
+ .wrap_struct_name = "xmlXPathContext",
32
+ .function = {
33
+ .dmark = _noko_xml_xpath_context_dmark,
34
+ .dfree = _noko_xml_xpath_context_dfree,
35
+ },
36
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
37
+ };
38
+
39
+ /* find a CSS class in an HTML element's `class` attribute */
40
+ static const xmlChar *
41
+ _noko_xml_xpath_context__css_class(const xmlChar *str, const xmlChar *val)
42
+ {
43
+ int val_len;
44
+
45
+ if (str == NULL) { return (NULL); }
46
+ if (val == NULL) { return (NULL); }
47
+
48
+ val_len = xmlStrlen(val);
49
+ if (val_len == 0) { return (str); }
50
+
51
+ while (*str != 0) {
52
+ if ((*str == *val) && !xmlStrncmp(str, val, val_len)) {
53
+ const xmlChar *next_byte = str + val_len;
54
+
55
+ /* only match if the next byte is whitespace or end of string */
56
+ if ((*next_byte == 0) || (IS_BLANK_CH(*next_byte))) {
57
+ return ((const xmlChar *)str);
58
+ }
59
+ }
60
+
61
+ /* advance str to whitespace */
62
+ while ((*str != 0) && !IS_BLANK_CH(*str)) {
63
+ str++;
64
+ }
65
+
66
+ /* advance str to start of next word or end of string */
67
+ while ((*str != 0) && IS_BLANK_CH(*str)) {
68
+ str++;
69
+ }
70
+ }
71
+
72
+ return (NULL);
73
+ }
74
+
75
+ /* xmlXPathFunction to wrap _noko_xml_xpath_context__css_class() */
76
+ static void
77
+ noko_xml_xpath_context_xpath_func_css_class(xmlXPathParserContextPtr ctxt, int nargs)
78
+ {
79
+ xmlXPathObjectPtr hay, needle;
80
+
81
+ CHECK_ARITY(2);
82
+
83
+ CAST_TO_STRING;
84
+ needle = valuePop(ctxt);
85
+ if ((needle == NULL) || (needle->type != XPATH_STRING)) {
86
+ xmlXPathFreeObject(needle);
87
+ XP_ERROR(XPATH_INVALID_TYPE);
88
+ }
89
+
90
+ CAST_TO_STRING;
91
+ hay = valuePop(ctxt);
92
+ if ((hay == NULL) || (hay->type != XPATH_STRING)) {
93
+ xmlXPathFreeObject(hay);
94
+ xmlXPathFreeObject(needle);
95
+ XP_ERROR(XPATH_INVALID_TYPE);
96
+ }
97
+
98
+ if (_noko_xml_xpath_context__css_class(hay->stringval, needle->stringval)) {
99
+ valuePush(ctxt, xmlXPathNewBoolean(1));
100
+ } else {
101
+ valuePush(ctxt, xmlXPathNewBoolean(0));
102
+ }
103
+
104
+ xmlXPathFreeObject(hay);
105
+ xmlXPathFreeObject(needle);
106
+ }
107
+
108
+
109
+ /* xmlXPathFunction to select nodes whose local name matches, for HTML5 CSS queries that should
110
+ * ignore namespaces */
111
+ static void
112
+ noko_xml_xpath_context_xpath_func_local_name_is(xmlXPathParserContextPtr ctxt, int nargs)
113
+ {
114
+ xmlXPathObjectPtr element_name;
115
+
116
+ assert(ctxt->context->node);
117
+
118
+ CHECK_ARITY(1);
119
+ CAST_TO_STRING;
120
+ CHECK_TYPE(XPATH_STRING);
121
+ element_name = valuePop(ctxt);
122
+
123
+ valuePush(
124
+ ctxt,
125
+ xmlXPathNewBoolean(xmlStrEqual(ctxt->context->node->name, element_name->stringval))
126
+ );
127
+
128
+ xmlXPathFreeObject(element_name);
129
+ }
130
+
131
+
132
+ /*
133
+ * call-seq:
134
+ * register_ns(prefix, uri) → Nokogiri::XML::XPathContext
135
+ *
136
+ * Register the namespace with +prefix+ and +uri+ for use in future queries.
137
+ * Passing a uri of +nil+ will unregister the namespace.
138
+ *
139
+ * [Returns] +self+
140
+ */
141
+ static VALUE
142
+ noko_xml_xpath_context_register_ns(VALUE rb_context, VALUE prefix, VALUE uri)
143
+ {
144
+ xmlXPathContextPtr c_context;
145
+ const xmlChar *ns_uri;
146
+
147
+ TypedData_Get_Struct(rb_context, xmlXPathContext, &_noko_xml_xpath_context_type, c_context);
148
+
149
+ if (NIL_P(uri)) {
150
+ ns_uri = NULL;
151
+ } else {
152
+ ns_uri = (const xmlChar *)StringValueCStr(uri);
153
+ }
154
+
155
+ xmlXPathRegisterNs(c_context, (const xmlChar *)StringValueCStr(prefix), ns_uri);
156
+
157
+ return rb_context;
158
+ }
159
+
160
+ /*
161
+ * call-seq:
162
+ * register_variable(name, value) → Nokogiri::XML::XPathContext
163
+ *
164
+ * Register the variable +name+ with +value+ for use in future queries.
165
+ * Passing a value of +nil+ will unregister the variable.
166
+ *
167
+ * [Returns] +self+
168
+ */
169
+ static VALUE
170
+ noko_xml_xpath_context_register_variable(VALUE rb_context, VALUE name, VALUE value)
171
+ {
172
+ xmlXPathContextPtr c_context;
173
+ xmlXPathObjectPtr xmlValue;
174
+
175
+ TypedData_Get_Struct(rb_context, xmlXPathContext, &_noko_xml_xpath_context_type, c_context);
176
+
177
+ if (NIL_P(value)) {
178
+ xmlValue = NULL;
179
+ } else {
180
+ xmlValue = xmlXPathNewCString(StringValueCStr(value));
181
+ }
182
+
183
+ xmlXPathRegisterVariable(c_context, (const xmlChar *)StringValueCStr(name), xmlValue);
184
+
185
+ return rb_context;
186
+ }
187
+
188
+
189
+ /*
190
+ * convert an XPath object into a Ruby object of the appropriate type.
191
+ * returns Qundef if no conversion was possible.
192
+ */
193
+ static VALUE
194
+ _noko_xml_xpath_context__xpath2ruby(xmlXPathObjectPtr c_xpath_object, xmlXPathContextPtr c_context)
195
+ {
196
+ VALUE rb_retval;
197
+
198
+ assert(c_context->doc);
199
+ assert(DOC_RUBY_OBJECT_TEST(c_context->doc));
200
+
201
+ switch (c_xpath_object->type) {
202
+ case XPATH_STRING:
203
+ rb_retval = NOKOGIRI_STR_NEW2(c_xpath_object->stringval);
204
+ xmlFree(c_xpath_object->stringval);
205
+ return rb_retval;
206
+
207
+ case XPATH_NODESET:
208
+ return noko_xml_node_set_wrap(
209
+ c_xpath_object->nodesetval,
210
+ DOC_RUBY_OBJECT(c_context->doc)
211
+ );
212
+
213
+ case XPATH_NUMBER:
214
+ return rb_float_new(c_xpath_object->floatval);
215
+
216
+ case XPATH_BOOLEAN:
217
+ return (c_xpath_object->boolval == 1) ? Qtrue : Qfalse;
218
+
219
+ default:
220
+ return Qundef;
221
+ }
222
+ }
223
+
224
+ void
225
+ Nokogiri_marshal_xpath_funcall_and_return_values(
226
+ xmlXPathParserContextPtr ctxt,
227
+ int argc,
228
+ VALUE rb_xpath_handler,
229
+ const char *method_name
230
+ )
231
+ {
232
+ VALUE rb_retval;
233
+ VALUE *argv;
234
+ VALUE rb_node_set = Qnil;
235
+ xmlNodeSetPtr c_node_set = NULL;
236
+ xmlXPathObjectPtr c_xpath_object;
237
+
238
+ assert(ctxt->context->doc);
239
+ assert(DOC_RUBY_OBJECT_TEST(ctxt->context->doc));
240
+
241
+ argv = (VALUE *)ruby_xcalloc((size_t)argc, sizeof(VALUE));
242
+ for (int j = 0 ; j < argc ; ++j) {
243
+ rb_gc_register_address(&argv[j]);
244
+ }
245
+
246
+ for (int j = argc - 1 ; j >= 0 ; --j) {
247
+ c_xpath_object = valuePop(ctxt);
248
+ argv[j] = _noko_xml_xpath_context__xpath2ruby(c_xpath_object, ctxt->context);
249
+ if (argv[j] == Qundef) {
250
+ argv[j] = NOKOGIRI_STR_NEW2(xmlXPathCastToString(c_xpath_object));
251
+ }
252
+ xmlXPathFreeNodeSetList(c_xpath_object);
253
+ }
254
+
255
+ rb_retval = rb_funcall2(
256
+ rb_xpath_handler,
257
+ rb_intern((const char *)method_name),
258
+ argc,
259
+ argv
260
+ );
261
+
262
+ for (int j = 0 ; j < argc ; ++j) {
263
+ rb_gc_unregister_address(&argv[j]);
264
+ }
265
+ ruby_xfree(argv);
266
+
267
+ switch (TYPE(rb_retval)) {
268
+ case T_FLOAT:
269
+ case T_BIGNUM:
270
+ case T_FIXNUM:
271
+ xmlXPathReturnNumber(ctxt, NUM2DBL(rb_retval));
272
+ break;
273
+ case T_STRING:
274
+ xmlXPathReturnString(ctxt, xmlCharStrdup(StringValueCStr(rb_retval)));
275
+ break;
276
+ case T_TRUE:
277
+ xmlXPathReturnTrue(ctxt);
278
+ break;
279
+ case T_FALSE:
280
+ xmlXPathReturnFalse(ctxt);
281
+ break;
282
+ case T_NIL:
283
+ break;
284
+ case T_ARRAY: {
285
+ VALUE construct_args[2] = { DOC_RUBY_OBJECT(ctxt->context->doc), rb_retval };
286
+ rb_node_set = rb_class_new_instance(2, construct_args, cNokogiriXmlNodeSet);
287
+ c_node_set = noko_xml_node_set_unwrap(rb_node_set);
288
+ xmlXPathReturnNodeSet(ctxt, xmlXPathNodeSetMerge(NULL, c_node_set));
289
+ }
290
+ break;
291
+ case T_DATA:
292
+ if (rb_obj_is_kind_of(rb_retval, cNokogiriXmlNodeSet)) {
293
+ c_node_set = noko_xml_node_set_unwrap(rb_retval);
294
+ /* Copy the node set, otherwise it will get GC'd. */
295
+ xmlXPathReturnNodeSet(ctxt, xmlXPathNodeSetMerge(NULL, c_node_set));
296
+ break;
297
+ }
298
+ default:
299
+ rb_raise(rb_eRuntimeError, "Invalid return type");
300
+ }
301
+ }
302
+
303
+ static void
304
+ _noko_xml_xpath_context__handler_invoker(xmlXPathParserContextPtr ctxt, int argc)
305
+ {
306
+ VALUE rb_xpath_handler = Qnil;
307
+ const char *method_name = NULL ;
308
+
309
+ assert(ctxt);
310
+ assert(ctxt->context);
311
+ assert(ctxt->context->userData);
312
+ assert(ctxt->context->function);
313
+
314
+ rb_xpath_handler = (VALUE)(ctxt->context->userData);
315
+ method_name = (const char *)(ctxt->context->function);
316
+
317
+ Nokogiri_marshal_xpath_funcall_and_return_values(
318
+ ctxt,
319
+ argc,
320
+ rb_xpath_handler,
321
+ method_name
322
+ );
323
+ }
324
+
325
+ static xmlXPathFunction
326
+ _noko_xml_xpath_context_handler_lookup(void *data, const xmlChar *c_name, const xmlChar *c_ns_uri)
327
+ {
328
+ VALUE rb_handler = (VALUE)data;
329
+ if (rb_respond_to(rb_handler, rb_intern((const char *)c_name))) {
330
+ if (c_ns_uri == NULL) {
331
+ NOKO_WARN_DEPRECATION("A custom XPath or CSS handler function named '%s' is being invoked without a namespace. Please update your query to reference this function as 'nokogiri:%s'. Invoking custom handler functions without a namespace is deprecated and will become an error in Nokogiri v1.17.0.",
332
+ c_name, c_name); // TODO deprecated in v1.15.0, remove in v1.19.0
333
+ }
334
+ return _noko_xml_xpath_context__handler_invoker;
335
+ }
336
+
337
+ return NULL;
338
+ }
339
+
340
+ PRINTFLIKE_DECL(2, 3)
341
+ static void
342
+ _noko_xml_xpath_context__generic_exception_pusher(void *data, const char *msg, ...)
343
+ {
344
+ VALUE rb_errors = (VALUE)data;
345
+ VALUE rb_message;
346
+ VALUE rb_exception;
347
+
348
+ Check_Type(rb_errors, T_ARRAY);
349
+
350
+ #ifdef TRUFFLERUBY_NOKOGIRI_SYSTEM_LIBRARIES
351
+ /* It is not currently possible to pass var args from native
352
+ functions to sulong, so we work around the issue here. */
353
+ rb_message = rb_sprintf("_noko_xml_xpath_context__generic_exception_pusher: %s", msg);
354
+ #else
355
+ va_list args;
356
+ va_start(args, msg);
357
+ rb_message = rb_vsprintf(msg, args);
358
+ va_end(args);
359
+ #endif
360
+
361
+ rb_exception = rb_exc_new_str(cNokogiriXmlXpathSyntaxError, rb_message);
362
+ rb_ary_push(rb_errors, rb_exception);
363
+ }
364
+
365
+ /*
366
+ * call-seq:
367
+ * evaluate(search_path, handler = nil) → Object
368
+ *
369
+ * Evaluate the +search_path+ query.
370
+ *
371
+ * [Returns] an object of the appropriate type for the query, which could be +NodeSet+, a +String+,
372
+ * a +Float+, or a boolean.
373
+ */
374
+ static VALUE
375
+ noko_xml_xpath_context_evaluate(int argc, VALUE *argv, VALUE rb_context)
376
+ {
377
+ xmlXPathContextPtr c_context;
378
+ VALUE rb_expression = Qnil;
379
+ VALUE rb_function_lookup_handler = Qnil;
380
+ xmlChar *c_expression_str = NULL;
381
+ VALUE rb_errors = rb_ary_new();
382
+ xmlXPathObjectPtr c_xpath_object;
383
+ VALUE rb_xpath_object = Qnil;
384
+
385
+ TypedData_Get_Struct(rb_context, xmlXPathContext, &_noko_xml_xpath_context_type, c_context);
386
+
387
+ rb_scan_args(argc, argv, "11", &rb_expression, &rb_function_lookup_handler);
388
+
389
+ c_expression_str = (xmlChar *)StringValueCStr(rb_expression);
390
+
391
+ if (Qnil != rb_function_lookup_handler) {
392
+ /* FIXME: not sure if this is the correct place to shove private data. */
393
+ c_context->userData = (void *)rb_function_lookup_handler;
394
+ xmlXPathRegisterFuncLookup(
395
+ c_context,
396
+ _noko_xml_xpath_context_handler_lookup,
397
+ (void *)rb_function_lookup_handler
398
+ );
399
+ }
400
+
401
+ /* TODO: use xmlXPathSetErrorHandler (as of 2.13.0) */
402
+ xmlSetStructuredErrorFunc((void *)rb_errors, noko__error_array_pusher);
403
+ xmlSetGenericErrorFunc((void *)rb_errors, _noko_xml_xpath_context__generic_exception_pusher);
404
+
405
+ c_xpath_object = xmlXPathEvalExpression(c_expression_str, c_context);
406
+
407
+ xmlSetStructuredErrorFunc(NULL, NULL);
408
+ xmlSetGenericErrorFunc(NULL, NULL);
409
+
410
+ xmlXPathRegisterFuncLookup(c_context, NULL, NULL);
411
+
412
+ if (c_xpath_object == NULL) {
413
+ rb_exc_raise(rb_ary_entry(rb_errors, 0));
414
+ }
415
+
416
+ rb_xpath_object = _noko_xml_xpath_context__xpath2ruby(c_xpath_object, c_context);
417
+ if (rb_xpath_object == Qundef) {
418
+ rb_xpath_object = noko_xml_node_set_wrap(NULL, DOC_RUBY_OBJECT(c_context->doc));
419
+ }
420
+
421
+ xmlXPathFreeNodeSetList(c_xpath_object);
422
+
423
+ return rb_xpath_object;
424
+ }
425
+
426
+ /*
427
+ * call-seq:
428
+ * new(node)
429
+ *
430
+ * Create a new XPathContext with +node+ as the context node.
431
+ */
432
+ static VALUE
433
+ noko_xml_xpath_context_new(VALUE klass, VALUE rb_node)
434
+ {
435
+ xmlNodePtr c_node;
436
+ xmlXPathContextPtr c_context;
437
+ VALUE rb_context;
438
+
439
+ Noko_Node_Get_Struct(rb_node, xmlNode, c_node);
440
+
441
+ #if LIBXML_VERSION < 21000
442
+ xmlXPathInit(); /* deprecated in 40483d0 */
443
+ #endif
444
+
445
+ c_context = xmlXPathNewContext(c_node->doc);
446
+ c_context->node = c_node;
447
+
448
+ xmlXPathRegisterNs(c_context, NOKOGIRI_PREFIX, NOKOGIRI_URI);
449
+ xmlXPathRegisterNs(c_context, NOKOGIRI_BUILTIN_PREFIX, NOKOGIRI_BUILTIN_URI);
450
+
451
+ xmlXPathRegisterFuncNS(c_context,
452
+ (const xmlChar *)"css-class", NOKOGIRI_BUILTIN_URI,
453
+ noko_xml_xpath_context_xpath_func_css_class);
454
+ xmlXPathRegisterFuncNS(c_context,
455
+ (const xmlChar *)"local-name-is", NOKOGIRI_BUILTIN_URI,
456
+ noko_xml_xpath_context_xpath_func_local_name_is);
457
+
458
+ rb_context = TypedData_Wrap_Struct(klass, &_noko_xml_xpath_context_type, c_context);
459
+
460
+ return rb_context;
461
+ }
462
+
463
+
464
+ /* :nodoc: */
465
+ static VALUE
466
+ noko_xml_xpath_context_set_node(VALUE rb_context, VALUE rb_node)
467
+ {
468
+ xmlNodePtr c_node;
469
+ xmlXPathContextPtr c_context;
470
+
471
+ TypedData_Get_Struct(rb_context, xmlXPathContext, &_noko_xml_xpath_context_type, c_context);
472
+ Noko_Node_Get_Struct(rb_node, xmlNode, c_node);
473
+
474
+ c_context->doc = c_node->doc;
475
+ c_context->node = c_node;
476
+
477
+ return rb_node;
478
+ }
479
+
480
+ void
481
+ noko_init_xml_xpath_context(void)
482
+ {
483
+ /*
484
+ * XPathContext is the entry point for searching a +Document+ by using XPath.
485
+ */
486
+ cNokogiriXmlXpathContext = rb_define_class_under(mNokogiriXml, "XPathContext", rb_cObject);
487
+
488
+ rb_undef_alloc_func(cNokogiriXmlXpathContext);
489
+
490
+ rb_define_singleton_method(cNokogiriXmlXpathContext, "new", noko_xml_xpath_context_new, 1);
491
+
492
+ rb_define_method(cNokogiriXmlXpathContext, "evaluate", noko_xml_xpath_context_evaluate, -1);
493
+ rb_define_method(cNokogiriXmlXpathContext, "register_variable", noko_xml_xpath_context_register_variable, 2);
494
+ rb_define_method(cNokogiriXmlXpathContext, "register_ns", noko_xml_xpath_context_register_ns, 2);
495
+ rb_define_method(cNokogiriXmlXpathContext, "node=", noko_xml_xpath_context_set_node, 1);
496
+ }