Parent

Getopt::Declare::Arg

Class used to handle other arguments (flags, etc)

Constants

Helpcmd
Versioncmd

Attributes

actions[RW]
args[RW]
desc[RW]
ditto[RW]
flag[RW]
id[RW]
nocase[RW]
repeatable[RW]
required[RW]
requires[RW]

Public Class Methods

besthelp() click to toggle source
# File lib/Getopt/Declare.rb, line 470
def Arg.besthelp
  for i in Helpcmd; return i if @@helpcmdH[i]; end
end
bestversion() click to toggle source
# File lib/Getopt/Declare.rb, line 485
def Arg.bestversion
  for i in Versioncmd; return i if @@versioncmdH[i]; end
end
clear() click to toggle source
# File lib/Getopt/Declare.rb, line 498
def Arg.clear
  @@flags = []
  @@nextid = 0
  @@posflagpat  = nil
  @@negflagpath = nil
end
helppat() click to toggle source

Create regex of help flags based on help shortcuts left

# File lib/Getopt/Declare.rb, line 475
def Arg.helppat
  @@helpcmdH.keys.join('|')
end
negflagpat(*t) click to toggle source

Return string with regex that avoids all flags in declaration

# File lib/Getopt/Declare.rb, line 506
def Arg.negflagpat(*t)
  if !@@negflagpat && @@flags
    @@negflagpat = ( @@flags.map { |i| 
                      "(?!" + Regexp::quote(i) + ")" } ).join('')
  else
    @@negflagpat
  end
end
new(spec, desc, dittoflag) click to toggle source

Constructor

# File lib/Getopt/Declare.rb, line 543
def initialize(spec, desc, dittoflag)
  first = 1


  @@nextid += 1
  @flag     = ''
  @foundid  = nil
  @args     = []
  @actions  = []
  @ditto    = dittoflag
  @required = false
  @requires = nil
  @id       = @@nextid
  @desc     = spec.dup
  @items    = 0
  @nocase   = false

  @desc.sub!(/\A\s*(.*?)\s*\Z/,'\1')

  while spec && spec != ''
    begin

      # OPTIONAL
      if spec.sub!( /\A(\s*)\[/, '\1' )
        @args.push( StartOpt.new )
        next
      elsif spec.sub!(/\A\s*\]/,"")
        @args.push( EndOpt.new )
        next
      end

      # ARG

      se  = DelimScanner::new( spec )
      tmp = se.scanBracketed('<>')

      arg = nows = nil
      arg, spec, nows = tmp[:match], tmp[:suffix], tmp[:prefix] if tmp


      if arg
        arg =~ /\A(\s*)(<)([a-zA-Z]\w*)(:[^>]+|)>/ or
          raise "Error: bad Getopt::Declare parameter variable specification near '#{arg}'\n"

        # NAME,TYPE,NOW
        details = [ "#$3", "#$4", !first && !(nows.length>0) ]

        if spec && spec.sub!( /\A\.\.\./, "")      # ARRAY ARG
          @args.push( ArrayArg.new(*details) )
        else  # SCALAR ARG
          @args.push( ScalarArg.new(*details) )
        end
        @items += 1
        next

        # PUNCTUATION
      elsif spec.sub!( /\A(\s*)((\\.|[^\] \t\n\[<])+)/, '' )
        ows, punct = $1, $2
        punct.gsub!( /\\(?!\\)(.)/, '\1' )

        if first
          spec  =~ /\A(\S+)/
          @foundid = "#{punct}#{$1}"
          @flag = punct
          @@flags.push( punct )
        else
          @args.push( Punctuator.new(punct, !(ows.size > 0)) )
          @items += 1
        end

      else 
        break
      end # if arg/spec.sub
    ensure
      first = nil
    end
  end # while

  @@helpcmdH.delete(@flag)    if @@helpcmdH.key?(@flag)
  @@versioncmdH.delete(@flag) if @@versioncmdH.key?(@flag)
end
posflagpat(*t) click to toggle source

Return string with regex that matches any of the flags in declaration

# File lib/Getopt/Declare.rb, line 516
def Arg.posflagpat(*t)
  if !@@posflagpat && @@flags
    @@posflagpat = '(?:' + ( @@flags.map { |i| 
                              Regexp::quote(i) } ).join('|') + ')'
  else
    @@posflagpat
  end
end
versionpat() click to toggle source

Create regex of version flags based on help shortcuts left

# File lib/Getopt/Declare.rb, line 490
def Arg.versionpat
  @@versioncmdH.keys.join('|')
end

Public Instance Methods

code(*t) click to toggle source

Return String with code to parse this argument (ie. flag)

# File lib/Getopt/Declare.rb, line 628
def code(*t)
  owner = t[0]
  mod   = t[1]


  code = "\n"
  flag = @flag
  clump = owner.clump
  i = 0
  nocasei = ((Getopt::Declare::nocase || @nocase) ? 'i' : '')

  code << "          catch(:paramout) do\n            while "
  code += !@repeatable? "!_FOUND_['" + self.foundid + "']" : "true"

  if (flag && (clump==1 && flag !~ /\A[^a-z0-9]+[a-z0-9]\Z/ ||
               (clump<3 && @args.size > 0 )))
    code << ' and !_lastprefix'
  end

  code       if flag != ''        # This boundary is to handle -- option, so that if user uses        # --foo and --foo is not a flag, it does not become        # --  and unused: 'foo', but an error saying flag '--foo' not defined.        boundary = ''        boundary = '(\s+|\Z)' if flag =~ /^(--|-|\+|\+\+)$/        code << '                  _args && _pos = gindex( _args, /\G[\s|\0]*' +           Regexp::quote(flag) + boundary + '/' + nocasei + ", _pos) or throw(:paramout)                   unless @_errormsg                    @_errormsg = %q|incorrect specification of '" + flag + "' parameter|                  end"      elsif ( ScalarArg::stdtype(@args[0].type)||'') !~ /\%F/        code << "\n                  throw(:paramout) if @_errormsg\n"      end      code << "\n                  _PARAM_ = '" + self.name + "'\n"      trailer = []      i = @args.size-1      while i > 0        trailer[i-1] = @args[i].trailer        trailer[i-1] = trailer[i] unless trailer[i-1]        i -= 1      end # while i      if @args        code << "\n"+'                 _args && _pos = gindex( _args, /\G'        @args.each_with_index { |arg, i|          code << arg.ows(arg.matcher(trailer[i]))        }        code << '/x' + nocasei + ", _pos ) or throw(:paramout)\n"      end # if @args      @args.each_with_index { |arg, i|        code << arg.code(i,mod)        #, $flag ????      }      if flag        mutexlist = owner.mutex[flag] ?         (  owner.mutex[flag].map {|i| "'#{i}'"} ).join(',') : ''        code << "                  if _invalid.has_key?('#{flag}')                    @_errormsg = %q|parameter '#{flag}' not allowed with parameter '| + _invalid['#{flag}'] + %q|'|                    throw(:paramout)                  else                    for i in [#{mutexlist}]                        _invalid[i] = '#{flag}'                    end                  end  #if/then"      end      for action in @actions        #action.sub!( /(\s*\{)/, '\1 module '+mod )  # @TODO        code << "\n                  " + action + "\n"      end      if flag && @items==0        code << "\n                  @cache['#{flag}'] = '#{flag}'\n"        if @ditto          code << "\n                  @cache['#{@ditto.flag}'] = '#{flag}'\n"        end      end      if @items > 1        code << "                  @cache['#{self.name}'] = {} unless @cache['#{self.name}'].kind_of?(Hash)\n"        if @ditto          code << "\n                  @cache['#{@ditto.name}'] = {} unless @cache['#{@ditto.name}'].kind_of?(Hash)\n"        end      end      for subarg in @args        code << subarg.cachecode(self.name,@items)        if ditto        code << subarg.cachecode(@ditto.name,@items)        end      end      if flag =~ /\A([^a-z0-9]+)/i        code << '                  _lastprefix = "'+ Regexp::quote("#$1") + '"' + "\n"      else        code << "                  _lastprefix = nil\n"      end      code << "                  _FOUND_['"+ self.foundid + "'] = 1                  throw :arg if _pos > 0                  _nextpos = _args.size                  throw :alldone                end  # catch(:param)              end  # begin            end # while          end # catch(:paramout)"      code    end    # Return name of argument, which can be flag's name or variable's name    def name      return @flag unless @flag.empty?      for i in @args        return "<#{i.name}>" if i.respond_to?(:name)      end      raise "Unknown flag name for parameter #{self.desc}"    end    # Return foundid of argument, which can be flag's name or variable's name    def foundid      return @foundid || self.name    end  end # Arg  private  class << self    @nocase = false    attr_accessor :nocase  end  #  # This is an additional function added to the class to simulate Perl's  # pos() \G behavior and m///g  #  # It performs a regex match, and returns the last index position of the   # match or nil.  On successive invocations, it allows doing regex matches  # NOT from the beginning of the string easily.  #  # Class Array @@m stores the list of matches, as #$1 and similar   # variables have short lifespan in ruby, unlike perl.  #  def gindex(str, re, pos)    @@m.clear()    if pos = str.index( re, pos )      l = $&.size  # length of match      if l > 0        @@m[0] = "#$1"        @@m[1] = "#$2"        @@m[2] = "#$3"        @@m[3] = "#$4"        @@m[4] = "#$5"        @@m[5] = "#$6"        @@m[6] = "#$7"        @@m[7] = "#$8"        @@m[8] = "#$9"        pos += l      end    end    pos  end  # Given an array or hash, flatten them to a string  def flatten(val, nested = nil)    case val    when Array      return val.map{ |i| flatten(i,1) }.join(" ")    when Hash      return val.keys.map{ |i| nested ||           i =~ /^-/ ? [i, flatten(val[i],1)] :                       [flatten(val[i],1)] }.join(" ")    else      return val    end  end  # Read the next line from stdin  def _get_nextline    $stdin.readline  end  # For each file provided and found, read it in  def _load_sources( _get_nextline, files )    text  = ''    found = []        for i in files      begin        f = File.open(i,"r")      rescue        next      end      if f.tty?        found.push( '<STDIN>' )        _get_nextline = method(:_get_nextline)      else        found.push( i );        t = f.readlines.join(' ')        t.tr!('\t\n',' ')        text += t      end    end    return nil unless found.size > 0    text = $stdin.readline if text.empty?    return [text, found.join(' or ')]  end  # Check parameter description for special options  def _infer(desc, arg, mutex)    while desc.sub!(/\[\s*mutex:\s*(.*?)\]/i,"")      _mutex(mutex, "#$1".split(' '))    end    if desc =~ /\[\s*no\s*case\s*\]/i      if arg        arg.nocase = true      else         nocase = true      end    end    if !arg.nil?      if desc =~ /.*\[\s*excludes:\s*(.*?)\]/i        _exclude(mutex, arg.name, ("#$1".split(' ')))      end      if desc =~ /.*\[\s*requires:\s*(.*?)\s*\]/i        arg.requires = "#$1"      end      arg.required   = ( desc =~ /\[\s*required\s*\]/i )      arg.repeatable = ( desc =~ /\[\s*repeatable\s*\]/i )    end    _typedef(desc) while desc.sub!(/.*?\[\s*pvtype:\s*/,"")  end  # Extract a new type from the description and add it to the list  # of standard types  def _typedef(desc)    se  = DelimScanner::new( desc )    tmp = se.scanQuotelike    name = nil    name, desc = tmp[:delimText], tmp[:suffix]  if tmp    unless name      desc.sub!(/\A\s*([^\] \t\n]+)/,"") and name = "#$1"    end    raise "Error: bad type directive (missing type name): [pvtype: " +      desc[0,desc.index(']')||20] + "....\n" unless name    se  = DelimScanner::new( desc )    tmp = se.scanQuotelike('\s*:?\s*')    # @TODO  What is element 2 of extract_quotelike?  :trail is a fake here    # pat,desc,ind = (extract_quotelike(desc,'\s*:?\s*'))[5,1,2]    pat = ind = nil    pat, desc, ind = tmp[:match], tmp[:suffix], tmp[:prefix] if tmp    pat = pat[1..-2] if pat    unless pat      desc.sub!(/\A\s*(:?)\s*([^\] \t\n]+)/,"") and pat = "#$2" and ind = "#$1"    end    pat = '' unless pat        se  = DelimScanner::new( desc )    action = se.extractCodeblock || ''    desc.sub!( Regexp::quote(action).to_re, '' )    action = action[1..-2]    raise "Error: bad type directive (expected closing ']' but found " +      "'#$1' instead): [pvtype: #{name} " + (pat ? "/#{pat}/" : '') +      " action:#{action} #$1#$2....\n" if desc =~ /\A\s*([^\] \t\n])(\S*)/            Getopt::Declare::ScalarArg::addtype(name,pat,action,ind=~/:/)  end  # Handle quote replacements for [ditto] flag  def _ditto(originalflag, originaldesc, extra)    if originaldesc =~ /\n.*\n/      originaldesc = "Same as #{originalflag} "    else      originaldesc.chomp      originaldesc.gsub!(/\S/,'"')      while originaldesc.gsub!(/"("+)"/,' \1 ')      end      originaldesc.gsub!(/""/,'" ')    end    "#{originaldesc}#{extra}\n"  end  # Check mutex conditions  def _mutex(mref, mutexlist)    for flag in mutexlist      mref[flag] = [] unless mref[flag]      for otherflag in mutexlist        next if flag == otherflag        mref[flag].push( otherflag )      end    end  end  # Check exclude conditions  def _exclude(mref, excluded, mutexlist)    for flag in mutexlist      unless flag == excluded        mref[flag]     = [] unless mref[flag]        mref[excluded] = [] unless mref[excluded]        mref[excluded].push( flag )        mref[flag].push( excluded )      end    end  end  # Returns a regex to match a single argument line  def re_argument    /\A(.*?\S.*?#{@@separator})(.*?\n)/  end  # Returns a regex to keep matching a multi-line description  # for an argument.  def re_more_desc    /\A((?![ \t]*(\{|\n)|.*?\S.*?#{@@separator}.*?\S).*?\S.*\n)/  end  public  # Constructor  def initialize(*opts)    @cache = nil    Getopt::Declare::Arg::clear    # HANDLE SHORT-CIRCUITS    return if opts.size==2 && (!opts[1] || opts[1] == '-SKIP')     grammar, source = opts    if grammar.nil?      raise "Error: No grammar description provided."    end    ### REMOVED PREDEF GRAMMAR AS IT WAS NOT DOCUMENTED NOR     ### WORKING IN PERL'S Declare.pm VERSION.    # PRESERVE ESCAPED '['s    grammar.gsub!(/\\\[/,"\29")    # MAKE SURE GRAMMAR ENDS WITH A NEWLINE.    grammar.sub!(/([^\n])\Z/,'\1'+"\n")    @usage   = grammar.dup    # SET-UP    i = grammar    _args = []    _mutex = {}    _strict = false    _all_repeatable = false    _lastdesc = nil    arg = nil    Getopt::Declare::nocase = false    Getopt::Declare::ScalarArg::_reset_stdtype    # CONSTRUCT GRAMMAR    while i.length > 0      # COMMENT:      i.sub!(/\A[ \t]*#.*\n/,"") and next      # TYPE DIRECTIVE:      se  = DelimScanner::new( i )      if i =~ /\A\s*\[\s*pvtype:/         _action = se.extractBracketed("[")        if _action          i.sub!( Regexp::quote( _action ).to_re, "" )   ### @GGA: added          i.sub!(/\A[ \t]*\n/,"")                        ### @GGA: added          _action.sub!(/.*?\[\s*pvtype:\s*/,"")          _typedef(_action)          next        end # if      end      # ACTION        codeblockDelimiters = {        '{'     => '}',      }      _action = se.extractCodeblock(codeblockDelimiters)      if _action        i.sub!( Regexp::quote(_action ).to_re, "" )        i.sub!(/\A[ \t]*\n/,"")        _action = _action[1..-2]        if !valid_syntax?( _action )          raise "Error: bad action in Getopt::Declare specification:" +            "\n\n#{_action}\n\n\n"        end        if _args.length == 0          raise "Error: unattached action in Getopt::Declare specification:\n#{_action}\n" +                "\t(did you forget the tab after the preceding parameter specification?)\n"        end        _args.last.actions.push( _action )        next      elsif i =~ /\A(\s*[{].*)/        raise "Error: incomplete action in Getopt::Declare specification:\n$1.....\n" +              "\t(did you forget a closing '}'?)\n"      end      # ARG + DESC:      if i.sub!(re_argument,"")        spec = "#$1".strip        desc = "#$2"        _strict ||= desc =~ /\[\s*strict\s*\]/        while i.sub!(re_more_desc,"")          desc += "#$1"        end                ditto = nil        if _lastdesc and desc.sub!(/\A\s*\[\s*ditto\s*\]/,_lastdesc)          ditto = arg        else          _lastdesc = desc        end        # Check for GNU spec line like:  -d, --debug        arg = nil        if spec =~ /(-[\w_\d]+),\s+(--?[\w_\d]+)(\s+.*)?/          specs = ["#$1#$3", "#$2#$3"]          specs.each { |spec|            arg = Arg.new(spec,desc,ditto)            _args.push( arg )            _infer(desc, arg, _mutex)            ditto = arg          }        else          arg = Arg.new(spec,desc,ditto)          _args.push( arg )          _infer(desc, arg, _mutex)        end        next      end      # OTHERWISE: DECORATION      i.sub!(/((?:(?!\[\s*pvtype:).)*)(\n|(?=\[\s*pvtype:))/,"")      decorator = "#$1"      _strict ||= decorator =~ /\[\s*strict\s*\]/      _infer(decorator, nil, _mutex)      _all_repeatable = true if decorator =~ /\[\s*repeatable\s*\]/      @@debug = true if decorator =~ /\[\s*debug\s*\]/    end # while i.length    _lastactions = nil    for i in _args      if _lastactions && i.ditto && i.actions.size == 0        i.actions = _lastactions      else        _lastactions = i.actions      end      if _all_repeatable        i.repeatable = 1      end    end    # Sort flags based on criteria described in docs    # Sadly, this cannot be reduced to sort_by     _args = _args.sort() { |a,b|      cond1 = ( b.flag.size <=> a.flag.size )      cond2 = ( b.flag == a.flag and ( b.args.size <=> a.args.size ) )      cond3 = ( a.id <=> b.id )      cond1 = nil if cond1 == 0      cond2 = nil if cond2 == 0      cond1 or cond2 or cond3    }    # Handle clump    clump = (@usage =~ /\[\s*cluster:\s*none\s*\]/i)     ? 0 :      (@usage =~ /\[\s*cluster:\s*singles?\s*\]/i) ? 1 :      (@usage =~ /\[\s*cluster:\s*flags?\s*\]/i)   ? 2 :      (@usage =~ /\[\s*cluster:\s*any\s*\]/i)      ? 3 :      (@usage =~ /\[\s*cluster:(.*)\s*\]/i)      ? "r" : 3    raise "Error: unknown clustering mode: [cluster:#$1]\n" if clump == "r"    # CONSTRUCT OBJECT ITSELF    @args    = _args    @mutex   = _mutex    @helppat = Arg::helppat()    @verspat = Arg::versionpat()    @strict  = _strict    @clump   = clump    @source  = ''    @tight   = @usage =~ /\[\s*tight\s*\]/i    @caller  = caller()    # VESTIGAL DEBUGGING CODE    if @@debug      f = File.new(".CODE.rb","w") and        f.puts( code() ) and        f.close()     end    # DO THE PARSE (IF APPROPRIATE)    if opts.size == 2      return nil unless parse(source)    else      return nil unless parse()    end  end # initialize  # Parse the parameter description and in some cases,  # optionally eval it, too.  def parse(*opts)    source = opts[0]    _args = nil    _get_nextline = proc { nil }    if source      case source      when Method        _get_nextline = source        _args = _get_nextline.call(self)        source = '[METHOD]'      when Proc        _get_nextline = source        _args = _get_nextline.call(self)        source = '[PROC]'      when IO        if source.fileno > 0 && source.tty?          _get_nextline = method(:_get_nextline)          _args = $stdin.readline          source = '<STDIN>'        else          _args = source.readlines.join(' ')          _args.tr!('\t\n',' ')        end      when :build, :skip        return 0      when Array        if source.length() == 1 && !source[0] ||            source[0] == "-BUILD" ||            source[0] == "-SKIP"          return 0        elsif source.length() == 2 && source[0] == "-ARGV"          if !source[1] or !source[1] === Array            raise 'Error: parse(["-ARGV"]) not passed an array as second parameter.'          end          _args  = source[1].map { |i| i.tr( " \t\n", "\0\0\0" ) }.join(' ')          source = '<ARRAY>'        elsif source.length() == 1 && source[0] == "-STDIN"          _get_nextline = method(:_get_nextline)          _args = $stdin.readline          source = '<STDIN>'        elsif source.length() == 1 && source[0] == '-CONFIG'          progname = "#{$0}rc"          progname.sub!(%r#.*/#,'')          home = ENV['HOME'] || ''          _args, source = _load_sources( _get_nextline,                                        [ home+"/.#{progname}",                                          ".#{progname}" ] )        else          # Bunch of files to load passed to parse()          _args, source = _load_sources( _get_nextline, source )        end      when String  # else/case LITERAL STRING TO PARSE        _args = source.dup        source = source[0,7] + '...' if source && source.length() > 7        source = "\"#{source[0..9]}\""      else        raise "Unknown source type for Getopt::Declare::parse"      end  # case      return 0 unless _args      source = " (in #{source})"    else      _args  = ARGV.map { |i| i.tr( " \t\n", "\0\0\0" ) }.join(' ')      source = ''    end    @source = source    begin      err = eval( code(@caller) )      if $@        # oops, something wrong... exit        puts "#{$!}: #{$@.inspect}"        exit(1)      end      if !err        exit(1)      end    rescue      raise    end    true  end  def type(*t)    Getopt::Declare::ScalarArg::addtype(t)  end  # Print out version information and maybe exit  def version(*t)    prog = "#{$0}"    begin      filedate = File.stat( prog ).mtime.localtime()    rescue      filedate = 'Unknown date'    end    prog.sub!(%r#.*/#,'')    r = ''    if defined?(::Timetrap::VERSION)      r << "\n#{prog}: version #{::Timetrap::VERSION}  (#{filedate})\n\n"    else      r << "\n#{prog}: version dated #{filedate}\n\n"    end    if t.empty?      return r    else      puts r      exit t[0]    end   end  # Print out usage information  def usage(*opt)    t = @usage    lastflag = nil    lastdesc = nil    usage = ''    while !t.empty?      # COMMENT:      t.sub!(/\A[ \t]*#.*\n/,".") and next      # TYPE DIRECTIVE:      se  = DelimScanner::new( t )      if t =~ /\A\s*\[\s*pvtype:/        if action = se.extractBracketed("[")          t.sub!(Regexp::quote( action ).to_re,'')          t.sub!(/\A[ \t]*\n/,"")            next        end      end      # ACTION      codeblockDelimiters = {        '{'     => '}'      }      se  = DelimScanner::new( t )      if action = se.extractCodeblock(codeblockDelimiters)        t.sub!(Regexp::quote( action ).to_re,'')        t.sub!(/\A[ \t]*\n/,"")        decfirst = 0 unless !decfirst.nil?        next      end      # ARG + DESC:      if t.sub!(re_argument,"")        decfirst = 0 unless !decfirst.nil?        spec = "#$1".expand_tabs!()        desc = "#$2".expand_tabs!()        while t.gsub!(re_more_desc, '')          desc += "#$1".expand_tabs!        end        next if desc =~ /\[\s*undocumented\s*\]/i        uoff = 0        spec.gsub!(/(<[a-zA-Z]\w*):([^>]+)>/e) { |i|          uoff += 1 + "#$2".length() and "#$1>"        }        spec.gsub!(/\t/,"=")        ditto = desc =~ /\A\s*\[ditto\]/        desc.gsub!(/^\s*\[.*?\]\s*\n/m,"")        desc.gsub!(BracketDirectives,'')        #desc.gsub!(/\[.*?\]/,"")                if ditto          desc = (lastdesc ? _ditto(lastflag,lastdesc,desc) : "" )        elsif desc =~ /\A\s*\Z/          next        else          lastdesc = desc        end        spec =~ /\A\s*(\S+)/ and lastflag = "#$1"                desc.sub!(/\s+\Z/, "\n")        usage += spec + ' ' * uoff + desc        next      end            # OTHERWISE, DECORATION      if t.sub!(/((?:(?!\[\s*pvtype:).)*)(\n|(?=\[\s*pvtype:))/,"")        desc = "#$1"+("#$2"||'')        #desc.gsub!(/^(\s*\[.*?\])+\s*\n/m,'')        #desc.gsub!(/\[.*?\]/,'')  # eliminates anything in brackets        if @tight || desc !~ /\A\s*\Z/          desc.gsub!(BracketDirectives,'')          next if desc =~ /\A\s*\Z/        end        decfirst = 1 unless !decfirst.nil? or desc =~ /\A\s*\Z/        usage += desc      end    end  #while    required = ''        for arg in @args      required += ' ' + arg.desc + ' '  if arg.required    end          usage.gsub!(Regexp.new("\29"),"[/") # REINSTATE ESCAPED '['s          required.gsub!(/<([a-zA-Z]\w*):[^>]+>/,'<\1>')    required.rstrip!        helpcmd = Getopt::Declare::Arg::besthelp    versioncmd = Getopt::Declare::Arg::bestversion              header = ''    unless @source.nil?      header << version()      prog = "#{$0}"      prog.sub!(%r#.*/#,'')      header <<  "Usage: #{prog} [options]#{required}\n"      header <<  "       #{prog} #{helpcmd}\n" if helpcmd      header <<  "       #{prog} #{versioncmd}\n" if versioncmd      header <<  "\n" unless decfirst && decfirst == 1 && usage =~ /\A[ \t]*\n/    end        header << "Options:\n" unless decfirst && decfirst == 1        usage.sub!(/[\s\n]+\Z/m, '')    pager = $stdout    #begin    #  eval('require "IO/Pager";')    #  pager = IO::Pager.new()    #rescue    #end    if opt.empty?      pager.puts "#{header}#{usage}"      return 0      ### usage    end    #usage.sub!(/\A[\s\n]+/m, '')    pager.puts "#{header}#{usage}"    exit(opt[0]) if opt[0]  end  attr_accessor :unused    # Return list of used parameters (after parsing)  def used    used = @cache.keys    return used.join(' ')  end  @@m = []  # Main method to generate code to be evaluated for parsing.  def code(*t)    package = t[0] || ''    code = %q%@_deferred = []@_errormsg = nil@_finished = nilbegin  begin    undef :defer    undef :reject    undef :finish  rescue  end  def defer(&i)    @_deferred.push( i )  end  def reject(*i)    if !i || i[0]      @_errormsg = i[1] if i[1]      throw :paramout    end  end  def finish(*i)    if i.size      @_finished = i    else      @_finished = true    end  end  @unused = []  @cache  = {}  _FOUND_ = {}  _errors = 0  _invalid = {}  _lastprefix = nil  _pos     = 0   # current position to match from  _nextpos = 0   # next position to match from  catch(:alldone) do     while !@_finished      begin        catch(:arg) do          @_errormsg = nil          # This is used for clustering of flags          while _lastprefix            substr = _args[_nextpos..-1]            substr =~ /^(?!\s|\0|\Z)% +                Getopt::Declare::Arg::negflagpat() + %q%/ or              begin                 _lastprefix=nil                break              end            "#{_lastprefix}#{substr}" =~ /^(% +                Getopt::Declare::Arg::posflagpat() + %q%)/ or              begin                 _lastprefix=nil                break              end            _args = _args[0.._nextpos-1] + _lastprefix + _args[_nextpos..-1]            break          end #  while _lastprefix          % + '' + %q%          _pos = _nextpos if _args          usage(0) if _args && gindex(_args,/\G(% + @helppat + %q%)(\s|\0|\Z)/,_pos)          version(0) if _args && _args =~ /\G(% + @verspat + %q%)(\s|\0|\Z)/      %          for arg in @args            code << arg.code(self,package)          end          code << %q%        if _lastprefix           _pos = _nextpos + _lastprefix.length()           _lastprefix = nil           next        end          _pos = _nextpos          _args && _pos = gindex( _args, /\G[\s|\0]*(\S+)/, _pos ) or throw(:alldone)          if @_errormsg             $stderr.puts( "Error#{source}: #{@_errormsg}\n" )          else             @unused.push( @@m[0] )          end          _errors += 1 if @_errormsg        end  # catch(:arg)      ensure  # begin        _pos = 0 if _pos.nil?        _nextpos = _pos if _args        if _args and _args.index( /\G(\s|\0)*\Z/, _pos )          _args = _get_nextline.call(self) if !@_finished          throw(:alldone) unless _args          _pos = _nextpos = 0          _lastprefix = ''        end   # if      end   # begin/ensure    end   # while @_finished  end   # catch(:alldone)end  # begin%            ################################            # Check for required arguments #            ################################          for arg in @args            next unless arg.required            code << %q%unless _FOUND_['% + arg.name + %q%'] %              if @mutex[arg.name]                for m in @mutex[arg.name]                  code << %q# or _FOUND_['# + m + %q#']#                end              end            code << %q%   $stderr.puts "Error#{@source}: required parameter '% + arg.name + %q%' not found."   _errors += 1end%          end            ########################################            # Check for arguments requiring others #            ########################################          for arg in @args            next unless arg.requires            code << %q%if _FOUND_['% + arg.name + %q%'] && !(% + arg.found_requires +              %q%)   $stderr.puts "Error#{@source}: parameter '% + arg.name + %q%' can only be specified with '% + arg.requires + %q%'"   _errors += 1end            %          end          code << %q%#################### Add unused argumentsif _args && _nextpos > 0 && _args.length() > 0    @unused.replace( @unused + _args[_nextpos..-1].split(' ') )endfor i in @unused    i.tr!( "\0", " " )end%          if @strict            code << %q%#################### Handle strict flagunless _nextpos < ( _args ? _args.length : 0 )  for i in @unused    $stderr.puts "Error#{@source}: unrecognizable argument ('#{i}')"    _errors += 1  endend%          end          code << %q%#################### Print help hintif _errors > 0 && !@source.nil?  $stderr.puts "\n(try '#$0 % + Getopt::Declare::Arg::besthelp + %q%' for more information)"end## cannot just assign unused to ARGV in rubyunless @source != ''  ARGV.clear  @unused.map { |i| ARGV.push(i) }endunless _errors > 0  for i in @_deferred    begin      i.call    rescue => e      STDERR.puts "Action in Getopt::Declare specification produced:\n#{e}"      _errors += 1    end  endend!(_errors>0)  # return true or false (false for errors)%        return code  end  # Inspect cache (not the declare object)  def inspect    return nil if !@cache     t = ''    @cache.each { |a,b|      t << a + " => "      case b      when Hash        t << "{"        i = []        b.each { |c,d|          i.push( " '#{c}' => " + d.inspect )        }        t << i.join(',')        t << " }"      else        t << b.inspect      end      t << "\n"    }    t << "Unused: " + unused.join(', ')  end  # Iterator for Getopt::Declare (travels thru all cache keys)  def each(&t)    @cache.each(&t)  end  # Operator to easily create new value in of Getopt::Declare  def []=(name,val)    @cache = {} unless @cache    @cache[name] = val  end  # Operator to easily return cache of Getopt::Declare  def [](name)    if @cache      return @cache[name]    else      return nil    end  end  # Operator to return number of flags set  def size    return 0 unless @cache    return @cache.keys.size  end  attr :mutex  attr :helppat  attr :verspat  attr :strict  attr :clump  attr :source end # class Declareend # module Getopt
found_requires() click to toggle source
# File lib/Getopt/Declare.rb, line 531
def found_requires
  expr = @requires.gsub(/((?:&&|\|\|)?\s*(?:[!(]\s*)*)([^ \t\n|&\)]+)/,
                        '\1_FOUND_[\\2\]')
  
  if !valid_syntax?( expr )
    raise "Error: bad condition in [requires: #{original}]\n"
  end
  expr
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.