mkrf 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }