km-psych 0.1.0

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