class Benry::Cmdopt::SCHEMA_CLASS

Public Class Methods

new() click to toggle source
# File lib/benry/cmdopt.rb, line 143
def initialize()
  @items = []
end

Public Instance Methods

add(key, optdef, help, type: nil, pattern: nil, enum: nil, &callback) click to toggle source
# File lib/benry/cmdopt.rb, line 147
def add(key, optdef, help, type: nil, pattern: nil, enum: nil, &callback)
  #; [!rhhji] raises SchemaError when key is not a Symbol.
  key.nil? || key.is_a?(Symbol)  or
    raise error("add(#{key.inspect}): 1st arg should be a Symbol as an option key.")
  #; [!vq6eq] raises SchemaError when help message is missing."
  help.nil? || help.is_a?(String)  or
    raise error("add(#{key.inspect}, #{optdef.inspect}): help message required as 3rd argument.")
  #; [!7hi2d] takes command option definition string.
  short, long, param, optional = parse_optdef(optdef)
  #; [!p9924] option key is omittable only when long option specified.
  #; [!jtp7z] raises SchemaError when key is nil and no long option.
  key || long  or
    raise error("add(#{key.inspect}, #{optdef.inspect}): long option required when option key (1st arg) not specified.")
  key ||= long.gsub(/-/, '_').intern
  #; [!97sn0] raises SchemaError when ',' is missing between short and long options.
  if long.nil? && param =~ /\A--/
    raise error("add(#{key.inspect}, #{optdef.inspect}): missing ',' between short option and long options.")
  end
  #; [!7xmr5] raises SchemaError when type is not registered.
  #; [!s2aaj] raises SchemaError when option has no params but type specified.
  if type
    PARAM_TYPES.key?(type)  or
      raise error("#{type.inspect}: unregistered type.")
    param  or
      raise error("#{type.inspect}: type specified in spite of option has no params.")
  end
  #; [!bi2fh] raises SchemaError when pattern is not a regexp.
  #; [!01fmt] raises SchmeaError when option has no params but pattern specified.
  if pattern
    pattern.is_a?(Regexp)  or
      raise error("#{pattern.inspect}: regexp expected.")
    param  or
      raise error("#{pattern.inspect}: pattern specified in spite of option has no params.")
  end
  #; [!melyd] raises SchmeaError when enum is not a Array nor Set.
  #; [!xqed8] raises SchemaError when enum specified for no param option.
  if enum
    enum.is_a?(Array) || enum.is_a?(Set)  or
      raise error("#{enum.inspect}: array or set expected.")
    param  or
      raise error("#{enum.inspect}: enum specified in spite of option has no params.")
  end
  #; [!yht0v] keeps command option definitions.
  item = SchemaItem.new(key, optdef, short, long, param, help,
             optional: optional, type: type, pattern: pattern, enum: enum, &callback)
  @items << item
  item
end
each_option_help() { |optdef, help| ... } click to toggle source
# File lib/benry/cmdopt.rb, line 231
def each_option_help(&block)
  #; [!4b911] yields each optin definition str and help message.
  @items.each do |item|
    yield item.optdef, item.help
  end
  #; [!zbxyv] returns self.
  self
end
find_long_option(long) click to toggle source
# File lib/benry/cmdopt.rb, line 246
def find_long_option(long)
  #; [!atmf9] returns option definition matched to long name.
  #; [!6haoo] returns nil when nothing found.
  return @items.find {|item| item.long == long }
end
find_short_option(short) click to toggle source
# File lib/benry/cmdopt.rb, line 240
def find_short_option(short)
  #; [!b4js1] returns option definition matched to short name.
  #; [!s4d1y] returns nil when nothing found.
  return @items.find {|item| item.short == short }
end
option_help(width_or_format=nil, all: false) click to toggle source
# File lib/benry/cmdopt.rb, line 196
def option_help(width_or_format=nil, all: false)
  #; [!0aq0i] can take integer as width.
  #; [!pcsah] can take format string.
  #; [!dndpd] detects option width automatically when nothing specified.
  case width_or_format
  when nil    ; format = _default_format()
  when Integer; format = "  %-#{width_or_format}s : %s"
  when String ; format = width_or_format
  else
    raise ArgumentError.new("#{width_or_format.inspect}: width (integer) or format (string) expected.")
  end
  #; [!v7z4x] skips option help if help message is not specified.
  #; [!to1th] includes all option help when `all` is true.
  buf = []
  width = nil
  each_option_help do |opt, help|
    #buf << format % [opt, help] << "\n" if help || all
    if help
      #; [!848rm] supports multi-lines help message.
      n = 0
      help.each_line do |line|
        if (n += 1) == 1
          buf << format % [opt, line.chomp] << "\n"
        else
          width ||= (format % ['', '']).length
          buf << (' ' * width) << line.chomp << "\n"
        end
      end
    elsif all
      buf << format % [opt, ''] << "\n"
    end
  end
  return buf.join()
end

Private Instance Methods

_default_format(min_width=nil, max_width=35) click to toggle source
# File lib/benry/cmdopt.rb, line 278
def _default_format(min_width=nil, max_width=35)
  #; [!bmr7d] changes min_with according to options.
  min_width ||= _preferred_option_width()
  #; [!hr45y] detects preffered option width.
  w = 0
  each_option_help do |opt, help|
    w = opt.length if w < opt.length
  end
  w = min_width if w < min_width
  w = max_width if w > max_width
  #; [!kkh9t] returns format string.
  return "  %-#{w}s : %s"
end
_preferred_option_width() click to toggle source
# File lib/benry/cmdopt.rb, line 292
def _preferred_option_width()
  #; [!kl91t] shorten option help min width when only single options which take no arg.
  #; [!0koqb] widen option help min width when any option takes an arg.
  #; [!kl91t] widen option help min width when long option exists.
  long_p  = @items.any? {|x| x.help &&  x.long &&  x.param }
  short_p = @items.all? {|x| x.help && !x.long && !x.param }
  return short_p ? 8 : long_p ? 20 : 14
end
error(msg) click to toggle source
# File lib/benry/cmdopt.rb, line 254
def error(msg)
  return SchemaError.new(msg)
end
parse_optdef(optdef) click to toggle source
# File lib/benry/cmdopt.rb, line 258
def parse_optdef(optdef)
  #; [!qw0ac] parses command option definition string.
  #; [!ae733] parses command option definition which has a required param.
  #; [!4h05c] parses command option definition which has an optional param.
  #; [!b7jo3] raises SchemaError when command option definition is invalid.
  case optdef
  when /\A[ \t]*-(\w),[ \t]*--(\w[-\w]*)(?:=(\S*?)|\[=(\S*?)\])?\z/
    short, long, param1, param2 = $1, $2, $3, $4
  when /\A[ \t]*-(\w)(?:[ \t]+(\S+)|\[(\S+)\])?\z/
    short, long, param1, param2 = $1, nil, $2, $3
  when /\A[ \t]*--(\w[-\w]*)(?:=(\S*?)|\[=(\S*?)\])?\z/
    short, long, param1, param2 = nil, $1, $2, $3
  when /(--\w[-\w])*[ \t]+(\S+)/
    raise error("#{optdef}: invalid option definition (use '#{$1}=#{$2}' instead of '#{$1} #{$2}').")
  else
    raise error("#{optdef}: invalid option definition.")
  end
  return short, long, param1 || param2, !!param2
end