symphony 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+