lib/schedulability/parser.rb in schedulability-0.1.0 vs lib/schedulability/parser.rb in schedulability-0.2.0
- old
+ new
@@ -54,19 +54,47 @@
###############
module_function
###############
+ ### Normalize an array of parsed periods into a human readable string.
+ def stringify( periods )
+ strings = []
+ periods.each do |period|
+ period_string = []
+ period.sort_by{|k, v| k}.each do |scale, ranges|
+ range_string = ""
+ range_string << "%s { " % [ scale.to_s ]
+
+ range_strings = ranges.each_with_object( [] ).each do |range, acc|
+ if range.min == range.max
+ acc << range.min
+ elsif range.exclude_end?
+ acc << "%d-%d" % [ range.min, range.max + 1 ]
+ else
+ acc << "%d-%d" % [ range.min, range.max ]
+ end
+ end
+
+ range_string << range_strings.join( ' ' ) << " }"
+ period_string << range_string
+ end
+ strings << period_string.join( ' ' )
+ end
+
+ return strings.join( ', ' )
+ end
+
+
### Scan +expression+ for periods and return them in an Array.
def extract_periods( expression )
positive_periods = []
negative_periods = []
expression.strip.downcase.split( /\s*,\s*/ ).each do |subexpr|
hash, negative = self.extract_period( subexpr )
if negative
- self.log.debug "Adding %p to the negative "
negative_periods << hash
else
positive_periods << hash
end
end
@@ -79,11 +107,10 @@
def extract_period( expression )
hash = {}
scanner = StringScanner.new( expression )
negative = scanner.skip( /\s*(!|not |except )\s*/ )
- self.log.debug "Period %p is %snegative!" % [ expression, negative ? "" : "not " ]
while scanner.scan( PERIOD_PATTERN )
ranges = scanner[:ranges].strip
scale = scanner[:scale]
@@ -185,19 +212,19 @@
end
### Return an Array of Integer minute Ranges for the specified +ranges+ expression.
def extract_minute_ranges( ranges )
- return self.extract_ranges( :minute, ranges, 0, 59 ) do |val|
+ return self.extract_ranges( :minute, ranges, 0, 60 ) do |val|
Integer( strip_leading_zeros(val) )
end
end
### Return an Array of Integer second Ranges for the specified +ranges+ expression.
def extract_second_ranges( ranges )
- return self.extract_ranges( :second, ranges, 0, 59 ) do |val|
+ return self.extract_ranges( :second, ranges, 0, 60 ) do |val|
Integer( strip_leading_zeros(val) )
end
end
@@ -231,24 +258,21 @@
exclude_end = EXCLUSIVE_RANGED_SCALES.include?( scale )
valid_range = Range.new( minval, maxval, exclude_end )
ints = ranges.split( /(?<!-)\s+(?!-)/ ).flat_map do |range|
min, max = range.split( /\s*-\s*/, 2 )
- self.log.debug "Min = %p, max = %p" % [ min, max ]
min = yield( min )
raise Schedulability::ParseError, "invalid %s value: %p" % [ scale, min ] unless
valid_range.cover?( min )
next [ min ] unless max
max = yield( max )
raise Schedulability::ParseError, "invalid %s value: %p" % [ scale, max ] unless
valid_range.cover?( max )
- self.log.debug "Parsed min = %p, max = %p" % [ min, max ]
if min > max
- self.log.debug "wrapped: %d-%d and %d-%d" % [ minval, max, min, maxval ]
Range.new( minval, max, exclude_end ).to_a +
Range.new( min, maxval, false ).to_a
else
Range.new( min, max, exclude_end ).to_a
end
@@ -259,12 +283,10 @@
### Coalese an Array of non-contiguous Range objects from the specified +ints+ for +scale+.
def coalesce_ranges( ints, scale )
exclude_end = EXCLUSIVE_RANGED_SCALES.include?( scale )
- self.log.debug "Coalescing %d ints to Ranges (%p, %s)" %
- [ ints.size, ints, exclude_end ? "exclusive" : "inclusive" ]
ints.flatten!
return [] if ints.empty?
prev = ints[0]
range_ints = ints.sort.slice_before do |v|
@@ -274,12 +296,10 @@
return range_ints.map do |values|
last_val = values.last
last_val += 1 if exclude_end
Range.new( values.first, last_val, exclude_end )
- end.tap do |ranges|
- self.log.debug "Coalesced range integers to Ranges: %p" % [ ranges ]
end
end
### Map a +value+ from a period's range to an Integer, using the specified +index_arrays+
@@ -300,10 +320,12 @@
return index
end
### Return a copy of the specified +val+ with any leading zeros stripped.
+ ### If the resulting string is empty, return "0".
def strip_leading_zeros( val )
- return val.sub( /\A0+/, '' )
+ return val.sub( /\A0+(?!$)/, '' )
end
end # module Schedulability::Parser
+