tickly 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -1
- data/lib/tickly/parser.rb +29 -4
- data/lib/tickly.rb +1 -1
- data/test/test-data/huge_nuke_tcl.tcl +331 -0
- data/test/test_profile.rb +27 -0
- data/tickly.gemspec +9 -4
- metadata +22 -4
data/Gemfile
CHANGED
@@ -3,7 +3,7 @@ source "http://rubygems.org"
|
|
3
3
|
# Example:
|
4
4
|
# gem "activesupport", ">= 2.3.5"
|
5
5
|
|
6
|
-
gem "bychar", "~> 1.0"
|
6
|
+
gem "bychar", "~> 1.0.1"
|
7
7
|
|
8
8
|
# Add dependencies to develop your gem here.
|
9
9
|
# Include everything needed to run rake, tests, features, etc.
|
@@ -12,4 +12,5 @@ group :development do
|
|
12
12
|
gem "rdoc", "~> 3.12"
|
13
13
|
gem "bundler"
|
14
14
|
gem "jeweler", "~> 1.8.3"
|
15
|
+
gem "ruby-prof"
|
15
16
|
end
|
data/lib/tickly/parser.rb
CHANGED
@@ -3,6 +3,23 @@ require 'bychar'
|
|
3
3
|
|
4
4
|
module Tickly
|
5
5
|
|
6
|
+
|
7
|
+
# Since you parse char by char, you will likely call
|
8
|
+
# eof? on each iteration. Instead. allow it to raise and do not check.
|
9
|
+
# This takes the profile time down from 36 seconds to 30 seconds
|
10
|
+
# for a large file.
|
11
|
+
class EOFError < RuntimeError #:nodoc: all
|
12
|
+
end
|
13
|
+
|
14
|
+
class W < Bychar::Reader #:nodoc: all
|
15
|
+
def read_one_byte
|
16
|
+
cache if @buf.eos?
|
17
|
+
raise EOFError if @buf.eos?
|
18
|
+
|
19
|
+
@buf.getch
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
6
23
|
# Simplistic, incomplete and most likely incorrect TCL parser
|
7
24
|
class Parser
|
8
25
|
|
@@ -13,7 +30,7 @@ module Tickly
|
|
13
30
|
def parse(io_or_str)
|
14
31
|
bare_io = io_or_str.respond_to?(:read) ? io_or_str : StringIO.new(io_or_str)
|
15
32
|
# Wrap the IO in a Bychar buffer to read faster
|
16
|
-
reader =
|
33
|
+
reader = W.new(bare_io)
|
17
34
|
sub_parse(reader)
|
18
35
|
end
|
19
36
|
|
@@ -37,9 +54,10 @@ module Tickly
|
|
37
54
|
stack = []
|
38
55
|
buf = ''
|
39
56
|
last_char_was_linebreak = false
|
40
|
-
|
57
|
+
|
58
|
+
no_eof do
|
41
59
|
char = io.read_one_byte
|
42
|
-
|
60
|
+
|
43
61
|
if buf[LAST_CHAR] != ESC
|
44
62
|
if char == stop_char # Bail out of a subexpr
|
45
63
|
stack << buf if (buf.length > 0)
|
@@ -122,9 +140,16 @@ module Tickly
|
|
122
140
|
return stack[0...previous_i] + [subexpr] + [nil]
|
123
141
|
end
|
124
142
|
|
143
|
+
def no_eof(&blk)
|
144
|
+
begin
|
145
|
+
loop(&blk)
|
146
|
+
rescue EOFError
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
125
150
|
def parse_str(io, stop_char)
|
126
151
|
buf = ''
|
127
|
-
|
152
|
+
no_eof do
|
128
153
|
c = io.read_one_byte
|
129
154
|
if c == stop_char && buf[LAST_CHAR] != ESC
|
130
155
|
return buf
|