[macruby-changes] [2867] MacRuby/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Tue Oct 20 01:09:11 PDT 2009
Revision: 2867
http://trac.macosforge.org/projects/ruby/changeset/2867
Author: neeracher at apple.com
Date: 2009-10-20 01:09:07 -0700 (Tue, 20 Oct 2009)
Log Message:
-----------
Implement YAML support for date/time
Modified Paths:
--------------
MacRuby/trunk/ext/libyaml/rubyext.c
MacRuby/trunk/lib/yaml/rubytypes.rb
MacRuby/trunk/spec/frozen/tags/macruby/library/yaml/to_yaml_tags.txt
Removed Paths:
-------------
MacRuby/trunk/spec/frozen/tags/macruby/library/yaml/load_tags.txt
Modified: MacRuby/trunk/ext/libyaml/rubyext.c
===================================================================
--- MacRuby/trunk/ext/libyaml/rubyext.c 2009-10-20 07:05:21 UTC (rev 2866)
+++ MacRuby/trunk/ext/libyaml/rubyext.c 2009-10-20 08:09:07 UTC (rev 2867)
@@ -359,6 +359,121 @@
return true;
}
+static inline bool
+is_timestamp(const char *str, size_t length)
+{
+ // TODO: This probably should be coded as a regex and/or in ruby
+ bool canonical = true;
+ if (length < 10) {
+ return false;
+ }
+ /* 4 digit year - */
+ if (!isdigit(str[0]) ||
+ !isdigit(str[1]) ||
+ !isdigit(str[2]) ||
+ !isdigit(str[3]) ||
+ str[4] != '-') {
+ return false;
+ }
+ str += 5;
+ /* 1/2 digit month - */
+ if (!isdigit(*str++)) {
+ return false;
+ }
+ if (isdigit(*str)) {
+ ++str;
+ }
+ else {
+ canonical = false;
+ }
+ if (*str++ != '-') {
+ return false;
+ }
+ /* 1/2 digit day */
+ if (!isdigit(*str++)) {
+ return false;
+ }
+ if (isdigit(*str)) {
+ ++str;
+ }
+ else {
+ canonical = false;
+ }
+ /* Date alone must be YYYY-MM-DD */
+ if (*str == '\0') {
+ return canonical;
+ }
+ else if (*str == 't' || *str == 'T') {
+ ++str;
+ }
+ else if (*str == ' ' || *str == '\t') {
+ do {
+ ++str;
+ } while (*str == ' ' || *str == '\t');
+ }
+ else {
+ return false;
+ }
+ /* 1/2 digit hour : */
+ if (!isdigit(*str++)) {
+ return false;
+ }
+ if (isdigit(*str)) {
+ ++str;
+ }
+ if (*str++ != ':') {
+ return false;
+ }
+ /* 2 digit minute:second */
+ if (!isdigit(str[0]) ||
+ !isdigit(str[1]) ||
+ (str[2] != ':') ||
+ !isdigit(str[3]) ||
+ !isdigit(str[4])) {
+ return false;
+ }
+ str += 5;
+ /* Optional fraction */
+ if (*str == '.') {
+ do {
+ ++str;
+ } while (isdigit(*str));
+ }
+ if (*str == '\0') {
+ return true; /* Assumed UTC */
+ }
+ while (*str == ' ' || *str == '\t') {
+ ++str;
+ }
+ if (str[0] == 'Z' && str[1] == '\0') {
+ return true; /* UTC */
+ }
+ else if (str[0] != '+' && str[0] != '-') {
+ return false;
+ }
+ ++str;
+ /* 1/2 digit time zone hour */
+ if (!isdigit(*str++)) {
+ return false;
+ }
+ if (isdigit(*str)) {
+ ++str;
+ }
+ if (*str == '\0') {
+ return true;
+ }
+ /* Optional minute */
+ if ((str[0] != ':') ||
+ !isdigit(str[1]) ||
+ !isdigit(str[2]) ||
+ (str[3] != '\0')) {
+ return false;
+ }
+ else {
+ return true;
+ }
+}
+
static char *
detect_scalar_type(const char * val, size_t length)
{
@@ -380,6 +495,9 @@
else if (strcmp(val, "false") == 0) {
return "tag:yaml.org,2002:false";
}
+ else if (is_timestamp(val, length)) {
+ return "tag:yaml.org,2002:timestamp";
+ }
else {
return NULL;
}
@@ -576,6 +694,7 @@
(strcmp(tag, "tag:yaml.org,2002:true") == 0) ||
(strcmp(tag, "tag:yaml.org,2002:false") == 0) ||
(strcmp(tag, "tag:yaml.org,2002:null") == 0) ||
+ (strcmp(tag, "tag:yaml.org,2002:timestamp") == 0) ||
(strcmp(tag, YAML_DEFAULT_SEQUENCE_TAG) == 0) ||
(strcmp(tag, YAML_DEFAULT_MAPPING_TAG) == 0)) {
*can_omit_tag = 1;
Modified: MacRuby/trunk/lib/yaml/rubytypes.rb
===================================================================
--- MacRuby/trunk/lib/yaml/rubytypes.rb 2009-10-20 07:05:21 UTC (rev 2866)
+++ MacRuby/trunk/lib/yaml/rubytypes.rb 2009-10-20 08:09:07 UTC (rev 2867)
@@ -1,5 +1,5 @@
# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4
-# require 'date'
+require 'date'
require 'libyaml'
class Class
@@ -258,7 +258,69 @@
end
end
+class DateTime
+ yaml_as "tag:yaml.org,2002:timestamp"
+ def self.yaml_new(val)
+ if val.length <= 10
+ Date.strptime(val)
+ else
+ format = "%F %T"
+ if val =~ /([tT])/
+ format = "%F#{$1}%T"
+ end
+ if val =~ /\./
+ format += ".%N%z"
+ else
+ format += "%z"
+ end
+ val = val.tr(" \t", "")
+ if val !~ /(Z|[-+]\d\d?(?::\d\d)?)$/
+ val = val + "Z"
+ end
+ strptime(val, format).to_time
+ end
+ end
+ def to_yaml(output = nil)
+ to_time.to_yaml(output)
+ end
+end
+class Time
+ def to_yaml(output = nil)
+ # Not exactly canonical YAML format, but legal, and consistent with syck
+ YAML::quick_emit(output) do |out|
+ tz = "Z"
+ # from the tidy Tobias Peters <t-peters at 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]
+ out.scalar("tag:yaml.org,2002:timestamp", standard, :plain)
+ end
+ end
+end
+
+class Date
+ def to_yaml(output = nil)
+ YAML::quick_emit(output) do |out|
+ out.scalar("tag:yaml.org,2002:timestamp", self.to_s, :plain)
+ end
+ end
+end
+
=begin
class Hash
Deleted: MacRuby/trunk/spec/frozen/tags/macruby/library/yaml/load_tags.txt
===================================================================
--- MacRuby/trunk/spec/frozen/tags/macruby/library/yaml/load_tags.txt 2009-10-20 07:05:21 UTC (rev 2866)
+++ MacRuby/trunk/spec/frozen/tags/macruby/library/yaml/load_tags.txt 2009-10-20 08:09:07 UTC (rev 2867)
@@ -1 +0,0 @@
-fails:YAML.load works on complex keys
Modified: MacRuby/trunk/spec/frozen/tags/macruby/library/yaml/to_yaml_tags.txt
===================================================================
--- MacRuby/trunk/spec/frozen/tags/macruby/library/yaml/to_yaml_tags.txt 2009-10-20 07:05:21 UTC (rev 2866)
+++ MacRuby/trunk/spec/frozen/tags/macruby/library/yaml/to_yaml_tags.txt 2009-10-20 08:09:07 UTC (rev 2867)
@@ -1,7 +1,4 @@
fails:Object#to_yaml returns the YAML representation of a Struct object
-fails:Object#to_yaml returns the YAML representation of an Array object
-fails:Object#to_yaml returns the YAML representation of a Date object
fails:Object#to_yaml returns the YAML represenation of a RegExp object
-fails:Object#to_yaml returns the YAML representation of a Time object
fails:Object#to_yaml returns the YAML representation of a Error object
fails:Object#to_yaml returns the YAML representation for Range objects
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20091020/3e831ecd/attachment-0001.html>
More information about the macruby-changes
mailing list