glark 1.9.0 → 1.10.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.
- data/bin/glark +2 -2
- data/lib/glark.rb +1 -1
- data/lib/glark/app/app.rb +48 -0
- data/lib/glark/app/help.rb +103 -0
- data/lib/glark/app/info/options.rb +84 -0
- data/lib/glark/app/options.rb +201 -0
- data/lib/glark/app/rcfile.rb +49 -0
- data/lib/glark/app/runner.rb +140 -0
- data/lib/glark/app/spec.rb +19 -0
- data/lib/glark/input/filter/criteria_opts.rb +41 -0
- data/lib/glark/input/filter/dir_criteria_opts.rb +37 -0
- data/lib/glark/input/filter/file_criteria_opts.rb +33 -0
- data/lib/glark/input/filter/filter.rb +59 -0
- data/lib/glark/input/filter/options.rb +171 -0
- data/lib/glark/input/options.rb +120 -0
- data/lib/glark/input/range.rb +104 -0
- data/lib/glark/input/spec.rb +39 -0
- data/lib/glark/io/file/archive_file.rb +64 -0
- data/lib/glark/io/file/binary_file.rb +19 -0
- data/lib/glark/io/file/file.rb +57 -0
- data/lib/glark/io/file/gz_file.rb +21 -0
- data/lib/glark/io/file/tar_file.rb +35 -0
- data/lib/glark/io/file/tar_gz_file.rb +52 -0
- data/lib/glark/io/file/zip_file.rb +39 -0
- data/lib/glark/match/and.rb +83 -0
- data/lib/glark/match/and_distance.rb +58 -0
- data/lib/glark/match/compound.rb +34 -0
- data/lib/glark/match/expression.rb +63 -0
- data/lib/glark/match/factory.rb +173 -0
- data/lib/glark/match/ior.rb +20 -0
- data/lib/glark/match/options.rb +74 -0
- data/lib/glark/match/or.rb +41 -0
- data/lib/glark/match/re.rb +81 -0
- data/lib/glark/match/re_factory.rb +44 -0
- data/lib/glark/match/spec.rb +59 -0
- data/lib/glark/match/xor.rb +20 -0
- data/lib/glark/output/binary_file_summary.rb +17 -0
- data/lib/glark/output/common.rb +43 -0
- data/lib/glark/output/context.rb +57 -0
- data/lib/glark/output/count.rb +26 -0
- data/lib/glark/output/file_header.rb +20 -0
- data/lib/glark/output/file_name_only.rb +35 -0
- data/lib/glark/output/formatted.rb +22 -0
- data/lib/glark/output/glark_count.rb +23 -0
- data/lib/glark/output/glark_format.rb +62 -0
- data/lib/glark/output/glark_lines.rb +36 -0
- data/lib/glark/output/grep_count.rb +18 -0
- data/lib/glark/output/grep_lines.rb +42 -0
- data/lib/glark/output/line_status.rb +46 -0
- data/lib/glark/output/lines.rb +100 -0
- data/lib/glark/output/match_list.rb +15 -0
- data/lib/glark/output/options.rb +103 -0
- data/lib/glark/output/results.rb +23 -0
- data/lib/glark/output/spec.rb +105 -0
- data/lib/glark/output/unfiltered_lines.rb +28 -0
- data/lib/glark/util/colors/options.rb +143 -0
- data/lib/glark/util/colors/spec.rb +21 -0
- data/lib/glark/util/highlight.rb +108 -0
- data/lib/glark/util/io/depth.rb +29 -0
- data/lib/glark/util/io/fileset.rb +162 -0
- data/lib/glark/util/io/filter/criteria.rb +49 -0
- data/lib/glark/util/io/filter/filter.rb +10 -0
- data/lib/glark/util/io/lines.rb +117 -0
- data/lib/glark/util/option.rb +34 -0
- data/lib/glark/util/options.rb +12 -0
- data/lib/glark/util/optutil.rb +69 -0
- data/lib/glark/util/timestamper.rb +18 -0
- data/man/glark.1 +1134 -0
- data/test/glark/app/and_test.rb +82 -0
- data/test/glark/app/compound_test.rb +33 -0
- data/test/glark/app/context_test.rb +43 -0
- data/test/glark/app/count_test.rb +89 -0
- data/test/glark/app/dump_test.rb +16 -0
- data/test/glark/app/expression_file_test.rb +22 -0
- data/test/glark/app/extended_regexp_test.rb +17 -0
- data/test/glark/app/extract_matches_test.rb +27 -0
- data/test/glark/app/files_with_match_test.rb +32 -0
- data/test/glark/app/files_without_match_test.rb +26 -0
- data/test/glark/app/filter_test.rb +118 -0
- data/test/glark/app/highlight_test.rb +78 -0
- data/test/glark/app/ignore_case_test.rb +22 -0
- data/test/glark/app/invert_test.rb +49 -0
- data/test/glark/app/ior_test.rb +21 -0
- data/test/glark/app/label_test.rb +28 -0
- data/test/glark/app/line_number_color_test.rb +42 -0
- data/test/glark/app/line_numbers_test.rb +42 -0
- data/test/glark/app/match_limit_test.rb +49 -0
- data/test/glark/app/options_test.rb +722 -0
- data/test/glark/app/range_test.rb +101 -0
- data/test/glark/app/rcfile_test.rb +113 -0
- data/test/glark/app/record_separator_test.rb +32 -0
- data/test/glark/app/regexp_test.rb +48 -0
- data/test/glark/app/tc.rb +92 -0
- data/test/glark/app/text_color_test.rb +31 -0
- data/test/glark/app/whole_lines_test.rb +17 -0
- data/test/glark/app/whole_words_test.rb +42 -0
- data/test/glark/app/xor_test.rb +19 -0
- data/test/glark/input/binary_file_test.rb +0 -0
- data/test/glark/input/directory_test.rb +202 -0
- data/test/glark/input/dirname_test.rb +69 -0
- data/test/glark/input/exclude_matching_test.rb +20 -0
- data/test/glark/input/ext_test.rb +65 -0
- data/test/glark/input/filter/criteria_test.rb +91 -0
- data/test/glark/input/filter/filter_spec_test.rb +27 -0
- data/test/glark/input/filter/filter_test.rb +21 -0
- data/test/glark/input/name_test.rb +75 -0
- data/test/glark/input/path_test.rb +72 -0
- data/test/glark/input/range_test.rb +82 -0
- data/test/glark/input/size_limit_test.rb +51 -0
- data/test/glark/input/split_as_path_test.rb +28 -0
- data/test/glark/match_test.rb +192 -0
- data/test/glark/resources.rb +21 -0
- data/test/glark/tc.rb +37 -0
- data/test/resources/add.rb +10 -0
- data/test/resources/echo.rb +2 -0
- data/test/resources/greet.rb +13 -0
- metadata +198 -28
- data/README +0 -0
- data/bin/jlark +0 -63
- data/lib/glark/expression.rb +0 -440
- data/lib/glark/exprfactory.rb +0 -248
- data/lib/glark/glark.rb +0 -297
- data/lib/glark/help.rb +0 -85
- data/lib/glark/input.rb +0 -183
- data/lib/glark/options.rb +0 -757
- data/lib/glark/output.rb +0 -266
- data/test/lib/glark/glark_test.rb +0 -317
- data/test/lib/glark/options_test.rb +0 -891
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
require 'glark/io/file/gz_file'
|
5
|
+
require 'glark/io/file/tar_file'
|
6
|
+
|
7
|
+
module Glark
|
8
|
+
class TarGzFile
|
9
|
+
include Loggable
|
10
|
+
|
11
|
+
def initialize fname, range
|
12
|
+
@fname = fname
|
13
|
+
@range = range
|
14
|
+
end
|
15
|
+
|
16
|
+
def list
|
17
|
+
contents = Array.new
|
18
|
+
each_file do |entry|
|
19
|
+
contents << entry.full_name
|
20
|
+
end
|
21
|
+
contents
|
22
|
+
end
|
23
|
+
|
24
|
+
def run_search &blk
|
25
|
+
# a glitch with zlib results in a warning ("attempt to close unfinished
|
26
|
+
# zstream; reset forced.") for some tarballs, so we turn off warnings for
|
27
|
+
# a moment:
|
28
|
+
$-w = false
|
29
|
+
|
30
|
+
Zlib::GzipReader.open(@fname) do |gzio|
|
31
|
+
tarfile = Glark::TarFile.new @fname, @range, gzio
|
32
|
+
blk.call tarfile
|
33
|
+
end
|
34
|
+
|
35
|
+
$-w = true
|
36
|
+
end
|
37
|
+
|
38
|
+
def search_list expr, output_cls, output_opts
|
39
|
+
run_search do |tarfile|
|
40
|
+
tarfile.search_list expr, output_cls, output_opts
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def search expr, output_type_cls, output_opts
|
45
|
+
matched = nil
|
46
|
+
run_search do |tarfile|
|
47
|
+
matched = tarfile.search(expr, output_type_cls, output_opts) || matched
|
48
|
+
end
|
49
|
+
matched
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
require 'glark/io/file/archive_file'
|
5
|
+
|
6
|
+
module Glark
|
7
|
+
class ZipFile < ArchiveFile
|
8
|
+
include Loggable
|
9
|
+
|
10
|
+
def initialize fname, range, &blk
|
11
|
+
super fname, range
|
12
|
+
|
13
|
+
# Same caveat as ZipFile. Given that this is a gem, I'm not sure if it is
|
14
|
+
# installed with other package managers. So the require is down here, used
|
15
|
+
# only if needed.
|
16
|
+
|
17
|
+
begin
|
18
|
+
require 'zip/zip'
|
19
|
+
rescue LoadError => e
|
20
|
+
msg = "error loading zip gem: #{e}\n"
|
21
|
+
msg << "to install this dependency, run 'gem install rubyzip'"
|
22
|
+
info "msg: #{msg}".on_red
|
23
|
+
raise msg
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_reader
|
28
|
+
@zipfile = Zip::ZipFile.new @fname
|
29
|
+
end
|
30
|
+
|
31
|
+
def read entry
|
32
|
+
@zipfile.read entry
|
33
|
+
end
|
34
|
+
|
35
|
+
def entry_name entry
|
36
|
+
entry.name
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
#!ruby -w
|
3
|
+
# vim: set filetype=ruby : set sw=2
|
4
|
+
|
5
|
+
require 'glark/match/compound'
|
6
|
+
|
7
|
+
# Evaluates both expressions, and is satisfied when both return true.
|
8
|
+
class AndExpression < CompoundExpression
|
9
|
+
|
10
|
+
def initialize dist, op1, op2
|
11
|
+
@dist = dist
|
12
|
+
super op1, op2
|
13
|
+
end
|
14
|
+
|
15
|
+
def match_within_distance op, lnum
|
16
|
+
op.matches.size > 0 and (op.matches[-1] - lnum <= @dist)
|
17
|
+
end
|
18
|
+
|
19
|
+
def inspect
|
20
|
+
str = "("+ @ops[0].to_s
|
21
|
+
if @dist == 0
|
22
|
+
str += " same line as "
|
23
|
+
elsif @dist.kind_of?(Float) && @dist.infinite?
|
24
|
+
str += " same file as "
|
25
|
+
else
|
26
|
+
str += " within " + @dist.to_s + " lines of "
|
27
|
+
end
|
28
|
+
str += @ops[1].to_s + ")"
|
29
|
+
str
|
30
|
+
end
|
31
|
+
|
32
|
+
def match? line, lnum, file, formatter
|
33
|
+
matches = (0 ... @ops.length).select do |oi|
|
34
|
+
@ops[oi].evaluate line, lnum, file, formatter
|
35
|
+
end
|
36
|
+
|
37
|
+
matches.each do |mi|
|
38
|
+
oidx = (1 + mi) % @ops.length
|
39
|
+
other = @ops[oidx]
|
40
|
+
if match_within_distance other, lnum
|
41
|
+
# search for the maximum match within the distance limit
|
42
|
+
other.matches.each do |m|
|
43
|
+
if lnum - m <= @dist
|
44
|
+
@last_start = m
|
45
|
+
return true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
return false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
false
|
53
|
+
end
|
54
|
+
|
55
|
+
def end_position
|
56
|
+
@ops.collect { |op| op.end_position }.max
|
57
|
+
end
|
58
|
+
|
59
|
+
def evaluate line, lnum, file, formatter
|
60
|
+
if match? line, lnum, file, formatter
|
61
|
+
@match_line_number = lnum
|
62
|
+
true
|
63
|
+
else
|
64
|
+
false
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def explain level = 0
|
69
|
+
str = ""
|
70
|
+
if @dist == 0
|
71
|
+
str += " " * level + "on the same line:\n"
|
72
|
+
elsif @dist.kind_of?(Float) && @dist.infinite?
|
73
|
+
str += " " * level + "in the same file:\n"
|
74
|
+
else
|
75
|
+
lnstr = @dist == 1 ? "line" : "lines"
|
76
|
+
str += " " * level + "within #{@dist} #{lnstr} of each other:\n"
|
77
|
+
end
|
78
|
+
str += @ops[0].explain(level + 4)
|
79
|
+
str += " " * level + "and\n"
|
80
|
+
str += @ops[1].explain(level + 4)
|
81
|
+
str
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
#!ruby -w
|
3
|
+
# vim: set filetype=ruby : set sw=2
|
4
|
+
|
5
|
+
# Distance for and expression
|
6
|
+
|
7
|
+
require 'rubygems'
|
8
|
+
require 'riel/string'
|
9
|
+
require 'glark/match/re'
|
10
|
+
require 'glark/match/ior'
|
11
|
+
require 'glark/match/xor'
|
12
|
+
require 'glark/match/and'
|
13
|
+
|
14
|
+
class AndDistance
|
15
|
+
include Loggable
|
16
|
+
|
17
|
+
# signifies no limit to the distance between matches, i.e., anywhere within
|
18
|
+
# the entire file is valid.
|
19
|
+
INFINITE_DISTANCE = -1
|
20
|
+
|
21
|
+
AND_EQ_NUM_RE = Regexp.new '^--and=(\-?\d+)?$'
|
22
|
+
|
23
|
+
attr_reader :distance
|
24
|
+
|
25
|
+
def initialize arg, args
|
26
|
+
@distance = if arg == "-a"
|
27
|
+
args.shift
|
28
|
+
elsif arg == "--and"
|
29
|
+
if args.size > 0 && numeric?(args[0])
|
30
|
+
args.shift
|
31
|
+
else
|
32
|
+
"0"
|
33
|
+
end
|
34
|
+
elsif md = AND_EQ_NUM_RE.match(arg)
|
35
|
+
md[1]
|
36
|
+
else
|
37
|
+
raise "invalid 'and' option: '#{arg}'"
|
38
|
+
end
|
39
|
+
|
40
|
+
# check to ensure that this is numeric
|
41
|
+
if !numeric? @distance
|
42
|
+
raise "invalid distance for 'and' expression: '#{@distance}'\n" +
|
43
|
+
" expecting an integer, or #{INFINITE_DISTANCE} for 'infinite'"
|
44
|
+
end
|
45
|
+
|
46
|
+
if @distance.to_i == INFINITE_DISTANCE
|
47
|
+
@distance = 1.0 / 0.0 # infinity
|
48
|
+
else
|
49
|
+
@distance = @distance.to_i
|
50
|
+
end
|
51
|
+
|
52
|
+
@distance
|
53
|
+
end
|
54
|
+
|
55
|
+
def numeric? x
|
56
|
+
x && (x.kind_of?(Fixnum) || x.to_i == INFINITE_DISTANCE || x.num)
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
#!ruby -w
|
3
|
+
# vim: set filetype=ruby : set sw=2
|
4
|
+
|
5
|
+
require 'glark/match/expression'
|
6
|
+
|
7
|
+
# -------------------------------------------------------
|
8
|
+
# Compound expression function object
|
9
|
+
# -------------------------------------------------------
|
10
|
+
|
11
|
+
# Associates a collection of expressions.
|
12
|
+
class CompoundExpression < Expression
|
13
|
+
attr_reader :ops
|
14
|
+
|
15
|
+
def initialize(*ops)
|
16
|
+
@ops = ops
|
17
|
+
super()
|
18
|
+
end
|
19
|
+
|
20
|
+
def reset_file file
|
21
|
+
@ops.each do |op|
|
22
|
+
op.reset_file file
|
23
|
+
end
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
def start_position
|
28
|
+
@last_start
|
29
|
+
end
|
30
|
+
|
31
|
+
def == other
|
32
|
+
self.class == other.class && @ops == other.ops
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
#!ruby -w
|
3
|
+
# vim: set filetype=ruby : set sw=2
|
4
|
+
|
5
|
+
# Extended regular-expression-based expressions.
|
6
|
+
|
7
|
+
require 'rubygems'
|
8
|
+
require 'riel'
|
9
|
+
|
10
|
+
# An expression, which can be applied (processed) against a Glark::File.
|
11
|
+
class Expression
|
12
|
+
include Loggable
|
13
|
+
|
14
|
+
attr_accessor :matches
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@match_line_number = nil
|
18
|
+
@matches = Array.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_match lnum
|
22
|
+
@matches.push lnum
|
23
|
+
end
|
24
|
+
|
25
|
+
def start_position
|
26
|
+
@match_line_number
|
27
|
+
end
|
28
|
+
|
29
|
+
def end_position
|
30
|
+
start_position
|
31
|
+
end
|
32
|
+
|
33
|
+
def reset_file file
|
34
|
+
@match_line_number = nil
|
35
|
+
@matches = Array.new
|
36
|
+
end
|
37
|
+
|
38
|
+
def process file, formatter
|
39
|
+
reset_file file.fname
|
40
|
+
|
41
|
+
rgstart = file.get_range_start
|
42
|
+
rgend = file.get_range_end
|
43
|
+
|
44
|
+
lastmatch = 0
|
45
|
+
lnum = 0
|
46
|
+
file.each_line do |line|
|
47
|
+
if ((!rgstart || lnum >= rgstart) &&
|
48
|
+
(!rgend || lnum < rgend) &&
|
49
|
+
evaluate(line, lnum, file, formatter))
|
50
|
+
|
51
|
+
break if formatter.process_match start_position, end_position, lastmatch, lnum
|
52
|
+
lastmatch = lnum + 1
|
53
|
+
end
|
54
|
+
lnum += 1
|
55
|
+
end
|
56
|
+
|
57
|
+
formatter.process_end lnum
|
58
|
+
end
|
59
|
+
|
60
|
+
def to_s
|
61
|
+
inspect
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
#!ruby -w
|
3
|
+
# vim: set filetype=ruby : set sw=2
|
4
|
+
|
5
|
+
# Expression factory.
|
6
|
+
|
7
|
+
require 'rubygems'
|
8
|
+
require 'riel/regexp'
|
9
|
+
require 'riel/log/loggable'
|
10
|
+
require 'glark/match/and'
|
11
|
+
require 'glark/match/and_distance'
|
12
|
+
require 'glark/match/ior'
|
13
|
+
require 'glark/match/re_factory'
|
14
|
+
require 'glark/match/xor'
|
15
|
+
|
16
|
+
class ExpressionFactory
|
17
|
+
include Loggable
|
18
|
+
|
19
|
+
attr_reader :expr
|
20
|
+
|
21
|
+
def initialize matchspec
|
22
|
+
@regexp_factory = RegexpExpressionFactory.new matchspec
|
23
|
+
end
|
24
|
+
|
25
|
+
# reads a file containing one regular expression per line.
|
26
|
+
def read_file fname
|
27
|
+
expr = nil
|
28
|
+
File.open(fname) do |file|
|
29
|
+
file.each_line do |line|
|
30
|
+
line.strip!
|
31
|
+
next if line.empty?
|
32
|
+
|
33
|
+
# flatten the or expression instead of nesting it, to avoid
|
34
|
+
# stack overruns for very large files.
|
35
|
+
re = make_regular_expression line.chomp
|
36
|
+
if expr
|
37
|
+
expr.ops << re
|
38
|
+
else
|
39
|
+
expr = InclusiveOrExpression.new re
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
expr
|
44
|
+
end
|
45
|
+
|
46
|
+
def make_regular_expression pattern, negated = false
|
47
|
+
@regexp_factory.create_expression pattern, negated
|
48
|
+
end
|
49
|
+
|
50
|
+
# creates two expressions and returns them.
|
51
|
+
def make_expressions args
|
52
|
+
a1 = make_expression args
|
53
|
+
a2 = make_expression args
|
54
|
+
|
55
|
+
[ a1, a2 ]
|
56
|
+
end
|
57
|
+
|
58
|
+
# removes optional end tag
|
59
|
+
def shift_end_tag name, args
|
60
|
+
# explicit end tag is optional:
|
61
|
+
args.shift if args[0] == ("--end-of-" + name)
|
62
|
+
end
|
63
|
+
|
64
|
+
def make_not_expression args
|
65
|
+
expr = make_regular_expression args, true
|
66
|
+
unless expr
|
67
|
+
raise "'not' expression takes one argument"
|
68
|
+
end
|
69
|
+
|
70
|
+
# explicit end tag is optional:
|
71
|
+
shift_end_tag "not", args
|
72
|
+
expr
|
73
|
+
end
|
74
|
+
|
75
|
+
def make_two_expressions args, type
|
76
|
+
a1, a2 = make_expressions args
|
77
|
+
unless a1 && a2
|
78
|
+
raise "'" + type + "' expression takes two arguments"
|
79
|
+
end
|
80
|
+
|
81
|
+
shift_end_tag type, args
|
82
|
+
[ a1, a2 ]
|
83
|
+
end
|
84
|
+
|
85
|
+
def make_or_expression args
|
86
|
+
a1, a2 = make_two_expressions args, "or"
|
87
|
+
InclusiveOrExpression.new a1, a2
|
88
|
+
end
|
89
|
+
|
90
|
+
def make_xor_expression args
|
91
|
+
a1, a2 = make_two_expressions args, "xor"
|
92
|
+
ExclusiveOrExpression.new a1, a2
|
93
|
+
end
|
94
|
+
|
95
|
+
def make_and_distance arg, args
|
96
|
+
adist = AndDistance.new arg, args
|
97
|
+
adist.distance
|
98
|
+
end
|
99
|
+
|
100
|
+
def make_and_expression arg, args
|
101
|
+
dist = make_and_distance arg, args
|
102
|
+
|
103
|
+
a1, a2 = make_two_expressions args, "and"
|
104
|
+
AndExpression.new dist, a1, a2
|
105
|
+
end
|
106
|
+
|
107
|
+
def make_infix_expression arg, args = []
|
108
|
+
expr = nil
|
109
|
+
|
110
|
+
while arg
|
111
|
+
case arg
|
112
|
+
when '('
|
113
|
+
arg = args.shift
|
114
|
+
expr = make_infix_expression arg, args
|
115
|
+
when '--or', '-o'
|
116
|
+
arg = args.shift
|
117
|
+
rhs = make_infix_expression arg, args
|
118
|
+
expr = InclusiveOrExpression.new expr, rhs
|
119
|
+
when '--xor'
|
120
|
+
arg = args.shift
|
121
|
+
rhs = make_infix_expression arg, args
|
122
|
+
expr = ExclusiveOrExpression.new expr, rhs
|
123
|
+
when Regexp.new('^--and'), '-a'
|
124
|
+
dist = make_and_distance arg, args
|
125
|
+
arg = args.shift
|
126
|
+
rhs = make_infix_expression arg, args
|
127
|
+
expr = AndExpression.new dist, expr, rhs
|
128
|
+
when ')'
|
129
|
+
break
|
130
|
+
else
|
131
|
+
expr = make_regular_expression arg
|
132
|
+
break
|
133
|
+
end
|
134
|
+
arg = args.shift
|
135
|
+
end
|
136
|
+
|
137
|
+
if !expr
|
138
|
+
raise "No expression provided."
|
139
|
+
end
|
140
|
+
|
141
|
+
expr
|
142
|
+
end
|
143
|
+
|
144
|
+
def make_expression args, warn_option = false
|
145
|
+
arg = args[0]
|
146
|
+
|
147
|
+
if arg
|
148
|
+
case arg
|
149
|
+
when "--or", "-o"
|
150
|
+
args.shift
|
151
|
+
make_or_expression args
|
152
|
+
when "--xor"
|
153
|
+
args.shift
|
154
|
+
make_xor_expression args
|
155
|
+
when %r{^\-\-and}, %r{^\-a}
|
156
|
+
args.shift
|
157
|
+
make_and_expression arg, args
|
158
|
+
when '('
|
159
|
+
args.shift
|
160
|
+
make_infix_expression arg, args
|
161
|
+
else
|
162
|
+
if warn_option && arg.index(%r{^\-{1,2}\w})
|
163
|
+
raise "option not understood: #{arg}"
|
164
|
+
end
|
165
|
+
|
166
|
+
args.shift
|
167
|
+
make_regular_expression arg
|
168
|
+
end
|
169
|
+
else
|
170
|
+
nil
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|