nokolexbor 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (486) hide show
  1. checksums.yaml +7 -0
  2. data/ext/nokolexbor/config.h +186 -0
  3. data/ext/nokolexbor/extconf.rb +131 -0
  4. data/ext/nokolexbor/libxml/HTMLparser.h +320 -0
  5. data/ext/nokolexbor/libxml/SAX2.h +173 -0
  6. data/ext/nokolexbor/libxml/chvalid.h +230 -0
  7. data/ext/nokolexbor/libxml/debugXML.h +217 -0
  8. data/ext/nokolexbor/libxml/dict.h +81 -0
  9. data/ext/nokolexbor/libxml/encoding.h +232 -0
  10. data/ext/nokolexbor/libxml/entities.h +153 -0
  11. data/ext/nokolexbor/libxml/globals.h +529 -0
  12. data/ext/nokolexbor/libxml/hash.h +236 -0
  13. data/ext/nokolexbor/libxml/list.h +137 -0
  14. data/ext/nokolexbor/libxml/parser.h +1264 -0
  15. data/ext/nokolexbor/libxml/parserInternals.h +641 -0
  16. data/ext/nokolexbor/libxml/pattern.h +100 -0
  17. data/ext/nokolexbor/libxml/threads.h +94 -0
  18. data/ext/nokolexbor/libxml/tree.h +1315 -0
  19. data/ext/nokolexbor/libxml/uri.h +94 -0
  20. data/ext/nokolexbor/libxml/valid.h +448 -0
  21. data/ext/nokolexbor/libxml/xmlIO.h +369 -0
  22. data/ext/nokolexbor/libxml/xmlautomata.h +146 -0
  23. data/ext/nokolexbor/libxml/xmlerror.h +919 -0
  24. data/ext/nokolexbor/libxml/xmlexports.h +79 -0
  25. data/ext/nokolexbor/libxml/xmlmemory.h +226 -0
  26. data/ext/nokolexbor/libxml/xmlregexp.h +222 -0
  27. data/ext/nokolexbor/libxml/xmlstring.h +140 -0
  28. data/ext/nokolexbor/libxml/xmlversion.h +526 -0
  29. data/ext/nokolexbor/libxml/xpath.h +575 -0
  30. data/ext/nokolexbor/libxml/xpathInternals.h +632 -0
  31. data/ext/nokolexbor/libxml/xpointer.h +137 -0
  32. data/ext/nokolexbor/libxml.h +76 -0
  33. data/ext/nokolexbor/memory.c +39 -0
  34. data/ext/nokolexbor/nl_document.c +51 -0
  35. data/ext/nokolexbor/nl_node.c +790 -0
  36. data/ext/nokolexbor/nl_node_set.c +368 -0
  37. data/ext/nokolexbor/nl_xpath_context.c +200 -0
  38. data/ext/nokolexbor/nokolexbor.c +63 -0
  39. data/ext/nokolexbor/nokolexbor.h +37 -0
  40. data/ext/nokolexbor/private/buf.h +70 -0
  41. data/ext/nokolexbor/private/dict.h +11 -0
  42. data/ext/nokolexbor/private/enc.h +17 -0
  43. data/ext/nokolexbor/private/error.h +21 -0
  44. data/ext/nokolexbor/private/globals.h +9 -0
  45. data/ext/nokolexbor/private/memory.h +9 -0
  46. data/ext/nokolexbor/private/parser.h +27 -0
  47. data/ext/nokolexbor/private/string.h +9 -0
  48. data/ext/nokolexbor/private/threads.h +50 -0
  49. data/ext/nokolexbor/private/tree.h +18 -0
  50. data/ext/nokolexbor/private/xpath.h +7 -0
  51. data/ext/nokolexbor/timsort.h +601 -0
  52. data/ext/nokolexbor/xml_SAX2.c +80 -0
  53. data/ext/nokolexbor/xml_buf.c +363 -0
  54. data/ext/nokolexbor/xml_chvalid.c +334 -0
  55. data/ext/nokolexbor/xml_dict.c +1264 -0
  56. data/ext/nokolexbor/xml_encoding.c +124 -0
  57. data/ext/nokolexbor/xml_error.c +134 -0
  58. data/ext/nokolexbor/xml_globals.c +1085 -0
  59. data/ext/nokolexbor/xml_hash.c +1141 -0
  60. data/ext/nokolexbor/xml_memory.c +203 -0
  61. data/ext/nokolexbor/xml_parser.c +127 -0
  62. data/ext/nokolexbor/xml_parserInternals.c +338 -0
  63. data/ext/nokolexbor/xml_pattern.c +2375 -0
  64. data/ext/nokolexbor/xml_string.c +1051 -0
  65. data/ext/nokolexbor/xml_threads.c +881 -0
  66. data/ext/nokolexbor/xml_tree.c +148 -0
  67. data/ext/nokolexbor/xml_xpath.c +14743 -0
  68. data/lib/nokolexbor/attribute.rb +18 -0
  69. data/lib/nokolexbor/document.rb +6 -0
  70. data/lib/nokolexbor/node.rb +264 -0
  71. data/lib/nokolexbor/node_set.rb +124 -0
  72. data/lib/nokolexbor/version.rb +5 -0
  73. data/lib/nokolexbor/xpath_context.rb +14 -0
  74. data/lib/nokolexbor.rb +17 -0
  75. data/patches/0001-lexbor-support-text-pseudo-element.patch +137 -0
  76. data/patches/0002-lexbor-match-id-class-case-sensitive.patch +22 -0
  77. data/patches/0003-lexbor-attach-template-content-to-self.patch +13 -0
  78. data/vendor/lexbor/CMakeLists.txt +331 -0
  79. data/vendor/lexbor/config.cmake +890 -0
  80. data/vendor/lexbor/feature.cmake +134 -0
  81. data/vendor/lexbor/source/lexbor/core/array.c +208 -0
  82. data/vendor/lexbor/source/lexbor/core/array.h +100 -0
  83. data/vendor/lexbor/source/lexbor/core/array_obj.c +216 -0
  84. data/vendor/lexbor/source/lexbor/core/array_obj.h +134 -0
  85. data/vendor/lexbor/source/lexbor/core/avl.c +442 -0
  86. data/vendor/lexbor/source/lexbor/core/avl.h +82 -0
  87. data/vendor/lexbor/source/lexbor/core/base.h +86 -0
  88. data/vendor/lexbor/source/lexbor/core/bst.c +468 -0
  89. data/vendor/lexbor/source/lexbor/core/bst.h +108 -0
  90. data/vendor/lexbor/source/lexbor/core/bst_map.c +238 -0
  91. data/vendor/lexbor/source/lexbor/core/bst_map.h +87 -0
  92. data/vendor/lexbor/source/lexbor/core/config.cmake +12 -0
  93. data/vendor/lexbor/source/lexbor/core/conv.c +203 -0
  94. data/vendor/lexbor/source/lexbor/core/conv.h +53 -0
  95. data/vendor/lexbor/source/lexbor/core/core.h +35 -0
  96. data/vendor/lexbor/source/lexbor/core/def.h +57 -0
  97. data/vendor/lexbor/source/lexbor/core/diyfp.c +153 -0
  98. data/vendor/lexbor/source/lexbor/core/diyfp.h +258 -0
  99. data/vendor/lexbor/source/lexbor/core/dobject.c +187 -0
  100. data/vendor/lexbor/source/lexbor/core/dobject.h +92 -0
  101. data/vendor/lexbor/source/lexbor/core/dtoa.c +404 -0
  102. data/vendor/lexbor/source/lexbor/core/dtoa.h +28 -0
  103. data/vendor/lexbor/source/lexbor/core/fs.h +60 -0
  104. data/vendor/lexbor/source/lexbor/core/hash.c +476 -0
  105. data/vendor/lexbor/source/lexbor/core/hash.h +218 -0
  106. data/vendor/lexbor/source/lexbor/core/in.c +267 -0
  107. data/vendor/lexbor/source/lexbor/core/in.h +172 -0
  108. data/vendor/lexbor/source/lexbor/core/lexbor.h +35 -0
  109. data/vendor/lexbor/source/lexbor/core/mem.c +228 -0
  110. data/vendor/lexbor/source/lexbor/core/mem.h +141 -0
  111. data/vendor/lexbor/source/lexbor/core/mraw.c +428 -0
  112. data/vendor/lexbor/source/lexbor/core/mraw.h +114 -0
  113. data/vendor/lexbor/source/lexbor/core/perf.h +45 -0
  114. data/vendor/lexbor/source/lexbor/core/plog.c +73 -0
  115. data/vendor/lexbor/source/lexbor/core/plog.h +102 -0
  116. data/vendor/lexbor/source/lexbor/core/print.c +168 -0
  117. data/vendor/lexbor/source/lexbor/core/print.h +39 -0
  118. data/vendor/lexbor/source/lexbor/core/sbst.h +59 -0
  119. data/vendor/lexbor/source/lexbor/core/serialize.c +27 -0
  120. data/vendor/lexbor/source/lexbor/core/serialize.h +32 -0
  121. data/vendor/lexbor/source/lexbor/core/shs.c +118 -0
  122. data/vendor/lexbor/source/lexbor/core/shs.h +82 -0
  123. data/vendor/lexbor/source/lexbor/core/str.c +617 -0
  124. data/vendor/lexbor/source/lexbor/core/str.h +247 -0
  125. data/vendor/lexbor/source/lexbor/core/str_res.h +369 -0
  126. data/vendor/lexbor/source/lexbor/core/strtod.c +326 -0
  127. data/vendor/lexbor/source/lexbor/core/strtod.h +28 -0
  128. data/vendor/lexbor/source/lexbor/core/types.h +39 -0
  129. data/vendor/lexbor/source/lexbor/core/utils.c +43 -0
  130. data/vendor/lexbor/source/lexbor/core/utils.h +36 -0
  131. data/vendor/lexbor/source/lexbor/css/base.h +44 -0
  132. data/vendor/lexbor/source/lexbor/css/config.cmake +2 -0
  133. data/vendor/lexbor/source/lexbor/css/css.h +25 -0
  134. data/vendor/lexbor/source/lexbor/css/log.c +336 -0
  135. data/vendor/lexbor/source/lexbor/css/log.h +103 -0
  136. data/vendor/lexbor/source/lexbor/css/node.h +29 -0
  137. data/vendor/lexbor/source/lexbor/css/parser.c +473 -0
  138. data/vendor/lexbor/source/lexbor/css/parser.h +368 -0
  139. data/vendor/lexbor/source/lexbor/css/selectors/base.h +48 -0
  140. data/vendor/lexbor/source/lexbor/css/selectors/pseudo.c +91 -0
  141. data/vendor/lexbor/source/lexbor/css/selectors/pseudo.h +66 -0
  142. data/vendor/lexbor/source/lexbor/css/selectors/pseudo_const.h +109 -0
  143. data/vendor/lexbor/source/lexbor/css/selectors/pseudo_res.h +302 -0
  144. data/vendor/lexbor/source/lexbor/css/selectors/pseudo_state.c +279 -0
  145. data/vendor/lexbor/source/lexbor/css/selectors/pseudo_state.h +85 -0
  146. data/vendor/lexbor/source/lexbor/css/selectors/selector.c +927 -0
  147. data/vendor/lexbor/source/lexbor/css/selectors/selector.h +200 -0
  148. data/vendor/lexbor/source/lexbor/css/selectors/selectors.c +340 -0
  149. data/vendor/lexbor/source/lexbor/css/selectors/selectors.h +137 -0
  150. data/vendor/lexbor/source/lexbor/css/selectors/state.c +1718 -0
  151. data/vendor/lexbor/source/lexbor/css/selectors/state.h +79 -0
  152. data/vendor/lexbor/source/lexbor/css/stylesheet.h +37 -0
  153. data/vendor/lexbor/source/lexbor/css/syntax/anb.c +443 -0
  154. data/vendor/lexbor/source/lexbor/css/syntax/anb.h +45 -0
  155. data/vendor/lexbor/source/lexbor/css/syntax/base.h +33 -0
  156. data/vendor/lexbor/source/lexbor/css/syntax/parser.c +9 -0
  157. data/vendor/lexbor/source/lexbor/css/syntax/parser.h +25 -0
  158. data/vendor/lexbor/source/lexbor/css/syntax/res.h +48 -0
  159. data/vendor/lexbor/source/lexbor/css/syntax/state.c +2603 -0
  160. data/vendor/lexbor/source/lexbor/css/syntax/state.h +140 -0
  161. data/vendor/lexbor/source/lexbor/css/syntax/state_res.h +273 -0
  162. data/vendor/lexbor/source/lexbor/css/syntax/syntax.c +67 -0
  163. data/vendor/lexbor/source/lexbor/css/syntax/token.c +618 -0
  164. data/vendor/lexbor/source/lexbor/css/syntax/token.h +298 -0
  165. data/vendor/lexbor/source/lexbor/css/syntax/token_res.h +68 -0
  166. data/vendor/lexbor/source/lexbor/css/syntax/tokenizer/error.c +30 -0
  167. data/vendor/lexbor/source/lexbor/css/syntax/tokenizer/error.h +58 -0
  168. data/vendor/lexbor/source/lexbor/css/syntax/tokenizer.c +278 -0
  169. data/vendor/lexbor/source/lexbor/css/syntax/tokenizer.h +121 -0
  170. data/vendor/lexbor/source/lexbor/dom/base.h +32 -0
  171. data/vendor/lexbor/source/lexbor/dom/collection.c +97 -0
  172. data/vendor/lexbor/source/lexbor/dom/collection.h +112 -0
  173. data/vendor/lexbor/source/lexbor/dom/config.cmake +3 -0
  174. data/vendor/lexbor/source/lexbor/dom/dom.h +29 -0
  175. data/vendor/lexbor/source/lexbor/dom/exception.c +18 -0
  176. data/vendor/lexbor/source/lexbor/dom/exception.h +73 -0
  177. data/vendor/lexbor/source/lexbor/dom/interface.c +110 -0
  178. data/vendor/lexbor/source/lexbor/dom/interface.h +88 -0
  179. data/vendor/lexbor/source/lexbor/dom/interfaces/attr.c +445 -0
  180. data/vendor/lexbor/source/lexbor/dom/interfaces/attr.h +152 -0
  181. data/vendor/lexbor/source/lexbor/dom/interfaces/attr_const.h +62 -0
  182. data/vendor/lexbor/source/lexbor/dom/interfaces/attr_res.h +143 -0
  183. data/vendor/lexbor/source/lexbor/dom/interfaces/cdata_section.c +55 -0
  184. data/vendor/lexbor/source/lexbor/dom/interfaces/cdata_section.h +38 -0
  185. data/vendor/lexbor/source/lexbor/dom/interfaces/character_data.c +110 -0
  186. data/vendor/lexbor/source/lexbor/dom/interfaces/character_data.h +51 -0
  187. data/vendor/lexbor/source/lexbor/dom/interfaces/comment.c +64 -0
  188. data/vendor/lexbor/source/lexbor/dom/interfaces/comment.h +42 -0
  189. data/vendor/lexbor/source/lexbor/dom/interfaces/document.c +536 -0
  190. data/vendor/lexbor/source/lexbor/dom/interfaces/document.h +243 -0
  191. data/vendor/lexbor/source/lexbor/dom/interfaces/document_fragment.c +36 -0
  192. data/vendor/lexbor/source/lexbor/dom/interfaces/document_fragment.h +36 -0
  193. data/vendor/lexbor/source/lexbor/dom/interfaces/document_type.c +125 -0
  194. data/vendor/lexbor/source/lexbor/dom/interfaces/document_type.h +108 -0
  195. data/vendor/lexbor/source/lexbor/dom/interfaces/element.c +1411 -0
  196. data/vendor/lexbor/source/lexbor/dom/interfaces/element.h +319 -0
  197. data/vendor/lexbor/source/lexbor/dom/interfaces/event_target.c +32 -0
  198. data/vendor/lexbor/source/lexbor/dom/interfaces/event_target.h +34 -0
  199. data/vendor/lexbor/source/lexbor/dom/interfaces/node.c +661 -0
  200. data/vendor/lexbor/source/lexbor/dom/interfaces/node.h +192 -0
  201. data/vendor/lexbor/source/lexbor/dom/interfaces/processing_instruction.c +87 -0
  202. data/vendor/lexbor/source/lexbor/dom/interfaces/processing_instruction.h +66 -0
  203. data/vendor/lexbor/source/lexbor/dom/interfaces/shadow_root.c +36 -0
  204. data/vendor/lexbor/source/lexbor/dom/interfaces/shadow_root.h +44 -0
  205. data/vendor/lexbor/source/lexbor/dom/interfaces/text.c +63 -0
  206. data/vendor/lexbor/source/lexbor/dom/interfaces/text.h +42 -0
  207. data/vendor/lexbor/source/lexbor/encoding/base.h +218 -0
  208. data/vendor/lexbor/source/lexbor/encoding/big5.c +42839 -0
  209. data/vendor/lexbor/source/lexbor/encoding/config.cmake +12 -0
  210. data/vendor/lexbor/source/lexbor/encoding/const.h +65 -0
  211. data/vendor/lexbor/source/lexbor/encoding/decode.c +3193 -0
  212. data/vendor/lexbor/source/lexbor/encoding/decode.h +370 -0
  213. data/vendor/lexbor/source/lexbor/encoding/encode.c +1931 -0
  214. data/vendor/lexbor/source/lexbor/encoding/encode.h +377 -0
  215. data/vendor/lexbor/source/lexbor/encoding/encoding.c +252 -0
  216. data/vendor/lexbor/source/lexbor/encoding/encoding.h +475 -0
  217. data/vendor/lexbor/source/lexbor/encoding/euc_kr.c +53883 -0
  218. data/vendor/lexbor/source/lexbor/encoding/gb18030.c +47905 -0
  219. data/vendor/lexbor/source/lexbor/encoding/iso_2022_jp_katakana.c +159 -0
  220. data/vendor/lexbor/source/lexbor/encoding/jis0208.c +22477 -0
  221. data/vendor/lexbor/source/lexbor/encoding/jis0212.c +15787 -0
  222. data/vendor/lexbor/source/lexbor/encoding/multi.h +53 -0
  223. data/vendor/lexbor/source/lexbor/encoding/range.c +71 -0
  224. data/vendor/lexbor/source/lexbor/encoding/range.h +34 -0
  225. data/vendor/lexbor/source/lexbor/encoding/res.c +222 -0
  226. data/vendor/lexbor/source/lexbor/encoding/res.h +34 -0
  227. data/vendor/lexbor/source/lexbor/encoding/single.c +13748 -0
  228. data/vendor/lexbor/source/lexbor/encoding/single.h +116 -0
  229. data/vendor/lexbor/source/lexbor/html/base.h +44 -0
  230. data/vendor/lexbor/source/lexbor/html/config.cmake +3 -0
  231. data/vendor/lexbor/source/lexbor/html/encoding.c +574 -0
  232. data/vendor/lexbor/source/lexbor/html/encoding.h +106 -0
  233. data/vendor/lexbor/source/lexbor/html/html.h +107 -0
  234. data/vendor/lexbor/source/lexbor/html/interface.c +165 -0
  235. data/vendor/lexbor/source/lexbor/html/interface.h +186 -0
  236. data/vendor/lexbor/source/lexbor/html/interface_res.h +4449 -0
  237. data/vendor/lexbor/source/lexbor/html/interfaces/anchor_element.c +36 -0
  238. data/vendor/lexbor/source/lexbor/html/interfaces/anchor_element.h +34 -0
  239. data/vendor/lexbor/source/lexbor/html/interfaces/area_element.c +36 -0
  240. data/vendor/lexbor/source/lexbor/html/interfaces/area_element.h +34 -0
  241. data/vendor/lexbor/source/lexbor/html/interfaces/audio_element.c +36 -0
  242. data/vendor/lexbor/source/lexbor/html/interfaces/audio_element.h +34 -0
  243. data/vendor/lexbor/source/lexbor/html/interfaces/base_element.c +36 -0
  244. data/vendor/lexbor/source/lexbor/html/interfaces/base_element.h +34 -0
  245. data/vendor/lexbor/source/lexbor/html/interfaces/body_element.c +36 -0
  246. data/vendor/lexbor/source/lexbor/html/interfaces/body_element.h +34 -0
  247. data/vendor/lexbor/source/lexbor/html/interfaces/br_element.c +36 -0
  248. data/vendor/lexbor/source/lexbor/html/interfaces/br_element.h +34 -0
  249. data/vendor/lexbor/source/lexbor/html/interfaces/button_element.c +36 -0
  250. data/vendor/lexbor/source/lexbor/html/interfaces/button_element.h +34 -0
  251. data/vendor/lexbor/source/lexbor/html/interfaces/canvas_element.c +36 -0
  252. data/vendor/lexbor/source/lexbor/html/interfaces/canvas_element.h +34 -0
  253. data/vendor/lexbor/source/lexbor/html/interfaces/d_list_element.c +36 -0
  254. data/vendor/lexbor/source/lexbor/html/interfaces/d_list_element.h +34 -0
  255. data/vendor/lexbor/source/lexbor/html/interfaces/data_element.c +36 -0
  256. data/vendor/lexbor/source/lexbor/html/interfaces/data_element.h +34 -0
  257. data/vendor/lexbor/source/lexbor/html/interfaces/data_list_element.c +36 -0
  258. data/vendor/lexbor/source/lexbor/html/interfaces/data_list_element.h +34 -0
  259. data/vendor/lexbor/source/lexbor/html/interfaces/details_element.c +36 -0
  260. data/vendor/lexbor/source/lexbor/html/interfaces/details_element.h +34 -0
  261. data/vendor/lexbor/source/lexbor/html/interfaces/dialog_element.c +36 -0
  262. data/vendor/lexbor/source/lexbor/html/interfaces/dialog_element.h +34 -0
  263. data/vendor/lexbor/source/lexbor/html/interfaces/directory_element.c +36 -0
  264. data/vendor/lexbor/source/lexbor/html/interfaces/directory_element.h +34 -0
  265. data/vendor/lexbor/source/lexbor/html/interfaces/div_element.c +36 -0
  266. data/vendor/lexbor/source/lexbor/html/interfaces/div_element.h +34 -0
  267. data/vendor/lexbor/source/lexbor/html/interfaces/document.c +444 -0
  268. data/vendor/lexbor/source/lexbor/html/interfaces/document.h +256 -0
  269. data/vendor/lexbor/source/lexbor/html/interfaces/element.c +64 -0
  270. data/vendor/lexbor/source/lexbor/html/interfaces/element.h +54 -0
  271. data/vendor/lexbor/source/lexbor/html/interfaces/embed_element.c +36 -0
  272. data/vendor/lexbor/source/lexbor/html/interfaces/embed_element.h +34 -0
  273. data/vendor/lexbor/source/lexbor/html/interfaces/field_set_element.c +36 -0
  274. data/vendor/lexbor/source/lexbor/html/interfaces/field_set_element.h +34 -0
  275. data/vendor/lexbor/source/lexbor/html/interfaces/font_element.c +36 -0
  276. data/vendor/lexbor/source/lexbor/html/interfaces/font_element.h +34 -0
  277. data/vendor/lexbor/source/lexbor/html/interfaces/form_element.c +36 -0
  278. data/vendor/lexbor/source/lexbor/html/interfaces/form_element.h +34 -0
  279. data/vendor/lexbor/source/lexbor/html/interfaces/frame_element.c +36 -0
  280. data/vendor/lexbor/source/lexbor/html/interfaces/frame_element.h +34 -0
  281. data/vendor/lexbor/source/lexbor/html/interfaces/frame_set_element.c +36 -0
  282. data/vendor/lexbor/source/lexbor/html/interfaces/frame_set_element.h +34 -0
  283. data/vendor/lexbor/source/lexbor/html/interfaces/head_element.c +36 -0
  284. data/vendor/lexbor/source/lexbor/html/interfaces/head_element.h +34 -0
  285. data/vendor/lexbor/source/lexbor/html/interfaces/heading_element.c +36 -0
  286. data/vendor/lexbor/source/lexbor/html/interfaces/heading_element.h +34 -0
  287. data/vendor/lexbor/source/lexbor/html/interfaces/hr_element.c +36 -0
  288. data/vendor/lexbor/source/lexbor/html/interfaces/hr_element.h +34 -0
  289. data/vendor/lexbor/source/lexbor/html/interfaces/html_element.c +36 -0
  290. data/vendor/lexbor/source/lexbor/html/interfaces/html_element.h +34 -0
  291. data/vendor/lexbor/source/lexbor/html/interfaces/iframe_element.c +36 -0
  292. data/vendor/lexbor/source/lexbor/html/interfaces/iframe_element.h +34 -0
  293. data/vendor/lexbor/source/lexbor/html/interfaces/image_element.c +36 -0
  294. data/vendor/lexbor/source/lexbor/html/interfaces/image_element.h +34 -0
  295. data/vendor/lexbor/source/lexbor/html/interfaces/input_element.c +36 -0
  296. data/vendor/lexbor/source/lexbor/html/interfaces/input_element.h +34 -0
  297. data/vendor/lexbor/source/lexbor/html/interfaces/label_element.c +36 -0
  298. data/vendor/lexbor/source/lexbor/html/interfaces/label_element.h +34 -0
  299. data/vendor/lexbor/source/lexbor/html/interfaces/legend_element.c +36 -0
  300. data/vendor/lexbor/source/lexbor/html/interfaces/legend_element.h +34 -0
  301. data/vendor/lexbor/source/lexbor/html/interfaces/li_element.c +36 -0
  302. data/vendor/lexbor/source/lexbor/html/interfaces/li_element.h +34 -0
  303. data/vendor/lexbor/source/lexbor/html/interfaces/link_element.c +36 -0
  304. data/vendor/lexbor/source/lexbor/html/interfaces/link_element.h +34 -0
  305. data/vendor/lexbor/source/lexbor/html/interfaces/map_element.c +36 -0
  306. data/vendor/lexbor/source/lexbor/html/interfaces/map_element.h +34 -0
  307. data/vendor/lexbor/source/lexbor/html/interfaces/marquee_element.c +36 -0
  308. data/vendor/lexbor/source/lexbor/html/interfaces/marquee_element.h +34 -0
  309. data/vendor/lexbor/source/lexbor/html/interfaces/media_element.c +36 -0
  310. data/vendor/lexbor/source/lexbor/html/interfaces/media_element.h +34 -0
  311. data/vendor/lexbor/source/lexbor/html/interfaces/menu_element.c +36 -0
  312. data/vendor/lexbor/source/lexbor/html/interfaces/menu_element.h +34 -0
  313. data/vendor/lexbor/source/lexbor/html/interfaces/meta_element.c +36 -0
  314. data/vendor/lexbor/source/lexbor/html/interfaces/meta_element.h +34 -0
  315. data/vendor/lexbor/source/lexbor/html/interfaces/meter_element.c +36 -0
  316. data/vendor/lexbor/source/lexbor/html/interfaces/meter_element.h +34 -0
  317. data/vendor/lexbor/source/lexbor/html/interfaces/mod_element.c +36 -0
  318. data/vendor/lexbor/source/lexbor/html/interfaces/mod_element.h +34 -0
  319. data/vendor/lexbor/source/lexbor/html/interfaces/o_list_element.c +36 -0
  320. data/vendor/lexbor/source/lexbor/html/interfaces/o_list_element.h +34 -0
  321. data/vendor/lexbor/source/lexbor/html/interfaces/object_element.c +36 -0
  322. data/vendor/lexbor/source/lexbor/html/interfaces/object_element.h +34 -0
  323. data/vendor/lexbor/source/lexbor/html/interfaces/opt_group_element.c +36 -0
  324. data/vendor/lexbor/source/lexbor/html/interfaces/opt_group_element.h +34 -0
  325. data/vendor/lexbor/source/lexbor/html/interfaces/option_element.c +36 -0
  326. data/vendor/lexbor/source/lexbor/html/interfaces/option_element.h +34 -0
  327. data/vendor/lexbor/source/lexbor/html/interfaces/output_element.c +36 -0
  328. data/vendor/lexbor/source/lexbor/html/interfaces/output_element.h +34 -0
  329. data/vendor/lexbor/source/lexbor/html/interfaces/paragraph_element.c +36 -0
  330. data/vendor/lexbor/source/lexbor/html/interfaces/paragraph_element.h +34 -0
  331. data/vendor/lexbor/source/lexbor/html/interfaces/param_element.c +36 -0
  332. data/vendor/lexbor/source/lexbor/html/interfaces/param_element.h +34 -0
  333. data/vendor/lexbor/source/lexbor/html/interfaces/picture_element.c +36 -0
  334. data/vendor/lexbor/source/lexbor/html/interfaces/picture_element.h +34 -0
  335. data/vendor/lexbor/source/lexbor/html/interfaces/pre_element.c +36 -0
  336. data/vendor/lexbor/source/lexbor/html/interfaces/pre_element.h +34 -0
  337. data/vendor/lexbor/source/lexbor/html/interfaces/progress_element.c +36 -0
  338. data/vendor/lexbor/source/lexbor/html/interfaces/progress_element.h +34 -0
  339. data/vendor/lexbor/source/lexbor/html/interfaces/quote_element.c +36 -0
  340. data/vendor/lexbor/source/lexbor/html/interfaces/quote_element.h +34 -0
  341. data/vendor/lexbor/source/lexbor/html/interfaces/script_element.c +36 -0
  342. data/vendor/lexbor/source/lexbor/html/interfaces/script_element.h +34 -0
  343. data/vendor/lexbor/source/lexbor/html/interfaces/select_element.c +36 -0
  344. data/vendor/lexbor/source/lexbor/html/interfaces/select_element.h +34 -0
  345. data/vendor/lexbor/source/lexbor/html/interfaces/slot_element.c +36 -0
  346. data/vendor/lexbor/source/lexbor/html/interfaces/slot_element.h +34 -0
  347. data/vendor/lexbor/source/lexbor/html/interfaces/source_element.c +36 -0
  348. data/vendor/lexbor/source/lexbor/html/interfaces/source_element.h +34 -0
  349. data/vendor/lexbor/source/lexbor/html/interfaces/span_element.c +36 -0
  350. data/vendor/lexbor/source/lexbor/html/interfaces/span_element.h +34 -0
  351. data/vendor/lexbor/source/lexbor/html/interfaces/style_element.c +36 -0
  352. data/vendor/lexbor/source/lexbor/html/interfaces/style_element.h +34 -0
  353. data/vendor/lexbor/source/lexbor/html/interfaces/table_caption_element.c +36 -0
  354. data/vendor/lexbor/source/lexbor/html/interfaces/table_caption_element.h +34 -0
  355. data/vendor/lexbor/source/lexbor/html/interfaces/table_cell_element.c +36 -0
  356. data/vendor/lexbor/source/lexbor/html/interfaces/table_cell_element.h +34 -0
  357. data/vendor/lexbor/source/lexbor/html/interfaces/table_col_element.c +36 -0
  358. data/vendor/lexbor/source/lexbor/html/interfaces/table_col_element.h +34 -0
  359. data/vendor/lexbor/source/lexbor/html/interfaces/table_element.c +36 -0
  360. data/vendor/lexbor/source/lexbor/html/interfaces/table_element.h +34 -0
  361. data/vendor/lexbor/source/lexbor/html/interfaces/table_row_element.c +36 -0
  362. data/vendor/lexbor/source/lexbor/html/interfaces/table_row_element.h +34 -0
  363. data/vendor/lexbor/source/lexbor/html/interfaces/table_section_element.c +36 -0
  364. data/vendor/lexbor/source/lexbor/html/interfaces/table_section_element.h +34 -0
  365. data/vendor/lexbor/source/lexbor/html/interfaces/template_element.c +46 -0
  366. data/vendor/lexbor/source/lexbor/html/interfaces/template_element.h +38 -0
  367. data/vendor/lexbor/source/lexbor/html/interfaces/text_area_element.c +36 -0
  368. data/vendor/lexbor/source/lexbor/html/interfaces/text_area_element.h +34 -0
  369. data/vendor/lexbor/source/lexbor/html/interfaces/time_element.c +36 -0
  370. data/vendor/lexbor/source/lexbor/html/interfaces/time_element.h +34 -0
  371. data/vendor/lexbor/source/lexbor/html/interfaces/title_element.c +133 -0
  372. data/vendor/lexbor/source/lexbor/html/interfaces/title_element.h +42 -0
  373. data/vendor/lexbor/source/lexbor/html/interfaces/track_element.c +36 -0
  374. data/vendor/lexbor/source/lexbor/html/interfaces/track_element.h +34 -0
  375. data/vendor/lexbor/source/lexbor/html/interfaces/u_list_element.c +36 -0
  376. data/vendor/lexbor/source/lexbor/html/interfaces/u_list_element.h +34 -0
  377. data/vendor/lexbor/source/lexbor/html/interfaces/unknown_element.c +36 -0
  378. data/vendor/lexbor/source/lexbor/html/interfaces/unknown_element.h +34 -0
  379. data/vendor/lexbor/source/lexbor/html/interfaces/video_element.c +36 -0
  380. data/vendor/lexbor/source/lexbor/html/interfaces/video_element.h +34 -0
  381. data/vendor/lexbor/source/lexbor/html/interfaces/window.c +36 -0
  382. data/vendor/lexbor/source/lexbor/html/interfaces/window.h +34 -0
  383. data/vendor/lexbor/source/lexbor/html/node.c +14 -0
  384. data/vendor/lexbor/source/lexbor/html/node.h +67 -0
  385. data/vendor/lexbor/source/lexbor/html/parser.c +469 -0
  386. data/vendor/lexbor/source/lexbor/html/parser.h +170 -0
  387. data/vendor/lexbor/source/lexbor/html/serialize.c +1510 -0
  388. data/vendor/lexbor/source/lexbor/html/serialize.h +93 -0
  389. data/vendor/lexbor/source/lexbor/html/tag.h +103 -0
  390. data/vendor/lexbor/source/lexbor/html/tag_res.h +2262 -0
  391. data/vendor/lexbor/source/lexbor/html/token.c +386 -0
  392. data/vendor/lexbor/source/lexbor/html/token.h +130 -0
  393. data/vendor/lexbor/source/lexbor/html/token_attr.c +44 -0
  394. data/vendor/lexbor/source/lexbor/html/token_attr.h +67 -0
  395. data/vendor/lexbor/source/lexbor/html/tokenizer/error.c +28 -0
  396. data/vendor/lexbor/source/lexbor/html/tokenizer/error.h +141 -0
  397. data/vendor/lexbor/source/lexbor/html/tokenizer/res.h +4956 -0
  398. data/vendor/lexbor/source/lexbor/html/tokenizer/state.c +2171 -0
  399. data/vendor/lexbor/source/lexbor/html/tokenizer/state.h +225 -0
  400. data/vendor/lexbor/source/lexbor/html/tokenizer/state_comment.c +489 -0
  401. data/vendor/lexbor/source/lexbor/html/tokenizer/state_comment.h +27 -0
  402. data/vendor/lexbor/source/lexbor/html/tokenizer/state_doctype.c +1654 -0
  403. data/vendor/lexbor/source/lexbor/html/tokenizer/state_doctype.h +27 -0
  404. data/vendor/lexbor/source/lexbor/html/tokenizer/state_rawtext.c +303 -0
  405. data/vendor/lexbor/source/lexbor/html/tokenizer/state_rawtext.h +32 -0
  406. data/vendor/lexbor/source/lexbor/html/tokenizer/state_rcdata.c +311 -0
  407. data/vendor/lexbor/source/lexbor/html/tokenizer/state_rcdata.h +32 -0
  408. data/vendor/lexbor/source/lexbor/html/tokenizer/state_script.c +1209 -0
  409. data/vendor/lexbor/source/lexbor/html/tokenizer/state_script.h +32 -0
  410. data/vendor/lexbor/source/lexbor/html/tokenizer.c +499 -0
  411. data/vendor/lexbor/source/lexbor/html/tokenizer.h +343 -0
  412. data/vendor/lexbor/source/lexbor/html/tree/active_formatting.c +241 -0
  413. data/vendor/lexbor/source/lexbor/html/tree/active_formatting.h +117 -0
  414. data/vendor/lexbor/source/lexbor/html/tree/error.c +26 -0
  415. data/vendor/lexbor/source/lexbor/html/tree/error.h +114 -0
  416. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/after_after_body.c +62 -0
  417. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/after_after_frameset.c +63 -0
  418. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/after_body.c +82 -0
  419. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/after_frameset.c +88 -0
  420. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/after_head.c +222 -0
  421. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/before_head.c +144 -0
  422. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/before_html.c +166 -0
  423. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/foreign_content.c +358 -0
  424. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/in_body.c +1974 -0
  425. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/in_caption.c +158 -0
  426. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/in_cell.c +187 -0
  427. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/in_column_group.c +194 -0
  428. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/in_frameset.c +149 -0
  429. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/in_head.c +374 -0
  430. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/in_head_noscript.c +121 -0
  431. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/in_row.c +211 -0
  432. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/in_select.c +341 -0
  433. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/in_select_in_table.c +115 -0
  434. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/in_table.c +451 -0
  435. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/in_table_body.c +208 -0
  436. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/in_table_text.c +127 -0
  437. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/in_template.c +189 -0
  438. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/initial.c +411 -0
  439. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode/text.c +61 -0
  440. data/vendor/lexbor/source/lexbor/html/tree/insertion_mode.h +135 -0
  441. data/vendor/lexbor/source/lexbor/html/tree/open_elements.c +251 -0
  442. data/vendor/lexbor/source/lexbor/html/tree/open_elements.h +105 -0
  443. data/vendor/lexbor/source/lexbor/html/tree/template_insertion.c +10 -0
  444. data/vendor/lexbor/source/lexbor/html/tree/template_insertion.h +100 -0
  445. data/vendor/lexbor/source/lexbor/html/tree.c +1726 -0
  446. data/vendor/lexbor/source/lexbor/html/tree.h +431 -0
  447. data/vendor/lexbor/source/lexbor/html/tree_res.h +111 -0
  448. data/vendor/lexbor/source/lexbor/ns/base.h +32 -0
  449. data/vendor/lexbor/source/lexbor/ns/config.cmake +2 -0
  450. data/vendor/lexbor/source/lexbor/ns/const.h +37 -0
  451. data/vendor/lexbor/source/lexbor/ns/ns.c +154 -0
  452. data/vendor/lexbor/source/lexbor/ns/ns.h +66 -0
  453. data/vendor/lexbor/source/lexbor/ns/res.h +97 -0
  454. data/vendor/lexbor/source/lexbor/ports/posix/config.cmake +11 -0
  455. data/vendor/lexbor/source/lexbor/ports/posix/lexbor/core/fs.c +236 -0
  456. data/vendor/lexbor/source/lexbor/ports/posix/lexbor/core/memory.c +33 -0
  457. data/vendor/lexbor/source/lexbor/ports/posix/lexbor/core/perf.c +158 -0
  458. data/vendor/lexbor/source/lexbor/ports/windows_nt/config.cmake +18 -0
  459. data/vendor/lexbor/source/lexbor/ports/windows_nt/lexbor/core/fs.c +239 -0
  460. data/vendor/lexbor/source/lexbor/ports/windows_nt/lexbor/core/memory.c +33 -0
  461. data/vendor/lexbor/source/lexbor/ports/windows_nt/lexbor/core/perf.c +81 -0
  462. data/vendor/lexbor/source/lexbor/selectors/base.h +30 -0
  463. data/vendor/lexbor/source/lexbor/selectors/config.cmake +2 -0
  464. data/vendor/lexbor/source/lexbor/selectors/selectors.c +1591 -0
  465. data/vendor/lexbor/source/lexbor/selectors/selectors.h +71 -0
  466. data/vendor/lexbor/source/lexbor/tag/base.h +32 -0
  467. data/vendor/lexbor/source/lexbor/tag/config.cmake +2 -0
  468. data/vendor/lexbor/source/lexbor/tag/const.h +225 -0
  469. data/vendor/lexbor/source/lexbor/tag/res.h +562 -0
  470. data/vendor/lexbor/source/lexbor/tag/tag.c +144 -0
  471. data/vendor/lexbor/source/lexbor/tag/tag.h +123 -0
  472. data/vendor/lexbor/source/lexbor/utils/base.h +32 -0
  473. data/vendor/lexbor/source/lexbor/utils/config.cmake +2 -0
  474. data/vendor/lexbor/source/lexbor/utils/http.c +534 -0
  475. data/vendor/lexbor/source/lexbor/utils/http.h +90 -0
  476. data/vendor/lexbor/source/lexbor/utils/utils.h +15 -0
  477. data/vendor/lexbor/source/lexbor/utils/warc.c +817 -0
  478. data/vendor/lexbor/source/lexbor/utils/warc.h +126 -0
  479. data/vendor/lexbor/utils/lexbor/css/selectors/pseudo.py +231 -0
  480. data/vendor/lexbor/utils/lexbor/css/selectors/tmp/const.h +21 -0
  481. data/vendor/lexbor/utils/lexbor/css/selectors/tmp/res.h +26 -0
  482. data/vendor/lexbor/utils/lexbor/css/syntax/definitions.py +49 -0
  483. data/vendor/lexbor/utils/lexbor/css/syntax/token_res.py +54 -0
  484. data/vendor/lexbor/utils/lexbor/css/syntax/tokenizer_code_map.py +36 -0
  485. data/vendor/lexbor/version +1 -0
  486. metadata +542 -0
@@ -0,0 +1,2375 @@
1
+ /*
2
+ * pattern.c: Implementation of selectors for nodes
3
+ *
4
+ * Reference:
5
+ * http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/
6
+ * to some extent
7
+ * http://www.w3.org/TR/1999/REC-xml-19991116
8
+ *
9
+ * See Copyright for the status of this software.
10
+ *
11
+ * daniel@veillard.com
12
+ */
13
+
14
+ /*
15
+ * TODO:
16
+ * - compilation flags to check for specific syntaxes
17
+ * using flags of xmlPatterncompile()
18
+ * - making clear how pattern starting with / or . need to be handled,
19
+ * currently push(NULL, NULL) means a reset of the streaming context
20
+ * and indicating we are on / (the document node), probably need
21
+ * something similar for .
22
+ * - get rid of the "compile" starting with lowercase
23
+ * - DONE (2006-05-16): get rid of the Strdup/Strndup in case of dictionary
24
+ */
25
+
26
+ #define IN_LIBXML
27
+ #include "libxml.h"
28
+
29
+ #include <string.h>
30
+ #include "libxml/xmlmemory.h"
31
+ #include "libxml/tree.h"
32
+ #include "libxml/hash.h"
33
+ #include "libxml/dict.h"
34
+ #include "libxml/xmlerror.h"
35
+ #include "libxml/parserInternals.h"
36
+ #include "libxml/pattern.h"
37
+
38
+ #ifdef LIBXML_PATTERN_ENABLED
39
+
40
+ /* #define DEBUG_STREAMING */
41
+
42
+ #ifdef ERROR
43
+ #undef ERROR
44
+ #endif
45
+ #define ERROR(a, b, c, d)
46
+ #define ERROR5(a, b, c, d, e)
47
+
48
+ #define XML_STREAM_STEP_DESC 1
49
+ #define XML_STREAM_STEP_FINAL 2
50
+ #define XML_STREAM_STEP_ROOT 4
51
+ #define XML_STREAM_STEP_ATTR 8
52
+ #define XML_STREAM_STEP_NODE 16
53
+ #define XML_STREAM_STEP_IN_SET 32
54
+
55
+ /*
56
+ * NOTE: Those private flags (XML_STREAM_xxx) are used
57
+ * in _xmlStreamCtxt->flag. They extend the public
58
+ * xmlPatternFlags, so be careful not to interfere with the
59
+ * reserved values for xmlPatternFlags.
60
+ */
61
+ #define XML_STREAM_FINAL_IS_ANY_NODE 1<<14
62
+ #define XML_STREAM_FROM_ROOT 1<<15
63
+ #define XML_STREAM_DESC 1<<16
64
+
65
+ /*
66
+ * XML_STREAM_ANY_NODE is used for comparison against
67
+ * xmlElementType enums, to indicate a node of any type.
68
+ */
69
+ #define XML_STREAM_ANY_NODE 100
70
+
71
+ #define XML_PATTERN_NOTPATTERN (XML_PATTERN_XPATH | \
72
+ XML_PATTERN_XSSEL | \
73
+ XML_PATTERN_XSFIELD)
74
+
75
+ #define XML_STREAM_XS_IDC(c) ((c)->flags & \
76
+ (XML_PATTERN_XSSEL | XML_PATTERN_XSFIELD))
77
+
78
+ #define XML_STREAM_XS_IDC_SEL(c) ((c)->flags & XML_PATTERN_XSSEL)
79
+
80
+ #define XML_STREAM_XS_IDC_FIELD(c) ((c)->flags & XML_PATTERN_XSFIELD)
81
+
82
+ #define XML_PAT_COPY_NSNAME(c, r, nsname) \
83
+ if ((c)->comp->dict) \
84
+ r = (xmlChar *) xmlDictLookup((c)->comp->dict, BAD_CAST nsname, -1); \
85
+ else r = xmlStrdup(BAD_CAST nsname);
86
+
87
+ #define XML_PAT_FREE_STRING(c, r) if ((c)->comp->dict == NULL) xmlFree(r);
88
+
89
+ typedef struct _xmlStreamStep xmlStreamStep;
90
+ typedef xmlStreamStep *xmlStreamStepPtr;
91
+ struct _xmlStreamStep {
92
+ int flags; /* properties of that step */
93
+ const xmlChar *name; /* first string value if NULL accept all */
94
+ const xmlChar *ns; /* second string value */
95
+ int nodeType; /* type of node */
96
+ };
97
+
98
+ typedef struct _xmlStreamComp xmlStreamComp;
99
+ typedef xmlStreamComp *xmlStreamCompPtr;
100
+ struct _xmlStreamComp {
101
+ xmlDict *dict; /* the dictionary if any */
102
+ int nbStep; /* number of steps in the automata */
103
+ int maxStep; /* allocated number of steps */
104
+ xmlStreamStepPtr steps; /* the array of steps */
105
+ int flags;
106
+ };
107
+
108
+ struct _xmlStreamCtxt {
109
+ struct _xmlStreamCtxt *next;/* link to next sub pattern if | */
110
+ xmlStreamCompPtr comp; /* the compiled stream */
111
+ int nbState; /* number of states in the automata */
112
+ int maxState; /* allocated number of states */
113
+ int level; /* how deep are we ? */
114
+ int *states; /* the array of step indexes */
115
+ int flags; /* validation options */
116
+ int blockLevel;
117
+ };
118
+
119
+ static void xmlFreeStreamComp(xmlStreamCompPtr comp);
120
+
121
+ /*
122
+ * Types are private:
123
+ */
124
+
125
+ typedef enum {
126
+ XML_OP_END=0,
127
+ XML_OP_ROOT,
128
+ XML_OP_ELEM,
129
+ XML_OP_CHILD,
130
+ XML_OP_ATTR,
131
+ XML_OP_PARENT,
132
+ XML_OP_ANCESTOR,
133
+ XML_OP_NS,
134
+ XML_OP_ALL
135
+ } xmlPatOp;
136
+
137
+
138
+ typedef struct _xmlStepState xmlStepState;
139
+ typedef xmlStepState *xmlStepStatePtr;
140
+ struct _xmlStepState {
141
+ int step;
142
+ lxb_dom_node_t_ptr node;
143
+ };
144
+
145
+ typedef struct _xmlStepStates xmlStepStates;
146
+ typedef xmlStepStates *xmlStepStatesPtr;
147
+ struct _xmlStepStates {
148
+ int nbstates;
149
+ int maxstates;
150
+ xmlStepStatePtr states;
151
+ };
152
+
153
+ typedef struct _xmlStepOp xmlStepOp;
154
+ typedef xmlStepOp *xmlStepOpPtr;
155
+ struct _xmlStepOp {
156
+ xmlPatOp op;
157
+ const xmlChar *value;
158
+ const xmlChar *value2; /* The namespace name */
159
+ };
160
+
161
+ #define PAT_FROM_ROOT (1<<8)
162
+ #define PAT_FROM_CUR (1<<9)
163
+
164
+ struct _xmlPattern {
165
+ void *data; /* the associated template */
166
+ xmlDictPtr dict; /* the optional dictionary */
167
+ struct _xmlPattern *next; /* next pattern if | is used */
168
+ const xmlChar *pattern; /* the pattern */
169
+ int flags; /* flags */
170
+ int nbStep;
171
+ int maxStep;
172
+ xmlStepOpPtr steps; /* ops for computation */
173
+ xmlStreamCompPtr stream; /* the streaming data if any */
174
+ };
175
+
176
+ typedef struct _xmlPatParserContext xmlPatParserContext;
177
+ typedef xmlPatParserContext *xmlPatParserContextPtr;
178
+ struct _xmlPatParserContext {
179
+ const xmlChar *cur; /* the current char being parsed */
180
+ const xmlChar *base; /* the full expression */
181
+ int error; /* error code */
182
+ xmlDictPtr dict; /* the dictionary if any */
183
+ xmlPatternPtr comp; /* the result */
184
+ lxb_dom_node_t_ptr elem; /* the current node if any */
185
+ const xmlChar **namespaces; /* the namespaces definitions */
186
+ int nb_namespaces; /* the number of namespaces */
187
+ };
188
+
189
+ /************************************************************************
190
+ * *
191
+ * Type functions *
192
+ * *
193
+ ************************************************************************/
194
+
195
+ /**
196
+ * xmlNewPattern:
197
+ *
198
+ * Create a new XSLT Pattern
199
+ *
200
+ * Returns the newly allocated xmlPatternPtr or NULL in case of error
201
+ */
202
+ static xmlPatternPtr
203
+ xmlNewPattern(void) {
204
+ xmlPatternPtr cur;
205
+
206
+ cur = (xmlPatternPtr) xmlMalloc(sizeof(xmlPattern));
207
+ if (cur == NULL) {
208
+ ERROR(NULL, NULL, NULL,
209
+ "xmlNewPattern : malloc failed\n");
210
+ return(NULL);
211
+ }
212
+ memset(cur, 0, sizeof(xmlPattern));
213
+ cur->maxStep = 10;
214
+ cur->steps = (xmlStepOpPtr) xmlMalloc(cur->maxStep * sizeof(xmlStepOp));
215
+ if (cur->steps == NULL) {
216
+ xmlFree(cur);
217
+ ERROR(NULL, NULL, NULL,
218
+ "xmlNewPattern : malloc failed\n");
219
+ return(NULL);
220
+ }
221
+ return(cur);
222
+ }
223
+
224
+ /**
225
+ * xmlFreePattern:
226
+ * @comp: an XSLT comp
227
+ *
228
+ * Free up the memory allocated by @comp
229
+ */
230
+ void
231
+ xmlFreePattern(xmlPatternPtr comp) {
232
+ xmlFreePatternList(comp);
233
+ }
234
+
235
+ static void
236
+ xmlFreePatternInternal(xmlPatternPtr comp) {
237
+ xmlStepOpPtr op;
238
+ int i;
239
+
240
+ if (comp == NULL)
241
+ return;
242
+ if (comp->stream != NULL)
243
+ xmlFreeStreamComp(comp->stream);
244
+ if (comp->pattern != NULL)
245
+ xmlFree((xmlChar *)comp->pattern);
246
+ if (comp->steps != NULL) {
247
+ if (comp->dict == NULL) {
248
+ for (i = 0;i < comp->nbStep;i++) {
249
+ op = &comp->steps[i];
250
+ if (op->value != NULL)
251
+ xmlFree((xmlChar *) op->value);
252
+ if (op->value2 != NULL)
253
+ xmlFree((xmlChar *) op->value2);
254
+ }
255
+ }
256
+ xmlFree(comp->steps);
257
+ }
258
+ if (comp->dict != NULL)
259
+ xmlDictFree(comp->dict);
260
+
261
+ memset(comp, -1, sizeof(xmlPattern));
262
+ xmlFree(comp);
263
+ }
264
+
265
+ /**
266
+ * xmlFreePatternList:
267
+ * @comp: an XSLT comp list
268
+ *
269
+ * Free up the memory allocated by all the elements of @comp
270
+ */
271
+ void
272
+ xmlFreePatternList(xmlPatternPtr comp) {
273
+ xmlPatternPtr cur;
274
+
275
+ while (comp != NULL) {
276
+ cur = comp;
277
+ comp = comp->next;
278
+ cur->next = NULL;
279
+ xmlFreePatternInternal(cur);
280
+ }
281
+ }
282
+
283
+ /**
284
+ * xmlNewPatParserContext:
285
+ * @pattern: the pattern context
286
+ * @dict: the inherited dictionary or NULL
287
+ * @namespaces: the prefix definitions, array of [URI, prefix] terminated
288
+ * with [NULL, NULL] or NULL if no namespace is used
289
+ *
290
+ * Create a new XML pattern parser context
291
+ *
292
+ * Returns the newly allocated xmlPatParserContextPtr or NULL in case of error
293
+ */
294
+ static xmlPatParserContextPtr
295
+ xmlNewPatParserContext(const xmlChar *pattern, xmlDictPtr dict,
296
+ const xmlChar **namespaces) {
297
+ xmlPatParserContextPtr cur;
298
+
299
+ if (pattern == NULL)
300
+ return(NULL);
301
+
302
+ cur = (xmlPatParserContextPtr) xmlMalloc(sizeof(xmlPatParserContext));
303
+ if (cur == NULL) {
304
+ ERROR(NULL, NULL, NULL,
305
+ "xmlNewPatParserContext : malloc failed\n");
306
+ return(NULL);
307
+ }
308
+ memset(cur, 0, sizeof(xmlPatParserContext));
309
+ cur->dict = dict;
310
+ cur->cur = pattern;
311
+ cur->base = pattern;
312
+ if (namespaces != NULL) {
313
+ int i;
314
+ for (i = 0;namespaces[2 * i] != NULL;i++)
315
+ ;
316
+ cur->nb_namespaces = i;
317
+ } else {
318
+ cur->nb_namespaces = 0;
319
+ }
320
+ cur->namespaces = namespaces;
321
+ return(cur);
322
+ }
323
+
324
+ /**
325
+ * xmlFreePatParserContext:
326
+ * @ctxt: an XSLT parser context
327
+ *
328
+ * Free up the memory allocated by @ctxt
329
+ */
330
+ static void
331
+ xmlFreePatParserContext(xmlPatParserContextPtr ctxt) {
332
+ if (ctxt == NULL)
333
+ return;
334
+ memset(ctxt, -1, sizeof(xmlPatParserContext));
335
+ xmlFree(ctxt);
336
+ }
337
+
338
+ /**
339
+ * xmlPatternAdd:
340
+ * @comp: the compiled match expression
341
+ * @op: an op
342
+ * @value: the first value
343
+ * @value2: the second value
344
+ *
345
+ * Add a step to an XSLT Compiled Match
346
+ *
347
+ * Returns -1 in case of failure, 0 otherwise.
348
+ */
349
+ static int
350
+ xmlPatternAdd(xmlPatParserContextPtr ctxt ATTRIBUTE_UNUSED,
351
+ xmlPatternPtr comp,
352
+ xmlPatOp op, xmlChar * value, xmlChar * value2)
353
+ {
354
+ if (comp->nbStep >= comp->maxStep) {
355
+ xmlStepOpPtr temp;
356
+ temp = (xmlStepOpPtr) xmlRealloc(comp->steps, comp->maxStep * 2 *
357
+ sizeof(xmlStepOp));
358
+ if (temp == NULL) {
359
+ ERROR(ctxt, NULL, NULL,
360
+ "xmlPatternAdd: realloc failed\n");
361
+ return (-1);
362
+ }
363
+ comp->steps = temp;
364
+ comp->maxStep *= 2;
365
+ }
366
+ comp->steps[comp->nbStep].op = op;
367
+ comp->steps[comp->nbStep].value = value;
368
+ comp->steps[comp->nbStep].value2 = value2;
369
+ comp->nbStep++;
370
+ return (0);
371
+ }
372
+
373
+ #if 0
374
+ /**
375
+ * xsltSwapTopPattern:
376
+ * @comp: the compiled match expression
377
+ *
378
+ * reverse the two top steps.
379
+ */
380
+ static void
381
+ xsltSwapTopPattern(xmlPatternPtr comp) {
382
+ int i;
383
+ int j = comp->nbStep - 1;
384
+
385
+ if (j > 0) {
386
+ register const xmlChar *tmp;
387
+ register xmlPatOp op;
388
+ i = j - 1;
389
+ tmp = comp->steps[i].value;
390
+ comp->steps[i].value = comp->steps[j].value;
391
+ comp->steps[j].value = tmp;
392
+ tmp = comp->steps[i].value2;
393
+ comp->steps[i].value2 = comp->steps[j].value2;
394
+ comp->steps[j].value2 = tmp;
395
+ op = comp->steps[i].op;
396
+ comp->steps[i].op = comp->steps[j].op;
397
+ comp->steps[j].op = op;
398
+ }
399
+ }
400
+ #endif
401
+
402
+ /**
403
+ * xmlReversePattern:
404
+ * @comp: the compiled match expression
405
+ *
406
+ * reverse all the stack of expressions
407
+ *
408
+ * returns 0 in case of success and -1 in case of error.
409
+ */
410
+ static int
411
+ xmlReversePattern(xmlPatternPtr comp) {
412
+ int i, j;
413
+
414
+ /*
415
+ * remove the leading // for //a or .//a
416
+ */
417
+ if ((comp->nbStep > 0) && (comp->steps[0].op == XML_OP_ANCESTOR)) {
418
+ for (i = 0, j = 1;j < comp->nbStep;i++,j++) {
419
+ comp->steps[i].value = comp->steps[j].value;
420
+ comp->steps[i].value2 = comp->steps[j].value2;
421
+ comp->steps[i].op = comp->steps[j].op;
422
+ }
423
+ comp->nbStep--;
424
+ }
425
+ if (comp->nbStep >= comp->maxStep) {
426
+ xmlStepOpPtr temp;
427
+ temp = (xmlStepOpPtr) xmlRealloc(comp->steps, comp->maxStep * 2 *
428
+ sizeof(xmlStepOp));
429
+ if (temp == NULL) {
430
+ ERROR(ctxt, NULL, NULL,
431
+ "xmlReversePattern: realloc failed\n");
432
+ return (-1);
433
+ }
434
+ comp->steps = temp;
435
+ comp->maxStep *= 2;
436
+ }
437
+ i = 0;
438
+ j = comp->nbStep - 1;
439
+ while (j > i) {
440
+ register const xmlChar *tmp;
441
+ register xmlPatOp op;
442
+ tmp = comp->steps[i].value;
443
+ comp->steps[i].value = comp->steps[j].value;
444
+ comp->steps[j].value = tmp;
445
+ tmp = comp->steps[i].value2;
446
+ comp->steps[i].value2 = comp->steps[j].value2;
447
+ comp->steps[j].value2 = tmp;
448
+ op = comp->steps[i].op;
449
+ comp->steps[i].op = comp->steps[j].op;
450
+ comp->steps[j].op = op;
451
+ j--;
452
+ i++;
453
+ }
454
+ comp->steps[comp->nbStep].value = NULL;
455
+ comp->steps[comp->nbStep].value2 = NULL;
456
+ comp->steps[comp->nbStep++].op = XML_OP_END;
457
+ return(0);
458
+ }
459
+
460
+ /************************************************************************
461
+ * *
462
+ * The interpreter for the precompiled patterns *
463
+ * *
464
+ ************************************************************************/
465
+
466
+ static int
467
+ xmlPatPushState(xmlStepStates *states, int step, lxb_dom_node_t_ptr node) {
468
+ if ((states->states == NULL) || (states->maxstates <= 0)) {
469
+ states->maxstates = 4;
470
+ states->nbstates = 0;
471
+ states->states = xmlMalloc(4 * sizeof(xmlStepState));
472
+ }
473
+ else if (states->maxstates <= states->nbstates) {
474
+ xmlStepState *tmp;
475
+
476
+ tmp = (xmlStepStatePtr) xmlRealloc(states->states,
477
+ 2 * states->maxstates * sizeof(xmlStepState));
478
+ if (tmp == NULL)
479
+ return(-1);
480
+ states->states = tmp;
481
+ states->maxstates *= 2;
482
+ }
483
+ states->states[states->nbstates].step = step;
484
+ states->states[states->nbstates++].node = node;
485
+ #if 0
486
+ fprintf(stderr, "Push: %d, %s\n", step, node->name);
487
+ #endif
488
+ return(0);
489
+ }
490
+
491
+ /************************************************************************
492
+ * *
493
+ * Dedicated parser for templates *
494
+ * *
495
+ ************************************************************************/
496
+
497
+ #define TODO \
498
+ xmlGenericError(xmlGenericErrorContext, \
499
+ "Unimplemented block at %s:%d\n", \
500
+ __FILE__, __LINE__);
501
+ #define CUR (*ctxt->cur)
502
+ #define SKIP(val) ctxt->cur += (val)
503
+ #define NXT(val) ctxt->cur[(val)]
504
+ #define PEEKPREV(val) ctxt->cur[-(val)]
505
+ #define CUR_PTR ctxt->cur
506
+
507
+ #define SKIP_BLANKS \
508
+ while (IS_BLANK_CH(CUR)) NEXT
509
+
510
+ #define CURRENT (*ctxt->cur)
511
+ #define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur)
512
+
513
+
514
+ #define PUSH(op, val, val2) \
515
+ if (xmlPatternAdd(ctxt, ctxt->comp, (op), (val), (val2))) goto error;
516
+
517
+ #define XSLT_ERROR(X) \
518
+ { xsltError(ctxt, __FILE__, __LINE__, X); \
519
+ ctxt->error = (X); return; }
520
+
521
+ #define XSLT_ERROR0(X) \
522
+ { xsltError(ctxt, __FILE__, __LINE__, X); \
523
+ ctxt->error = (X); return(0); }
524
+
525
+ #if 0
526
+ /**
527
+ * xmlPatScanLiteral:
528
+ * @ctxt: the XPath Parser context
529
+ *
530
+ * Parse an XPath Literal:
531
+ *
532
+ * [29] Literal ::= '"' [^"]* '"'
533
+ * | "'" [^']* "'"
534
+ *
535
+ * Returns the Literal parsed or NULL
536
+ */
537
+
538
+ static xmlChar *
539
+ xmlPatScanLiteral(xmlPatParserContextPtr ctxt) {
540
+ const xmlChar *q, *cur;
541
+ xmlChar *ret = NULL;
542
+ int val, len;
543
+
544
+ SKIP_BLANKS;
545
+ if (CUR == '"') {
546
+ NEXT;
547
+ cur = q = CUR_PTR;
548
+ val = xmlStringCurrentChar(NULL, cur, &len);
549
+ while ((IS_CHAR(val)) && (val != '"')) {
550
+ cur += len;
551
+ val = xmlStringCurrentChar(NULL, cur, &len);
552
+ }
553
+ if (!IS_CHAR(val)) {
554
+ ctxt->error = 1;
555
+ return(NULL);
556
+ } else {
557
+ if (ctxt->dict)
558
+ ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);
559
+ else
560
+ ret = xmlStrndup(q, cur - q);
561
+ }
562
+ cur += len;
563
+ CUR_PTR = cur;
564
+ } else if (CUR == '\'') {
565
+ NEXT;
566
+ cur = q = CUR_PTR;
567
+ val = xmlStringCurrentChar(NULL, cur, &len);
568
+ while ((IS_CHAR(val)) && (val != '\'')) {
569
+ cur += len;
570
+ val = xmlStringCurrentChar(NULL, cur, &len);
571
+ }
572
+ if (!IS_CHAR(val)) {
573
+ ctxt->error = 1;
574
+ return(NULL);
575
+ } else {
576
+ if (ctxt->dict)
577
+ ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);
578
+ else
579
+ ret = xmlStrndup(q, cur - q);
580
+ }
581
+ cur += len;
582
+ CUR_PTR = cur;
583
+ } else {
584
+ /* XP_ERROR(XPATH_START_LITERAL_ERROR); */
585
+ ctxt->error = 1;
586
+ return(NULL);
587
+ }
588
+ return(ret);
589
+ }
590
+ #endif
591
+
592
+ /**
593
+ * xmlPatScanName:
594
+ * @ctxt: the XPath Parser context
595
+ *
596
+ * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' |
597
+ * CombiningChar | Extender
598
+ *
599
+ * [5] Name ::= (Letter | '_' | ':') (NameChar)*
600
+ *
601
+ * [6] Names ::= Name (S Name)*
602
+ *
603
+ * Returns the Name parsed or NULL
604
+ */
605
+
606
+ static xmlChar *
607
+ xmlPatScanName(xmlPatParserContextPtr ctxt) {
608
+ const xmlChar *q, *cur;
609
+ xmlChar *ret = NULL;
610
+ int val, len;
611
+
612
+ SKIP_BLANKS;
613
+
614
+ cur = q = CUR_PTR;
615
+ val = xmlStringCurrentChar(NULL, cur, &len);
616
+ if (!IS_LETTER(val) && (val != '_') && (val != ':'))
617
+ return(NULL);
618
+
619
+ while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
620
+ (val == '.') || (val == '-') ||
621
+ (val == '_') ||
622
+ (IS_COMBINING(val)) ||
623
+ (IS_EXTENDER(val))) {
624
+ cur += len;
625
+ val = xmlStringCurrentChar(NULL, cur, &len);
626
+ }
627
+ if (ctxt->dict)
628
+ ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);
629
+ else
630
+ ret = xmlStrndup(q, cur - q);
631
+ CUR_PTR = cur;
632
+ return(ret);
633
+ }
634
+
635
+ /**
636
+ * xmlPatScanNCName:
637
+ * @ctxt: the XPath Parser context
638
+ *
639
+ * Parses a non qualified name
640
+ *
641
+ * Returns the Name parsed or NULL
642
+ */
643
+
644
+ static xmlChar *
645
+ xmlPatScanNCName(xmlPatParserContextPtr ctxt) {
646
+ const xmlChar *q, *cur;
647
+ xmlChar *ret = NULL;
648
+ int val, len;
649
+
650
+ SKIP_BLANKS;
651
+
652
+ cur = q = CUR_PTR;
653
+ val = xmlStringCurrentChar(NULL, cur, &len);
654
+ if (!IS_LETTER(val) && (val != '_'))
655
+ return(NULL);
656
+
657
+ while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
658
+ (val == '.') || (val == '-') ||
659
+ (val == '_') ||
660
+ (IS_COMBINING(val)) ||
661
+ (IS_EXTENDER(val))) {
662
+ cur += len;
663
+ val = xmlStringCurrentChar(NULL, cur, &len);
664
+ }
665
+ if (ctxt->dict)
666
+ ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);
667
+ else
668
+ ret = xmlStrndup(q, cur - q);
669
+ CUR_PTR = cur;
670
+ return(ret);
671
+ }
672
+
673
+ #if 0
674
+ /**
675
+ * xmlPatScanQName:
676
+ * @ctxt: the XPath Parser context
677
+ * @prefix: the place to store the prefix
678
+ *
679
+ * Parse a qualified name
680
+ *
681
+ * Returns the Name parsed or NULL
682
+ */
683
+
684
+ static xmlChar *
685
+ xmlPatScanQName(xmlPatParserContextPtr ctxt, xmlChar **prefix) {
686
+ xmlChar *ret = NULL;
687
+
688
+ *prefix = NULL;
689
+ ret = xmlPatScanNCName(ctxt);
690
+ if (CUR == ':') {
691
+ *prefix = ret;
692
+ NEXT;
693
+ ret = xmlPatScanNCName(ctxt);
694
+ }
695
+ return(ret);
696
+ }
697
+ #endif
698
+
699
+ /**
700
+ * xmlCompileAttributeTest:
701
+ * @ctxt: the compilation context
702
+ *
703
+ * Compile an attribute test.
704
+ */
705
+ static void
706
+ xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) {
707
+ xmlChar *token = NULL;
708
+ xmlChar *name = NULL;
709
+ xmlChar *URL = NULL;
710
+
711
+ SKIP_BLANKS;
712
+ name = xmlPatScanNCName(ctxt);
713
+ if (name == NULL) {
714
+ if (CUR == '*') {
715
+ PUSH(XML_OP_ATTR, NULL, NULL);
716
+ NEXT;
717
+ } else {
718
+ ERROR(NULL, NULL, NULL,
719
+ "xmlCompileAttributeTest : Name expected\n");
720
+ ctxt->error = 1;
721
+ }
722
+ return;
723
+ }
724
+ if (CUR == ':') {
725
+ int i;
726
+ xmlChar *prefix = name;
727
+
728
+ NEXT;
729
+
730
+ if (IS_BLANK_CH(CUR)) {
731
+ ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL);
732
+ XML_PAT_FREE_STRING(ctxt, prefix);
733
+ ctxt->error = 1;
734
+ goto error;
735
+ }
736
+ /*
737
+ * This is a namespace match
738
+ */
739
+ token = xmlPatScanName(ctxt);
740
+ if ((prefix[0] == 'x') &&
741
+ (prefix[1] == 'm') &&
742
+ (prefix[2] == 'l') &&
743
+ (prefix[3] == 0))
744
+ {
745
+ XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE);
746
+ } else {
747
+ for (i = 0;i < ctxt->nb_namespaces;i++) {
748
+ if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
749
+ XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i])
750
+ break;
751
+ }
752
+ }
753
+ if (i >= ctxt->nb_namespaces) {
754
+ ERROR5(NULL, NULL, NULL,
755
+ "xmlCompileAttributeTest : no namespace bound to prefix %s\n",
756
+ prefix);
757
+ XML_PAT_FREE_STRING(ctxt, prefix);
758
+ ctxt->error = 1;
759
+ goto error;
760
+ }
761
+ }
762
+ XML_PAT_FREE_STRING(ctxt, prefix);
763
+ if (token == NULL) {
764
+ if (CUR == '*') {
765
+ NEXT;
766
+ PUSH(XML_OP_ATTR, NULL, URL);
767
+ } else {
768
+ ERROR(NULL, NULL, NULL,
769
+ "xmlCompileAttributeTest : Name expected\n");
770
+ ctxt->error = 1;
771
+ goto error;
772
+ }
773
+ } else {
774
+ PUSH(XML_OP_ATTR, token, URL);
775
+ }
776
+ } else {
777
+ PUSH(XML_OP_ATTR, name, NULL);
778
+ }
779
+ return;
780
+ error:
781
+ if (URL != NULL)
782
+ XML_PAT_FREE_STRING(ctxt, URL)
783
+ if (token != NULL)
784
+ XML_PAT_FREE_STRING(ctxt, token);
785
+ }
786
+
787
+ /**
788
+ * xmlCompileStepPattern:
789
+ * @ctxt: the compilation context
790
+ *
791
+ * Compile the Step Pattern and generates a precompiled
792
+ * form suitable for fast matching.
793
+ *
794
+ * [3] Step ::= '.' | NameTest
795
+ * [4] NameTest ::= QName | '*' | NCName ':' '*'
796
+ */
797
+
798
+ static void
799
+ xmlCompileStepPattern(xmlPatParserContextPtr ctxt) {
800
+ xmlChar *token = NULL;
801
+ xmlChar *name = NULL;
802
+ xmlChar *URL = NULL;
803
+ int hasBlanks = 0;
804
+
805
+ SKIP_BLANKS;
806
+ if (CUR == '.') {
807
+ /*
808
+ * Context node.
809
+ */
810
+ NEXT;
811
+ PUSH(XML_OP_ELEM, NULL, NULL);
812
+ return;
813
+ }
814
+ if (CUR == '@') {
815
+ /*
816
+ * Attribute test.
817
+ */
818
+ if (XML_STREAM_XS_IDC_SEL(ctxt->comp)) {
819
+ ERROR5(NULL, NULL, NULL,
820
+ "Unexpected attribute axis in '%s'.\n", ctxt->base);
821
+ ctxt->error = 1;
822
+ return;
823
+ }
824
+ NEXT;
825
+ xmlCompileAttributeTest(ctxt);
826
+ if (ctxt->error != 0)
827
+ goto error;
828
+ return;
829
+ }
830
+ name = xmlPatScanNCName(ctxt);
831
+ if (name == NULL) {
832
+ if (CUR == '*') {
833
+ NEXT;
834
+ PUSH(XML_OP_ALL, NULL, NULL);
835
+ return;
836
+ } else {
837
+ ERROR(NULL, NULL, NULL,
838
+ "xmlCompileStepPattern : Name expected\n");
839
+ ctxt->error = 1;
840
+ return;
841
+ }
842
+ }
843
+ if (IS_BLANK_CH(CUR)) {
844
+ hasBlanks = 1;
845
+ SKIP_BLANKS;
846
+ }
847
+ if (CUR == ':') {
848
+ NEXT;
849
+ if (CUR != ':') {
850
+ xmlChar *prefix = name;
851
+ int i;
852
+
853
+ if (hasBlanks || IS_BLANK_CH(CUR)) {
854
+ ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL);
855
+ ctxt->error = 1;
856
+ goto error;
857
+ }
858
+ /*
859
+ * This is a namespace match
860
+ */
861
+ token = xmlPatScanName(ctxt);
862
+ if ((prefix[0] == 'x') &&
863
+ (prefix[1] == 'm') &&
864
+ (prefix[2] == 'l') &&
865
+ (prefix[3] == 0))
866
+ {
867
+ XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE)
868
+ } else {
869
+ for (i = 0;i < ctxt->nb_namespaces;i++) {
870
+ if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
871
+ XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i])
872
+ break;
873
+ }
874
+ }
875
+ if (i >= ctxt->nb_namespaces) {
876
+ ERROR5(NULL, NULL, NULL,
877
+ "xmlCompileStepPattern : no namespace bound to prefix %s\n",
878
+ prefix);
879
+ ctxt->error = 1;
880
+ goto error;
881
+ }
882
+ }
883
+ XML_PAT_FREE_STRING(ctxt, prefix);
884
+ name = NULL;
885
+ if (token == NULL) {
886
+ if (CUR == '*') {
887
+ NEXT;
888
+ PUSH(XML_OP_NS, URL, NULL);
889
+ } else {
890
+ ERROR(NULL, NULL, NULL,
891
+ "xmlCompileStepPattern : Name expected\n");
892
+ ctxt->error = 1;
893
+ goto error;
894
+ }
895
+ } else {
896
+ PUSH(XML_OP_ELEM, token, URL);
897
+ }
898
+ } else {
899
+ NEXT;
900
+ if (xmlStrEqual(name, (const xmlChar *) "child")) {
901
+ XML_PAT_FREE_STRING(ctxt, name);
902
+ name = xmlPatScanName(ctxt);
903
+ if (name == NULL) {
904
+ if (CUR == '*') {
905
+ NEXT;
906
+ PUSH(XML_OP_ALL, NULL, NULL);
907
+ return;
908
+ } else {
909
+ ERROR(NULL, NULL, NULL,
910
+ "xmlCompileStepPattern : QName expected\n");
911
+ ctxt->error = 1;
912
+ goto error;
913
+ }
914
+ }
915
+ if (CUR == ':') {
916
+ xmlChar *prefix = name;
917
+ int i;
918
+
919
+ NEXT;
920
+ if (IS_BLANK_CH(CUR)) {
921
+ ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL);
922
+ ctxt->error = 1;
923
+ goto error;
924
+ }
925
+ /*
926
+ * This is a namespace match
927
+ */
928
+ token = xmlPatScanName(ctxt);
929
+ if ((prefix[0] == 'x') &&
930
+ (prefix[1] == 'm') &&
931
+ (prefix[2] == 'l') &&
932
+ (prefix[3] == 0))
933
+ {
934
+ XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE)
935
+ } else {
936
+ for (i = 0;i < ctxt->nb_namespaces;i++) {
937
+ if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
938
+ XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i])
939
+ break;
940
+ }
941
+ }
942
+ if (i >= ctxt->nb_namespaces) {
943
+ ERROR5(NULL, NULL, NULL,
944
+ "xmlCompileStepPattern : no namespace bound "
945
+ "to prefix %s\n", prefix);
946
+ ctxt->error = 1;
947
+ goto error;
948
+ }
949
+ }
950
+ XML_PAT_FREE_STRING(ctxt, prefix);
951
+ name = NULL;
952
+ if (token == NULL) {
953
+ if (CUR == '*') {
954
+ NEXT;
955
+ PUSH(XML_OP_NS, URL, NULL);
956
+ } else {
957
+ ERROR(NULL, NULL, NULL,
958
+ "xmlCompileStepPattern : Name expected\n");
959
+ ctxt->error = 1;
960
+ goto error;
961
+ }
962
+ } else {
963
+ PUSH(XML_OP_CHILD, token, URL);
964
+ }
965
+ } else
966
+ PUSH(XML_OP_CHILD, name, NULL);
967
+ return;
968
+ } else if (xmlStrEqual(name, (const xmlChar *) "attribute")) {
969
+ XML_PAT_FREE_STRING(ctxt, name)
970
+ name = NULL;
971
+ if (XML_STREAM_XS_IDC_SEL(ctxt->comp)) {
972
+ ERROR5(NULL, NULL, NULL,
973
+ "Unexpected attribute axis in '%s'.\n", ctxt->base);
974
+ ctxt->error = 1;
975
+ goto error;
976
+ }
977
+ xmlCompileAttributeTest(ctxt);
978
+ if (ctxt->error != 0)
979
+ goto error;
980
+ return;
981
+ } else {
982
+ ERROR5(NULL, NULL, NULL,
983
+ "The 'element' or 'attribute' axis is expected.\n", NULL);
984
+ ctxt->error = 1;
985
+ goto error;
986
+ }
987
+ }
988
+ } else if (CUR == '*') {
989
+ if (name != NULL) {
990
+ ctxt->error = 1;
991
+ goto error;
992
+ }
993
+ NEXT;
994
+ PUSH(XML_OP_ALL, token, NULL);
995
+ } else {
996
+ PUSH(XML_OP_ELEM, name, NULL);
997
+ }
998
+ return;
999
+ error:
1000
+ if (URL != NULL)
1001
+ XML_PAT_FREE_STRING(ctxt, URL)
1002
+ if (token != NULL)
1003
+ XML_PAT_FREE_STRING(ctxt, token)
1004
+ if (name != NULL)
1005
+ XML_PAT_FREE_STRING(ctxt, name)
1006
+ }
1007
+
1008
+ /**
1009
+ * xmlCompilePathPattern:
1010
+ * @ctxt: the compilation context
1011
+ *
1012
+ * Compile the Path Pattern and generates a precompiled
1013
+ * form suitable for fast matching.
1014
+ *
1015
+ * [5] Path ::= ('.//')? ( Step '/' )* ( Step | '@' NameTest )
1016
+ */
1017
+ static void
1018
+ xmlCompilePathPattern(xmlPatParserContextPtr ctxt) {
1019
+ SKIP_BLANKS;
1020
+ if (CUR == '/') {
1021
+ ctxt->comp->flags |= PAT_FROM_ROOT;
1022
+ } else if ((CUR == '.') || (ctxt->comp->flags & XML_PATTERN_NOTPATTERN)) {
1023
+ ctxt->comp->flags |= PAT_FROM_CUR;
1024
+ }
1025
+
1026
+ if ((CUR == '/') && (NXT(1) == '/')) {
1027
+ PUSH(XML_OP_ANCESTOR, NULL, NULL);
1028
+ NEXT;
1029
+ NEXT;
1030
+ } else if ((CUR == '.') && (NXT(1) == '/') && (NXT(2) == '/')) {
1031
+ PUSH(XML_OP_ANCESTOR, NULL, NULL);
1032
+ NEXT;
1033
+ NEXT;
1034
+ NEXT;
1035
+ /* Check for incompleteness. */
1036
+ SKIP_BLANKS;
1037
+ if (CUR == 0) {
1038
+ ERROR5(NULL, NULL, NULL,
1039
+ "Incomplete expression '%s'.\n", ctxt->base);
1040
+ ctxt->error = 1;
1041
+ goto error;
1042
+ }
1043
+ }
1044
+ if (CUR == '@') {
1045
+ NEXT;
1046
+ xmlCompileAttributeTest(ctxt);
1047
+ SKIP_BLANKS;
1048
+ /* TODO: check for incompleteness */
1049
+ if (CUR != 0) {
1050
+ xmlCompileStepPattern(ctxt);
1051
+ if (ctxt->error != 0)
1052
+ goto error;
1053
+ }
1054
+ } else {
1055
+ if (CUR == '/') {
1056
+ PUSH(XML_OP_ROOT, NULL, NULL);
1057
+ NEXT;
1058
+ /* Check for incompleteness. */
1059
+ SKIP_BLANKS;
1060
+ if (CUR == 0) {
1061
+ ERROR5(NULL, NULL, NULL,
1062
+ "Incomplete expression '%s'.\n", ctxt->base);
1063
+ ctxt->error = 1;
1064
+ goto error;
1065
+ }
1066
+ }
1067
+ xmlCompileStepPattern(ctxt);
1068
+ if (ctxt->error != 0)
1069
+ goto error;
1070
+ SKIP_BLANKS;
1071
+ while (CUR == '/') {
1072
+ if (NXT(1) == '/') {
1073
+ PUSH(XML_OP_ANCESTOR, NULL, NULL);
1074
+ NEXT;
1075
+ NEXT;
1076
+ SKIP_BLANKS;
1077
+ xmlCompileStepPattern(ctxt);
1078
+ if (ctxt->error != 0)
1079
+ goto error;
1080
+ } else {
1081
+ PUSH(XML_OP_PARENT, NULL, NULL);
1082
+ NEXT;
1083
+ SKIP_BLANKS;
1084
+ if (CUR == 0) {
1085
+ ERROR5(NULL, NULL, NULL,
1086
+ "Incomplete expression '%s'.\n", ctxt->base);
1087
+ ctxt->error = 1;
1088
+ goto error;
1089
+ }
1090
+ xmlCompileStepPattern(ctxt);
1091
+ if (ctxt->error != 0)
1092
+ goto error;
1093
+ }
1094
+ }
1095
+ }
1096
+ if (CUR != 0) {
1097
+ ERROR5(NULL, NULL, NULL,
1098
+ "Failed to compile pattern %s\n", ctxt->base);
1099
+ ctxt->error = 1;
1100
+ }
1101
+ error:
1102
+ return;
1103
+ }
1104
+
1105
+ /**
1106
+ * xmlCompileIDCXPathPath:
1107
+ * @ctxt: the compilation context
1108
+ *
1109
+ * Compile the Path Pattern and generates a precompiled
1110
+ * form suitable for fast matching.
1111
+ *
1112
+ * [5] Path ::= ('.//')? ( Step '/' )* ( Step | '@' NameTest )
1113
+ */
1114
+ static void
1115
+ xmlCompileIDCXPathPath(xmlPatParserContextPtr ctxt) {
1116
+ SKIP_BLANKS;
1117
+ if (CUR == '/') {
1118
+ ERROR5(NULL, NULL, NULL,
1119
+ "Unexpected selection of the document root in '%s'.\n",
1120
+ ctxt->base);
1121
+ goto error;
1122
+ }
1123
+ ctxt->comp->flags |= PAT_FROM_CUR;
1124
+
1125
+ if (CUR == '.') {
1126
+ /* "." - "self::node()" */
1127
+ NEXT;
1128
+ SKIP_BLANKS;
1129
+ if (CUR == 0) {
1130
+ /*
1131
+ * Selection of the context node.
1132
+ */
1133
+ PUSH(XML_OP_ELEM, NULL, NULL);
1134
+ return;
1135
+ }
1136
+ if (CUR != '/') {
1137
+ /* TODO: A more meaningful error message. */
1138
+ ERROR5(NULL, NULL, NULL,
1139
+ "Unexpected token after '.' in '%s'.\n", ctxt->base);
1140
+ goto error;
1141
+ }
1142
+ /* "./" - "self::node()/" */
1143
+ NEXT;
1144
+ SKIP_BLANKS;
1145
+ if (CUR == '/') {
1146
+ if (IS_BLANK_CH(PEEKPREV(1))) {
1147
+ /*
1148
+ * Disallow "./ /"
1149
+ */
1150
+ ERROR5(NULL, NULL, NULL,
1151
+ "Unexpected '/' token in '%s'.\n", ctxt->base);
1152
+ goto error;
1153
+ }
1154
+ /* ".//" - "self:node()/descendant-or-self::node()/" */
1155
+ PUSH(XML_OP_ANCESTOR, NULL, NULL);
1156
+ NEXT;
1157
+ SKIP_BLANKS;
1158
+ }
1159
+ if (CUR == 0)
1160
+ goto error_unfinished;
1161
+ }
1162
+ /*
1163
+ * Process steps.
1164
+ */
1165
+ do {
1166
+ xmlCompileStepPattern(ctxt);
1167
+ if (ctxt->error != 0)
1168
+ goto error;
1169
+ SKIP_BLANKS;
1170
+ if (CUR != '/')
1171
+ break;
1172
+ PUSH(XML_OP_PARENT, NULL, NULL);
1173
+ NEXT;
1174
+ SKIP_BLANKS;
1175
+ if (CUR == '/') {
1176
+ /*
1177
+ * Disallow subsequent '//'.
1178
+ */
1179
+ ERROR5(NULL, NULL, NULL,
1180
+ "Unexpected subsequent '//' in '%s'.\n",
1181
+ ctxt->base);
1182
+ goto error;
1183
+ }
1184
+ if (CUR == 0)
1185
+ goto error_unfinished;
1186
+
1187
+ } while (CUR != 0);
1188
+
1189
+ if (CUR != 0) {
1190
+ ERROR5(NULL, NULL, NULL,
1191
+ "Failed to compile expression '%s'.\n", ctxt->base);
1192
+ ctxt->error = 1;
1193
+ }
1194
+ return;
1195
+ error:
1196
+ ctxt->error = 1;
1197
+ return;
1198
+
1199
+ error_unfinished:
1200
+ ctxt->error = 1;
1201
+ ERROR5(NULL, NULL, NULL,
1202
+ "Unfinished expression '%s'.\n", ctxt->base);
1203
+ return;
1204
+ }
1205
+
1206
+ /************************************************************************
1207
+ * *
1208
+ * The streaming code *
1209
+ * *
1210
+ ************************************************************************/
1211
+
1212
+ #ifdef DEBUG_STREAMING
1213
+ static void
1214
+ xmlDebugStreamComp(xmlStreamCompPtr stream) {
1215
+ int i;
1216
+
1217
+ if (stream == NULL) {
1218
+ printf("Stream: NULL\n");
1219
+ return;
1220
+ }
1221
+ printf("Stream: %d steps\n", stream->nbStep);
1222
+ for (i = 0;i < stream->nbStep;i++) {
1223
+ if (stream->steps[i].ns != NULL) {
1224
+ printf("{%s}", stream->steps[i].ns);
1225
+ }
1226
+ if (stream->steps[i].name == NULL) {
1227
+ printf("* ");
1228
+ } else {
1229
+ printf("%s ", stream->steps[i].name);
1230
+ }
1231
+ if (stream->steps[i].flags & XML_STREAM_STEP_ROOT)
1232
+ printf("root ");
1233
+ if (stream->steps[i].flags & XML_STREAM_STEP_DESC)
1234
+ printf("// ");
1235
+ if (stream->steps[i].flags & XML_STREAM_STEP_FINAL)
1236
+ printf("final ");
1237
+ printf("\n");
1238
+ }
1239
+ }
1240
+ static void
1241
+ xmlDebugStreamCtxt(xmlStreamCtxtPtr ctxt, int match) {
1242
+ int i;
1243
+
1244
+ if (ctxt == NULL) {
1245
+ printf("Stream: NULL\n");
1246
+ return;
1247
+ }
1248
+ printf("Stream: level %d, %d states: ", ctxt->level, ctxt->nbState);
1249
+ if (match)
1250
+ printf("matches\n");
1251
+ else
1252
+ printf("\n");
1253
+ for (i = 0;i < ctxt->nbState;i++) {
1254
+ if (ctxt->states[2 * i] < 0)
1255
+ printf(" %d: free\n", i);
1256
+ else {
1257
+ printf(" %d: step %d, level %d", i, ctxt->states[2 * i],
1258
+ ctxt->states[(2 * i) + 1]);
1259
+ if (ctxt->comp->steps[ctxt->states[2 * i]].flags &
1260
+ XML_STREAM_STEP_DESC)
1261
+ printf(" //\n");
1262
+ else
1263
+ printf("\n");
1264
+ }
1265
+ }
1266
+ }
1267
+ #endif
1268
+ /**
1269
+ * xmlNewStreamComp:
1270
+ * @size: the number of expected steps
1271
+ *
1272
+ * build a new compiled pattern for streaming
1273
+ *
1274
+ * Returns the new structure or NULL in case of error.
1275
+ */
1276
+ static xmlStreamCompPtr
1277
+ xmlNewStreamComp(int size) {
1278
+ xmlStreamCompPtr cur;
1279
+
1280
+ if (size < 4)
1281
+ size = 4;
1282
+
1283
+ cur = (xmlStreamCompPtr) xmlMalloc(sizeof(xmlStreamComp));
1284
+ if (cur == NULL) {
1285
+ ERROR(NULL, NULL, NULL,
1286
+ "xmlNewStreamComp: malloc failed\n");
1287
+ return(NULL);
1288
+ }
1289
+ memset(cur, 0, sizeof(xmlStreamComp));
1290
+ cur->steps = (xmlStreamStepPtr) xmlMalloc(size * sizeof(xmlStreamStep));
1291
+ if (cur->steps == NULL) {
1292
+ xmlFree(cur);
1293
+ ERROR(NULL, NULL, NULL,
1294
+ "xmlNewStreamComp: malloc failed\n");
1295
+ return(NULL);
1296
+ }
1297
+ cur->nbStep = 0;
1298
+ cur->maxStep = size;
1299
+ return(cur);
1300
+ }
1301
+
1302
+ /**
1303
+ * xmlFreeStreamComp:
1304
+ * @comp: the compiled pattern for streaming
1305
+ *
1306
+ * Free the compiled pattern for streaming
1307
+ */
1308
+ static void
1309
+ xmlFreeStreamComp(xmlStreamCompPtr comp) {
1310
+ if (comp != NULL) {
1311
+ if (comp->steps != NULL)
1312
+ xmlFree(comp->steps);
1313
+ if (comp->dict != NULL)
1314
+ xmlDictFree(comp->dict);
1315
+ xmlFree(comp);
1316
+ }
1317
+ }
1318
+
1319
+ /**
1320
+ * xmlStreamCompAddStep:
1321
+ * @comp: the compiled pattern for streaming
1322
+ * @name: the first string, the name, or NULL for *
1323
+ * @ns: the second step, the namespace name
1324
+ * @flags: the flags for that step
1325
+ *
1326
+ * Add a new step to the compiled pattern
1327
+ *
1328
+ * Returns -1 in case of error or the step index if successful
1329
+ */
1330
+ static int
1331
+ xmlStreamCompAddStep(xmlStreamCompPtr comp, const xmlChar *name,
1332
+ const xmlChar *ns, int nodeType, int flags) {
1333
+ xmlStreamStepPtr cur;
1334
+
1335
+ if (comp->nbStep >= comp->maxStep) {
1336
+ cur = (xmlStreamStepPtr) xmlRealloc(comp->steps,
1337
+ comp->maxStep * 2 * sizeof(xmlStreamStep));
1338
+ if (cur == NULL) {
1339
+ ERROR(NULL, NULL, NULL,
1340
+ "xmlNewStreamComp: malloc failed\n");
1341
+ return(-1);
1342
+ }
1343
+ comp->steps = cur;
1344
+ comp->maxStep *= 2;
1345
+ }
1346
+ cur = &comp->steps[comp->nbStep++];
1347
+ cur->flags = flags;
1348
+ cur->name = name;
1349
+ cur->ns = ns;
1350
+ cur->nodeType = nodeType;
1351
+ return(comp->nbStep - 1);
1352
+ }
1353
+
1354
+ /**
1355
+ * xmlStreamCompile:
1356
+ * @comp: the precompiled pattern
1357
+ *
1358
+ * Tries to stream compile a pattern
1359
+ *
1360
+ * Returns -1 in case of failure and 0 in case of success.
1361
+ */
1362
+ static int
1363
+ xmlStreamCompile(xmlPatternPtr comp) {
1364
+ xmlStreamCompPtr stream;
1365
+ int i, s = 0, root = 0, flags = 0, prevs = -1;
1366
+ xmlStepOp step;
1367
+
1368
+ if ((comp == NULL) || (comp->steps == NULL))
1369
+ return(-1);
1370
+ /*
1371
+ * special case for .
1372
+ */
1373
+ if ((comp->nbStep == 1) &&
1374
+ (comp->steps[0].op == XML_OP_ELEM) &&
1375
+ (comp->steps[0].value == NULL) &&
1376
+ (comp->steps[0].value2 == NULL)) {
1377
+ stream = xmlNewStreamComp(0);
1378
+ if (stream == NULL)
1379
+ return(-1);
1380
+ /* Note that the stream will have no steps in this case. */
1381
+ stream->flags |= XML_STREAM_FINAL_IS_ANY_NODE;
1382
+ comp->stream = stream;
1383
+ return(0);
1384
+ }
1385
+
1386
+ stream = xmlNewStreamComp((comp->nbStep / 2) + 1);
1387
+ if (stream == NULL)
1388
+ return(-1);
1389
+ if (comp->dict != NULL) {
1390
+ stream->dict = comp->dict;
1391
+ xmlDictReference(stream->dict);
1392
+ }
1393
+
1394
+ i = 0;
1395
+ if (comp->flags & PAT_FROM_ROOT)
1396
+ stream->flags |= XML_STREAM_FROM_ROOT;
1397
+
1398
+ for (;i < comp->nbStep;i++) {
1399
+ step = comp->steps[i];
1400
+ switch (step.op) {
1401
+ case XML_OP_END:
1402
+ break;
1403
+ case XML_OP_ROOT:
1404
+ if (i != 0)
1405
+ goto error;
1406
+ root = 1;
1407
+ break;
1408
+ case XML_OP_NS:
1409
+ s = xmlStreamCompAddStep(stream, NULL, step.value,
1410
+ XML_ELEMENT_NODE, flags);
1411
+ if (s < 0)
1412
+ goto error;
1413
+ prevs = s;
1414
+ flags = 0;
1415
+ break;
1416
+ case XML_OP_ATTR:
1417
+ flags |= XML_STREAM_STEP_ATTR;
1418
+ prevs = -1;
1419
+ s = xmlStreamCompAddStep(stream,
1420
+ step.value, step.value2, XML_ATTRIBUTE_NODE, flags);
1421
+ flags = 0;
1422
+ if (s < 0)
1423
+ goto error;
1424
+ break;
1425
+ case XML_OP_ELEM:
1426
+ if ((step.value == NULL) && (step.value2 == NULL)) {
1427
+ /*
1428
+ * We have a "." or "self::node()" here.
1429
+ * Eliminate redundant self::node() tests like in "/./."
1430
+ * or "//./"
1431
+ * The only case we won't eliminate is "//.", i.e. if
1432
+ * self::node() is the last node test and we had
1433
+ * continuation somewhere beforehand.
1434
+ */
1435
+ if ((comp->nbStep == i + 1) &&
1436
+ (flags & XML_STREAM_STEP_DESC)) {
1437
+ /*
1438
+ * Mark the special case where the expression resolves
1439
+ * to any type of node.
1440
+ */
1441
+ if (comp->nbStep == i + 1) {
1442
+ stream->flags |= XML_STREAM_FINAL_IS_ANY_NODE;
1443
+ }
1444
+ flags |= XML_STREAM_STEP_NODE;
1445
+ s = xmlStreamCompAddStep(stream, NULL, NULL,
1446
+ XML_STREAM_ANY_NODE, flags);
1447
+ if (s < 0)
1448
+ goto error;
1449
+ flags = 0;
1450
+ /*
1451
+ * If there was a previous step, mark it to be added to
1452
+ * the result node-set; this is needed since only
1453
+ * the last step will be marked as "final" and only
1454
+ * "final" nodes are added to the resulting set.
1455
+ */
1456
+ if (prevs != -1) {
1457
+ stream->steps[prevs].flags |= XML_STREAM_STEP_IN_SET;
1458
+ prevs = -1;
1459
+ }
1460
+ break;
1461
+
1462
+ } else {
1463
+ /* Just skip this one. */
1464
+ continue;
1465
+ }
1466
+ }
1467
+ /* An element node. */
1468
+ s = xmlStreamCompAddStep(stream, step.value, step.value2,
1469
+ XML_ELEMENT_NODE, flags);
1470
+ if (s < 0)
1471
+ goto error;
1472
+ prevs = s;
1473
+ flags = 0;
1474
+ break;
1475
+ case XML_OP_CHILD:
1476
+ /* An element node child. */
1477
+ s = xmlStreamCompAddStep(stream, step.value, step.value2,
1478
+ XML_ELEMENT_NODE, flags);
1479
+ if (s < 0)
1480
+ goto error;
1481
+ prevs = s;
1482
+ flags = 0;
1483
+ break;
1484
+ case XML_OP_ALL:
1485
+ s = xmlStreamCompAddStep(stream, NULL, NULL,
1486
+ XML_ELEMENT_NODE, flags);
1487
+ if (s < 0)
1488
+ goto error;
1489
+ prevs = s;
1490
+ flags = 0;
1491
+ break;
1492
+ case XML_OP_PARENT:
1493
+ break;
1494
+ case XML_OP_ANCESTOR:
1495
+ /* Skip redundant continuations. */
1496
+ if (flags & XML_STREAM_STEP_DESC)
1497
+ break;
1498
+ flags |= XML_STREAM_STEP_DESC;
1499
+ /*
1500
+ * Mark the expression as having "//".
1501
+ */
1502
+ if ((stream->flags & XML_STREAM_DESC) == 0)
1503
+ stream->flags |= XML_STREAM_DESC;
1504
+ break;
1505
+ }
1506
+ }
1507
+ if ((! root) && (comp->flags & XML_PATTERN_NOTPATTERN) == 0) {
1508
+ /*
1509
+ * If this should behave like a real pattern, we will mark
1510
+ * the first step as having "//", to be reentrant on every
1511
+ * tree level.
1512
+ */
1513
+ if ((stream->flags & XML_STREAM_DESC) == 0)
1514
+ stream->flags |= XML_STREAM_DESC;
1515
+
1516
+ if (stream->nbStep > 0) {
1517
+ if ((stream->steps[0].flags & XML_STREAM_STEP_DESC) == 0)
1518
+ stream->steps[0].flags |= XML_STREAM_STEP_DESC;
1519
+ }
1520
+ }
1521
+ if (stream->nbStep <= s)
1522
+ goto error;
1523
+ stream->steps[s].flags |= XML_STREAM_STEP_FINAL;
1524
+ if (root)
1525
+ stream->steps[0].flags |= XML_STREAM_STEP_ROOT;
1526
+ #ifdef DEBUG_STREAMING
1527
+ xmlDebugStreamComp(stream);
1528
+ #endif
1529
+ comp->stream = stream;
1530
+ return(0);
1531
+ error:
1532
+ xmlFreeStreamComp(stream);
1533
+ return(0);
1534
+ }
1535
+
1536
+ /**
1537
+ * xmlNewStreamCtxt:
1538
+ * @size: the number of expected states
1539
+ *
1540
+ * build a new stream context
1541
+ *
1542
+ * Returns the new structure or NULL in case of error.
1543
+ */
1544
+ static xmlStreamCtxtPtr
1545
+ xmlNewStreamCtxt(xmlStreamCompPtr stream) {
1546
+ xmlStreamCtxtPtr cur;
1547
+
1548
+ cur = (xmlStreamCtxtPtr) xmlMalloc(sizeof(xmlStreamCtxt));
1549
+ if (cur == NULL) {
1550
+ ERROR(NULL, NULL, NULL,
1551
+ "xmlNewStreamCtxt: malloc failed\n");
1552
+ return(NULL);
1553
+ }
1554
+ memset(cur, 0, sizeof(xmlStreamCtxt));
1555
+ cur->states = (int *) xmlMalloc(4 * 2 * sizeof(int));
1556
+ if (cur->states == NULL) {
1557
+ xmlFree(cur);
1558
+ ERROR(NULL, NULL, NULL,
1559
+ "xmlNewStreamCtxt: malloc failed\n");
1560
+ return(NULL);
1561
+ }
1562
+ cur->nbState = 0;
1563
+ cur->maxState = 4;
1564
+ cur->level = 0;
1565
+ cur->comp = stream;
1566
+ cur->blockLevel = -1;
1567
+ return(cur);
1568
+ }
1569
+
1570
+ /**
1571
+ * xmlFreeStreamCtxt:
1572
+ * @stream: the stream context
1573
+ *
1574
+ * Free the stream context
1575
+ */
1576
+ void
1577
+ xmlFreeStreamCtxt(xmlStreamCtxtPtr stream) {
1578
+ xmlStreamCtxtPtr next;
1579
+
1580
+ while (stream != NULL) {
1581
+ next = stream->next;
1582
+ if (stream->states != NULL)
1583
+ xmlFree(stream->states);
1584
+ xmlFree(stream);
1585
+ stream = next;
1586
+ }
1587
+ }
1588
+
1589
+ /**
1590
+ * xmlStreamCtxtAddState:
1591
+ * @comp: the stream context
1592
+ * @idx: the step index for that streaming state
1593
+ *
1594
+ * Add a new state to the stream context
1595
+ *
1596
+ * Returns -1 in case of error or the state index if successful
1597
+ */
1598
+ static int
1599
+ xmlStreamCtxtAddState(xmlStreamCtxtPtr comp, int idx, int level) {
1600
+ int i;
1601
+ for (i = 0;i < comp->nbState;i++) {
1602
+ if (comp->states[2 * i] < 0) {
1603
+ comp->states[2 * i] = idx;
1604
+ comp->states[2 * i + 1] = level;
1605
+ return(i);
1606
+ }
1607
+ }
1608
+ if (comp->nbState >= comp->maxState) {
1609
+ int *cur;
1610
+
1611
+ cur = (int *) xmlRealloc(comp->states,
1612
+ comp->maxState * 4 * sizeof(int));
1613
+ if (cur == NULL) {
1614
+ ERROR(NULL, NULL, NULL,
1615
+ "xmlNewStreamCtxt: malloc failed\n");
1616
+ return(-1);
1617
+ }
1618
+ comp->states = cur;
1619
+ comp->maxState *= 2;
1620
+ }
1621
+ comp->states[2 * comp->nbState] = idx;
1622
+ comp->states[2 * comp->nbState++ + 1] = level;
1623
+ return(comp->nbState - 1);
1624
+ }
1625
+
1626
+ /**
1627
+ * xmlStreamPushInternal:
1628
+ * @stream: the stream context
1629
+ * @name: the current name
1630
+ * @ns: the namespace name
1631
+ * @nodeType: the type of the node
1632
+ *
1633
+ * Push new data onto the stream. NOTE: if the call xmlPatterncompile()
1634
+ * indicated a dictionary, then strings for name and ns will be expected
1635
+ * to come from the dictionary.
1636
+ * Both @name and @ns being NULL means the / i.e. the root of the document.
1637
+ * This can also act as a reset.
1638
+ *
1639
+ * Returns: -1 in case of error, 1 if the current state in the stream is a
1640
+ * match and 0 otherwise.
1641
+ */
1642
+ static int
1643
+ xmlStreamPushInternal(xmlStreamCtxtPtr stream,
1644
+ const xmlChar *name, const xmlChar *ns,
1645
+ int nodeType) {
1646
+ int ret = 0, err = 0, final = 0, tmp, i, m, match, stepNr, desc;
1647
+ xmlStreamCompPtr comp;
1648
+ xmlStreamStep step;
1649
+ #ifdef DEBUG_STREAMING
1650
+ xmlStreamCtxtPtr orig = stream;
1651
+ #endif
1652
+
1653
+ if ((stream == NULL) || (stream->nbState < 0))
1654
+ return(-1);
1655
+
1656
+ while (stream != NULL) {
1657
+ comp = stream->comp;
1658
+
1659
+ if ((nodeType == XML_ELEMENT_NODE) &&
1660
+ (name == NULL) && (ns == NULL)) {
1661
+ /* We have a document node here (or a reset). */
1662
+ stream->nbState = 0;
1663
+ stream->level = 0;
1664
+ stream->blockLevel = -1;
1665
+ if (comp->flags & XML_STREAM_FROM_ROOT) {
1666
+ if (comp->nbStep == 0) {
1667
+ /* TODO: We have a "/." here? */
1668
+ ret = 1;
1669
+ } else {
1670
+ if ((comp->nbStep == 1) &&
1671
+ (comp->steps[0].nodeType == XML_STREAM_ANY_NODE) &&
1672
+ (comp->steps[0].flags & XML_STREAM_STEP_DESC))
1673
+ {
1674
+ /*
1675
+ * In the case of "//." the document node will match
1676
+ * as well.
1677
+ */
1678
+ ret = 1;
1679
+ } else if (comp->steps[0].flags & XML_STREAM_STEP_ROOT) {
1680
+ /* TODO: Do we need this ? */
1681
+ tmp = xmlStreamCtxtAddState(stream, 0, 0);
1682
+ if (tmp < 0)
1683
+ err++;
1684
+ }
1685
+ }
1686
+ }
1687
+ stream = stream->next;
1688
+ continue; /* while */
1689
+ }
1690
+
1691
+ /*
1692
+ * Fast check for ".".
1693
+ */
1694
+ if (comp->nbStep == 0) {
1695
+ /*
1696
+ * / and . are handled at the XPath node set creation
1697
+ * level by checking min depth
1698
+ */
1699
+ if (stream->flags & XML_PATTERN_XPATH) {
1700
+ stream = stream->next;
1701
+ continue; /* while */
1702
+ }
1703
+ /*
1704
+ * For non-pattern like evaluation like XML Schema IDCs
1705
+ * or traditional XPath expressions, this will match if
1706
+ * we are at the first level only, otherwise on every level.
1707
+ */
1708
+ if ((nodeType != XML_ATTRIBUTE_NODE) &&
1709
+ (((stream->flags & XML_PATTERN_NOTPATTERN) == 0) ||
1710
+ (stream->level == 0))) {
1711
+ ret = 1;
1712
+ }
1713
+ stream->level++;
1714
+ goto stream_next;
1715
+ }
1716
+ if (stream->blockLevel != -1) {
1717
+ /*
1718
+ * Skip blocked expressions.
1719
+ */
1720
+ stream->level++;
1721
+ goto stream_next;
1722
+ }
1723
+
1724
+ if ((nodeType != XML_ELEMENT_NODE) &&
1725
+ (nodeType != XML_ATTRIBUTE_NODE) &&
1726
+ ((comp->flags & XML_STREAM_FINAL_IS_ANY_NODE) == 0)) {
1727
+ /*
1728
+ * No need to process nodes of other types if we don't
1729
+ * resolve to those types.
1730
+ * TODO: Do we need to block the context here?
1731
+ */
1732
+ stream->level++;
1733
+ goto stream_next;
1734
+ }
1735
+
1736
+ /*
1737
+ * Check evolution of existing states
1738
+ */
1739
+ i = 0;
1740
+ m = stream->nbState;
1741
+ while (i < m) {
1742
+ if ((comp->flags & XML_STREAM_DESC) == 0) {
1743
+ /*
1744
+ * If there is no "//", then only the last
1745
+ * added state is of interest.
1746
+ */
1747
+ stepNr = stream->states[2 * (stream->nbState -1)];
1748
+ /*
1749
+ * TODO: Security check, should not happen, remove it.
1750
+ */
1751
+ if (stream->states[(2 * (stream->nbState -1)) + 1] <
1752
+ stream->level) {
1753
+ return (-1);
1754
+ }
1755
+ desc = 0;
1756
+ /* loop-stopper */
1757
+ i = m;
1758
+ } else {
1759
+ /*
1760
+ * If there are "//", then we need to process every "//"
1761
+ * occurring in the states, plus any other state for this
1762
+ * level.
1763
+ */
1764
+ stepNr = stream->states[2 * i];
1765
+
1766
+ /* TODO: should not happen anymore: dead states */
1767
+ if (stepNr < 0)
1768
+ goto next_state;
1769
+
1770
+ tmp = stream->states[(2 * i) + 1];
1771
+
1772
+ /* skip new states just added */
1773
+ if (tmp > stream->level)
1774
+ goto next_state;
1775
+
1776
+ /* skip states at ancestor levels, except if "//" */
1777
+ desc = comp->steps[stepNr].flags & XML_STREAM_STEP_DESC;
1778
+ if ((tmp < stream->level) && (!desc))
1779
+ goto next_state;
1780
+ }
1781
+ /*
1782
+ * Check for correct node-type.
1783
+ */
1784
+ step = comp->steps[stepNr];
1785
+ if (step.nodeType != nodeType) {
1786
+ if (step.nodeType == XML_ATTRIBUTE_NODE) {
1787
+ /*
1788
+ * Block this expression for deeper evaluation.
1789
+ */
1790
+ if ((comp->flags & XML_STREAM_DESC) == 0)
1791
+ stream->blockLevel = stream->level +1;
1792
+ goto next_state;
1793
+ } else if (step.nodeType != XML_STREAM_ANY_NODE)
1794
+ goto next_state;
1795
+ }
1796
+ /*
1797
+ * Compare local/namespace-name.
1798
+ */
1799
+ match = 0;
1800
+ if (step.nodeType == XML_STREAM_ANY_NODE) {
1801
+ match = 1;
1802
+ } else if (step.name == NULL) {
1803
+ if (step.ns == NULL) {
1804
+ /*
1805
+ * This lets through all elements/attributes.
1806
+ */
1807
+ match = 1;
1808
+ } else if (ns != NULL)
1809
+ match = xmlStrEqual(step.ns, ns);
1810
+ } else if (((step.ns != NULL) == (ns != NULL)) &&
1811
+ (name != NULL) &&
1812
+ (step.name[0] == name[0]) &&
1813
+ xmlStrEqual(step.name, name) &&
1814
+ ((step.ns == ns) || xmlStrEqual(step.ns, ns)))
1815
+ {
1816
+ match = 1;
1817
+ }
1818
+ #if 0
1819
+ /*
1820
+ * TODO: Pointer comparison won't work, since not guaranteed that the given
1821
+ * values are in the same dict; especially if it's the namespace name,
1822
+ * normally coming from ns->href. We need a namespace dict mechanism !
1823
+ */
1824
+ } else if (comp->dict) {
1825
+ if (step.name == NULL) {
1826
+ if (step.ns == NULL)
1827
+ match = 1;
1828
+ else
1829
+ match = (step.ns == ns);
1830
+ } else {
1831
+ match = ((step.name == name) && (step.ns == ns));
1832
+ }
1833
+ #endif /* if 0 ------------------------------------------------------- */
1834
+ if (match) {
1835
+ final = step.flags & XML_STREAM_STEP_FINAL;
1836
+ if (desc) {
1837
+ if (final) {
1838
+ ret = 1;
1839
+ } else {
1840
+ /* descending match create a new state */
1841
+ xmlStreamCtxtAddState(stream, stepNr + 1,
1842
+ stream->level + 1);
1843
+ }
1844
+ } else {
1845
+ if (final) {
1846
+ ret = 1;
1847
+ } else {
1848
+ xmlStreamCtxtAddState(stream, stepNr + 1,
1849
+ stream->level + 1);
1850
+ }
1851
+ }
1852
+ if ((ret != 1) && (step.flags & XML_STREAM_STEP_IN_SET)) {
1853
+ /*
1854
+ * Check if we have a special case like "foo/bar//.", where
1855
+ * "foo" is selected as well.
1856
+ */
1857
+ ret = 1;
1858
+ }
1859
+ }
1860
+ if (((comp->flags & XML_STREAM_DESC) == 0) &&
1861
+ ((! match) || final)) {
1862
+ /*
1863
+ * Mark this expression as blocked for any evaluation at
1864
+ * deeper levels. Note that this includes "/foo"
1865
+ * expressions if the *pattern* behaviour is used.
1866
+ */
1867
+ stream->blockLevel = stream->level +1;
1868
+ }
1869
+ next_state:
1870
+ i++;
1871
+ }
1872
+
1873
+ stream->level++;
1874
+
1875
+ /*
1876
+ * Re/enter the expression.
1877
+ * Don't reenter if it's an absolute expression like "/foo",
1878
+ * except "//foo".
1879
+ */
1880
+ step = comp->steps[0];
1881
+ if (step.flags & XML_STREAM_STEP_ROOT)
1882
+ goto stream_next;
1883
+
1884
+ desc = step.flags & XML_STREAM_STEP_DESC;
1885
+ if (stream->flags & XML_PATTERN_NOTPATTERN) {
1886
+ /*
1887
+ * Re/enter the expression if it is a "descendant" one,
1888
+ * or if we are at the 1st level of evaluation.
1889
+ */
1890
+
1891
+ if (stream->level == 1) {
1892
+ if (XML_STREAM_XS_IDC(stream)) {
1893
+ /*
1894
+ * XS-IDC: The missing "self::node()" will always
1895
+ * match the first given node.
1896
+ */
1897
+ goto stream_next;
1898
+ } else
1899
+ goto compare;
1900
+ }
1901
+ /*
1902
+ * A "//" is always reentrant.
1903
+ */
1904
+ if (desc)
1905
+ goto compare;
1906
+
1907
+ /*
1908
+ * XS-IDC: Process the 2nd level, since the missing
1909
+ * "self::node()" is responsible for the 2nd level being
1910
+ * the real start level.
1911
+ */
1912
+ if ((stream->level == 2) && XML_STREAM_XS_IDC(stream))
1913
+ goto compare;
1914
+
1915
+ goto stream_next;
1916
+ }
1917
+
1918
+ compare:
1919
+ /*
1920
+ * Check expected node-type.
1921
+ */
1922
+ if (step.nodeType != nodeType) {
1923
+ if (nodeType == XML_ATTRIBUTE_NODE)
1924
+ goto stream_next;
1925
+ else if (step.nodeType != XML_STREAM_ANY_NODE)
1926
+ goto stream_next;
1927
+ }
1928
+ /*
1929
+ * Compare local/namespace-name.
1930
+ */
1931
+ match = 0;
1932
+ if (step.nodeType == XML_STREAM_ANY_NODE) {
1933
+ match = 1;
1934
+ } else if (step.name == NULL) {
1935
+ if (step.ns == NULL) {
1936
+ /*
1937
+ * This lets through all elements/attributes.
1938
+ */
1939
+ match = 1;
1940
+ } else if (ns != NULL)
1941
+ match = xmlStrEqual(step.ns, ns);
1942
+ } else if (((step.ns != NULL) == (ns != NULL)) &&
1943
+ (name != NULL) &&
1944
+ (step.name[0] == name[0]) &&
1945
+ xmlStrEqual(step.name, name) &&
1946
+ ((step.ns == ns) || xmlStrEqual(step.ns, ns)))
1947
+ {
1948
+ match = 1;
1949
+ }
1950
+ final = step.flags & XML_STREAM_STEP_FINAL;
1951
+ if (match) {
1952
+ if (final)
1953
+ ret = 1;
1954
+ else
1955
+ xmlStreamCtxtAddState(stream, 1, stream->level);
1956
+ if ((ret != 1) && (step.flags & XML_STREAM_STEP_IN_SET)) {
1957
+ /*
1958
+ * Check if we have a special case like "foo//.", where
1959
+ * "foo" is selected as well.
1960
+ */
1961
+ ret = 1;
1962
+ }
1963
+ }
1964
+ if (((comp->flags & XML_STREAM_DESC) == 0) &&
1965
+ ((! match) || final)) {
1966
+ /*
1967
+ * Mark this expression as blocked for any evaluation at
1968
+ * deeper levels.
1969
+ */
1970
+ stream->blockLevel = stream->level;
1971
+ }
1972
+
1973
+ stream_next:
1974
+ stream = stream->next;
1975
+ } /* while stream != NULL */
1976
+
1977
+ if (err > 0)
1978
+ ret = -1;
1979
+ #ifdef DEBUG_STREAMING
1980
+ xmlDebugStreamCtxt(orig, ret);
1981
+ #endif
1982
+ return(ret);
1983
+ }
1984
+
1985
+ /**
1986
+ * xmlStreamPush:
1987
+ * @stream: the stream context
1988
+ * @name: the current name
1989
+ * @ns: the namespace name
1990
+ *
1991
+ * Push new data onto the stream. NOTE: if the call xmlPatterncompile()
1992
+ * indicated a dictionary, then strings for name and ns will be expected
1993
+ * to come from the dictionary.
1994
+ * Both @name and @ns being NULL means the / i.e. the root of the document.
1995
+ * This can also act as a reset.
1996
+ * Otherwise the function will act as if it has been given an element-node.
1997
+ *
1998
+ * Returns: -1 in case of error, 1 if the current state in the stream is a
1999
+ * match and 0 otherwise.
2000
+ */
2001
+ int
2002
+ xmlStreamPush(xmlStreamCtxtPtr stream,
2003
+ const xmlChar *name, const xmlChar *ns) {
2004
+ return (xmlStreamPushInternal(stream, name, ns, XML_ELEMENT_NODE));
2005
+ }
2006
+
2007
+ /**
2008
+ * xmlStreamPushNode:
2009
+ * @stream: the stream context
2010
+ * @name: the current name
2011
+ * @ns: the namespace name
2012
+ * @nodeType: the type of the node being pushed
2013
+ *
2014
+ * Push new data onto the stream. NOTE: if the call xmlPatterncompile()
2015
+ * indicated a dictionary, then strings for name and ns will be expected
2016
+ * to come from the dictionary.
2017
+ * Both @name and @ns being NULL means the / i.e. the root of the document.
2018
+ * This can also act as a reset.
2019
+ * Different from xmlStreamPush() this function can be fed with nodes of type:
2020
+ * element-, attribute-, text-, cdata-section-, comment- and
2021
+ * processing-instruction-node.
2022
+ *
2023
+ * Returns: -1 in case of error, 1 if the current state in the stream is a
2024
+ * match and 0 otherwise.
2025
+ */
2026
+ int
2027
+ xmlStreamPushNode(xmlStreamCtxtPtr stream,
2028
+ const xmlChar *name, const xmlChar *ns,
2029
+ int nodeType)
2030
+ {
2031
+ return (xmlStreamPushInternal(stream, name, ns,
2032
+ nodeType));
2033
+ }
2034
+
2035
+ /**
2036
+ * xmlStreamPushAttr:
2037
+ * @stream: the stream context
2038
+ * @name: the current name
2039
+ * @ns: the namespace name
2040
+ *
2041
+ * Push new attribute data onto the stream. NOTE: if the call xmlPatterncompile()
2042
+ * indicated a dictionary, then strings for name and ns will be expected
2043
+ * to come from the dictionary.
2044
+ * Both @name and @ns being NULL means the / i.e. the root of the document.
2045
+ * This can also act as a reset.
2046
+ * Otherwise the function will act as if it has been given an attribute-node.
2047
+ *
2048
+ * Returns: -1 in case of error, 1 if the current state in the stream is a
2049
+ * match and 0 otherwise.
2050
+ */
2051
+ int
2052
+ xmlStreamPushAttr(xmlStreamCtxtPtr stream,
2053
+ const xmlChar *name, const xmlChar *ns) {
2054
+ return (xmlStreamPushInternal(stream, name, ns, XML_ATTRIBUTE_NODE));
2055
+ }
2056
+
2057
+ /**
2058
+ * xmlStreamPop:
2059
+ * @stream: the stream context
2060
+ *
2061
+ * push one level from the stream.
2062
+ *
2063
+ * Returns: -1 in case of error, 0 otherwise.
2064
+ */
2065
+ int
2066
+ xmlStreamPop(xmlStreamCtxtPtr stream) {
2067
+ int i, lev;
2068
+
2069
+ if (stream == NULL)
2070
+ return(-1);
2071
+ while (stream != NULL) {
2072
+ /*
2073
+ * Reset block-level.
2074
+ */
2075
+ if (stream->blockLevel == stream->level)
2076
+ stream->blockLevel = -1;
2077
+
2078
+ /*
2079
+ * stream->level can be zero when XML_FINAL_IS_ANY_NODE is set
2080
+ * (see the thread at
2081
+ * http://mail.gnome.org/archives/xslt/2008-July/msg00027.html)
2082
+ */
2083
+ if (stream->level)
2084
+ stream->level--;
2085
+ /*
2086
+ * Check evolution of existing states
2087
+ */
2088
+ for (i = stream->nbState -1; i >= 0; i--) {
2089
+ /* discard obsoleted states */
2090
+ lev = stream->states[(2 * i) + 1];
2091
+ if (lev > stream->level)
2092
+ stream->nbState--;
2093
+ if (lev <= stream->level)
2094
+ break;
2095
+ }
2096
+ stream = stream->next;
2097
+ }
2098
+ return(0);
2099
+ }
2100
+
2101
+ /**
2102
+ * xmlStreamWantsAnyNode:
2103
+ * @streamCtxt: the stream context
2104
+ *
2105
+ * Query if the streaming pattern additionally needs to be fed with
2106
+ * text-, cdata-section-, comment- and processing-instruction-nodes.
2107
+ * If the result is 0 then only element-nodes and attribute-nodes
2108
+ * need to be pushed.
2109
+ *
2110
+ * Returns: 1 in case of need of nodes of the above described types,
2111
+ * 0 otherwise. -1 on API errors.
2112
+ */
2113
+ int
2114
+ xmlStreamWantsAnyNode(xmlStreamCtxtPtr streamCtxt)
2115
+ {
2116
+ if (streamCtxt == NULL)
2117
+ return(-1);
2118
+ while (streamCtxt != NULL) {
2119
+ if (streamCtxt->comp->flags & XML_STREAM_FINAL_IS_ANY_NODE)
2120
+ return(1);
2121
+ streamCtxt = streamCtxt->next;
2122
+ }
2123
+ return(0);
2124
+ }
2125
+
2126
+ /************************************************************************
2127
+ * *
2128
+ * The public interfaces *
2129
+ * *
2130
+ ************************************************************************/
2131
+
2132
+ /**
2133
+ * xmlPatterncompile:
2134
+ * @pattern: the pattern to compile
2135
+ * @dict: an optional dictionary for interned strings
2136
+ * @flags: compilation flags, see xmlPatternFlags
2137
+ * @namespaces: the prefix definitions, array of [URI, prefix] or NULL
2138
+ *
2139
+ * Compile a pattern.
2140
+ *
2141
+ * Returns the compiled form of the pattern or NULL in case of error
2142
+ */
2143
+ xmlPatternPtr
2144
+ xmlPatterncompile(const xmlChar *pattern, xmlDict *dict, int flags,
2145
+ const xmlChar **namespaces) {
2146
+ xmlPatternPtr ret = NULL, cur;
2147
+ xmlPatParserContextPtr ctxt = NULL;
2148
+ const xmlChar *or, *start;
2149
+ xmlChar *tmp = NULL;
2150
+ int type = 0;
2151
+ int streamable = 1;
2152
+
2153
+ if (pattern == NULL)
2154
+ return(NULL);
2155
+
2156
+ start = pattern;
2157
+ or = start;
2158
+ while (*or != 0) {
2159
+ tmp = NULL;
2160
+ while ((*or != 0) && (*or != '|')) or++;
2161
+ if (*or == 0)
2162
+ ctxt = xmlNewPatParserContext(start, dict, namespaces);
2163
+ else {
2164
+ tmp = xmlStrndup(start, or - start);
2165
+ if (tmp != NULL) {
2166
+ ctxt = xmlNewPatParserContext(tmp, dict, namespaces);
2167
+ }
2168
+ or++;
2169
+ }
2170
+ if (ctxt == NULL) goto error;
2171
+ cur = xmlNewPattern();
2172
+ if (cur == NULL) goto error;
2173
+ /*
2174
+ * Assign string dict.
2175
+ */
2176
+ if (dict) {
2177
+ cur->dict = dict;
2178
+ xmlDictReference(dict);
2179
+ }
2180
+ if (ret == NULL)
2181
+ ret = cur;
2182
+ else {
2183
+ cur->next = ret->next;
2184
+ ret->next = cur;
2185
+ }
2186
+ cur->flags = flags;
2187
+ ctxt->comp = cur;
2188
+
2189
+ if (XML_STREAM_XS_IDC(cur))
2190
+ xmlCompileIDCXPathPath(ctxt);
2191
+ else
2192
+ xmlCompilePathPattern(ctxt);
2193
+ if (ctxt->error != 0)
2194
+ goto error;
2195
+ xmlFreePatParserContext(ctxt);
2196
+ ctxt = NULL;
2197
+
2198
+
2199
+ if (streamable) {
2200
+ if (type == 0) {
2201
+ type = cur->flags & (PAT_FROM_ROOT | PAT_FROM_CUR);
2202
+ } else if (type == PAT_FROM_ROOT) {
2203
+ if (cur->flags & PAT_FROM_CUR)
2204
+ streamable = 0;
2205
+ } else if (type == PAT_FROM_CUR) {
2206
+ if (cur->flags & PAT_FROM_ROOT)
2207
+ streamable = 0;
2208
+ }
2209
+ }
2210
+ if (streamable)
2211
+ xmlStreamCompile(cur);
2212
+ if (xmlReversePattern(cur) < 0)
2213
+ goto error;
2214
+ if (tmp != NULL) {
2215
+ xmlFree(tmp);
2216
+ tmp = NULL;
2217
+ }
2218
+ start = or;
2219
+ }
2220
+ if (streamable == 0) {
2221
+ cur = ret;
2222
+ while (cur != NULL) {
2223
+ if (cur->stream != NULL) {
2224
+ xmlFreeStreamComp(cur->stream);
2225
+ cur->stream = NULL;
2226
+ }
2227
+ cur = cur->next;
2228
+ }
2229
+ }
2230
+
2231
+ return(ret);
2232
+ error:
2233
+ if (ctxt != NULL) xmlFreePatParserContext(ctxt);
2234
+ if (ret != NULL) xmlFreePattern(ret);
2235
+ if (tmp != NULL) xmlFree(tmp);
2236
+ return(NULL);
2237
+ }
2238
+
2239
+ /**
2240
+ * xmlPatternGetStreamCtxt:
2241
+ * @comp: the precompiled pattern
2242
+ *
2243
+ * Get a streaming context for that pattern
2244
+ * Use xmlFreeStreamCtxt to free the context.
2245
+ *
2246
+ * Returns a pointer to the context or NULL in case of failure
2247
+ */
2248
+ xmlStreamCtxtPtr
2249
+ xmlPatternGetStreamCtxt(xmlPatternPtr comp)
2250
+ {
2251
+ xmlStreamCtxtPtr ret = NULL, cur;
2252
+
2253
+ if ((comp == NULL) || (comp->stream == NULL))
2254
+ return(NULL);
2255
+
2256
+ while (comp != NULL) {
2257
+ if (comp->stream == NULL)
2258
+ goto failed;
2259
+ cur = xmlNewStreamCtxt(comp->stream);
2260
+ if (cur == NULL)
2261
+ goto failed;
2262
+ if (ret == NULL)
2263
+ ret = cur;
2264
+ else {
2265
+ cur->next = ret->next;
2266
+ ret->next = cur;
2267
+ }
2268
+ cur->flags = comp->flags;
2269
+ comp = comp->next;
2270
+ }
2271
+ return(ret);
2272
+ failed:
2273
+ xmlFreeStreamCtxt(ret);
2274
+ return(NULL);
2275
+ }
2276
+
2277
+ /**
2278
+ * xmlPatternStreamable:
2279
+ * @comp: the precompiled pattern
2280
+ *
2281
+ * Check if the pattern is streamable i.e. xmlPatternGetStreamCtxt()
2282
+ * should work.
2283
+ *
2284
+ * Returns 1 if streamable, 0 if not and -1 in case of error.
2285
+ */
2286
+ int
2287
+ xmlPatternStreamable(xmlPatternPtr comp) {
2288
+ if (comp == NULL)
2289
+ return(-1);
2290
+ while (comp != NULL) {
2291
+ if (comp->stream == NULL)
2292
+ return(0);
2293
+ comp = comp->next;
2294
+ }
2295
+ return(1);
2296
+ }
2297
+
2298
+ /**
2299
+ * xmlPatternMaxDepth:
2300
+ * @comp: the precompiled pattern
2301
+ *
2302
+ * Check the maximum depth reachable by a pattern
2303
+ *
2304
+ * Returns -2 if no limit (using //), otherwise the depth,
2305
+ * and -1 in case of error
2306
+ */
2307
+ int
2308
+ xmlPatternMaxDepth(xmlPatternPtr comp) {
2309
+ int ret = 0, i;
2310
+ if (comp == NULL)
2311
+ return(-1);
2312
+ while (comp != NULL) {
2313
+ if (comp->stream == NULL)
2314
+ return(-1);
2315
+ for (i = 0;i < comp->stream->nbStep;i++)
2316
+ if (comp->stream->steps[i].flags & XML_STREAM_STEP_DESC)
2317
+ return(-2);
2318
+ if (comp->stream->nbStep > ret)
2319
+ ret = comp->stream->nbStep;
2320
+ comp = comp->next;
2321
+ }
2322
+ return(ret);
2323
+ }
2324
+
2325
+ /**
2326
+ * xmlPatternMinDepth:
2327
+ * @comp: the precompiled pattern
2328
+ *
2329
+ * Check the minimum depth reachable by a pattern, 0 mean the / or . are
2330
+ * part of the set.
2331
+ *
2332
+ * Returns -1 in case of error otherwise the depth,
2333
+ *
2334
+ */
2335
+ int
2336
+ xmlPatternMinDepth(xmlPatternPtr comp) {
2337
+ int ret = 12345678;
2338
+ if (comp == NULL)
2339
+ return(-1);
2340
+ while (comp != NULL) {
2341
+ if (comp->stream == NULL)
2342
+ return(-1);
2343
+ if (comp->stream->nbStep < ret)
2344
+ ret = comp->stream->nbStep;
2345
+ if (ret == 0)
2346
+ return(0);
2347
+ comp = comp->next;
2348
+ }
2349
+ return(ret);
2350
+ }
2351
+
2352
+ /**
2353
+ * xmlPatternFromRoot:
2354
+ * @comp: the precompiled pattern
2355
+ *
2356
+ * Check if the pattern must be looked at from the root.
2357
+ *
2358
+ * Returns 1 if true, 0 if false and -1 in case of error
2359
+ */
2360
+ int
2361
+ xmlPatternFromRoot(xmlPatternPtr comp) {
2362
+ if (comp == NULL)
2363
+ return(-1);
2364
+ while (comp != NULL) {
2365
+ if (comp->stream == NULL)
2366
+ return(-1);
2367
+ if (comp->flags & PAT_FROM_ROOT)
2368
+ return(1);
2369
+ comp = comp->next;
2370
+ }
2371
+ return(0);
2372
+
2373
+ }
2374
+
2375
+ #endif /* LIBXML_PATTERN_ENABLED */