flor 0.14.0 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +9 -0
- data/CREDITS.md +21 -0
- data/LICENSE.txt +4 -1
- data/Makefile +4 -0
- data/README.md +8 -0
- data/flor.gemspec +10 -10
- data/lib/flor.rb +2 -2
- data/lib/flor/changes.rb +3 -3
- data/lib/flor/colours.rb +14 -8
- data/lib/flor/conf.rb +63 -58
- data/lib/flor/core.rb +4 -4
- data/lib/flor/core/executor.rb +65 -29
- data/lib/flor/core/node.rb +37 -20
- data/lib/flor/core/procedure.rb +182 -40
- data/lib/flor/core/texecutor.rb +125 -52
- data/lib/flor/djan.rb +111 -82
- data/lib/flor/dollar.rb +31 -30
- data/lib/flor/flor.rb +314 -237
- data/lib/flor/id.rb +7 -2
- data/lib/flor/log.rb +250 -245
- data/lib/flor/parser.rb +72 -38
- data/lib/flor/pcore/_arr.rb +10 -10
- data/lib/flor/pcore/_att.rb +49 -14
- data/lib/flor/pcore/_coll.rb +18 -0
- data/lib/flor/pcore/_obj.rb +23 -7
- data/lib/flor/pcore/_pat_.rb +1 -1
- data/lib/flor/pcore/_pat_guard.rb +8 -0
- data/lib/flor/pcore/_pat_obj.rb +3 -3
- data/lib/flor/pcore/_pat_or.rb +4 -0
- data/lib/flor/pcore/_pat_regex.rb +24 -0
- data/lib/flor/pcore/_skip.rb +4 -0
- data/lib/flor/pcore/_val.rb +0 -1
- data/lib/flor/pcore/all.rb +111 -0
- data/lib/flor/pcore/any.rb +83 -0
- data/lib/flor/pcore/arith.rb +35 -6
- data/lib/flor/pcore/break.rb +39 -1
- data/lib/flor/pcore/case.rb +82 -4
- data/lib/flor/pcore/cmp.rb +7 -7
- data/lib/flor/pcore/collect.rb +50 -0
- data/lib/flor/pcore/cond.rb +17 -3
- data/lib/flor/pcore/cursor.rb +8 -2
- data/lib/flor/pcore/detect.rb +45 -0
- data/lib/flor/pcore/each.rb +52 -0
- data/lib/flor/pcore/empty.rb +60 -0
- data/lib/flor/pcore/filter.rb +94 -0
- data/lib/flor/pcore/find.rb +67 -0
- data/lib/flor/pcore/for_each.rb +65 -0
- data/lib/flor/pcore/includes.rb +32 -0
- data/lib/flor/pcore/inject.rb +55 -0
- data/lib/flor/pcore/iterator.rb +151 -0
- data/lib/flor/pcore/keys.rb +60 -0
- data/lib/flor/pcore/length.rb +34 -7
- data/lib/flor/pcore/logo.rb +18 -0
- data/lib/flor/pcore/loop.rb +4 -0
- data/lib/flor/pcore/map.rb +77 -46
- data/lib/flor/pcore/match.rb +8 -2
- data/lib/flor/pcore/matchr.rb +4 -5
- data/lib/flor/pcore/move.rb +3 -3
- data/lib/flor/pcore/noeval.rb +13 -0
- data/lib/flor/pcore/not.rb +16 -0
- data/lib/flor/pcore/on.rb +172 -0
- data/lib/flor/pcore/on_cancel.rb +54 -0
- data/lib/flor/pcore/on_error.rb +68 -0
- data/lib/flor/pcore/rand.rb +2 -2
- data/lib/flor/pcore/range.rb +2 -1
- data/lib/flor/pcore/reduce.rb +124 -0
- data/lib/flor/pcore/reverse.rb +46 -0
- data/lib/flor/pcore/select.rb +72 -0
- data/lib/flor/pcore/set.rb +8 -0
- data/lib/flor/pcore/stall.rb +10 -0
- data/lib/flor/pcore/to_array.rb +61 -0
- data/lib/flor/pcore/until.rb +34 -0
- data/lib/flor/punit/cancel.rb +30 -5
- data/lib/flor/punit/ccollect.rb +11 -0
- data/lib/flor/punit/cmap.rb +10 -5
- data/lib/flor/punit/concurrence.rb +42 -51
- data/lib/flor/punit/cron.rb +33 -0
- data/lib/flor/punit/do_trap.rb +42 -0
- data/lib/flor/punit/every.rb +48 -13
- data/lib/flor/punit/graft.rb +3 -3
- data/lib/flor/punit/on_timeout.rb +38 -0
- data/lib/flor/punit/schedule.rb +69 -6
- data/lib/flor/punit/signal.rb +54 -0
- data/lib/flor/punit/sleep.rb +1 -1
- data/lib/flor/punit/task.rb +4 -1
- data/lib/flor/punit/trap.rb +188 -13
- data/lib/flor/tools/shell.rb +408 -62
- data/lib/flor/tools/shell_out.rb +31 -0
- data/lib/flor/unit.rb +1 -1
- data/lib/flor/unit/caller.rb +177 -0
- data/lib/flor/unit/executor.rb +1 -0
- data/lib/flor/unit/ganger.rb +15 -21
- data/lib/flor/unit/hook.rb +1 -1
- data/lib/flor/unit/hooker.rb +22 -10
- data/lib/flor/unit/loader.rb +22 -22
- data/lib/flor/unit/logger.rb +63 -36
- data/lib/flor/unit/models.rb +6 -1
- data/lib/flor/unit/models/execution.rb +12 -1
- data/lib/flor/unit/models/message.rb +7 -0
- data/lib/flor/unit/models/trap.rb +31 -17
- data/lib/flor/unit/scheduler.rb +18 -10
- data/lib/flor/unit/storage.rb +83 -23
- data/lib/flor/unit/waiter.rb +1 -2
- metadata +96 -52
- data/lib/flor/deep.rb +0 -144
- data/lib/flor/punit/on.rb +0 -57
- data/lib/flor/unit/runner.rb +0 -84
- data/match.md +0 -22
data/lib/flor/dollar.rb
CHANGED
@@ -85,8 +85,8 @@ module Flor
|
|
85
85
|
def stringify(v)
|
86
86
|
|
87
87
|
case v
|
88
|
-
|
89
|
-
|
88
|
+
when Array, Hash then JSON.dump(v)
|
89
|
+
else v.to_s
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
@@ -118,21 +118,21 @@ module Flor
|
|
118
118
|
l = s.length
|
119
119
|
|
120
120
|
case cmp
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
121
|
+
when '>' then l > len
|
122
|
+
when '>=' then l >= len
|
123
|
+
when '<' then l < len
|
124
|
+
when '<=' then l <= len
|
125
|
+
when '=', '==' then l == len
|
126
|
+
when '!=', '<>' then l != len
|
127
|
+
else false
|
128
128
|
end
|
129
129
|
end
|
130
130
|
|
131
131
|
def to_json(o)
|
132
132
|
|
133
133
|
case o
|
134
|
-
|
135
|
-
|
134
|
+
when Array, Hash then JSON.dump(o)
|
135
|
+
else JSON.dump([ o ])[1..-2]
|
136
136
|
end
|
137
137
|
end
|
138
138
|
|
@@ -142,31 +142,32 @@ module Flor
|
|
142
142
|
|
143
143
|
case fun
|
144
144
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
145
|
+
when 'u' then o.to_s.upcase
|
146
|
+
when 'd' then o.to_s.downcase
|
147
|
+
when 'r' then o.reverse
|
148
|
+
when 'c' then o.to_s.capitalize.gsub(/\s[a-z]/) { |c| c.upcase }
|
149
|
+
when 'q' then quote(o, false)
|
150
|
+
when 'Q' then quote(o, true)
|
151
|
+
when 'l' then o.length.to_s
|
151
152
|
|
152
|
-
|
153
|
+
when 'json' then to_json(o)
|
153
154
|
|
154
|
-
|
155
|
-
|
155
|
+
when /^j(.+)/
|
156
|
+
o.respond_to?(:join) ? o.join($1) : o
|
156
157
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
158
|
+
when /\Am\/(.+)\/\z/
|
159
|
+
match($1, o.to_s)
|
160
|
+
when /\As\/(.*[^\\]\/)(.+)\/([gix]*)\z/
|
161
|
+
substitute($1.chop, $2, $3, o.to_s)
|
161
162
|
|
162
|
-
|
163
|
-
|
164
|
-
|
163
|
+
when /\A-?\d+\z/ then o.to_s[fun.to_i]
|
164
|
+
when /\A(-?\d+), *(-?\d+)\z/ then o.to_s[$1.to_i, $2.to_i]
|
165
|
+
when /\A(-?\d+)\.\.(-?\d+)\z/ then o.to_s[$1.to_i..$2.to_i]
|
165
166
|
|
166
|
-
|
167
|
-
|
167
|
+
when /\A\s*l\s*([><=!]=?|<>)\s*(\d+)\z/
|
168
|
+
lfilter(o.to_s, $1, $2.to_i) ? o.to_s : nil
|
168
169
|
|
169
|
-
|
170
|
+
else o
|
170
171
|
end
|
171
172
|
end
|
172
173
|
|
data/lib/flor/flor.rb
CHANGED
@@ -1,180 +1,247 @@
|
|
1
1
|
|
2
2
|
module Flor
|
3
3
|
|
4
|
-
|
4
|
+
NAME_REX = '[a-zA-Z0-9_]+'
|
5
|
+
UNIT_NAME_REX = /\A#{NAME_REX}\z/
|
6
|
+
DOMAIN_NAME_REX = /\A#{NAME_REX}(\.#{NAME_REX})*\z/
|
7
|
+
FLOW_NAME_REX = /\A(#{NAME_REX}(?:\.#{NAME_REX})*)\.([a-zA-Z0-9_-]+)\z/
|
5
8
|
|
6
|
-
|
7
|
-
end
|
9
|
+
DOMAIN_UNIT_REX = /\A(#{NAME_REX}(?:\.#{NAME_REX})*)-(#{NAME_REX})[-\z]/
|
8
10
|
|
9
|
-
|
10
|
-
# misc
|
11
|
-
#
|
12
|
-
# miscellaneous functions
|
11
|
+
SPLAT_REGEX = /\A(.*)__(_|\d+)\z/.freeze
|
13
12
|
|
14
|
-
|
13
|
+
POINTS = %w[
|
14
|
+
execute receive
|
15
|
+
return
|
16
|
+
entered left
|
17
|
+
task detask
|
18
|
+
schedule trigger
|
19
|
+
signal cancel
|
20
|
+
terminated failed ceased
|
21
|
+
idle
|
22
|
+
]
|
15
23
|
|
16
|
-
|
17
|
-
end
|
24
|
+
class << self
|
18
25
|
|
19
|
-
|
26
|
+
def to_a(o)
|
20
27
|
|
21
|
-
|
22
|
-
|
28
|
+
o.nil? ? nil : Array(o)
|
29
|
+
end
|
23
30
|
|
24
|
-
|
31
|
+
#
|
32
|
+
# misc
|
33
|
+
#
|
34
|
+
# miscellaneous functions
|
25
35
|
|
26
|
-
|
27
|
-
end
|
28
|
-
def self.dupm(h, hh); self.dup_and_merge(h, hh); end
|
36
|
+
def env_i(k)
|
29
37
|
|
30
|
-
|
38
|
+
v = ENV[k]; (v && v.match(/\A\d+\z/)) ? v.to_i : nil
|
39
|
+
end
|
31
40
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
o.each { |k, v| k.freeze; v.freeze }
|
41
|
+
def dup(o)
|
42
|
+
|
43
|
+
Marshal.load(Marshal.dump(o))
|
36
44
|
end
|
37
45
|
|
38
|
-
|
39
|
-
end
|
46
|
+
def dup_and_merge(h, hh)
|
40
47
|
|
41
|
-
|
48
|
+
self.dup(h).merge(hh)
|
49
|
+
end
|
50
|
+
def dupm(h, hh); self.dup_and_merge(h, hh); end
|
42
51
|
|
43
|
-
|
44
|
-
end
|
52
|
+
def deep_freeze(o)
|
45
53
|
|
46
|
-
|
54
|
+
if o.is_a?(Array)
|
55
|
+
o.each { |e| e.freeze }
|
56
|
+
elsif o.is_a?(Hash)
|
57
|
+
o.each { |k, v| k.freeze; v.freeze }
|
58
|
+
end
|
47
59
|
|
48
|
-
|
49
|
-
|
60
|
+
o.freeze
|
61
|
+
end
|
62
|
+
|
63
|
+
def false?(o)
|
64
|
+
|
65
|
+
o == nil || o == false
|
66
|
+
end
|
50
67
|
|
51
|
-
|
68
|
+
def true?(o)
|
52
69
|
|
53
|
-
|
54
|
-
|
55
|
-
t = nil
|
70
|
+
o != nil && o != false
|
71
|
+
end
|
56
72
|
|
57
|
-
|
73
|
+
def to_error(o)
|
58
74
|
|
59
|
-
h
|
75
|
+
h = {}
|
76
|
+
h['kla'] = o.class.to_s
|
60
77
|
|
61
|
-
t =
|
78
|
+
m, t =
|
79
|
+
if o.is_a?(::Exception)
|
80
|
+
[ o.message, o.backtrace ]
|
81
|
+
else
|
82
|
+
[ o.to_s, caller[1..-1] ]
|
83
|
+
end
|
62
84
|
|
63
85
|
if n = o.respond_to?(:node) && o.node
|
86
|
+
h['prc'] = n.tree[0]
|
64
87
|
h['lin'] = n.tree[2]
|
65
|
-
#h['tre'] = n.tree
|
66
88
|
end
|
67
89
|
|
68
|
-
|
90
|
+
h['msg'] = m
|
91
|
+
h['trc'] = t[0..(t.rindex { |l| l.match(/\/lib\/flor\//) }) + 1] if t
|
92
|
+
h['cwd'] = Dir.pwd
|
93
|
+
h['rlp'] = $: if o.is_a?(::LoadError)
|
94
|
+
|
95
|
+
h
|
96
|
+
end
|
69
97
|
|
70
|
-
|
98
|
+
def const_lookup(s)
|
71
99
|
|
72
|
-
|
100
|
+
s.split('::')
|
101
|
+
.select { |ss| ss.length > 0 }
|
102
|
+
.inject(Kernel) { |k, sk| k.const_get(sk, k == Kernel) }
|
73
103
|
end
|
74
104
|
|
75
|
-
|
76
|
-
h['cwd'] = Dir.pwd
|
77
|
-
h['rlp'] = $: if o.is_a?(::LoadError)
|
105
|
+
def to_coll(o)
|
78
106
|
|
79
|
-
|
80
|
-
|
107
|
+
#o.respond_to?(:to_a) ? o.to_a : [ a ]
|
108
|
+
Array(o)
|
109
|
+
end
|
81
110
|
|
82
|
-
|
111
|
+
def relativize_path(path, from=Dir.getwd)
|
83
112
|
|
84
|
-
|
85
|
-
end
|
113
|
+
path = File.absolute_path(path)
|
86
114
|
|
87
|
-
|
115
|
+
path = path[from.length + 1..-1] if path[0, from.length] == from
|
88
116
|
|
89
|
-
|
90
|
-
|
91
|
-
end
|
117
|
+
path || '.'
|
118
|
+
end
|
92
119
|
|
93
|
-
|
120
|
+
def is_array_of_messages?(o)
|
94
121
|
|
95
|
-
|
122
|
+
o.is_a?(Array) &&
|
123
|
+
o.all? { |e|
|
124
|
+
e.is_a?(Hash) &&
|
125
|
+
e['point'].is_a?(String) &&
|
126
|
+
e.keys.all? { |k| k.is_a?(String) } }
|
127
|
+
end
|
96
128
|
|
97
|
-
|
129
|
+
def h_fetch(h, *keys)
|
98
130
|
|
99
|
-
|
100
|
-
|
131
|
+
k = keys.find { |k| h.has_key?(k) }
|
132
|
+
k ? h[k] : nil
|
133
|
+
end
|
101
134
|
|
102
|
-
|
135
|
+
def h_fetch_a(h, *keys)
|
103
136
|
|
104
|
-
|
105
|
-
o.all? { |e|
|
106
|
-
e.is_a?(Hash) &&
|
107
|
-
e['point'].is_a?(String) &&
|
108
|
-
e.keys.all? { |k| k.is_a?(String) } }
|
109
|
-
end
|
137
|
+
default = keys.last.is_a?(String) ? [] : keys.pop
|
110
138
|
|
111
|
-
|
139
|
+
k = keys.find { |k| h.has_key?(k) }
|
140
|
+
v = k ? h[k] : nil
|
112
141
|
|
113
|
-
|
142
|
+
v_to_a(v) || default
|
143
|
+
end
|
114
144
|
|
115
|
-
|
116
|
-
v = k ? h[k] : nil
|
145
|
+
def v_to_a(o)
|
117
146
|
|
118
|
-
|
119
|
-
|
147
|
+
return o if o.is_a?(Array)
|
148
|
+
return o.split(',') if o.is_a?(String)
|
149
|
+
return nil if o.nil?
|
120
150
|
|
121
|
-
|
151
|
+
fail ArgumentError.new("cannot turn instance of #{o.class} into an array")
|
152
|
+
end
|
122
153
|
|
123
|
-
|
124
|
-
return o.split(',') if o.is_a?(String)
|
125
|
-
return nil if o.nil?
|
154
|
+
def is_regex_string?(s)
|
126
155
|
|
127
|
-
|
128
|
-
|
156
|
+
!! (
|
157
|
+
s.is_a?(String) &&
|
158
|
+
s[0] == '/' &&
|
159
|
+
s.match(/\/[imxouesn]*\z/)
|
160
|
+
)
|
161
|
+
end
|
129
162
|
|
130
|
-
|
131
|
-
# functions about time
|
163
|
+
def to_regex(o)
|
132
164
|
|
133
|
-
|
165
|
+
s =
|
166
|
+
case o
|
167
|
+
when String then o
|
168
|
+
when Array then o[1].to_s # hopefully regex tree
|
169
|
+
else o.to_s
|
170
|
+
end
|
134
171
|
|
135
|
-
|
136
|
-
s = StringIO.new
|
172
|
+
m = s.match(/\A\/(.*)\/([imxouesn]*)\z/)
|
137
173
|
|
138
|
-
|
139
|
-
s << t.strftime('T%H:%M:%S') if show_time
|
140
|
-
s << sprintf('.%06d', t.usec) if show_time && show_usec
|
141
|
-
s << 'Z' if show_time
|
174
|
+
return Regexp.new(s) unless m
|
142
175
|
|
143
|
-
|
144
|
-
|
176
|
+
m1 = m[1]
|
177
|
+
e = (m[2].match(/[uesn]/) || [])[0]
|
145
178
|
|
146
|
-
|
179
|
+
m1 =
|
180
|
+
case e
|
181
|
+
when 'u' then m1.encode('UTF-8')
|
182
|
+
when 'e' then m1.encode('EUC-JP')
|
183
|
+
when 's' then m1.encode('Windows-31J')
|
184
|
+
when 'n' then m1.encode('ASCII-8BIT')
|
185
|
+
else m1
|
186
|
+
end
|
147
187
|
|
148
|
-
|
149
|
-
|
188
|
+
flags = 0
|
189
|
+
flags = flags | Regexp::EXTENDED if m[2].index('x')
|
190
|
+
flags = flags | Regexp::IGNORECASE if m[2].index('i')
|
191
|
+
#flags = flags | Regexp::MULTILINE if m[2].index('m')
|
192
|
+
flags = flags | Regexp::FIXEDENCODING if e
|
150
193
|
|
151
|
-
|
194
|
+
Regexp.new(m1, flags)
|
195
|
+
end
|
152
196
|
|
153
|
-
|
154
|
-
|
197
|
+
#
|
198
|
+
# functions about time
|
155
199
|
|
156
|
-
|
200
|
+
def isostamp(show_date, show_time, show_usec, time)
|
157
201
|
|
158
|
-
|
159
|
-
|
202
|
+
t = (time || Time.now).utc
|
203
|
+
s = StringIO.new
|
160
204
|
|
161
|
-
|
205
|
+
s << t.strftime('%Y-%m-%d') if show_date
|
206
|
+
s << t.strftime('T%H:%M:%S') if show_time
|
207
|
+
s << sprintf('.%06d', t.usec) if show_time && show_usec
|
208
|
+
s << 'Z' if show_time
|
162
209
|
|
163
|
-
|
164
|
-
|
165
|
-
s << t.strftime('%Y%m%dT%H%M%S') << sprintf('.%06dZ', t.usec)
|
210
|
+
s.string
|
211
|
+
end
|
166
212
|
|
167
|
-
|
168
|
-
end
|
213
|
+
def tstamp(t=Time.now)
|
169
214
|
|
170
|
-
|
171
|
-
|
172
|
-
def self.hstamp(t=Time.now)
|
215
|
+
isostamp(true, true, true, t)
|
216
|
+
end
|
173
217
|
|
174
|
-
|
175
|
-
|
218
|
+
def ststamp(t=Time.now)
|
219
|
+
|
220
|
+
isostamp(true, true, false, t)
|
221
|
+
end
|
222
|
+
|
223
|
+
def dstamp(t=Time.now)
|
224
|
+
|
225
|
+
isostamp(true, false, false, t)
|
226
|
+
end
|
227
|
+
|
228
|
+
def tamp(t=Time.now)
|
229
|
+
|
230
|
+
t = t.utc
|
231
|
+
s = StringIO.new
|
232
|
+
s << t.strftime('%Y%m%dT%H%M%S') << sprintf('.%06dZ', t.usec)
|
233
|
+
|
234
|
+
s.string
|
235
|
+
end
|
176
236
|
|
177
|
-
#
|
237
|
+
# hour stamp
|
238
|
+
#
|
239
|
+
def hstamp(t=Time.now)
|
240
|
+
|
241
|
+
isostamp(false, true, true, t)
|
242
|
+
end
|
243
|
+
|
244
|
+
# def to_time(ts)
|
178
245
|
#
|
179
246
|
# m = ts.match(/\A(\d{4})(\d{2})(\d{2})\.(\d{2})(\d{2})(\d{2})(\d+)([uU]?)\z/)
|
180
247
|
# fail ArgumentError.new("cannot parse timestamp #{ts.inspect}") unless m
|
@@ -183,194 +250,204 @@ module Flor
|
|
183
250
|
# Time.local(*m[1, 7].collect(&:to_i))
|
184
251
|
# end
|
185
252
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
NAME_REX = '[a-zA-Z0-9_]+'
|
190
|
-
UNIT_NAME_REX = /\A#{NAME_REX}\z/
|
191
|
-
DOMAIN_NAME_REX = /\A#{NAME_REX}(\.#{NAME_REX})*\z/
|
192
|
-
FLOW_NAME_REX = /\A(#{NAME_REX}(?:\.#{NAME_REX})*)\.([a-zA-Z0-9_-]+)\z/
|
253
|
+
#
|
254
|
+
# functions about domains and units
|
193
255
|
|
194
|
-
|
256
|
+
def potential_unit_name?(s)
|
195
257
|
|
196
|
-
|
197
|
-
|
258
|
+
s.is_a?(String) && !! s.match(UNIT_NAME_REX)
|
259
|
+
end
|
198
260
|
|
199
|
-
|
261
|
+
def potential_domain_name?(s)
|
200
262
|
|
201
|
-
|
202
|
-
|
263
|
+
s.is_a?(String) && !! s.match(DOMAIN_NAME_REX)
|
264
|
+
end
|
203
265
|
|
204
|
-
|
266
|
+
def split_flow_name(s)
|
205
267
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
268
|
+
if s.is_a?(String) && m = s.match(FLOW_NAME_REX)
|
269
|
+
[ m[1], m[2] ]
|
270
|
+
else
|
271
|
+
nil
|
272
|
+
end
|
210
273
|
end
|
211
|
-
end
|
212
|
-
|
213
|
-
def self.is_sub_domain?(dom, sub)
|
214
274
|
|
215
|
-
|
216
|
-
"not a domain #{dom.inspect}"
|
217
|
-
) unless potential_domain_name?(dom)
|
275
|
+
def is_sub_domain?(dom, sub)
|
218
276
|
|
219
|
-
|
220
|
-
|
221
|
-
|
277
|
+
fail ArgumentError.new(
|
278
|
+
"not a domain #{dom.inspect}"
|
279
|
+
) unless potential_domain_name?(dom)
|
222
280
|
|
223
|
-
|
224
|
-
|
281
|
+
fail ArgumentError.new(
|
282
|
+
"not a sub domain #{sub.inspect}"
|
283
|
+
) unless potential_domain_name?(sub)
|
225
284
|
|
226
|
-
|
285
|
+
sub == dom || sub[0, dom.length + 1] == dom + '.'
|
286
|
+
end
|
227
287
|
|
228
|
-
|
288
|
+
def split_domain_unit(s)
|
229
289
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
290
|
+
if m = DOMAIN_UNIT_REX.match(s)
|
291
|
+
[ m[1], m[2] ]
|
292
|
+
else
|
293
|
+
[]
|
294
|
+
end
|
234
295
|
end
|
235
|
-
end
|
236
296
|
|
237
|
-
|
297
|
+
def domain(s)
|
238
298
|
|
239
|
-
|
240
|
-
|
299
|
+
split_domain_unit(s).first
|
300
|
+
end
|
241
301
|
|
242
|
-
|
302
|
+
def unit(s)
|
243
303
|
|
244
|
-
|
245
|
-
|
304
|
+
split_domain_unit(s).last
|
305
|
+
end
|
246
306
|
|
247
|
-
|
307
|
+
def to_pretty_s(o, twidth=79)
|
248
308
|
|
249
|
-
|
250
|
-
|
309
|
+
sio = StringIO.new
|
310
|
+
PP.pp(o, sio, twidth)
|
251
311
|
|
252
|
-
|
253
|
-
|
312
|
+
sio.string
|
313
|
+
end
|
254
314
|
|
255
315
|
|
256
|
-
|
257
|
-
|
316
|
+
#
|
317
|
+
# tree
|
258
318
|
|
259
|
-
|
319
|
+
def is_tree?(t)
|
260
320
|
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
321
|
+
t.is_a?(Array) &&
|
322
|
+
t.size > 2 &&
|
323
|
+
(t[0].is_a?(String) || Flor.is_tree?(t[0])) &&
|
324
|
+
t[2].is_a?(Integer)
|
325
|
+
end
|
266
326
|
|
267
|
-
|
327
|
+
def is_string_tree?(t, s=nil)
|
268
328
|
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
329
|
+
t.is_a?(Array) &&
|
330
|
+
t[2].is_a?(Integer) &&
|
331
|
+
%w[ _sqs _dqs ].include?(t[0]) &&
|
332
|
+
(s ? (t[1] == s) : t[1].is_a?(String))
|
333
|
+
end
|
274
334
|
|
275
|
-
|
335
|
+
def is_att_tree?(t)
|
276
336
|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
337
|
+
t.is_a?(Array) &&
|
338
|
+
t[2].is_a?(Integer) &&
|
339
|
+
t[0] == '_att' &&
|
340
|
+
t[1].is_a?(Array)
|
341
|
+
end
|
282
342
|
|
283
|
-
|
343
|
+
def is_array_of_trees?(o)
|
284
344
|
|
285
|
-
|
286
|
-
|
287
|
-
|
345
|
+
o.is_a?(Array) &&
|
346
|
+
o.all? { |e| Flor.is_tree?(e) }
|
347
|
+
end
|
288
348
|
|
289
349
|
# # Array, object or atom tree
|
290
350
|
# #
|
291
|
-
# def
|
351
|
+
# def is_value_tree?(o)
|
292
352
|
#
|
293
353
|
# o.is_a?(Array) &&
|
294
354
|
# %w[ _num _boo _sqs _dqs _rxs _nul _arr _obj ].include?(o[0]) &&
|
295
355
|
# o[2].is_a?(Integer)
|
296
356
|
# end
|
297
357
|
|
298
|
-
|
299
|
-
|
300
|
-
o.is_a?(Array) &&
|
301
|
-
o[0] == '_proc' &&
|
302
|
-
o[2].is_a?(Integer) &&
|
303
|
-
o[1].is_a?(Hash) &&
|
304
|
-
o[1]['proc'].is_a?(String)
|
305
|
-
end
|
306
|
-
|
307
|
-
def self.is_func_tree?(o)
|
358
|
+
def is_proc_tree?(o)
|
308
359
|
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
360
|
+
o.is_a?(Array) &&
|
361
|
+
o[0] == '_proc' &&
|
362
|
+
o[2].is_a?(Integer) &&
|
363
|
+
o[1].is_a?(Hash) &&
|
364
|
+
o[1]['proc'].is_a?(String)
|
365
|
+
end
|
314
366
|
|
315
|
-
|
367
|
+
def is_func_tree?(o)
|
316
368
|
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
end
|
369
|
+
o.is_a?(Array) &&
|
370
|
+
o[0] == '_func' &&
|
371
|
+
o[2].is_a?(Integer) &&
|
372
|
+
o[1].is_a?(Hash) && (o[1].keys & %w[ nid cnid fun ]).size == 3
|
373
|
+
end
|
323
374
|
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
375
|
+
# def is_task_tree?(o)
|
376
|
+
#
|
377
|
+
# o.is_a?(Array) &&
|
378
|
+
# o[0] == '_task' &&
|
379
|
+
# o[2].is_a?(Integer) &&
|
380
|
+
# o[1].is_a?(Hash) &&
|
381
|
+
# o[1]['task'].is_a?(String)
|
382
|
+
# end
|
383
|
+
|
384
|
+
def is_regex_tree?(o)
|
385
|
+
|
386
|
+
o.is_a?(Array) &&
|
387
|
+
o[0] == '_rxs' &&
|
388
|
+
o[2].is_a?(Integer) &&
|
389
|
+
o[1].is_a?(String) &&
|
390
|
+
o[1].match(/\A\/.*\/[a-zA-Z]*\z/)
|
391
|
+
end
|
328
392
|
|
329
|
-
|
393
|
+
# Returns [ st, i ], the parent subtree for the final i index of the nid
|
394
|
+
# Used when inserting updated subtrees.
|
395
|
+
#
|
396
|
+
def parent_tree_locate(t, nid)
|
330
397
|
|
331
|
-
|
398
|
+
return nil if t == nil
|
332
399
|
|
333
|
-
|
334
|
-
return [ t, i.to_i ] if ! d
|
335
|
-
parent_tree_locate(t[1][i.to_i], [ i, d ].join('_'))
|
336
|
-
end
|
400
|
+
n, i, d = nid.split('_', 3)
|
337
401
|
|
338
|
-
|
339
|
-
|
340
|
-
|
402
|
+
return [ t, nil ] if i == nil
|
403
|
+
return [ t, i.to_i ] if ! d
|
404
|
+
parent_tree_locate(t[1][i.to_i], [ i, d ].join('_'))
|
405
|
+
end
|
341
406
|
|
342
|
-
|
407
|
+
# Returns the subtree down at the given nid
|
408
|
+
#
|
409
|
+
def tree_locate(t, nid)
|
343
410
|
|
344
|
-
|
345
|
-
return st if i == nil
|
346
|
-
st[1][i]
|
347
|
-
end
|
411
|
+
st, i = parent_tree_locate(t, nid)
|
348
412
|
|
413
|
+
return nil if st == nil
|
414
|
+
return st if i == nil
|
415
|
+
st[1][i]
|
416
|
+
end
|
349
417
|
|
350
|
-
#
|
351
|
-
# splat
|
352
418
|
|
353
|
-
|
419
|
+
#
|
420
|
+
# splat
|
354
421
|
|
355
|
-
|
422
|
+
def splat(keys, array)
|
356
423
|
|
357
|
-
|
358
|
-
|
359
|
-
|
424
|
+
ks = keys.dup
|
425
|
+
a = array.dup
|
426
|
+
h = {}
|
360
427
|
|
361
|
-
|
428
|
+
while k = ks.shift
|
362
429
|
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
430
|
+
if m = SPLAT_REGEX.match(k)
|
431
|
+
r, l = m[1, 2]
|
432
|
+
l = (l == '_') ? a.length - ks.length : l.to_i
|
433
|
+
h[r] = a.take(l) if r.length > 0
|
434
|
+
a = a.drop(l)
|
435
|
+
else
|
436
|
+
h[k] = a.shift
|
437
|
+
end
|
370
438
|
end
|
439
|
+
|
440
|
+
h
|
371
441
|
end
|
372
442
|
|
373
|
-
|
443
|
+
|
444
|
+
#
|
445
|
+
# misc
|
446
|
+
|
447
|
+
def point?(s)
|
448
|
+
|
449
|
+
POINTS.include?(s)
|
450
|
+
end
|
374
451
|
end
|
375
452
|
end
|
376
453
|
|