symphony 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d010875d95ecf17ce0545379d8192f0af823d93a
4
- data.tar.gz: 94e08919b08b5a95e68ddc8989de48419e7c9275
3
+ metadata.gz: e56f49638e5786e9f84f0411f4065d2766582ea1
4
+ data.tar.gz: 2fd2aed4198733e2a6295a758eca506daa60f5db
5
5
  SHA512:
6
- metadata.gz: 117430acaa264b8160de3df95869a34ffaf2dbe0e471269e333838ee52058fc4bd7932bcb99bccd38cbd00cd876c02addf413d15780a9d2fd132358321d1e966
7
- data.tar.gz: ffed928bb686cd2aa65d82d696e1e487564e65d7b5f6b78a9a7a47ff71e303d5bb83a10257714333f4deca80d0381a246921610c9cca0758ff83482121ee5900
6
+ metadata.gz: 9d382c108292a680028806b3807a24475cee35d7d48b79eccba152eb27adb62136b68c0a99f5622668f44ffaf332048f4418a6140bf2d020525acf3f2df2f872
7
+ data.tar.gz: 90bee202f40bf9791f81775df6879adff6b2e07ed19101286f4eb3c47b2628306e80a5dd0678f0cb93b9662a3fef92d36159a0e4c2596707bb33c80bb81947c7
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
data/ChangeLog CHANGED
@@ -1,9 +1,47 @@
1
+ 2014-04-04 Mahlon E. Smith <mahlon@laika.com>
2
+
3
+ * .hgignore, Manifest.txt, Rakefile,
4
+ lib/symphony/intervalexpression.rl, lib/symphony/mixins.rb,
5
+ spec/symphony/intervalexpression_spec.rb,
6
+ spec/symphony/mixins_spec.rb:
7
+ Add an interval expression parsing library in preparation for
8
+ Symphony scheduling.
9
+ [cddc160bc76f] [tip]
10
+
11
+ 2014-04-01 Michael Granger <ged@FaerieMUD.org>
12
+
13
+ * Rakefile:
14
+ Add direct dependency on loggability
15
+ [3afd6890a914] [github/master]
16
+
17
+ * TODO.md:
18
+ Update TODO list
19
+ [3615936701c5]
20
+
21
+ * lib/symphony/tasks/pinger.rb:
22
+ Remove the pinger example task
23
+ [cd84bece7998]
24
+
25
+ 2014-03-29 Michael Granger <ged@FaerieMUD.org>
26
+
27
+ * .hgtags:
28
+ Added tag v0.4.0 for changeset ccf6adfeb268
29
+ [a5c661d2b122]
30
+
31
+ * .hgsigs:
32
+ Added signature for changeset 855c7801eaea
33
+ [ccf6adfeb268] [v0.4.0]
34
+
35
+ * History.rdoc, Rakefile, lib/symphony.rb:
36
+ Bump the minor version, update history.
37
+ [855c7801eaea]
38
+
1
39
  2014-03-28 Mahlon E. Smith <mahlon@laika.com>
2
40
 
3
41
  * lib/symphony/signal_handling.rb:
4
42
  Just return true if a signal was handled in wait_for_signals(), or
5
43
  false if a timeout occurred.
6
- [aa8c912414a6] [tip]
44
+ [aa8c912414a6]
7
45
 
8
46
  * lib/symphony/signal_handling.rb:
9
47
  Add an optional (disabled by default) timeout for the signal
@@ -29,7 +67,7 @@
29
67
  spec/symphony/daemon_spec.rb, spec/symphony/task_spec.rb,
30
68
  spec/symphony_spec.rb:
31
69
  Add some more Task specs, add a placeholder for Daemon specs.
32
- [97812070cd5b] [github/master]
70
+ [97812070cd5b]
33
71
 
34
72
  * TODO.md, USAGE.rdoc:
35
73
  Update docs until we implement the generic plugin system
data/History.rdoc CHANGED
@@ -1,3 +1,10 @@
1
+ == v0.5.0 [2014-04-08] Michael Granger <ged@FaerieMUD.org>
2
+
3
+ - Don't set up default signal handlers for WINCH and CHLD for Tasks.
4
+ - Add an interval expression parsing library in preparation for
5
+ Symphony scheduling.
6
+
7
+
1
8
  == v0.4.0 [2014-03-28] Mahlon E. Smith <mahlon@martini.nu>
2
9
 
3
10
  Enhancement:
data/Manifest.txt CHANGED
@@ -11,6 +11,7 @@ bin/symphony-task
11
11
  etc/config.yml.example
12
12
  lib/symphony.rb
13
13
  lib/symphony/daemon.rb
14
+ lib/symphony/intervalexpression.rb
14
15
  lib/symphony/metrics.rb
15
16
  lib/symphony/mixins.rb
16
17
  lib/symphony/queue.rb
@@ -19,12 +20,12 @@ lib/symphony/signal_handling.rb
19
20
  lib/symphony/task.rb
20
21
  lib/symphony/tasks/auditor.rb
21
22
  lib/symphony/tasks/failure_logger.rb
22
- lib/symphony/tasks/pinger.rb
23
23
  lib/symphony/tasks/simulator.rb
24
24
  lib/symphony/tasks/ssh.rb
25
25
  lib/symphony/tasks/sshscript.rb
26
26
  spec/helpers.rb
27
27
  spec/symphony/daemon_spec.rb
28
+ spec/symphony/intervalexpression_spec.rb
28
29
  spec/symphony/mixins_spec.rb
29
30
  spec/symphony/queue_spec.rb
30
31
  spec/symphony/task_spec.rb
data/Rakefile CHANGED
@@ -1,12 +1,22 @@
1
1
  #!/usr/bin/env rake
2
2
 
3
+ require 'pathname'
4
+
3
5
  begin
4
6
  require 'hoe'
5
7
  rescue LoadError
6
8
  abort "This Rakefile requires hoe (gem install hoe)"
7
9
  end
8
10
 
9
- GEMSPEC = 'symphony.gemspec'
11
+
12
+ BASEDIR = Pathname( __FILE__ ).dirname.relative_path_from( Pathname.pwd )
13
+
14
+ LIBDIR = BASEDIR + 'lib'
15
+ SYMPHONY_LIBDIR = LIBDIR + 'symphony'
16
+
17
+ GEMSPEC = BASEDIR + 'symphony.gemspec'
18
+ EXPRESSION_RL = SYMPHONY_LIBDIR + 'intervalexpression.rl'
19
+ EXPRESSION_RB = SYMPHONY_LIBDIR + 'intervalexpression.rb'
10
20
 
11
21
 
12
22
  Hoe.plugin :mercurial
@@ -27,6 +37,7 @@ hoespec = Hoe.spec 'symphony' do |spec|
27
37
  spec.developer 'Michael Granger', 'ged@FaerieMUD.org'
28
38
  spec.developer 'Mahlon E. Smith', 'mahlon@martini.nu'
29
39
 
40
+ spec.dependency 'loggability', '~> 0.10'
30
41
  spec.dependency 'pluggability', '~> 0.4'
31
42
  spec.dependency 'bunny', '~> 1.1'
32
43
  spec.dependency 'sysexits', '~> 1.1'
@@ -42,6 +53,8 @@ hoespec = Hoe.spec 'symphony' do |spec|
42
53
 
43
54
  spec.require_ruby_version( '>=2.0.0' )
44
55
  spec.hg_sign_tags = true if spec.respond_to?( :hg_sign_tags= )
56
+ spec.quality_check_whitelist.include( EXPRESSION_RB.to_s ) if
57
+ spec.respond_to?( :quality_check_whitelist )
45
58
 
46
59
  self.rdoc_locations << "deveiate:/usr/local/www/public/code/#{remote_rdoc_dir}"
47
60
  end
@@ -51,10 +64,12 @@ ENV['VERSION'] ||= hoespec.spec.version.to_s
51
64
  # Run the tests before checking in
52
65
  task 'hg:precheckin' => [ :check_history, :check_manifest, :spec ]
53
66
 
67
+
54
68
  # Rebuild the ChangeLog immediately before release
55
69
  task :prerelease => 'ChangeLog'
56
70
  CLOBBER.include( 'ChangeLog' )
57
71
 
72
+
58
73
  desc "Build a coverage report"
59
74
  task :coverage do
60
75
  ENV["COVERAGE"] = 'yes'
@@ -62,6 +77,16 @@ task :coverage do
62
77
  end
63
78
 
64
79
 
80
+ # Generate the expression parser with Ragel
81
+ file EXPRESSION_RL
82
+ file EXPRESSION_RB
83
+ task EXPRESSION_RB => EXPRESSION_RL do |task|
84
+ sh 'ragel', '-R', '-T1', '-Ls', task.prerequisites.first
85
+ end
86
+ task :spec => EXPRESSION_RB
87
+
88
+
89
+ # Generate a .gemspec file for integration with systems that read it
65
90
  task :gemspec => GEMSPEC
66
91
  file GEMSPEC => __FILE__ do |task|
67
92
  spec = $hoespec.spec
@@ -71,6 +96,5 @@ file GEMSPEC => __FILE__ do |task|
71
96
  fh.write( spec.to_ruby )
72
97
  end
73
98
  end
74
-
75
99
  task :default => :gemspec
76
100
 
data/TODO.md CHANGED
@@ -1,6 +1,4 @@
1
1
 
2
- [ ] Convert routing / metrics to 'plugins' syntax (inside/outside for prepend/include)
3
2
  [ ] Update pinger/ssh/sshscript
4
3
  [ ] Per Task throttling for daemon
5
4
  [ ] Task scaling (min/max settings), check queue backlog during received message
6
- [ ] Make the block of routes declared with on() method accept various arities
data/lib/symphony.rb CHANGED
@@ -12,10 +12,10 @@ module Symphony
12
12
  Configurability
13
13
 
14
14
  # Library version constant
15
- VERSION = '0.4.0'
15
+ VERSION = '0.5.0'
16
16
 
17
17
  # Version-control revision constant
18
- REVISION = %q$Revision: 855c7801eaea $
18
+ REVISION = %q$Revision: 369353a62297 $
19
19
 
20
20
 
21
21
  # The name of the environment variable to check for config file overrides
@@ -0,0 +1,1216 @@
1
+
2
+ # vim: set noet nosta sw=4 ts=4 ft=ragel :
3
+
4
+
5
+
6
+
7
+
8
+ require 'symphony' unless defined?( Symphony )
9
+ require 'symphony/mixins'
10
+ require 'time'
11
+
12
+ using Symphony::TimeRefinements
13
+
14
+
15
+ ### Parse natural English expressions of times and intervals.
16
+ ###
17
+ ### in 30 minutes
18
+ ### once an hour
19
+ ### every 15 minutes for 2 days
20
+ ### starting on 2014-05-01
21
+ ### at 2014-04-01 14:00:25
22
+ ### at 2pm
23
+ ### starting at 2pm once a day
24
+ ### start in 1 hour from now run every 5 seconds end at 11:15pm
25
+ ### every other hour
26
+ ### once a day ending in 1 week
27
+ ### 10 times a minute for 2 days
28
+ ### run 45 times every hour
29
+ ### start at 2010-01-02 run 12 times and end on 2010-01-03
30
+ ### starting in an hour from now run 6 times a minute for 2 hours
31
+ ### beginning a day from now, run 30 times per minute and finish in 2 weeks
32
+ ###
33
+ class Symphony::IntervalExpression
34
+ include Comparable,
35
+ Symphony::TimeFunctions
36
+ extend Loggability
37
+
38
+ log_to :symphony
39
+
40
+ # Ragel accessors are injected as class methods/variables for some reason.
41
+
42
+ class << self
43
+ attr_accessor :_interval_expression_key_offsets
44
+ private :_interval_expression_key_offsets, :_interval_expression_key_offsets=
45
+ end
46
+ self._interval_expression_key_offsets = [
47
+ 0, 0, 10, 15, 19, 20, 21, 22,
48
+ 23, 40, 45, 54, 55, 56, 63, 64,
49
+ 65, 69, 84, 89, 94, 96, 97, 99,
50
+ 101, 102, 104, 106, 112, 114, 115, 117,
51
+ 119, 123, 124, 125, 126, 127, 128, 129,
52
+ 130, 132, 134, 136, 138, 140, 141, 149,
53
+ 158, 159, 160, 161, 162, 163, 165, 167,
54
+ 168, 169, 170, 171, 172, 173, 174, 175,
55
+ 176, 177, 178, 179, 180, 181, 182, 183,
56
+ 184, 185, 186, 194, 199, 205, 210, 215,
57
+ 218, 221, 226, 227, 230, 243, 247, 248,
58
+ 249, 250, 251, 253, 254, 255, 258, 261,
59
+ 262, 263, 264, 265, 266, 269, 285, 286,
60
+ 287, 288, 289, 290, 291, 292, 293, 294,
61
+ 295, 296, 297, 298, 305, 307, 308, 309,
62
+ 310, 311, 312, 313, 314, 315, 316, 317,
63
+ 319, 321, 322, 323, 324, 325, 326, 327,
64
+ 328, 329, 330, 331, 332, 333, 334, 335,
65
+ 336, 337, 338, 339, 340, 344, 347, 350,
66
+ 351, 352, 355, 368, 369, 370, 371, 372,
67
+ 373, 374, 375, 377, 378, 379, 382, 396,
68
+ 397, 398, 400, 401, 404, 409, 414, 419,
69
+ 421, 422, 424, 426, 427, 429, 431, 440,
70
+ 442, 443, 445, 447, 449, 451, 453, 455,
71
+ 457, 458, 459, 460, 461, 462, 467, 482,
72
+ 487, 492, 494, 495, 497, 499, 500, 502,
73
+ 504, 508, 520, 525, 531, 533, 535, 540,
74
+ 552, 555, 556, 557, 561, 571, 573, 574,
75
+ 575, 579, 580, 581, 584, 585, 586, 587,
76
+ 588, 589, 590, 591, 595, 606, 607, 608,
77
+ 611, 614, 618, 620, 622, 626, 628, 630,
78
+ 632, 633, 641, 650, 651, 652, 657, 661,
79
+ 662, 663, 664, 666, 668, 669, 670, 671,
80
+ 672, 673, 674, 675, 676, 677, 678, 679,
81
+ 680, 681, 682, 683, 684, 685, 686, 687,
82
+ 695, 700, 706, 711, 716, 719, 722, 727,
83
+ 728, 731, 744, 748, 749, 750, 751, 752,
84
+ 754, 755, 756, 759, 763, 764, 765, 766,
85
+ 767, 770, 774, 777, 781, 781, 784, 788,
86
+ 791, 794, 797, 800, 804
87
+ ]
88
+
89
+ class << self
90
+ attr_accessor :_interval_expression_trans_keys
91
+ private :_interval_expression_trans_keys, :_interval_expression_trans_keys=
92
+ end
93
+ self._interval_expression_trans_keys = [
94
+ 97, 98, 101, 105, 111, 112, 114, 115,
95
+ 48, 57, 32, 9, 13, 48, 57, 32,
96
+ 116, 9, 13, 105, 109, 101, 115, 32,
97
+ 97, 100, 101, 102, 104, 109, 111, 112,
98
+ 115, 117, 119, 121, 9, 13, 49, 57,
99
+ 32, 9, 13, 48, 57, 32, 100, 104,
100
+ 109, 115, 119, 121, 9, 13, 97, 121,
101
+ 32, 101, 102, 115, 117, 9, 13, 110,
102
+ 100, 32, 105, 9, 13, 32, 48, 97,
103
+ 100, 104, 105, 109, 111, 115, 119, 121,
104
+ 9, 13, 49, 57, 58, 97, 112, 48,
105
+ 57, 58, 97, 112, 48, 57, 48, 57,
106
+ 45, 48, 57, 48, 57, 45, 48, 57,
107
+ 48, 57, 32, 102, 9, 13, 48, 57,
108
+ 48, 57, 58, 48, 57, 48, 57, 32,
109
+ 102, 9, 13, 114, 111, 109, 32, 110,
110
+ 111, 119, 48, 57, 48, 57, 48, 57,
111
+ 48, 57, 97, 112, 109, 32, 58, 97,
112
+ 112, 9, 13, 48, 57, 32, 100, 104,
113
+ 109, 115, 119, 121, 9, 13, 97, 121,
114
+ 111, 117, 114, 105, 111, 108, 110, 108,
115
+ 105, 115, 101, 99, 111, 110, 100, 117,
116
+ 116, 101, 110, 116, 104, 101, 101, 107,
117
+ 101, 97, 32, 58, 97, 112, 9, 13,
118
+ 48, 57, 32, 9, 13, 48, 57, 32,
119
+ 45, 9, 13, 48, 57, 32, 9, 13,
120
+ 48, 57, 32, 110, 116, 9, 13, 32,
121
+ 9, 13, 32, 9, 13, 32, 9, 13,
122
+ 48, 57, 110, 32, 9, 13, 32, 97,
123
+ 100, 104, 109, 111, 115, 119, 121, 9,
124
+ 13, 49, 57, 32, 110, 9, 13, 116,
125
+ 104, 101, 114, 110, 116, 110, 103, 32,
126
+ 9, 13, 105, 111, 114, 110, 105, 115,
127
+ 104, 114, 32, 9, 13, 32, 48, 97,
128
+ 100, 104, 105, 109, 111, 115, 116, 119,
129
+ 121, 9, 13, 49, 57, 104, 101, 32,
130
+ 110, 101, 120, 116, 111, 109, 32, 110,
131
+ 111, 119, 32, 101, 102, 115, 117, 9,
132
+ 13, 105, 111, 116, 111, 112, 110, 116,
133
+ 105, 108, 111, 117, 114, 105, 111, 108,
134
+ 110, 108, 105, 115, 101, 99, 111, 110,
135
+ 100, 117, 116, 101, 110, 116, 104, 101,
136
+ 101, 107, 101, 97, 32, 110, 9, 13,
137
+ 32, 9, 13, 97, 110, 118, 99, 104,
138
+ 32, 9, 13, 32, 97, 100, 104, 109,
139
+ 111, 115, 119, 121, 9, 13, 49, 57,
140
+ 116, 104, 101, 114, 101, 114, 121, 110,
141
+ 116, 99, 101, 32, 9, 13, 32, 97,
142
+ 100, 104, 109, 111, 112, 115, 119, 121,
143
+ 9, 13, 49, 57, 101, 114, 101, 116,
144
+ 116, 32, 9, 13, 32, 9, 13, 48,
145
+ 57, 58, 97, 112, 48, 57, 58, 97,
146
+ 112, 48, 57, 48, 57, 45, 48, 57,
147
+ 48, 57, 45, 48, 57, 48, 57, 32,
148
+ 101, 102, 115, 117, 9, 13, 48, 57,
149
+ 48, 57, 58, 48, 57, 48, 57, 48,
150
+ 57, 48, 57, 48, 57, 48, 57, 97,
151
+ 112, 109, 101, 103, 105, 110, 32, 105,
152
+ 110, 9, 13, 32, 48, 97, 100, 104,
153
+ 105, 109, 111, 115, 119, 121, 9, 13,
154
+ 49, 57, 58, 97, 112, 48, 57, 58,
155
+ 97, 112, 48, 57, 48, 57, 45, 48,
156
+ 57, 48, 57, 45, 48, 57, 48, 57,
157
+ 32, 44, 9, 13, 32, 97, 101, 102,
158
+ 105, 111, 112, 114, 9, 13, 48, 57,
159
+ 32, 9, 13, 48, 57, 32, 58, 9,
160
+ 13, 48, 57, 48, 57, 48, 57, 32,
161
+ 44, 58, 9, 13, 32, 97, 101, 102,
162
+ 105, 111, 112, 114, 9, 13, 48, 57,
163
+ 97, 118, 120, 101, 99, 32, 117, 9,
164
+ 13, 32, 97, 101, 105, 111, 112, 9,
165
+ 13, 48, 57, 97, 118, 110, 110, 32,
166
+ 99, 9, 13, 116, 101, 32, 9, 13,
167
+ 114, 111, 109, 32, 110, 111, 119, 32,
168
+ 44, 9, 13, 32, 97, 101, 105, 111,
169
+ 112, 114, 9, 13, 48, 57, 117, 110,
170
+ 32, 9, 13, 32, 9, 13, 32, 102,
171
+ 9, 13, 48, 57, 48, 57, 32, 44,
172
+ 9, 13, 48, 57, 48, 57, 97, 112,
173
+ 109, 32, 58, 97, 112, 9, 13, 48,
174
+ 57, 32, 100, 104, 109, 115, 119, 121,
175
+ 9, 13, 97, 121, 32, 44, 115, 9,
176
+ 13, 32, 44, 9, 13, 111, 117, 114,
177
+ 105, 111, 108, 110, 108, 105, 115, 101,
178
+ 99, 111, 110, 100, 117, 116, 101, 110,
179
+ 116, 104, 101, 101, 107, 101, 97, 32,
180
+ 58, 97, 112, 9, 13, 48, 57, 32,
181
+ 9, 13, 48, 57, 32, 45, 9, 13,
182
+ 48, 57, 32, 9, 13, 48, 57, 32,
183
+ 110, 116, 9, 13, 32, 9, 13, 32,
184
+ 9, 13, 32, 9, 13, 48, 57, 110,
185
+ 32, 9, 13, 32, 97, 100, 104, 109,
186
+ 111, 115, 119, 121, 9, 13, 49, 57,
187
+ 32, 110, 9, 13, 116, 104, 101, 114,
188
+ 110, 116, 110, 103, 32, 9, 13, 32,
189
+ 105, 9, 13, 116, 97, 114, 116, 32,
190
+ 9, 13, 32, 115, 9, 13, 32, 9,
191
+ 13, 32, 58, 9, 13, 32, 9, 13,
192
+ 32, 115, 9, 13, 32, 9, 13, 32,
193
+ 9, 13, 32, 9, 13, 32, 9, 13,
194
+ 32, 58, 9, 13, 32, 9, 13, 0
195
+ ]
196
+
197
+ class << self
198
+ attr_accessor :_interval_expression_single_lengths
199
+ private :_interval_expression_single_lengths, :_interval_expression_single_lengths=
200
+ end
201
+ self._interval_expression_single_lengths = [
202
+ 0, 8, 1, 2, 1, 1, 1, 1,
203
+ 13, 1, 7, 1, 1, 5, 1, 1,
204
+ 2, 11, 3, 3, 0, 1, 0, 0,
205
+ 1, 0, 0, 2, 0, 1, 0, 0,
206
+ 2, 1, 1, 1, 1, 1, 1, 1,
207
+ 0, 0, 0, 0, 2, 1, 4, 7,
208
+ 1, 1, 1, 1, 1, 2, 2, 1,
209
+ 1, 1, 1, 1, 1, 1, 1, 1,
210
+ 1, 1, 1, 1, 1, 1, 1, 1,
211
+ 1, 1, 4, 1, 2, 1, 3, 1,
212
+ 1, 1, 1, 1, 9, 2, 1, 1,
213
+ 1, 1, 2, 1, 1, 1, 3, 1,
214
+ 1, 1, 1, 1, 1, 12, 1, 1,
215
+ 1, 1, 1, 1, 1, 1, 1, 1,
216
+ 1, 1, 1, 5, 2, 1, 1, 1,
217
+ 1, 1, 1, 1, 1, 1, 1, 2,
218
+ 2, 1, 1, 1, 1, 1, 1, 1,
219
+ 1, 1, 1, 1, 1, 1, 1, 1,
220
+ 1, 1, 1, 1, 2, 1, 3, 1,
221
+ 1, 1, 9, 1, 1, 1, 1, 1,
222
+ 1, 1, 2, 1, 1, 1, 10, 1,
223
+ 1, 2, 1, 1, 1, 3, 3, 0,
224
+ 1, 0, 0, 1, 0, 0, 5, 0,
225
+ 1, 0, 0, 0, 0, 0, 0, 2,
226
+ 1, 1, 1, 1, 1, 3, 11, 3,
227
+ 3, 0, 1, 0, 0, 1, 0, 0,
228
+ 2, 8, 1, 2, 0, 0, 3, 8,
229
+ 3, 1, 1, 2, 6, 2, 1, 1,
230
+ 2, 1, 1, 1, 1, 1, 1, 1,
231
+ 1, 1, 1, 2, 7, 1, 1, 1,
232
+ 1, 2, 0, 0, 2, 0, 0, 2,
233
+ 1, 4, 7, 1, 1, 3, 2, 1,
234
+ 1, 1, 2, 2, 1, 1, 1, 1,
235
+ 1, 1, 1, 1, 1, 1, 1, 1,
236
+ 1, 1, 1, 1, 1, 1, 1, 4,
237
+ 1, 2, 1, 3, 1, 1, 1, 1,
238
+ 1, 9, 2, 1, 1, 1, 1, 2,
239
+ 1, 1, 1, 2, 1, 1, 1, 1,
240
+ 1, 2, 1, 2, 0, 1, 2, 1,
241
+ 1, 1, 1, 2, 1
242
+ ]
243
+
244
+ class << self
245
+ attr_accessor :_interval_expression_range_lengths
246
+ private :_interval_expression_range_lengths, :_interval_expression_range_lengths=
247
+ end
248
+ self._interval_expression_range_lengths = [
249
+ 0, 1, 2, 1, 0, 0, 0, 0,
250
+ 2, 2, 1, 0, 0, 1, 0, 0,
251
+ 1, 2, 1, 1, 1, 0, 1, 1,
252
+ 0, 1, 1, 2, 1, 0, 1, 1,
253
+ 1, 0, 0, 0, 0, 0, 0, 0,
254
+ 1, 1, 1, 1, 0, 0, 2, 1,
255
+ 0, 0, 0, 0, 0, 0, 0, 0,
256
+ 0, 0, 0, 0, 0, 0, 0, 0,
257
+ 0, 0, 0, 0, 0, 0, 0, 0,
258
+ 0, 0, 2, 2, 2, 2, 1, 1,
259
+ 1, 2, 0, 1, 2, 1, 0, 0,
260
+ 0, 0, 0, 0, 0, 1, 0, 0,
261
+ 0, 0, 0, 0, 1, 2, 0, 0,
262
+ 0, 0, 0, 0, 0, 0, 0, 0,
263
+ 0, 0, 0, 1, 0, 0, 0, 0,
264
+ 0, 0, 0, 0, 0, 0, 0, 0,
265
+ 0, 0, 0, 0, 0, 0, 0, 0,
266
+ 0, 0, 0, 0, 0, 0, 0, 0,
267
+ 0, 0, 0, 0, 1, 1, 0, 0,
268
+ 0, 1, 2, 0, 0, 0, 0, 0,
269
+ 0, 0, 0, 0, 0, 1, 2, 0,
270
+ 0, 0, 0, 1, 2, 1, 1, 1,
271
+ 0, 1, 1, 0, 1, 1, 2, 1,
272
+ 0, 1, 1, 1, 1, 1, 1, 0,
273
+ 0, 0, 0, 0, 0, 1, 2, 1,
274
+ 1, 1, 0, 1, 1, 0, 1, 1,
275
+ 1, 2, 2, 2, 1, 1, 1, 2,
276
+ 0, 0, 0, 1, 2, 0, 0, 0,
277
+ 1, 0, 0, 1, 0, 0, 0, 0,
278
+ 0, 0, 0, 1, 2, 0, 0, 1,
279
+ 1, 1, 1, 1, 1, 1, 1, 0,
280
+ 0, 2, 1, 0, 0, 1, 1, 0,
281
+ 0, 0, 0, 0, 0, 0, 0, 0,
282
+ 0, 0, 0, 0, 0, 0, 0, 0,
283
+ 0, 0, 0, 0, 0, 0, 0, 2,
284
+ 2, 2, 2, 1, 1, 1, 2, 0,
285
+ 1, 2, 1, 0, 0, 0, 0, 0,
286
+ 0, 0, 1, 1, 0, 0, 0, 0,
287
+ 1, 1, 1, 1, 0, 1, 1, 1,
288
+ 1, 1, 1, 1, 1
289
+ ]
290
+
291
+ class << self
292
+ attr_accessor :_interval_expression_index_offsets
293
+ private :_interval_expression_index_offsets, :_interval_expression_index_offsets=
294
+ end
295
+ self._interval_expression_index_offsets = [
296
+ 0, 0, 10, 14, 18, 20, 22, 24,
297
+ 26, 42, 46, 55, 57, 59, 66, 68,
298
+ 70, 74, 88, 93, 98, 100, 102, 104,
299
+ 106, 108, 110, 112, 117, 119, 121, 123,
300
+ 125, 129, 131, 133, 135, 137, 139, 141,
301
+ 143, 145, 147, 149, 151, 154, 156, 163,
302
+ 172, 174, 176, 178, 180, 182, 185, 188,
303
+ 190, 192, 194, 196, 198, 200, 202, 204,
304
+ 206, 208, 210, 212, 214, 216, 218, 220,
305
+ 222, 224, 226, 233, 237, 242, 246, 251,
306
+ 254, 257, 261, 263, 266, 278, 282, 284,
307
+ 286, 288, 290, 293, 295, 297, 300, 304,
308
+ 306, 308, 310, 312, 314, 317, 332, 334,
309
+ 336, 338, 340, 342, 344, 346, 348, 350,
310
+ 352, 354, 356, 358, 365, 368, 370, 372,
311
+ 374, 376, 378, 380, 382, 384, 386, 388,
312
+ 391, 394, 396, 398, 400, 402, 404, 406,
313
+ 408, 410, 412, 414, 416, 418, 420, 422,
314
+ 424, 426, 428, 430, 432, 436, 439, 443,
315
+ 445, 447, 450, 462, 464, 466, 468, 470,
316
+ 472, 474, 476, 479, 481, 483, 486, 499,
317
+ 501, 503, 506, 508, 511, 515, 520, 525,
318
+ 527, 529, 531, 533, 535, 537, 539, 547,
319
+ 549, 551, 553, 555, 557, 559, 561, 563,
320
+ 566, 568, 570, 572, 574, 576, 581, 595,
321
+ 600, 605, 607, 609, 611, 613, 615, 617,
322
+ 619, 623, 634, 638, 643, 645, 647, 652,
323
+ 663, 667, 669, 671, 675, 684, 687, 689,
324
+ 691, 695, 697, 699, 702, 704, 706, 708,
325
+ 710, 712, 714, 716, 720, 730, 732, 734,
326
+ 737, 740, 744, 746, 748, 752, 754, 756,
327
+ 759, 761, 768, 777, 779, 781, 786, 790,
328
+ 792, 794, 796, 799, 802, 804, 806, 808,
329
+ 810, 812, 814, 816, 818, 820, 822, 824,
330
+ 826, 828, 830, 832, 834, 836, 838, 840,
331
+ 847, 851, 856, 860, 865, 868, 871, 875,
332
+ 877, 880, 892, 896, 898, 900, 902, 904,
333
+ 907, 909, 911, 914, 918, 920, 922, 924,
334
+ 926, 929, 933, 936, 940, 941, 944, 948,
335
+ 951, 954, 957, 960, 964
336
+ ]
337
+
338
+ class << self
339
+ attr_accessor :_interval_expression_trans_targs
340
+ private :_interval_expression_trans_targs, :_interval_expression_trans_targs=
341
+ end
342
+ self._interval_expression_trans_targs = [
343
+ 170, 193, 216, 222, 223, 167, 237, 300,
344
+ 2, 0, 3, 3, 2, 0, 3, 4,
345
+ 3, 0, 5, 0, 6, 0, 7, 0,
346
+ 304, 0, 8, 148, 11, 150, 94, 124,
347
+ 127, 162, 167, 169, 120, 143, 146, 8,
348
+ 9, 0, 10, 10, 9, 0, 10, 11,
349
+ 124, 127, 132, 143, 146, 10, 0, 12,
350
+ 0, 305, 0, 13, 14, 94, 117, 120,
351
+ 13, 0, 15, 0, 16, 0, 17, 91,
352
+ 17, 0, 17, 18, 78, 48, 50, 82,
353
+ 53, 90, 58, 69, 72, 17, 46, 0,
354
+ 42, 45, 45, 19, 0, 42, 45, 45,
355
+ 20, 0, 21, 0, 22, 0, 23, 0,
356
+ 24, 0, 25, 0, 26, 0, 306, 0,
357
+ 27, 33, 27, 28, 0, 29, 0, 30,
358
+ 0, 31, 0, 307, 0, 32, 33, 32,
359
+ 0, 34, 0, 35, 0, 36, 0, 37,
360
+ 0, 38, 0, 39, 0, 308, 0, 41,
361
+ 0, 309, 0, 43, 0, 44, 0, 45,
362
+ 45, 0, 309, 0, 47, 42, 45, 45,
363
+ 47, 74, 0, 47, 48, 50, 53, 58,
364
+ 69, 72, 47, 0, 49, 0, 310, 0,
365
+ 51, 0, 52, 0, 310, 0, 54, 66,
366
+ 0, 55, 63, 0, 56, 0, 57, 0,
367
+ 58, 0, 59, 0, 60, 0, 61, 0,
368
+ 62, 0, 310, 0, 64, 0, 65, 0,
369
+ 310, 0, 67, 0, 68, 0, 310, 0,
370
+ 70, 0, 71, 0, 310, 0, 73, 0,
371
+ 52, 0, 47, 42, 45, 45, 47, 75,
372
+ 0, 47, 47, 76, 0, 47, 22, 47,
373
+ 77, 0, 47, 47, 77, 0, 47, 79,
374
+ 80, 47, 0, 47, 47, 0, 81, 81,
375
+ 0, 81, 81, 18, 0, 83, 0, 84,
376
+ 84, 0, 84, 85, 48, 50, 53, 86,
377
+ 58, 69, 72, 84, 77, 0, 47, 79,
378
+ 47, 0, 87, 0, 88, 0, 89, 0,
379
+ 79, 0, 80, 87, 0, 92, 0, 93,
380
+ 0, 17, 17, 0, 95, 99, 109, 0,
381
+ 96, 0, 97, 0, 98, 0, 16, 0,
382
+ 100, 0, 101, 17, 0, 17, 18, 78,
383
+ 48, 50, 82, 53, 90, 58, 102, 69,
384
+ 72, 17, 46, 0, 103, 0, 104, 0,
385
+ 105, 0, 106, 0, 107, 0, 108, 0,
386
+ 93, 0, 110, 0, 111, 0, 112, 0,
387
+ 113, 0, 114, 0, 312, 0, 115, 14,
388
+ 116, 117, 120, 115, 0, 95, 99, 0,
389
+ 118, 0, 119, 0, 16, 0, 121, 0,
390
+ 122, 0, 123, 0, 93, 0, 125, 0,
391
+ 126, 0, 305, 0, 128, 140, 0, 129,
392
+ 137, 0, 130, 0, 131, 0, 132, 0,
393
+ 133, 0, 134, 0, 135, 0, 136, 0,
394
+ 305, 0, 138, 0, 139, 0, 305, 0,
395
+ 141, 0, 142, 0, 305, 0, 144, 0,
396
+ 145, 0, 305, 0, 147, 0, 126, 0,
397
+ 10, 149, 10, 0, 10, 10, 0, 151,
398
+ 15, 159, 0, 152, 0, 153, 0, 154,
399
+ 154, 0, 154, 148, 11, 124, 127, 155,
400
+ 132, 143, 146, 154, 9, 0, 156, 0,
401
+ 157, 0, 158, 0, 149, 0, 160, 0,
402
+ 161, 0, 153, 0, 163, 156, 0, 164,
403
+ 0, 165, 0, 166, 154, 0, 154, 148,
404
+ 11, 124, 127, 155, 167, 132, 143, 146,
405
+ 154, 9, 0, 168, 0, 153, 0, 133,
406
+ 118, 0, 171, 0, 172, 172, 0, 172,
407
+ 172, 173, 0, 189, 192, 192, 174, 0,
408
+ 189, 192, 192, 175, 0, 176, 0, 177,
409
+ 0, 178, 0, 179, 0, 180, 0, 181,
410
+ 0, 314, 0, 182, 14, 94, 117, 120,
411
+ 182, 183, 0, 184, 0, 185, 0, 186,
412
+ 0, 315, 0, 188, 0, 316, 0, 190,
413
+ 0, 191, 0, 192, 192, 0, 316, 0,
414
+ 194, 0, 195, 0, 196, 0, 197, 0,
415
+ 198, 296, 299, 198, 0, 198, 199, 283,
416
+ 251, 255, 287, 258, 295, 263, 274, 277,
417
+ 198, 249, 0, 245, 248, 248, 200, 0,
418
+ 245, 248, 248, 201, 0, 202, 0, 203,
419
+ 0, 204, 0, 205, 0, 206, 0, 207,
420
+ 0, 208, 0, 209, 240, 209, 0, 209,
421
+ 170, 216, 228, 222, 223, 167, 237, 209,
422
+ 210, 0, 3, 3, 211, 0, 3, 212,
423
+ 3, 2, 0, 213, 0, 214, 0, 215,
424
+ 240, 242, 215, 0, 215, 170, 216, 228,
425
+ 222, 223, 167, 237, 215, 2, 0, 151,
426
+ 159, 217, 0, 218, 0, 219, 0, 220,
427
+ 225, 220, 0, 220, 170, 221, 222, 223,
428
+ 167, 220, 2, 0, 151, 159, 0, 153,
429
+ 0, 224, 0, 172, 164, 172, 0, 226,
430
+ 0, 227, 0, 220, 220, 0, 229, 0,
431
+ 230, 0, 231, 0, 232, 0, 233, 0,
432
+ 234, 0, 235, 0, 236, 239, 236, 0,
433
+ 236, 170, 216, 222, 223, 167, 237, 236,
434
+ 2, 0, 238, 0, 227, 0, 236, 236,
435
+ 0, 241, 241, 0, 241, 228, 241, 0,
436
+ 243, 0, 244, 0, 215, 240, 215, 0,
437
+ 246, 0, 247, 0, 248, 248, 0, 244,
438
+ 0, 250, 245, 248, 248, 250, 279, 0,
439
+ 250, 251, 255, 258, 263, 274, 277, 250,
440
+ 0, 252, 0, 253, 0, 215, 240, 254,
441
+ 215, 0, 215, 240, 215, 0, 256, 0,
442
+ 257, 0, 253, 0, 259, 271, 0, 260,
443
+ 268, 0, 261, 0, 262, 0, 263, 0,
444
+ 264, 0, 265, 0, 266, 0, 267, 0,
445
+ 253, 0, 269, 0, 270, 0, 253, 0,
446
+ 272, 0, 273, 0, 253, 0, 275, 0,
447
+ 276, 0, 253, 0, 278, 0, 257, 0,
448
+ 250, 245, 248, 248, 250, 280, 0, 250,
449
+ 250, 281, 0, 250, 203, 250, 282, 0,
450
+ 250, 250, 282, 0, 250, 284, 285, 250,
451
+ 0, 250, 250, 0, 286, 286, 0, 286,
452
+ 286, 199, 0, 288, 0, 289, 289, 0,
453
+ 289, 290, 251, 255, 258, 291, 263, 274,
454
+ 277, 289, 282, 0, 250, 284, 250, 0,
455
+ 292, 0, 293, 0, 294, 0, 284, 0,
456
+ 285, 292, 0, 297, 0, 298, 0, 198,
457
+ 198, 0, 198, 296, 198, 0, 301, 0,
458
+ 302, 0, 303, 0, 299, 0, 8, 8,
459
+ 0, 13, 313, 13, 0, 27, 27, 0,
460
+ 32, 40, 32, 0, 0, 32, 32, 0,
461
+ 32, 311, 32, 0, 32, 32, 0, 115,
462
+ 115, 0, 13, 13, 0, 182, 182, 0,
463
+ 13, 187, 13, 0, 13, 13, 0, 0
464
+ ]
465
+
466
+ class << self
467
+ attr_accessor :_interval_expression_trans_actions
468
+ private :_interval_expression_trans_actions, :_interval_expression_trans_actions=
469
+ end
470
+ self._interval_expression_trans_actions = [
471
+ 0, 0, 0, 0, 0, 0, 0, 0,
472
+ 1, 0, 0, 0, 0, 0, 0, 0,
473
+ 0, 0, 0, 0, 0, 0, 0, 0,
474
+ 2, 0, 0, 1, 1, 0, 0, 1,
475
+ 1, 1, 0, 1, 0, 1, 1, 0,
476
+ 1, 3, 0, 0, 0, 0, 0, 0,
477
+ 0, 0, 0, 0, 0, 0, 0, 0,
478
+ 0, 0, 0, 0, 0, 0, 0, 0,
479
+ 0, 3, 0, 3, 0, 3, 0, 0,
480
+ 0, 3, 0, 1, 1, 1, 1, 0,
481
+ 1, 1, 1, 1, 1, 0, 1, 3,
482
+ 0, 0, 0, 0, 3, 0, 0, 0,
483
+ 0, 3, 0, 3, 0, 3, 0, 3,
484
+ 0, 3, 0, 3, 0, 3, 0, 3,
485
+ 0, 0, 0, 0, 3, 0, 3, 0,
486
+ 3, 0, 3, 0, 3, 0, 0, 0,
487
+ 3, 0, 3, 0, 3, 0, 3, 0,
488
+ 3, 0, 3, 0, 3, 0, 3, 0,
489
+ 3, 0, 3, 0, 3, 0, 3, 0,
490
+ 0, 3, 0, 3, 0, 0, 0, 0,
491
+ 0, 0, 3, 0, 0, 0, 0, 0,
492
+ 0, 0, 0, 3, 0, 3, 0, 3,
493
+ 0, 3, 0, 3, 0, 3, 0, 0,
494
+ 3, 0, 0, 3, 0, 3, 0, 3,
495
+ 0, 3, 0, 3, 0, 3, 0, 3,
496
+ 0, 3, 0, 3, 0, 3, 0, 3,
497
+ 0, 3, 0, 3, 0, 3, 0, 3,
498
+ 0, 3, 0, 3, 0, 3, 0, 3,
499
+ 0, 3, 0, 0, 0, 0, 0, 0,
500
+ 3, 0, 0, 0, 3, 0, 0, 0,
501
+ 0, 3, 0, 0, 0, 3, 0, 0,
502
+ 0, 0, 3, 0, 0, 3, 0, 0,
503
+ 3, 0, 0, 1, 3, 0, 3, 0,
504
+ 0, 3, 0, 1, 1, 1, 1, 1,
505
+ 1, 1, 1, 0, 1, 3, 0, 0,
506
+ 0, 3, 0, 3, 0, 3, 0, 3,
507
+ 0, 3, 0, 0, 3, 0, 3, 0,
508
+ 3, 0, 0, 3, 0, 0, 0, 3,
509
+ 0, 3, 0, 3, 0, 3, 0, 3,
510
+ 0, 3, 0, 0, 3, 0, 1, 1,
511
+ 1, 1, 0, 1, 1, 1, 0, 1,
512
+ 1, 0, 1, 3, 0, 3, 0, 3,
513
+ 0, 3, 0, 3, 0, 3, 0, 3,
514
+ 0, 3, 0, 0, 0, 0, 0, 0,
515
+ 0, 0, 0, 0, 0, 0, 0, 0,
516
+ 0, 0, 0, 0, 3, 0, 0, 3,
517
+ 0, 3, 0, 3, 0, 3, 0, 3,
518
+ 0, 3, 0, 3, 0, 3, 0, 0,
519
+ 0, 0, 0, 0, 0, 0, 0, 0,
520
+ 0, 0, 0, 0, 0, 0, 0, 0,
521
+ 0, 0, 0, 0, 0, 0, 0, 0,
522
+ 0, 0, 0, 0, 0, 0, 0, 0,
523
+ 0, 0, 0, 0, 0, 0, 0, 0,
524
+ 0, 0, 0, 0, 0, 0, 0, 0,
525
+ 0, 0, 0, 0, 0, 0, 0, 0,
526
+ 0, 0, 3, 0, 0, 2, 0, 0,
527
+ 0, 0, 0, 1, 1, 1, 1, 1,
528
+ 1, 1, 1, 0, 1, 0, 0, 0,
529
+ 0, 0, 0, 0, 0, 0, 0, 0,
530
+ 0, 0, 2, 0, 0, 0, 0, 0,
531
+ 0, 2, 0, 0, 0, 0, 0, 1,
532
+ 1, 1, 1, 1, 0, 1, 1, 1,
533
+ 0, 1, 0, 0, 0, 2, 0, 0,
534
+ 0, 3, 0, 0, 0, 0, 0, 0,
535
+ 0, 1, 0, 0, 0, 0, 0, 0,
536
+ 0, 0, 0, 0, 0, 0, 0, 0,
537
+ 0, 0, 0, 0, 0, 0, 0, 0,
538
+ 0, 0, 0, 0, 0, 0, 0, 0,
539
+ 0, 0, 3, 0, 0, 0, 0, 0,
540
+ 0, 0, 0, 0, 0, 0, 0, 0,
541
+ 0, 0, 0, 0, 0, 0, 0, 0,
542
+ 0, 0, 0, 0, 0, 0, 0, 0,
543
+ 0, 0, 0, 0, 0, 0, 1, 1,
544
+ 1, 1, 0, 1, 1, 1, 1, 1,
545
+ 0, 1, 0, 0, 0, 0, 0, 0,
546
+ 0, 0, 0, 0, 0, 0, 0, 0,
547
+ 0, 0, 0, 0, 0, 0, 0, 0,
548
+ 0, 0, 0, 4, 4, 4, 0, 0,
549
+ 0, 0, 0, 0, 0, 0, 0, 0,
550
+ 1, 0, 0, 0, 0, 0, 0, 0,
551
+ 0, 0, 0, 0, 0, 0, 0, 4,
552
+ 4, 0, 4, 0, 0, 0, 0, 0,
553
+ 0, 0, 0, 0, 0, 1, 0, 0,
554
+ 0, 0, 0, 0, 0, 0, 0, 0,
555
+ 0, 0, 0, 0, 0, 0, 0, 0,
556
+ 0, 0, 1, 0, 0, 0, 0, 0,
557
+ 0, 0, 0, 0, 0, 0, 0, 0,
558
+ 0, 0, 0, 0, 0, 0, 0, 0,
559
+ 0, 0, 0, 0, 0, 0, 0, 0,
560
+ 0, 0, 0, 0, 0, 0, 0, 0,
561
+ 0, 0, 0, 0, 0, 0, 0, 0,
562
+ 1, 0, 0, 0, 0, 0, 0, 0,
563
+ 0, 0, 0, 0, 0, 0, 0, 0,
564
+ 0, 0, 0, 0, 4, 4, 4, 0,
565
+ 0, 0, 0, 0, 0, 0, 0, 0,
566
+ 0, 0, 0, 0, 0, 0, 0, 0,
567
+ 0, 0, 0, 0, 0, 0, 0, 0,
568
+ 0, 0, 0, 0, 0, 5, 5, 0,
569
+ 5, 0, 5, 5, 5, 0, 0, 0,
570
+ 0, 0, 0, 0, 0, 0, 0, 0,
571
+ 0, 0, 0, 0, 0, 0, 0, 0,
572
+ 0, 0, 0, 0, 0, 0, 0, 0,
573
+ 0, 0, 0, 0, 0, 0, 0, 0,
574
+ 0, 0, 0, 0, 0, 0, 0, 0,
575
+ 0, 0, 0, 0, 0, 0, 0, 0,
576
+ 0, 0, 0, 0, 0, 0, 0, 0,
577
+ 0, 0, 0, 0, 0, 0, 0, 0,
578
+ 0, 0, 0, 0, 0, 0, 0, 0,
579
+ 0, 0, 0, 0, 0, 0, 0, 0,
580
+ 0, 1, 0, 0, 0, 0, 0, 0,
581
+ 0, 1, 1, 1, 1, 1, 1, 1,
582
+ 1, 0, 1, 0, 0, 0, 0, 0,
583
+ 0, 0, 0, 0, 0, 0, 0, 0,
584
+ 0, 0, 0, 0, 0, 0, 0, 0,
585
+ 0, 0, 0, 0, 0, 0, 0, 0,
586
+ 0, 0, 0, 0, 0, 0, 7, 7,
587
+ 0, 9, 0, 9, 0, 11, 11, 0,
588
+ 11, 0, 11, 0, 0, 11, 11, 0,
589
+ 14, 0, 14, 0, 14, 14, 0, 0,
590
+ 0, 0, 9, 9, 0, 16, 16, 0,
591
+ 16, 0, 16, 0, 16, 16, 0, 0
592
+ ]
593
+
594
+ class << self
595
+ attr_accessor :_interval_expression_eof_actions
596
+ private :_interval_expression_eof_actions, :_interval_expression_eof_actions=
597
+ end
598
+ self._interval_expression_eof_actions = [
599
+ 0, 0, 0, 0, 0, 0, 0, 0,
600
+ 3, 0, 0, 0, 0, 3, 3, 3,
601
+ 3, 3, 3, 3, 3, 3, 3, 3,
602
+ 3, 3, 3, 3, 3, 3, 3, 3,
603
+ 3, 3, 3, 3, 3, 3, 3, 3,
604
+ 3, 3, 3, 3, 3, 3, 3, 3,
605
+ 3, 3, 3, 3, 3, 3, 3, 3,
606
+ 3, 3, 3, 3, 3, 3, 3, 3,
607
+ 3, 3, 3, 3, 3, 3, 3, 3,
608
+ 3, 3, 3, 3, 3, 3, 3, 3,
609
+ 3, 3, 3, 3, 3, 3, 3, 3,
610
+ 3, 3, 3, 3, 3, 3, 3, 3,
611
+ 3, 3, 3, 3, 3, 3, 3, 3,
612
+ 3, 3, 3, 3, 3, 0, 0, 0,
613
+ 0, 0, 0, 3, 3, 3, 3, 3,
614
+ 3, 3, 3, 3, 0, 0, 0, 0,
615
+ 0, 0, 0, 0, 0, 0, 0, 0,
616
+ 0, 0, 0, 0, 0, 0, 0, 0,
617
+ 0, 0, 0, 0, 0, 0, 3, 0,
618
+ 0, 0, 0, 0, 0, 0, 0, 0,
619
+ 0, 0, 0, 0, 0, 0, 0, 0,
620
+ 0, 3, 0, 0, 0, 0, 0, 0,
621
+ 0, 0, 0, 0, 0, 0, 3, 0,
622
+ 0, 0, 0, 0, 0, 0, 0, 0,
623
+ 0, 0, 0, 0, 0, 0, 0, 0,
624
+ 0, 0, 0, 0, 0, 0, 0, 0,
625
+ 0, 0, 0, 0, 0, 0, 0, 0,
626
+ 0, 0, 0, 0, 0, 0, 0, 0,
627
+ 0, 0, 0, 0, 0, 0, 0, 0,
628
+ 0, 0, 0, 0, 0, 0, 0, 0,
629
+ 0, 0, 0, 0, 0, 0, 0, 0,
630
+ 0, 0, 0, 0, 0, 0, 0, 0,
631
+ 0, 0, 0, 0, 0, 0, 0, 0,
632
+ 0, 0, 0, 0, 0, 0, 0, 0,
633
+ 0, 0, 0, 0, 0, 0, 0, 0,
634
+ 0, 0, 0, 0, 0, 0, 0, 0,
635
+ 0, 0, 0, 0, 0, 0, 0, 0,
636
+ 0, 0, 0, 0, 0, 0, 0, 0,
637
+ 6, 8, 10, 10, 12, 10, 13, 13,
638
+ 12, 8, 15, 15, 15
639
+ ]
640
+
641
+ class << self
642
+ attr_accessor :interval_expression_start
643
+ end
644
+ self.interval_expression_start = 1;
645
+ class << self
646
+ attr_accessor :interval_expression_first_final
647
+ end
648
+ self.interval_expression_first_final = 304;
649
+ class << self
650
+ attr_accessor :interval_expression_error
651
+ end
652
+ self.interval_expression_error = 0;
653
+
654
+ class << self
655
+ attr_accessor :interval_expression_en_main
656
+ end
657
+ self.interval_expression_en_main = 1;
658
+
659
+
660
+
661
+ # The generic parse exception class.
662
+ class Symphony::TimeParseError < ArgumentError; end
663
+
664
+
665
+ ########################################################################
666
+ ### C L A S S M E T H O D S
667
+ ########################################################################
668
+
669
+ ### Parse a schedule expression +exp+.
670
+ ###
671
+ ### Parsing defaults to Time.now(), but if passed a +time+ object,
672
+ ### all contexual times (2pm) are relative to it. If you know when
673
+ ### an expression was generated, you can 'reconstitute' an interval
674
+ ### object this way.
675
+ ###
676
+ def self::parse( exp, time=nil )
677
+
678
+ # Normalize the expression before parsing
679
+ #
680
+ exp = exp.downcase.
681
+ gsub( /(?:[^[a-z][0-9][\-:]\s]+)/, '' ). # : - a-z 0-9 only
682
+ gsub( /(?:and|then)/, '' ). # remove common decorator words
683
+ gsub( /\s+/, ' ' ). # collapse whitespace
684
+ gsub( /([:\-])+/, '\1' ) # collapse multiple - or : chars
685
+
686
+ event = new( exp, time || Time.now )
687
+ data = event.instance_variable_get( :@data )
688
+
689
+ # Ragel interface variables
690
+ #
691
+ key = ''
692
+ mark = 0
693
+
694
+ begin
695
+ p ||= 0
696
+ pe ||= data.length
697
+ cs = interval_expression_start
698
+ end
699
+
700
+ eof = pe
701
+
702
+ begin
703
+ testEof = false
704
+ _klen, _trans, _keys = nil
705
+ _goto_level = 0
706
+ _resume = 10
707
+ _eof_trans = 15
708
+ _again = 20
709
+ _test_eof = 30
710
+ _out = 40
711
+ while true
712
+ if _goto_level <= 0
713
+ if p == pe
714
+ _goto_level = _test_eof
715
+ next
716
+ end
717
+ if cs == 0
718
+ _goto_level = _out
719
+ next
720
+ end
721
+ end
722
+ if _goto_level <= _resume
723
+ _keys = _interval_expression_key_offsets[cs]
724
+ _trans = _interval_expression_index_offsets[cs]
725
+ _klen = _interval_expression_single_lengths[cs]
726
+ _break_match = false
727
+
728
+ begin
729
+ if _klen > 0
730
+ _lower = _keys
731
+ _upper = _keys + _klen - 1
732
+
733
+ loop do
734
+ break if _upper < _lower
735
+ _mid = _lower + ( (_upper - _lower) >> 1 )
736
+
737
+ if data[p].ord < _interval_expression_trans_keys[_mid]
738
+ _upper = _mid - 1
739
+ elsif data[p].ord > _interval_expression_trans_keys[_mid]
740
+ _lower = _mid + 1
741
+ else
742
+ _trans += (_mid - _keys)
743
+ _break_match = true
744
+ break
745
+ end
746
+ end # loop
747
+ break if _break_match
748
+ _keys += _klen
749
+ _trans += _klen
750
+ end
751
+ _klen = _interval_expression_range_lengths[cs]
752
+ if _klen > 0
753
+ _lower = _keys
754
+ _upper = _keys + (_klen << 1) - 2
755
+ loop do
756
+ break if _upper < _lower
757
+ _mid = _lower + (((_upper-_lower) >> 1) & ~1)
758
+ if data[p].ord < _interval_expression_trans_keys[_mid]
759
+ _upper = _mid - 2
760
+ elsif data[p].ord > _interval_expression_trans_keys[_mid+1]
761
+ _lower = _mid + 2
762
+ else
763
+ _trans += ((_mid - _keys) >> 1)
764
+ _break_match = true
765
+ break
766
+ end
767
+ end # loop
768
+ break if _break_match
769
+ _trans += _klen
770
+ end
771
+ end while false
772
+ cs = _interval_expression_trans_targs[_trans];
773
+
774
+ if _interval_expression_trans_actions[_trans] != 0
775
+
776
+ case _interval_expression_trans_actions[_trans]
777
+ when 1 then
778
+ begin
779
+ mark = p end
780
+ when 3 then
781
+ begin
782
+ event.instance_variable_set( :@valid, false ) end
783
+ when 2 then
784
+ begin
785
+ event.instance_variable_set( :@recurring, true ) end
786
+ when 4 then
787
+ begin
788
+
789
+ time = event.send( :extract, mark, p - mark )
790
+ event.send( :set_starting, time, :time )
791
+ end
792
+ when 5 then
793
+ begin
794
+
795
+ interval = event.send( :extract, mark, p - mark )
796
+ event.send( :set_starting, interval, :interval )
797
+ end
798
+ when 16 then
799
+ begin
800
+
801
+ time = event.send( :extract, mark, p - mark )
802
+ event.send( :set_interval, time, :time )
803
+ end
804
+ when 9 then
805
+ begin
806
+
807
+ interval = event.send( :extract, mark, p - mark )
808
+ event.send( :set_interval, interval, :interval )
809
+ end
810
+ when 7 then
811
+ begin
812
+
813
+ multiplier = event.send( :extract, mark, p - mark ).sub( / times/, '' )
814
+ event.instance_variable_set( :@multiplier, multiplier.to_i )
815
+ end
816
+ when 11 then
817
+ begin
818
+
819
+ time = event.send( :extract, mark, p - mark )
820
+ event.send( :set_ending, time, :time )
821
+ end
822
+ when 14 then
823
+ begin
824
+
825
+ interval = event.send( :extract, mark, p - mark )
826
+ event.send( :set_ending, interval, :interval )
827
+ end
828
+ end # action switch
829
+ end
830
+
831
+ end
832
+ if _goto_level <= _again
833
+ if cs == 0
834
+ _goto_level = _out
835
+ next
836
+ end
837
+ p += 1
838
+ if p != pe
839
+ _goto_level = _resume
840
+ next
841
+ end
842
+ end
843
+ if _goto_level <= _test_eof
844
+ if p == eof
845
+ begin
846
+ case ( _interval_expression_eof_actions[cs] )
847
+ when 12 then
848
+ begin
849
+ event.instance_variable_set( :@valid, true ) end
850
+ when 3 then
851
+ begin
852
+ event.instance_variable_set( :@valid, false ) end
853
+ when 15 then
854
+ begin
855
+
856
+ time = event.send( :extract, mark, p - mark )
857
+ event.send( :set_interval, time, :time )
858
+ end
859
+ begin
860
+ event.instance_variable_set( :@valid, true ) end
861
+ when 8 then
862
+ begin
863
+
864
+ interval = event.send( :extract, mark, p - mark )
865
+ event.send( :set_interval, interval, :interval )
866
+ end
867
+ begin
868
+ event.instance_variable_set( :@valid, true ) end
869
+ when 6 then
870
+ begin
871
+
872
+ multiplier = event.send( :extract, mark, p - mark ).sub( / times/, '' )
873
+ event.instance_variable_set( :@multiplier, multiplier.to_i )
874
+ end
875
+ begin
876
+ event.instance_variable_set( :@valid, true ) end
877
+ when 10 then
878
+ begin
879
+
880
+ time = event.send( :extract, mark, p - mark )
881
+ event.send( :set_ending, time, :time )
882
+ end
883
+ begin
884
+ event.instance_variable_set( :@valid, true ) end
885
+ when 13 then
886
+ begin
887
+
888
+ interval = event.send( :extract, mark, p - mark )
889
+ event.send( :set_ending, interval, :interval )
890
+ end
891
+ begin
892
+ event.instance_variable_set( :@valid, true ) end
893
+ end
894
+ end
895
+ end
896
+
897
+ end
898
+ if _goto_level <= _out
899
+ break
900
+ end
901
+ end
902
+ end
903
+
904
+
905
+ # Attach final time logic and sanity checks.
906
+ event.send( :finalize )
907
+
908
+ return event
909
+ end
910
+
911
+
912
+ ########################################################################
913
+ ### I N S T A N C E M E T H O D S
914
+ ########################################################################
915
+
916
+ ### Instantiate a new TimeExpression, provided an +expression+ string
917
+ ### that describes when this event will take place in natural english,
918
+ ### and a +base+ Time to perform calculations against.
919
+ ###
920
+ private_class_method :new
921
+ def initialize( expression, base ) # :nodoc:
922
+ @exp = expression
923
+ @data = expression.to_s.unpack( 'c*' )
924
+ @base = base
925
+
926
+ @valid = false
927
+ @recurring = false
928
+ @starting = nil
929
+ @interval = nil
930
+ @multiplier = nil
931
+ @ending = nil
932
+ end
933
+
934
+
935
+ ######
936
+ public
937
+ ######
938
+
939
+ # Is the schedule expression parsable?
940
+ attr_reader :valid
941
+
942
+ # Does this event repeat?
943
+ attr_reader :recurring
944
+
945
+ # The valid start time for the schedule (for recurring events)
946
+ attr_reader :starting
947
+
948
+ # The valid end time for the schedule (for recurring events)
949
+ attr_reader :ending
950
+
951
+ # The interval to wait before the event should be acted on.
952
+ attr_reader :interval
953
+
954
+ # An optional interval multipler for expressing counts.
955
+ attr_reader :multiplier
956
+
957
+
958
+ ### If this interval is on a stack somewhere and ready to
959
+ ### fire, is it okay to do so based on the specified
960
+ ### expression criteria?
961
+ ###
962
+ ### Returns +true+ if it should fire, +false+ if it should not
963
+ ### but could at a later attempt, and +nil+ if the interval has
964
+ ### expired.
965
+ ###
966
+ def fire?
967
+ now = Time.now
968
+
969
+ # Interval has expired.
970
+ return nil if self.ending && now > self.ending
971
+
972
+ # Interval is not yet in its current time window.
973
+ return false if self.starting - now > 0
974
+
975
+ # Looking good.
976
+ return true
977
+ end
978
+
979
+
980
+ ### Just return the original event expression.
981
+ ###
982
+ def to_s
983
+ return @exp
984
+ end
985
+
986
+
987
+ ### Inspection string.
988
+ ###
989
+ def inspect
990
+ return ( "<%s:0x%08x valid:%s recur:%s expression:%p " +
991
+ "starting:%p interval:%p ending:%p>" ) % [
992
+ self.class.name,
993
+ self.object_id * 2,
994
+ self.valid,
995
+ self.recurring,
996
+ self.to_s,
997
+ self.starting,
998
+ self.interval,
999
+ self.ending
1000
+ ]
1001
+ end
1002
+
1003
+
1004
+ ### Comparable interface, order by interval, 'soonest' first.
1005
+ ###
1006
+ def <=>( other )
1007
+ return self.interval <=> other.interval
1008
+ end
1009
+
1010
+
1011
+ #########
1012
+ protected
1013
+ #########
1014
+
1015
+ ### Given a +start+ and +ending+ scanner position,
1016
+ ### return an ascii representation of the data slice.
1017
+ ###
1018
+ def extract( start, ending )
1019
+ slice = @data[ start, ending ]
1020
+ return '' unless slice
1021
+ return slice.pack( 'c*' )
1022
+ end
1023
+
1024
+
1025
+ ### Parse and set the starting attribute, given a +time_arg+
1026
+ ### string and the +type+ of string (interval or exact time)
1027
+ ###
1028
+ def set_starting( time_arg, type )
1029
+ start = self.get_time( time_arg, type )
1030
+ @starting = start
1031
+ return @starting
1032
+ end
1033
+
1034
+
1035
+ ### Parse and set the interval attribute, given a +time_arg+
1036
+ ### string and the +type+ of string (interval or exact time)
1037
+ ###
1038
+ ### Perform consistency and sanity checks before returning an
1039
+ ### integer representing the amount of time needed to sleep before
1040
+ ### firing the event.
1041
+ ###
1042
+ def set_interval( time_arg, type )
1043
+ interval = nil
1044
+ if self.starting && type == :time
1045
+ raise Symphony::TimeParseError, "That doesn't make sense, just use 'at [datetime]' instead"
1046
+ else
1047
+ interval = self.get_time( time_arg, type )
1048
+ interval = interval - @base
1049
+ end
1050
+
1051
+ @interval = interval
1052
+ return @interval
1053
+ end
1054
+
1055
+
1056
+ ### Parse and set the ending attribute, given a +time_arg+
1057
+ ### string and the +type+ of string (interval or exact time)
1058
+ ###
1059
+ ### Perform consistency and sanity checks before returning a
1060
+ ### Time object.
1061
+ ###
1062
+ def set_ending( time_arg, type )
1063
+ ending = nil
1064
+
1065
+ # Ending dates only make sense for recurring events.
1066
+ #
1067
+ if self.recurring
1068
+
1069
+ # Make the interval an offset of the start time, instead of now.
1070
+ #
1071
+ # This is the contextual difference between:
1072
+ # every minute until 6 hours from now (ending based on NOW)
1073
+ # and
1074
+ # starting in a year run every minute for 1 month (ending based on start time)
1075
+ #
1076
+ if self.starting && type == :interval
1077
+ diff = self.parse_interval( time_arg )
1078
+ ending = self.starting + diff
1079
+
1080
+ # (offset from now)
1081
+ #
1082
+ else
1083
+ ending = self.get_time( time_arg, type )
1084
+ end
1085
+
1086
+ # Check the end time is after the start time.
1087
+ #
1088
+ if self.starting && ending < self.starting
1089
+ raise Symphony::TimeParseError, "recurring event ends after it begins"
1090
+ end
1091
+
1092
+ else
1093
+ self.log.debug "Ignoring ending date, event is not recurring."
1094
+ end
1095
+
1096
+ @ending = ending
1097
+ return @ending
1098
+ end
1099
+
1100
+
1101
+ ### Perform finishing logic and final sanity checks before returning
1102
+ ### a parsed object.
1103
+ ###
1104
+ def finalize
1105
+ raise Symphony::TimeParseError, "unable to parse expression" unless self.valid
1106
+
1107
+ # Ensure start time is populated.
1108
+ #
1109
+ # TODO: This will be required for future modulus
1110
+ # (run every other day) feature.
1111
+ #
1112
+ @starting = @base unless self.starting
1113
+
1114
+ # Alter the interval if a multiplier was specified.
1115
+ #
1116
+ if self.multiplier
1117
+ if self.ending
1118
+
1119
+ # Regular 'count' style multipler with end date.
1120
+ # (run 10 times a minute for 2 days)
1121
+ # Just divide the current interval by the count.
1122
+ #
1123
+ if self.interval
1124
+ @interval = self.interval.to_f / self.multiplier
1125
+
1126
+ # Timeboxed multiplier (start [date] run 10 times end [date])
1127
+ # Evenly spread the interval out over the time window.
1128
+ #
1129
+ else
1130
+ diff = self.ending - self.starting
1131
+ @interval = diff.to_f / self.multiplier
1132
+ end
1133
+
1134
+ # Regular 'count' style multipler (run 10 times a minute)
1135
+ # Just divide the current interval by the count.
1136
+ #
1137
+ else
1138
+ raise Symphony::TimeParseError, "An end date or interval is required" unless self.interval
1139
+ @interval = self.interval.to_f / self.multiplier
1140
+ end
1141
+ end
1142
+ end
1143
+
1144
+
1145
+ ### Given a +time_arg+ string and a type (:interval or :time),
1146
+ ### dispatch to the appropriate parser.
1147
+ ###
1148
+ def get_time( time_arg, type )
1149
+ time = nil
1150
+
1151
+ if type == :interval
1152
+ secs = self.parse_interval( time_arg )
1153
+ time = @base + secs if secs
1154
+ end
1155
+
1156
+ if type == :time
1157
+ time = self.parse_time( time_arg )
1158
+ end
1159
+
1160
+ raise Symphony::TimeParseError, "unable to parse time" if time.nil?
1161
+ return time
1162
+ end
1163
+
1164
+
1165
+ ### Parse a +time_arg+ string (anything parsable buy Time.parse())
1166
+ ### into a Time object.
1167
+ ###
1168
+ def parse_time( time_arg )
1169
+ time = Time.parse( time_arg, @base ) rescue nil
1170
+
1171
+ # Generated date is in the past.
1172
+ #
1173
+ if time && @base > time
1174
+
1175
+ # Ensure future dates for ambiguous times (2pm)
1176
+ time = time + 1.day if time_arg.length < 8
1177
+
1178
+ # Still in the past, abandon all hope.
1179
+ raise Symphony::TimeParseError, "attempt to schedule in the past" if @base > time
1180
+ end
1181
+
1182
+ self.log.debug "Parsed %p (time) to: %p" % [ time_arg, time ]
1183
+ return time
1184
+ end
1185
+
1186
+
1187
+ ### Parse a +time_arg+ interval string ("30 seconds") into an
1188
+ ### Integer.
1189
+ ###
1190
+ def parse_interval( interval_arg )
1191
+ duration, span = interval_arg.split( /\s+/ )
1192
+
1193
+ # catch the 'a' or 'an' case (ex: "an hour")
1194
+ duration = 1 if duration.index( 'a' ) == 0
1195
+
1196
+ # catch the 'other' case, ie: 'every other hour'
1197
+ duration = 2 if duration == 'other'
1198
+
1199
+ # catch the singular case (ex: "hour")
1200
+ unless span
1201
+ span = duration
1202
+ duration = 1
1203
+ end
1204
+
1205
+ use_milliseconds = span.sub!( 'milli', '' )
1206
+ interval = calculate_seconds( duration.to_i, span.to_sym )
1207
+
1208
+ # milliseconds
1209
+ interval = duration.to_f / 1000 if use_milliseconds
1210
+
1211
+ self.log.debug "Parsed %p (interval) to: %p" % [ interval_arg, interval ]
1212
+ return interval
1213
+ end
1214
+
1215
+ end # class TimeExpression
1216
+