mkrf 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. data/CHANGELOG +2 -0
  2. data/MIT-LICENSE +7 -0
  3. data/README +54 -0
  4. data/Rakefile +107 -0
  5. data/lib/mkrf.rb +4 -0
  6. data/lib/mkrf/availability.rb +219 -0
  7. data/lib/mkrf/generator.rb +146 -0
  8. data/test/abstract_unit.rb +4 -0
  9. data/test/fixtures/down_a_directory/header_down_a_directory.h +1 -0
  10. data/test/fixtures/stdmkrf.h +1 -0
  11. data/test/sample_files/libtrivial/Rakefile +31 -0
  12. data/test/sample_files/libtrivial/extconf.rb +3 -0
  13. data/test/sample_files/libtrivial/lib/libtrivial.c +5 -0
  14. data/test/sample_files/libtrivial/lib/libtrivial.o +0 -0
  15. data/test/sample_files/libtrivial/libtrivial_so.bundle +0 -0
  16. data/test/sample_files/libtrivial/mkrf.log +1 -0
  17. data/test/sample_files/libxml-ruby-0.3.8/CHANGELOG +74 -0
  18. data/test/sample_files/libxml-ruby-0.3.8/LICENSE +22 -0
  19. data/test/sample_files/libxml-ruby-0.3.8/README +144 -0
  20. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/cbg.c +76 -0
  21. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/extconf.rb +49 -0
  22. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/libxml.c +86 -0
  23. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/libxml.h +82 -0
  24. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/libxml.rb +107 -0
  25. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/mkrf.log +1 -0
  26. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/old_extconf.rb +95 -0
  27. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_attr.c +372 -0
  28. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_attr.h +21 -0
  29. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_attribute.c +224 -0
  30. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_attribute.h +21 -0
  31. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_document.c +1159 -0
  32. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_document.h +27 -0
  33. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_dtd.c +168 -0
  34. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_dtd.h +17 -0
  35. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_input_cbg.c +167 -0
  36. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_input_cbg.h +21 -0
  37. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_node.c +2139 -0
  38. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_node.h +28 -0
  39. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_node_set.c +248 -0
  40. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_node_set.h +26 -0
  41. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_ns.c +153 -0
  42. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_ns.h +21 -0
  43. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_parser.c +1417 -0
  44. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_parser.h +31 -0
  45. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_parser_context.c +715 -0
  46. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_parser_context.h +22 -0
  47. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_sax_parser.c +426 -0
  48. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_sax_parser.h +52 -0
  49. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_schema.c +142 -0
  50. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_schema.h +16 -0
  51. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_tree.c +43 -0
  52. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_tree.h +12 -0
  53. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_xinclude.c +20 -0
  54. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_xinclude.h +13 -0
  55. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_xpath.c +363 -0
  56. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_xpath.h +24 -0
  57. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_xpath_context.c +125 -0
  58. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_xpath_context.h +24 -0
  59. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_xpointer.c +100 -0
  60. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_xpointer.h +27 -0
  61. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_xpointer_context.c +21 -0
  62. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/ruby_xml_xpointer_context.h +18 -0
  63. data/test/sample_files/libxml-ruby-0.3.8/ext/xml/sax_parser_callbacks.inc +202 -0
  64. data/test/sample_files/syck-0.55/CHANGELOG +186 -0
  65. data/test/sample_files/syck-0.55/COPYING +54 -0
  66. data/test/sample_files/syck-0.55/Makefile +582 -0
  67. data/test/sample_files/syck-0.55/Makefile.am +5 -0
  68. data/test/sample_files/syck-0.55/Makefile.in +582 -0
  69. data/test/sample_files/syck-0.55/README +105 -0
  70. data/test/sample_files/syck-0.55/README.BYTECODE +484 -0
  71. data/test/sample_files/syck-0.55/README.EXT +444 -0
  72. data/test/sample_files/syck-0.55/RELEASE +123 -0
  73. data/test/sample_files/syck-0.55/TODO +25 -0
  74. data/test/sample_files/syck-0.55/aclocal.m4 +883 -0
  75. data/test/sample_files/syck-0.55/bootstrap +7 -0
  76. data/test/sample_files/syck-0.55/config.h +79 -0
  77. data/test/sample_files/syck-0.55/config.h.in +78 -0
  78. data/test/sample_files/syck-0.55/config.status +1197 -0
  79. data/test/sample_files/syck-0.55/config/README +14 -0
  80. data/test/sample_files/syck-0.55/config/depcomp +529 -0
  81. data/test/sample_files/syck-0.55/config/install-sh +323 -0
  82. data/test/sample_files/syck-0.55/config/missing +357 -0
  83. data/test/sample_files/syck-0.55/configure +6728 -0
  84. data/test/sample_files/syck-0.55/configure.in +36 -0
  85. data/test/sample_files/syck-0.55/ext/ruby/CHANGELOG +303 -0
  86. data/test/sample_files/syck-0.55/ext/ruby/README +400 -0
  87. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/MANIFEST +1 -0
  88. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/bytecode.c +1170 -0
  89. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/emitter.c +1224 -0
  90. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/extconf.rb +10 -0
  91. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/gram.c +1894 -0
  92. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/gram.h +79 -0
  93. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/handler.c +174 -0
  94. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/implicit.c +2989 -0
  95. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/mkrf.log +1 -0
  96. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/node.c +407 -0
  97. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/rubyext.c +2385 -0
  98. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/syck.c +504 -0
  99. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/syck.h +458 -0
  100. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/token.c +2707 -0
  101. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/yaml2byte.c +250 -0
  102. data/test/sample_files/syck-0.55/ext/ruby/ext/syck/yamlbyte.h +170 -0
  103. data/test/sample_files/syck-0.55/ext/ruby/install.rb +1022 -0
  104. data/test/sample_files/syck-0.55/ext/ruby/lib/okay.rb +161 -0
  105. data/test/sample_files/syck-0.55/ext/ruby/lib/okay/news.rb +69 -0
  106. data/test/sample_files/syck-0.55/ext/ruby/lib/okay/rpc.rb +434 -0
  107. data/test/sample_files/syck-0.55/ext/ruby/lib/yaml.rb +436 -0
  108. data/test/sample_files/syck-0.55/ext/ruby/lib/yaml/baseemitter.rb +247 -0
  109. data/test/sample_files/syck-0.55/ext/ruby/lib/yaml/basenode.rb +216 -0
  110. data/test/sample_files/syck-0.55/ext/ruby/lib/yaml/compat.rb +26 -0
  111. data/test/sample_files/syck-0.55/ext/ruby/lib/yaml/constants.rb +45 -0
  112. data/test/sample_files/syck-0.55/ext/ruby/lib/yaml/dbm.rb +111 -0
  113. data/test/sample_files/syck-0.55/ext/ruby/lib/yaml/emitter.rb +107 -0
  114. data/test/sample_files/syck-0.55/ext/ruby/lib/yaml/encoding.rb +33 -0
  115. data/test/sample_files/syck-0.55/ext/ruby/lib/yaml/error.rb +34 -0
  116. data/test/sample_files/syck-0.55/ext/ruby/lib/yaml/rubytypes.rb +438 -0
  117. data/test/sample_files/syck-0.55/ext/ruby/lib/yaml/store.rb +29 -0
  118. data/test/sample_files/syck-0.55/ext/ruby/lib/yaml/stream.rb +40 -0
  119. data/test/sample_files/syck-0.55/ext/ruby/lib/yaml/stringio.rb +83 -0
  120. data/test/sample_files/syck-0.55/ext/ruby/lib/yaml/syck.rb +19 -0
  121. data/test/sample_files/syck-0.55/ext/ruby/lib/yaml/tag.rb +86 -0
  122. data/test/sample_files/syck-0.55/ext/ruby/lib/yaml/types.rb +188 -0
  123. data/test/sample_files/syck-0.55/ext/ruby/lib/yaml/yamlnode.rb +54 -0
  124. data/test/sample_files/syck-0.55/ext/ruby/lib/yaml/ypath.rb +52 -0
  125. data/test/sample_files/syck-0.55/ext/ruby/lib/yod.rb +1168 -0
  126. data/test/sample_files/syck-0.55/ext/ruby/samples/okayNews-modules.rb +27 -0
  127. data/test/sample_files/syck-0.55/ext/ruby/samples/okayNews-sample.rb +336 -0
  128. data/test/sample_files/syck-0.55/ext/ruby/samples/okayNews-validate.rb +341 -0
  129. data/test/sample_files/syck-0.55/ext/ruby/samples/okayRpc-client.rb +51 -0
  130. data/test/sample_files/syck-0.55/ext/ruby/samples/okayRpc-server.rb +85 -0
  131. data/test/sample_files/syck-0.55/ext/ruby/samples/yaml-sortHashKeys.rb +128 -0
  132. data/test/sample_files/syck-0.55/ext/ruby/tests/basic.rb +1653 -0
  133. data/test/sample_files/syck-0.55/ext/ruby/yts/YtsAnchorAlias.yml +51 -0
  134. data/test/sample_files/syck-0.55/ext/ruby/yts/YtsBasicTests.yml +282 -0
  135. data/test/sample_files/syck-0.55/ext/ruby/yts/YtsBlockMapping.yml +78 -0
  136. data/test/sample_files/syck-0.55/ext/ruby/yts/YtsBlockSequence.yml +0 -0
  137. data/test/sample_files/syck-0.55/ext/ruby/yts/YtsDocumentSeparator.yml +102 -0
  138. data/test/sample_files/syck-0.55/ext/ruby/yts/YtsErrorTests.yml +23 -0
  139. data/test/sample_files/syck-0.55/ext/ruby/yts/YtsFlowCollections.yml +73 -0
  140. data/test/sample_files/syck-0.55/ext/ruby/yts/YtsFoldedScalars.yml +215 -0
  141. data/test/sample_files/syck-0.55/ext/ruby/yts/YtsMapInSeq.yml +0 -0
  142. data/test/sample_files/syck-0.55/ext/ruby/yts/YtsNullsAndEmpties.yml +66 -0
  143. data/test/sample_files/syck-0.55/ext/ruby/yts/YtsRubyTests.yml +182 -0
  144. data/test/sample_files/syck-0.55/ext/ruby/yts/YtsSpecificationExamples.yml +2699 -0
  145. data/test/sample_files/syck-0.55/ext/ruby/yts/YtsTypeTransfers.yml +265 -0
  146. data/test/sample_files/syck-0.55/ext/ruby/yts/YtsYpath.yml +221 -0
  147. data/test/sample_files/syck-0.55/ext/ruby/yts/cookbook.rb +159 -0
  148. data/test/sample_files/syck-0.55/ext/ruby/yts/index.yml +10 -0
  149. data/test/sample_files/syck-0.55/ext/ruby/yts/yts.rb +193 -0
  150. data/test/sample_files/syck-0.55/lib/Makefile +497 -0
  151. data/test/sample_files/syck-0.55/lib/Makefile.am +27 -0
  152. data/test/sample_files/syck-0.55/lib/Makefile.in +497 -0
  153. data/test/sample_files/syck-0.55/lib/bytecode.c +1170 -0
  154. data/test/sample_files/syck-0.55/lib/bytecode.re +525 -0
  155. data/test/sample_files/syck-0.55/lib/emitter.c +1224 -0
  156. data/test/sample_files/syck-0.55/lib/gram.c +1894 -0
  157. data/test/sample_files/syck-0.55/lib/gram.h +79 -0
  158. data/test/sample_files/syck-0.55/lib/gram.output +2005 -0
  159. data/test/sample_files/syck-0.55/lib/gram.y +481 -0
  160. data/test/sample_files/syck-0.55/lib/handler.c +174 -0
  161. data/test/sample_files/syck-0.55/lib/implicit.c +2989 -0
  162. data/test/sample_files/syck-0.55/lib/implicit.re +206 -0
  163. data/test/sample_files/syck-0.55/lib/node.c +407 -0
  164. data/test/sample_files/syck-0.55/lib/syck.c +504 -0
  165. data/test/sample_files/syck-0.55/lib/syck.h +458 -0
  166. data/test/sample_files/syck-0.55/lib/syck_st.c +577 -0
  167. data/test/sample_files/syck-0.55/lib/syck_st.h +46 -0
  168. data/test/sample_files/syck-0.55/lib/token.c +2707 -0
  169. data/test/sample_files/syck-0.55/lib/token.re +1139 -0
  170. data/test/sample_files/syck-0.55/lib/yaml2byte.c +250 -0
  171. data/test/sample_files/syck-0.55/lib/yamlbyte.h +170 -0
  172. data/test/sample_files/syck-0.55/stamp-h1 +1 -0
  173. data/test/sample_files/syck-0.55/tests/Basic.c +141 -0
  174. data/test/sample_files/syck-0.55/tests/CuTest.c +294 -0
  175. data/test/sample_files/syck-0.55/tests/CuTest.h +84 -0
  176. data/test/sample_files/syck-0.55/tests/Emit.c +87 -0
  177. data/test/sample_files/syck-0.55/tests/Makefile +480 -0
  178. data/test/sample_files/syck-0.55/tests/Makefile.am +13 -0
  179. data/test/sample_files/syck-0.55/tests/Makefile.in +480 -0
  180. data/test/sample_files/syck-0.55/tests/Parse.c +208 -0
  181. data/test/sample_files/syck-0.55/tests/YTS.c +2310 -0
  182. data/test/sample_files/syck-0.55/tests/YTS.c.erb +326 -0
  183. data/test/sample_files/syck-0.55/tests/YTS.c.rb +44 -0
  184. data/test/test_availability.rb +68 -0
  185. data/test/test_generator.rb +74 -0
  186. metadata +252 -0
@@ -0,0 +1,27 @@
1
+ /* $Id: ruby_xml_document.h,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
2
+
3
+ /* Please see the LICENSE file for copyright and distribution information */
4
+
5
+ #ifndef __RUBY_XML_DOCUMENT__
6
+ #define __RUBY_XML_DOCUMENT__
7
+
8
+ extern VALUE cXMLDocument;
9
+
10
+ typedef struct rxp_document {
11
+ xmlDocPtr doc; /* Tree/DOM interface */
12
+ int data_type; /* The data type referenced by *data */
13
+ void *data; /* Pointer to an external structure of options */
14
+ int is_ptr; /* Determines if this object owns its data or points to it someplace else */
15
+ VALUE xmlver; /* T_STRING with the xml version */
16
+ } ruby_xml_document;
17
+
18
+ VALUE ruby_xml_document_filename_get(VALUE self);
19
+ void ruby_xml_document_free(ruby_xml_document *rxd);
20
+ VALUE ruby_xml_document_new(VALUE class, xmlDocPtr doc);
21
+ VALUE ruby_xml_document_new2(VALUE class, VALUE xmlver);
22
+ VALUE ruby_xml_document_new3(VALUE class);
23
+ VALUE ruby_xml_document_new4(VALUE class, xmlDocPtr doc);
24
+ VALUE ruby_xml_document_root_get(VALUE self);
25
+ void ruby_init_xml_document(void);
26
+
27
+ #endif
@@ -0,0 +1,168 @@
1
+ #include "libxml.h"
2
+ #include "ruby_xml_dtd.h"
3
+
4
+ VALUE cXMLDtd;
5
+
6
+ void
7
+ ruby_xml_dtd_free(ruby_xml_dtd *rxdtd) {
8
+ if (rxdtd->dtd != NULL) {
9
+ xmlFreeDtd(rxdtd->dtd);
10
+ rxdtd->dtd = NULL;
11
+ }
12
+
13
+ free(rxdtd);
14
+ }
15
+
16
+ static void
17
+ ruby_xml_dtd_mark(ruby_xml_dtd *rxdtd) {
18
+ return;
19
+ //if (rxdtd == NULL) return;
20
+ //if (!NIL_P(rxd->xmlver)) rb_gc_mark(rxd->xmlver);
21
+ }
22
+
23
+ /*
24
+ * call-seq:
25
+ * XML::Dtd.new("public system") => dtd
26
+ * XML::Dtd.new("public", "system") => dtd
27
+ *
28
+ * Create a new Dtd from the specified public and system
29
+ * identifiers.
30
+ */
31
+ VALUE
32
+ ruby_xml_dtd_initialize(int argc, VALUE *argv, VALUE class) {
33
+ ruby_xml_dtd *rxdtd;
34
+ VALUE external, system, dtd_string;
35
+ xmlParserInputBufferPtr buffer;
36
+ xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
37
+ xmlChar *new_string;
38
+
39
+ // 1 argument -- string --> parsujeme jako dtd
40
+ // 2 argumenty -- public, system --> bude se hledat
41
+ switch (argc) {
42
+ case 2:
43
+ rb_scan_args(argc, argv, "20", &external, &system);
44
+
45
+ Check_Type(external, T_STRING);
46
+ Check_Type(system, T_STRING);
47
+ rxdtd = ALLOC(ruby_xml_dtd);
48
+ rxdtd->dtd = xmlParseDTD( (xmlChar*)StringValuePtr(external),
49
+ (xmlChar*)StringValuePtr(system) );
50
+ if (rxdtd->dtd == NULL) {
51
+ free(rxdtd);
52
+ return(Qfalse);
53
+ }
54
+
55
+ xmlSetTreeDoc( (xmlNodePtr)rxdtd->dtd, NULL );
56
+ return( Data_Wrap_Struct(cXMLDtd, ruby_xml_dtd_mark, ruby_xml_dtd_free, rxdtd) );
57
+ break;
58
+
59
+ /*
60
+ SV *
61
+ new(CLASS, external, system)
62
+ char * CLASS
63
+ char * external
64
+ char * system
65
+ ALIAS:
66
+ parse_uri = 1
67
+ PREINIT:
68
+ xmlDtdPtr dtd = NULL;
69
+ CODE:
70
+ LibXML_error = sv_2mortal(newSVpv("", 0));
71
+ dtd = xmlParseDTD((const xmlChar*)external, (const xmlChar*)system);
72
+ if ( dtd == NULL ) {
73
+ XSRETURN_UNDEF;
74
+ }
75
+ xmlSetTreeDoc((xmlNodePtr)dtd, NULL);
76
+ RETVAL = PmmNodeToSv( (xmlNodePtr) dtd, NULL );
77
+ OUTPUT:
78
+ RETVAL
79
+ */
80
+
81
+ case 1:
82
+
83
+ rb_scan_args(argc, argv, "10", &dtd_string);
84
+ buffer = xmlAllocParserInputBuffer(enc);
85
+ //if ( !buffer) return Qnil
86
+ new_string = xmlStrdup((xmlChar*)StringValuePtr(dtd_string));
87
+ xmlParserInputBufferPush(buffer, xmlStrlen(new_string), (const char*)new_string);
88
+
89
+ rxdtd = ALLOC(ruby_xml_dtd);
90
+ rxdtd->dtd = xmlIOParseDTD(NULL, buffer, enc);
91
+
92
+ // NOTE: For some reason freeing this InputBuffer causes a segfault!
93
+ // xmlFreeParserInputBuffer(buffer);
94
+ xmlFree(new_string);
95
+
96
+ return( Data_Wrap_Struct(cXMLDtd, ruby_xml_dtd_mark, ruby_xml_dtd_free, rxdtd) );
97
+
98
+ break;
99
+ /*
100
+ SV * parse_string(CLASS, str, ...)
101
+ char * CLASS
102
+ char * str
103
+ PREINIT:
104
+ STRLEN n_a;
105
+ xmlDtdPtr res;
106
+ SV * encoding_sv;
107
+ xmlParserInputBufferPtr buffer;
108
+ xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
109
+ xmlChar * new_string;
110
+ STRLEN len;
111
+ CODE:
112
+ LibXML_init_error();
113
+ if (items > 2) {
114
+ encoding_sv = ST(2);
115
+ if (items > 3) {
116
+ croak("parse_string: too many parameters");
117
+ }
118
+ // warn("getting encoding...\n");
119
+ enc = xmlParseCharEncoding(SvPV(encoding_sv, n_a));
120
+ if (enc == XML_CHAR_ENCODING_ERROR) {
121
+ croak("Parse of encoding %s failed: %s", SvPV(encoding_sv, n_a), SvPV(LibXML_error, n_a));
122
+ }
123
+ }
124
+ buffer = xmlAllocParserInputBuffer(enc);
125
+ // buffer = xmlParserInputBufferCreateMem(str, xmlStrlen(str), enc);
126
+ if ( !buffer)
127
+ croak("cant create buffer!\n" );
128
+
129
+ new_string = xmlStrdup((const xmlChar*)str);
130
+ xmlParserInputBufferPush(buffer, xmlStrlen(new_string), (const char*)new_string);
131
+
132
+ res = xmlIOParseDTD(NULL, buffer, enc);
133
+
134
+ // NOTE: For some reason freeing this InputBuffer causes a segfault!
135
+ // xmlFreeParserInputBuffer(buffer);
136
+ xmlFree(new_string);
137
+
138
+ sv_2mortal( LibXML_error );
139
+ LibXML_croak_error();
140
+
141
+ if (res == NULL) {
142
+ croak("no DTD parsed!");
143
+ }
144
+ RETVAL = PmmNodeToSv((xmlNodePtr)res, NULL);
145
+ OUTPUT:
146
+ RETVAL
147
+ */
148
+
149
+ default:
150
+ rb_raise(rb_eArgError, "wrong number of arguments (need 1 or 2)");
151
+ }
152
+
153
+ //docobj = ruby_xml_document_new2(cXMLDocument, xmlver);
154
+ return Qnil;
155
+ }
156
+
157
+ // Rdoc needs to know
158
+ #ifdef RDOC_NEVER_DEFINED
159
+ mXML = rb_define_module("XML");
160
+ #endif
161
+
162
+ void
163
+ ruby_init_xml_dtd(void) {
164
+ cXMLDtd = rb_define_class_under(mXML, "Dtd", rb_cObject);
165
+ rb_define_singleton_method(cXMLDtd, "new", ruby_xml_dtd_initialize, -1);
166
+ //rb_define_method(cXMLDocument, "xinclude", ruby_xml_document_xinclude, 0);
167
+ }
168
+
@@ -0,0 +1,17 @@
1
+ #ifndef __RUBY_XML_DTD__
2
+ #define __RUBY_XML_DTD__
3
+
4
+ extern VALUE cXMLDtd;
5
+
6
+ typedef struct rxp_dtd {
7
+ xmlDtdPtr dtd; /* DTD interface */
8
+ //int data_type; /* The data type referenced by *data */
9
+ //void *data; /* Pointer to an external structure of options */
10
+ //int is_ptr; /* Determines if this object owns its data or points to it someplace else */
11
+ //VALUE xmlver; /* T_STRING with the xml version */
12
+ } ruby_xml_dtd;
13
+
14
+ void ruby_init_xml_dtd(void);
15
+ void ruby_dtd_free(ruby_xml_dtd *rxdtd);
16
+
17
+ #endif
@@ -0,0 +1,167 @@
1
+
2
+ /* ruby support for custom scheme handlers */
3
+ /* Author: Martin Povolny (xpovolny@fi.muni.cz) */
4
+
5
+ #include "libxml.h"
6
+ #include "ruby_xml_input_cbg.h"
7
+
8
+ static ic_scheme *first_scheme = 0;
9
+
10
+ int ic_match (char const *filename) {
11
+ ic_scheme *scheme;
12
+
13
+ //fprintf( stderr, "ic_match: %s\n", filename );
14
+
15
+ scheme = first_scheme;
16
+ while (0 != scheme) {
17
+ if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST scheme->scheme_name, scheme->name_len)) {
18
+ return 1;
19
+ }
20
+ scheme = scheme->next_scheme;
21
+ }
22
+ return 0;
23
+ }
24
+
25
+ void* ic_open (char const *filename) {
26
+ ic_doc_context *ic_doc;
27
+ ic_scheme *scheme;
28
+ VALUE res;
29
+
30
+ scheme = first_scheme;
31
+ while (0 != scheme) {
32
+ if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST scheme->scheme_name, scheme->name_len)) {
33
+ ic_doc = (ic_doc_context*)malloc( sizeof(ic_doc_context) );
34
+
35
+ // MUFF res = rb_funcall(
36
+ // rb_funcall( rb_mKernel,
37
+ // rb_intern("const_get"), 1,
38
+ // rb_str_new2(scheme->class) ),
39
+ // rb_intern("document_query"), 1, rb_str_new2(filename) );
40
+ res = rb_funcall( scheme->class,
41
+ rb_intern("document_query"),
42
+ 1,
43
+ rb_str_new2(filename) );
44
+
45
+ ic_doc->buffer = strdup( StringValuePtr(res) );
46
+
47
+ ic_doc->bpos = ic_doc->buffer;
48
+ ic_doc->remaining = strlen(ic_doc->buffer);
49
+ return ic_doc;
50
+ }
51
+ scheme = scheme->next_scheme;
52
+ }
53
+ return 0;
54
+ }
55
+
56
+ int ic_read (void *context, char *buffer, int len) {
57
+ ic_doc_context *ic_doc;
58
+ int ret_len;
59
+ ic_doc = (ic_doc_context*)context;
60
+
61
+ if (len >= ic_doc->remaining) {
62
+ ret_len = ic_doc->remaining;
63
+ } else {
64
+ ret_len = len;
65
+ }
66
+ ic_doc->remaining -= ret_len;
67
+ strncpy( buffer, ic_doc->bpos, ret_len );
68
+ ic_doc->bpos += ret_len;
69
+
70
+ return ret_len;
71
+ }
72
+
73
+ int ic_close (void *context) {
74
+ free( ((ic_doc_context*)context)->buffer );
75
+ free( context );
76
+ return 1;
77
+ }
78
+
79
+ VALUE input_callbacks_register_input_callbacks() {
80
+ xmlRegisterInputCallbacks( ic_match, ic_open, ic_read, ic_close );
81
+ return(Qtrue);
82
+ }
83
+
84
+ VALUE
85
+ input_callbacks_add_scheme (VALUE self, VALUE scheme_name, VALUE class) {
86
+ ic_scheme *scheme;
87
+
88
+ Check_Type(scheme_name, T_STRING);
89
+ //MUFF Check_Type(class, T_STRING);
90
+
91
+ scheme = (ic_scheme*)malloc(sizeof(ic_scheme));
92
+ scheme->next_scheme = 0;
93
+ scheme->scheme_name = strdup(StringValuePtr(scheme_name)); /* TODO alloc, dealloc */
94
+ scheme->name_len = strlen(scheme->scheme_name);
95
+ //MUFF scheme->class = strdup(StringValuePtr(class)); /* TODO alloc, dealloc */
96
+ scheme->class = class; /* TODO alloc, dealloc */
97
+
98
+ //fprintf( stderr, "registered: %s, %d, %s\n", scheme->scheme_name, scheme->name_len, scheme->class );
99
+
100
+ if (0 == first_scheme)
101
+ first_scheme = scheme;
102
+ else {
103
+ ic_scheme *pos;
104
+ pos = first_scheme;
105
+ while (0 != pos->next_scheme)
106
+ pos = pos->next_scheme;
107
+ pos->next_scheme = scheme;
108
+ }
109
+
110
+ return(Qtrue);
111
+ }
112
+
113
+ VALUE
114
+ input_callbacks_remove_scheme (VALUE self, VALUE scheme_name) {
115
+ char *name;
116
+ ic_scheme *save_scheme, *scheme;
117
+
118
+ Check_Type(scheme_name, T_STRING);
119
+ name = StringValuePtr(scheme_name);
120
+
121
+ if (0 == first_scheme)
122
+ return Qfalse;
123
+
124
+ /* check the first one */
125
+ if (!strncmp(name, first_scheme->scheme_name, first_scheme->name_len)) {
126
+ save_scheme = first_scheme->next_scheme;
127
+
128
+ free(first_scheme->scheme_name);
129
+ //MUFF free(first_scheme->class);
130
+ free(first_scheme);
131
+
132
+ first_scheme = save_scheme;
133
+ return Qtrue;
134
+ }
135
+
136
+ scheme = first_scheme;
137
+ while (0 != scheme->next_scheme) {
138
+ if ( !strncmp( name, scheme->next_scheme->scheme_name, scheme->next_scheme->name_len ) ) {
139
+ save_scheme = scheme->next_scheme->next_scheme;
140
+
141
+ free(scheme->next_scheme->scheme_name);
142
+ //MUFF free(scheme->next_scheme->class);
143
+ free(scheme->next_scheme);
144
+
145
+ scheme->next_scheme = save_scheme;
146
+ return Qtrue;
147
+ }
148
+ scheme = scheme->next_scheme;
149
+ }
150
+ return Qfalse;
151
+ }
152
+
153
+ // Rdoc needs to know
154
+ #ifdef RDOC_NEVER_DEFINED
155
+ mXML = rb_define_module("XML");
156
+ #endif
157
+
158
+ void
159
+ ruby_init_input_callbacks(void) {
160
+ VALUE cInputCallbacks;
161
+ cInputCallbacks = rb_define_class_under(mXML, "InputCallbacks", rb_cObject);
162
+
163
+ /* Class Methods */
164
+ rb_define_singleton_method(cInputCallbacks, "register", input_callbacks_register_input_callbacks, 0);
165
+ rb_define_singleton_method(cInputCallbacks, "add_scheme", input_callbacks_add_scheme, 2);
166
+ rb_define_singleton_method(cInputCallbacks, "remove_scheme", input_callbacks_remove_scheme, 1);
167
+ }
@@ -0,0 +1,21 @@
1
+ #ifndef _INPUT_CBG_
2
+ #define _INPUT_CBG_
3
+
4
+ void ruby_init_input_callbacks(void);
5
+
6
+ typedef struct ic_doc_context {
7
+ char *buffer;
8
+ char *bpos;
9
+ int remaining;
10
+ } ic_doc_context;
11
+
12
+ typedef struct ic_scheme {
13
+ char *scheme_name;
14
+ //MUFF char *class;
15
+ VALUE class;
16
+ int name_len;
17
+
18
+ struct ic_scheme *next_scheme;
19
+ } ic_scheme;
20
+
21
+ #endif
@@ -0,0 +1,2139 @@
1
+ /* $Id: ruby_xml_node.c,v 1.3 2006/04/12 12:08:39 roscopeco Exp $ */
2
+
3
+ /* Please see the LICENSE file for copyright and distribution information */
4
+
5
+ #include "libxml.h"
6
+ #include "ruby_xml_node.h"
7
+
8
+ VALUE cXMLNode;
9
+ VALUE eXMLNodeSetNamespace;
10
+ VALUE eXMLNodeFailedModify;
11
+ VALUE eXMLNodeUnknownType;
12
+
13
+ /*
14
+ * call-seq:
15
+ * node.attribute? => (true|false)
16
+ *
17
+ * Determine whether this is an attribute node,
18
+ */
19
+ VALUE
20
+ ruby_xml_node_attribute_q(VALUE self) {
21
+ ruby_xml_node *rxn;
22
+ Data_Get_Struct(self, ruby_xml_node, rxn);
23
+ if (rxn->node->type == XML_ATTRIBUTE_NODE)
24
+ return(Qtrue);
25
+ else
26
+ return(Qfalse);
27
+ }
28
+
29
+
30
+ /*
31
+ * call-seq:
32
+ * node.attribute_decl? => (true|false)
33
+ *
34
+ * Determine whether this is an attribute declaration node,
35
+ */
36
+ VALUE
37
+ ruby_xml_node_attribute_decl_q(VALUE self) {
38
+ ruby_xml_node *rxn;
39
+ Data_Get_Struct(self, ruby_xml_node, rxn);
40
+ if (rxn->node->type == XML_ATTRIBUTE_DECL)
41
+ return(Qtrue);
42
+ else
43
+ return(Qfalse);
44
+ }
45
+
46
+
47
+ /*
48
+ * call-seq:
49
+ * node.base => "uri"
50
+ *
51
+ * Obtain this node's base URI.
52
+ */
53
+ VALUE
54
+ ruby_xml_node_base_get(VALUE self) {
55
+ ruby_xml_node *rxn;
56
+ Data_Get_Struct(self, ruby_xml_node, rxn);
57
+ if (rxn->node->doc == NULL)
58
+ return(Qnil);
59
+
60
+ // TODO some NULL checking, raises ArgumentError in Ruby:
61
+ // ArgumentError: NULL pointer given
62
+
63
+ return(rb_str_new2((const char*)xmlNodeGetBase(rxn->node->doc, rxn->node)));
64
+ }
65
+
66
+
67
+ // TODO node_base_set should support setting back to nil
68
+
69
+ /*
70
+ * call-seq:
71
+ * node.base = "uri"
72
+ *
73
+ * Set this node's base URI.
74
+ */
75
+ VALUE
76
+ ruby_xml_node_base_set(VALUE self, VALUE uri) {
77
+ ruby_xml_node *node;
78
+
79
+ Check_Type(uri, T_STRING);
80
+ Data_Get_Struct(self, ruby_xml_node, node);
81
+ if (node->node->doc == NULL)
82
+ return(Qnil);
83
+
84
+ xmlNodeSetBase(node->node, (xmlChar*)StringValuePtr(uri));
85
+ return(Qtrue);
86
+ }
87
+
88
+
89
+ /*
90
+ * call-seq:
91
+ * node.cdata? => (true|false)
92
+ *
93
+ * Determine whether this is a #CDATA node
94
+ */
95
+ VALUE
96
+ ruby_xml_node_cdata_q(VALUE self) {
97
+ ruby_xml_node *rxn;
98
+ Data_Get_Struct(self, ruby_xml_node, rxn);
99
+ if (rxn->node->type == XML_CDATA_SECTION_NODE)
100
+ return(Qtrue);
101
+ else
102
+ return(Qfalse);
103
+ }
104
+
105
+
106
+ /*
107
+ * call-seq:
108
+ * node.comment? => (true|false)
109
+ *
110
+ * Determine whether this is a comment node
111
+ */
112
+ VALUE
113
+ ruby_xml_node_comment_q(VALUE self) {
114
+ ruby_xml_node *rxn;
115
+ Data_Get_Struct(self, ruby_xml_node, rxn);
116
+ if (rxn->node->type == XML_COMMENT_NODE)
117
+ return(Qtrue);
118
+ else
119
+ return(Qfalse);
120
+ }
121
+
122
+
123
+ /*
124
+ * call-seq:
125
+ * node << ("string" | node)
126
+ *
127
+ * Add the specified string or XML::Node to this node's
128
+ * content.
129
+ */
130
+ VALUE
131
+ ruby_xml_node_content_add(VALUE self, VALUE obj) {
132
+ ruby_xml_node *node;
133
+ VALUE str;
134
+
135
+ Data_Get_Struct(self, ruby_xml_node, node);
136
+ if (rb_obj_is_kind_of(obj, cXMLNode)) {
137
+ return(ruby_xml_node_child_set(self, obj));
138
+ } else if (TYPE(obj) == T_STRING) {
139
+ xmlNodeAddContent(node->node, (xmlChar*)StringValuePtr(obj));
140
+ return(obj);
141
+ } else {
142
+ str = rb_obj_as_string(obj);
143
+ if (NIL_P(str) || TYPE(str) != T_STRING)
144
+ rb_raise(rb_eTypeError, "invalid argument: must be string or XML::Node");
145
+
146
+ xmlNodeAddContent(node->node, (xmlChar*)StringValuePtr(str));
147
+ return(obj);
148
+ }
149
+ }
150
+
151
+
152
+ /*
153
+ * call-seq:
154
+ * node.content => "string"
155
+ *
156
+ * Obtain this node's content as a string.
157
+ */
158
+ VALUE
159
+ ruby_xml_node_content_get(VALUE self) {
160
+ ruby_xml_node *rxn;
161
+ xmlChar *content;
162
+ VALUE out;
163
+
164
+ Data_Get_Struct(self, ruby_xml_node, rxn);
165
+ content = xmlNodeGetContent(rxn->node);
166
+ out = rb_str_new2((const char *) content);
167
+ xmlFree(content);
168
+
169
+ return out;
170
+ }
171
+
172
+ /*
173
+ * call-seq:
174
+ * node.content = "string"
175
+ *
176
+ * Set this node's content to the specified string.
177
+ */
178
+ VALUE
179
+ ruby_xml_node_content_set(VALUE self, VALUE content) {
180
+ ruby_xml_node *node;
181
+
182
+ Check_Type(content, T_STRING);
183
+ Data_Get_Struct(self, ruby_xml_node, node);
184
+ xmlNodeSetContent(node->node, (xmlChar*)StringValuePtr(content));
185
+ return(Qtrue);
186
+ }
187
+
188
+
189
+ /*
190
+ * call-seq:
191
+ * node.content_stripped => "string"
192
+ *
193
+ * Obtain this node's stripped content.
194
+ *
195
+ * *Deprecated*: Stripped content can be obtained via the
196
+ * +content+ method.
197
+ */
198
+ VALUE
199
+ ruby_xml_node_content_stripped_get(VALUE self) {
200
+ ruby_xml_node *rxn;
201
+
202
+ Data_Get_Struct(self, ruby_xml_node, rxn);
203
+ if (rxn->node->content == NULL)
204
+ return(Qnil);
205
+ else
206
+ return(rb_str_new2((const char*)xmlNodeGetContent(rxn->node)));
207
+ }
208
+
209
+ ////////////////////////////////////////////////////
210
+ // TODO This whole child thing seems to work in some odd ways.
211
+ // Try setting child= to a node with multiple children,
212
+ // then get it back through child= .
213
+
214
+ /*
215
+ * call-seq:
216
+ * node.child => node
217
+ *
218
+ * Obtain this node's first child node, if any.
219
+ */
220
+ VALUE
221
+ ruby_xml_node_child_get(VALUE self) {
222
+ ruby_xml_node *node;
223
+ xmlNodePtr tmp;
224
+
225
+ Data_Get_Struct(self, ruby_xml_node, node);
226
+
227
+ switch (node->node->type) {
228
+ case XML_ELEMENT_NODE:
229
+ case XML_ENTITY_REF_NODE:
230
+ case XML_ENTITY_NODE:
231
+ case XML_PI_NODE:
232
+ case XML_COMMENT_NODE:
233
+ case XML_DOCUMENT_NODE:
234
+ #ifdef LIBXML_DOCB_ENABLED
235
+ case XML_DOCB_DOCUMENT_NODE:
236
+ #endif
237
+ case XML_HTML_DOCUMENT_NODE:
238
+ case XML_DTD_NODE:
239
+ tmp = node->node->children;
240
+ break;
241
+ case XML_ATTRIBUTE_NODE:
242
+ {
243
+ xmlAttrPtr attr = (xmlAttrPtr) node->node;
244
+ tmp = attr->children;
245
+ break;
246
+ }
247
+ default:
248
+ tmp = NULL;
249
+ break;
250
+ }
251
+
252
+ if (tmp == NULL)
253
+ return(Qnil);
254
+ else
255
+ return(ruby_xml_node_new2(cXMLNode, node->xd, tmp));
256
+ }
257
+
258
+
259
+ /*
260
+ * call-seq:
261
+ * node.child? => (true|false)
262
+ *
263
+ * Determine whether this node has at least one child.
264
+ */
265
+ VALUE
266
+ ruby_xml_node_child_q(VALUE self) {
267
+ ruby_xml_node *rxn;
268
+ xmlNodePtr node;
269
+ Data_Get_Struct(self, ruby_xml_node, rxn);
270
+
271
+ node = NULL;
272
+ switch (rxn->node->type) {
273
+ case XML_ELEMENT_NODE:
274
+ case XML_ENTITY_REF_NODE:
275
+ case XML_ENTITY_NODE:
276
+ case XML_PI_NODE:
277
+ case XML_COMMENT_NODE:
278
+ case XML_DOCUMENT_NODE:
279
+ #ifdef LIBXML_DOCB_ENABLED
280
+ case XML_DOCB_DOCUMENT_NODE:
281
+ #endif
282
+ case XML_HTML_DOCUMENT_NODE:
283
+ case XML_DTD_NODE:
284
+ node = rxn->node->children;
285
+ break;
286
+ case XML_ATTRIBUTE_NODE:
287
+ {
288
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
289
+ node = attr->children;
290
+ break;
291
+ }
292
+ default:
293
+ node = NULL;
294
+ }
295
+
296
+ if (node == NULL)
297
+ return(Qfalse);
298
+ else
299
+ return(Qtrue);
300
+ }
301
+
302
+
303
+ /*
304
+ * call-seq:
305
+ * node.child = node
306
+ *
307
+ * Set a child node for this node.
308
+ */
309
+ VALUE
310
+ ruby_xml_node_child_set(VALUE self, VALUE rnode) {
311
+ ruby_xml_node *cnode, *pnode;
312
+ xmlNodePtr ret;
313
+
314
+ if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
315
+ rb_raise(rb_eTypeError, "Must pass an XML::Node object");
316
+
317
+ Data_Get_Struct(self, ruby_xml_node, pnode);
318
+ Data_Get_Struct(rnode, ruby_xml_node, cnode);
319
+
320
+ ret = xmlAddChild(pnode->node, cnode->node);
321
+ if (ret == NULL)
322
+ rb_raise(eXMLNodeFailedModify, "unable to add a child to the document");
323
+
324
+ ruby_xml_node_set_ptr(rnode, 1);
325
+ return(ruby_xml_node_new2(cXMLNode, pnode->xd, ret));
326
+ }
327
+
328
+ ////////////////////////////////////////////////
329
+ // TODO new Documents seem to be created quite readily...
330
+
331
+ /*
332
+ * call-seq:
333
+ * node.doc => document
334
+ *
335
+ * Obtain the XML::Document this node belongs to.
336
+ */
337
+ VALUE
338
+ ruby_xml_node_doc(VALUE self) {
339
+ ruby_xml_document *rxd;
340
+ ruby_xml_node *rxn;
341
+ xmlDocPtr doc;
342
+ VALUE docobj;
343
+
344
+ Data_Get_Struct(self, ruby_xml_node, rxn);
345
+
346
+ switch (rxn->node->type) {
347
+ case XML_DOCUMENT_NODE:
348
+ #ifdef LIBXML_DOCB_ENABLED
349
+ case XML_DOCB_DOCUMENT_NODE:
350
+ #endif
351
+ case XML_HTML_DOCUMENT_NODE:
352
+ doc = NULL;
353
+ break;
354
+ case XML_ATTRIBUTE_NODE:
355
+ {
356
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
357
+ doc = attr->doc;
358
+ break;
359
+ }
360
+ case XML_NAMESPACE_DECL:
361
+ doc = NULL;
362
+ break;
363
+ default:
364
+ doc = rxn->node->doc;
365
+ break;
366
+ }
367
+
368
+ if (doc == NULL)
369
+ return(Qnil);
370
+
371
+ docobj = ruby_xml_document_new(cXMLDocument, doc);
372
+ Data_Get_Struct(docobj, ruby_xml_document, rxd);
373
+ rxd->is_ptr = 1;
374
+ return(docobj);
375
+ }
376
+
377
+
378
+ /*
379
+ * call-seq:
380
+ * node.docbook? => (true|false)
381
+ *
382
+ * Determine whether this is a docbook node.
383
+ */
384
+ VALUE
385
+ ruby_xml_node_docbook_doc_q(VALUE self) {
386
+ #ifdef LIBXML_DOCB_ENABLED
387
+ ruby_xml_node *rxn;
388
+ Data_Get_Struct(self, ruby_xml_node, rxn);
389
+ if (rxn->node->type == XML_DOCB_DOCUMENT_NODE)
390
+ return(Qtrue);
391
+ else
392
+ return(Qfalse);
393
+ #else
394
+ rb_warn("libxml compiled without docbook support");
395
+ return(Qfalse);
396
+ #endif
397
+ }
398
+
399
+
400
+ /*
401
+ * call-seq:
402
+ * node.doctype? => (true|false)
403
+ *
404
+ * Determine whether this is a DOCTYPE node.
405
+ */
406
+ VALUE
407
+ ruby_xml_node_doctype_q(VALUE self) {
408
+ ruby_xml_node *rxn;
409
+ Data_Get_Struct(self, ruby_xml_node, rxn);
410
+ if (rxn->node->type == XML_DOCUMENT_TYPE_NODE)
411
+ return(Qtrue);
412
+ else
413
+ return(Qfalse);
414
+ }
415
+
416
+
417
+ /*
418
+ * call-seq:
419
+ * node.document? => (true|false)
420
+ *
421
+ * Determine whether this is a document node.
422
+ */
423
+ VALUE
424
+ ruby_xml_node_document_q(VALUE self) {
425
+ ruby_xml_node *rxn;
426
+ Data_Get_Struct(self, ruby_xml_node, rxn);
427
+ if (rxn->node->type == XML_DOCUMENT_NODE)
428
+ return(Qtrue);
429
+ else
430
+ return(Qfalse);
431
+ }
432
+
433
+
434
+ /*
435
+ * call-seq:
436
+ * node.dtd? => (true|false)
437
+ *
438
+ * Determine whether this is a DTD node.
439
+ */
440
+ VALUE
441
+ ruby_xml_node_dtd_q(VALUE self) {
442
+ ruby_xml_node *rxn;
443
+ Data_Get_Struct(self, ruby_xml_node, rxn);
444
+ if (rxn->node->type == XML_DTD_NODE)
445
+ return(Qtrue);
446
+ else
447
+ return(Qfalse);
448
+ }
449
+
450
+
451
+ /*
452
+ * call-seq:
453
+ * node.dump => (true|nil)
454
+ *
455
+ * Dump this node to stdout.
456
+ */
457
+ VALUE
458
+ ruby_xml_node_dump(VALUE self) {
459
+ ruby_xml_node *rxn;
460
+ xmlBufferPtr buf;
461
+
462
+ Data_Get_Struct(self, ruby_xml_node, rxn);
463
+
464
+ if (rxn->node->doc == NULL)
465
+ return(Qnil);
466
+
467
+ buf = xmlBufferCreate();
468
+ xmlNodeDump(buf, rxn->node->doc, rxn->node, 0, 1);
469
+ xmlBufferDump(stdout, buf);
470
+ xmlBufferFree(buf);
471
+ return(Qtrue);
472
+ }
473
+
474
+
475
+ /*
476
+ * call-seq:
477
+ * node.debug_dump => (true|nil)
478
+ *
479
+ * Dump this node to stdout, including any debugging
480
+ * information.
481
+ */
482
+ VALUE
483
+ ruby_xml_node_debug_dump(VALUE self) {
484
+ ruby_xml_node *rxn;
485
+ Data_Get_Struct(self, ruby_xml_node, rxn);
486
+
487
+ if (rxn->node->doc == NULL)
488
+ return(Qnil);
489
+
490
+ xmlElemDump(stdout, rxn->node->doc, rxn->node);
491
+ return(Qtrue);
492
+ }
493
+
494
+
495
+ /*
496
+ * call-seq:
497
+ * node.element? => (true|false)
498
+ *
499
+ * Determine whether this is an element node.
500
+ */
501
+ VALUE
502
+ ruby_xml_node_element_q(VALUE self) {
503
+ ruby_xml_node *rxn;
504
+ Data_Get_Struct(self, ruby_xml_node, rxn);
505
+ if (rxn->node->type == XML_ELEMENT_NODE)
506
+ return(Qtrue);
507
+ else
508
+ return(Qfalse);
509
+ }
510
+
511
+
512
+ /*
513
+ * call-seq:
514
+ * node.element_decl? => (true|false)
515
+ *
516
+ * Determine whether this is an element declaration node.
517
+ */
518
+ VALUE
519
+ ruby_xml_node_element_decl_q(VALUE self) {
520
+ ruby_xml_node *rxn;
521
+ Data_Get_Struct(self, ruby_xml_node, rxn);
522
+ if (rxn->node->type == XML_ELEMENT_DECL)
523
+ return(Qtrue);
524
+ else
525
+ return(Qfalse);
526
+ }
527
+
528
+
529
+ /*
530
+ * call-seq:
531
+ * node.empty? => (true|false)
532
+ *
533
+ * Determine whether this node is empty.
534
+ */
535
+ VALUE
536
+ ruby_xml_node_empty_q(VALUE self) {
537
+ ruby_xml_node *rxn;
538
+ Data_Get_Struct(self, ruby_xml_node, rxn);
539
+ if (rxn->node == NULL)
540
+ return(Qnil);
541
+
542
+ return((xmlIsBlankNode(rxn->node) == 1) ? Qtrue : Qfalse);
543
+ }
544
+
545
+
546
+ /*
547
+ * call-seq:
548
+ * node.entity? => (true|false)
549
+ *
550
+ * Determine whether this is an entity node.
551
+ */
552
+ VALUE
553
+ ruby_xml_node_entity_q(VALUE self) {
554
+ ruby_xml_node *rxn;
555
+ Data_Get_Struct(self, ruby_xml_node, rxn);
556
+ if (rxn->node->type == XML_ENTITY_NODE)
557
+ return(Qtrue);
558
+ else
559
+ return(Qfalse);
560
+ }
561
+
562
+
563
+ /*
564
+ * call-seq:
565
+ * node.entity_ref? => (true|false)
566
+ *
567
+ * Determine whether this is an entity reference node.
568
+ */
569
+ VALUE
570
+ ruby_xml_node_entity_ref_q(VALUE self) {
571
+ ruby_xml_node *rxn;
572
+ Data_Get_Struct(self, ruby_xml_node, rxn);
573
+ if (rxn->node->type == XML_ENTITY_REF_NODE)
574
+ return(Qtrue);
575
+ else
576
+ return(Qfalse);
577
+ }
578
+
579
+ VALUE ruby_xml_node_to_s(VALUE self);
580
+
581
+ /*
582
+ * call-seq:
583
+ * node.eql?(other_node) => (true|false)
584
+ *
585
+ * Test equality between the two nodes. Equality is determined based
586
+ * on the XML representation of the nodes.
587
+ */
588
+ VALUE
589
+ ruby_xml_node_eql_q(VALUE self, VALUE other) {
590
+ // TODO this isn't the best way to handle this
591
+ ruby_xml_node *rxn, *orxn;
592
+ VALUE thisxml, otherxml;
593
+ Data_Get_Struct(self, ruby_xml_node, rxn);
594
+ Data_Get_Struct(other, ruby_xml_node, orxn);
595
+ thisxml = ruby_xml_node_to_s(self);
596
+ otherxml = ruby_xml_node_to_s(other);
597
+
598
+ return(rb_funcall(thisxml, rb_intern("=="), 1, otherxml));
599
+ }
600
+
601
+
602
+ /*
603
+ * call-seq:
604
+ * node.find(xpath_expr, namespace = [any]) => nodeset
605
+ *
606
+ * Find nodes matching the specified xpath expression, optionally
607
+ * using the specified namespaces. Returns an XML::Node::Set.
608
+ */
609
+ VALUE
610
+ ruby_xml_node_find(int argc, VALUE *argv, VALUE self) {
611
+ int i, vargc;
612
+ VALUE *vargv;
613
+
614
+ if (argc > 2 || argc < 1)
615
+ rb_raise(rb_eArgError, "wrong number of arguments (need 1 or 2)");
616
+
617
+ vargc = argc + 1;
618
+ vargv = ALLOC_N(VALUE, vargc + 1);
619
+ vargv[0] = self;
620
+ for (i = 0; i<argc; i++)
621
+ vargv[i + 1] = argv[i];
622
+
623
+ return(ruby_xml_xpath_find2(vargc, vargv));
624
+ }
625
+
626
+ /*
627
+ * call-seq:
628
+ * node.find_first(xpath_expr, namespace = [any]) => nodeset
629
+ *
630
+ * Find the first node matching the specified xpath expression, optionally
631
+ * using the specified namespaces. Returns an XML::Node.
632
+ */
633
+ VALUE
634
+ ruby_xml_node_find_first(int argc, VALUE *argv, VALUE self) {
635
+ VALUE ns = ruby_xml_node_find(argc, argv, self);
636
+ ruby_xml_node_set *rxnset;
637
+
638
+ Data_Get_Struct(ns, ruby_xml_node_set, rxnset);
639
+ if (rxnset->node_set == NULL || rxnset->node_set->nodeNr < 1)
640
+ return(Qnil);
641
+
642
+ VALUE nodeobj;
643
+ switch(rxnset->node_set->nodeTab[0]->type) {
644
+ case XML_ATTRIBUTE_NODE:
645
+ nodeobj = ruby_xml_attr_new2(cXMLAttr, rxnset->xd, (xmlAttrPtr)rxnset->node_set->nodeTab[0]);
646
+ break;
647
+ default:
648
+ nodeobj = ruby_xml_node_new2(cXMLNode, rxnset->xd, rxnset->node_set->nodeTab[0]);
649
+ }
650
+
651
+ return(nodeobj);
652
+ }
653
+
654
+
655
+ /*
656
+ * call-seq:
657
+ * node.fragment? => (true|false)
658
+ *
659
+ * Determine whether this node is a fragment.
660
+ */
661
+ VALUE
662
+ ruby_xml_node_fragment_q(VALUE self) {
663
+ ruby_xml_node *rxn;
664
+ Data_Get_Struct(self, ruby_xml_node, rxn);
665
+ if (rxn->node->type == XML_DOCUMENT_FRAG_NODE)
666
+ return(Qtrue);
667
+ else
668
+ return(Qfalse);
669
+ }
670
+
671
+
672
+ void ruby_xml_node_free(ruby_xml_node *rxn) {
673
+ if (rxn->node != NULL && !rxn->is_ptr) {
674
+ xmlUnlinkNode(rxn->node);
675
+ xmlFreeNode(rxn->node);
676
+ rxn->node = NULL;
677
+ }
678
+
679
+ free(rxn);
680
+ }
681
+
682
+
683
+ /*
684
+ * call-seq:
685
+ * node.hash => fixnum
686
+ *
687
+ * Returns the hash-code for this node. This is the hash of the XML
688
+ * representation in order to be consistent with eql.
689
+ */
690
+ VALUE
691
+ ruby_xml_node_hash(VALUE self) {
692
+ ruby_xml_node *rxn;
693
+ VALUE thisxml;
694
+ Data_Get_Struct(self, ruby_xml_node, rxn);
695
+ thisxml = ruby_xml_node_to_s(self);
696
+
697
+ return(rb_funcall(thisxml, rb_intern("hash"), 0));
698
+ }
699
+
700
+
701
+ /*
702
+ * call-seq:
703
+ * node.html_doc? => (true|false)
704
+ *
705
+ * Determine whether this node is an html document node.
706
+ */
707
+ VALUE
708
+ ruby_xml_node_html_doc_q(VALUE self) {
709
+ ruby_xml_node *rxn;
710
+ Data_Get_Struct(self, ruby_xml_node, rxn);
711
+ if (rxn->node->type == XML_HTML_DOCUMENT_NODE)
712
+ return(Qtrue);
713
+ else
714
+ return(Qfalse);
715
+ }
716
+
717
+
718
+ /*
719
+ * call-seq:
720
+ * XML::Node.new(name, content = nil) => node
721
+ *
722
+ * Create a new node with the specified name, optionally setting
723
+ * the node's content.
724
+ */
725
+ VALUE
726
+ ruby_xml_node_initialize(int argc, VALUE *argv, VALUE class) {
727
+ ruby_xml_node *rxn;
728
+ VALUE name, node, str;
729
+
730
+ str = Qnil;
731
+
732
+ switch(argc) {
733
+ case 2:
734
+ switch (TYPE(str)) {
735
+ case T_STRING:
736
+ str = argv[1];
737
+ break;
738
+ default:
739
+ str = rb_obj_as_string(argv[1]);
740
+ if (NIL_P(str))
741
+ Check_Type(str, T_STRING);
742
+ break;
743
+ }
744
+
745
+ /* Intentionally fall through to case 1: as a way of setting up
746
+ * the object. Sneaky, but effective. Probably should use a goto
747
+ * instead. */
748
+ case 1:
749
+ name = argv[0];
750
+ Check_Type(name, T_STRING);
751
+ node = ruby_xml_node_new(class, NULL);
752
+ Data_Get_Struct(node, ruby_xml_node, rxn);
753
+ rxn->node = xmlNewNode(NULL, (xmlChar*)StringValuePtr(name));
754
+ if (rxn->node == NULL)
755
+ return(Qnil);
756
+
757
+ if (!NIL_P(str))
758
+ ruby_xml_node_content_set(node, str);
759
+
760
+ break;
761
+
762
+ default:
763
+ rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
764
+ }
765
+
766
+ return(node);
767
+ }
768
+
769
+
770
+ /*
771
+ * call-seq:
772
+ * node.lang => "string"
773
+ *
774
+ * Obtain the language set for this node, if any.
775
+ * This is set in XML via the xml:lang attribute.
776
+ */
777
+ VALUE
778
+ ruby_xml_node_lang_get(VALUE self) {
779
+ ruby_xml_node *rxn;
780
+ xmlChar *lang;
781
+
782
+ Data_Get_Struct(self, ruby_xml_node, rxn);
783
+ lang = xmlNodeGetLang(rxn->node);
784
+
785
+ if (lang == NULL)
786
+ return(Qnil);
787
+ else
788
+ return(rb_str_new2((const char*)lang));
789
+ }
790
+
791
+
792
+ // TODO node_lang_set should support setting back to nil
793
+
794
+ /*
795
+ * call-seq:
796
+ * node.lang = "string"
797
+ *
798
+ * Set the language for this node. This affects the value
799
+ * of the xml:lang attribute.
800
+ */
801
+ VALUE
802
+ ruby_xml_node_lang_set(VALUE self, VALUE lang) {
803
+ ruby_xml_node *node;
804
+
805
+ Check_Type(lang, T_STRING);
806
+ Data_Get_Struct(self, ruby_xml_node, node);
807
+ xmlNodeSetLang(node->node, (xmlChar*)StringValuePtr(lang));
808
+
809
+ return(Qtrue);
810
+ }
811
+
812
+
813
+ /*
814
+ * call-seq:
815
+ * node.last => node
816
+ *
817
+ * Obtain the last child node of this node, if any.
818
+ */
819
+ VALUE
820
+ ruby_xml_node_last_get(VALUE self) {
821
+ ruby_xml_node *rxn;
822
+ xmlNodePtr node;
823
+
824
+ Data_Get_Struct(self, ruby_xml_node, rxn);
825
+
826
+ switch (rxn->node->type) {
827
+ case XML_ELEMENT_NODE:
828
+ case XML_ENTITY_REF_NODE:
829
+ case XML_ENTITY_NODE:
830
+ case XML_PI_NODE:
831
+ case XML_COMMENT_NODE:
832
+ case XML_DOCUMENT_NODE:
833
+ #ifdef LIBXML_DOCB_ENABLED
834
+ case XML_DOCB_DOCUMENT_NODE:
835
+ #endif
836
+ case XML_HTML_DOCUMENT_NODE:
837
+ case XML_DTD_NODE:
838
+ node = rxn->node->last;
839
+ break;
840
+ case XML_ATTRIBUTE_NODE:
841
+ {
842
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
843
+ node = attr->last;
844
+ }
845
+ default:
846
+ node = NULL;
847
+ break;
848
+ }
849
+
850
+ if (node == NULL)
851
+ return(Qnil);
852
+ else
853
+ return(ruby_xml_node_new2(cXMLNode, rxn->xd, node));
854
+ }
855
+
856
+
857
+ /*
858
+ * call-seq:
859
+ * node.last? => (true|false)
860
+ *
861
+ * Determine whether this node has a last child node.
862
+ */
863
+ VALUE
864
+ ruby_xml_node_last_q(VALUE self) {
865
+ ruby_xml_node *rxn;
866
+ xmlNodePtr node;
867
+
868
+ Data_Get_Struct(self, ruby_xml_node, rxn);
869
+
870
+ switch (rxn->node->type) {
871
+ case XML_ELEMENT_NODE:
872
+ case XML_ENTITY_REF_NODE:
873
+ case XML_ENTITY_NODE:
874
+ case XML_PI_NODE:
875
+ case XML_COMMENT_NODE:
876
+ case XML_DOCUMENT_NODE:
877
+ #ifdef LIBXML_DOCB_ENABLED
878
+ case XML_DOCB_DOCUMENT_NODE:
879
+ #endif
880
+ case XML_HTML_DOCUMENT_NODE:
881
+ case XML_DTD_NODE:
882
+ node = rxn->node->last;
883
+ break;
884
+ case XML_ATTRIBUTE_NODE:
885
+ {
886
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
887
+ node = attr->last;
888
+ }
889
+ default:
890
+ node = NULL;
891
+ break;
892
+ }
893
+
894
+ if (node == NULL)
895
+ return(Qfalse);
896
+ else
897
+ return(Qtrue);
898
+ }
899
+
900
+
901
+ /*
902
+ * call-seq:
903
+ * node.line_num => num
904
+ *
905
+ * Obtain the line number (in the XML document) that this
906
+ * node was read from. If +default_line_numbers+ is set
907
+ * false (the default), this method returns zero.
908
+ */
909
+ VALUE
910
+ ruby_xml_node_line_num(VALUE self) {
911
+ ruby_xml_node *rxn;
912
+ long line_num;
913
+ Data_Get_Struct(self, ruby_xml_node, rxn);
914
+
915
+ if (!xmlLineNumbersDefaultValue)
916
+ rb_warn("Line numbers were not retained: use XML::Parser::default_line_numbers=true");
917
+
918
+ line_num = xmlGetLineNo(rxn->node);
919
+ if (line_num == -1)
920
+ return(Qnil);
921
+ else
922
+ return(INT2NUM((long)line_num));
923
+ }
924
+
925
+
926
+ /*
927
+ * call-seq:
928
+ * node.xlink? => (true|false)
929
+ *
930
+ * Determine whether this node is an xlink node.
931
+ */
932
+ VALUE
933
+ ruby_xml_node_xlink_q(VALUE self) {
934
+ ruby_xml_node *node;
935
+ ruby_xml_document *doc;
936
+ xlinkType xlt;
937
+
938
+ Data_Get_Struct(self, ruby_xml_node, node);
939
+ Data_Get_Struct(node->xd, ruby_xml_document, doc);
940
+ xlt = xlinkIsLink(doc->doc, node->node);
941
+
942
+ if (xlt == XLINK_TYPE_NONE)
943
+ return(Qfalse);
944
+ else
945
+ return(Qtrue);
946
+ }
947
+
948
+
949
+ /*
950
+ * call-seq:
951
+ * node.xlink_type => num
952
+ *
953
+ * Obtain the type identifier for this xlink, if applicable.
954
+ * If this is not an xlink node (see +xlink?+), will return
955
+ * nil.
956
+ */
957
+ VALUE
958
+ ruby_xml_node_xlink_type(VALUE self) {
959
+ ruby_xml_node *node;
960
+ ruby_xml_document *doc;
961
+ xlinkType xlt;
962
+
963
+ Data_Get_Struct(self, ruby_xml_node, node);
964
+ Data_Get_Struct(node->xd, ruby_xml_document, doc);
965
+ xlt = xlinkIsLink(doc->doc, node->node);
966
+
967
+ if (xlt == XLINK_TYPE_NONE)
968
+ return(Qnil);
969
+ else
970
+ return(INT2NUM(xlt));
971
+ }
972
+
973
+
974
+ /*
975
+ * call-seq:
976
+ * node.xlink_type_name => "string"
977
+ *
978
+ * Obtain the type name for this xlink, if applicable.
979
+ * If this is not an xlink node (see +xlink?+), will return
980
+ * nil.
981
+ */
982
+ VALUE
983
+ ruby_xml_node_xlink_type_name(VALUE self) {
984
+ ruby_xml_node *node;
985
+ ruby_xml_document *doc;
986
+ xlinkType xlt;
987
+
988
+ Data_Get_Struct(self, ruby_xml_node, node);
989
+ Data_Get_Struct(node->xd, ruby_xml_document, doc);
990
+ xlt = xlinkIsLink(doc->doc, node->node);
991
+
992
+ switch(xlt) {
993
+ case XLINK_TYPE_NONE:
994
+ return(Qnil);
995
+ case XLINK_TYPE_SIMPLE:
996
+ return(rb_str_new2("simple"));
997
+ case XLINK_TYPE_EXTENDED:
998
+ return(rb_str_new2("extended"));
999
+ case XLINK_TYPE_EXTENDED_SET:
1000
+ return(rb_str_new2("extended_set"));
1001
+ default:
1002
+ rb_fatal("Unknowng xlink type, %d", xlt);
1003
+ }
1004
+ }
1005
+
1006
+
1007
+ static void
1008
+ ruby_xml_node_mark(ruby_xml_node *rxn) {
1009
+ if (rxn == NULL) return;
1010
+ if (!NIL_P(rxn->xd)) rb_gc_mark(rxn->xd);
1011
+ }
1012
+
1013
+
1014
+ /*
1015
+ * call-seq:
1016
+ * node.name => "string"
1017
+ *
1018
+ * Obtain this node's name.
1019
+ */
1020
+ VALUE
1021
+ ruby_xml_node_name_get(VALUE self) {
1022
+ ruby_xml_node *rxn;
1023
+ const xmlChar *name;
1024
+
1025
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1026
+
1027
+ switch (rxn->node->type) {
1028
+ case XML_DOCUMENT_NODE:
1029
+ #ifdef LIBXML_DOCB_ENABLED
1030
+ case XML_DOCB_DOCUMENT_NODE:
1031
+ #endif
1032
+ case XML_HTML_DOCUMENT_NODE:
1033
+ {
1034
+ xmlDocPtr doc = (xmlDocPtr) rxn->node;
1035
+ name = doc->URL;
1036
+ break;
1037
+ }
1038
+ case XML_ATTRIBUTE_NODE:
1039
+ {
1040
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1041
+ name = attr->name;
1042
+ break;
1043
+ }
1044
+ case XML_NAMESPACE_DECL:
1045
+ {
1046
+ xmlNsPtr ns = (xmlNsPtr) rxn->node;
1047
+ name = ns->prefix;
1048
+ break;
1049
+ }
1050
+ default:
1051
+ name = rxn->node->name;
1052
+ break;
1053
+ }
1054
+
1055
+ if (rxn->node->name == NULL)
1056
+ return(Qnil);
1057
+ else
1058
+ return(rb_str_new2((const char*)name));
1059
+ }
1060
+
1061
+
1062
+ /*
1063
+ * call-seq:
1064
+ * node.name = "string"
1065
+ *
1066
+ * Set this node's name.
1067
+ */
1068
+ VALUE
1069
+ ruby_xml_node_name_set(VALUE self, VALUE name) {
1070
+ ruby_xml_node *node;
1071
+
1072
+ Check_Type(name, T_STRING);
1073
+ Data_Get_Struct(self, ruby_xml_node, node);
1074
+ xmlNodeSetName(node->node, (xmlChar*)StringValuePtr(name));
1075
+ return(Qtrue);
1076
+ }
1077
+
1078
+
1079
+ /*
1080
+ * call-seq:
1081
+ * node.namespace => [namespace, ..., namespace]
1082
+ *
1083
+ * Obtain an array of +XML::NS+ objects representing
1084
+ * this node's xmlns attributes
1085
+ */
1086
+ VALUE
1087
+ ruby_xml_node_namespace_get(VALUE self) {
1088
+ ruby_xml_node *node;
1089
+ xmlNsPtr *nsList, *cur;
1090
+ VALUE arr, ns;
1091
+
1092
+ Data_Get_Struct(self, ruby_xml_node, node);
1093
+ if (node->node == NULL)
1094
+ return(Qnil);
1095
+
1096
+ nsList = xmlGetNsList(node->node->doc, node->node);
1097
+
1098
+ if (nsList == NULL)
1099
+ return(Qnil);
1100
+
1101
+ arr = rb_ary_new();
1102
+ for (cur = nsList; *cur != NULL; cur++) {
1103
+ ns = ruby_xml_ns_new2(cXMLNS, node->xd, *cur);
1104
+ if (ns == Qnil)
1105
+ continue;
1106
+ else
1107
+ rb_ary_push(arr, ns);
1108
+ }
1109
+ xmlFree(nsList);
1110
+
1111
+ return(arr);
1112
+ }
1113
+
1114
+
1115
+ /*
1116
+ * call-seq:
1117
+ * node.namespace_node => namespace.
1118
+ *
1119
+ * Obtain this node's namespace node.
1120
+ */
1121
+ VALUE
1122
+ ruby_xml_node_namespace_get_node(VALUE self) {
1123
+ ruby_xml_node *node;
1124
+
1125
+ Data_Get_Struct(self, ruby_xml_node, node);
1126
+ if (node->node->ns == NULL)
1127
+ return(Qnil);
1128
+ else
1129
+ return(ruby_xml_ns_new2(cXMLNS, node->xd, node->node->ns));
1130
+ }
1131
+
1132
+ // TODO namespace_set can take varargs (in fact, must if used
1133
+ // with strings), but I cannot see how you can call
1134
+ // that version, apart from with 'send'
1135
+ //
1136
+ // Would sure be nice to support foo.namespace['foo'] = 'bar'
1137
+ // but maybe that's not practical...
1138
+
1139
+ /*
1140
+ * call-seq:
1141
+ * node.namespace = namespace
1142
+ *
1143
+ * Add the specified XML::NS object to this node's xmlns attributes.
1144
+ */
1145
+ VALUE
1146
+ ruby_xml_node_namespace_set(int argc, VALUE *argv, VALUE self) {
1147
+ VALUE rns, rprefix;
1148
+ ruby_xml_node *rxn;
1149
+ ruby_xml_ns *rxns;
1150
+ xmlNsPtr ns;
1151
+ char *cp, *href;
1152
+
1153
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1154
+ switch (argc) {
1155
+ case 1:
1156
+ rns = argv[0];
1157
+ if (TYPE(rns) == T_STRING) {
1158
+ cp = strchr(StringValuePtr(rns), (int)':');
1159
+ if (cp == NULL) {
1160
+ rprefix = rns;
1161
+ href = NULL;
1162
+ } else {
1163
+ rprefix = rb_str_new(StringValuePtr(rns), (int)((long)cp - (long)StringValuePtr(rns)));
1164
+ href = &cp[1]; /* skip the : */
1165
+ }
1166
+ } else if (rb_obj_is_kind_of(rns, cXMLNS) == Qtrue) {
1167
+ Data_Get_Struct(self, ruby_xml_ns, rxns);
1168
+ xmlSetNs(rxn->node, rxns->ns);
1169
+ return(rns);
1170
+ } else
1171
+ rb_raise(rb_eTypeError, "must pass a string or an XML::Ns object");
1172
+
1173
+ /* Fall through to next case because when argc == 1, we need to
1174
+ * manually setup the additional args unless the arg passed is of
1175
+ * cXMLNS type */
1176
+ case 2:
1177
+ /* Don't want this code run in the fall through case */
1178
+ if (argc == 2) {
1179
+ rprefix = argv[0];
1180
+ href = StringValuePtr(argv[1]);
1181
+ }
1182
+
1183
+ ns = xmlNewNs(rxn->node, (xmlChar*)href, (xmlChar*)StringValuePtr(rprefix));
1184
+ if (ns == NULL)
1185
+ rb_raise(eXMLNodeSetNamespace, "unable to set the namespace");
1186
+ else
1187
+ return(ruby_xml_ns_new2(cXMLNS, rxn->xd, ns));
1188
+ break;
1189
+
1190
+ default:
1191
+ rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
1192
+ }
1193
+
1194
+ /* can't get here */
1195
+ return(Qnil);
1196
+ }
1197
+
1198
+
1199
+ /*
1200
+ * call-seq:
1201
+ * node.namespace? => (true|false)
1202
+ *
1203
+ * Determine whether this node *is* (not has) a namespace
1204
+ * node.
1205
+ */
1206
+ VALUE
1207
+ ruby_xml_node_namespace_q(VALUE self) {
1208
+ ruby_xml_node *rxn;
1209
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1210
+ if (rxn->node->type == XML_NAMESPACE_DECL)
1211
+ return(Qtrue);
1212
+ else
1213
+ return(Qfalse);
1214
+ }
1215
+
1216
+
1217
+ VALUE
1218
+ ruby_xml_node_new(VALUE class, xmlNodePtr node) {
1219
+ ruby_xml_node *rxn;
1220
+
1221
+ rxn = ALLOC(ruby_xml_node);
1222
+ rxn->is_ptr = 0;
1223
+ rxn->node = node;
1224
+ rxn->xd = Qnil;
1225
+ return(Data_Wrap_Struct(class, ruby_xml_node_mark,
1226
+ ruby_xml_node_free, rxn));
1227
+ }
1228
+
1229
+
1230
+ VALUE
1231
+ ruby_xml_node_new2(VALUE class, VALUE xd, xmlNodePtr node) {
1232
+ ruby_xml_node *rxn;
1233
+
1234
+ rxn = ALLOC(ruby_xml_node);
1235
+ rxn->is_ptr = 1;
1236
+ rxn->node = node;
1237
+ if (NIL_P(xd))
1238
+ rxn->xd = Qnil;
1239
+ else
1240
+ rxn->xd = xd;
1241
+ return(Data_Wrap_Struct(class, ruby_xml_node_mark,
1242
+ ruby_xml_node_free, rxn));
1243
+ }
1244
+
1245
+
1246
+ /*
1247
+ * call-seq:
1248
+ * node.next => node
1249
+ *
1250
+ * Obtain the next sibling node, if any.
1251
+ */
1252
+ VALUE
1253
+ ruby_xml_node_next_get(VALUE self) {
1254
+ ruby_xml_node *rxn;
1255
+ xmlNodePtr node;
1256
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1257
+
1258
+ switch (rxn->node->type) {
1259
+ case XML_DOCUMENT_NODE:
1260
+ #ifdef LIBXML_DOCB_ENABLED
1261
+ case XML_DOCB_DOCUMENT_NODE:
1262
+ #endif
1263
+ case XML_HTML_DOCUMENT_NODE:
1264
+ node = NULL;
1265
+ break;
1266
+ case XML_ATTRIBUTE_NODE:
1267
+ {
1268
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1269
+ node = (xmlNodePtr) attr->next;
1270
+ break;
1271
+ }
1272
+ case XML_NAMESPACE_DECL:
1273
+ {
1274
+ xmlNsPtr ns = (xmlNsPtr) rxn->node;
1275
+ node = (xmlNodePtr) ns->next;
1276
+ break;
1277
+ }
1278
+ default:
1279
+ node = rxn->node->next;
1280
+ break;
1281
+ }
1282
+
1283
+ if (node == NULL)
1284
+ return(Qnil);
1285
+ else
1286
+ return(ruby_xml_node_new2(cXMLNode, rxn->xd, node));
1287
+ }
1288
+
1289
+
1290
+ /*
1291
+ * call-seq:
1292
+ * node.next? => (true|false)
1293
+ *
1294
+ * Determine whether this node has a next sibling.
1295
+ */
1296
+ VALUE
1297
+ ruby_xml_node_next_q(VALUE self) {
1298
+ ruby_xml_node *rxn;
1299
+ xmlNodePtr node;
1300
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1301
+
1302
+ switch (rxn->node->type) {
1303
+ case XML_DOCUMENT_NODE:
1304
+ #ifdef LIBXML_DOCB_ENABLED
1305
+ case XML_DOCB_DOCUMENT_NODE:
1306
+ #endif
1307
+ case XML_HTML_DOCUMENT_NODE:
1308
+ node = NULL;
1309
+ break;
1310
+ case XML_ATTRIBUTE_NODE:
1311
+ {
1312
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1313
+ node = (xmlNodePtr) attr->next;
1314
+ break;
1315
+ }
1316
+ case XML_NAMESPACE_DECL:
1317
+ {
1318
+ xmlNsPtr ns = (xmlNsPtr) rxn->node;
1319
+ node = (xmlNodePtr) ns->next;
1320
+ break;
1321
+ }
1322
+ default:
1323
+ node = rxn->node->next;
1324
+ break;
1325
+ }
1326
+
1327
+ if (node == NULL)
1328
+ return(Qfalse);
1329
+ else
1330
+ return(Qtrue);
1331
+ }
1332
+
1333
+
1334
+ /*
1335
+ * call-seq:
1336
+ * node.notation? => (true|false)
1337
+ *
1338
+ * Determine whether this is a notation node
1339
+ */
1340
+ VALUE
1341
+ ruby_xml_node_notation_q(VALUE self) {
1342
+ ruby_xml_node *rxn;
1343
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1344
+ if (rxn->node->type == XML_NOTATION_NODE)
1345
+ return(Qtrue);
1346
+ else
1347
+ return(Qfalse);
1348
+ }
1349
+
1350
+
1351
+ /*
1352
+ * call-seq:
1353
+ * node.ns? => (true|false)
1354
+ *
1355
+ * Determine whether this node is a namespace node.
1356
+ */
1357
+ VALUE
1358
+ ruby_xml_node_ns_q(VALUE self) {
1359
+ ruby_xml_node *rxn;
1360
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1361
+ if (rxn->node->ns == NULL)
1362
+ return(Qfalse);
1363
+ else
1364
+ return(Qtrue);
1365
+ }
1366
+
1367
+
1368
+ /*
1369
+ * call-seq:
1370
+ * node.ns_def => namespace
1371
+ *
1372
+ * Obtain this node's default namespace.
1373
+ */
1374
+ VALUE
1375
+ ruby_xml_node_ns_def_get(VALUE self) {
1376
+ ruby_xml_node *rxn;
1377
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1378
+ if (rxn->node->nsDef == NULL)
1379
+ return(Qnil);
1380
+ else
1381
+ return(ruby_xml_ns_new2(cXMLNS, rxn->xd, rxn->node->nsDef));
1382
+ }
1383
+
1384
+
1385
+ /*
1386
+ * call-seq:
1387
+ * node.ns_def? => (true|false)
1388
+ *
1389
+ * Obtain an array of +XML::NS+ objects representing
1390
+ * this node's xmlns attributes
1391
+ */
1392
+ VALUE
1393
+ ruby_xml_node_ns_def_q(VALUE self) {
1394
+ ruby_xml_node *rxn;
1395
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1396
+ if (rxn->node->nsDef == NULL)
1397
+ return(Qfalse);
1398
+ else
1399
+ return(Qtrue);
1400
+ }
1401
+
1402
+
1403
+ /*
1404
+ * call-seq:
1405
+ * node.parent => node
1406
+ *
1407
+ * Obtain this node's parent node, if any.
1408
+ */
1409
+ VALUE
1410
+ ruby_xml_node_parent_get(VALUE self) {
1411
+ ruby_xml_node *rxn;
1412
+ xmlNodePtr node;
1413
+
1414
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1415
+
1416
+ switch (rxn->node->type) {
1417
+ case XML_DOCUMENT_NODE:
1418
+ case XML_HTML_DOCUMENT_NODE:
1419
+ #ifdef LIBXML_DOCB_ENABLED
1420
+ case XML_DOCB_DOCUMENT_NODE:
1421
+ #endif
1422
+ node = NULL;
1423
+ break;
1424
+ case XML_ATTRIBUTE_NODE:
1425
+ {
1426
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1427
+ node = attr->parent;
1428
+ }
1429
+ case XML_ENTITY_DECL:
1430
+ case XML_NAMESPACE_DECL:
1431
+ case XML_XINCLUDE_START:
1432
+ case XML_XINCLUDE_END:
1433
+ node = NULL;
1434
+ break;
1435
+ default:
1436
+ node = rxn->node->parent;
1437
+ break;
1438
+ }
1439
+
1440
+ if (node == NULL)
1441
+ return(Qnil);
1442
+ else
1443
+ return(ruby_xml_node_new2(cXMLNode, rxn->xd, node));
1444
+ }
1445
+
1446
+
1447
+ /*
1448
+ * call-seq:
1449
+ * node.parent? => (true|false)
1450
+ *
1451
+ * Determine whether this node has a parent node.
1452
+ */
1453
+ VALUE
1454
+ ruby_xml_node_parent_q(VALUE self) {
1455
+ ruby_xml_node *rxn;
1456
+ xmlNodePtr node;
1457
+
1458
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1459
+
1460
+ switch (rxn->node->type) {
1461
+ case XML_DOCUMENT_NODE:
1462
+ case XML_HTML_DOCUMENT_NODE:
1463
+ #ifdef LIBXML_DOCB_ENABLED
1464
+ case XML_DOCB_DOCUMENT_NODE:
1465
+ #endif
1466
+ node = NULL;
1467
+ break;
1468
+ case XML_ATTRIBUTE_NODE:
1469
+ {
1470
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1471
+ node = attr->parent;
1472
+ }
1473
+ case XML_ENTITY_DECL:
1474
+ case XML_NAMESPACE_DECL:
1475
+ case XML_XINCLUDE_START:
1476
+ case XML_XINCLUDE_END:
1477
+ node = NULL;
1478
+ break;
1479
+ default:
1480
+ node = rxn->node->parent;
1481
+ break;
1482
+ }
1483
+
1484
+ if (node == NULL)
1485
+ return(Qfalse);
1486
+ else
1487
+ return(Qtrue);
1488
+ }
1489
+
1490
+
1491
+ /*
1492
+ * call-seq:
1493
+ * node.path => path
1494
+ *
1495
+ * Obtain this node's path.
1496
+ */
1497
+ VALUE
1498
+ ruby_xml_node_path(VALUE self) {
1499
+ ruby_xml_node *rxn;
1500
+ xmlChar *path;
1501
+
1502
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1503
+ path = xmlGetNodePath(rxn->node);
1504
+
1505
+ if (path == NULL)
1506
+ return(Qnil);
1507
+ else
1508
+ return(rb_str_new2((const char*)path));
1509
+ }
1510
+
1511
+
1512
+ /*
1513
+ * call-seq:
1514
+ * node.pi? => (true|false)
1515
+ *
1516
+ * Determine whether this is a processing instruction node.
1517
+ */
1518
+ VALUE
1519
+ ruby_xml_node_pi_q(VALUE self) {
1520
+ ruby_xml_node *rxn;
1521
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1522
+ if (rxn->node->type == XML_PI_NODE)
1523
+ return(Qtrue);
1524
+ else
1525
+ return(Qfalse);
1526
+ }
1527
+
1528
+
1529
+ /*
1530
+ * call-seq:
1531
+ * node.pointer => node_set
1532
+ *
1533
+ * Evaluates an XPointer expression relative to this node.
1534
+ */
1535
+ VALUE
1536
+ ruby_xml_node_pointer(VALUE self, VALUE xptr_str) {
1537
+ return(ruby_xml_xpointer_point2(self, xptr_str));
1538
+ }
1539
+
1540
+
1541
+ /*
1542
+ * call-seq:
1543
+ * node.prev => node
1544
+ *
1545
+ * Obtain the previous sibling, if any.
1546
+ */
1547
+ VALUE
1548
+ ruby_xml_node_prev_get(VALUE self) {
1549
+ ruby_xml_node *rxn;
1550
+ xmlNodePtr node;
1551
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1552
+
1553
+ switch (rxn->node->type) {
1554
+ case XML_DOCUMENT_NODE:
1555
+ #ifdef LIBXML_DOCB_ENABLED
1556
+ case XML_DOCB_DOCUMENT_NODE:
1557
+ #endif
1558
+ case XML_HTML_DOCUMENT_NODE:
1559
+ case XML_NAMESPACE_DECL:
1560
+ node = NULL;
1561
+ break;
1562
+ case XML_ATTRIBUTE_NODE:
1563
+ {
1564
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1565
+ node = (xmlNodePtr) attr->next;
1566
+ }
1567
+ break;
1568
+ default:
1569
+ node = rxn->node->next;
1570
+ break;
1571
+ }
1572
+
1573
+ if (node == NULL)
1574
+ return(Qnil);
1575
+ else
1576
+ return(ruby_xml_node_new2(cXMLNode, rxn->xd, node));
1577
+ }
1578
+
1579
+
1580
+ /*
1581
+ * call-seq:
1582
+ * node.prev? => (true|false)
1583
+ *
1584
+ * Determines whether this node has a previous sibling node.
1585
+ */
1586
+ VALUE
1587
+ ruby_xml_node_prev_q(VALUE self) {
1588
+ ruby_xml_node *rxn;
1589
+ xmlNodePtr node;
1590
+
1591
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1592
+
1593
+ switch (rxn->node->type) {
1594
+ case XML_DOCUMENT_NODE:
1595
+ #ifdef LIBXML_DOCB_ENABLED
1596
+ case XML_DOCB_DOCUMENT_NODE:
1597
+ #endif
1598
+ case XML_HTML_DOCUMENT_NODE:
1599
+ case XML_NAMESPACE_DECL:
1600
+ node = NULL;
1601
+ break;
1602
+ case XML_ATTRIBUTE_NODE:
1603
+ {
1604
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1605
+ node = (xmlNodePtr) attr->next;
1606
+ }
1607
+ break;
1608
+ default:
1609
+ node = rxn->node->next;
1610
+ break;
1611
+ }
1612
+
1613
+ if (node == NULL)
1614
+ return(Qfalse);
1615
+ else
1616
+ return(Qtrue);
1617
+ }
1618
+
1619
+
1620
+ /*
1621
+ * call-seq:
1622
+ * node.property("name") => "string"
1623
+ * node["name"] => "string"
1624
+ *
1625
+ * Obtain the named property.
1626
+ */
1627
+ VALUE
1628
+ ruby_xml_node_property_get(VALUE self, VALUE prop) {
1629
+ ruby_xml_node *rxn;
1630
+ xmlChar *p;
1631
+ VALUE r;
1632
+
1633
+ Check_Type(prop, T_STRING);
1634
+
1635
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1636
+ p = xmlGetProp(rxn->node, (xmlChar*)StringValuePtr(prop));
1637
+
1638
+ if (p == NULL)
1639
+ r = Qnil;
1640
+ else {
1641
+ r = rb_str_new2((const char*)p);
1642
+ xmlFree(p);
1643
+ }
1644
+
1645
+ return r;
1646
+ }
1647
+
1648
+
1649
+ /*
1650
+ * call-seq:
1651
+ * node["name"] = "string"
1652
+ *
1653
+ * Set the named property.
1654
+ */
1655
+ VALUE
1656
+ ruby_xml_node_property_set(VALUE self, VALUE key, VALUE val) {
1657
+ ruby_xml_node *node;
1658
+ ruby_xml_attr *rxa;
1659
+ xmlAttrPtr attr;
1660
+ VALUE rattr;
1661
+
1662
+ Data_Get_Struct(self, ruby_xml_node, node);
1663
+ Check_Type(key, T_STRING);
1664
+
1665
+ if( val == Qnil ) {
1666
+ attr = xmlSetProp(node->node, (xmlChar*)StringValuePtr(key), NULL);
1667
+ xmlRemoveProp( attr );
1668
+ return Qnil;
1669
+ } else {
1670
+ Check_Type(val, T_STRING);
1671
+ }
1672
+
1673
+ attr = xmlSetProp(node->node, (xmlChar*)StringValuePtr(key), (xmlChar*)StringValuePtr(val));
1674
+ if (attr == NULL) {
1675
+ attr = xmlNewProp(node->node, (xmlChar*)StringValuePtr(key), (xmlChar*)StringValuePtr(val));
1676
+ if (attr == NULL)
1677
+ return(Qnil);
1678
+ }
1679
+ rattr = ruby_xml_attr_new(cXMLAttr, node->xd, attr);
1680
+ Data_Get_Struct(rattr, ruby_xml_attr, rxa);
1681
+ rxa->is_ptr = 1;
1682
+ return(rattr);
1683
+ }
1684
+
1685
+
1686
+ /*
1687
+ * call-seq:
1688
+ * node.properties => attributes
1689
+ *
1690
+ * Returns the +XML::Attr+ for this node.
1691
+ */
1692
+ VALUE
1693
+ ruby_xml_node_properties_get(VALUE self) {
1694
+ ruby_xml_node *node;
1695
+ xmlAttrPtr attr;
1696
+
1697
+ Data_Get_Struct(self, ruby_xml_node, node);
1698
+
1699
+ if (node->node->type == XML_ELEMENT_NODE) {
1700
+ attr = node->node->properties;
1701
+ return(ruby_xml_attr_new2(cXMLAttr, node->xd, attr));
1702
+ } else {
1703
+ return(Qnil);
1704
+ }
1705
+ }
1706
+
1707
+
1708
+ /*
1709
+ * call-seq:
1710
+ * node.properties? => (true|false)
1711
+ *
1712
+ * Determine whether this node has properties
1713
+ * (attributes).
1714
+ */
1715
+ VALUE
1716
+ ruby_xml_node_properties_q(VALUE self) {
1717
+ ruby_xml_node *rxn;
1718
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1719
+ if (rxn->node->type == XML_ELEMENT_NODE && rxn->node->properties != NULL)
1720
+ return(Qtrue);
1721
+ else
1722
+ return(Qfalse);
1723
+ }
1724
+
1725
+
1726
+ /*
1727
+ * call-seq:
1728
+ * node.remove! => nil
1729
+ *
1730
+ * Removes this node from it's parent.
1731
+ */
1732
+ VALUE
1733
+ ruby_xml_node_remove_ex(VALUE self) {
1734
+ ruby_xml_node *rxn;
1735
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1736
+ xmlUnlinkNode(rxn->node);
1737
+ return(Qnil);
1738
+ }
1739
+
1740
+
1741
+ /*
1742
+ * call-seq:
1743
+ * node.search_href => namespace
1744
+ *
1745
+ * Search for a namespace by href.
1746
+ */
1747
+ VALUE
1748
+ ruby_xml_node_search_href(VALUE self, VALUE href) {
1749
+ ruby_xml_document *doc;
1750
+ ruby_xml_node *node;
1751
+
1752
+ Check_Type(href, T_STRING);
1753
+ Data_Get_Struct(self, ruby_xml_node, node);
1754
+ Data_Get_Struct(node->xd, ruby_xml_document, doc);
1755
+ return(ruby_xml_ns_new2(cXMLNS, node->xd,
1756
+ xmlSearchNsByHref(doc->doc, node->node,
1757
+ (xmlChar*)StringValuePtr(href))));
1758
+ }
1759
+
1760
+
1761
+ /*
1762
+ * call-seq:
1763
+ * node.search_ns => namespace
1764
+ *
1765
+ * Search for a namespace by namespace.
1766
+ */
1767
+ VALUE
1768
+ ruby_xml_node_search_ns(VALUE self, VALUE ns) {
1769
+ ruby_xml_document *doc;
1770
+ ruby_xml_node *node;
1771
+
1772
+ Check_Type(ns, T_STRING);
1773
+ Data_Get_Struct(self, ruby_xml_node, node);
1774
+ Data_Get_Struct(node->xd, ruby_xml_document, doc);
1775
+ return(ruby_xml_ns_new2(cXMLNS, node->xd,
1776
+ xmlSearchNs(doc->doc, node->node,
1777
+ (xmlChar*)StringValuePtr(ns))));
1778
+ }
1779
+
1780
+
1781
+ VALUE
1782
+ ruby_xml_node_set_ptr(VALUE node, int is_ptr) {
1783
+ ruby_xml_node *rxn;
1784
+ Data_Get_Struct(node, ruby_xml_node, rxn);
1785
+ rxn->is_ptr = is_ptr;
1786
+ return(Qtrue);
1787
+ }
1788
+
1789
+
1790
+ /*
1791
+ * call-seq:
1792
+ * node.sibling(node) => node
1793
+ *
1794
+ * Add the specified node as a sibling of this node.
1795
+ */
1796
+ VALUE
1797
+ ruby_xml_node_sibling_set(VALUE self, VALUE rnode) {
1798
+ ruby_xml_node *cnode, *pnode;
1799
+ xmlNodePtr ret;
1800
+
1801
+ if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
1802
+ rb_raise(rb_eTypeError, "Must pass an XML::Node object");
1803
+
1804
+ Data_Get_Struct(self, ruby_xml_node, pnode);
1805
+ Data_Get_Struct(rnode, ruby_xml_node, cnode);
1806
+
1807
+ ret = xmlAddSibling(pnode->node, cnode->node);
1808
+ if (ret == NULL)
1809
+ rb_raise(eXMLNodeFailedModify, "unable to add a sibling to the document");
1810
+
1811
+ cnode->is_ptr = 1;
1812
+ return(ruby_xml_node_new2(cXMLNode, pnode->xd, ret));
1813
+ }
1814
+
1815
+
1816
+ /*
1817
+ * call-seq:
1818
+ * node.space_preserve => (true|false)
1819
+ *
1820
+ * Determine whether this node preserves whitespace.
1821
+ */
1822
+ VALUE
1823
+ ruby_xml_node_space_preserve_get(VALUE self) {
1824
+ ruby_xml_node *rxn;
1825
+
1826
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1827
+ return(INT2NUM(xmlNodeGetSpacePreserve(rxn->node)));
1828
+ }
1829
+
1830
+
1831
+ /*
1832
+ * call-seq:
1833
+ * node.space_preserve = true|false
1834
+ *
1835
+ * Control whether this node preserves whitespace.
1836
+ */
1837
+ VALUE
1838
+ ruby_xml_node_space_preserve_set(VALUE self, VALUE bool) {
1839
+ ruby_xml_node *rxn;
1840
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1841
+
1842
+ if (TYPE(bool) == T_FALSE)
1843
+ xmlNodeSetSpacePreserve(rxn->node, 1);
1844
+ else
1845
+ xmlNodeSetSpacePreserve(rxn->node, 0);
1846
+
1847
+ return(Qnil);
1848
+ }
1849
+
1850
+
1851
+ /*
1852
+ * call-seq:
1853
+ * node.text? => (true|false)
1854
+ *
1855
+ * Determine whether this node has text.
1856
+ */
1857
+ VALUE
1858
+ ruby_xml_node_text_q(VALUE self) {
1859
+ ruby_xml_node *rxn;
1860
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1861
+ if (rxn->node == NULL)
1862
+ return(Qnil);
1863
+
1864
+ return((xmlNodeIsText(rxn->node) == 1) ? Qtrue : Qfalse);
1865
+ }
1866
+
1867
+
1868
+ /*
1869
+ * call-seq:
1870
+ * node.to_s => "string"
1871
+ *
1872
+ * Coerce this node to a string representation of
1873
+ * it's XML.
1874
+ */
1875
+ VALUE
1876
+ ruby_xml_node_to_s(VALUE self) {
1877
+ ruby_xml_node *rxn;
1878
+ xmlBufferPtr buf;
1879
+ VALUE result;
1880
+
1881
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1882
+ buf = xmlBufferCreate();
1883
+ xmlNodeDump(buf, rxn->node->doc, rxn->node, 0, 1);
1884
+ result = rb_str_new2((const char*)buf->content);
1885
+
1886
+ xmlBufferFree(buf);
1887
+ return result;
1888
+ }
1889
+
1890
+
1891
+ /*
1892
+ * call-seq:
1893
+ * node.type => num
1894
+ *
1895
+ * Obtain this node's type identifier.
1896
+ */
1897
+ VALUE
1898
+ ruby_xml_node_type(VALUE self) {
1899
+ ruby_xml_node *rxn;
1900
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1901
+ return(INT2NUM(rxn->node->type));
1902
+ }
1903
+
1904
+
1905
+ /*
1906
+ * call-seq:
1907
+ * node.type_name => num
1908
+ *
1909
+ * Obtain this node's type name.
1910
+ */
1911
+ VALUE
1912
+ ruby_xml_node_type_name(VALUE self) {
1913
+ ruby_xml_node *rxn;
1914
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1915
+
1916
+ switch(rxn->node->type) {
1917
+ case XML_ELEMENT_NODE:
1918
+ return(rb_str_new2("element"));
1919
+ case XML_ATTRIBUTE_NODE:
1920
+ return(rb_str_new2("attribute"));
1921
+ case XML_TEXT_NODE:
1922
+ return(rb_str_new2("text"));
1923
+ case XML_CDATA_SECTION_NODE:
1924
+ return(rb_str_new2("cdata"));
1925
+ case XML_ENTITY_REF_NODE:
1926
+ return(rb_str_new2("entity_ref"));
1927
+ case XML_ENTITY_NODE:
1928
+ return(rb_str_new2("entity"));
1929
+ case XML_PI_NODE:
1930
+ return(rb_str_new2("pi"));
1931
+ case XML_COMMENT_NODE:
1932
+ return(rb_str_new2("comment"));
1933
+ case XML_DOCUMENT_NODE:
1934
+ return(rb_str_new2("document_xml"));
1935
+ case XML_DOCUMENT_TYPE_NODE:
1936
+ return(rb_str_new2("doctype"));
1937
+ case XML_DOCUMENT_FRAG_NODE:
1938
+ return(rb_str_new2("fragment"));
1939
+ case XML_NOTATION_NODE:
1940
+ return(rb_str_new2("notation"));
1941
+ case XML_HTML_DOCUMENT_NODE:
1942
+ return(rb_str_new2("document_html"));
1943
+ case XML_DTD_NODE:
1944
+ return(rb_str_new2("dtd"));
1945
+ case XML_ELEMENT_DECL:
1946
+ return(rb_str_new2("elem_decl"));
1947
+ case XML_ATTRIBUTE_DECL:
1948
+ return(rb_str_new2("attribute_decl"));
1949
+ case XML_ENTITY_DECL:
1950
+ return(rb_str_new2("entity_decl"));
1951
+ case XML_NAMESPACE_DECL:
1952
+ return(rb_str_new2("namespace"));
1953
+ case XML_XINCLUDE_START:
1954
+ return(rb_str_new2("xinclude_start"));
1955
+ case XML_XINCLUDE_END:
1956
+ return(rb_str_new2("xinclude_end"));
1957
+ #ifdef LIBXML_DOCB_ENABLED
1958
+ case XML_DOCB_DOCUMENT_NODE:
1959
+ return(rb_str_new2("document_docbook"));
1960
+ #endif
1961
+ default:
1962
+ rb_raise(eXMLNodeUnknownType, "Unknown node type: %n", rxn->node->type);
1963
+ return(Qfalse);
1964
+ }
1965
+ }
1966
+
1967
+
1968
+ /*
1969
+ * call-seq:
1970
+ * node.xinclude_end? => num
1971
+ *
1972
+ * Determine whether this node is an xinclude end node.
1973
+ */
1974
+ VALUE
1975
+ ruby_xml_node_xinclude_end_q(VALUE self) {
1976
+ ruby_xml_node *rxn;
1977
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1978
+ if (rxn->node->type == XML_XINCLUDE_END)
1979
+ return(Qtrue);
1980
+ else
1981
+ return(Qfalse);
1982
+ }
1983
+
1984
+
1985
+ /*
1986
+ * call-seq:
1987
+ * node.xinclude_start? => num
1988
+ *
1989
+ * Determine whether this node is an xinclude start node.
1990
+ */
1991
+ VALUE
1992
+ ruby_xml_node_xinclude_start_q(VALUE self) {
1993
+ ruby_xml_node *rxn;
1994
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1995
+ if (rxn->node->type == XML_XINCLUDE_START)
1996
+ return(Qtrue);
1997
+ else
1998
+ return(Qfalse);
1999
+ }
2000
+
2001
+
2002
+ // TODO my gut tells me this is where our sigseg etc. problems start...
2003
+
2004
+ /*
2005
+ * call-seq:
2006
+ * node.copy => node
2007
+ *
2008
+ * Create a copy of this node.
2009
+ */
2010
+ VALUE
2011
+ ruby_xml_node_copy(VALUE self, VALUE deep) { /* MUFF */
2012
+ ruby_xml_node *rxn, *n_rxn;
2013
+ VALUE n_node;
2014
+
2015
+ Data_Get_Struct(self, ruby_xml_node, rxn);
2016
+
2017
+ n_node = ruby_xml_node_new(cXMLNode, NULL); // class??
2018
+ Data_Get_Struct(n_node, ruby_xml_node, n_rxn);
2019
+
2020
+ n_rxn->node = xmlCopyNode( rxn->node, ((deep==Qnil)||(deep==Qfalse))?0:1 );
2021
+ if (rxn->node == NULL)
2022
+ return(Qnil);
2023
+
2024
+ return n_node;
2025
+ }
2026
+
2027
+
2028
+ // Rdoc needs to know
2029
+ #ifdef RDOC_NEVER_DEFINED
2030
+ mXML = rb_define_module("XML");
2031
+ #endif
2032
+
2033
+ void
2034
+ ruby_init_xml_node(void) {
2035
+ cXMLNode = rb_define_class_under(mXML, "Node", rb_cObject);
2036
+ eXMLNodeSetNamespace = rb_define_class_under(cXMLNode, "SetNamespace", rb_eException);
2037
+ eXMLNodeFailedModify = rb_define_class_under(cXMLNode, "FailedModify", rb_eException);
2038
+ eXMLNodeUnknownType = rb_define_class_under(cXMLNode, "UnknownType", rb_eException);
2039
+
2040
+ rb_define_const(cXMLNode, "SPACE_DEFAULT", INT2NUM(0));
2041
+ rb_define_const(cXMLNode, "SPACE_PRESERVE", INT2NUM(1));
2042
+ rb_define_const(cXMLNode, "SPACE_NOT_INHERIT", INT2NUM(-1));
2043
+ rb_define_const(cXMLNode, "XLINK_ACTUATE_AUTO", INT2NUM(1));
2044
+ rb_define_const(cXMLNode, "XLINK_ACTUATE_NONE", INT2NUM(0));
2045
+ rb_define_const(cXMLNode, "XLINK_ACTUATE_ONREQUEST", INT2NUM(2));
2046
+ rb_define_const(cXMLNode, "XLINK_SHOW_EMBED", INT2NUM(2));
2047
+ rb_define_const(cXMLNode, "XLINK_SHOW_NEW", INT2NUM(1));
2048
+ rb_define_const(cXMLNode, "XLINK_SHOW_NONE", INT2NUM(0));
2049
+ rb_define_const(cXMLNode, "XLINK_SHOW_REPLACE", INT2NUM(3));
2050
+ rb_define_const(cXMLNode, "XLINK_TYPE_EXTENDED", INT2NUM(2));
2051
+ rb_define_const(cXMLNode, "XLINK_TYPE_EXTENDED_SET", INT2NUM(3));
2052
+ rb_define_const(cXMLNode, "XLINK_TYPE_NONE", INT2NUM(0));
2053
+ rb_define_const(cXMLNode, "XLINK_TYPE_SIMPLE", INT2NUM(1));
2054
+
2055
+ rb_define_singleton_method(cXMLNode, "new", ruby_xml_node_initialize, -1);
2056
+
2057
+ rb_define_method(cXMLNode, "<<", ruby_xml_node_content_add, 1);
2058
+ rb_define_method(cXMLNode, "[]", ruby_xml_node_property_get, 1);
2059
+ rb_define_method(cXMLNode, "[]=", ruby_xml_node_property_set, 2);
2060
+ rb_define_method(cXMLNode, "attribute?", ruby_xml_node_attribute_q, 0);
2061
+ rb_define_method(cXMLNode, "attribute_decl?", ruby_xml_node_attribute_decl_q, 0);
2062
+ rb_define_method(cXMLNode, "base", ruby_xml_node_base_get, 0);
2063
+ rb_define_method(cXMLNode, "base=", ruby_xml_node_base_set, 1);
2064
+ rb_define_method(cXMLNode, "blank?", ruby_xml_node_empty_q, 0);
2065
+ rb_define_method(cXMLNode, "cdata?", ruby_xml_node_cdata_q, 0);
2066
+ rb_define_method(cXMLNode, "comment?", ruby_xml_node_comment_q, 0);
2067
+ rb_define_method(cXMLNode, "copy", ruby_xml_node_copy, 1);
2068
+ rb_define_method(cXMLNode, "child", ruby_xml_node_child_get, 0);
2069
+ rb_define_method(cXMLNode, "child?", ruby_xml_node_child_q, 0);
2070
+ rb_define_method(cXMLNode, "child=", ruby_xml_node_child_set, 1);
2071
+ rb_define_method(cXMLNode, "children", ruby_xml_node_child_get, 0);
2072
+ rb_define_method(cXMLNode, "children?", ruby_xml_node_child_q, 0);
2073
+ rb_define_method(cXMLNode, "content", ruby_xml_node_content_get, 0);
2074
+ rb_define_method(cXMLNode, "content=", ruby_xml_node_content_set, 1);
2075
+ rb_define_method(cXMLNode, "content_stripped", ruby_xml_node_content_stripped_get, 0);
2076
+ rb_define_method(cXMLNode, "doc", ruby_xml_node_doc, 0);
2077
+ rb_define_method(cXMLNode, "docbook_doc?", ruby_xml_node_docbook_doc_q, 0);
2078
+ rb_define_method(cXMLNode, "doctype?", ruby_xml_node_doctype_q, 0);
2079
+ rb_define_method(cXMLNode, "document?", ruby_xml_node_document_q, 0);
2080
+ rb_define_method(cXMLNode, "dtd?", ruby_xml_node_dtd_q, 0);
2081
+ rb_define_method(cXMLNode, "dump", ruby_xml_node_dump, 0);
2082
+ rb_define_method(cXMLNode, "debug_dump", ruby_xml_node_debug_dump, 0);
2083
+ rb_define_method(cXMLNode, "element?", ruby_xml_node_element_q, 0);
2084
+ rb_define_method(cXMLNode, "element_decl?", ruby_xml_node_element_decl_q, 0);
2085
+ rb_define_method(cXMLNode, "empty?", ruby_xml_node_empty_q, 0);
2086
+ rb_define_method(cXMLNode, "entity?", ruby_xml_node_entity_q, 0);
2087
+ rb_define_method(cXMLNode, "entity_ref?", ruby_xml_node_entity_ref_q, 0);
2088
+ rb_define_method(cXMLNode, "eql?", ruby_xml_node_eql_q, 1);
2089
+ rb_define_method(cXMLNode, "find", ruby_xml_node_find, -1);
2090
+ rb_define_method(cXMLNode, "find_first", ruby_xml_node_find_first, -1);
2091
+ rb_define_method(cXMLNode, "fragment?", ruby_xml_node_fragment_q, 0);
2092
+ rb_define_method(cXMLNode, "hash", ruby_xml_node_hash, 0);
2093
+ rb_define_method(cXMLNode, "html_doc?", ruby_xml_node_html_doc_q, 0);
2094
+ rb_define_method(cXMLNode, "lang", ruby_xml_node_lang_get, 0);
2095
+ rb_define_method(cXMLNode, "lang=", ruby_xml_node_lang_set, 1);
2096
+ rb_define_method(cXMLNode, "last", ruby_xml_node_last_get, 0);
2097
+ rb_define_method(cXMLNode, "last?", ruby_xml_node_last_q, 0);
2098
+ rb_define_method(cXMLNode, "line_num", ruby_xml_node_line_num, 0);
2099
+ rb_define_method(cXMLNode, "name", ruby_xml_node_name_get, 0);
2100
+ rb_define_method(cXMLNode, "name=", ruby_xml_node_name_set, 1);
2101
+ rb_define_method(cXMLNode, "namespace", ruby_xml_node_namespace_get, 0);
2102
+ rb_define_method(cXMLNode, "namespace_node", ruby_xml_node_namespace_get_node, 0);
2103
+ rb_define_method(cXMLNode, "namespace?", ruby_xml_node_namespace_q, 0);
2104
+ rb_define_method(cXMLNode, "namespace=", ruby_xml_node_namespace_set, -1);
2105
+ rb_define_method(cXMLNode, "next", ruby_xml_node_next_get, 0);
2106
+ rb_define_method(cXMLNode, "next?", ruby_xml_node_next_q, 0);
2107
+ rb_define_method(cXMLNode, "node_type", ruby_xml_node_type, 0);
2108
+ rb_define_method(cXMLNode, "node_type_name", ruby_xml_node_type_name, 0);
2109
+ rb_define_method(cXMLNode, "notation?", ruby_xml_node_notation_q, 0);
2110
+ rb_define_method(cXMLNode, "ns", ruby_xml_node_namespace_get, 0);
2111
+ rb_define_method(cXMLNode, "ns?", ruby_xml_node_ns_q, 0);
2112
+ rb_define_method(cXMLNode, "ns_def", ruby_xml_node_ns_def_get, 0);
2113
+ rb_define_method(cXMLNode, "ns_def?", ruby_xml_node_ns_def_q, 0);
2114
+ rb_define_method(cXMLNode, "parent", ruby_xml_node_parent_get, 0);
2115
+ rb_define_method(cXMLNode, "parent?", ruby_xml_node_parent_q, 0);
2116
+ rb_define_method(cXMLNode, "path", ruby_xml_node_path, 0);
2117
+ rb_define_method(cXMLNode, "pi?", ruby_xml_node_pi_q, 0);
2118
+ rb_define_method(cXMLNode, "pointer", ruby_xml_node_pointer, 1);
2119
+ rb_define_method(cXMLNode, "prev", ruby_xml_node_prev_get, 0);
2120
+ rb_define_method(cXMLNode, "prev?", ruby_xml_node_prev_q, 0);
2121
+ rb_define_method(cXMLNode, "property", ruby_xml_node_property_get, 1);
2122
+ rb_define_method(cXMLNode, "properties", ruby_xml_node_properties_get, 0);
2123
+ rb_define_method(cXMLNode, "properties?", ruby_xml_node_properties_q, 0);
2124
+ rb_define_method(cXMLNode, "remove!", ruby_xml_node_remove_ex, 0);
2125
+ rb_define_method(cXMLNode, "search_ns", ruby_xml_node_search_ns, 1);
2126
+ rb_define_method(cXMLNode, "search_href", ruby_xml_node_search_href, 1);
2127
+ rb_define_method(cXMLNode, "sibling=", ruby_xml_node_sibling_set, 1);
2128
+ rb_define_method(cXMLNode, "space_preserve", ruby_xml_node_space_preserve_get, 0);
2129
+ rb_define_method(cXMLNode, "space_preserve=", ruby_xml_node_space_preserve_set, 1);
2130
+ rb_define_method(cXMLNode, "text?", ruby_xml_node_text_q, 0);
2131
+ rb_define_method(cXMLNode, "to_s", ruby_xml_node_to_s, 0);
2132
+ rb_define_method(cXMLNode, "xinclude_end?", ruby_xml_node_xinclude_end_q, 0);
2133
+ rb_define_method(cXMLNode, "xinclude_start?", ruby_xml_node_xinclude_start_q, 0);
2134
+ rb_define_method(cXMLNode, "xlink?", ruby_xml_node_xlink_q, 0);
2135
+ rb_define_method(cXMLNode, "xlink_type", ruby_xml_node_xlink_type, 0);
2136
+ rb_define_method(cXMLNode, "xlink_type_name", ruby_xml_node_xlink_type_name, 0);
2137
+
2138
+ rb_define_alias(cXMLNode, "==", "eql?");
2139
+ }