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 @@
1
+ # Logfile created on Mon Jun 26 15:44:42 PDT 2006 by logger.rb/1.5.2.4
@@ -0,0 +1,407 @@
1
+ /*
2
+ * node.c
3
+ *
4
+ * $Author: why $
5
+ * $Date: 2005/04/13 06:27:54 $
6
+ *
7
+ * Copyright (C) 2003 why the lucky stiff
8
+ */
9
+
10
+ #include "syck.h"
11
+
12
+ /*
13
+ * Node allocation functions
14
+ */
15
+ SyckNode *
16
+ syck_alloc_node( enum syck_kind_tag type )
17
+ {
18
+ SyckNode *s;
19
+
20
+ s = S_ALLOC( SyckNode );
21
+ s->kind = type;
22
+ s->id = 0;
23
+ s->type_id = NULL;
24
+ s->anchor = NULL;
25
+ s->shortcut = NULL;
26
+
27
+ return s;
28
+ }
29
+
30
+ void
31
+ syck_free_node( SyckNode *n )
32
+ {
33
+ syck_free_members( n );
34
+ if ( n->type_id != NULL )
35
+ {
36
+ S_FREE( n->type_id );
37
+ n->type_id = NULL;
38
+ }
39
+ if ( n->anchor != NULL )
40
+ {
41
+ S_FREE( n->anchor );
42
+ n->anchor = NULL;
43
+ }
44
+ S_FREE( n );
45
+ }
46
+
47
+ SyckNode *
48
+ syck_alloc_map()
49
+ {
50
+ SyckNode *n;
51
+ struct SyckMap *m;
52
+
53
+ m = S_ALLOC( struct SyckMap );
54
+ m->style = map_none;
55
+ m->idx = 0;
56
+ m->capa = ALLOC_CT;
57
+ m->keys = S_ALLOC_N( SYMID, m->capa );
58
+ m->values = S_ALLOC_N( SYMID, m->capa );
59
+
60
+ n = syck_alloc_node( syck_map_kind );
61
+ n->data.pairs = m;
62
+
63
+ return n;
64
+ }
65
+
66
+ SyckNode *
67
+ syck_alloc_seq()
68
+ {
69
+ SyckNode *n;
70
+ struct SyckSeq *s;
71
+
72
+ s = S_ALLOC( struct SyckSeq );
73
+ s->style = seq_none;
74
+ s->idx = 0;
75
+ s->capa = ALLOC_CT;
76
+ s->items = S_ALLOC_N( SYMID, s->capa );
77
+
78
+ n = syck_alloc_node( syck_seq_kind );
79
+ n->data.list = s;
80
+
81
+ return n;
82
+ }
83
+
84
+ SyckNode *
85
+ syck_alloc_str()
86
+ {
87
+ SyckNode *n;
88
+ struct SyckStr *s;
89
+
90
+ s = S_ALLOC( struct SyckStr );
91
+ s->len = 0;
92
+ s->ptr = NULL;
93
+ s->style = scalar_none;
94
+
95
+ n = syck_alloc_node( syck_str_kind );
96
+ n->data.str = s;
97
+
98
+ return n;
99
+ }
100
+
101
+ SyckNode *
102
+ syck_new_str( char *str, enum scalar_style style )
103
+ {
104
+ return syck_new_str2( str, strlen( str ), style );
105
+ }
106
+
107
+ SyckNode *
108
+ syck_new_str2( char *str, long len, enum scalar_style style )
109
+ {
110
+ SyckNode *n;
111
+
112
+ n = syck_alloc_str();
113
+ n->data.str->ptr = S_ALLOC_N( char, len + 1 );
114
+ n->data.str->len = len;
115
+ n->data.str->style = style;
116
+ memcpy( n->data.str->ptr, str, len );
117
+ n->data.str->ptr[len] = '\0';
118
+
119
+ return n;
120
+ }
121
+
122
+ void
123
+ syck_replace_str( SyckNode *n, char *str, enum scalar_style style )
124
+ {
125
+ return syck_replace_str2( n, str, strlen( str ), style );
126
+ }
127
+
128
+ void
129
+ syck_replace_str2( SyckNode *n, char *str, long len, enum scalar_style style )
130
+ {
131
+ if ( n->data.str != NULL )
132
+ {
133
+ S_FREE( n->data.str->ptr );
134
+ n->data.str->ptr = NULL;
135
+ n->data.str->len = 0;
136
+ }
137
+ n->data.str->ptr = S_ALLOC_N( char, len + 1 );
138
+ n->data.str->len = len;
139
+ n->data.str->style = style;
140
+ memcpy( n->data.str->ptr, str, len );
141
+ n->data.str->ptr[len] = '\0';
142
+ }
143
+
144
+ void
145
+ syck_str_blow_away_commas( SyckNode *n )
146
+ {
147
+ char *go, *end;
148
+
149
+ go = n->data.str->ptr;
150
+ end = go + n->data.str->len;
151
+ while ( *(++go) != '\0' )
152
+ {
153
+ if ( *go == ',' )
154
+ {
155
+ n->data.str->len -= 1;
156
+ memmove( go, go + 1, end - go );
157
+ end -= 1;
158
+ }
159
+ }
160
+ }
161
+
162
+ char *
163
+ syck_str_read( SyckNode *n )
164
+ {
165
+ ASSERT( n != NULL );
166
+ return n->data.str->ptr;
167
+ }
168
+
169
+ SyckNode *
170
+ syck_new_map( SYMID key, SYMID value )
171
+ {
172
+ SyckNode *n;
173
+
174
+ n = syck_alloc_map();
175
+ syck_map_add( n, key, value );
176
+
177
+ return n;
178
+ }
179
+
180
+ void
181
+ syck_map_empty( SyckNode *n )
182
+ {
183
+ struct SyckMap *m;
184
+ ASSERT( n != NULL );
185
+ ASSERT( n->data.list != NULL );
186
+
187
+ S_FREE( n->data.pairs->keys );
188
+ S_FREE( n->data.pairs->values );
189
+ m = n->data.pairs;
190
+ m->idx = 0;
191
+ m->capa = ALLOC_CT;
192
+ m->keys = S_ALLOC_N( SYMID, m->capa );
193
+ m->values = S_ALLOC_N( SYMID, m->capa );
194
+ }
195
+
196
+ void
197
+ syck_map_add( SyckNode *map, SYMID key, SYMID value )
198
+ {
199
+ struct SyckMap *m;
200
+ long idx;
201
+
202
+ ASSERT( map != NULL );
203
+ ASSERT( map->data.pairs != NULL );
204
+
205
+ m = map->data.pairs;
206
+ idx = m->idx;
207
+ m->idx += 1;
208
+ if ( m->idx > m->capa )
209
+ {
210
+ m->capa += ALLOC_CT;
211
+ S_REALLOC_N( m->keys, SYMID, m->capa );
212
+ S_REALLOC_N( m->values, SYMID, m->capa );
213
+ }
214
+ m->keys[idx] = key;
215
+ m->values[idx] = value;
216
+ }
217
+
218
+ void
219
+ syck_map_update( SyckNode *map1, SyckNode *map2 )
220
+ {
221
+ struct SyckMap *m1, *m2;
222
+ long new_idx, new_capa;
223
+ ASSERT( map1 != NULL );
224
+ ASSERT( map2 != NULL );
225
+
226
+ m1 = map1->data.pairs;
227
+ m2 = map2->data.pairs;
228
+ if ( m2->idx < 1 ) return;
229
+
230
+ new_idx = m1->idx;
231
+ new_idx += m2->idx;
232
+ new_capa = m1->capa;
233
+ while ( new_idx > new_capa )
234
+ {
235
+ new_capa += ALLOC_CT;
236
+ }
237
+ if ( new_capa > m1->capa )
238
+ {
239
+ m1->capa = new_capa;
240
+ S_REALLOC_N( m1->keys, SYMID, m1->capa );
241
+ S_REALLOC_N( m1->values, SYMID, m1->capa );
242
+ }
243
+ for ( new_idx = 0; new_idx < m2->idx; m1->idx++, new_idx++ )
244
+ {
245
+ m1->keys[m1->idx] = m2->keys[new_idx];
246
+ m1->values[m1->idx] = m2->values[new_idx];
247
+ }
248
+ }
249
+
250
+ long
251
+ syck_map_count( SyckNode *map )
252
+ {
253
+ ASSERT( map != NULL );
254
+ ASSERT( map->data.pairs != NULL );
255
+ return map->data.pairs->idx;
256
+ }
257
+
258
+ void
259
+ syck_map_assign( SyckNode *map, enum map_part p, long idx, SYMID id )
260
+ {
261
+ struct SyckMap *m;
262
+
263
+ ASSERT( map != NULL );
264
+ m = map->data.pairs;
265
+ ASSERT( m != NULL );
266
+ if ( p == map_key )
267
+ {
268
+ m->keys[idx] = id;
269
+ }
270
+ else
271
+ {
272
+ m->values[idx] = id;
273
+ }
274
+ }
275
+
276
+ SYMID
277
+ syck_map_read( SyckNode *map, enum map_part p, long idx )
278
+ {
279
+ struct SyckMap *m;
280
+
281
+ ASSERT( map != NULL );
282
+ m = map->data.pairs;
283
+ ASSERT( m != NULL );
284
+ if ( p == map_key )
285
+ {
286
+ return m->keys[idx];
287
+ }
288
+ else
289
+ {
290
+ return m->values[idx];
291
+ }
292
+ }
293
+
294
+ SyckNode *
295
+ syck_new_seq( SYMID value )
296
+ {
297
+ SyckNode *n;
298
+
299
+ n = syck_alloc_seq();
300
+ syck_seq_add( n, value );
301
+
302
+ return n;
303
+ }
304
+
305
+ void
306
+ syck_seq_empty( SyckNode *n )
307
+ {
308
+ struct SyckSeq *s;
309
+ ASSERT( n != NULL );
310
+ ASSERT( n->data.list != NULL );
311
+
312
+ S_FREE( n->data.list->items );
313
+ s = n->data.list;
314
+ s->idx = 0;
315
+ s->capa = ALLOC_CT;
316
+ s->items = S_ALLOC_N( SYMID, s->capa );
317
+ }
318
+
319
+ void
320
+ syck_seq_add( SyckNode *arr, SYMID value )
321
+ {
322
+ struct SyckSeq *s;
323
+ long idx;
324
+
325
+ ASSERT( arr != NULL );
326
+ ASSERT( arr->data.list != NULL );
327
+
328
+ s = arr->data.list;
329
+ idx = s->idx;
330
+ s->idx += 1;
331
+ if ( s->idx > s->capa )
332
+ {
333
+ s->capa += ALLOC_CT;
334
+ S_REALLOC_N( s->items, SYMID, s->capa );
335
+ }
336
+ s->items[idx] = value;
337
+ }
338
+
339
+ long
340
+ syck_seq_count( SyckNode *seq )
341
+ {
342
+ ASSERT( seq != NULL );
343
+ ASSERT( seq->data.list != NULL );
344
+ return seq->data.list->idx;
345
+ }
346
+
347
+ void
348
+ syck_seq_assign( SyckNode *seq, long idx, SYMID id )
349
+ {
350
+ struct SyckSeq *s;
351
+
352
+ ASSERT( map != NULL );
353
+ s = seq->data.list;
354
+ ASSERT( m != NULL );
355
+ s->items[idx] = id;
356
+ }
357
+
358
+ SYMID
359
+ syck_seq_read( SyckNode *seq, long idx )
360
+ {
361
+ struct SyckSeq *s;
362
+
363
+ ASSERT( seq != NULL );
364
+ s = seq->data.list;
365
+ ASSERT( s != NULL );
366
+ return s->items[idx];
367
+ }
368
+
369
+ void
370
+ syck_free_members( SyckNode *n )
371
+ {
372
+ if ( n == NULL ) return;
373
+
374
+ switch ( n->kind )
375
+ {
376
+ case syck_str_kind:
377
+ if ( n->data.str != NULL )
378
+ {
379
+ S_FREE( n->data.str->ptr );
380
+ n->data.str->ptr = NULL;
381
+ n->data.str->len = 0;
382
+ S_FREE( n->data.str );
383
+ n->data.str = NULL;
384
+ }
385
+ break;
386
+
387
+ case syck_seq_kind:
388
+ if ( n->data.list != NULL )
389
+ {
390
+ S_FREE( n->data.list->items );
391
+ S_FREE( n->data.list );
392
+ n->data.list = NULL;
393
+ }
394
+ break;
395
+
396
+ case syck_map_kind:
397
+ if ( n->data.pairs != NULL )
398
+ {
399
+ S_FREE( n->data.pairs->keys );
400
+ S_FREE( n->data.pairs->values );
401
+ S_FREE( n->data.pairs );
402
+ n->data.pairs = NULL;
403
+ }
404
+ break;
405
+ }
406
+ }
407
+
@@ -0,0 +1,2385 @@
1
+ /* -*- indent-tabs-mode: nil -*- */
2
+ /*
3
+ * rubyext.c
4
+ *
5
+ * $Author: why $
6
+ * $Date: 2005/05/19 06:07:42 $
7
+ *
8
+ * Copyright (C) 2003-2005 why the lucky stiff
9
+ */
10
+
11
+ #include "ruby.h"
12
+ #include "syck.h"
13
+ #include <sys/types.h>
14
+ #include <time.h>
15
+
16
+ typedef struct RVALUE {
17
+ union {
18
+ #if 0
19
+ struct {
20
+ unsigned long flags; /* always 0 for freed obj */
21
+ struct RVALUE *next;
22
+ } free;
23
+ #endif
24
+ struct RBasic basic;
25
+ struct RObject object;
26
+ struct RClass klass;
27
+ /*struct RFloat flonum;*/
28
+ /*struct RString string;*/
29
+ struct RArray array;
30
+ /*struct RRegexp regexp;*/
31
+ struct RHash hash;
32
+ /*struct RData data;*/
33
+ struct RStruct rstruct;
34
+ /*struct RBignum bignum;*/
35
+ /*struct RFile file;*/
36
+ } as;
37
+ } RVALUE;
38
+
39
+ typedef struct {
40
+ long hash;
41
+ char *buffer;
42
+ long length;
43
+ long remaining;
44
+ int printed;
45
+ } bytestring_t;
46
+
47
+ #define RUBY_DOMAIN "ruby.yaml.org,2002"
48
+
49
+ #ifndef StringValue
50
+ #define StringValue(v) (v)
51
+ #endif
52
+ #ifndef rb_attr_get
53
+ #define rb_attr_get(o, i) rb_ivar_get(o, i)
54
+ #endif
55
+
56
+ /*
57
+ * symbols and constants
58
+ */
59
+ static ID s_new, s_utc, s_at, s_to_f, s_to_i, s_read, s_binmode, s_call, s_cmp, s_transfer, s_update, s_dup, s_haskey, s_match, s_keys, s_unpack, s_tr_bang, s_default_set, s_tag_read_class, s_tag_subclasses, s_resolver, s_push, s_emitter, s_level, s_detect_implicit, s_node_import, s_out, s_input, s_intern, s_transform, s_yaml_new, s_yaml_initialize, s_node_export, s_to_yaml, s_write, s_set_resolver;
60
+ static ID s_tags, s_domain, s_kind, s_name, s_options, s_type_id, s_type_id_set, s_style, s_style_set, s_value, s_value_set;
61
+ static VALUE sym_model, sym_generic, sym_input, sym_bytecode;
62
+ static VALUE sym_scalar, sym_seq, sym_map;
63
+ static VALUE sym_1quote, sym_2quote, sym_fold, sym_literal, sym_plain, sym_inline;
64
+ static VALUE cDate, cNode, cMap, cSeq, cScalar, cOut, cParser, cResolver, cPrivateType, cDomainType, cYObject, cBadAlias, cDefaultKey, cMergeKey, cEmitter;
65
+ static VALUE oDefaultResolver, oGenericResolver;
66
+
67
+ /*
68
+ * my private collection of numerical oddities.
69
+ */
70
+ static double S_zero() { return 0.0; }
71
+ static double S_one() { return 1.0; }
72
+ static double S_inf() { return S_one() / S_zero(); }
73
+ static double S_nan() { return S_zero() / S_zero(); }
74
+
75
+ static VALUE syck_node_transform( VALUE );
76
+
77
+ /*
78
+ * handler prototypes
79
+ */
80
+ SYMID rb_syck_load_handler _((SyckParser *, SyckNode *));
81
+ void rb_syck_err_handler _((SyckParser *, char *));
82
+ SyckNode * rb_syck_bad_anchor_handler _((SyckParser *, char *));
83
+ void rb_syck_output_handler _((SyckEmitter *, char *, long));
84
+ void rb_syck_emitter_handler _((SyckEmitter *, st_data_t));
85
+ int syck_parser_assign_io _((SyckParser *, VALUE));
86
+
87
+ struct parser_xtra {
88
+ VALUE data; /* Borrowed this idea from marshal.c to fix [ruby-core:8067] problem */
89
+ VALUE proc;
90
+ VALUE resolver;
91
+ int taint;
92
+ };
93
+
94
+ struct emitter_xtra {
95
+ VALUE oid;
96
+ VALUE data;
97
+ VALUE port;
98
+ };
99
+
100
+ /*
101
+ * Convert YAML to bytecode
102
+ */
103
+ VALUE
104
+ rb_syck_compile(self, port)
105
+ VALUE self, port;
106
+ {
107
+ SYMID oid;
108
+ int taint;
109
+ char *ret;
110
+ VALUE bc;
111
+ bytestring_t *sav;
112
+
113
+ SyckParser *parser = syck_new_parser();
114
+ taint = syck_parser_assign_io(parser, port);
115
+ syck_parser_handler( parser, syck_yaml2byte_handler );
116
+ syck_parser_error_handler( parser, NULL );
117
+ syck_parser_implicit_typing( parser, 0 );
118
+ syck_parser_taguri_expansion( parser, 0 );
119
+ oid = syck_parse( parser );
120
+ syck_lookup_sym( parser, oid, (char **)&sav );
121
+
122
+ ret = S_ALLOC_N( char, strlen( sav->buffer ) + 3 );
123
+ ret[0] = '\0';
124
+ strcat( ret, "D\n" );
125
+ strcat( ret, sav->buffer );
126
+
127
+ syck_free_parser( parser );
128
+
129
+ bc = rb_str_new2( ret );
130
+ if ( taint ) OBJ_TAINT( bc );
131
+ return bc;
132
+ }
133
+
134
+ /*
135
+ * read from io.
136
+ */
137
+ long
138
+ rb_syck_io_str_read( char *buf, SyckIoStr *str, long max_size, long skip )
139
+ {
140
+ long len = 0;
141
+
142
+ ASSERT( str != NULL );
143
+ max_size -= skip;
144
+
145
+ if ( max_size <= 0 ) max_size = 0;
146
+ else
147
+ {
148
+ /*
149
+ * call io#read.
150
+ */
151
+ VALUE src = (VALUE)str->ptr;
152
+ VALUE n = LONG2NUM(max_size);
153
+ VALUE str2 = rb_funcall2(src, s_read, 1, &n);
154
+ if (!NIL_P(str2))
155
+ {
156
+ StringValue(str2);
157
+ len = RSTRING(str2)->len;
158
+ memcpy( buf + skip, RSTRING(str2)->ptr, len );
159
+ }
160
+ }
161
+ len += skip;
162
+ buf[len] = '\0';
163
+ return len;
164
+ }
165
+
166
+ /*
167
+ * determine: are we reading from a string or io?
168
+ * (returns tainted? boolean)
169
+ */
170
+ int
171
+ syck_parser_assign_io(parser, port)
172
+ SyckParser *parser;
173
+ VALUE port;
174
+ {
175
+ int taint = Qtrue;
176
+ VALUE tmp;
177
+ if (!NIL_P(tmp = rb_check_string_type(port))) {
178
+ taint = OBJ_TAINTED(port); /* original taintedness */
179
+ port = tmp;
180
+ syck_parser_str( parser, RSTRING(port)->ptr, RSTRING(port)->len, NULL );
181
+ }
182
+ else if (rb_respond_to(port, s_read)) {
183
+ if (rb_respond_to(port, s_binmode)) {
184
+ rb_funcall2(port, s_binmode, 0, 0);
185
+ }
186
+ syck_parser_str( parser, (char *)port, 0, rb_syck_io_str_read );
187
+ }
188
+ else {
189
+ rb_raise(rb_eTypeError, "instance of IO needed");
190
+ }
191
+ return taint;
192
+ }
193
+
194
+ /*
195
+ * Get value in hash by key, forcing an empty hash if nil.
196
+ */
197
+ VALUE
198
+ syck_get_hash_aref(hsh, key)
199
+ VALUE hsh, key;
200
+ {
201
+ VALUE val = rb_hash_aref( hsh, key );
202
+ if ( NIL_P( val ) )
203
+ {
204
+ val = rb_hash_new();
205
+ rb_hash_aset(hsh, key, val);
206
+ }
207
+ return val;
208
+ }
209
+
210
+ /*
211
+ * creating timestamps
212
+ */
213
+ SYMID
214
+ rb_syck_mktime(str, len)
215
+ char *str;
216
+ long len;
217
+ {
218
+ VALUE time;
219
+ char *ptr = str;
220
+ VALUE year = INT2FIX(0);
221
+ VALUE mon = INT2FIX(0);
222
+ VALUE day = INT2FIX(0);
223
+ VALUE hour = INT2FIX(0);
224
+ VALUE min = INT2FIX(0);
225
+ VALUE sec = INT2FIX(0);
226
+ long usec;
227
+
228
+ /* Year*/
229
+ if ( ptr[0] != '\0' && len > 0 ) {
230
+ year = INT2FIX(strtol(ptr, NULL, 10));
231
+ }
232
+
233
+ /* Month*/
234
+ ptr += 4;
235
+ if ( ptr[0] != '\0' && len > ptr - str ) {
236
+ while ( !ISDIGIT( *ptr ) ) ptr++;
237
+ mon = INT2FIX(strtol(ptr, NULL, 10));
238
+ }
239
+
240
+ /* Day*/
241
+ ptr += 2;
242
+ if ( ptr[0] != '\0' && len > ptr - str ) {
243
+ while ( !ISDIGIT( *ptr ) ) ptr++;
244
+ day = INT2FIX(strtol(ptr, NULL, 10));
245
+ }
246
+
247
+ /* Hour*/
248
+ ptr += 2;
249
+ if ( ptr[0] != '\0' && len > ptr - str ) {
250
+ while ( !ISDIGIT( *ptr ) ) ptr++;
251
+ hour = INT2FIX(strtol(ptr, NULL, 10));
252
+ }
253
+
254
+ /* Minute */
255
+ ptr += 2;
256
+ if ( ptr[0] != '\0' && len > ptr - str ) {
257
+ while ( !ISDIGIT( *ptr ) ) ptr++;
258
+ min = INT2FIX(strtol(ptr, NULL, 10));
259
+ }
260
+
261
+ /* Second */
262
+ ptr += 2;
263
+ if ( ptr[0] != '\0' && len > ptr - str ) {
264
+ while ( !ISDIGIT( *ptr ) ) ptr++;
265
+ sec = INT2FIX(strtol(ptr, NULL, 10));
266
+ }
267
+
268
+ /* Millisecond */
269
+ ptr += 2;
270
+ if ( len > ptr - str && *ptr == '.' )
271
+ {
272
+ char *padded = syck_strndup( "000000", 6 );
273
+ char *end = ptr + 1;
274
+ while ( isdigit( *end ) ) end++;
275
+ MEMCPY(padded, ptr + 1, char, end - (ptr + 1));
276
+ usec = strtol(padded, NULL, 10);
277
+ S_FREE(padded);
278
+ }
279
+ else
280
+ {
281
+ usec = 0;
282
+ }
283
+
284
+ /* Time Zone*/
285
+ while ( len > ptr - str && *ptr != 'Z' && *ptr != '+' && *ptr != '-' && *ptr != '\0' ) ptr++;
286
+ if ( len > ptr - str && ( *ptr == '-' || *ptr == '+' ) )
287
+ {
288
+ time_t tz_offset = strtol(ptr, NULL, 10) * 3600;
289
+ time_t tmp;
290
+
291
+ while ( *ptr != ':' && *ptr != '\0' ) ptr++;
292
+ if ( *ptr == ':' )
293
+ {
294
+ ptr += 1;
295
+ if ( tz_offset < 0 )
296
+ {
297
+ tz_offset -= strtol(ptr, NULL, 10) * 60;
298
+ }
299
+ else
300
+ {
301
+ tz_offset += strtol(ptr, NULL, 10) * 60;
302
+ }
303
+ }
304
+
305
+ /* Make TZ time*/
306
+ time = rb_funcall(rb_cTime, s_utc, 6, year, mon, day, hour, min, sec);
307
+ tmp = NUM2LONG(rb_funcall(time, s_to_i, 0)) - tz_offset;
308
+ return rb_funcall(rb_cTime, s_at, 2, LONG2NUM(tmp), LONG2NUM(usec));
309
+ }
310
+ else
311
+ {
312
+ /* Make UTC time*/
313
+ return rb_funcall(rb_cTime, s_utc, 7, year, mon, day, hour, min, sec, LONG2NUM(usec));
314
+ }
315
+ }
316
+
317
+ /*
318
+ * handles merging of an array of hashes
319
+ * (see http://www.yaml.org/type/merge/)
320
+ */
321
+ VALUE
322
+ syck_merge_i( entry, hsh )
323
+ VALUE entry, hsh;
324
+ {
325
+ VALUE tmp;
326
+ if ( !NIL_P(tmp = rb_check_convert_type(entry, T_HASH, "Hash", "to_hash")) )
327
+ {
328
+ entry = tmp;
329
+ rb_funcall( hsh, s_update, 1, entry );
330
+ }
331
+ return Qnil;
332
+ }
333
+
334
+ /*
335
+ * default handler for ruby.yaml.org types
336
+ */
337
+ int
338
+ yaml_org_handler( n, ref )
339
+ SyckNode *n;
340
+ VALUE *ref;
341
+ {
342
+ char *type_id = n->type_id;
343
+ int transferred = 0;
344
+ long i = 0;
345
+ VALUE obj = Qnil;
346
+
347
+ if ( type_id != NULL && strncmp( type_id, "tag:yaml.org,2002:", 18 ) == 0 )
348
+ {
349
+ type_id += 18;
350
+ }
351
+
352
+ switch (n->kind)
353
+ {
354
+ case syck_str_kind:
355
+ transferred = 1;
356
+ if ( type_id == NULL )
357
+ {
358
+ obj = rb_str_new( n->data.str->ptr, n->data.str->len );
359
+ }
360
+ else if ( strcmp( type_id, "null" ) == 0 )
361
+ {
362
+ obj = Qnil;
363
+ }
364
+ else if ( strcmp( type_id, "binary" ) == 0 )
365
+ {
366
+ VALUE arr;
367
+ obj = rb_str_new( n->data.str->ptr, n->data.str->len );
368
+ rb_funcall( obj, s_tr_bang, 2, rb_str_new2( "\n\t " ), rb_str_new2( "" ) );
369
+ arr = rb_funcall( obj, s_unpack, 1, rb_str_new2( "m" ) );
370
+ obj = rb_ary_shift( arr );
371
+ }
372
+ else if ( strcmp( type_id, "bool#yes" ) == 0 )
373
+ {
374
+ obj = Qtrue;
375
+ }
376
+ else if ( strcmp( type_id, "bool#no" ) == 0 )
377
+ {
378
+ obj = Qfalse;
379
+ }
380
+ else if ( strcmp( type_id, "int#hex" ) == 0 )
381
+ {
382
+ syck_str_blow_away_commas( n );
383
+ obj = rb_cstr2inum( n->data.str->ptr, 16 );
384
+ }
385
+ else if ( strcmp( type_id, "int#oct" ) == 0 )
386
+ {
387
+ syck_str_blow_away_commas( n );
388
+ obj = rb_cstr2inum( n->data.str->ptr, 8 );
389
+ }
390
+ else if ( strcmp( type_id, "int#base60" ) == 0 )
391
+ {
392
+ char *ptr, *end;
393
+ long sixty = 1;
394
+ long total = 0;
395
+ syck_str_blow_away_commas( n );
396
+ ptr = n->data.str->ptr;
397
+ end = n->data.str->ptr + n->data.str->len;
398
+ while ( end > ptr )
399
+ {
400
+ long bnum = 0;
401
+ char *colon = end - 1;
402
+ while ( colon >= ptr && *colon != ':' )
403
+ {
404
+ colon--;
405
+ }
406
+ if ( *colon == ':' ) *colon = '\0';
407
+
408
+ bnum = strtol( colon + 1, NULL, 10 );
409
+ total += bnum * sixty;
410
+ sixty *= 60;
411
+ end = colon;
412
+ }
413
+ obj = INT2FIX(total);
414
+ }
415
+ else if ( strncmp( type_id, "int", 3 ) == 0 )
416
+ {
417
+ syck_str_blow_away_commas( n );
418
+ obj = rb_cstr2inum( n->data.str->ptr, 10 );
419
+ }
420
+ else if ( strcmp( type_id, "float#base60" ) == 0 )
421
+ {
422
+ char *ptr, *end;
423
+ long sixty = 1;
424
+ double total = 0.0;
425
+ syck_str_blow_away_commas( n );
426
+ ptr = n->data.str->ptr;
427
+ end = n->data.str->ptr + n->data.str->len;
428
+ while ( end > ptr )
429
+ {
430
+ double bnum = 0;
431
+ char *colon = end - 1;
432
+ while ( colon >= ptr && *colon != ':' )
433
+ {
434
+ colon--;
435
+ }
436
+ if ( *colon == ':' ) *colon = '\0';
437
+
438
+ bnum = strtod( colon + 1, NULL );
439
+ total += bnum * sixty;
440
+ sixty *= 60;
441
+ end = colon;
442
+ }
443
+ obj = rb_float_new( total );
444
+ }
445
+ else if ( strcmp( type_id, "float#nan" ) == 0 )
446
+ {
447
+ obj = rb_float_new( S_nan() );
448
+ }
449
+ else if ( strcmp( type_id, "float#inf" ) == 0 )
450
+ {
451
+ obj = rb_float_new( S_inf() );
452
+ }
453
+ else if ( strcmp( type_id, "float#neginf" ) == 0 )
454
+ {
455
+ obj = rb_float_new( -S_inf() );
456
+ }
457
+ else if ( strncmp( type_id, "float", 5 ) == 0 )
458
+ {
459
+ double f;
460
+ syck_str_blow_away_commas( n );
461
+ f = strtod( n->data.str->ptr, NULL );
462
+ obj = rb_float_new( f );
463
+ }
464
+ else if ( strcmp( type_id, "timestamp#iso8601" ) == 0 )
465
+ {
466
+ obj = rb_syck_mktime( n->data.str->ptr, n->data.str->len );
467
+ }
468
+ else if ( strcmp( type_id, "timestamp#spaced" ) == 0 )
469
+ {
470
+ obj = rb_syck_mktime( n->data.str->ptr, n->data.str->len );
471
+ }
472
+ else if ( strcmp( type_id, "timestamp#ymd" ) == 0 )
473
+ {
474
+ char *ptr = n->data.str->ptr;
475
+ VALUE year, mon, day;
476
+
477
+ /* Year*/
478
+ ptr[4] = '\0';
479
+ year = INT2FIX(strtol(ptr, NULL, 10));
480
+
481
+ /* Month*/
482
+ ptr += 4;
483
+ while ( !ISDIGIT( *ptr ) ) ptr++;
484
+ mon = INT2FIX(strtol(ptr, NULL, 10));
485
+
486
+ /* Day*/
487
+ ptr += 2;
488
+ while ( !ISDIGIT( *ptr ) ) ptr++;
489
+ day = INT2FIX(strtol(ptr, NULL, 10));
490
+
491
+ if ( !cDate ) {
492
+ /*
493
+ * Load Date module
494
+ */
495
+ rb_require( "date" );
496
+ cDate = rb_const_get( rb_cObject, rb_intern("Date") );
497
+ }
498
+
499
+ obj = rb_funcall( cDate, s_new, 3, year, mon, day );
500
+ }
501
+ else if ( strncmp( type_id, "timestamp", 9 ) == 0 )
502
+ {
503
+ obj = rb_syck_mktime( n->data.str->ptr, n->data.str->len );
504
+ }
505
+ else if ( strncmp( type_id, "merge", 5 ) == 0 )
506
+ {
507
+ obj = rb_funcall( cMergeKey, s_new, 0 );
508
+ }
509
+ else if ( strncmp( type_id, "default", 7 ) == 0 )
510
+ {
511
+ obj = rb_funcall( cDefaultKey, s_new, 0 );
512
+ }
513
+ else if ( n->data.str->style == scalar_plain &&
514
+ n->data.str->len > 1 &&
515
+ strncmp( n->data.str->ptr, ":", 1 ) == 0 )
516
+ {
517
+ obj = rb_funcall( oDefaultResolver, s_transfer, 2,
518
+ rb_str_new2( "tag:ruby.yaml.org,2002:sym" ),
519
+ rb_str_new( n->data.str->ptr + 1, n->data.str->len - 1 ) );
520
+ }
521
+ else if ( strcmp( type_id, "str" ) == 0 )
522
+ {
523
+ obj = rb_str_new( n->data.str->ptr, n->data.str->len );
524
+ }
525
+ else
526
+ {
527
+ transferred = 0;
528
+ obj = rb_str_new( n->data.str->ptr, n->data.str->len );
529
+ }
530
+ break;
531
+
532
+ case syck_seq_kind:
533
+ if ( type_id == NULL || strcmp( type_id, "seq" ) == 0 )
534
+ {
535
+ transferred = 1;
536
+ }
537
+ obj = rb_ary_new2( n->data.list->idx );
538
+ for ( i = 0; i < n->data.list->idx; i++ )
539
+ {
540
+ rb_ary_store( obj, i, syck_seq_read( n, i ) );
541
+ }
542
+ break;
543
+
544
+ case syck_map_kind:
545
+ if ( type_id == NULL || strcmp( type_id, "map" ) == 0 )
546
+ {
547
+ transferred = 1;
548
+ }
549
+ obj = rb_hash_new();
550
+ for ( i = 0; i < n->data.pairs->idx; i++ )
551
+ {
552
+ VALUE k = syck_map_read( n, map_key, i );
553
+ VALUE v = syck_map_read( n, map_value, i );
554
+ int skip_aset = 0;
555
+
556
+ /*
557
+ * Handle merge keys
558
+ */
559
+ if ( rb_obj_is_kind_of( k, cMergeKey ) )
560
+ {
561
+ VALUE tmp;
562
+ if ( !NIL_P(tmp = rb_check_convert_type(v, T_HASH, "Hash", "to_hash")) )
563
+ {
564
+ VALUE dup = rb_funcall( tmp, s_dup, 0 );
565
+ rb_funcall( dup, s_update, 1, obj );
566
+ obj = dup;
567
+ skip_aset = 1;
568
+ }
569
+ else if ( !NIL_P(tmp = rb_check_array_type(v)) )
570
+ {
571
+ VALUE end = rb_ary_pop( tmp );
572
+ VALUE tmph = rb_check_convert_type(end, T_HASH, "Hash", "to_hash");
573
+ if ( !NIL_P(tmph) )
574
+ {
575
+ VALUE dup = rb_funcall( tmph, s_dup, 0 );
576
+ tmp = rb_ary_reverse( tmp );
577
+ rb_ary_push( tmp, obj );
578
+ rb_iterate( rb_each, tmp, syck_merge_i, dup );
579
+ obj = dup;
580
+ skip_aset = 1;
581
+ }
582
+ }
583
+ }
584
+ else if ( rb_obj_is_kind_of( k, cDefaultKey ) )
585
+ {
586
+ rb_funcall( obj, s_default_set, 1, v );
587
+ skip_aset = 1;
588
+ }
589
+
590
+ if ( ! skip_aset )
591
+ {
592
+ rb_hash_aset( obj, k, v );
593
+ }
594
+ }
595
+ break;
596
+ }
597
+
598
+ *ref = obj;
599
+ return transferred;
600
+ }
601
+
602
+ /*
603
+ * {native mode} node handler
604
+ * - Converts data into native Ruby types
605
+ */
606
+ SYMID
607
+ rb_syck_load_handler(p, n)
608
+ SyckParser *p;
609
+ SyckNode *n;
610
+ {
611
+ VALUE obj = Qnil;
612
+ struct parser_xtra *bonus = (struct parser_xtra *)p->bonus;
613
+ VALUE resolver = bonus->resolver;
614
+ if ( NIL_P( resolver ) )
615
+ {
616
+ resolver = oDefaultResolver;
617
+ }
618
+
619
+ /*
620
+ * Create node,
621
+ */
622
+ obj = rb_funcall( resolver, s_node_import, 1, Data_Wrap_Struct( cNode, NULL, NULL, n ) );
623
+
624
+ /*
625
+ * ID already set, let's alter the symbol table to accept the new object
626
+ */
627
+ if (n->id > 0 && !NIL_P(obj))
628
+ {
629
+ MEMCPY((void *)n->id, (void *)obj, RVALUE, 1);
630
+ MEMZERO((void *)obj, RVALUE, 1);
631
+ obj = n->id;
632
+ }
633
+
634
+ if ( bonus->taint) OBJ_TAINT( obj );
635
+ if ( bonus->proc != 0 ) rb_funcall(bonus->proc, s_call, 1, obj);
636
+
637
+ rb_hash_aset(bonus->data, INT2FIX(RHASH(bonus->data)->tbl->num_entries), obj);
638
+ return obj;
639
+ }
640
+
641
+ /*
642
+ * friendly errors.
643
+ */
644
+ void
645
+ rb_syck_err_handler(p, msg)
646
+ SyckParser *p;
647
+ char *msg;
648
+ {
649
+ char *endl = p->cursor;
650
+
651
+ while ( *endl != '\0' && *endl != '\n' )
652
+ endl++;
653
+
654
+ endl[0] = '\0';
655
+ rb_raise(rb_eArgError, "%s on line %d, col %d: `%s'",
656
+ msg,
657
+ p->linect,
658
+ p->cursor - p->lineptr,
659
+ p->lineptr);
660
+ }
661
+
662
+ /*
663
+ * provide bad anchor object to the parser.
664
+ */
665
+ SyckNode *
666
+ rb_syck_bad_anchor_handler(p, a)
667
+ SyckParser *p;
668
+ char *a;
669
+ {
670
+ VALUE anchor_name = rb_str_new2( a );
671
+ SyckNode *badanc = syck_new_map( rb_str_new2( "name" ), anchor_name );
672
+ badanc->type_id = syck_strndup( "tag:ruby.yaml.org,2002:object:YAML::Syck::BadAlias", 53 );
673
+ return badanc;
674
+ }
675
+
676
+ /*
677
+ * data loaded based on the model requested.
678
+ */
679
+ void
680
+ syck_set_model( p, input, model )
681
+ VALUE p, input, model;
682
+ {
683
+ SyckParser *parser;
684
+ Data_Get_Struct(p, SyckParser, parser);
685
+ syck_parser_handler( parser, rb_syck_load_handler );
686
+ /* WARN: gonna be obsoleted soon!! */
687
+ if ( model == sym_generic )
688
+ {
689
+ rb_funcall( p, s_set_resolver, 1, oGenericResolver );
690
+ }
691
+ syck_parser_implicit_typing( parser, 1 );
692
+ syck_parser_taguri_expansion( parser, 1 );
693
+
694
+ if ( NIL_P( input ) )
695
+ {
696
+ input = rb_ivar_get( p, s_input );
697
+ }
698
+ if ( input == sym_bytecode )
699
+ {
700
+ syck_parser_set_input_type( parser, syck_bytecode_utf8 );
701
+ }
702
+ else
703
+ {
704
+ syck_parser_set_input_type( parser, syck_yaml_utf8 );
705
+ }
706
+ syck_parser_error_handler( parser, rb_syck_err_handler );
707
+ syck_parser_bad_anchor_handler( parser, rb_syck_bad_anchor_handler );
708
+ }
709
+
710
+ /*
711
+ * mark parser nodes
712
+ */
713
+ static void
714
+ syck_mark_parser(parser)
715
+ SyckParser *parser;
716
+ {
717
+ struct parser_xtra *bonus;
718
+ rb_gc_mark(parser->root);
719
+ rb_gc_mark(parser->root_on_error);
720
+ if ( parser->bonus != NULL )
721
+ {
722
+ bonus = (struct parser_xtra *)parser->bonus;
723
+ rb_gc_mark( bonus->data );
724
+ rb_gc_mark( bonus->proc );
725
+ }
726
+ }
727
+
728
+ /*
729
+ * Free the parser and any bonus attachment.
730
+ */
731
+ void
732
+ rb_syck_free_parser(p)
733
+ SyckParser *p;
734
+ {
735
+ struct parser_xtra *bonus = (struct parser_xtra *)p->bonus;
736
+ if ( bonus != NULL ) S_FREE( bonus );
737
+ syck_free_parser(p);
738
+ }
739
+
740
+ /*
741
+ * YAML::Syck::Parser.allocate
742
+ */
743
+ VALUE syck_parser_s_alloc _((VALUE));
744
+ VALUE
745
+ syck_parser_s_alloc(class)
746
+ VALUE class;
747
+ {
748
+ VALUE pobj;
749
+ SyckParser *parser = syck_new_parser();
750
+
751
+ pobj = Data_Wrap_Struct( class, syck_mark_parser, rb_syck_free_parser, parser );
752
+
753
+ syck_parser_set_root_on_error( parser, Qnil );
754
+
755
+ return pobj;
756
+ }
757
+
758
+ /*
759
+ * YAML::Syck::Parser.initialize( resolver, options )
760
+ */
761
+ static VALUE
762
+ syck_parser_initialize(argc, argv, self)
763
+ int argc;
764
+ VALUE *argv;
765
+ VALUE self;
766
+ {
767
+ VALUE options;
768
+ if (rb_scan_args(argc, argv, "01", &options) == 0)
769
+ {
770
+ options = rb_hash_new();
771
+ }
772
+ else
773
+ {
774
+ Check_Type(options, T_HASH);
775
+ }
776
+ rb_ivar_set(self, s_options, options);
777
+ return self;
778
+ }
779
+
780
+ /*
781
+ * YAML::Syck::Parser.bufsize = Integer
782
+ */
783
+ static VALUE
784
+ syck_parser_bufsize_set( self, size )
785
+ VALUE self, size;
786
+ {
787
+ SyckParser *parser;
788
+
789
+ if ( rb_respond_to( size, s_to_i ) ) {
790
+ int n = NUM2INT(rb_funcall(size, s_to_i, 0));
791
+ Data_Get_Struct(self, SyckParser, parser);
792
+ parser->bufsize = n;
793
+ }
794
+ return self;
795
+ }
796
+
797
+ /*
798
+ * YAML::Syck::Parser.bufsize => Integer
799
+ */
800
+ static VALUE
801
+ syck_parser_bufsize_get( self )
802
+ VALUE self;
803
+ {
804
+ SyckParser *parser;
805
+
806
+ Data_Get_Struct(self, SyckParser, parser);
807
+ return INT2FIX( parser->bufsize );
808
+ }
809
+
810
+ /*
811
+ * YAML::Syck::Parser.load( IO or String )
812
+ */
813
+ VALUE
814
+ syck_parser_load(argc, argv, self)
815
+ int argc;
816
+ VALUE *argv;
817
+ VALUE self;
818
+ {
819
+ VALUE port, proc, model, input;
820
+ SyckParser *parser;
821
+ struct parser_xtra *bonus = S_ALLOC_N( struct parser_xtra, 1 );
822
+ volatile VALUE hash; /* protect from GC */
823
+
824
+ rb_scan_args(argc, argv, "11", &port, &proc);
825
+
826
+ input = rb_hash_aref( rb_attr_get( self, s_options ), sym_input );
827
+ model = rb_hash_aref( rb_attr_get( self, s_options ), sym_model );
828
+ Data_Get_Struct(self, SyckParser, parser);
829
+ syck_set_model( self, input, model );
830
+
831
+ bonus->taint = syck_parser_assign_io(parser, port);
832
+ bonus->data = hash = rb_hash_new();
833
+ bonus->resolver = rb_attr_get( self, s_resolver );
834
+ if ( NIL_P( proc ) ) bonus->proc = 0;
835
+ else bonus->proc = proc;
836
+
837
+ parser->bonus = (void *)bonus;
838
+
839
+ return syck_parse( parser );
840
+ }
841
+
842
+ /*
843
+ * YAML::Syck::Parser.load_documents( IO or String ) { |doc| }
844
+ */
845
+ VALUE
846
+ syck_parser_load_documents(argc, argv, self)
847
+ int argc;
848
+ VALUE *argv;
849
+ VALUE self;
850
+ {
851
+ VALUE port, proc, v, input, model;
852
+ SyckParser *parser;
853
+ struct parser_xtra *bonus = S_ALLOC_N( struct parser_xtra, 1 );
854
+ volatile VALUE hash;
855
+
856
+ rb_scan_args(argc, argv, "1&", &port, &proc);
857
+
858
+ input = rb_hash_aref( rb_attr_get( self, s_options ), sym_input );
859
+ model = rb_hash_aref( rb_attr_get( self, s_options ), sym_model );
860
+ Data_Get_Struct(self, SyckParser, parser);
861
+ syck_set_model( self, input, model );
862
+
863
+ bonus->taint = syck_parser_assign_io(parser, port);
864
+ bonus->resolver = rb_attr_get( self, s_resolver );
865
+ bonus->proc = 0;
866
+ parser->bonus = (void *)bonus;
867
+
868
+ while ( 1 )
869
+ {
870
+ /* Reset hash for tracking nodes */
871
+ bonus->data = hash = rb_hash_new();
872
+
873
+ /* Parse a document */
874
+ v = syck_parse( parser );
875
+ if ( parser->eof == 1 )
876
+ {
877
+ break;
878
+ }
879
+
880
+ /* Pass document to block */
881
+ rb_funcall( proc, s_call, 1, v );
882
+ }
883
+
884
+ return Qnil;
885
+ }
886
+
887
+ /*
888
+ * YAML::Syck::Parser#set_resolver
889
+ */
890
+ VALUE
891
+ syck_parser_set_resolver( self, resolver )
892
+ VALUE self, resolver;
893
+ {
894
+ rb_ivar_set( self, s_resolver, resolver );
895
+ return self;
896
+ }
897
+
898
+ /*
899
+ * YAML::Syck::Resolver.initialize
900
+ */
901
+ static VALUE
902
+ syck_resolver_initialize( self )
903
+ VALUE self;
904
+ {
905
+ VALUE tags = rb_hash_new();
906
+ rb_ivar_set(self, s_tags, rb_hash_new());
907
+ return self;
908
+ }
909
+
910
+ /*
911
+ * YAML::Syck::Resolver#add_type
912
+ */
913
+ VALUE
914
+ syck_resolver_add_type( self, taguri, cls )
915
+ VALUE self, taguri, cls;
916
+ {
917
+ VALUE tags = rb_attr_get(self, s_tags);
918
+ rb_hash_aset( tags, taguri, cls );
919
+ return Qnil;
920
+ }
921
+
922
+ /*
923
+ * YAML::Syck::Resolver#use_types_at
924
+ */
925
+ VALUE
926
+ syck_resolver_use_types_at( self, hsh )
927
+ VALUE self, hsh;
928
+ {
929
+ rb_ivar_set( self, s_tags, hsh );
930
+ return Qnil;
931
+ }
932
+
933
+ /*
934
+ * YAML::Syck::Resolver#detect_implicit
935
+ */
936
+ VALUE
937
+ syck_resolver_detect_implicit( self, val )
938
+ VALUE self, val;
939
+ {
940
+ char *type_id;
941
+ return rb_str_new2( "" );
942
+ }
943
+
944
+ /*
945
+ * YAML::Syck::Resolver#node_import
946
+ */
947
+ VALUE
948
+ syck_resolver_node_import( self, node )
949
+ VALUE self, node;
950
+ {
951
+ SyckNode *n;
952
+ VALUE obj;
953
+ int i = 0;
954
+ Data_Get_Struct(node, SyckNode, n);
955
+
956
+ switch (n->kind)
957
+ {
958
+ case syck_str_kind:
959
+ obj = rb_str_new( n->data.str->ptr, n->data.str->len );
960
+ break;
961
+
962
+ case syck_seq_kind:
963
+ obj = rb_ary_new2( n->data.list->idx );
964
+ for ( i = 0; i < n->data.list->idx; i++ )
965
+ {
966
+ rb_ary_store( obj, i, syck_seq_read( n, i ) );
967
+ }
968
+ break;
969
+
970
+ case syck_map_kind:
971
+ obj = rb_hash_new();
972
+ for ( i = 0; i < n->data.pairs->idx; i++ )
973
+ {
974
+ VALUE k = syck_map_read( n, map_key, i );
975
+ VALUE v = syck_map_read( n, map_value, i );
976
+ int skip_aset = 0;
977
+
978
+ /*
979
+ * Handle merge keys
980
+ */
981
+ if ( rb_obj_is_kind_of( k, cMergeKey ) )
982
+ {
983
+ if ( rb_obj_is_kind_of( v, rb_cHash ) )
984
+ {
985
+ VALUE dup = rb_funcall( v, s_dup, 0 );
986
+ rb_funcall( dup, s_update, 1, obj );
987
+ obj = dup;
988
+ skip_aset = 1;
989
+ }
990
+ else if ( rb_obj_is_kind_of( v, rb_cArray ) )
991
+ {
992
+ VALUE end = rb_ary_pop( v );
993
+ if ( rb_obj_is_kind_of( end, rb_cHash ) )
994
+ {
995
+ VALUE dup = rb_funcall( end, s_dup, 0 );
996
+ v = rb_ary_reverse( v );
997
+ rb_ary_push( v, obj );
998
+ rb_iterate( rb_each, v, syck_merge_i, dup );
999
+ obj = dup;
1000
+ skip_aset = 1;
1001
+ }
1002
+ }
1003
+ }
1004
+ else if ( rb_obj_is_kind_of( k, cDefaultKey ) )
1005
+ {
1006
+ rb_funcall( obj, s_default_set, 1, v );
1007
+ skip_aset = 1;
1008
+ }
1009
+
1010
+ if ( ! skip_aset )
1011
+ {
1012
+ rb_hash_aset( obj, k, v );
1013
+ }
1014
+ }
1015
+ break;
1016
+ }
1017
+
1018
+ if ( n->type_id != NULL )
1019
+ {
1020
+ obj = rb_funcall( self, s_transfer, 2, rb_str_new2( n->type_id ), obj );
1021
+ }
1022
+ return obj;
1023
+ }
1024
+
1025
+ /*
1026
+ * Set instance variables
1027
+ */
1028
+ VALUE
1029
+ syck_set_ivars( vars, obj )
1030
+ VALUE vars, obj;
1031
+ {
1032
+ VALUE ivname = rb_ary_entry( vars, 0 );
1033
+ char *ivn;
1034
+ StringValue( ivname );
1035
+ ivn = S_ALLOC_N( char, RSTRING(ivname)->len + 2 );
1036
+ ivn[0] = '@';
1037
+ ivn[1] = '\0';
1038
+ strncat( ivn, RSTRING(ivname)->ptr, RSTRING(ivname)->len );
1039
+ rb_iv_set( obj, ivn, rb_ary_entry( vars, 1 ) );
1040
+ S_FREE( ivn );
1041
+ return Qnil;
1042
+ }
1043
+
1044
+ /*
1045
+ * YAML::Syck::Resolver#const_find
1046
+ */
1047
+ VALUE
1048
+ syck_const_find( const_name )
1049
+ VALUE const_name;
1050
+ {
1051
+ VALUE tclass = rb_cObject;
1052
+ VALUE tparts = rb_str_split( const_name, "::" );
1053
+ int i = 0;
1054
+ for ( i = 0; i < RARRAY(tparts)->len; i++ ) {
1055
+ VALUE tpart = rb_to_id( rb_ary_entry( tparts, i ) );
1056
+ if ( !rb_const_defined( tclass, tpart ) ) return Qnil;
1057
+ tclass = rb_const_get( tclass, tpart );
1058
+ }
1059
+ return tclass;
1060
+ }
1061
+
1062
+ /*
1063
+ * YAML::Syck::Resolver#transfer
1064
+ */
1065
+ VALUE
1066
+ syck_resolver_transfer( self, type, val )
1067
+ VALUE self, type, val;
1068
+ {
1069
+ if (NIL_P(type) || RSTRING(StringValue(type))->len == 0)
1070
+ {
1071
+ type = rb_funcall( self, s_detect_implicit, 1, val );
1072
+ }
1073
+
1074
+ if ( ! (NIL_P(type) || RSTRING(StringValue(type))->len == 0) )
1075
+ {
1076
+ VALUE str_xprivate = rb_str_new2( "x-private" );
1077
+ VALUE colon = rb_str_new2( ":" );
1078
+ VALUE tags = rb_attr_get(self, s_tags);
1079
+ VALUE target_class = rb_hash_aref( tags, type );
1080
+ VALUE subclass = target_class;
1081
+ VALUE obj = Qnil;
1082
+
1083
+ /*
1084
+ * Should no tag match exactly, check for subclass format
1085
+ */
1086
+ if ( NIL_P( target_class ) )
1087
+ {
1088
+ VALUE subclass_parts = rb_ary_new();
1089
+ VALUE parts = rb_str_split( type, ":" );
1090
+
1091
+ while ( RARRAY(parts)->len > 1 )
1092
+ {
1093
+ VALUE partial;
1094
+ rb_ary_unshift( subclass_parts, rb_ary_pop( parts ) );
1095
+ partial = rb_ary_join( parts, colon );
1096
+ target_class = rb_hash_aref( tags, partial );
1097
+ if ( NIL_P( target_class ) )
1098
+ {
1099
+ rb_str_append( partial, colon );
1100
+ target_class = rb_hash_aref( tags, partial );
1101
+ }
1102
+
1103
+ /*
1104
+ * Possible subclass found, see if it supports subclassing
1105
+ */
1106
+ if ( ! NIL_P( target_class ) )
1107
+ {
1108
+ subclass = target_class;
1109
+ if ( RARRAY(subclass_parts)->len > 0 && rb_respond_to( target_class, s_tag_subclasses ) &&
1110
+ RTEST( rb_funcall( target_class, s_tag_subclasses, 0 ) ) )
1111
+ {
1112
+ VALUE subclass_v;
1113
+ subclass = rb_ary_join( subclass_parts, colon );
1114
+ subclass = rb_funcall( target_class, s_tag_read_class, 1, subclass );
1115
+ subclass_v = syck_const_find( subclass );
1116
+
1117
+ if ( subclass_v != Qnil )
1118
+ {
1119
+ subclass = subclass_v;
1120
+ }
1121
+ else if ( rb_cObject == target_class && subclass_v == Qnil )
1122
+ {
1123
+ // StringValue(subclass);
1124
+ // printf( "No class: %s\n", RSTRING(subclass)->ptr );
1125
+ target_class = cYObject;
1126
+ type = subclass;
1127
+ subclass = cYObject;
1128
+ }
1129
+ }
1130
+ break;
1131
+ }
1132
+ }
1133
+ }
1134
+
1135
+ /* rb_raise(rb_eTypeError, "invalid typing scheme: %s given",
1136
+ * scheme);
1137
+ */
1138
+
1139
+ if ( rb_respond_to( target_class, s_call ) )
1140
+ {
1141
+ obj = rb_funcall( target_class, s_call, 2, type, val );
1142
+ }
1143
+ else
1144
+ {
1145
+ if ( rb_respond_to( target_class, s_yaml_new ) )
1146
+ {
1147
+ obj = rb_funcall( target_class, s_yaml_new, 3, subclass, type, val );
1148
+ }
1149
+ else if ( !NIL_P( target_class ) )
1150
+ {
1151
+ obj = rb_obj_alloc( subclass );
1152
+ if ( rb_respond_to( obj, s_yaml_initialize ) )
1153
+ {
1154
+ rb_funcall( obj, s_yaml_initialize, 2, type, val );
1155
+ }
1156
+ else if ( !NIL_P( obj ) && rb_obj_is_instance_of( val, rb_cHash ) )
1157
+ {
1158
+ rb_iterate( rb_each, val, syck_set_ivars, obj );
1159
+ }
1160
+ }
1161
+ else
1162
+ {
1163
+ VALUE parts = rb_str_split( type, ":" );
1164
+ VALUE scheme = rb_ary_shift( parts );
1165
+ if ( rb_str_cmp( scheme, str_xprivate ) == 0 )
1166
+ {
1167
+ VALUE name = rb_ary_join( parts, colon );
1168
+ obj = rb_funcall( cPrivateType, s_new, 2, name, val );
1169
+ }
1170
+ else
1171
+ {
1172
+ VALUE domain = rb_ary_shift( parts );
1173
+ VALUE name = rb_ary_join( parts, colon );
1174
+ obj = rb_funcall( cDomainType, s_new, 3, domain, name, val );
1175
+ }
1176
+ }
1177
+ }
1178
+ val = obj;
1179
+ }
1180
+
1181
+ return val;
1182
+ }
1183
+
1184
+ /*
1185
+ * YAML::Syck::Resolver#tagurize
1186
+ */
1187
+ VALUE
1188
+ syck_resolver_tagurize( self, val )
1189
+ VALUE self, val;
1190
+ {
1191
+ VALUE tmp = rb_check_string_type(val);
1192
+
1193
+ if ( !NIL_P(tmp) )
1194
+ {
1195
+ char *taguri;
1196
+ val = tmp;
1197
+ taguri = syck_type_id_to_uri( RSTRING(val)->ptr );
1198
+ return rb_str_new2( taguri );
1199
+ }
1200
+
1201
+ return val;
1202
+ }
1203
+
1204
+ /*
1205
+ * YAML::Syck::DefaultResolver#detect_implicit
1206
+ */
1207
+ VALUE
1208
+ syck_defaultresolver_detect_implicit( self, val )
1209
+ VALUE self, val;
1210
+ {
1211
+ char *type_id;
1212
+ VALUE tmp = rb_check_string_type(val);
1213
+
1214
+ if ( !NIL_P(tmp) )
1215
+ {
1216
+ val = tmp;
1217
+ type_id = syck_match_implicit( RSTRING(val)->ptr, RSTRING(val)->len );
1218
+ return rb_str_new2( type_id );
1219
+ }
1220
+
1221
+ return rb_str_new2( "" );
1222
+ }
1223
+
1224
+ /*
1225
+ * YAML::Syck::DefaultResolver#node_import
1226
+ */
1227
+ VALUE
1228
+ syck_defaultresolver_node_import( self, node )
1229
+ VALUE self, node;
1230
+ {
1231
+ SyckNode *n;
1232
+ VALUE obj;
1233
+ Data_Get_Struct( node, SyckNode, n );
1234
+ if ( !yaml_org_handler( n, &obj ) )
1235
+ {
1236
+ obj = rb_funcall( self, s_transfer, 2, rb_str_new2( n->type_id ), obj );
1237
+ }
1238
+ return obj;
1239
+ }
1240
+
1241
+ /*
1242
+ * YAML::Syck::GenericResolver#node_import
1243
+ */
1244
+ VALUE
1245
+ syck_genericresolver_node_import( self, node )
1246
+ VALUE self, node;
1247
+ {
1248
+ SyckNode *n;
1249
+ int i = 0;
1250
+ VALUE t = Qnil, obj = Qnil, v = Qnil, style = Qnil;
1251
+ Data_Get_Struct(node, SyckNode, n);
1252
+
1253
+ if ( n->type_id != NULL )
1254
+ {
1255
+ t = rb_str_new2(n->type_id);
1256
+ }
1257
+
1258
+ switch (n->kind)
1259
+ {
1260
+ case syck_str_kind:
1261
+ {
1262
+ v = rb_str_new( n->data.str->ptr, n->data.str->len );
1263
+ if ( n->data.str->style == scalar_1quote )
1264
+ {
1265
+ style = sym_1quote;
1266
+ }
1267
+ else if ( n->data.str->style == scalar_2quote )
1268
+ {
1269
+ style = sym_2quote;
1270
+ }
1271
+ else if ( n->data.str->style == scalar_fold )
1272
+ {
1273
+ style = sym_fold;
1274
+ }
1275
+ else if ( n->data.str->style == scalar_literal )
1276
+ {
1277
+ style = sym_literal;
1278
+ }
1279
+ else if ( n->data.str->style == scalar_plain )
1280
+ {
1281
+ style = sym_plain;
1282
+ }
1283
+ obj = rb_funcall( cScalar, s_new, 3, t, v, style );
1284
+ }
1285
+ break;
1286
+
1287
+ case syck_seq_kind:
1288
+ rb_iv_set(obj, "@kind", sym_seq);
1289
+ v = rb_ary_new2( syck_seq_count( n ) );
1290
+ for ( i = 0; i < syck_seq_count( n ); i++ )
1291
+ {
1292
+ rb_ary_store( v, i, syck_seq_read( n, i ) );
1293
+ }
1294
+ if ( n->data.list->style == seq_inline )
1295
+ {
1296
+ style = sym_inline;
1297
+ }
1298
+ obj = rb_funcall( cSeq, s_new, 3, t, v, style );
1299
+ break;
1300
+
1301
+ case syck_map_kind:
1302
+ rb_iv_set(obj, "@kind", sym_map);
1303
+ v = rb_hash_new();
1304
+ for ( i = 0; i < syck_map_count( n ); i++ )
1305
+ {
1306
+ rb_hash_aset( v, syck_map_read( n, map_key, i ), syck_map_read( n, map_value, i ) );
1307
+ }
1308
+ if ( n->data.pairs->style == map_inline )
1309
+ {
1310
+ style = sym_inline;
1311
+ }
1312
+ obj = rb_funcall( cMap, s_new, 3, t, v, style );
1313
+ break;
1314
+ }
1315
+
1316
+ return obj;
1317
+ }
1318
+
1319
+ /*
1320
+ * YAML::Syck::BadAlias.initialize
1321
+ */
1322
+ VALUE
1323
+ syck_badalias_initialize( self, val )
1324
+ VALUE self, val;
1325
+ {
1326
+ rb_iv_set( self, "@name", val );
1327
+ return self;
1328
+ }
1329
+
1330
+ /*
1331
+ * YAML::Syck::BadAlias.<=>
1332
+ */
1333
+ VALUE
1334
+ syck_badalias_cmp( alias1, alias2 )
1335
+ VALUE alias1, alias2;
1336
+ {
1337
+ VALUE str1 = rb_ivar_get( alias1, s_name );
1338
+ VALUE str2 = rb_ivar_get( alias2, s_name );
1339
+ VALUE val = rb_funcall( str1, s_cmp, 1, str2 );
1340
+ return val;
1341
+ }
1342
+
1343
+ /*
1344
+ * YAML::DomainType.initialize
1345
+ */
1346
+ VALUE
1347
+ syck_domaintype_initialize( self, domain, type_id, val )
1348
+ VALUE self, type_id, val;
1349
+ {
1350
+ rb_iv_set( self, "@domain", domain );
1351
+ rb_iv_set( self, "@type_id", type_id );
1352
+ rb_iv_set( self, "@value", val );
1353
+ return self;
1354
+ }
1355
+
1356
+ /*
1357
+ * YAML::Object.initialize
1358
+ */
1359
+ VALUE
1360
+ syck_yobject_initialize( self, klass, ivars )
1361
+ VALUE self, klass, ivars;
1362
+ {
1363
+ rb_iv_set( self, "@class", klass );
1364
+ rb_iv_set( self, "@ivars", ivars );
1365
+ return self;
1366
+ }
1367
+
1368
+ /*
1369
+ * YAML::PrivateType.initialize
1370
+ */
1371
+ VALUE
1372
+ syck_privatetype_initialize( self, type_id, val )
1373
+ VALUE self, type_id, val;
1374
+ {
1375
+ rb_iv_set( self, "@type_id", type_id );
1376
+ rb_iv_set( self, "@value", val );
1377
+ return self;
1378
+ }
1379
+
1380
+ /*
1381
+ * Mark node contents.
1382
+ */
1383
+ static void
1384
+ syck_node_mark( n )
1385
+ SyckNode *n;
1386
+ {
1387
+ int i;
1388
+ switch ( n->kind )
1389
+ {
1390
+ case syck_seq_kind:
1391
+ for ( i = 0; i < n->data.list->idx; i++ )
1392
+ {
1393
+ rb_gc_mark( syck_seq_read( n, i ) );
1394
+ }
1395
+ break;
1396
+
1397
+ case syck_map_kind:
1398
+ for ( i = 0; i < n->data.pairs->idx; i++ )
1399
+ {
1400
+ rb_gc_mark( syck_map_read( n, map_key, i ) );
1401
+ rb_gc_mark( syck_map_read( n, map_value, i ) );
1402
+ }
1403
+ break;
1404
+ }
1405
+ }
1406
+
1407
+ /*
1408
+ * Don't free Ruby data, Ruby will do that
1409
+ */
1410
+ void
1411
+ rb_syck_free_node( SyckNode *n )
1412
+ {
1413
+ switch ( n->kind )
1414
+ {
1415
+ case syck_str_kind:
1416
+ S_FREE( n->data.str );
1417
+ n->data.str = NULL;
1418
+ break;
1419
+
1420
+ case syck_seq_kind:
1421
+ if ( n->data.list != NULL )
1422
+ {
1423
+ S_FREE( n->data.list->items );
1424
+ S_FREE( n->data.list );
1425
+ n->data.list = NULL;
1426
+ }
1427
+ break;
1428
+
1429
+ case syck_map_kind:
1430
+ if ( n->data.pairs != NULL )
1431
+ {
1432
+ S_FREE( n->data.pairs->keys );
1433
+ S_FREE( n->data.pairs->values );
1434
+ S_FREE( n->data.pairs );
1435
+ n->data.pairs = NULL;
1436
+ }
1437
+ break;
1438
+ }
1439
+
1440
+ S_FREE( n );
1441
+ }
1442
+
1443
+ /*
1444
+ * YAML::Syck::Scalar.allocate
1445
+ */
1446
+ VALUE
1447
+ syck_scalar_alloc( class )
1448
+ VALUE class;
1449
+ {
1450
+ SyckNode *node = syck_alloc_str();
1451
+ VALUE obj = Data_Wrap_Struct( class, syck_node_mark, rb_syck_free_node, node );
1452
+ node->id = obj;
1453
+ return obj;
1454
+ }
1455
+
1456
+ /*
1457
+ * YAML::Syck::Scalar.initialize
1458
+ */
1459
+ VALUE
1460
+ syck_scalar_initialize( self, type_id, val, style )
1461
+ VALUE self, type_id, val, style;
1462
+ {
1463
+ rb_iv_set( self, "@kind", sym_scalar );
1464
+ rb_funcall( self, s_type_id_set, 1, type_id );
1465
+ rb_funcall( self, s_value_set, 1, val );
1466
+ rb_funcall( self, s_style_set, 1, style );
1467
+ return self;
1468
+ }
1469
+
1470
+ /*
1471
+ * YAML::Syck::Scalar.style=
1472
+ */
1473
+ VALUE
1474
+ syck_scalar_style_set( self, style )
1475
+ VALUE self, style;
1476
+ {
1477
+ SyckNode *node;
1478
+ Data_Get_Struct( self, SyckNode, node );
1479
+
1480
+ if ( NIL_P( style ) )
1481
+ {
1482
+ node->data.str->style = scalar_none;
1483
+ }
1484
+ else if ( style == sym_1quote )
1485
+ {
1486
+ node->data.str->style = scalar_1quote;
1487
+ }
1488
+ else if ( style == sym_2quote )
1489
+ {
1490
+ node->data.str->style = scalar_2quote;
1491
+ }
1492
+ else if ( style == sym_fold )
1493
+ {
1494
+ node->data.str->style = scalar_fold;
1495
+ }
1496
+ else if ( style == sym_literal )
1497
+ {
1498
+ node->data.str->style = scalar_literal;
1499
+ }
1500
+ else if ( style == sym_plain )
1501
+ {
1502
+ node->data.str->style = scalar_plain;
1503
+ }
1504
+
1505
+ rb_iv_set( self, "@style", style );
1506
+ return self;
1507
+ }
1508
+
1509
+ /*
1510
+ * YAML::Syck::Scalar.value=
1511
+ */
1512
+ VALUE
1513
+ syck_scalar_value_set( self, val )
1514
+ VALUE self, val;
1515
+ {
1516
+ SyckNode *node;
1517
+ Data_Get_Struct( self, SyckNode, node );
1518
+
1519
+ StringValue( val );
1520
+ node->data.str->ptr = RSTRING(val)->ptr;
1521
+ node->data.str->len = RSTRING(val)->len;
1522
+ node->data.str->style = scalar_none;
1523
+
1524
+ rb_iv_set( self, "@value", val );
1525
+ return val;
1526
+ }
1527
+
1528
+ /*
1529
+ * YAML::Syck::Seq.allocate
1530
+ */
1531
+ VALUE
1532
+ syck_seq_alloc( class )
1533
+ VALUE class;
1534
+ {
1535
+ SyckNode *node;
1536
+ VALUE obj;
1537
+ node = syck_alloc_seq();
1538
+ obj = Data_Wrap_Struct( class, syck_node_mark, rb_syck_free_node, node );
1539
+ node->id = obj;
1540
+ return obj;
1541
+ }
1542
+
1543
+ /*
1544
+ * YAML::Syck::Seq.initialize
1545
+ */
1546
+ VALUE
1547
+ syck_seq_initialize( self, type_id, val, style )
1548
+ VALUE self, type_id, val, style;
1549
+ {
1550
+ SyckNode *node;
1551
+ Data_Get_Struct( self, SyckNode, node );
1552
+
1553
+ rb_iv_set( self, "@kind", sym_seq );
1554
+ rb_funcall( self, s_type_id_set, 1, type_id );
1555
+ rb_funcall( self, s_value_set, 1, val );
1556
+ rb_funcall( self, s_style_set, 1, style );
1557
+ return self;
1558
+ }
1559
+
1560
+ /*
1561
+ * YAML::Syck::Seq.value=
1562
+ */
1563
+ VALUE
1564
+ syck_seq_value_set( self, val )
1565
+ VALUE self, val;
1566
+ {
1567
+ SyckNode *node;
1568
+ Data_Get_Struct( self, SyckNode, node );
1569
+
1570
+ val = rb_check_array_type( val );
1571
+ if ( !NIL_P( val ) ) {
1572
+ int i;
1573
+ syck_seq_empty( node );
1574
+ for ( i = 0; i < RARRAY( val )->len; i++ )
1575
+ {
1576
+ syck_seq_add( node, rb_ary_entry(val, i) );
1577
+ }
1578
+ }
1579
+
1580
+ rb_iv_set( self, "@value", val );
1581
+ return val;
1582
+ }
1583
+
1584
+ /*
1585
+ * YAML::Syck::Seq.add
1586
+ */
1587
+ VALUE
1588
+ syck_seq_add_m( self, val )
1589
+ VALUE self, val;
1590
+ {
1591
+ SyckNode *node;
1592
+ VALUE emitter = rb_ivar_get( self, s_emitter );
1593
+ Data_Get_Struct( self, SyckNode, node );
1594
+
1595
+ if ( rb_respond_to( emitter, s_node_export ) ) {
1596
+ val = rb_funcall( emitter, s_node_export, 1, val );
1597
+ }
1598
+ syck_seq_add( node, val );
1599
+ rb_ary_push( rb_ivar_get( self, s_value ), val );
1600
+
1601
+ return self;
1602
+ }
1603
+
1604
+ /*
1605
+ * YAML::Syck::Seq.style=
1606
+ */
1607
+ VALUE
1608
+ syck_seq_style_set( self, style )
1609
+ VALUE self, style;
1610
+ {
1611
+ SyckNode *node;
1612
+ Data_Get_Struct( self, SyckNode, node );
1613
+
1614
+ if ( style == sym_inline )
1615
+ {
1616
+ node->data.list->style = seq_inline;
1617
+ }
1618
+ else
1619
+ {
1620
+ node->data.list->style = seq_none;
1621
+ }
1622
+
1623
+ rb_iv_set( self, "@style", style );
1624
+ return self;
1625
+ }
1626
+
1627
+ /*
1628
+ * YAML::Syck::Map.allocate
1629
+ */
1630
+ VALUE
1631
+ syck_map_alloc( class )
1632
+ VALUE class;
1633
+ {
1634
+ SyckNode *node;
1635
+ VALUE obj;
1636
+ node = syck_alloc_map();
1637
+ obj = Data_Wrap_Struct( class, syck_node_mark, rb_syck_free_node, node );
1638
+ node->id = obj;
1639
+ return obj;
1640
+ }
1641
+
1642
+ /*
1643
+ * YAML::Syck::Map.initialize
1644
+ */
1645
+ VALUE
1646
+ syck_map_initialize( self, type_id, val, style )
1647
+ VALUE self, type_id, val, style;
1648
+ {
1649
+ SyckNode *node;
1650
+ Data_Get_Struct( self, SyckNode, node );
1651
+
1652
+ if ( !NIL_P( val ) )
1653
+ {
1654
+ VALUE hsh = rb_check_convert_type(val, T_HASH, "Hash", "to_hash");
1655
+ VALUE keys;
1656
+ int i;
1657
+ if ( NIL_P(hsh) )
1658
+ {
1659
+ rb_raise( rb_eTypeError, "wrong argument type" );
1660
+ }
1661
+
1662
+ keys = rb_funcall( hsh, s_keys, 0 );
1663
+ for ( i = 0; i < RARRAY(keys)->len; i++ )
1664
+ {
1665
+ VALUE key = rb_ary_entry(keys, i);
1666
+ syck_map_add( node, key, rb_hash_aref(hsh, key) );
1667
+ }
1668
+ }
1669
+
1670
+ rb_iv_set( self, "@kind", sym_seq );
1671
+ rb_funcall( self, s_type_id_set, 1, type_id );
1672
+ rb_funcall( self, s_value_set, 1, val );
1673
+ rb_funcall( self, s_style_set, 1, style );
1674
+ return self;
1675
+ }
1676
+
1677
+ /*
1678
+ * YAML::Syck::Map.value=
1679
+ */
1680
+ VALUE
1681
+ syck_map_value_set( self, val )
1682
+ VALUE self, val;
1683
+ {
1684
+ SyckNode *node;
1685
+ Data_Get_Struct( self, SyckNode, node );
1686
+
1687
+ if ( !NIL_P( val ) )
1688
+ {
1689
+ VALUE hsh = rb_check_convert_type(val, T_HASH, "Hash", "to_hash");
1690
+ VALUE keys;
1691
+ int i;
1692
+ if ( NIL_P(hsh) )
1693
+ {
1694
+ rb_raise( rb_eTypeError, "wrong argument type" );
1695
+ }
1696
+
1697
+ syck_map_empty( node );
1698
+ keys = rb_funcall( hsh, s_keys, 0 );
1699
+ for ( i = 0; i < RARRAY(keys)->len; i++ )
1700
+ {
1701
+ VALUE key = rb_ary_entry(keys, i);
1702
+ syck_map_add( node, key, rb_hash_aref(hsh, key) );
1703
+ }
1704
+ }
1705
+
1706
+ rb_iv_set( self, "@value", val );
1707
+ return val;
1708
+ }
1709
+
1710
+ /*
1711
+ * YAML::Syck::Map.add
1712
+ */
1713
+ VALUE
1714
+ syck_map_add_m( self, key, val )
1715
+ VALUE self, key, val;
1716
+ {
1717
+ SyckNode *node;
1718
+ VALUE emitter = rb_ivar_get( self, s_emitter );
1719
+ Data_Get_Struct( self, SyckNode, node );
1720
+
1721
+ if ( rb_respond_to( emitter, s_node_export ) ) {
1722
+ key = rb_funcall( emitter, s_node_export, 1, key );
1723
+ val = rb_funcall( emitter, s_node_export, 1, val );
1724
+ }
1725
+ syck_map_add( node, key, val );
1726
+ rb_hash_aset( rb_ivar_get( self, s_value ), key, val );
1727
+
1728
+ return self;
1729
+ }
1730
+
1731
+ /*
1732
+ * YAML::Syck::Map.style=
1733
+ */
1734
+ VALUE
1735
+ syck_map_style_set( self, style )
1736
+ VALUE self, style;
1737
+ {
1738
+ SyckNode *node;
1739
+ Data_Get_Struct( self, SyckNode, node );
1740
+
1741
+ if ( style == sym_inline )
1742
+ {
1743
+ node->data.pairs->style = map_inline;
1744
+ }
1745
+ else
1746
+ {
1747
+ node->data.pairs->style = map_none;
1748
+ }
1749
+
1750
+ rb_iv_set( self, "@style", style );
1751
+ return self;
1752
+ }
1753
+
1754
+ /*
1755
+ * Cloning method for all node types
1756
+ */
1757
+ VALUE
1758
+ syck_node_init_copy( copy, orig )
1759
+ VALUE copy, orig;
1760
+ {
1761
+ SyckNode *copy_n;
1762
+ SyckNode *orig_n;
1763
+
1764
+ if ( copy == orig )
1765
+ return copy;
1766
+
1767
+ if ( TYPE( orig ) != T_DATA ||
1768
+ RDATA( orig )->dfree != ( RUBY_DATA_FUNC )rb_syck_free_node )
1769
+ {
1770
+ rb_raise( rb_eTypeError, "wrong argument type" );
1771
+ }
1772
+
1773
+ Data_Get_Struct( orig, SyckNode, orig_n );
1774
+ Data_Get_Struct( copy, SyckNode, copy_n );
1775
+ MEMCPY( copy_n, orig_n, SyckNode, 1 );
1776
+ return copy;
1777
+ }
1778
+
1779
+ /*
1780
+ * YAML::Syck::Node#type_id=
1781
+ */
1782
+ VALUE
1783
+ syck_node_type_id_set( self, type_id )
1784
+ VALUE self, type_id;
1785
+ {
1786
+ SyckNode *node;
1787
+ Data_Get_Struct( self, SyckNode, node );
1788
+
1789
+ if ( node->type_id != NULL ) S_FREE( node->type_id );
1790
+
1791
+ if ( NIL_P( type_id ) ) {
1792
+ node->type_id = NULL;
1793
+ } else {
1794
+ node->type_id = StringValuePtr( type_id );
1795
+ }
1796
+
1797
+ rb_iv_set( self, "@type_id", type_id );
1798
+ return type_id;
1799
+ }
1800
+
1801
+ /*
1802
+ * YAML::Syck::Node.transform
1803
+ */
1804
+ VALUE
1805
+ syck_node_transform( self )
1806
+ VALUE self;
1807
+ {
1808
+ VALUE t;
1809
+ SyckNode *n;
1810
+ SyckNode *orig_n;
1811
+ Data_Get_Struct(self, SyckNode, orig_n);
1812
+
1813
+ switch (orig_n->kind)
1814
+ {
1815
+ case syck_map_kind:
1816
+ {
1817
+ int i;
1818
+ n = syck_alloc_map();
1819
+ for ( i = 0; i < orig_n->data.pairs->idx; i++ )
1820
+ {
1821
+ syck_map_add( n, rb_funcall( syck_map_read( orig_n, map_key, i ), s_transform, 0 ),
1822
+ rb_funcall( syck_map_read( orig_n, map_value, i ), s_transform, 0 ) );
1823
+ }
1824
+ }
1825
+ break;
1826
+
1827
+ case syck_seq_kind:
1828
+ {
1829
+ int i;
1830
+ n = syck_alloc_seq();
1831
+ for ( i = 0; i < orig_n->data.list->idx; i++ )
1832
+ {
1833
+ syck_seq_add( n, rb_funcall( syck_seq_read( orig_n, i ), s_transform, 0 ) );
1834
+ }
1835
+ }
1836
+ break;
1837
+
1838
+ case syck_str_kind:
1839
+ n = syck_new_str2( orig_n->data.str->ptr, orig_n->data.str->len, orig_n->data.str->style );
1840
+ break;
1841
+ }
1842
+
1843
+ if ( orig_n->type_id != NULL )
1844
+ {
1845
+ n->type_id = syck_strndup( orig_n->type_id, strlen( orig_n->type_id ) );
1846
+ }
1847
+ if ( orig_n->anchor != NULL )
1848
+ {
1849
+ n->anchor = syck_strndup( orig_n->anchor, strlen( orig_n->anchor ) );
1850
+ }
1851
+ t = Data_Wrap_Struct( cNode, NULL, NULL, n );
1852
+ n->id = t;
1853
+ t = rb_funcall( oDefaultResolver, s_node_import, 1, t );
1854
+ syck_free_node( n );
1855
+ return t;
1856
+ }
1857
+
1858
+ /*
1859
+ * Emitter callback: assembles YAML document events from
1860
+ * Ruby symbols. This is a brilliant way to do it.
1861
+ * No one could possibly object.
1862
+ */
1863
+ void
1864
+ rb_syck_emitter_handler(e, data)
1865
+ SyckEmitter *e;
1866
+ st_data_t data;
1867
+ {
1868
+ SyckNode *n;
1869
+ Data_Get_Struct((VALUE)data, SyckNode, n);
1870
+
1871
+ switch (n->kind)
1872
+ {
1873
+ case syck_map_kind:
1874
+ {
1875
+ int i;
1876
+ syck_emit_map( e, n->type_id, n->data.pairs->style );
1877
+ for ( i = 0; i < n->data.pairs->idx; i++ )
1878
+ {
1879
+ syck_emit_item( e, syck_map_read( n, map_key, i ) );
1880
+ syck_emit_item( e, syck_map_read( n, map_value, i ) );
1881
+ }
1882
+ syck_emit_end( e );
1883
+ }
1884
+ break;
1885
+
1886
+ case syck_seq_kind:
1887
+ {
1888
+ int i;
1889
+ syck_emit_seq( e, n->type_id, n->data.list->style );
1890
+ for ( i = 0; i < n->data.list->idx; i++ )
1891
+ {
1892
+ syck_emit_item( e, syck_seq_read( n, i ) );
1893
+ }
1894
+ syck_emit_end( e );
1895
+ }
1896
+ break;
1897
+
1898
+ case syck_str_kind:
1899
+ {
1900
+ syck_emit_scalar( e, n->type_id, n->data.str->style, 0, 0, 0, n->data.str->ptr, n->data.str->len );
1901
+ }
1902
+ break;
1903
+ }
1904
+ }
1905
+
1906
+ /*
1907
+ * Handle output from the emitter
1908
+ */
1909
+ void
1910
+ rb_syck_output_handler( emitter, str, len )
1911
+ SyckEmitter *emitter;
1912
+ char *str;
1913
+ long len;
1914
+ {
1915
+ struct emitter_xtra *bonus = (struct emitter_xtra *)emitter->bonus;
1916
+ VALUE dest = bonus->port;
1917
+ if (TYPE(dest) == T_STRING) {
1918
+ rb_str_cat( dest, str, len );
1919
+ } else {
1920
+ rb_io_write( dest, rb_str_new( str, len ) );
1921
+ }
1922
+ }
1923
+
1924
+ /*
1925
+ * Helper function for marking nodes in the anchor
1926
+ * symbol table.
1927
+ */
1928
+ void
1929
+ syck_out_mark( emitter, node )
1930
+ VALUE emitter, node;
1931
+ {
1932
+ SyckEmitter *emitterPtr;
1933
+ struct emitter_xtra *bonus;
1934
+ Data_Get_Struct(emitter, SyckEmitter, emitterPtr);
1935
+ bonus = (struct emitter_xtra *)emitterPtr->bonus;
1936
+ rb_ivar_set( node, s_emitter, emitter );
1937
+ /* syck_emitter_mark_node( emitterPtr, (st_data_t)node ); */
1938
+ if ( !NIL_P( bonus->oid ) ) {
1939
+ rb_hash_aset( bonus->data, bonus->oid, node );
1940
+ }
1941
+ }
1942
+
1943
+ /*
1944
+ * Mark emitter values.
1945
+ */
1946
+ static void
1947
+ syck_mark_emitter(emitter)
1948
+ SyckEmitter *emitter;
1949
+ {
1950
+ struct emitter_xtra *bonus;
1951
+ if ( emitter->bonus != NULL )
1952
+ {
1953
+ bonus = (struct emitter_xtra *)emitter->bonus;
1954
+ rb_gc_mark( bonus->data );
1955
+ rb_gc_mark( bonus->port );
1956
+ }
1957
+ }
1958
+
1959
+ /*
1960
+ * Free the emitter and any bonus attachment.
1961
+ */
1962
+ void
1963
+ rb_syck_free_emitter(e)
1964
+ SyckEmitter *e;
1965
+ {
1966
+ struct emitter_xtra *bonus = (struct emitter_xtra *)e->bonus;
1967
+ if ( bonus != NULL ) S_FREE( bonus );
1968
+ syck_free_emitter(e);
1969
+ }
1970
+
1971
+ /*
1972
+ * YAML::Syck::Emitter.allocate
1973
+ */
1974
+ VALUE syck_emitter_s_alloc _((VALUE));
1975
+ VALUE
1976
+ syck_emitter_s_alloc(class)
1977
+ VALUE class;
1978
+ {
1979
+ VALUE pobj;
1980
+ SyckEmitter *emitter = syck_new_emitter();
1981
+
1982
+ pobj = Data_Wrap_Struct( class, syck_mark_emitter, rb_syck_free_emitter, emitter );
1983
+ syck_emitter_handler( emitter, rb_syck_emitter_handler );
1984
+ syck_output_handler( emitter, rb_syck_output_handler );
1985
+
1986
+ rb_ivar_set( pobj, s_out, rb_funcall( cOut, s_new, 1, pobj ) );
1987
+ return pobj;
1988
+ }
1989
+
1990
+ /*
1991
+ * YAML::Syck::Emitter.reset( options )
1992
+ */
1993
+ VALUE
1994
+ syck_emitter_reset( argc, argv, self )
1995
+ int argc;
1996
+ VALUE *argv;
1997
+ VALUE self;
1998
+ {
1999
+ VALUE options, tmp;
2000
+ SyckEmitter *emitter;
2001
+ struct emitter_xtra *bonus;
2002
+ volatile VALUE hash; /* protect from GC */
2003
+
2004
+ Data_Get_Struct(self, SyckEmitter, emitter);
2005
+ bonus = (struct emitter_xtra *)emitter->bonus;
2006
+ if ( bonus != NULL ) S_FREE( bonus );
2007
+
2008
+ bonus = S_ALLOC_N( struct emitter_xtra, 1 );
2009
+ bonus->port = rb_str_new2( "" );
2010
+ bonus->data = hash = rb_hash_new();
2011
+
2012
+ if (rb_scan_args(argc, argv, "01", &options) == 0)
2013
+ {
2014
+ options = rb_hash_new();
2015
+ rb_ivar_set(self, s_options, options);
2016
+ }
2017
+ else if ( !NIL_P(tmp = rb_check_string_type(options)) )
2018
+ {
2019
+ bonus->port = tmp;
2020
+ }
2021
+ else if ( rb_respond_to( options, s_write ) )
2022
+ {
2023
+ bonus->port = options;
2024
+ }
2025
+ else
2026
+ {
2027
+ Check_Type(options, T_HASH);
2028
+ rb_ivar_set(self, s_options, options);
2029
+ }
2030
+
2031
+ emitter->bonus = (void *)bonus;
2032
+ rb_ivar_set(self, s_level, INT2FIX(0));
2033
+ rb_ivar_set(self, s_resolver, Qnil);
2034
+ return self;
2035
+ }
2036
+
2037
+ /*
2038
+ * YAML::Syck::Emitter.emit( object_id ) { |out| ... }
2039
+ */
2040
+ VALUE
2041
+ syck_emitter_emit( argc, argv, self )
2042
+ int argc;
2043
+ VALUE *argv;
2044
+ VALUE self;
2045
+ {
2046
+ VALUE oid, proc;
2047
+ char *anchor_name;
2048
+ SyckEmitter *emitter;
2049
+ struct emitter_xtra *bonus;
2050
+ SYMID symple;
2051
+ int level = FIX2INT(rb_ivar_get(self, s_level)) + 1;
2052
+ rb_ivar_set(self, s_level, INT2FIX(level));
2053
+
2054
+ rb_scan_args(argc, argv, "1&", &oid, &proc);
2055
+ Data_Get_Struct(self, SyckEmitter, emitter);
2056
+ bonus = (struct emitter_xtra *)emitter->bonus;
2057
+
2058
+ /* Calculate anchors, normalize nodes, build a simpler symbol table */
2059
+ bonus->oid = oid;
2060
+ if ( !NIL_P( oid ) && RTEST( rb_funcall( bonus->data, s_haskey, 1, oid ) ) ) {
2061
+ symple = rb_hash_aref( bonus->data, oid );
2062
+ } else {
2063
+ symple = rb_funcall( proc, s_call, 1, rb_ivar_get( self, s_out ) );
2064
+ }
2065
+ syck_emitter_mark_node( emitter, (st_data_t)symple );
2066
+
2067
+ /* Second pass, build emitted string */
2068
+ level -= 1;
2069
+ rb_ivar_set(self, s_level, INT2FIX(level));
2070
+ if ( level == 0 )
2071
+ {
2072
+ syck_emit(emitter, (st_data_t)symple);
2073
+ syck_emitter_flush(emitter, 0);
2074
+
2075
+ return bonus->port;
2076
+ }
2077
+
2078
+ return symple;
2079
+ }
2080
+
2081
+ /*
2082
+ * YAML::Syck::Emitter#node_export
2083
+ */
2084
+ VALUE
2085
+ syck_emitter_node_export( self, node )
2086
+ VALUE self, node;
2087
+ {
2088
+ return rb_funcall( node, s_to_yaml, 1, self );
2089
+ }
2090
+
2091
+ /*
2092
+ * YAML::Syck::Emitter#set_resolver
2093
+ */
2094
+ VALUE
2095
+ syck_emitter_set_resolver( self, resolver )
2096
+ VALUE self, resolver;
2097
+ {
2098
+ rb_ivar_set( self, s_resolver, resolver );
2099
+ return self;
2100
+ }
2101
+
2102
+ /*
2103
+ * YAML::Syck::Out::initialize
2104
+ */
2105
+ VALUE
2106
+ syck_out_initialize( self, emitter )
2107
+ VALUE self, emitter;
2108
+ {
2109
+ rb_ivar_set( self, s_emitter, emitter );
2110
+ return self;
2111
+ }
2112
+
2113
+ /*
2114
+ * YAML::Syck::Out::map
2115
+ */
2116
+ VALUE
2117
+ syck_out_map( argc, argv, self )
2118
+ int argc;
2119
+ VALUE *argv;
2120
+ VALUE self;
2121
+ {
2122
+ VALUE type_id, style, map;
2123
+ if (rb_scan_args(argc, argv, "11", &type_id, &style) == 1) {
2124
+ style = Qnil;
2125
+ }
2126
+ map = rb_funcall( cMap, s_new, 3, type_id, rb_hash_new(), style );
2127
+ syck_out_mark( rb_ivar_get( self, s_emitter ), map );
2128
+ rb_yield( map );
2129
+ return map;
2130
+ }
2131
+
2132
+ /*
2133
+ * YAML::Syck::Out::seq
2134
+ */
2135
+ VALUE
2136
+ syck_out_seq( argc, argv, self )
2137
+ int argc;
2138
+ VALUE *argv;
2139
+ VALUE self;
2140
+ {
2141
+ VALUE type_id, style, seq;
2142
+ if (rb_scan_args(argc, argv, "11", &type_id, &style) == 1) {
2143
+ style = Qnil;
2144
+ }
2145
+ seq = rb_funcall( cSeq, s_new, 3, type_id, rb_ary_new(), style );
2146
+ syck_out_mark( rb_ivar_get( self, s_emitter ), seq );
2147
+ rb_yield( seq );
2148
+ return seq;
2149
+ }
2150
+
2151
+ /*
2152
+ * YAML::Syck::Out::scalar
2153
+ syck_out_scalar( self, type_id, str, style )
2154
+ VALUE self, type_id, str, style;
2155
+ */
2156
+ VALUE
2157
+ syck_out_scalar( argc, argv, self )
2158
+ int argc;
2159
+ VALUE *argv;
2160
+ VALUE self;
2161
+ {
2162
+ VALUE type_id, str, style, scalar;
2163
+ if (rb_scan_args(argc, argv, "21", &type_id, &str, &style) == 2) {
2164
+ style = Qnil;
2165
+ }
2166
+ scalar = rb_funcall( cScalar, s_new, 3, type_id, str, style );
2167
+ syck_out_mark( rb_ivar_get( self, s_emitter ), scalar );
2168
+ return scalar;
2169
+ }
2170
+
2171
+ /*
2172
+ * Initialize Syck extension
2173
+ */
2174
+ void
2175
+ Init_syck()
2176
+ {
2177
+ VALUE rb_yaml = rb_define_module( "YAML" );
2178
+ VALUE rb_syck = rb_define_module_under( rb_yaml, "Syck" );
2179
+ rb_define_const( rb_syck, "VERSION", rb_str_new2( SYCK_VERSION ) );
2180
+ rb_define_module_function( rb_syck, "compile", rb_syck_compile, 1 );
2181
+
2182
+ /*
2183
+ * Global symbols
2184
+ */
2185
+ s_new = rb_intern("new");
2186
+ s_utc = rb_intern("utc");
2187
+ s_at = rb_intern("at");
2188
+ s_to_f = rb_intern("to_f");
2189
+ s_to_i = rb_intern("to_i");
2190
+ s_read = rb_intern("read");
2191
+ s_binmode = rb_intern("binmode");
2192
+ s_transfer = rb_intern("transfer");
2193
+ s_call = rb_intern("call");
2194
+ s_cmp = rb_intern("<=>");
2195
+ s_intern = rb_intern("intern");
2196
+ s_update = rb_intern("update");
2197
+ s_detect_implicit = rb_intern("detect_implicit");
2198
+ s_dup = rb_intern("dup");
2199
+ s_default_set = rb_intern("default=");
2200
+ s_match = rb_intern("match");
2201
+ s_push = rb_intern("push");
2202
+ s_haskey = rb_intern("has_key?");
2203
+ s_keys = rb_intern("keys");
2204
+ s_node_import = rb_intern("node_import");
2205
+ s_tr_bang = rb_intern("tr!");
2206
+ s_unpack = rb_intern("unpack");
2207
+ s_write = rb_intern("write");
2208
+ s_tag_read_class = rb_intern( "tag_read_class" );
2209
+ s_tag_subclasses = rb_intern( "tag_subclasses?" );
2210
+ s_emitter = rb_intern( "emitter" );
2211
+ s_set_resolver = rb_intern( "set_resolver" );
2212
+ s_node_export = rb_intern( "node_export" );
2213
+ s_to_yaml = rb_intern( "to_yaml" );
2214
+ s_transform = rb_intern( "transform" );
2215
+ s_yaml_new = rb_intern("yaml_new");
2216
+ s_yaml_initialize = rb_intern("yaml_initialize");
2217
+
2218
+ s_tags = rb_intern("@tags");
2219
+ s_name = rb_intern("@name");
2220
+ s_options = rb_intern("@options");
2221
+ s_kind = rb_intern("@kind");
2222
+ s_type_id = rb_intern("@type_id");
2223
+ s_type_id_set = rb_intern("type_id=");
2224
+ s_resolver = rb_intern("@resolver");
2225
+ s_level = rb_intern( "@level" );
2226
+ s_style = rb_intern("@style");
2227
+ s_style_set = rb_intern("style=");
2228
+ s_value = rb_intern("@value");
2229
+ s_value_set = rb_intern("value=");
2230
+ s_out = rb_intern("@out");
2231
+ s_input = rb_intern("@input");
2232
+
2233
+ sym_model = ID2SYM(rb_intern("Model"));
2234
+ sym_generic = ID2SYM(rb_intern("Generic"));
2235
+ sym_bytecode = ID2SYM(rb_intern("bytecode"));
2236
+ sym_map = ID2SYM(rb_intern("map"));
2237
+ sym_scalar = ID2SYM(rb_intern("scalar"));
2238
+ sym_seq = ID2SYM(rb_intern("seq"));
2239
+ sym_1quote = ID2SYM(rb_intern("quote1"));
2240
+ sym_2quote = ID2SYM(rb_intern("quote2"));
2241
+ sym_fold = ID2SYM(rb_intern("fold"));
2242
+ sym_literal = ID2SYM(rb_intern("literal"));
2243
+ sym_plain = ID2SYM(rb_intern("plain"));
2244
+ sym_inline = ID2SYM(rb_intern("inline"));
2245
+
2246
+ /*
2247
+ * Define YAML::Syck::Resolver class
2248
+ */
2249
+ cResolver = rb_define_class_under( rb_syck, "Resolver", rb_cObject );
2250
+ rb_define_attr( cResolver, "tags", 1, 1 );
2251
+ rb_define_method( cResolver, "initialize", syck_resolver_initialize, 0 );
2252
+ rb_define_method( cResolver, "add_type", syck_resolver_add_type, 2 );
2253
+ rb_define_method( cResolver, "use_types_at", syck_resolver_use_types_at, 1 );
2254
+ rb_define_method( cResolver, "detect_implicit", syck_resolver_detect_implicit, 1 );
2255
+ rb_define_method( cResolver, "transfer", syck_resolver_transfer, 2 );
2256
+ rb_define_method( cResolver, "node_import", syck_resolver_node_import, 1 );
2257
+ rb_define_method( cResolver, "tagurize", syck_resolver_tagurize, 1 );
2258
+
2259
+ oDefaultResolver = rb_funcall( cResolver, rb_intern( "new" ), 0 );
2260
+ rb_define_singleton_method( oDefaultResolver, "node_import", syck_defaultresolver_node_import, 1 );
2261
+ rb_define_singleton_method( oDefaultResolver, "detect_implicit", syck_defaultresolver_detect_implicit, 1 );
2262
+ rb_define_const( rb_syck, "DefaultResolver", oDefaultResolver );
2263
+ oGenericResolver = rb_funcall( cResolver, rb_intern( "new" ), 0 );
2264
+ rb_define_singleton_method( oGenericResolver, "node_import", syck_genericresolver_node_import, 1 );
2265
+ rb_define_const( rb_syck, "GenericResolver", oGenericResolver );
2266
+
2267
+ /*
2268
+ * Define YAML::Syck::Parser class
2269
+ */
2270
+ cParser = rb_define_class_under( rb_syck, "Parser", rb_cObject );
2271
+ rb_define_attr( cParser, "options", 1, 1 );
2272
+ rb_define_attr( cParser, "resolver", 1, 1 );
2273
+ rb_define_attr( cParser, "input", 1, 1 );
2274
+ rb_define_alloc_func( cParser, syck_parser_s_alloc );
2275
+ rb_define_method(cParser, "initialize", syck_parser_initialize, -1 );
2276
+ rb_define_method(cParser, "bufsize=", syck_parser_bufsize_set, 1 );
2277
+ rb_define_method(cParser, "bufsize", syck_parser_bufsize_get, 0 );
2278
+ rb_define_method(cParser, "load", syck_parser_load, -1);
2279
+ rb_define_method(cParser, "load_documents", syck_parser_load_documents, -1);
2280
+ rb_define_method(cParser, "set_resolver", syck_parser_set_resolver, 1);
2281
+
2282
+ /*
2283
+ * Define YAML::Syck::Node class
2284
+ */
2285
+ cNode = rb_define_class_under( rb_syck, "Node", rb_cObject );
2286
+ rb_define_method( cNode, "initialize_copy", syck_node_init_copy, 1 );
2287
+ rb_define_attr( cNode, "emitter", 1, 1 );
2288
+ rb_define_attr( cNode, "resolver", 1, 1 );
2289
+ rb_define_attr( cNode, "kind", 1, 0 );
2290
+ rb_define_attr( cNode, "type_id", 1, 0 );
2291
+ rb_define_attr( cNode, "value", 1, 0 );
2292
+ rb_define_method( cNode, "type_id=", syck_node_type_id_set, 1 );
2293
+ rb_define_method( cNode, "transform", syck_node_transform, 0);
2294
+
2295
+ /*
2296
+ * Define YAML::Syck::Scalar, YAML::Syck::Seq, YAML::Syck::Map --
2297
+ * all are the publicly usable variants of YAML::Syck::Node
2298
+ */
2299
+ cScalar = rb_define_class_under( rb_syck, "Scalar", cNode );
2300
+ rb_define_alloc_func( cScalar, syck_scalar_alloc );
2301
+ rb_define_attr( cNode, "value", 1, 0 );
2302
+ rb_define_method( cScalar, "initialize", syck_scalar_initialize, 3 );
2303
+ rb_define_method( cScalar, "value=", syck_scalar_value_set, 1 );
2304
+ rb_define_method( cScalar, "style=", syck_scalar_style_set, 1 );
2305
+ cSeq = rb_define_class_under( rb_syck, "Seq", cNode );
2306
+ rb_define_alloc_func( cSeq, syck_seq_alloc );
2307
+ rb_define_method( cSeq, "initialize", syck_seq_initialize, 3 );
2308
+ rb_define_method( cSeq, "value=", syck_seq_value_set, 1 );
2309
+ rb_define_method( cSeq, "add", syck_seq_add_m, 1 );
2310
+ rb_define_method( cSeq, "style=", syck_seq_style_set, 1 );
2311
+ cMap = rb_define_class_under( rb_syck, "Map", cNode );
2312
+ rb_define_alloc_func( cMap, syck_map_alloc );
2313
+ rb_define_method( cMap, "initialize", syck_map_initialize, 3 );
2314
+ rb_define_method( cMap, "value=", syck_map_value_set, 1 );
2315
+ rb_define_method( cMap, "add", syck_map_add_m, 2 );
2316
+ rb_define_method( cMap, "style=", syck_map_style_set, 1 );
2317
+
2318
+ /*
2319
+ * Define YAML::PrivateType class
2320
+ */
2321
+ cPrivateType = rb_define_class_under( rb_yaml, "PrivateType", rb_cObject );
2322
+ rb_define_attr( cPrivateType, "type_id", 1, 1 );
2323
+ rb_define_attr( cPrivateType, "value", 1, 1 );
2324
+ rb_define_method( cPrivateType, "initialize", syck_privatetype_initialize, 2);
2325
+
2326
+ /*
2327
+ * Define YAML::DomainType class
2328
+ */
2329
+ cDomainType = rb_define_class_under( rb_yaml, "DomainType", rb_cObject );
2330
+ rb_define_attr( cDomainType, "domain", 1, 1 );
2331
+ rb_define_attr( cDomainType, "type_id", 1, 1 );
2332
+ rb_define_attr( cDomainType, "value", 1, 1 );
2333
+ rb_define_method( cDomainType, "initialize", syck_domaintype_initialize, 3);
2334
+
2335
+ /*
2336
+ * Define YAML::Object class
2337
+ */
2338
+ cYObject = rb_define_class_under( rb_yaml, "Object", rb_cObject );
2339
+ rb_define_attr( cYObject, "class", 1, 1 );
2340
+ rb_define_attr( cYObject, "ivars", 1, 1 );
2341
+ rb_define_method( cYObject, "initialize", syck_yobject_initialize, 2);
2342
+ rb_define_method( cYObject, "yaml_initialize", syck_yobject_initialize, 2);
2343
+
2344
+ /*
2345
+ * Define YAML::Syck::BadAlias class
2346
+ */
2347
+ cBadAlias = rb_define_class_under( rb_syck, "BadAlias", rb_cObject );
2348
+ rb_define_attr( cBadAlias, "name", 1, 1 );
2349
+ rb_define_method( cBadAlias, "initialize", syck_badalias_initialize, 1);
2350
+ rb_define_method( cBadAlias, "<=>", syck_badalias_cmp, 1);
2351
+ rb_include_module( cBadAlias, rb_const_get( rb_cObject, rb_intern("Comparable") ) );
2352
+
2353
+ /*
2354
+ * Define YAML::Syck::MergeKey class
2355
+ */
2356
+ cMergeKey = rb_define_class_under( rb_syck, "MergeKey", rb_cObject );
2357
+
2358
+ /*
2359
+ * Define YAML::Syck::DefaultKey class
2360
+ */
2361
+ cDefaultKey = rb_define_class_under( rb_syck, "DefaultKey", rb_cObject );
2362
+
2363
+ /*
2364
+ * Define YAML::Syck::Out classes
2365
+ */
2366
+ cOut = rb_define_class_under( rb_syck, "Out", rb_cObject );
2367
+ rb_define_attr( cOut, "emitter", 1, 1 );
2368
+ rb_define_method( cOut, "initialize", syck_out_initialize, 1 );
2369
+ rb_define_method( cOut, "map", syck_out_map, -1 );
2370
+ rb_define_method( cOut, "seq", syck_out_seq, -1 );
2371
+ rb_define_method( cOut, "scalar", syck_out_scalar, -1 );
2372
+
2373
+ /*
2374
+ * Define YAML::Syck::Emitter class
2375
+ */
2376
+ cEmitter = rb_define_class_under( rb_syck, "Emitter", rb_cObject );
2377
+ rb_define_attr( cEmitter, "level", 1, 1 );
2378
+ rb_define_alloc_func( cEmitter, syck_emitter_s_alloc );
2379
+ rb_define_method( cEmitter, "initialize", syck_emitter_reset, -1 );
2380
+ rb_define_method( cEmitter, "reset", syck_emitter_reset, -1 );
2381
+ rb_define_method( cEmitter, "emit", syck_emitter_emit, -1 );
2382
+ rb_define_method( cEmitter, "set_resolver", syck_emitter_set_resolver, 1);
2383
+ rb_define_method( cEmitter, "node_export", syck_emitter_node_export, 1);
2384
+ }
2385
+