km-psych 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. data/README.rdoc +129 -0
  2. data/ext/psych/emitter.c +488 -0
  3. data/ext/psych/emitter.h +8 -0
  4. data/ext/psych/extconf.rb +22 -0
  5. data/ext/psych/parser.c +349 -0
  6. data/ext/psych/parser.h +6 -0
  7. data/ext/psych/psych.c +34 -0
  8. data/ext/psych/psych.h +20 -0
  9. data/ext/psych/to_ruby.c +41 -0
  10. data/ext/psych/to_ruby.h +8 -0
  11. data/ext/psych/yaml_tree.c +24 -0
  12. data/ext/psych/yaml_tree.h +8 -0
  13. data/lib/km-psych.rb +244 -0
  14. data/lib/psych/coder.rb +86 -0
  15. data/lib/psych/core_ext.rb +38 -0
  16. data/lib/psych/deprecated.rb +82 -0
  17. data/lib/psych/handler.rb +221 -0
  18. data/lib/psych/json.rb +6 -0
  19. data/lib/psych/json/stream.rb +32 -0
  20. data/lib/psych/json/tree_builder.rb +32 -0
  21. data/lib/psych/nodes.rb +77 -0
  22. data/lib/psych/nodes/alias.rb +18 -0
  23. data/lib/psych/nodes/document.rb +60 -0
  24. data/lib/psych/nodes/mapping.rb +56 -0
  25. data/lib/psych/nodes/node.rb +42 -0
  26. data/lib/psych/nodes/scalar.rb +67 -0
  27. data/lib/psych/nodes/sequence.rb +81 -0
  28. data/lib/psych/nodes/stream.rb +37 -0
  29. data/lib/psych/omap.rb +4 -0
  30. data/lib/psych/parser.rb +44 -0
  31. data/lib/psych/scalar_scanner.rb +105 -0
  32. data/lib/psych/set.rb +4 -0
  33. data/lib/psych/stream.rb +53 -0
  34. data/lib/psych/tree_builder.rb +94 -0
  35. data/lib/psych/visitors.rb +5 -0
  36. data/lib/psych/visitors/emitter.rb +41 -0
  37. data/lib/psych/visitors/json_tree.rb +14 -0
  38. data/lib/psych/visitors/to_ruby.rb +263 -0
  39. data/lib/psych/visitors/visitor.rb +27 -0
  40. data/lib/psych/visitors/yaml_tree.rb +342 -0
  41. data/test/psych/helper.rb +63 -0
  42. data/test/psych/json/test_stream.rb +75 -0
  43. data/test/psych/test_alias_and_anchor.rb +26 -0
  44. data/test/psych/test_array.rb +19 -0
  45. data/test/psych/test_boolean.rb +36 -0
  46. data/test/psych/test_class.rb +17 -0
  47. data/test/psych/test_coder.rb +169 -0
  48. data/test/psych/test_date_time.rb +17 -0
  49. data/test/psych/test_deprecated.rb +210 -0
  50. data/test/psych/test_document.rb +46 -0
  51. data/test/psych/test_emitter.rb +88 -0
  52. data/test/psych/test_encoding.rb +179 -0
  53. data/test/psych/test_engine_manager.rb +57 -0
  54. data/test/psych/test_exception.rb +39 -0
  55. data/test/psych/test_hash.rb +30 -0
  56. data/test/psych/test_json_tree.rb +43 -0
  57. data/test/psych/test_null.rb +19 -0
  58. data/test/psych/test_object.rb +27 -0
  59. data/test/psych/test_omap.rb +68 -0
  60. data/test/psych/test_parser.rb +216 -0
  61. data/test/psych/test_psych.rb +133 -0
  62. data/test/psych/test_scalar.rb +11 -0
  63. data/test/psych/test_scalar_scanner.rb +70 -0
  64. data/test/psych/test_serialize_subclasses.rb +38 -0
  65. data/test/psych/test_set.rb +49 -0
  66. data/test/psych/test_stream.rb +49 -0
  67. data/test/psych/test_string.rb +49 -0
  68. data/test/psych/test_struct.rb +51 -0
  69. data/test/psych/test_symbol.rb +17 -0
  70. data/test/psych/test_to_yaml_properties.rb +63 -0
  71. data/test/psych/test_tree_builder.rb +79 -0
  72. data/test/psych/test_yaml.rb +1251 -0
  73. data/test/psych/visitors/test_emitter.rb +124 -0
  74. data/test/psych/visitors/test_to_ruby.rb +325 -0
  75. data/test/psych/visitors/test_yaml_tree.rb +149 -0
  76. metadata +187 -0
@@ -0,0 +1,8 @@
1
+ #ifndef PSYCH_TO_RUBY_H
2
+ #define PSYCH_TO_RUBY_H
3
+
4
+ #include <psych.h>
5
+
6
+ void Init_psych_to_ruby(void);
7
+
8
+ #endif
@@ -0,0 +1,24 @@
1
+ #include <psych.h>
2
+
3
+ VALUE cPsychVisitorsYamlTree;
4
+
5
+ /*
6
+ * call-seq: private_iv_get(target, prop)
7
+ *
8
+ * Get the private instance variable +prop+ from +target+
9
+ */
10
+ static VALUE private_iv_get(VALUE self, VALUE target, VALUE prop)
11
+ {
12
+ return rb_attr_get(target, rb_intern(StringValuePtr(prop)));
13
+ }
14
+
15
+ void Init_psych_yaml_tree(void)
16
+ {
17
+ VALUE psych = rb_define_module("Psych");
18
+ VALUE visitors = rb_define_module_under(psych, "Visitors");
19
+ VALUE visitor = rb_define_class_under(visitors, "Visitor", rb_cObject);
20
+ cPsychVisitorsYamlTree = rb_define_class_under(visitors, "YAMLTree", visitor);
21
+
22
+ rb_define_private_method(cPsychVisitorsYamlTree, "private_iv_get", private_iv_get, 2);
23
+ }
24
+ /* vim: set noet sws=4 sw=4: */
@@ -0,0 +1,8 @@
1
+ #ifndef PSYCH_YAML_TREE_H
2
+ #define PSYCH_YAML_TREE_H
3
+
4
+ #include <psych.h>
5
+
6
+ void Init_psych_yaml_tree(void);
7
+
8
+ #endif
@@ -0,0 +1,244 @@
1
+ require 'psych.so'
2
+ require 'psych/nodes'
3
+ require 'psych/visitors'
4
+ require 'psych/handler'
5
+ require 'psych/tree_builder'
6
+ require 'psych/parser'
7
+ require 'psych/omap'
8
+ require 'psych/set'
9
+ require 'psych/coder'
10
+ require 'psych/core_ext'
11
+ require 'psych/deprecated'
12
+
13
+ ###
14
+ # = Overview
15
+ #
16
+ # Psych is a YAML parser and emitter. Psych leverages
17
+ # libyaml[http://libyaml.org] for it's YAML parsing and emitting capabilities.
18
+ # In addition to wrapping libyaml, Psych also knows how to serialize and
19
+ # de-serialize most Ruby objects to and from the YAML format.
20
+ #
21
+ # = I NEED TO PARSE OR EMIT YAML RIGHT NOW!
22
+ #
23
+ # # Parse some YAML
24
+ # Psych.load("--- foo") # => "foo"
25
+ #
26
+ # # Emit some YAML
27
+ # Psych.dump("foo") # => "--- foo\n...\n"
28
+ # { :a => 'b'}.to_yaml # => "---\n:a: b\n"
29
+ #
30
+ # Got more time on your hands? Keep on reading!
31
+ #
32
+ # == YAML Parsing
33
+ #
34
+ # Psych provides a range of interfaces for parsing a YAML document ranging from
35
+ # low level to high level, depending on your parsing needs. At the lowest
36
+ # level, is an event based parser. Mid level is access to the raw YAML AST,
37
+ # and at the highest level is the ability to unmarshal YAML to ruby objects.
38
+ #
39
+ # === Low level parsing
40
+ #
41
+ # The lowest level parser should be used when the YAML input is already known,
42
+ # and the developer does not want to pay the price of building an AST or
43
+ # automatic detection and conversion to ruby objects. See Psych::Parser for
44
+ # more information on using the event based parser.
45
+ #
46
+ # === Mid level parsing
47
+ #
48
+ # Psych provides access to an AST produced from parsing a YAML document. This
49
+ # tree is built using the Psych::Parser and Psych::TreeBuilder. The AST can
50
+ # be examined and manipulated freely. Please see Psych::parse_stream,
51
+ # Psych::Nodes, and Psych::Nodes::Node for more information on dealing with
52
+ # YAML syntax trees.
53
+ #
54
+ # === High level parsing
55
+ #
56
+ # The high level YAML parser provided by Psych simply takes YAML as input and
57
+ # returns a Ruby data structure. For information on using the high level parser
58
+ # see Psych.load
59
+ #
60
+ # == YAML Emitting
61
+ #
62
+ # Psych provides a range of interfaces ranging from low to high level for
63
+ # producing YAML documents. Very similar to the YAML parsing interfaces, Psych
64
+ # provides at the lowest level, an event based system, mid-level is building
65
+ # a YAML AST, and the highest level is converting a Ruby object straight to
66
+ # a YAML document.
67
+ #
68
+ # === Low level emitting
69
+ #
70
+ # The lowest level emitter is an event based system. Events are sent to a
71
+ # Psych::Emitter object. That object knows how to convert the events to a YAML
72
+ # document. This interface should be used when document format is known in
73
+ # advance or speed is a concern. See Psych::Emitter for more information.
74
+ #
75
+ # === Mid level emitting
76
+ #
77
+ # At the mid level is building an AST. This AST is exactly the same as the AST
78
+ # used when parsing a YAML document. Users can build an AST by hand and the
79
+ # AST knows how to emit itself as a YAML document. See Psych::Nodes,
80
+ # Psych::Nodes::Node, and Psych::TreeBuilder for more information on building
81
+ # a YAML AST.
82
+ #
83
+ # === High level emitting
84
+ #
85
+ # The high level emitter has the easiest interface. Psych simply takes a Ruby
86
+ # data structure and converts it to a YAML document. See Psych.dump for more
87
+ # information on dumping a Ruby data structure.
88
+
89
+ module Psych
90
+ # The version is Psych you're using
91
+ VERSION = '1.0.0'
92
+
93
+ # The version of libyaml Psych is using
94
+ LIBYAML_VERSION = Psych.libyaml_version.join '.'
95
+
96
+ class Exception < RuntimeError
97
+ end
98
+
99
+ autoload :Stream, 'psych/stream'
100
+ autoload :JSON, 'psych/json'
101
+
102
+ ###
103
+ # Load +yaml+ in to a Ruby data structure. If multiple documents are
104
+ # provided, the object contained in the first document will be returned.
105
+ #
106
+ # Example:
107
+ #
108
+ # Psych.load("--- a") # => 'a'
109
+ # Psych.load("---\n - a\n - b") # => ['a', 'b']
110
+ def self.load yaml
111
+ result = parse(yaml)
112
+ result ? result.to_ruby : result
113
+ end
114
+
115
+ ###
116
+ # Parse a YAML string in +yaml+. Returns the first object of a YAML AST.
117
+ #
118
+ # Example:
119
+ #
120
+ # Psych.parse("---\n - a\n - b") # => #<Psych::Nodes::Sequence:0x00>
121
+ #
122
+ # See Psych::Nodes for more information about YAML AST.
123
+ def self.parse yaml
124
+ children = parse_stream(yaml).children
125
+ children.empty? ? false : children.first.children.first
126
+ end
127
+
128
+ ###
129
+ # Parse a file at +filename+. Returns the YAML AST.
130
+ def self.parse_file filename
131
+ File.open filename do |f|
132
+ parse f
133
+ end
134
+ end
135
+
136
+ ###
137
+ # Returns a default parser
138
+ def self.parser
139
+ Psych::Parser.new(TreeBuilder.new)
140
+ end
141
+
142
+ ###
143
+ # Parse a YAML string in +yaml+. Returns the full AST for the YAML document.
144
+ # This method can handle multiple YAML documents contained in +yaml+.
145
+ #
146
+ # Example:
147
+ #
148
+ # Psych.parse_stream("---\n - a\n - b") # => #<Psych::Nodes::Stream:0x00>
149
+ #
150
+ # See Psych::Nodes for more information about YAML AST.
151
+ def self.parse_stream yaml
152
+ parser = self.parser
153
+ parser.parse yaml
154
+ parser.handler.root
155
+ end
156
+
157
+ ###
158
+ # Dump Ruby object +o+ to a YAML string using +options+.
159
+ #
160
+ # Example:
161
+ #
162
+ # Psych.dump(['a', 'b']) # => "---\n- a\n- b\n"
163
+ def self.dump o, io = nil, options = {}
164
+ if Hash === io
165
+ options = io
166
+ io = nil
167
+ end
168
+
169
+ visitor = Psych::Visitors::YAMLTree.new options
170
+ visitor << o
171
+ visitor.tree.to_yaml io
172
+ end
173
+
174
+ ###
175
+ # Dump a list of objects as separate documents to a document stream.
176
+ #
177
+ # Example:
178
+ #
179
+ # Psych.dump_stream("foo\n ", {}) # => "--- ! \"foo\\n \"\n--- {}\n"
180
+ def self.dump_stream *objects
181
+ visitor = Psych::Visitors::YAMLTree.new {}
182
+ objects.each do |o|
183
+ visitor << o
184
+ end
185
+ visitor.tree.to_yaml
186
+ end
187
+
188
+ ###
189
+ # Dump Ruby object +o+ to a JSON string.
190
+ def self.to_json o
191
+ visitor = Psych::Visitors::JSONTree.new
192
+ visitor << o
193
+ visitor.tree.to_yaml
194
+ end
195
+
196
+ ###
197
+ # Load multiple documents given in +yaml+. Returns the parsed documents
198
+ # as a list. For example:
199
+ #
200
+ # Psych.load_stream("--- foo\n...\n--- bar\n...") # => ['foo', 'bar']
201
+ #
202
+ def self.load_stream yaml
203
+ parse_stream(yaml).children.map { |child| child.to_ruby }
204
+ end
205
+
206
+ ###
207
+ # Load the document contained in +filename+. Returns the yaml contained in
208
+ # +filename+ as a ruby object
209
+ def self.load_file filename
210
+ self.load File.open(filename)
211
+ end
212
+
213
+ # :stopdoc:
214
+ @domain_types = {}
215
+ def self.add_domain_type domain, type_tag, &block
216
+ key = ['tag', domain, type_tag].join ':'
217
+ @domain_types[key] = [key, block]
218
+ @domain_types["tag:#{type_tag}"] = [key, block]
219
+ end
220
+
221
+ def self.add_builtin_type type_tag, &block
222
+ domain = 'yaml.org,2002'
223
+ key = ['tag', domain, type_tag].join ':'
224
+ @domain_types[key] = [key, block]
225
+ end
226
+
227
+ def self.remove_type type_tag
228
+ @domain_types.delete type_tag
229
+ end
230
+
231
+ @load_tags = {}
232
+ @dump_tags = {}
233
+ def self.add_tag tag, klass
234
+ @load_tags[tag] = klass
235
+ @dump_tags[klass] = tag
236
+ end
237
+
238
+ class << self
239
+ attr_accessor :load_tags
240
+ attr_accessor :dump_tags
241
+ attr_accessor :domain_types
242
+ end
243
+ # :startdoc:
244
+ end
@@ -0,0 +1,86 @@
1
+ module Psych
2
+ ###
3
+ # If an object defines +encode_with+, then an instance of Psych::Coder will
4
+ # be passed to the method when the object is being serialized. The Coder
5
+ # automatically assumes a Psych::Nodes::Mapping is being emitted. Other
6
+ # objects like Sequence and Scalar may be emitted if +seq=+ or +scalar=+ are
7
+ # called, respectively.
8
+ class Coder
9
+ attr_accessor :tag, :style, :implicit
10
+ attr_reader :type, :seq
11
+
12
+ def initialize tag
13
+ @map = {}
14
+ @seq = []
15
+ @implicit = false
16
+ @type = :map
17
+ @tag = tag
18
+ @style = Psych::Nodes::Mapping::BLOCK
19
+ @scalar = nil
20
+ end
21
+
22
+ def scalar *args
23
+ if args.length > 0
24
+ warn "#{caller[0]}: Coder#scalar(a,b,c) is deprecated" if $VERBOSE
25
+ @tag, @scalar, _ = args
26
+ @type = :scalar
27
+ end
28
+ @scalar
29
+ end
30
+
31
+ # Emit a map. The coder will be yielded to the block.
32
+ def map tag = @tag, style = @style
33
+ @tag = tag
34
+ @style = style
35
+ yield self if block_given?
36
+ @map
37
+ end
38
+
39
+ # Emit a scalar with +value+ and +tag+
40
+ def represent_scalar tag, value
41
+ self.tag = tag
42
+ self.scalar = value
43
+ end
44
+
45
+ # Emit a sequence with +list+ and +tag+
46
+ def represent_seq tag, list
47
+ @tag = tag
48
+ self.seq = list
49
+ end
50
+
51
+ # Emit a sequence with +map+ and +tag+
52
+ def represent_map tag, map
53
+ @tag = tag
54
+ self.map = map
55
+ end
56
+
57
+ # Emit a scalar with +value+
58
+ def scalar= value
59
+ @type = :scalar
60
+ @scalar = value
61
+ end
62
+
63
+ # Emit a map with +value+
64
+ def map= map
65
+ @type = :map
66
+ @map = map
67
+ end
68
+
69
+ def []= k, v
70
+ @type = :map
71
+ @map[k] = v
72
+ end
73
+ alias :add :[]=
74
+
75
+ def [] k
76
+ @type = :map
77
+ @map[k]
78
+ end
79
+
80
+ # Emit a sequence of +list+
81
+ def seq= list
82
+ @type = :seq
83
+ @seq = list
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,38 @@
1
+ class Object
2
+ def self.yaml_tag url
3
+ Psych.add_tag(url, self)
4
+ end
5
+
6
+ # FIXME: rename this to "to_yaml" when syck is removed
7
+
8
+ ###
9
+ # call-seq: to_yaml
10
+ #
11
+ # Convert an object to YAML
12
+ def psych_to_yaml options = {}
13
+ Psych.dump self, options
14
+ end
15
+ remove_method :to_yaml rescue nil
16
+ alias :to_yaml :psych_to_yaml
17
+ end
18
+
19
+ class Module
20
+ def psych_yaml_as url
21
+ return if caller[0].end_with?('rubytypes.rb')
22
+ if $VERBOSE
23
+ warn "#{caller[0]}: yaml_as is deprecated, please use yaml_tag"
24
+ end
25
+ Psych.add_tag(url, self)
26
+ end
27
+
28
+ remove_method :yaml_as rescue nil
29
+ alias :yaml_as :psych_yaml_as
30
+ end
31
+
32
+ module Kernel
33
+ def psych_y *objects
34
+ puts Psych.dump_stream(*objects)
35
+ end
36
+ remove_method :y rescue nil
37
+ alias y psych_y
38
+ end
@@ -0,0 +1,82 @@
1
+ require 'date'
2
+
3
+ module Psych
4
+ DEPRECATED = __FILE__ # :nodoc:
5
+
6
+ module DeprecatedMethods # :nodoc:
7
+ attr_accessor :taguri
8
+ attr_accessor :to_yaml_style
9
+ end
10
+
11
+ def self.quick_emit thing, opts = {}, &block # :nodoc:
12
+ warn "#{caller[0]}: YAML.quick_emit is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
13
+ target = eval 'self', block.binding
14
+ target.extend DeprecatedMethods
15
+ metaclass = class << target; self; end
16
+ metaclass.send(:define_method, :encode_with) do |coder|
17
+ target.taguri = coder.tag
18
+ target.to_yaml_style = coder.style
19
+ block.call coder
20
+ end
21
+ target.psych_to_yaml unless opts[:nodump]
22
+ end
23
+
24
+ def self.load_documents yaml, &block
25
+ if $VERBOSE
26
+ warn "#{caller[0]}: load_documents is deprecated, use load_stream"
27
+ end
28
+ list = load_stream yaml
29
+ return list unless block_given?
30
+ list.each(&block)
31
+ end
32
+
33
+ def self.detect_implicit thing
34
+ warn "#{caller[0]}: detect_implicit is deprecated" if $VERBOSE
35
+ return '' unless String === thing
36
+ return 'null' if '' == thing
37
+ ScalarScanner.new.tokenize(thing).class.name.downcase
38
+ end
39
+
40
+ def self.add_ruby_type type_tag, &block
41
+ warn "#{caller[0]}: add_ruby_type is deprecated, use add_domain_type" if $VERBOSE
42
+ domain = 'ruby.yaml.org,2002'
43
+ key = ['tag', domain, type_tag].join ':'
44
+ @domain_types[key] = [key, block]
45
+ end
46
+
47
+ def self.add_private_type type_tag, &block
48
+ warn "#{caller[0]}: add_private_type is deprecated, use add_domain_type" if $VERBOSE
49
+ domain = 'x-private'
50
+ key = [domain, type_tag].join ':'
51
+ @domain_types[key] = [key, block]
52
+ end
53
+
54
+ def self.tagurize thing
55
+ warn "#{caller[0]}: add_private_type is deprecated, use add_domain_type" if $VERBOSE
56
+ return thing unless String === thing
57
+ "tag:yaml.org,2002:#{thing}"
58
+ end
59
+
60
+ def self.read_type_class type, reference
61
+ warn "#{caller[0]}: read_type_class is deprecated" if $VERBOSE
62
+ _, _, type, name = type.split ':', 4
63
+
64
+ reference = name.split('::').inject(reference) do |k,n|
65
+ k.const_get(n.to_sym)
66
+ end if name
67
+ [type, reference]
68
+ end
69
+
70
+ def self.object_maker klass, hash
71
+ warn "#{caller[0]}: object_maker is deprecated" if $VERBOSE
72
+ klass.allocate.tap do |obj|
73
+ hash.each { |k,v| obj.instance_variable_set(:"@#{k}", v) }
74
+ end
75
+ end
76
+ end
77
+
78
+ class Object
79
+ def to_yaml_properties # :nodoc:
80
+ instance_variables
81
+ end
82
+ end