1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
# frozen_string_literal: true
module Byebug
module Helpers
#
# Utilities to assist command parsing
#
module ParseHelper
#
# Parses +str+ of command +cmd+ as an integer between +min+ and +max+.
#
# If either +min+ or +max+ is nil, that value has no bound.
#
# @todo Remove the `cmd` parameter. It has nothing to do with the method's
# purpose.
#
def get_int(str, cmd, min = nil, max = nil)
return nil, pr("parse.errors.int.not_number", cmd: cmd, str: str) unless /\A-?[0-9]+\z/.match?(str)
int = str.to_i
if min && int < min
err = pr("parse.errors.int.too_low", cmd: cmd, str: str, min: min)
return nil, err
elsif max && int > max
err = pr("parse.errors.int.too_high", cmd: cmd, str: str, max: max)
return nil, err
end
int
end
#
# @return true if code is syntactically correct for Ruby, false otherwise
#
def syntax_valid?(code)
return true unless code
if defined?(RubyVM::InstructionSequence.compile)
without_stderr do
RubyVM::InstructionSequence.compile(code)
true
rescue SyntaxError
false
end
else
require "ripper" unless defined?(Ripper)
without_stderr do
!Ripper.sexp(code).nil?
end
end
end
#
# @return +str+ as an integer or 1 if +str+ is empty.
#
def parse_steps(str, cmd)
return 1 unless str
steps, err = get_int(str, cmd, 1)
return nil, err unless steps
steps
end
private
#
# Temporarily disable output to $stderr
#
def without_stderr
old_stderr = $stderr
$stderr = StringIO.new
yield
ensure
$stderr = old_stderr
end
end
end
end
|