~ubuntu-branches/ubuntu/quantal/ruby1.9.1/quantal

« back to all changes in this revision

Viewing changes to ext/psych/lib/psych/scalar_scanner.rb

  • Committer: Bazaar Package Importer
  • Author(s): Lucas Nussbaum
  • Date: 2010-07-31 17:08:39 UTC
  • mfrom: (1.1.4 upstream) (8.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20100731170839-j034dmpdqt1cc4p6
Tags: 1.9.2~svn28788-1
* New release based on upstream snapshot from the 1.9.2 branch,
  after 1.9.2 RC2. That branch is (supposed to be) binary-compatible
  with the 1.9.1 branch.
  + Builds fine on i386. Closes: #580852.
* Upgrade to Standards-Version: 3.9.1. No changes needed.
* Updated generated incs.
* Patches that still need work:
  + Unclear status, need more investigation:
   090729_fix_Makefile_deps.dpatch
   090803_exclude_rdoc.dpatch
   203_adjust_base_of_search_path.dpatch
   902_define_YAML_in_yaml_stringio.rb.dpatch
   919_common.mk_tweaks.dpatch
   931_libruby_suffix.dpatch
   940_test_thread_mutex_sync_shorter.dpatch
  + Maybe not needed anymore, keeping but not applying.
   102_skip_test_copy_stream.dpatch (test doesn't block anymore?)
   104_skip_btest_io.dpatch (test doesn't block anymore?)
   201_gem_prelude.dpatch (we don't use that rubygems anyway?)
   202_gem_default_dir.dpatch (we don't use that rubygems anyway?)
   940_test_file_exhaustive_fails_as_root.dpatch
   940_test_priority_fails.dpatch
   100518_load_libc_libm.dpatch
* Add disable-tests.diff: disable some tests that cause failures on FreeBSD.
  Closes: #590002, #543805, #542927.
* However, many new failures on FreeBSD. Since that version is still an
  improvement, add the check that makes test suite failures non-fatal on
  FreeBSD again. That still needs to be investigated.
* Re-add 903_skip_base_ruby_check.dpatch
* Add build-dependency on ruby1.8 and drop all pre-generated files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
require 'strscan'
 
2
 
 
3
module Psych
 
4
  ###
 
5
  # Scan scalars for built in types
 
6
  class ScalarScanner
 
7
    # Taken from http://yaml.org/type/timestamp.html
 
8
    TIME = /^\d{4}-\d{1,2}-\d{1,2}([Tt]|\s+)\d{1,2}:\d\d:\d\d(\.\d*)?(\s*Z|[-+]\d{1,2}(:\d\d)?)?/
 
9
 
 
10
    # Create a new scanner
 
11
    def initialize
 
12
      @string_cache = {}
 
13
    end
 
14
 
 
15
    # Tokenize +string+ returning the ruby object
 
16
    def tokenize string
 
17
      return nil if string.empty?
 
18
      return string if @string_cache.key?(string)
 
19
 
 
20
      case string
 
21
      when /^[A-Za-z~]/
 
22
        if string.length > 5
 
23
          @string_cache[string] = true
 
24
          return string
 
25
        end
 
26
 
 
27
        case string
 
28
        when /^[^ytonf~]/i
 
29
          @string_cache[string] = true
 
30
          string
 
31
        when '~', /^null$/i
 
32
          nil
 
33
        when /^(yes|true|on)$/i
 
34
          true
 
35
        when /^(no|false|off)$/i
 
36
          false
 
37
        else
 
38
          @string_cache[string] = true
 
39
          string
 
40
        end
 
41
      when TIME
 
42
        parse_time string
 
43
      when /^\d{4}-\d{1,2}-\d{1,2}$/
 
44
        require 'date'
 
45
        Date.strptime(string, '%Y-%m-%d')
 
46
      when /^\.inf$/i
 
47
        1 / 0.0
 
48
      when /^-\.inf$/i
 
49
        -1 / 0.0
 
50
      when /^\.nan$/i
 
51
        0.0 / 0.0
 
52
      when /^:./
 
53
        if string =~ /^:(["'])(.*)\1/
 
54
          $2.sub(/^:/, '').to_sym
 
55
        else
 
56
          string.sub(/^:/, '').to_sym
 
57
        end
 
58
      when /^[-+]?[1-9][0-9_]*(:[0-5]?[0-9])+$/
 
59
        i = 0
 
60
        string.split(':').each_with_index do |n,e|
 
61
          i += (n.to_i * 60 ** (e - 2).abs)
 
62
        end
 
63
        i
 
64
      when /^[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+\.[0-9_]*$/
 
65
        i = 0
 
66
        string.split(':').each_with_index do |n,e|
 
67
          i += (n.to_f * 60 ** (e - 2).abs)
 
68
        end
 
69
        i
 
70
      else
 
71
        return Integer(string.gsub(/[,_]/, '')) rescue ArgumentError
 
72
        return Float(string.gsub(/[,_]/, '')) rescue ArgumentError
 
73
        @string_cache[string] = true
 
74
        string
 
75
      end
 
76
    end
 
77
 
 
78
    ###
 
79
    # Parse and return a Time from +string+
 
80
    def parse_time string
 
81
      date, time = *(string.split(/[ tT]/, 2))
 
82
      (yy, m, dd) = date.split('-').map { |x| x.to_i }
 
83
      md = time.match(/(\d+:\d+:\d+)(\.\d*)?\s*(Z|[-+]\d+(:\d\d)?)?/)
 
84
 
 
85
      (hh, mm, ss) = md[1].split(':').map { |x| x.to_i }
 
86
      us = (md[2] ? Rational(md[2].sub(/^\./, '0.')) : 0) * 1000000
 
87
 
 
88
      time = Time.utc(yy, m, dd, hh, mm, ss, us)
 
89
 
 
90
      return time if 'Z' == md[3]
 
91
      return Time.at(time.to_i, us) unless md[3]
 
92
 
 
93
      tz = md[3].split(':').map { |digit| Integer(digit, 10) }
 
94
      offset = tz.first * 3600
 
95
 
 
96
      if offset < 0
 
97
        offset -= ((tz[1] || 0) * 60)
 
98
      else
 
99
        offset += ((tz[1] || 0) * 60)
 
100
      end
 
101
 
 
102
      Time.at((time - offset).to_i, us)
 
103
    end
 
104
  end
 
105
end