1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* ext/syck: removed. Fixes [ruby-core:43360]

* test/syck: removed.

* lib/yaml.rb: only require psych, show a warning if people try to set
  the engine to syck.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36786 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
tenderlove 2012-08-22 17:43:16 +00:00
parent b8910f3751
commit 5571c7315e
57 changed files with 33 additions and 18722 deletions

View file

@ -1,3 +1,12 @@
Thu Aug 23 02:37:35 2012 Aaron Patterson <aaron@tenderlovemaking.com>
* ext/syck: removed. Fixes [ruby-core:43360]
* test/syck: removed.
* lib/yaml.rb: only require psych, show a warning if people try to set
the engine to syck.
Thu Aug 23 01:46:53 2012 Aaron Patterson <aaron@tenderlovemaking.com>
* insns.def: search up the cf stack for an object that is an instance

4
NEWS
View file

@ -172,6 +172,10 @@ with all sufficient information, see the ChangeLog file.
private key to PEM with a password - it has to be at least four characters
long.
* yaml
* Syck has been removed. YAML now completely depends on libyaml being
installed.
=== Language changes
* Added %i and %I for symbol list creation (similar to %w and %W).

View file

@ -24,7 +24,6 @@
#socket
#stringio
#strscan
#syck
#syslog
#tk
#win32ole

View file

@ -25,7 +25,6 @@ sdbm
socket
stringio
strscan
syck
syslog
#tk
#win32ole

View file

@ -25,7 +25,6 @@ racc/cparse
socket
stringio
strscan
#syck
#syslog
#tk
#win32ole

View file

@ -43,7 +43,6 @@
# #socket
# stringio
# strscan
# syck
# #syslog
# #tk
# #tk/tkutil

View file

@ -25,7 +25,6 @@ sdbm
socket
stringio
strscan
syck
#syslog
#tk
win32ole

File diff suppressed because it is too large Load diff

View file

@ -1,12 +0,0 @@
ruby_headers = $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h \
$(hdrdir)/missing.h $(hdrdir)/intern.h $(hdrdir)/st.h
bytecode.o: bytecode.c syck.h gram.h $(ruby_headers)
emitter.o: emitter.c syck.h $(ruby_headers)
gram.o: gram.c syck.h $(hdrdir)/st.h
handler.o: handler.c syck.h $(ruby_headers)
implicit.o: implicit.c syck.h $(ruby_headers)
node.o: node.c syck.h $(ruby_headers)
rubyext.o: rubyext.c syck.h $(ruby_headers)
syck.o: syck.c syck.h $(ruby_headers)
token.o: token.c syck.h gram.h $(ruby_headers)
yaml2byte.o: yaml2byte.c syck.h yamlbyte.h $(ruby_headers)

File diff suppressed because it is too large Load diff

View file

@ -1,5 +0,0 @@
require 'mkmf'
have_header( "st.h" )
create_makefile( "syck" )

File diff suppressed because it is too large Load diff

View file

@ -1,79 +0,0 @@
/* A Bison parser, made by GNU Bison 1.875d. */
/* Skeleton parser for Yacc-like parsing with Bison,
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, when this file is copied by Bison into a
Bison output file, you may use that output file without restriction.
This special exception was added by the Free Software Foundation
in version 1.24 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
YAML_ANCHOR = 258,
YAML_ALIAS = 259,
YAML_TRANSFER = 260,
YAML_TAGURI = 261,
YAML_ITRANSFER = 262,
YAML_WORD = 263,
YAML_PLAIN = 264,
YAML_BLOCK = 265,
YAML_DOCSEP = 266,
YAML_IOPEN = 267,
YAML_INDENT = 268,
YAML_IEND = 269
};
#endif
#define YAML_ANCHOR 258
#define YAML_ALIAS 259
#define YAML_TRANSFER 260
#define YAML_TAGURI 261
#define YAML_ITRANSFER 262
#define YAML_WORD 263
#define YAML_PLAIN 264
#define YAML_BLOCK 265
#define YAML_DOCSEP 266
#define YAML_IOPEN 267
#define YAML_INDENT 268
#define YAML_IEND 269
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
#line 35 "gram.y"
typedef union YYSTYPE {
SYMID nodeId;
SyckNode *nodeData;
char *name;
} YYSTYPE;
/* Line 1285 of yacc.c. */
#line 71 "gram.h"
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif

View file

@ -1,173 +0,0 @@
/*
* handler.c
*
* $Author$
*
* Copyright (C) 2003 why the lucky stiff
*/
#include "ruby/ruby.h"
#include "syck.h"
SYMID
syck_hdlr_add_node( SyckParser *p, SyckNode *n )
{
SYMID id;
if ( ! n->id )
{
n->id = (p->handler)( p, n );
}
id = n->id;
if ( n->anchor == NULL )
{
syck_free_node( n );
}
return id;
}
SyckNode *
syck_hdlr_add_anchor( SyckParser *p, char *a, SyckNode *n )
{
SyckNode *ntmp = NULL;
n->anchor = a;
if ( p->bad_anchors != NULL )
{
SyckNode *bad;
if ( st_lookup( p->bad_anchors, (st_data_t)a, (void *)&bad ) )
{
if ( n->kind != syck_str_kind )
{
n->id = bad->id;
(p->handler)( p, n );
}
}
}
if ( p->anchors == NULL )
{
p->anchors = st_init_strtable();
}
if ( st_lookup( p->anchors, (st_data_t)a, (void *)&ntmp ) )
{
if ( ntmp != (void *)1 )
{
syck_free_node( ntmp );
}
}
st_insert( p->anchors, (st_data_t)a, (st_data_t)n );
return n;
}
void
syck_hdlr_remove_anchor( SyckParser *p, char *a )
{
char *atmp = a;
SyckNode *ntmp;
if ( p->anchors == NULL )
{
p->anchors = st_init_strtable();
}
if ( st_delete( p->anchors, (void *)&atmp, (void *)&ntmp ) )
{
if ( ntmp != (void *)1 )
{
syck_free_node( ntmp );
}
}
st_insert( p->anchors, (st_data_t)a, (st_data_t)1 );
}
SyckNode *
syck_hdlr_get_anchor( SyckParser *p, char *a )
{
SyckNode *n = NULL;
if ( p->anchors != NULL )
{
if ( st_lookup( p->anchors, (st_data_t)a, (void *)&n ) )
{
if ( n != (void *)1 )
{
S_FREE( a );
return n;
}
else
{
if ( p->bad_anchors == NULL )
{
p->bad_anchors = st_init_strtable();
}
if ( ! st_lookup( p->bad_anchors, (st_data_t)a, (void *)&n ) )
{
n = (p->bad_anchor_handler)( p, a );
st_insert( p->bad_anchors, (st_data_t)a, (st_data_t)n );
}
}
}
}
if ( n == NULL )
{
n = (p->bad_anchor_handler)( p, a );
}
if ( n->anchor )
{
S_FREE( a );
}
else
{
n->anchor = a;
}
return n;
}
void
syck_add_transfer( char *uri, SyckNode *n, int taguri )
{
if ( n->type_id != NULL )
{
S_FREE( n->type_id );
}
if ( taguri == 0 )
{
n->type_id = uri;
return;
}
n->type_id = syck_type_id_to_uri( uri );
S_FREE( uri );
}
char *
syck_xprivate( const char *type_id, int type_len )
{
char *uri = S_ALLOC_N( char, type_len + 14 );
uri[0] = '\0';
strcat( uri, "x-private:" );
strncat( uri, type_id, type_len );
return uri;
}
char *
syck_taguri( const char *domain, const char *type_id, int type_len )
{
char *uri = S_ALLOC_N( char, strlen( domain ) + type_len + 14 );
uri[0] = '\0';
strcat( uri, "tag:" );
strcat( uri, domain );
strcat( uri, ":" );
strncat( uri, type_id, type_len );
return uri;
}
int
syck_try_implicit( SyckNode *n )
{
return 1;
}

File diff suppressed because it is too large Load diff

View file

@ -1,447 +0,0 @@
# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4
# $Id$
#
# = yaml.rb: top-level module with methods for loading and parsing YAML documents
#
# Author:: why the lucky stiff
#
require 'yaml/syck'
# == YAML
#
# YAML(tm) (rhymes with 'camel') is a
# straightforward machine parsable data serialization format designed for
# human readability and interaction with scripting languages such as Perl
# and Python. YAML is optimized for data serialization, formatted
# dumping, configuration files, log files, Internet messaging and
# filtering. This specification describes the YAML information model and
# serialization format. Together with the Unicode standard for characters, it
# provides all the information necessary to understand YAML Version 1.0
# and construct computer programs to process it.
#
# See http://yaml.org/ for more information. For a quick tutorial, please
# visit YAML In Five Minutes (http://yaml.kwiki.org/?YamlInFiveMinutes).
#
# == About This Library
#
# The YAML 1.0 specification outlines four stages of YAML loading and dumping.
# This library honors all four of those stages, although data is really only
# available to you in three stages.
#
# The four stages are: native, representation, serialization, and presentation.
#
# The native stage refers to data which has been loaded completely into Ruby's
# own types. (See +YAML::load+.)
#
# The representation stage means data which has been composed into
# +YAML::BaseNode+ objects. In this stage, the document is available as a
# tree of node objects. You can perform YPath queries and transformations
# at this level. (See +YAML::parse+.)
#
# The serialization stage happens inside the parser. The YAML parser used in
# Ruby is called Syck. Serialized nodes are available in the extension as
# SyckNode structs.
#
# The presentation stage is the YAML document itself. This is accessible
# to you as a string. (See +YAML::dump+.)
#
# For more information about the various information models, see Chapter
# 3 of the YAML 1.0 Specification (http://yaml.org/spec/#id2491269).
#
# The YAML module provides quick access to the most common loading (YAML::load)
# and dumping (YAML::dump) tasks. This module also provides an API for registering
# global types (YAML::add_domain_type).
#
# == Example
#
# A simple round-trip (load and dump) of an object.
#
# require "yaml"
#
# test_obj = ["dogs", "cats", "badgers"]
#
# yaml_obj = YAML::dump( test_obj )
# # -> ---
# - dogs
# - cats
# - badgers
# ruby_obj = YAML::load( yaml_obj )
# # => ["dogs", "cats", "badgers"]
# ruby_obj == test_obj
# # => true
#
# To register your custom types with the global resolver, use +add_domain_type+.
#
# YAML::add_domain_type( "your-site.com,2004", "widget" ) do |type, val|
# Widget.new( val )
# end
#
module Syck
DefaultResolver.use_types_at( @@tagged_classes )
# Returns a new default parser
def self.parser; Parser.new.set_resolver( self.resolver ); end
# Returns a new generic parser
def self.generic_parser
warn "#{caller[0]}: YAML.generic_parser is deprecated, switch to psych" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
Parser.new.set_resolver( GenericResolver )
end
# Returns the default resolver
def self.resolver
warn "#{caller[0]}: YAML.resolver is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
DefaultResolver
end
# Returns a new default emitter
def self.emitter
warn "#{caller[0]}: YAML.emitter is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
Emitter.new.set_resolver( self.resolver )
end
#
# Converts _obj_ to YAML and writes the YAML result to _io_.
#
# File.open( 'animals.yaml', 'w' ) do |out|
# YAML.dump( ['badger', 'elephant', 'tiger'], out )
# end
#
# If no _io_ is provided, a string containing the dumped YAML
# is returned.
#
# YAML.dump( :locked )
# #=> "--- :locked"
#
def self.dump( obj, io = nil )
obj.to_yaml( io || io2 = StringIO.new )
io || ( io2.rewind; io2.read )
end
#
# Load a document from the current _io_ stream.
#
# File.open( 'animals.yaml' ) { |yf| YAML::load( yf ) }
# #=> ['badger', 'elephant', 'tiger']
#
# Can also load from a string.
#
# YAML.load( "--- :locked" )
# #=> :locked
#
def self.load( io )
parser.load( io )
end
#
# Load a document from the file located at _filepath_.
#
# YAML.load_file( 'animals.yaml' )
# #=> ['badger', 'elephant', 'tiger']
#
def self.load_file( filepath )
File.open( filepath ) do |f|
load( f )
end
end
#
# Parse the first document from the current _io_ stream
#
# File.open( 'animals.yaml' ) { |yf| YAML::load( yf ) }
# #=> #<YAML::Syck::Node:0x82ccce0
# @kind=:seq,
# @value=
# [#<YAML::Syck::Node:0x82ccd94
# @kind=:scalar,
# @type_id="str",
# @value="badger">,
# #<YAML::Syck::Node:0x82ccd58
# @kind=:scalar,
# @type_id="str",
# @value="elephant">,
# #<YAML::Syck::Node:0x82ccd1c
# @kind=:scalar,
# @type_id="str",
# @value="tiger">]>
#
# Can also load from a string.
#
# YAML.parse( "--- :locked" )
# #=> #<YAML::Syck::Node:0x82edddc
# @type_id="tag:ruby.yaml.org,2002:sym",
# @value=":locked", @kind=:scalar>
#
def self.parse( io )
generic_parser.load( io )
end
#
# Parse a document from the file located at _filepath_.
#
# YAML.parse_file( 'animals.yaml' )
# #=> #<YAML::Syck::Node:0x82ccce0
# @kind=:seq,
# @value=
# [#<YAML::Syck::Node:0x82ccd94
# @kind=:scalar,
# @type_id="str",
# @value="badger">,
# #<YAML::Syck::Node:0x82ccd58
# @kind=:scalar,
# @type_id="str",
# @value="elephant">,
# #<YAML::Syck::Node:0x82ccd1c
# @kind=:scalar,
# @type_id="str",
# @value="tiger">]>
#
def self.parse_file( filepath )
File.open( filepath ) do |f|
parse( f )
end
end
#
# Calls _block_ with each consecutive document in the YAML
# stream contained in _io_.
#
# File.open( 'many-docs.yaml' ) do |yf|
# YAML.each_document( yf ) do |ydoc|
# ## ydoc contains the single object
# ## from the YAML document
# end
# end
#
def self.each_document( io, &block )
warn "#{caller[0]}: YAML.each_document is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
parser.load_documents( io, &block )
end
#
# Calls _block_ with each consecutive document in the YAML
# stream contained in _io_.
#
# File.open( 'many-docs.yaml' ) do |yf|
# YAML.load_documents( yf ) do |ydoc|
# ## ydoc contains the single object
# ## from the YAML document
# end
# end
#
def self.load_documents( io, &doc_proc )
parser.load_documents( io, &doc_proc )
end
#
# Calls _block_ with a tree of +YAML::BaseNodes+, one tree for
# each consecutive document in the YAML stream contained in _io_.
#
# File.open( 'many-docs.yaml' ) do |yf|
# YAML.each_node( yf ) do |ydoc|
# ## ydoc contains a tree of nodes
# ## from the YAML document
# end
# end
#
def self.each_node( io, &doc_proc )
warn "#{caller[0]}: YAML.each_node is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
generic_parser.load_documents( io, &doc_proc )
end
#
# Calls _block_ with a tree of +YAML::BaseNodes+, one tree for
# each consecutive document in the YAML stream contained in _io_.
#
# File.open( 'many-docs.yaml' ) do |yf|
# YAML.parse_documents( yf ) do |ydoc|
# ## ydoc contains a tree of nodes
# ## from the YAML document
# end
# end
#
def self.parse_documents( io, &doc_proc )
warn "#{caller[0]}: YAML.parse_documents is deprecated, use load_stream" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
self.each_node( io, &doc_proc )
end
#
# Loads all documents from the current _io_ stream,
# returning a +YAML::Stream+ object containing all
# loaded documents.
#
def self.load_stream( io )
d = nil
parser.load_documents( io ) do |doc|
d = Stream.new if not d
d.add( doc )
end
return d
end
#
# Returns a YAML stream containing each of the items in +objs+,
# each having their own document.
#
# YAML.dump_stream( 0, [], {} )
# #=> --- 0
# --- []
# --- {}
#
def self.dump_stream( *objs )
d = Stream.new
objs.each do |doc|
d.add( doc )
end
d.emit
end
#
# Add a global handler for a YAML domain type.
#
def self.add_domain_type( domain, type_tag, &transfer_proc )
resolver.add_type( "tag:#{ domain }:#{ type_tag }", transfer_proc )
end
#
# Add a transfer method for a builtin type
#
def self.add_builtin_type( type_tag, &transfer_proc )
resolver.add_type( "tag:yaml.org,2002:#{ type_tag }", transfer_proc )
end
#
# Add a transfer method for a builtin type
#
def self.add_ruby_type( type_tag, &transfer_proc )
warn "#{caller[0]}: YAML.add_ruby_type is deprecated, use add_domain_type" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
resolver.add_type( "tag:ruby.yaml.org,2002:#{ type_tag }", transfer_proc )
end
#
# Add a private document type
#
def self.add_private_type( type_re, &transfer_proc )
warn "#{caller[0]}: YAML.add_private_type is deprecated, use add_domain_type" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
resolver.add_type( "x-private:" + type_re, transfer_proc )
end
#
# Detect typing of a string
#
def self.detect_implicit( val )
warn "#{caller[0]}: YAML.detect_implicit is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
resolver.detect_implicit( val )
end
#
# Convert a type_id to a taguri
#
def self.tagurize( val )
warn "#{caller[0]}: YAML.tagurize is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
resolver.tagurize( val )
end
#
# Apply a transfer method to a Ruby object
#
def self.transfer( type_id, obj )
warn "#{caller[0]}: YAML.transfer is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
resolver.transfer( tagurize( type_id ), obj )
end
#
# Apply any implicit a node may qualify for
#
def self.try_implicit( obj )
warn "#{caller[0]}: YAML.try_implicit is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
transfer( detect_implicit( obj ), obj )
end
#
# Method to extract colon-seperated type and class, returning
# the type and the constant of the class
#
def self.read_type_class( type, obj_class )
warn "#{caller[0]}: YAML.read_type_class is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
type, tclass = type.split( ':', 4 ).last(2)
tclass.split( "::" ).each { |c| obj_class = obj_class.const_get( c ) } if tclass
return [ type, obj_class ]
end
#
# Allocate blank object
#
def self.object_maker( obj_class, val )
warn "#{caller[0]}: YAML.object_maker is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
if Hash === val
o = obj_class.allocate
val.each_pair { |k,v|
o.instance_variable_set("@#{k}", v)
}
o
else
raise Error, "Invalid object explicitly tagged !ruby/Object: " + val.inspect
end
end
#
# Allocate an Emitter if needed
#
def self.quick_emit( oid, opts = {}, &e )
warn "#{caller[0]}: YAML.quick_emit is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
out =
if opts.is_a? Emitter
opts
else
emitter.reset( opts )
end
out.emit( oid, &e )
end
end
module Kernel
#
# ryan:: You know how Kernel.p is a really convenient way to dump ruby
# structures? The only downside is that it's not as legible as
# YAML.
#
# _why:: (listening)
#
# ryan:: I know you don't want to urinate all over your users' namespaces.
# But, on the other hand, convenience of dumping for debugging is,
# IMO, a big YAML use case.
#
# _why:: Go nuts! Have a pony parade!
#
# ryan:: Either way, I certainly will have a pony parade.
#
# Prints any supplied _objects_ out in YAML. Intended as
# a variation on +Kernel::p+.
#
# S = Struct.new(:name, :state)
# s = S['dave', 'TX']
# y s
#
# _produces:_
#
# --- !ruby/struct:S
# name: dave
# state: TX
#
def y( object, *objects )
objects.unshift object
puts( if objects.length == 1
YAML.dump( *objects )
else
YAML.dump_stream( *objects )
end )
end
private :y
end

View file

@ -1,242 +0,0 @@
#
# BaseEmitter
#
require 'syck/constants'
require 'syck/encoding'
require 'syck/error'
module Syck
module BaseEmitter
def options( opt = nil )
if opt
@options[opt] || DEFAULTS[opt]
else
@options
end
end
def options=( opt )
@options = opt
end
#
# Emit binary data
#
def binary_base64( value )
self << "!binary "
self.node_text( [value].pack("m"), '|' )
end
#
# Emit plain, normal flowing text
#
def node_text( value, block = nil )
@seq_map = false
valx = value.dup
unless block
block =
if options(:UseBlock)
'|'
elsif not options(:UseFold) and valx =~ /\n[ \t]/ and not valx =~ /#{ESCAPE_CHAR}/
'|'
else
'>'
end
indt = $&.to_i if block =~ /\d+/
if valx =~ /(\A\n*[ \t#]|^---\s+)/
indt = options(:Indent) unless indt.to_i > 0
block += indt.to_s
end
block +=
if valx =~ /\n\Z\n/
"+"
elsif valx =~ /\Z\n/
""
else
"-"
end
end
block += "\n"
if block[0] == ?"
esc_skip = ( "\t\n" unless valx =~ /^[ \t]/ ) || ""
valx = fold( Syck.escape( valx, esc_skip ) + "\"" ).chomp
self << '"' + indent_text( valx, indt, false )
else
if block[0] == ?>
valx = fold( valx )
end
#p [block, indt]
self << block + indent_text( valx, indt )
end
end
#
# Emit a simple, unqouted string
#
def simple( value )
@seq_map = false
self << value.to_s
end
#
# Emit double-quoted string
#
def double( value )
"\"#{Syck.escape( value )}\""
end
#
# Emit single-quoted string
#
def single( value )
"'#{value}'"
end
#
# Write a text block with the current indent
#
def indent_text( text, mod, first_line = true )
return "" if text.to_s.empty?
spacing = indent( mod )
text = text.gsub( /\A([^\n])/, "#{ spacing }\\1" ) if first_line
return text.gsub( /\n^([^\n])/, "\n#{spacing}\\1" )
end
#
# Write a current indent
#
def indent( mod = nil )
#p [ self.id, level, mod, :INDENT ]
if level <= 0
mod ||= 0
else
mod ||= options(:Indent)
mod += ( level - 1 ) * options(:Indent)
end
return " " * mod
end
#
# Add indent to the buffer
#
def indent!
self << indent
end
#
# Folding paragraphs within a column
#
def fold( value )
value.gsub( /(^[ \t]+.*$)|(\S.{0,#{options(:BestWidth) - 1}})(?:[ \t]+|(\n+(?=[ \t]|\Z))|$)/ ) do
$1 || $2 + ( $3 || "\n" )
end
end
#
# Quick mapping
#
def map( type, &e )
val = Mapping.new
e.call( val )
self << "#{type} " if type.length.nonzero?
#
# Empty hashes
#
if val.length.zero?
self << "{}"
@seq_map = false
else
# FIXME
# if @buffer.length == 1 and options(:UseHeader) == false and type.length.zero?
# @headless = 1
# end
defkey = @options.delete( :DefaultKey )
if defkey
seq_map_shortcut
self << "= : "
defkey.to_yaml( :Emitter => self )
end
#
# Emit the key and value
#
val.each { |v|
seq_map_shortcut
if v[0].is_complex_yaml?
self << "? "
end
v[0].to_yaml( :Emitter => self )
if v[0].is_complex_yaml?
self << "\n"
indent!
end
self << ": "
v[1].to_yaml( :Emitter => self )
}
end
end
def seq_map_shortcut
# FIXME: seq_map needs to work with the new anchoring system
# if @seq_map
# @anchor_extras[@buffer.length - 1] = "\n" + indent
# @seq_map = false
# else
self << "\n"
indent!
# end
end
#
# Quick sequence
#
def seq( type, &e )
@seq_map = false
val = Sequence.new
e.call( val )
self << "#{type} " if type.length.nonzero?
#
# Empty arrays
#
if val.length.zero?
self << "[]"
else
# FIXME
# if @buffer.length == 1 and options(:UseHeader) == false and type.length.zero?
# @headless = 1
# end
#
# Emit the key and value
#
val.each { |v|
self << "\n"
indent!
self << "- "
@seq_map = true if v.class == Hash
v.to_yaml( :Emitter => self )
}
end
end
end
#
# Emitter helper classes
#
class Mapping < Array
def add( k, v )
push [k, v]
end
end
class Sequence < Array
def add( v )
push v
end
end
end

View file

@ -1,222 +0,0 @@
#
# YAML::BaseNode class
#
module Syck
#
# YAML Generic Model container
#
module BaseNode
#
# Search for YPath entry and return
# qualified nodes.
#
def select( ypath_str )
warn "#{caller[0]}: select is deprecated" if $VERBOSE
matches = match_path( ypath_str )
#
# Create a new generic view of the elements selected
#
if matches
result = []
matches.each { |m|
result.push m.last
}
Syck.transfer( 'seq', result )
end
end
#
# Search for YPath entry and return
# transformed nodes.
#
def select!( ypath_str )
warn "#{caller[0]}: select!() is deprecated" if $VERBOSE
matches = match_path( ypath_str )
#
# Create a new generic view of the elements selected
#
if matches
result = []
matches.each { |m|
result.push m.last.transform
}
result
end
end
#
# Search for YPath entry and return a list of
# qualified paths.
#
def search( ypath_str )
warn "#{caller[0]}: search() is deprecated" if $VERBOSE
matches = match_path( ypath_str )
if matches
matches.collect { |m|
path = []
m.each_index { |i|
path.push m[i] if ( i % 2 ).zero?
}
"/" + path.compact.join( "/" )
}
end
end
def at( seg )
warn "#{caller[0]}: at() is deprecated" if $VERBOSE
if Hash === @value
self[seg]
elsif Array === @value and seg =~ /\A\d+\Z/ and @value[seg.to_i]
@value[seg.to_i]
end
end
#
# YPath search returning a complete depth array
#
def match_path( ypath_str )
warn "#{caller[0]}: match_path is deprecated" if $VERBOSE
require 'syck/ypath'
matches = []
YPath.each_path( ypath_str ) do |ypath|
seg = match_segment( ypath, 0 )
matches += seg if seg
end
matches.uniq
end
#
# Search a node for a single YPath segment
#
def match_segment( ypath, depth )
warn "#{caller[0]}: match_segment is deprecated" if $VERBOSE
deep_nodes = []
seg = ypath.segments[ depth ]
if seg == "/"
unless String === @value
idx = -1
@value.collect { |v|
idx += 1
if Hash === @value
match_init = [v[0].transform, v[1]]
match_deep = v[1].match_segment( ypath, depth )
else
match_init = [idx, v]
match_deep = v.match_segment( ypath, depth )
end
if match_deep
match_deep.each { |m|
deep_nodes.push( match_init + m )
}
end
}
end
depth += 1
seg = ypath.segments[ depth ]
end
match_nodes =
case seg
when "."
[[nil, self]]
when ".."
[["..", nil]]
when "*"
if @value.is_a? Enumerable
idx = -1
@value.collect { |h|
idx += 1
if Hash === @value
[h[0].transform, h[1]]
else
[idx, h]
end
}
end
else
if seg =~ /^"(.*)"$/
seg = $1
elsif seg =~ /^'(.*)'$/
seg = $1
end
if ( v = at( seg ) )
[[ seg, v ]]
end
end
return deep_nodes unless match_nodes
pred = ypath.predicates[ depth ]
if pred
case pred
when /^\.=/
pred = $' # '
match_nodes.reject! { |n|
n.last.value != pred
}
else
match_nodes.reject! { |n|
n.last.at( pred ).nil?
}
end
end
return match_nodes + deep_nodes unless ypath.segments.length > depth + 1
#puts "DEPTH: #{depth + 1}"
deep_nodes = []
match_nodes.each { |n|
if n[1].is_a? BaseNode
match_deep = n[1].match_segment( ypath, depth + 1 )
if match_deep
match_deep.each { |m|
deep_nodes.push( n + m )
}
end
else
deep_nodes = []
end
}
deep_nodes = nil if deep_nodes.length == 0
deep_nodes
end
#
# We want the node to act like as Hash
# if it is.
#
def []( *key )
if Hash === @value
v = @value.detect { |k,| k.transform == key.first }
v[1] if v
elsif Array === @value
@value.[]( *key )
end
end
def children
if Hash === @value
@value.values.collect { |c| c[1] }
elsif Array === @value
@value
end
end
def children_with_index
warn "#{caller[0]}: children_with_index is deprecated, use children" if $VERBOSE
if Hash === @value
@value.keys.collect { |i| [self[i], i] }
elsif Array === @value
i = -1; @value.collect { |v| i += 1; [v, i] }
end
end
def emit
transform.to_yaml
end
end
end

View file

@ -1,45 +0,0 @@
#
# Constants used throughout the library
#
module Syck
#
# Constants
#
VERSION = '0.60'
SUPPORTED_YAML_VERSIONS = ['1.0']
#
# Parser tokens
#
WORD_CHAR = 'A-Za-z0-9'
PRINTABLE_CHAR = '-_A-Za-z0-9!?/()$\'". '
NOT_PLAIN_CHAR = '\x7f\x0-\x1f\x80-\x9f'
ESCAPE_CHAR = '[\\x00-\\x09\\x0b-\\x1f]'
INDICATOR_CHAR = '*&!|\\\\^@%{}[]='
SPACE_INDICATORS = '-#:,?'
RESTRICTED_INDICATORS = '#:,}]'
DNS_COMP_RE = "\\w(?:[-\\w]*\\w)?"
DNS_NAME_RE = "(?:(?:#{DNS_COMP_RE}\\.)+#{DNS_COMP_RE}|#{DNS_COMP_RE})"
ESCAPES = %w{\x00 \x01 \x02 \x03 \x04 \x05 \x06 \a
\x08 \t \n \v \f \r \x0e \x0f
\x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17
\x18 \x19 \x1a \e \x1c \x1d \x1e \x1f
}
UNESCAPES = {
'a' => "\x07", 'b' => "\x08", 't' => "\x09",
'n' => "\x0a", 'v' => "\x0b", 'f' => "\x0c",
'r' => "\x0d", 'e' => "\x1b", '\\' => '\\',
}
#
# Default settings
#
DEFAULTS = {
:Indent => 2, :UseHeader => false, :UseVersion => false, :Version => '1.0',
:SortKeys => false, :AnchorFormat => 'id%03d', :ExplicitTypes => false,
:WidthType => 'absolute', :BestWidth => 80,
:UseBlock => false, :UseFold => false, :Encoding => :None
}
end

View file

@ -1,35 +0,0 @@
#
# Handle Unicode-to-Internal conversion
#
module Syck
#
# Escape the string, condensing common escapes
#
def self.escape( value, skip = "" )
warn "#{caller[0]}: YAML.escape is deprecated" if $VERBOSE
value.gsub( /\\/, "\\\\\\" ).
gsub( /"/, "\\\"" ).
gsub( /([\x00-\x1f])/ ) do
skip[$&] || ESCAPES[ $&.unpack("C")[0] ]
end
end
#
# Unescape the condenses escapes
#
def self.unescape( value )
warn "#{caller[0]}: YAML.unescape is deprecated" if $VERBOSE
value.gsub( /\\(?:([nevfbart\\])|0?x([0-9a-fA-F]{2})|u([0-9a-fA-F]{4}))/ ) {
if $3
["#$3".hex ].pack('U*')
elsif $2
[$2].pack( "H2" )
else
UNESCAPES[$1]
end
}
end
end

View file

@ -1,34 +0,0 @@
#
# Error messages and exception class
#
module Syck
#
# Error messages
#
ERROR_NO_HEADER_NODE = "With UseHeader=false, the node Array or Hash must have elements"
ERROR_NEED_HEADER = "With UseHeader=false, the node must be an Array or Hash"
ERROR_BAD_EXPLICIT = "Unsupported explicit transfer: '%s'"
ERROR_MANY_EXPLICIT = "More than one explicit transfer"
ERROR_MANY_IMPLICIT = "More than one implicit request"
ERROR_NO_ANCHOR = "No anchor for alias '%s'"
ERROR_BAD_ANCHOR = "Invalid anchor: %s"
ERROR_MANY_ANCHOR = "More than one anchor"
ERROR_ANCHOR_ALIAS = "Can't define both an anchor and an alias"
ERROR_BAD_ALIAS = "Invalid alias: %s"
ERROR_MANY_ALIAS = "More than one alias"
ERROR_ZERO_INDENT = "Can't use zero as an indentation width"
ERROR_UNSUPPORTED_VERSION = "This release of YAML.rb does not support YAML version %s"
ERROR_UNSUPPORTED_ENCODING = "Attempt to use unsupported encoding: %s"
#
# YAML Error classes
#
class Error < StandardError; end
class ParseError < Error; end
class TypeError < StandardError; end
end

View file

@ -1,14 +0,0 @@
#
# YAML::Loader class
# .. type handling ..
#
module Syck
class Loader
TRANSFER_DOMAINS = {
'yaml.org,2002' => {},
'ruby.yaml.org,2002' => {}
}
PRIVATE_TYPES = {}
IMPLICIT_TYPES = [ 'null', 'bool', 'time', 'int', 'float' ]
end
end

View file

@ -1,467 +0,0 @@
# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4
require 'date'
class Class
def to_yaml( opts = {} )
raise TypeError, "can't dump anonymous class %s" % self.class
end
end
class Object
yaml_as "tag:ruby.yaml.org,2002:object"
def to_yaml_style; end
undef to_yaml_properties rescue nil
def to_yaml_properties; instance_variables.sort; end
def to_yaml( opts = {} )
YAML::quick_emit( self, opts ) do |out|
out.map( taguri, to_yaml_style ) do |map|
to_yaml_properties.each do |m|
map.add( m[1..-1], instance_variable_get( m ) )
end
end
end
end
alias :syck_to_yaml :to_yaml
end
class Hash
yaml_as "tag:ruby.yaml.org,2002:hash"
yaml_as "tag:yaml.org,2002:map"
def yaml_initialize( tag, val )
if Array === val
update Hash.[]( *val ) # Convert the map to a sequence
elsif Hash === val
update val
else
raise YAML::TypeError, "Invalid map explicitly tagged #{ tag }: " + val.inspect
end
end
def to_yaml( opts = {} )
return super unless YAML::ENGINE.syck?
YAML::quick_emit( self, opts ) do |out|
out.map( taguri, to_yaml_style ) do |map|
each do |k, v|
map.add( k, v )
end
end
end
end
end
class Struct
yaml_as "tag:ruby.yaml.org,2002:struct"
def self.yaml_tag_class_name; self.name.gsub( "Struct::", "" ); end
def self.yaml_tag_read_class( name ); "Struct::#{ name }"; end
def self.yaml_new( klass, tag, val )
if Hash === val
struct_type = nil
#
# Use existing Struct if it exists
#
props = {}
val.delete_if { |k,v| props[k] = v if k =~ /^@/ }
begin
struct_type = YAML.read_type_class( tag, Struct ).last
rescue NameError
end
if not struct_type
struct_def = [ tag.split( ':', 4 ).last ]
struct_type = Struct.new( *struct_def.concat( val.keys.collect { |k| k.intern } ) )
end
#
# Set the Struct properties
#
st = YAML::object_maker( struct_type, {} )
st.members.each do |m|
st.send( "#{m}=", val[m.to_s] )
end
props.each do |k,v|
st.instance_variable_set(k, v)
end
st
else
raise YAML::TypeError, "Invalid Ruby Struct: " + val.inspect
end
end
def to_yaml( opts = {} )
return super unless YAML::ENGINE.syck?
YAML::quick_emit( self, opts ) do |out|
#
# Basic struct is passed as a YAML map
#
out.map( taguri, to_yaml_style ) do |map|
self.members.each do |m|
map.add( m.to_s, self[m.to_s] )
end
self.to_yaml_properties.each do |m|
map.add( m, instance_variable_get( m ) )
end
end
end
end
end
class Array
yaml_as "tag:ruby.yaml.org,2002:array"
yaml_as "tag:yaml.org,2002:seq"
def yaml_initialize( tag, val ); concat( val.to_a ); end
def to_yaml( opts = {} )
return super unless YAML::ENGINE.syck?
YAML::quick_emit( self, opts ) do |out|
out.seq( taguri, to_yaml_style ) do |seq|
each do |x|
seq.add( x )
end
end
end
end
end
class Exception
yaml_as "tag:ruby.yaml.org,2002:exception"
def Exception.yaml_new( klass, tag, val )
o = klass.allocate
Exception.instance_method(:initialize).bind(o).call(val.delete('message'))
val.each_pair do |k,v|
o.instance_variable_set("@#{k}", v)
end
o
end
def to_yaml( opts = {} )
return super unless YAML::ENGINE.syck?
YAML::quick_emit( self, opts ) do |out|
out.map( taguri, to_yaml_style ) do |map|
map.add( 'message', message )
to_yaml_properties.each do |m|
map.add( m[1..-1], instance_variable_get( m ) )
end
end
end
end
end
class String
yaml_as "tag:ruby.yaml.org,2002:string"
yaml_as "tag:yaml.org,2002:binary"
yaml_as "tag:yaml.org,2002:str"
def is_complex_yaml?
to_yaml_style or not to_yaml_properties.empty? or self =~ /\n.+/
end
def is_binary_data?
self.count("\x00-\x7F", "^ -~\t\r\n").fdiv(self.size) > 0.3 || self.index("\x00") unless self.empty?
end
def String.yaml_new( klass, tag, val )
val = val.unpack("m")[0] if tag == "tag:yaml.org,2002:binary"
val = { 'str' => val } if String === val
if Hash === val
s = klass.allocate
# Thank you, NaHi
String.instance_method(:initialize).
bind(s).
call( val.delete( 'str' ) )
val.each { |k,v| s.instance_variable_set( k, v ) }
s
else
raise YAML::TypeError, "Invalid String: " + val.inspect
end
end
def to_yaml( opts = {} )
return super unless YAML::ENGINE.syck?
YAML::quick_emit( is_complex_yaml? ? self : nil, opts ) do |out|
if is_binary_data?
out.scalar( "tag:yaml.org,2002:binary", [self].pack("m"), :literal )
elsif to_yaml_properties.empty?
out.scalar( taguri, self, self =~ /^:/ ? :quote2 : to_yaml_style )
else
out.map( taguri, to_yaml_style ) do |map|
map.add( 'str', "#{self}" )
to_yaml_properties.each do |m|
map.add( m, instance_variable_get( m ) )
end
end
end
end
end
end
class Symbol
yaml_as "tag:ruby.yaml.org,2002:symbol"
yaml_as "tag:ruby.yaml.org,2002:sym"
def Symbol.yaml_new( klass, tag, val )
if String === val
val = YAML::load( val ) if val =~ /\A(["']).*\1\z/
val.intern
else
raise YAML::TypeError, "Invalid Symbol: " + val.inspect
end
end
def to_yaml( opts = {} )
return super unless YAML::ENGINE.syck?
YAML::quick_emit( nil, opts ) do |out|
out.scalar( "tag:yaml.org,2002:str", self.inspect, :plain )
end
end
end
class Range
yaml_as "tag:ruby.yaml.org,2002:range"
def Range.yaml_new( klass, tag, val )
inr = %r'(\w+|[+-]?\d+(?:\.\d+)?(?:e[+-]\d+)?|"(?:[^\\"]|\\.)*")'
opts = {}
if String === val and val =~ /^#{inr}(\.{2,3})#{inr}$/o
r1, rdots, r2 = $1, $2, $3
opts = {
'begin' => YAML.load( "--- #{r1}" ),
'end' => YAML.load( "--- #{r2}" ),
'excl' => rdots.length == 3
}
val = {}
elsif Hash === val
opts['begin'] = val.delete('begin')
opts['end'] = val.delete('end')
opts['excl'] = val.delete('excl')
end
if Hash === opts
r = YAML::object_maker( klass, {} )
# Thank you, NaHi
Range.instance_method(:initialize).
bind(r).
call( opts['begin'], opts['end'], opts['excl'] )
val.each { |k,v| r.instance_variable_set( k, v ) }
r
else
raise YAML::TypeError, "Invalid Range: " + val.inspect
end
end
def to_yaml( opts = {} )
return super unless YAML::ENGINE.syck?
YAML::quick_emit( self, opts ) do |out|
# if self.begin.is_complex_yaml? or self.begin.respond_to? :to_str or
# self.end.is_complex_yaml? or self.end.respond_to? :to_str or
# not to_yaml_properties.empty?
out.map( taguri, to_yaml_style ) do |map|
map.add( 'begin', self.begin )
map.add( 'end', self.end )
map.add( 'excl', self.exclude_end? )
to_yaml_properties.each do |m|
map.add( m, instance_variable_get( m ) )
end
end
# else
# out.scalar( taguri ) do |sc|
# sc.embed( self.begin )
# sc.concat( self.exclude_end? ? "..." : ".." )
# sc.embed( self.end )
# end
# end
end
end
end
class Regexp
yaml_as "tag:ruby.yaml.org,2002:regexp"
def Regexp.yaml_new( klass, tag, val )
if String === val and val =~ /^\/(.*)\/([mixn]*)$/
val = { 'regexp' => $1, 'mods' => $2 }
end
if Hash === val
mods = nil
unless val['mods'].to_s.empty?
mods = 0x00
mods |= Regexp::EXTENDED if val['mods'].include?( 'x' )
mods |= Regexp::IGNORECASE if val['mods'].include?( 'i' )
mods |= Regexp::MULTILINE if val['mods'].include?( 'm' )
mods |= Regexp::NOENCODING if val['mods'].include?( 'n' )
end
val.delete( 'mods' )
r = YAML::object_maker( klass, {} )
Regexp.instance_method(:initialize).
bind(r).
call( val.delete( 'regexp' ), mods )
val.each { |k,v| r.instance_variable_set( k, v ) }
r
else
raise YAML::TypeError, "Invalid Regular expression: " + val.inspect
end
end
def to_yaml( opts = {} )
return super unless YAML::ENGINE.syck?
YAML::quick_emit( nil, opts ) do |out|
if to_yaml_properties.empty?
out.scalar( taguri, self.inspect, :plain )
else
out.map( taguri, to_yaml_style ) do |map|
src = self.inspect
if src =~ /\A\/(.*)\/([a-z]*)\Z/
map.add( 'regexp', $1 )
map.add( 'mods', $2 )
else
raise YAML::TypeError, "Invalid Regular expression: " + src
end
to_yaml_properties.each do |m|
map.add( m, instance_variable_get( m ) )
end
end
end
end
end
end
class Time
yaml_as "tag:ruby.yaml.org,2002:time"
yaml_as "tag:yaml.org,2002:timestamp"
def Time.yaml_new( klass, tag, val )
if Hash === val
t = val.delete( 'at' )
val.each { |k,v| t.instance_variable_set( k, v ) }
t
else
raise YAML::TypeError, "Invalid Time: " + val.inspect
end
end
def to_yaml( opts = {} )
return super unless YAML::ENGINE.syck?
YAML::quick_emit( self, opts ) do |out|
tz = "Z"
# from the tidy Tobias Peters <t-peters@gmx.de> Thanks!
unless self.utc?
utc_same_instant = self.dup.utc
utc_same_writing = Time.utc(year,month,day,hour,min,sec,usec)
difference_to_utc = utc_same_writing - utc_same_instant
if (difference_to_utc < 0)
difference_sign = '-'
absolute_difference = -difference_to_utc
else
difference_sign = '+'
absolute_difference = difference_to_utc
end
difference_minutes = (absolute_difference/60).round
tz = "%s%02d:%02d" % [ difference_sign, difference_minutes / 60, difference_minutes % 60]
end
standard = self.strftime( "%Y-%m-%d %H:%M:%S" )
standard += ".%06d" % [usec] if usec.nonzero?
standard += " %s" % [tz]
if to_yaml_properties.empty?
out.scalar( taguri, standard, :plain )
else
out.map( taguri, to_yaml_style ) do |map|
map.add( 'at', standard )
to_yaml_properties.each do |m|
map.add( m, instance_variable_get( m ) )
end
end
end
end
end
end
class Date
yaml_as "tag:yaml.org,2002:timestamp#ymd"
def to_yaml( opts = {} )
return super unless YAML::ENGINE.syck?
YAML::quick_emit( self, opts ) do |out|
out.scalar( "tag:yaml.org,2002:timestamp", self.to_s, :plain )
end
end
end
class Integer
yaml_as "tag:yaml.org,2002:int"
def to_yaml( opts = {} )
return super unless YAML::ENGINE.syck?
YAML::quick_emit( nil, opts ) do |out|
out.scalar( "tag:yaml.org,2002:int", self.to_s, :plain )
end
end
end
class Float
yaml_as "tag:yaml.org,2002:float"
def to_yaml( opts = {} )
return super unless YAML::ENGINE.syck?
YAML::quick_emit( nil, opts ) do |out|
str = self.to_s
if str == "Infinity"
str = ".Inf"
elsif str == "-Infinity"
str = "-.Inf"
elsif str == "NaN"
str = ".NaN"
end
out.scalar( "tag:yaml.org,2002:float", str, :plain )
end
end
end
class Rational
yaml_as "tag:ruby.yaml.org,2002:object:Rational"
def Rational.yaml_new( klass, tag, val )
if val.is_a? String
Rational( val )
else
Rational( val['numerator'], val['denominator'] )
end
end
def to_yaml( opts = {} )
return super unless YAML::ENGINE.syck?
YAML::quick_emit( self, opts ) do |out|
out.map( taguri, nil ) do |map|
map.add( 'denominator', denominator )
map.add( 'numerator', numerator )
end
end
end
end
class Complex
yaml_as "tag:ruby.yaml.org,2002:object:Complex"
def Complex.yaml_new( klass, tag, val )
if val.is_a? String
Complex( val )
else
Complex( val['real'], val['image'] )
end
end
def to_yaml( opts = {} )
return super unless YAML::ENGINE.syck?
YAML::quick_emit( self, opts ) do |out|
out.map( taguri, nil ) do |map|
map.add( 'image', imaginary )
map.add( 'real', real )
end
end
end
end
class TrueClass
yaml_as "tag:yaml.org,2002:bool#yes"
def to_yaml( opts = {} )
return super unless YAML::ENGINE.syck?
YAML::quick_emit( nil, opts ) do |out|
out.scalar( taguri, "true", :plain )
end
end
end
class FalseClass
yaml_as "tag:yaml.org,2002:bool#no"
def to_yaml( opts = {} )
return super unless YAML::ENGINE.syck?
YAML::quick_emit( nil, opts ) do |out|
out.scalar( taguri, "false", :plain )
end
end
end
class NilClass
yaml_as "tag:yaml.org,2002:null"
def to_yaml( opts = {} )
return super unless YAML::ENGINE.syck?
YAML::quick_emit( nil, opts ) do |out|
out.scalar( taguri, "", :plain )
end
end
end

View file

@ -1,41 +0,0 @@
module Syck
#
# YAML::Stream -- for emitting many documents
#
class Stream
attr_accessor :documents, :options
def initialize( opts = {} )
@options = opts
@documents = []
end
def []( i )
@documents[ i ]
end
def add( doc )
@documents << doc
end
def edit( doc_num, doc )
warn "#{caller[0]}: edit is deprecated" if $VERBOSE
@documents[ doc_num ] = doc
end
def emit( io = nil )
# opts = @options.dup
# opts[:UseHeader] = true if @documents.length > 1
out = Syck.emitter
out.reset( io || io2 = StringIO.new )
@documents.each { |v|
v.to_yaml( out )
}
io || ( io2.rewind; io2.read )
end
end
end

View file

@ -1,85 +0,0 @@
warn "#{caller[0]}: yaml/stringio is deprecated" if $VERBOSE
#
# Limited StringIO if no core lib is available
#
begin
require 'stringio'
rescue LoadError
# StringIO based on code by MoonWolf
class StringIO
def initialize(string="")
@string=string
@pos=0
@eof=(string.size==0)
end
def pos
@pos
end
def eof
@eof
end
alias eof? eof
def readline(rs=$/)
if @eof
raise EOFError
else
if p = @string[@pos..-1]=~rs
line = @string[@pos,p+1]
else
line = @string[@pos..-1]
end
@pos+=line.size
@eof =true if @pos==@string.size
$_ = line
end
end
def rewind
seek(0,0)
end
def seek(offset,whence)
case whence
when 0
@pos=offset
when 1
@pos+=offset
when 2
@pos=@string.size+offset
end
@eof=(@pos>=@string.size)
0
end
end
#
# Class method for creating streams
#
def Syck.make_stream( io )
if String === io
io = StringIO.new( io )
elsif not IO === io
raise Syck::Error, "YAML stream must be an IO or String object."
end
if Syck::unicode
def io.readline
Syck.utf_to_internal( readline( @ln_sep ), @utf_encoding )
end
def io.check_unicode
@utf_encoding = Syck.sniff_encoding( read( 4 ) )
@ln_sep = Syck.enc_separator( @utf_encoding )
seek( -4, IO::SEEK_CUR )
end
def io.utf_encoding
@utf_encoding
end
io.check_unicode
else
def io.utf_encoding
:None
end
end
io
end
end

View file

@ -1,16 +0,0 @@
#
# YAML::Syck module
# .. glues syck and yaml.rb together ..
#
require 'syck/basenode'
module Syck
#
# Mixin BaseNode functionality
#
class Node
include Syck::BaseNode
end
end

View file

@ -1,95 +0,0 @@
# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4
# $Id$
#
# = yaml/tag.rb: methods for associating a taguri to a class.
#
# Author:: why the lucky stiff
#
module Syck
# A dictionary of taguris which map to
# Ruby classes.
@@tagged_classes = {}
#
# Associates a taguri _tag_ with a Ruby class _cls_. The taguri is used to give types
# to classes when loading YAML. Taguris are of the form:
#
# tag:authorityName,date:specific
#
# The +authorityName+ is a domain name or email address. The +date+ is the date the type
# was issued in YYYY or YYYY-MM or YYYY-MM-DD format. The +specific+ is a name for
# the type being added.
#
# For example, built-in YAML types have 'yaml.org' as the +authorityName+ and '2002' as the
# +date+. The +specific+ is simply the name of the type:
#
# tag:yaml.org,2002:int
# tag:yaml.org,2002:float
# tag:yaml.org,2002:timestamp
#
# The domain must be owned by you on the +date+ declared. If you don't own any domains on the
# date you declare the type, you can simply use an e-mail address.
#
# tag:why@ruby-lang.org,2004:notes/personal
#
def self.tag_class( tag, cls )
if @@tagged_classes.has_key? tag
warn "class #{ @@tagged_classes[tag] } held ownership of the #{ tag } tag"
end
@@tagged_classes[tag] = cls
end
# Returns the complete dictionary of taguris, paired with classes. The key for
# the dictionary is the full taguri. The value for each key is the class constant
# associated to that taguri.
#
# YAML.tagged_classes["tag:yaml.org,2002:int"] => Integer
#
def self.tagged_classes
@@tagged_classes
end
end
class Module
# :stopdoc:
# Adds a taguri _tag_ to a class, used when dumping or loading the class
# in YAML. See YAML::tag_class for detailed information on typing and
# taguris.
def syck_yaml_as( tag, sc = true )
verbose, $VERBOSE = $VERBOSE, nil
class_eval <<-"END", __FILE__, __LINE__+1
attr_writer :taguri
def taguri
if respond_to? :to_yaml_type
Syck.tagurize( to_yaml_type[1..-1] )
else
return @taguri if defined?(@taguri) and @taguri
tag = #{ tag.dump }
if self.class.yaml_tag_subclasses? and self.class != Syck.tagged_classes[tag]
tag = "\#{ tag }:\#{ self.class.yaml_tag_class_name }"
end
tag
end
end
def self.yaml_tag_subclasses?; #{ sc ? 'true' : 'false' }; end
END
Syck.tag_class tag, self
ensure
$VERBOSE = verbose
end
remove_method :yaml_as rescue nil
alias :yaml_as :syck_yaml_as
# Transforms the subclass name into a name suitable for display
# in a subclassed tag.
def yaml_tag_class_name
self.name
end
# Transforms the subclass name found in the tag into a Ruby
# constant name.
def yaml_tag_read_class( name )
name
end
# :startdoc:
end

View file

@ -1,192 +0,0 @@
# -*- mode: ruby; ruby-indent-level: 4 -*- vim: sw=4
#
# Classes required by the full core typeset
#
module Syck
#
# Default private type
#
class PrivateType
def self.tag_subclasses?; false; end
verbose, $VERBOSE = $VERBOSE, nil
def initialize( type, val )
@type_id = type; @value = val
@value.taguri = "x-private:#{ @type_id }"
end
def to_yaml( opts = {} )
@value.to_yaml( opts )
end
ensure
$VERBOSE = verbose
end
#
# Default domain type
#
class DomainType
def self.tag_subclasses?; false; end
verbose, $VERBOSE = $VERBOSE, nil
def initialize( domain, type, val )
@domain = domain; @type_id = type; @value = val
@value.taguri = "tag:#{ @domain }:#{ @type_id }"
end
def to_yaml( opts = {} )
@value.to_yaml( opts )
end
ensure
$VERBOSE = verbose
end
#
# Unresolved objects
#
class Object
def self.tag_subclasses?; false; end
def to_yaml( opts = {} )
::Syck.quick_emit( self, opts ) do |out|
out.map( "tag:ruby.yaml.org,2002:object:#{ @class }", to_yaml_style ) do |map|
@ivars.each do |k,v|
map.add( k, v )
end
end
end
end
end
#
# YAML Hash class to support comments and defaults
#
class SpecialHash < ::Hash
attr_accessor :default
def inspect
self.default.to_s
end
def to_s
self.default.to_s
end
def update( h )
if ::Syck::SpecialHash === h
@default = h.default if h.default
end
super( h )
end
def to_yaml( opts = {} )
opts[:DefaultKey] = self.default
super( opts )
end
end
#
# Builtin collection: !omap
#
class Omap < ::Array
yaml_as "tag:yaml.org,2002:omap"
def yaml_initialize( tag, val )
if Array === val
val.each do |v|
if Hash === v
concat( v.to_a ) # Convert the map to a sequence
else
raise ::Syck::Error, "Invalid !omap entry: " + val.inspect
end
end
else
raise ::Syck::Error, "Invalid !omap: " + val.inspect
end
self
end
def self.[]( *vals )
o = Omap.new
0.step( vals.length - 1, 2 ) do |i|
o[vals[i]] = vals[i+1]
end
o
end
def []( k )
self.assoc( k ).to_a[1]
end
def []=( k, *rest )
val, set = rest.reverse
if ( tmp = self.assoc( k ) ) and not set
tmp[1] = val
else
self << [ k, val ]
end
val
end
def has_key?( k )
self.assoc( k ) ? true : false
end
def is_complex_yaml?
true
end
def to_yaml( opts = {} )
::Syck.quick_emit( self, opts ) do |out|
out.seq( taguri, to_yaml_style ) do |seq|
self.each do |v|
seq.add( Hash[ *v ] )
end
end
end
end
end
#
# Builtin collection: !pairs
#
class Pairs < ::Array
yaml_as "tag:yaml.org,2002:pairs"
def yaml_initialize( tag, val )
if Array === val
val.each do |v|
if Hash === v
concat( v.to_a ) # Convert the map to a sequence
else
raise ::Syck::Error, "Invalid !pairs entry: " + val.inspect
end
end
else
raise ::Syck::Error, "Invalid !pairs: " + val.inspect
end
self
end
def self.[]( *vals )
p = Pairs.new
0.step( vals.length - 1, 2 ) { |i|
p[vals[i]] = vals[i+1]
}
p
end
def []( k )
self.assoc( k ).to_a
end
def []=( k, val )
self << [ k, val ]
val
end
def has_key?( k )
self.assoc( k ) ? true : false
end
def is_complex_yaml?
true
end
def to_yaml( opts = {} )
::Syck.quick_emit( self, opts ) do |out|
out.seq( taguri, to_yaml_style ) do |seq|
self.each do |v|
seq.add( Hash[ *v ] )
end
end
end
end
end
#
# Builtin collection: !set
#
class Set < ::Hash
yaml_as "tag:yaml.org,2002:set"
end
end

View file

@ -1,54 +0,0 @@
#
# YAML::YamlNode class
#
require 'syck/basenode'
module Syck
#
# YAML Generic Model container
#
class YamlNode
include BaseNode
attr_accessor :kind, :type_id, :value, :anchor
def initialize(t, v)
@type_id = t
if Hash === v
@kind = 'map'
@value = {}
v.each {|key,val|
@value[key.transform] = [key, val]
}
elsif Array === v
@kind = 'seq'
@value = v
elsif String === v
@kind = 'scalar'
@value = v
end
end
#
# Transform this node fully into a native type
#
def transform
t = nil
if @value.is_a? Hash
t = {}
@value.each { |k,v|
t[ k ] = v[1].transform
}
elsif @value.is_a? Array
t = []
@value.each { |v|
t.push v.transform
}
else
t = @value
end
Syck.transfer_method( @type_id, t )
end
end
end

View file

@ -1,54 +0,0 @@
#
# YAML::YPath
#
warn "#{caller[0]}: YAML::YPath is deprecated" if $VERBOSE
module Syck
class YPath
attr_accessor :segments, :predicates, :flags
def initialize( str )
@segments = []
@predicates = []
@flags = nil
while str =~ /^\/?(\/|[^\/\[]+)(?:\[([^\]]+)\])?/
@segments.push $1
@predicates.push $2
str = $'
end
unless str.to_s.empty?
@segments += str.split( "/" )
end
if @segments.length == 0
@segments.push "."
end
end
def self.each_path( str )
#
# Find choices
#
paths = []
str = "(#{ str })"
while str.sub!( /\(([^()]+)\)/, "\n#{ paths.length }\n" )
paths.push $1.split( '|' )
end
#
# Construct all possible paths
#
all = [ str ]
( paths.length - 1 ).downto( 0 ) do |i|
all = all.collect do |a|
paths[i].collect do |p|
a.gsub( /\n#{ i }\n/, p )
end
end.flatten.uniq
end
all.collect do |path|
yield YPath.new( path )
end
end
end
end

View file

@ -1,14 +0,0 @@
# $Id$
#
# = yaml/syck.rb:
#
require 'stringio'
require 'syck.so'
require 'syck/error'
require 'syck/syck'
require 'syck/tag'
require 'syck/stream'
require 'syck/constants'
require 'syck/rubytypes'
require 'syck/types'

View file

@ -1,407 +0,0 @@
/*
* node.c
*
* $Author$
*
* Copyright (C) 2003 why the lucky stiff
*/
#include "ruby/ruby.h"
#include "syck.h"
/*
* Node allocation functions
*/
SyckNode *
syck_alloc_node( enum syck_kind_tag type )
{
SyckNode *s;
s = S_ALLOC( SyckNode );
s->kind = type;
s->id = 0;
s->type_id = NULL;
s->anchor = NULL;
s->shortcut = NULL;
return s;
}
void
syck_free_node( SyckNode *n )
{
syck_free_members( n );
if ( n->type_id != NULL )
{
S_FREE( n->type_id );
n->type_id = NULL;
}
if ( n->anchor != NULL )
{
S_FREE( n->anchor );
n->anchor = NULL;
}
S_FREE( n );
}
SyckNode *
syck_alloc_map(void)
{
SyckNode *n;
struct SyckMap *m;
m = S_ALLOC( struct SyckMap );
m->style = map_none;
m->idx = 0;
m->capa = ALLOC_CT;
m->keys = S_ALLOC_N( SYMID, m->capa );
m->values = S_ALLOC_N( SYMID, m->capa );
n = syck_alloc_node( syck_map_kind );
n->data.pairs = m;
return n;
}
SyckNode *
syck_alloc_seq(void)
{
SyckNode *n;
struct SyckSeq *s;
s = S_ALLOC( struct SyckSeq );
s->style = seq_none;
s->idx = 0;
s->capa = ALLOC_CT;
s->items = S_ALLOC_N( SYMID, s->capa );
n = syck_alloc_node( syck_seq_kind );
n->data.list = s;
return n;
}
SyckNode *
syck_alloc_str(void)
{
SyckNode *n;
struct SyckStr *s;
s = S_ALLOC( struct SyckStr );
s->len = 0;
s->ptr = NULL;
s->style = scalar_none;
n = syck_alloc_node( syck_str_kind );
n->data.str = s;
return n;
}
SyckNode *
syck_new_str( const char *str, enum scalar_style style )
{
return syck_new_str2( str, strlen( str ), style );
}
SyckNode *
syck_new_str2( const char *str, long len, enum scalar_style style )
{
SyckNode *n;
n = syck_alloc_str();
n->data.str->ptr = S_ALLOC_N( char, len + 1 );
n->data.str->len = len;
n->data.str->style = style;
memcpy( n->data.str->ptr, str, len );
n->data.str->ptr[len] = '\0';
return n;
}
void
syck_replace_str( SyckNode *n, char *str, enum scalar_style style )
{
syck_replace_str2( n, str, strlen( str ), style );
}
void
syck_replace_str2( SyckNode *n, char *str, long len, enum scalar_style style )
{
if ( n->data.str->ptr != NULL )
{
S_FREE( n->data.str->ptr );
n->data.str->ptr = NULL;
n->data.str->len = 0;
}
n->data.str->ptr = S_ALLOC_N( char, len + 1 );
n->data.str->len = len;
n->data.str->style = style;
memcpy( n->data.str->ptr, str, len );
n->data.str->ptr[len] = '\0';
}
void
syck_str_blow_away_commas( SyckNode *n )
{
char *go, *end;
go = n->data.str->ptr;
end = go + n->data.str->len;
while ( *(++go) != '\0' )
{
if ( *go == ',' )
{
n->data.str->len -= 1;
memmove( go, go + 1, end - go );
end -= 1;
}
}
}
char *
syck_str_read( SyckNode *n )
{
ASSERT( n != NULL );
return n->data.str->ptr;
}
SyckNode *
syck_new_map( SYMID key, SYMID value )
{
SyckNode *n;
n = syck_alloc_map();
syck_map_add( n, key, value );
return n;
}
void
syck_map_empty( SyckNode *n )
{
struct SyckMap *m;
ASSERT( n != NULL );
ASSERT( n->data.list != NULL );
S_FREE( n->data.pairs->keys );
S_FREE( n->data.pairs->values );
m = n->data.pairs;
m->idx = 0;
m->capa = ALLOC_CT;
m->keys = S_ALLOC_N( SYMID, m->capa );
m->values = S_ALLOC_N( SYMID, m->capa );
}
void
syck_map_add( SyckNode *map, SYMID key, SYMID value )
{
struct SyckMap *m;
long idx;
ASSERT( map != NULL );
ASSERT( map->data.pairs != NULL );
m = map->data.pairs;
idx = m->idx;
m->idx += 1;
if ( m->idx > m->capa )
{
m->capa += ALLOC_CT;
S_REALLOC_N( m->keys, SYMID, m->capa );
S_REALLOC_N( m->values, SYMID, m->capa );
}
m->keys[idx] = key;
m->values[idx] = value;
}
void
syck_map_update( SyckNode *map1, SyckNode *map2 )
{
struct SyckMap *m1, *m2;
long new_idx, new_capa;
ASSERT( map1 != NULL );
ASSERT( map2 != NULL );
m1 = map1->data.pairs;
m2 = map2->data.pairs;
if ( m2->idx < 1 ) return;
new_idx = m1->idx;
new_idx += m2->idx;
new_capa = m1->capa;
while ( new_idx > new_capa )
{
new_capa += ALLOC_CT;
}
if ( new_capa > m1->capa )
{
m1->capa = new_capa;
S_REALLOC_N( m1->keys, SYMID, m1->capa );
S_REALLOC_N( m1->values, SYMID, m1->capa );
}
for ( new_idx = 0; new_idx < m2->idx; m1->idx++, new_idx++ )
{
m1->keys[m1->idx] = m2->keys[new_idx];
m1->values[m1->idx] = m2->values[new_idx];
}
}
long
syck_map_count( SyckNode *map )
{
ASSERT( map != NULL );
ASSERT( map->data.pairs != NULL );
return map->data.pairs->idx;
}
void
syck_map_assign( SyckNode *map, enum map_part p, long idx, SYMID id )
{
struct SyckMap *m;
ASSERT( map != NULL );
m = map->data.pairs;
ASSERT( m != NULL );
if ( p == map_key )
{
m->keys[idx] = id;
}
else
{
m->values[idx] = id;
}
}
SYMID
syck_map_read( SyckNode *map, enum map_part p, long idx )
{
struct SyckMap *m;
ASSERT( map != NULL );
m = map->data.pairs;
ASSERT( m != NULL );
if ( p == map_key )
{
return m->keys[idx];
}
else
{
return m->values[idx];
}
}
SyckNode *
syck_new_seq( SYMID value )
{
SyckNode *n;
n = syck_alloc_seq();
syck_seq_add( n, value );
return n;
}
void
syck_seq_empty( SyckNode *n )
{
struct SyckSeq *s;
ASSERT( n != NULL );
ASSERT( n->data.list != NULL );
S_FREE( n->data.list->items );
s = n->data.list;
s->idx = 0;
s->capa = ALLOC_CT;
s->items = S_ALLOC_N( SYMID, s->capa );
}
void
syck_seq_add( SyckNode *arr, SYMID value )
{
struct SyckSeq *s;
long idx;
ASSERT( arr != NULL );
ASSERT( arr->data.list != NULL );
s = arr->data.list;
idx = s->idx;
s->idx += 1;
if ( s->idx > s->capa )
{
s->capa += ALLOC_CT;
S_REALLOC_N( s->items, SYMID, s->capa );
}
s->items[idx] = value;
}
long
syck_seq_count( SyckNode *seq )
{
ASSERT( seq != NULL );
ASSERT( seq->data.list != NULL );
return seq->data.list->idx;
}
void
syck_seq_assign( SyckNode *seq, long idx, SYMID id )
{
struct SyckSeq *s;
ASSERT( map != NULL );
s = seq->data.list;
ASSERT( m != NULL );
s->items[idx] = id;
}
SYMID
syck_seq_read( SyckNode *seq, long idx )
{
struct SyckSeq *s;
ASSERT( seq != NULL );
s = seq->data.list;
ASSERT( s != NULL );
return s->items[idx];
}
void
syck_free_members( SyckNode *n )
{
if ( n == NULL ) return;
switch ( n->kind )
{
case syck_str_kind:
if ( n->data.str != NULL )
{
S_FREE( n->data.str->ptr );
n->data.str->ptr = NULL;
n->data.str->len = 0;
S_FREE( n->data.str );
n->data.str = NULL;
}
break;
case syck_seq_kind:
if ( n->data.list != NULL )
{
S_FREE( n->data.list->items );
S_FREE( n->data.list );
n->data.list = NULL;
}
break;
case syck_map_kind:
if ( n->data.pairs != NULL )
{
S_FREE( n->data.pairs->keys );
S_FREE( n->data.pairs->values );
S_FREE( n->data.pairs );
n->data.pairs = NULL;
}
break;
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,524 +0,0 @@
/*
* syck.c
*
* $Author$
*
* Copyright (C) 2003 why the lucky stiff
*/
#include "ruby/ruby.h"
#include <stdio.h>
#include <string.h>
#include "syck.h"
void syck_parser_pop_level( SyckParser * );
/*
* Custom assert
*/
void
syck_assert( const char *file_name, unsigned line_num, const char *expr )
{
fflush( NULL );
fprintf( stderr, "\nAssertion failed: %s, line %u: %s\n",
file_name, line_num, expr );
fflush( stderr );
abort();
}
/*
* Allocates and copies a string
*/
char *
syck_strndup( const char *buf, long len )
{
char *new = S_ALLOC_N( char, len + 1 );
S_MEMZERO( new, char, len + 1 );
S_MEMCPY( new, buf, char, len );
return new;
}
/*
* Default FILE IO function
*/
long
syck_io_file_read( char *buf, SyckIoFile *file, long max_size, long skip )
{
long len = 0;
ASSERT( file != NULL );
max_size -= skip;
len = fread( buf + skip, sizeof( char ), max_size, file->ptr );
len += skip;
buf[len] = '\0';
return len;
}
/*
* Default string IO function
*/
long
syck_io_str_read( char *buf, SyckIoStr *str, long max_size, long skip )
{
char *beg;
long len = 0;
ASSERT( str != NULL );
beg = str->ptr;
if ( max_size >= 0 )
{
max_size -= skip;
if ( max_size <= 0 ) max_size = 0;
else str->ptr += max_size;
if ( str->ptr > str->end )
{
str->ptr = str->end;
}
}
else
{
/* Use exact string length */
while ( str->ptr < str->end ) {
if (*(str->ptr++) == '\n') break;
}
}
if ( beg < str->ptr )
{
len = ( str->ptr - beg );
S_MEMCPY( buf + skip, beg, char, len );
}
len += skip;
buf[len] = '\0';
return len;
}
void
syck_parser_reset_levels( SyckParser *p )
{
while ( p->lvl_idx > 1 )
{
syck_parser_pop_level( p );
}
if ( p->lvl_idx < 1 )
{
p->lvl_idx = 1;
p->levels[0].spaces = -1;
p->levels[0].ncount = 0;
p->levels[0].domain = syck_strndup( "", 0 );
}
p->levels[0].status = syck_lvl_header;
}
void
syck_parser_reset_cursor( SyckParser *p )
{
if ( p->buffer == NULL )
{
p->buffer = S_ALLOC_N( char, p->bufsize );
S_MEMZERO( p->buffer, char, p->bufsize );
}
p->buffer[0] = '\0';
p->cursor = NULL;
p->lineptr = NULL;
p->linectptr = NULL;
p->token = NULL;
p->toktmp = NULL;
p->marker = NULL;
p->limit = NULL;
p->root = 0;
p->root_on_error = 0;
p->linect = 0;
p->eof = 0;
p->last_token = 0;
p->force_token = 0;
}
/*
* Value to return on a parse error
*/
void
syck_parser_set_root_on_error( SyckParser *p, SYMID roer )
{
p->root_on_error = roer;
}
/*
* Allocate the parser
*/
SyckParser *
syck_new_parser(void)
{
SyckParser *p;
p = S_ALLOC( SyckParser );
S_MEMZERO( p, SyckParser, 1 );
p->lvl_capa = ALLOC_CT;
p->levels = S_ALLOC_N( SyckLevel, p->lvl_capa );
p->input_type = syck_yaml_utf8;
p->io_type = syck_io_str;
p->io.str = NULL;
p->syms = NULL;
p->anchors = NULL;
p->bad_anchors = NULL;
p->implicit_typing = 1;
p->taguri_expansion = 0;
p->bufsize = SYCK_BUFFERSIZE;
p->buffer = NULL;
p->lvl_idx = 0;
syck_parser_reset_levels( p );
return p;
}
int
syck_add_sym( SyckParser *p, void *data )
{
SYMID id = 0;
if ( p->syms == NULL )
{
p->syms = st_init_numtable();
}
id = p->syms->num_entries + 1;
st_insert( p->syms, id, (st_data_t)data );
return (int)id;
}
int
syck_lookup_sym( SyckParser *p, SYMID id, void **datap )
{
st_data_t data;
int ret;
if ( p->syms == NULL ) return 0;
ret = st_lookup( p->syms, id, &data );
if(ret) *datap = (void *)data;
return ret;
}
int
syck_st_free_nodes( char *key, SyckNode *n, char *arg )
{
if ( n != (void *)1 ) syck_free_node( n );
n = NULL;
return ST_CONTINUE;
}
void
syck_st_free( SyckParser *p )
{
/*
* Free the anchor tables
*/
if ( p->anchors != NULL )
{
st_foreach( p->anchors, syck_st_free_nodes, 0 );
st_free_table( p->anchors );
p->anchors = NULL;
}
if ( p->bad_anchors != NULL )
{
st_foreach( p->bad_anchors, syck_st_free_nodes, 0 );
st_free_table( p->bad_anchors );
p->bad_anchors = NULL;
}
}
typedef struct {
long hash;
char *buffer;
long length;
long remaining;
int printed;
} bytestring_t;
int
syck_st_free_syms( void *key, bytestring_t *sav, void *dummy )
{
S_FREE(sav->buffer);
S_FREE(sav);
return ST_CONTINUE;
}
void
syck_free_parser( SyckParser *p )
{
/*
* Free the adhoc symbol table
*/
if ( p->syms != NULL )
{
st_foreach( p->syms, syck_st_free_syms, 0 );
st_free_table( p->syms );
p->syms = NULL;
}
/*
* Free tables, levels
*/
syck_st_free( p );
syck_parser_reset_levels( p );
S_FREE( p->levels[0].domain );
S_FREE( p->levels );
if ( p->buffer != NULL )
{
S_FREE( p->buffer );
}
free_any_io( p );
S_FREE( p );
}
void
syck_parser_handler( SyckParser *p, SyckNodeHandler hdlr )
{
ASSERT( p != NULL );
p->handler = hdlr;
}
void
syck_parser_implicit_typing( SyckParser *p, int flag )
{
p->implicit_typing = ( flag == 0 ? 0 : 1 );
}
void
syck_parser_taguri_expansion( SyckParser *p, int flag )
{
p->taguri_expansion = ( flag == 0 ? 0 : 1 );
}
void
syck_parser_error_handler( SyckParser *p, SyckErrorHandler hdlr )
{
ASSERT( p != NULL );
p->error_handler = hdlr;
}
void
syck_parser_bad_anchor_handler( SyckParser *p, SyckBadAnchorHandler hdlr )
{
ASSERT( p != NULL );
p->bad_anchor_handler = hdlr;
}
void
syck_parser_set_input_type( SyckParser *p, enum syck_parser_input input_type )
{
ASSERT( p != NULL );
p->input_type = input_type;
}
void
syck_parser_file( SyckParser *p, FILE *fp, SyckIoFileRead read )
{
ASSERT( p != NULL );
free_any_io( p );
syck_parser_reset_cursor( p );
p->io_type = syck_io_file;
p->io.file = S_ALLOC( SyckIoFile );
p->io.file->ptr = fp;
if ( read != NULL )
{
p->io.file->read = read;
}
else
{
p->io.file->read = syck_io_file_read;
}
}
void
syck_parser_str( SyckParser *p, char *ptr, long len, SyckIoStrRead read )
{
ASSERT( p != NULL );
free_any_io( p );
syck_parser_reset_cursor( p );
p->io_type = syck_io_str;
p->io.str = S_ALLOC( SyckIoStr );
p->io.str->beg = ptr;
p->io.str->ptr = ptr;
p->io.str->end = ptr + len;
if ( read != NULL )
{
p->io.str->read = read;
}
else
{
p->io.str->read = syck_io_str_read;
}
}
void
syck_parser_str_auto( SyckParser *p, char *ptr, SyckIoStrRead read )
{
syck_parser_str( p, ptr, strlen( ptr ), read );
}
SyckLevel *
syck_parser_current_level( SyckParser *p )
{
return &p->levels[p->lvl_idx-1];
}
void
syck_parser_pop_level( SyckParser *p )
{
ASSERT( p != NULL );
/* The root level should never be popped */
if ( p->lvl_idx <= 1 ) return;
p->lvl_idx -= 1;
free( p->levels[p->lvl_idx].domain );
}
void
syck_parser_add_level( SyckParser *p, int len, enum syck_level_status status )
{
ASSERT( p != NULL );
if ( p->lvl_idx + 1 > p->lvl_capa )
{
p->lvl_capa += ALLOC_CT;
S_REALLOC_N( p->levels, SyckLevel, p->lvl_capa );
}
ASSERT( len > p->levels[p->lvl_idx-1].spaces );
p->levels[p->lvl_idx].spaces = len;
p->levels[p->lvl_idx].ncount = 0;
p->levels[p->lvl_idx].domain = syck_strndup( p->levels[p->lvl_idx-1].domain, strlen( p->levels[p->lvl_idx-1].domain ) );
p->levels[p->lvl_idx].status = status;
p->lvl_idx += 1;
}
void
free_any_io( SyckParser *p )
{
ASSERT( p != NULL );
switch ( p->io_type )
{
case syck_io_str:
if ( p->io.str != NULL )
{
S_FREE( p->io.str );
p->io.str = NULL;
}
break;
case syck_io_file:
if ( p->io.file != NULL )
{
S_FREE( p->io.file );
p->io.file = NULL;
}
break;
}
}
long
syck_move_tokens( SyckParser *p )
{
long count, skip;
ASSERT( p->buffer != NULL );
if ( p->token == NULL )
return 0;
skip = p->limit - p->token;
if ( ( count = p->token - p->buffer ) )
{
if (skip > 0)
S_MEMMOVE( p->buffer, p->token, char, skip );
p->token = p->buffer;
p->marker -= count;
p->cursor -= count;
p->toktmp -= count;
p->limit -= count;
p->lineptr -= count;
p->linectptr -= count;
}
return skip;
}
void
syck_check_limit( SyckParser *p, long len )
{
if ( p->cursor == NULL )
{
p->cursor = p->buffer;
p->lineptr = p->buffer;
p->linectptr = p->buffer;
p->marker = p->buffer;
}
p->limit = p->buffer + len;
}
long
syck_parser_read( SyckParser *p )
{
long len = 0;
long skip = 0;
ASSERT( p != NULL );
switch ( p->io_type )
{
case syck_io_str:
skip = syck_move_tokens( p );
len = (p->io.str->read)( p->buffer, p->io.str, SYCK_BUFFERSIZE - 1, skip );
break;
case syck_io_file:
skip = syck_move_tokens( p );
len = (p->io.file->read)( p->buffer, p->io.file, SYCK_BUFFERSIZE - 1, skip );
break;
}
syck_check_limit( p, len );
return len;
}
long
syck_parser_readlen( SyckParser *p, long max_size )
{
long len = 0;
long skip = 0;
ASSERT( p != NULL );
switch ( p->io_type )
{
case syck_io_str:
skip = syck_move_tokens( p );
len = (p->io.str->read)( p->buffer, p->io.str, max_size, skip );
break;
case syck_io_file:
skip = syck_move_tokens( p );
len = (p->io.file->read)( p->buffer, p->io.file, max_size, skip );
break;
}
syck_check_limit( p, len );
return len;
}
SYMID
syck_parse( SyckParser *p )
{
ASSERT( p != NULL );
syck_st_free( p );
syck_parser_reset_levels( p );
syckparse( p );
return p->root;
}
void
syck_default_error_handler( SyckParser *p, const char *msg )
{
printf( "Error at [Line %d, Col %"PRIdPTRDIFF"]: %s\n",
p->linect,
p->cursor - p->lineptr,
msg );
}

View file

@ -1,453 +0,0 @@
/*
* syck.h
*
* $Author$
*
* Copyright (C) 2003 why the lucky stiff
*/
#ifndef SYCK_H
#define SYCK_H
#define SYCK_YAML_MAJOR 1
#define SYCK_YAML_MINOR 0
#define YAML_DOMAIN "yaml.org,2002"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "ruby/st.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*
* Memory Allocation
*/
#if defined(HAVE_ALLOCA_H) && !defined(__GNUC__)
#include <alloca.h>
#endif
#ifdef DEBUG
void syck_assert( const char *, unsigned, const char * );
# define ASSERT(f) \
(( f ) ? (void)0 : syck_assert( __FILE__, __LINE__, #f ))
#else
# define ASSERT(f) ((void)0)
#endif
#ifndef NULL
# define NULL (void *)0
#endif
#define ALLOC_CT 8
#define SYCK_BUFFERSIZE 4096
#define S_ALLOC_N(type,n) (type*)malloc(sizeof(type)*(n))
#define S_ALLOC(type) (type*)malloc(sizeof(type))
#define S_REALLOC_N(var,type,n) (var)=(type*)realloc((char*)(var),sizeof(type)*(n))
#define S_FREE(n) if (n) { free(n); n = NULL; }
#define S_ALLOCA_N(type,n) (type*)alloca(sizeof(type)*(n))
#define S_MEMZERO(p,type,n) memset((p), 0, sizeof(type)*(n))
#define S_MEMCPY(p1,p2,type,n) memcpy((p1), (p2), sizeof(type)*(n))
#define S_MEMMOVE(p1,p2,type,n) memmove((p1), (p2), sizeof(type)*(n))
#define S_MEMCMP(p1,p2,type,n) memcmp((p1), (p2), sizeof(type)*(n))
#define BLOCK_FOLD 10
#define BLOCK_LIT 20
#define BLOCK_PLAIN 30
#define NL_CHOMP 40
#define NL_KEEP 50
/*
* Node definitions
*/
#ifndef ST_DATA_T_DEFINED
typedef long st_data_t;
#endif
#define SYMID st_data_t
typedef struct _syck_node SyckNode;
enum syck_kind_tag {
syck_map_kind,
syck_seq_kind,
syck_str_kind
};
enum map_part {
map_key,
map_value
};
enum map_style {
map_none,
map_inline
};
enum seq_style {
seq_none,
seq_inline
};
enum scalar_style {
scalar_none,
scalar_1quote,
scalar_2quote,
scalar_fold,
scalar_literal,
scalar_plain
};
/*
* Node metadata struct
*/
struct _syck_node {
/* Symbol table ID */
SYMID id;
/* Underlying kind */
enum syck_kind_tag kind;
/* Fully qualified tag-uri for type */
char *type_id;
/* Anchor name */
char *anchor;
union {
/* Storage for map data */
struct SyckMap {
enum map_style style;
SYMID *keys;
SYMID *values;
long capa;
long idx;
} *pairs;
/* Storage for sequence data */
struct SyckSeq {
enum seq_style style;
SYMID *items;
long capa;
long idx;
} *list;
/* Storage for string data */
struct SyckStr {
enum scalar_style style;
char *ptr;
long len;
} *str;
} data;
/* Shortcut node */
void *shortcut;
};
/*
* Parser definitions
*/
typedef struct _syck_parser SyckParser;
typedef struct _syck_file SyckIoFile;
typedef struct _syck_str SyckIoStr;
typedef struct _syck_level SyckLevel;
typedef SYMID (*SyckNodeHandler)(SyckParser *, SyckNode *);
typedef void (*SyckErrorHandler)(SyckParser *, const char *);
typedef SyckNode * (*SyckBadAnchorHandler)(SyckParser *, char *);
typedef long (*SyckIoFileRead)(char *, SyckIoFile *, long, long);
typedef long (*SyckIoStrRead)(char *, SyckIoStr *, long, long);
enum syck_io_type {
syck_io_str,
syck_io_file
};
enum syck_parser_input {
syck_yaml_utf8,
syck_yaml_utf16,
syck_yaml_utf32,
syck_bytecode_utf8
};
enum syck_level_status {
syck_lvl_header,
syck_lvl_doc,
syck_lvl_open,
syck_lvl_seq,
syck_lvl_map,
syck_lvl_block,
syck_lvl_str,
syck_lvl_iseq,
syck_lvl_imap,
syck_lvl_end,
syck_lvl_pause,
syck_lvl_anctag,
syck_lvl_mapx,
syck_lvl_seqx
};
/*
* Parser structs
*/
struct _syck_file {
/* File pointer */
FILE *ptr;
/* Function which FILE -> buffer */
SyckIoFileRead read;
};
struct _syck_str {
/* String buffer pointers */
char *beg, *ptr, *end;
/* Function which string -> buffer */
SyckIoStrRead read;
};
struct _syck_level {
/* Indent */
int spaces;
/* Counts nodes emitted at this level, useful for parsing
* keys and pairs in bytecode */
int ncount;
/* Does node have anchors or tags? */
int anctag;
/* Domain prefixing at the given level */
char *domain;
/* Keeps a node status */
enum syck_level_status status;
};
struct _syck_parser {
/* Root node */
SYMID root, root_on_error;
/* Implicit typing flag */
int implicit_typing, taguri_expansion;
/* Scripting language function to handle nodes */
SyckNodeHandler handler;
/* Error handler */
SyckErrorHandler error_handler;
/* InvalidAnchor handler */
SyckBadAnchorHandler bad_anchor_handler;
/* Parser input type */
enum syck_parser_input input_type;
/* IO type */
enum syck_io_type io_type;
/* Custom buffer size */
size_t bufsize;
/* Buffer pointers */
char *buffer, *linectptr, *lineptr, *toktmp, *token, *cursor, *marker, *limit;
/* Line counter */
int linect;
/* Last token from yylex() */
int last_token;
/* Force a token upon next call to yylex() */
int force_token;
/* EOF flag */
int eof;
union {
SyckIoFile *file;
SyckIoStr *str;
} io;
/* Symbol table for anchors */
st_table *anchors, *bad_anchors;
/* Optional symbol table for SYMIDs */
st_table *syms;
/* Levels of indentation */
SyckLevel *levels;
int lvl_idx;
int lvl_capa;
/* Pointer for extension's use */
void *bonus;
};
/*
* Emitter definitions
*/
typedef struct _syck_emitter SyckEmitter;
typedef struct _syck_emitter_node SyckEmitterNode;
typedef void (*SyckOutputHandler)(SyckEmitter *, char *, long);
typedef void (*SyckEmitterHandler)(SyckEmitter *, st_data_t);
enum doc_stage {
doc_open,
doc_processing
};
/*
* Emitter struct
*/
struct _syck_emitter {
/* Headerless doc flag */
int headless;
/* Force header? */
int use_header;
/* Force version? */
int use_version;
/* Sort hash keys */
int sort_keys;
/* Anchor format */
char *anchor_format;
/* Explicit typing on all collections? */
int explicit_typing;
/* Best width on folded scalars */
int best_width;
/* Use literal[1] or folded[2] blocks on all text? */
enum scalar_style style;
/* Stage of written document */
enum doc_stage stage;
/* Level counter */
int level;
/* Default indentation */
int indent;
/* Object ignore ID */
SYMID ignore_id;
/* Symbol table for anchors */
st_table *markers, *anchors, *anchored;
/* Custom buffer size */
size_t bufsize;
/* Buffer */
char *buffer, *marker;
/* Absolute position of the buffer */
long bufpos;
/* Handler for emitter nodes */
SyckEmitterHandler emitter_handler;
/* Handler for output */
SyckOutputHandler output_handler;
/* Levels of indentation */
SyckLevel *levels;
int lvl_idx;
int lvl_capa;
/* Pointer for extension's use */
void *bonus;
};
/*
* Emitter node metadata struct
*/
struct _syck_emitter_node {
/* Node buffer position */
long pos;
/* Current indent */
long indent;
/* Collection? */
int is_shortcut;
};
/*
* Handler prototypes
*/
SYMID syck_hdlr_add_node( SyckParser *, SyckNode * );
SyckNode *syck_hdlr_add_anchor( SyckParser *, char *, SyckNode * );
void syck_hdlr_remove_anchor( SyckParser *, char * );
SyckNode *syck_hdlr_get_anchor( SyckParser *, char * );
void syck_add_transfer( char *, SyckNode *, int );
char *syck_xprivate( const char *, int );
char *syck_taguri( const char *, const char *, int );
int syck_tagcmp( const char *, const char * );
int syck_add_sym( SyckParser *, void * );
int syck_lookup_sym( SyckParser *, SYMID, void ** );
int syck_try_implicit( SyckNode * );
char *syck_type_id_to_uri( const char * );
void try_tag_implicit( SyckNode *, int );
const char *syck_match_implicit( const char *, size_t );
/*
* API prototypes
*/
char *syck_strndup( const char *, long );
long syck_io_file_read( char *, SyckIoFile *, long, long );
long syck_io_str_read( char *, SyckIoStr *, long, long );
char *syck_base64enc( char *, long );
char *syck_base64dec( char *, long );
SyckEmitter *syck_new_emitter(void);
SYMID syck_emitter_mark_node( SyckEmitter *, st_data_t );
void syck_emitter_ignore_id( SyckEmitter *, SYMID );
void syck_output_handler( SyckEmitter *, SyckOutputHandler );
void syck_emitter_handler( SyckEmitter *, SyckEmitterHandler );
void syck_free_emitter( SyckEmitter * );
void syck_emitter_clear( SyckEmitter * );
void syck_emitter_write( SyckEmitter *, const char *, long );
void syck_emitter_escape( SyckEmitter *, const char *, long );
void syck_emitter_flush( SyckEmitter *, long );
void syck_emit( SyckEmitter *, st_data_t );
void syck_emit_scalar( SyckEmitter *, const char *, enum scalar_style, int, int, char, const char *, long );
void syck_emit_1quoted( SyckEmitter *, int, const char *, long );
void syck_emit_2quoted( SyckEmitter *, int, const char *, long );
void syck_emit_folded( SyckEmitter *, int, char, const char *, long );
void syck_emit_literal( SyckEmitter *, char, const char *, long );
void syck_emit_seq( SyckEmitter *, const char *, enum seq_style );
void syck_emit_item( SyckEmitter *, st_data_t );
void syck_emit_map( SyckEmitter *, const char *, enum map_style );
void syck_emit_end( SyckEmitter * );
void syck_emit_tag( SyckEmitter *, const char *, const char * );
void syck_emit_indent( SyckEmitter * );
SyckLevel *syck_emitter_current_level( SyckEmitter * );
SyckLevel *syck_emitter_parent_level( SyckEmitter * );
void syck_emitter_pop_level( SyckEmitter * );
void syck_emitter_add_level( SyckEmitter *, int, enum syck_level_status );
void syck_emitter_reset_levels( SyckEmitter * );
SyckParser *syck_new_parser(void);
void syck_free_parser( SyckParser * );
void syck_parser_set_root_on_error( SyckParser *, SYMID );
void syck_parser_implicit_typing( SyckParser *, int );
void syck_parser_taguri_expansion( SyckParser *, int );
int syck_scan_scalar( int, const char *, long );
void syck_parser_handler( SyckParser *, SyckNodeHandler );
void syck_parser_error_handler( SyckParser *, SyckErrorHandler );
void syck_parser_bad_anchor_handler( SyckParser *, SyckBadAnchorHandler );
void syck_parser_set_input_type( SyckParser *, enum syck_parser_input );
void syck_parser_file( SyckParser *, FILE *, SyckIoFileRead );
void syck_parser_str( SyckParser *, char *, long, SyckIoStrRead );
void syck_parser_str_auto( SyckParser *, char *, SyckIoStrRead );
SyckLevel *syck_parser_current_level( SyckParser * );
void syck_parser_add_level( SyckParser *, int, enum syck_level_status );
void syck_parser_pop_level( SyckParser * );
void free_any_io( SyckParser * );
long syck_parser_read( SyckParser * );
long syck_parser_readlen( SyckParser *, long );
SYMID syck_parse( SyckParser * );
void syck_default_error_handler( SyckParser *, const char * );
SYMID syck_yaml2byte_handler( SyckParser *, SyckNode * );
char *syck_yaml2byte( char * );
/*
* Allocation prototypes
*/
SyckNode *syck_alloc_map(void);
SyckNode *syck_alloc_seq(void);
SyckNode *syck_alloc_str(void);
void syck_free_node( SyckNode * );
void syck_free_members( SyckNode * );
SyckNode *syck_new_str( const char *, enum scalar_style );
SyckNode *syck_new_str2( const char *, long, enum scalar_style );
void syck_replace_str( SyckNode *, char *, enum scalar_style );
void syck_replace_str2( SyckNode *, char *, long, enum scalar_style );
void syck_str_blow_away_commas( SyckNode * );
char *syck_str_read( SyckNode * );
SyckNode *syck_new_map( SYMID, SYMID );
void syck_map_empty( SyckNode * );
void syck_map_add( SyckNode *, SYMID, SYMID );
SYMID syck_map_read( SyckNode *, enum map_part, long );
void syck_map_assign( SyckNode *, enum map_part, long, SYMID );
long syck_map_count( SyckNode * );
void syck_map_update( SyckNode *, SyckNode * );
SyckNode *syck_new_seq( SYMID );
void syck_seq_empty( SyckNode * );
void syck_seq_add( SyckNode *, SYMID );
void syck_seq_assign( SyckNode *, long, SYMID );
SYMID syck_seq_read( SyckNode *, long );
long syck_seq_count( SyckNode * );
/*
* Lexer prototypes
*/
void syckerror( const char * );
int syckparse( void * );
union YYSTYPE;
int sycklex( union YYSTYPE *, SyckParser * );
#if defined(__cplusplus)
} /* extern "C" { */
#endif
#endif /* ifndef SYCK_H */

File diff suppressed because it is too large Load diff

View file

@ -1,259 +0,0 @@
/*
* yaml2byte.c
*
* $Author$
*
* Copyright (C) 2003 why the lucky stiff, clark evans
*
* WARNING WARNING WARNING --- THIS IS *NOT JUST* PLAYING
* ANYMORE! -- WHY HAS EMBRACED THIS AS THE REAL THING!
*/
#include "ruby/ruby.h"
#include <syck.h>
#include <assert.h>
#define YAMLBYTE_UTF8
#include "yamlbyte.h"
#include <stdio.h>
#define TRACE0(a) \
do { printf(a); printf("\n"); fflush(stdout); } while(0)
#define TRACE1(a,b) \
do { printf(a,b); printf("\n"); fflush(stdout); } while(0)
#define TRACE2(a,b,c) \
do { printf(a,b,c); printf("\n"); fflush(stdout); } while(0)
#define TRACE3(a,b,c,d) \
do { printf(a,b,c,d); printf("\n"); fflush(stdout); } while(0)
/* Reinvent the wheel... */
#define CHUNKSIZE 64
#define HASH ((long)0xCAFECAFE)
typedef struct {
long hash;
char *buffer;
long length;
long remaining;
int printed;
} bytestring_t;
bytestring_t *bytestring_alloc(void) {
bytestring_t *ret;
/*TRACE0("bytestring_alloc()");*/
ret = S_ALLOC(bytestring_t);
ret->hash = HASH;
ret->length = CHUNKSIZE;
ret->remaining = ret->length;
ret->buffer = S_ALLOC_N(char, ret->length + 1 );
ret->buffer[0] = 0;
ret->printed = 0;
return ret;
}
void bytestring_append(bytestring_t *str, char code,
char *start, char *finish)
{
long grow;
long length = 2; /* CODE + LF */
char *curr;
assert(str && HASH == str->hash);
/*TRACE0("bytestring_append()");*/
if(start) {
if(!finish)
finish = start + strlen(start);
length += (finish-start);
}
if(length > str->remaining) {
grow = (length - str->remaining) + CHUNKSIZE;
str->remaining += grow;
str->length += grow;
S_REALLOC_N( str->buffer, char, str->length + 1 );
assert(str->buffer);
}
curr = str->buffer + (str->length - str->remaining);
*curr = code;
curr += 1;
if(start)
while(start < finish)
*curr ++ = *start ++;
*curr = '\n';
curr += 1;
*curr = 0;
str->remaining = str->remaining - length;
assert( (str->buffer + str->length) - str->remaining );
}
void bytestring_extend(bytestring_t *str, bytestring_t *ext)
{
char *from;
char *curr;
char *stop;
long grow;
long length;
assert(str && HASH == str->hash);
assert(ext && HASH == ext->hash);
if(ext->printed) {
assert(ext->buffer[0] ==YAMLBYTE_ANCHOR);
curr = ext->buffer;
while( '\n' != *curr)
curr++;
bytestring_append(str, YAMLBYTE_ALIAS, ext->buffer + 1, curr);
} else {
ext->printed = 1;
length = (ext->length - ext->remaining);
if(length > str->remaining) {
grow = (length - str->remaining) + CHUNKSIZE;
str->remaining += grow;
str->length += grow;
S_REALLOC_N( str->buffer, char, str->length + 1 );
}
curr = str->buffer + (str->length - str->remaining);
from = ext->buffer;
stop = ext->buffer + length;
while( from < stop )
*curr ++ = *from ++;
*curr = 0;
str->remaining = str->remaining - length;
assert( (str->buffer + str->length) - str->remaining );
}
}
/* convert SyckNode into yamlbyte_buffer_t objects */
SYMID
syck_yaml2byte_handler(p, n)
SyckParser *p;
SyckNode *n;
{
SYMID oid;
long i;
char ch;
char nextcode;
char *start;
char *current;
char *finish;
bytestring_t *val = NULL;
bytestring_t *sav = NULL;
void *data;
/*TRACE0("syck_yaml2byte_handler()");*/
val = bytestring_alloc();
if(n->anchor) bytestring_append(val,YAMLBYTE_ANCHOR, n->anchor, NULL);
if ( n->type_id )
{
if ( p->taguri_expansion )
{
bytestring_append(val,YAMLBYTE_TRANSFER, n->type_id, NULL);
}
else
{
char *type_tag = S_ALLOC_N( char, strlen( n->type_id ) + 1 );
type_tag[0] = '\0';
strcat( type_tag, "!" );
strcat( type_tag, n->type_id );
bytestring_append( val, YAMLBYTE_TRANSFER, type_tag, NULL);
S_FREE(type_tag);
}
}
switch (n->kind)
{
case syck_str_kind:
nextcode = YAMLBYTE_SCALAR;
start = n->data.str->ptr;
finish = start + n->data.str->len - 1;
current = start;
/*TRACE2("SCALAR: %s %d", start, n->data.str->len); */
while(1) {
ch = *current;
if('\n' == ch || 0 == ch || current > finish) {
if(current >= start) {
bytestring_append(val, nextcode, start, current);
nextcode = YAMLBYTE_CONTINUE;
}
start = current + 1;
if(current > finish)
{
break;
}
else if('\n' == ch )
{
bytestring_append(val,YAMLBYTE_NEWLINE,NULL,NULL);
}
else if(0 == ch)
{
bytestring_append(val,YAMLBYTE_NULLCHAR,NULL,NULL);
}
else
{
assert("oops");
}
}
current += 1;
}
break;
case syck_seq_kind:
bytestring_append(val,YAMLBYTE_SEQUENCE,NULL,NULL);
for ( i = 0; i < n->data.list->idx; i++ )
{
oid = syck_seq_read( n, i );
if (syck_lookup_sym( p, oid, &data )) sav = data;
bytestring_extend(val, sav);
}
bytestring_append(val,YAMLBYTE_END_BRANCH,NULL,NULL);
break;
case syck_map_kind:
bytestring_append(val,YAMLBYTE_MAPPING,NULL,NULL);
for ( i = 0; i < n->data.pairs->idx; i++ )
{
oid = syck_map_read( n, map_key, i );
if (syck_lookup_sym( p, oid, &data )) sav = data;
bytestring_extend(val, sav);
oid = syck_map_read( n, map_value, i );
if (syck_lookup_sym( p, oid, &data )) sav = data;
bytestring_extend(val, sav);
}
bytestring_append(val,YAMLBYTE_END_BRANCH,NULL,NULL);
break;
}
oid = syck_add_sym( p, (char *) val );
/*TRACE1("Saving: %s", val->buffer );*/
return oid;
}
char *
syck_yaml2byte(char *yamlstr)
{
SYMID oid;
char *ret;
bytestring_t *sav;
void *data;
SyckParser *parser = syck_new_parser();
syck_parser_str_auto( parser, yamlstr, NULL );
syck_parser_handler( parser, syck_yaml2byte_handler );
syck_parser_error_handler( parser, NULL );
syck_parser_implicit_typing( parser, 1 );
syck_parser_taguri_expansion( parser, 1 );
oid = syck_parse( parser );
if ( syck_lookup_sym( parser, oid, &data ) ) {
sav = data;
ret = S_ALLOC_N( char, strlen( sav->buffer ) + 3 );
ret[0] = '\0';
strcat( ret, "D\n" );
strcat( ret, sav->buffer );
}
else
{
ret = NULL;
}
syck_free_parser( parser );
return ret;
}
#ifdef TEST_YBEXT
#include <stdio.h>
int main() {
char *yaml = "test: 1\nand: \"with new\\nline\\n\"\nalso: &3 three\nmore: *3";
printf("--- # YAML \n");
printf(yaml);
printf("\n...\n");
printf(syck_yaml2byte(yaml));
return 0;
}
#endif

View file

@ -1,171 +0,0 @@
/* yamlbyte.h
*
* The YAML bytecode "C" interface header file. See the YAML bytecode
* reference for bytecode sequence rules and for the meaning of each
* bytecode.
*/
#ifndef YAMLBYTE_H
#define YAMLBYTE_H
#include <stddef.h>
/* define what a character is */
typedef unsigned char yamlbyte_utf8_t;
typedef unsigned short yamlbyte_utf16_t;
#ifdef YAMLBYTE_UTF8
#ifdef YAMLBYTE_UTF16
#error Must only define YAMLBYTE_UTF8 or YAMLBYTE_UTF16
#endif
typedef yamlbyte_utf8_t yamlbyte_char_t;
#else
#ifdef YAMLBYTE_UTF16
typedef yamlbyte_utf16_t yamlbyte_char_t;
#else
#error Must define YAMLBYTE_UTF8 or YAMLBYTE_UTF16
#endif
#endif
/* specify list of bytecodes */
#define YAMLBYTE_FINISH ((yamlbyte_char_t) 0)
#define YAMLBYTE_DOCUMENT ((yamlbyte_char_t)'D')
#define YAMLBYTE_DIRECTIVE ((yamlbyte_char_t)'V')
#define YAMLBYTE_PAUSE ((yamlbyte_char_t)'P')
#define YAMLBYTE_MAPPING ((yamlbyte_char_t)'M')
#define YAMLBYTE_SEQUENCE ((yamlbyte_char_t)'Q')
#define YAMLBYTE_END_BRANCH ((yamlbyte_char_t)'E')
#define YAMLBYTE_SCALAR ((yamlbyte_char_t)'S')
#define YAMLBYTE_CONTINUE ((yamlbyte_char_t)'C')
#define YAMLBYTE_NEWLINE ((yamlbyte_char_t)'N')
#define YAMLBYTE_NULLCHAR ((yamlbyte_char_t)'Z')
#define YAMLBYTE_ANCHOR ((yamlbyte_char_t)'A')
#define YAMLBYTE_ALIAS ((yamlbyte_char_t)'R')
#define YAMLBYTE_TRANSFER ((yamlbyte_char_t)'T')
/* formatting bytecodes */
#define YAMLBYTE_COMMENT ((yamlbyte_char_t)'c')
#define YAMLBYTE_INDENT ((yamlbyte_char_t)'i')
#define YAMLBYTE_STYLE ((yamlbyte_char_t)'s')
/* other bytecodes */
#define YAMLBYTE_LINE_NUMBER ((yamlbyte_char_t)'#')
#define YAMLBYTE_WHOLE_SCALAR ((yamlbyte_char_t)'<')
#define YAMLBYTE_NOTICE ((yamlbyte_char_t)'!')
#define YAMLBYTE_SPAN ((yamlbyte_char_t)')')
#define YAMLBYTE_ALLOC ((yamlbyte_char_t)'@')
/* second level style bytecodes, ie "s>" */
#define YAMLBYTE_FLOW ((yamlbyte_char_t)'>')
#define YAMLBYTE_LITERAL ((yamlbyte_char_t)'|')
#define YAMLBYTE_BLOCK ((yamlbyte_char_t)'b')
#define YAMLBYTE_PLAIN ((yamlbyte_char_t)'p')
#define YAMLBYTE_INLINE_MAPPING ((yamlbyte_char_t)'{')
#define YAMLBYTE_INLINE_SEQUENCE ((yamlbyte_char_t)'[')
#define YAMLBYTE_SINGLE_QUOTED ((yamlbyte_char_t)39)
#define YAMLBYTE_DOUBLE_QUOTED ((yamlbyte_char_t)'"')
/*
* The "C" API has two variants, one based on instructions,
* with events delivered via pointers; and the other one
* is character based where one or more instructions are
* serialized into a buffer.
*
* Note: In the instruction based API, WHOLE_SCALAR does
* not have the '<here' marshalling stuff.
*/
typedef void * yamlbyte_consumer_t;
typedef void * yamlbyte_producer_t;
/* push and pull APIs need a way to communicate results */
typedef enum {
YAMLBYTE_OK = 0, /* proceed */
YAMLBYTE_E_MEMORY = 'M', /* could not allocate memory */
YAMLBYTE_E_READ = 'R', /* input stream read error */
YAMLBYTE_E_WRITE = 'W', /* output stream write error */
YAMLBYTE_E_OTHER = '?', /* some other error condition */
YAMLBYTE_E_PARSE = 'P', /* parse error, check bytecodes */
YAMLBYTE_MAX
} yamlbyte_result_t;
typedef const yamlbyte_char_t *yamlbyte_buff_t;
/*
* The "Instruction" API
*/
typedef struct yaml_instruction {
yamlbyte_char_t bytecode;
yamlbyte_buff_t start;
yamlbyte_buff_t finish; /* open range, *finish is _not_ part */
} *yamlbyte_inst_t;
/* producer pushes the instruction with one bytecode event to the
* consumer; if the consumer's result is not YAMLBYTE_OK, then
* the producer should stop */
typedef
yamlbyte_result_t
(*yamlbyte_push_t)(
yamlbyte_consumer_t self,
yamlbyte_inst_t inst
);
/* consumer pulls a bytecode instruction from the producer; in this
* case the instruction (and is buffer) are owned by the producer and
* will remain valid till the pull function is called once again;
* if the instruction is NULL, then there are no more results; and
* it is important to call the pull function till it returns NULL so
* that the producer can clean up its memory allocations */
typedef
yamlbyte_result_t
(*yamlbyte_pull_t)(
yamlbyte_producer_t self,
yamlbyte_inst_t *inst /* to be filled in by the producer */
);
/*
* Buffer based API
*/
/* producer pushes a null terminated buffer filled with one or more
* bytecode events to the consumer; if the consumer's result is not
* YAMLBYTE_OK, then the producer should stop */
typedef
yamlbyte_result_t
(*yamlbyte_pushbuff_t)(
yamlbyte_consumer_t self,
yamlbyte_buff_t buff
);
/* consumer pulls bytecode events from the producer; in this case
* the buffer is owned by the producer, and will remain valid till
* the pull function is called once again; if the buffer pointer
* is set to NULL, then there are no more results; it is important
* to call the pull function till it returns NULL so that the
* producer can clean up its memory allocations */
typedef
yamlbyte_result_t
(*yamlbyte_pullbuff_t)(
yamlbyte_producer_t self,
yamlbyte_buff_t *buff /* to be filled in by the producer */
);
/* convert a pull interface to a push interface; the reverse process
* requires threads and thus is language dependent */
#define YAMLBYTE_PULL2PUSH(pull,producer,push,consumer,result) \
do { \
yamlbyte_pullbuff_t _pull = (pull); \
yamlbyte_pushbuff_t _push = (push); \
yamlbyte_result_t _result = YAMLBYTE_OK; \
yamlbyte_producer_t _producer = (producer); \
yamlbyte_consumer_t _consumer = (consumer); \
while(1) { \
yamlbyte_buff_t buff = NULL; \
_result = _pull(_producer,&buff); \
if(YAMLBYTE_OK != result || NULL == buff) \
break; \
_result = _push(_consumer,buff); \
if(YAMLBYTE_OK != result) \
break; \
} \
(result) = _result; \
} while(0)
#endif

View file

@ -2,75 +2,41 @@
# The YAML module allows you to use one of the two YAML engines that ship with
# ruby. By default Psych is used but the old and unmaintained Syck may be
# chosen.
#
# See Psych or Syck for usage and documentation.
#
# To set the YAML engine to syck:
#
# YAML::ENGINE.yamler = 'syck'
#
# To set the YAML engine back to psych:
#
# YAML::ENGINE.yamler = 'psych'
module YAML
begin
require 'psych'
rescue LoadError
warn "#{caller[0]}:"
warn "It seems your ruby installation is missing psych (for YAML output)."
warn "To eliminate this warning, please install libyaml and reinstall your ruby."
raise
end
module Psych
class EngineManager # :nodoc:
attr_reader :yamler
def initialize
@yamler = nil
@yamler = 'psych'
end
def syck?
'syck' == @yamler
false
end
def yamler= engine
raise(ArgumentError, "bad engine") unless %w{syck psych}.include?(engine)
case engine
when 'syck' then warn "syck has been removed"
when 'psych' then @yamler = 'psych'
else
raise(ArgumentError, "bad engine")
end
require engine unless (engine == 'syck' ? Syck : Psych).const_defined?(:VERSION)
::Object.class_eval <<-eorb, __FILE__, __LINE__ + 1
remove_const 'YAML'
YAML = #{engine.capitalize}
remove_method :to_yaml
alias :to_yaml :#{engine}_to_yaml
eorb
@yamler = engine
engine
end
end
##
# Allows changing the current YAML engine. See YAML for details.
ENGINE = YAML::EngineManager.new
ENGINE = EngineManager.new # :nodoc:
end
if defined?(Psych)
engine = 'psych'
elsif defined?(Syck)
engine = 'syck'
else
begin
require 'psych'
engine = 'psych'
rescue LoadError
warn "#{caller[0]}:"
warn "It seems your ruby installation is missing psych (for YAML output)."
warn "To eliminate this warning, please install libyaml and reinstall your ruby."
require 'syck'
engine = 'syck'
end
end
module Syck
ENGINE = YAML::ENGINE
end
module Psych
ENGINE = YAML::ENGINE
end
YAML::ENGINE.yamler = engine
YAML = Psych

View file

@ -3,10 +3,6 @@ require 'yaml'
module Psych
class TestEngineManager < TestCase
def teardown
YAML::ENGINE.yamler = 'syck'
end
def test_bad_engine
assert_raises(ArgumentError) do
YAML::ENGINE.yamler = 'foooo'
@ -19,12 +15,6 @@ module Psych
assert_equal 'psych', YAML::ENGINE.yamler
end
def test_set_syck
YAML::ENGINE.yamler = 'syck'
assert_equal ::Syck, YAML
assert_equal 'syck', YAML::ENGINE.yamler
end
A = Struct.new(:name)
def test_dump_types

View file

@ -1,24 +0,0 @@
require 'test/unit'
require 'yaml'
module Syck
class TestArray < Test::Unit::TestCase
def setup
@current_engine = YAML::ENGINE.yamler
YAML::ENGINE.yamler = 'syck'
@list = [{ :a => 'b' }, 'foo']
end
def teardown
YAML::ENGINE.yamler = @current_engine
end
def test_to_yaml
assert_equal @list, YAML.load(@list.to_yaml)
end
def test_dump
assert_equal @list, YAML.load(YAML.dump(@list))
end
end
end

View file

@ -1,37 +0,0 @@
require 'test/unit'
require 'yaml'
module Syck
###
# Test booleans from YAML spec:
# http://yaml.org/type/bool.html
class TestBoolean < Test::Unit::TestCase
%w{ yes Yes YES true True TRUE on On ON }.each do |truth|
define_method(:"test_#{truth}") do
assert_equal true, YAML.load("--- #{truth}")
end
end
%w{ no No NO false False FALSE off Off OFF }.each do |truth|
define_method(:"test_#{truth}") do
assert_equal false, YAML.load("--- #{truth}")
end
end
###
# YAML spec says "y" and "Y" may be used as true, but Syck treats them
# as literal strings
def test_y
assert_equal "y", YAML.load("--- y")
assert_equal "Y", YAML.load("--- Y")
end
###
# YAML spec says "n" and "N" may be used as false, but Syck treats them
# as literal strings
def test_n
assert_equal "n", YAML.load("--- n")
assert_equal "N", YAML.load("--- N")
end
end
end

View file

@ -1,27 +0,0 @@
require 'test/unit'
require 'yaml'
module Syck
class TestClass < Test::Unit::TestCase
def setup
@engine = YAML::ENGINE.yamler
YAML::ENGINE.yamler = 'syck'
end
def teardown
YAML::ENGINE.yamler = @engine
end
def test_to_yaml
assert_raises(::TypeError) do
TestClass.to_yaml
end
end
def test_dump
assert_raises(::TypeError) do
YAML.dump TestClass
end
end
end
end

View file

@ -1,3 +0,0 @@
require 'test/unit'
require 'yaml'

View file

@ -1,46 +0,0 @@
require 'test/unit'
require 'yaml'
module Syck
class TestException < Test::Unit::TestCase
class Wups < Exception
attr_reader :foo, :bar
def initialize *args
super
@foo = 1
@bar = 2
end
end
def setup
@wups = Wups.new('test_message')
end
def test_to_yaml
w = YAML.load(@wups.to_yaml)
assert_equal @wups, w
assert_equal 1, w.foo
assert_equal 2, w.bar
end
def test_dump
w = YAML.load(@wups.to_yaml)
assert_equal @wups, w
assert_equal 1, w.foo
assert_equal 2, w.bar
end
def test_to_yaml_properties
class << @wups
def to_yaml_properties
[:@foo]
end
end
w = YAML.load(YAML.dump(@wups))
assert_equal @wups, w
assert_equal 1, w.foo
assert_nil w.bar
end
end
end

View file

@ -1,29 +0,0 @@
require 'test/unit'
require 'yaml'
module Syck
class TestHash < Test::Unit::TestCase
def setup
@hash = { :a => 'b' }
end
def test_to_yaml
assert_equal @hash, YAML.load(@hash.to_yaml)
end
def test_dump
assert_equal @hash, YAML.load(YAML.dump(@hash))
end
def test_ref_append
hash = YAML.load(<<-eoyml)
---
foo: &foo
hello: world
bar:
<<: *foo
eoyml
assert_equal({"foo"=>{"hello"=>"world"}, "bar"=>{"hello"=>"world"}}, hash)
end
end
end

View file

@ -1,20 +0,0 @@
require 'test/unit'
require 'yaml'
module Syck
###
# Test null from YAML spec:
# http://yaml.org/type/null.html
class TestNull < Test::Unit::TestCase
def test_null_list
assert_equal [nil] * 5, YAML.load(<<-eoyml)
---
- ~
- null
-
- Null
- NULL
eoyml
end
end
end

View file

@ -1,56 +0,0 @@
require 'test/unit'
require 'yaml'
module Syck
class TestOmap < Test::Unit::TestCase
def test_keys
map = YAML::Omap.new
map['foo'] = 'bar'
assert_equal 'bar', map['foo']
end
def test_order
map = YAML::Omap.new
map['a'] = 'b'
map['b'] = 'c'
assert_equal [%w{a b}, %w{b c}], map.to_a
end
def test_square
list = [["a", "b"], ["b", "c"]]
map = YAML::Omap[*list.flatten]
assert_equal list, map.to_a
assert_equal 'b', map['a']
assert_equal 'c', map['b']
end
def test_to_yaml
map = YAML::Omap['a', 'b', 'c', 'd']
yaml = map.to_yaml
assert_match('!omap', yaml)
assert_match('- a: b', yaml)
assert_match('- c: d', yaml)
end
def test_round_trip
list = [["a", "b"], ["b", "c"]]
map = YAML::Omap[*list.flatten]
loaded = YAML.load(YAML.dump(map))
assert_equal map, loaded
assert_equal list, loaded.to_a
end
###
# FIXME: Syck should also support !!omap as shorthand
def test_load
list = [["a", "b"], ["c", "d"]]
map = YAML.load(<<-eoyml)
--- !omap
- a: b
- c: d
eoyml
assert_equal list, map.to_a
end
end
end

View file

@ -1,31 +0,0 @@
require 'test/unit'
require 'yaml'
module Syck
class TestSet < Test::Unit::TestCase
def setup
@set = YAML::Set.new
@set['foo'] = 'bar'
@set['bar'] = 'baz'
end
def test_to_yaml
assert_match(/!set/, @set.to_yaml)
end
def test_roundtrip
assert_equal(@set, YAML.load(YAML.dump(@set)))
end
###
# FIXME: Syck should also support !!set as shorthand
def test_load_from_yaml
loaded = YAML.load(<<-eoyml)
--- !set
foo: bar
bar: baz
eoyml
assert_equal(@set, loaded)
end
end
end

View file

@ -1,45 +0,0 @@
require 'test/unit'
require 'yaml'
module Syck
class TestString < Test::Unit::TestCase
def test_binary_string_null
string = "\x00"
yml = YAML.dump string
assert_match(/binary/, yml)
assert_equal string, YAML.load(yml)
end
def test_binary_string
string = binary_string
yml = YAML.dump string
assert_match(/binary/, yml)
assert_equal string, YAML.load(yml)
end
def test_non_binary_string
string = binary_string(0.29)
yml = YAML.dump string
assert_not_match(/binary/, yml)
assert_equal string, YAML.load(yml)
end
def test_string_with_ivars
food = "is delicious"
ivar = "on rock and roll"
food.instance_variable_set(:@we_built_this_city, ivar)
str = YAML.load YAML.dump food
assert_equal ivar, food.instance_variable_get(:@we_built_this_city)
end
def binary_string percentage = 0.31, length = 100
string = ''
(percentage * length).to_i.times do |i|
string << "\b"
end
string << 'a' * (length - string.length)
string
end
end
end

View file

@ -1,42 +0,0 @@
require 'test/unit'
require 'yaml'
class StructWithIvar < Struct.new(:foo)
attr_reader :bar
def initialize *args
super
@bar = 'hello'
end
end
module Syck
class TestStruct < MiniTest::Unit::TestCase
def setup
@current_engine = YAML::ENGINE.yamler
YAML::ENGINE.yamler = 'syck'
end
def teardown
YAML::ENGINE.yamler = @current_engine
end
def test_roundtrip
thing = StructWithIvar.new('bar')
struct = YAML.load(YAML.dump(thing))
assert_equal 'hello', struct.bar
assert_equal 'bar', struct.foo
end
def test_load
obj = YAML.load(<<-eoyml)
--- !ruby/struct:StructWithIvar
foo: bar
@bar: hello
eoyml
assert_equal 'hello', obj.bar
assert_equal 'bar', obj.foo
end
end
end

View file

@ -1,22 +0,0 @@
require 'test/unit'
require 'yaml'
module Syck
class TestSymbol < Test::Unit::TestCase
def test_to_yaml
assert_equal :a, YAML.load(:a.to_yaml)
end
def test_dump
assert_equal :a, YAML.load(YAML.dump(:a))
end
def test_stringy
assert_equal :"1", YAML.load(YAML.dump(:"1"))
end
def test_load_quoted
assert_equal :"1", YAML.load("--- :'1'\n")
end
end
end

View file

@ -1,24 +0,0 @@
require 'test/unit'
require 'yaml'
module Syck
class TestString < Test::Unit::TestCase
def test_usec_long
bug4571 = '[ruby-core:35713]'
assert_equal(34, YAML.load("2011-03-22t23:32:11.0000342222+01:00").usec, bug4571)
end
def test_usec_very_long
t = "2011-03-22t23:32:11.0000342"+"0"*1000+"1+01:00"
assert_equal(34, YAML.load(t).usec)
end
def test_usec_full
assert_equal(342222, YAML.load("2011-03-22t23:32:11.342222+01:00").usec)
end
def test_usec_short
assert_equal(330000, YAML.load("2011-03-22t23:32:11.33+01:00").usec)
end
end
end

File diff suppressed because it is too large Load diff

View file

@ -1,64 +0,0 @@
require 'test/unit'
require 'yaml'
module Syck
class TestYamlProperties < Test::Unit::TestCase
class Foo
attr_reader :a, :b, :c
def initialize
@a = 1
@b = 2
@c = 3
end
def to_yaml_properties
[:@a, :@b]
end
end
def test_object_dump_yaml_properties
foo = YAML.load(YAML.dump(Foo.new))
assert_equal 1, foo.a
assert_equal 2, foo.b
assert_nil foo.c
end
class Bar < Struct.new(:foo, :bar)
attr_reader :baz
def initialize *args
super
@baz = 'hello'
end
def to_yaml_properties
[]
end
end
def test_struct_dump_yaml_properties
bar = YAML.load(YAML.dump(Bar.new('a', 'b')))
assert_equal 'a', bar.foo
assert_equal 'b', bar.bar
assert_nil bar.baz
end
def test_string_dump
string = "okonomiyaki"
class << string
def to_yaml_properties
[:@tastes]
end
end
string.instance_variable_set(:@tastes, 'delicious')
v = YAML.load YAML.dump string
assert_equal 'delicious', v.instance_variable_get(:@tastes)
end
def test_string_load
str = YAML.load("--- !str \nstr: okonomiyaki\n:@tastes: delicious\n")
assert_equal 'okonomiyaki', str
assert_equal 'delicious', str.instance_variable_get(:@tastes)
end
end
end

View file

@ -1,194 +0,0 @@
# -*- coding: UTF-8 -*-
begin
require 'test/unit'
require 'yaml/dbm'
require 'tmpdir'
rescue LoadError
end
module Syck
::Syck::DBM = ::YAML::DBM unless defined?(::Syck::DBM)
class YAMLDBMTest < Test::Unit::TestCase
def setup
@engine, YAML::ENGINE.yamler = YAML::ENGINE.yamler, 'syck'
@dir = Dir.mktmpdir("rubytest-file")
File.chown(-1, Process.gid, @dir)
@yamldbm_file = make_tmp_filename("yamldbm")
@yamldbm = YAML::DBM.new(@yamldbm_file)
end
def teardown
YAML::ENGINE.yamler = @engine
@yamldbm.clear
@yamldbm.close
FileUtils.remove_entry_secure @dir
end
def make_tmp_filename(prefix)
@dir + "/" + prefix + File.basename(__FILE__) + ".#{$$}.test"
end
def test_store
@yamldbm.store('a','b')
@yamldbm.store('c','d')
assert_equal 'b', @yamldbm['a']
assert_equal 'd', @yamldbm['c']
assert_nil @yamldbm['e']
end
def test_store_using_carret
@yamldbm['a'] = 'b'
@yamldbm['c'] = 'd'
assert_equal 'b', @yamldbm['a']
assert_equal 'd', @yamldbm['c']
assert_nil @yamldbm['e']
end
def test_to_a
@yamldbm['a'] = 'b'
@yamldbm['c'] = 'd'
assert_equal([['a','b'],['c','d']], @yamldbm.to_a.sort)
end
def test_to_hash
@yamldbm['a'] = 'b'
@yamldbm['c'] = 'd'
assert_equal({'a'=>'b','c'=>'d'}, @yamldbm.to_hash)
end
def test_has_value?
@yamldbm['a'] = 'b'
@yamldbm['c'] = 'd'
assert_equal true, @yamldbm.has_value?('b')
assert_equal true, @yamldbm.has_value?('d')
assert_equal false, @yamldbm.has_value?('f')
end
# Note:
# YAML::DBM#index makes warning from internal of ::DBM#index.
# It says 'DBM#index is deprecated; use DBM#key', but DBM#key
# behaves not same as DBM#index.
#
# def test_index
# @yamldbm['a'] = 'b'
# @yamldbm['c'] = 'd'
# assert_equal 'a', @yamldbm.index('b')
# assert_equal 'c', @yamldbm.index('d')
# assert_nil @yamldbm.index('f')
# end
def test_key
@yamldbm['a'] = 'b'
@yamldbm['c'] = 'd'
assert_equal 'a', @yamldbm.key('b')
assert_equal 'c', @yamldbm.key('d')
assert_nil @yamldbm.key('f')
end
def test_fetch
assert_equal('bar', @yamldbm['foo']='bar')
assert_equal('bar', @yamldbm.fetch('foo'))
assert_nil @yamldbm.fetch('bar')
assert_equal('baz', @yamldbm.fetch('bar', 'baz'))
assert_equal('foobar', @yamldbm.fetch('bar') {|key| 'foo' + key })
end
def test_shift
@yamldbm['a'] = 'b'
@yamldbm['c'] = 'd'
assert_equal([['a','b'], ['c','d']],
[@yamldbm.shift, @yamldbm.shift].sort)
assert_nil @yamldbm.shift
end
def test_invert
@yamldbm['a'] = 'b'
@yamldbm['c'] = 'd'
assert_equal({'b'=>'a','d'=>'c'}, @yamldbm.invert)
end
def test_update
@yamldbm['a'] = 'b'
@yamldbm['c'] = 'd'
@yamldbm.update({'c'=>'d','e'=>'f'})
assert_equal 'b', @yamldbm['a']
assert_equal 'd', @yamldbm['c']
assert_equal 'f', @yamldbm['e']
end
def test_replace
@yamldbm['a'] = 'b'
@yamldbm['c'] = 'd'
@yamldbm.replace({'c'=>'d','e'=>'f'})
assert_nil @yamldbm['a']
assert_equal 'd', @yamldbm['c']
assert_equal 'f', @yamldbm['e']
end
def test_delete
@yamldbm['a'] = 'b'
@yamldbm['c'] = 'd'
assert_equal 'b', @yamldbm.delete('a')
assert_nil @yamldbm['a']
assert_equal 'd', @yamldbm['c']
assert_nil @yamldbm.delete('e')
end
def test_delete_if
@yamldbm['a'] = 'b'
@yamldbm['c'] = 'd'
@yamldbm['e'] = 'f'
@yamldbm.delete_if {|k,v| k == 'a'}
assert_nil @yamldbm['a']
assert_equal 'd', @yamldbm['c']
assert_equal 'f', @yamldbm['e']
@yamldbm.delete_if {|k,v| v == 'd'}
assert_nil @yamldbm['c']
assert_equal 'f', @yamldbm['e']
@yamldbm.delete_if {|k,v| false }
assert_equal 'f', @yamldbm['e']
end
def test_reject
@yamldbm['a'] = 'b'
@yamldbm['c'] = 'd'
@yamldbm['e'] = 'f'
assert_equal({'c'=>'d','e'=>'f'}, @yamldbm.reject {|k,v| k == 'a'})
assert_equal({'a'=>'b','e'=>'f'}, @yamldbm.reject {|k,v| v == 'd'})
assert_equal({'a'=>'b','c'=>'d','e'=>'f'}, @yamldbm.reject {false})
end
def test_values
assert_equal [], @yamldbm.values
@yamldbm['a'] = 'b'
@yamldbm['c'] = 'd'
assert_equal ['b','d'], @yamldbm.values.sort
end
def test_values_at
@yamldbm['a'] = 'b'
@yamldbm['c'] = 'd'
assert_equal ['b','d'], @yamldbm.values_at('a','c')
end
def test_selsct
@yamldbm['a'] = 'b'
@yamldbm['c'] = 'd'
@yamldbm['e'] = 'f'
assert_equal(['b','d'], @yamldbm.select('a','c'))
end
def test_selsct_with_block
@yamldbm['a'] = 'b'
@yamldbm['c'] = 'd'
@yamldbm['e'] = 'f'
assert_equal([['a','b']], @yamldbm.select {|k,v| k == 'a'})
assert_equal([['c','d']], @yamldbm.select {|k,v| v == 'd'})
assert_equal([], @yamldbm.select {false})
end
end
end if defined?(YAML::DBM)

View file

@ -1,87 +0,0 @@
require 'test/unit'
require 'yaml/store'
require 'tmpdir'
module Syck
Store = YAML::Store unless defined?(Store)
class YAMLStoreTest < Test::Unit::TestCase
def setup
@engine, YAML::ENGINE.yamler = YAML::ENGINE.yamler, 'syck'
@dir = Dir.mktmpdir("rubytest-file")
File.chown(-1, Process.gid, @dir)
@yamlstore_file = make_tmp_filename("yamlstore")
@yamlstore = YAML::Store.new(@yamlstore_file)
end
def teardown
YAML::ENGINE.yamler = @engine
FileUtils.remove_entry_secure @dir
end
def make_tmp_filename(prefix)
@dir + "/" + prefix + File.basename(__FILE__) + ".#{$$}.test"
end
def test_opening_new_file_in_readonly_mode_should_result_in_empty_values
@yamlstore.transaction(true) do
assert_nil @yamlstore[:foo]
assert_nil @yamlstore[:bar]
end
end
def test_opening_new_file_in_readwrite_mode_should_result_in_empty_values
@yamlstore.transaction do
assert_nil @yamlstore[:foo]
assert_nil @yamlstore[:bar]
end
end
def test_data_should_be_loaded_correctly_when_in_readonly_mode
@yamlstore.transaction do
@yamlstore[:foo] = "bar"
end
@yamlstore.transaction(true) do
assert_equal "bar", @yamlstore[:foo]
end
end
def test_data_should_be_loaded_correctly_when_in_readwrite_mode
@yamlstore.transaction do
@yamlstore[:foo] = "bar"
end
@yamlstore.transaction do
assert_equal "bar", @yamlstore[:foo]
end
end
def test_changes_after_commit_are_discarded
@yamlstore.transaction do
@yamlstore[:foo] = "bar"
@yamlstore.commit
@yamlstore[:foo] = "baz"
end
@yamlstore.transaction(true) do
assert_equal "bar", @yamlstore[:foo]
end
end
def test_changes_are_not_written_on_abort
@yamlstore.transaction do
@yamlstore[:foo] = "bar"
@yamlstore.abort
end
@yamlstore.transaction(true) do
assert_nil @yamlstore[:foo]
end
end
def test_writing_inside_readonly_transaction_raises_error
assert_raise(PStore::Error) do
@yamlstore.transaction(true) do
@yamlstore[:foo] = "bar"
end
end
end
end
end