class Como::Opt

Opt includes all options spec information and parsed options and their values. Option instance is accessed with “Opt”. The option status (Opt instance) can be queried with for example “given” and “value” methods.

Attributes

config[R]

Opt configuration.

doc[RW]

Option documentation string.

given[W]

Is option specified?

longOpt[RW]

Long option string.

name[RW]

Option name.

parent[RW]

Subcommand parent (i.e. host).

rules[R]

Opt rules.

shortOpt[RW]

Short option string.

subcmd[R]

List of subcommands.

subopt[R]

List of suboptions.

type[RW]

Option type as array of primitives (or :subcmd).

value[RW]

Option value.

Public Class Methods

[](str) click to toggle source

Select option object by name. Main is searched first and then the flattened list of all options.

# File lib/como.rb, line 1062
def Opt.[](str)

    # Search Main first.
    ret = Opt.main.argByName( str )

    unless ret
        ret = Opt.findOpt( str )
        unless ret
            raise RuntimeError, "Option \"#{str}\" does not exist..."
        end
    end

    ret
end
addOpt( opt ) click to toggle source

Add option to options list.

# File lib/como.rb, line 1026
def Opt.addOpt( opt )
    @@opts.push opt
end
author() click to toggle source

Return author.

# File lib/como.rb, line 1091
def Opt.author
    @@main.author
end
configGet() click to toggle source

Return default config for Como options.

# File lib/como.rb, line 1144
def Opt.configGet
    @@config
end
configOverlay( config ) click to toggle source

Overlay Opt default configuration options.

# File lib/como.rb, line 1138
def Opt.configOverlay( config )
    @@config.merge!( config )
end
configSet( config ) click to toggle source

Set default config for Como options. User can manipulate the defaults with “preHook”.

# File lib/como.rb, line 1151
def Opt.configSet( config )
    @@config = config
end
current() click to toggle source

Current subcmd processed.

# File lib/como.rb, line 1038
def Opt.current
    @@subcmd
end
default() click to toggle source

Return arguments (options) that have no switch.

# File lib/como.rb, line 1104
def Opt.default
    Opt.main.default
end
defaultOpt( doc = "No doc." ) click to toggle source

Create default option spec, no switch.

# File lib/como.rb, line 1120
def Opt.defaultOpt( doc = "No doc." )
    new( "<default>", "<default>", [ :default, :none, :one, :many, :opt ], doc, [] )
end
each( &blk ) click to toggle source

Options iterator for all options.

# File lib/como.rb, line 1126
def Opt.each( &blk )
    Opt.main.each( &blk )
end
each_given( &blk ) click to toggle source

Options iterator for given options.

# File lib/como.rb, line 1132
def Opt.each_given( &blk )
    Opt.main.each_given( &blk )
end
error( str, nl = false ) click to toggle source

Issue non-fatal user error. See {#error}.

# File lib/como.rb, line 1157
def Opt.error( str, nl = false )
    Opt.main.error( str, nl )
end
external() click to toggle source

Return arguments (options) that are specified as command external (i.e. after '–').

# File lib/como.rb, line 1098
def Opt.external
    Opt.main.external
end
fatal( str ) click to toggle source

Issue fatal user error. See {#fatal}.

# File lib/como.rb, line 1163
def Opt.fatal( str )
    Opt.main.fatal( str )
end
findOpt( name ) click to toggle source

Find option by name.

# File lib/como.rb, line 1044
def Opt.findOpt( name )
    idx = @@opts.index do |i| i.name == name end
    if idx
        @@opts[ idx ]
    else
        nil
    end
end
full( name, opt, type, doc = "No doc." ) click to toggle source

Create option spec.

# File lib/como.rb, line 1110
def Opt.full( name, opt, type, doc = "No doc." )
    new( name, opt, type, doc )
end
main() click to toggle source

Get main option.

# File lib/como.rb, line 1020
def Opt.main
    @@main
end
new( name, opt, type, doc, value = nil ) click to toggle source

Create Opt object. @param name [String] Option name. @param opt [String] Switch. @param type [Array<Symbol>, Symbol] Option type in

primitives (or :subcmd).

@param doc [String] Option documentation. @param value [Object] Default value.

# File lib/como.rb, line 1223
def initialize( name, opt, type, doc, value = nil )
    @parent = nil
    @name = name
    @shortOpt = opt
    @longOpt = "--#{name}"
    @type = type

    @value = value

    if @type != :subcmd
        if prim?( :many ) && value == nil
            @value = []
        end
    end

    @doc = doc
    # Whether option was set or not.
    @given = false
    @subopt = []
    @subcmd = []
    @rules = nil

    @config = @@config.dup

    Opt.addOpt( self )
end
progname() click to toggle source

Return program name.

# File lib/como.rb, line 1079
def Opt.progname
    @@main.name
end
reset() click to toggle source

Reset “dynamic” class members.

# File lib/como.rb, line 1055
def Opt.reset
    @@opts = []
end
setMain( main ) click to toggle source

Set main option.

# File lib/como.rb, line 1014
def Opt.setMain( main )
    @@main = main
    Opt.setSubcmd( main )
end
setSubcmd( opt ) click to toggle source

Set current subcmd.

# File lib/como.rb, line 1032
def Opt.setSubcmd( opt )
    @@subcmd = opt
end
subcmd( name, doc = "No doc." ) click to toggle source

Create sub-command option spec.

# File lib/como.rb, line 1115
def Opt.subcmd( name, doc = "No doc." )
    new( name, nil, :subcmd, doc, false )
end
warn( str, nl = false ) click to toggle source

Issue user warning. See {#warn}.

# File lib/como.rb, line 1169
def Opt.warn( str, nl = false )
    Opt.main.warn( str, nl )
end
year() click to toggle source

Return program year.

# File lib/como.rb, line 1085
def Opt.year
    @@main.year
end

Public Instance Methods

[]( str ) click to toggle source

Select option object by name operator.

# File lib/como.rb, line 1591
def []( str )
    ret = argByName( str )
    unless ret
        raise RuntimeError, "Subopt \"#{str}\" does not exist for \"#{@name}\"!"
    end
    ret
end
addOption( opt ) click to toggle source

Add subcommand option.

@param opt [Option] Option to add.

# File lib/como.rb, line 1268
def addOption( opt )
    opt.parent = self
    @subopt.push opt
end
addSubcmd( cmd ) click to toggle source

Add subcommand subcmd.

@param cmd [Option] Subcmd to add.

# File lib/como.rb, line 1277
def addSubcmd( cmd )
    cmd.parent = self
    @subcmd.push cmd
end
apply( default = nil ) click to toggle source

Return option value if given otherwise the default. Example usage: fileName = Opt.apply( “no_name.txt” )

# File lib/como.rb, line 1646
def apply( default = nil )
    if given
        if prim?( :none ) && !( prim?( :one ) || prim?( :many ) )
            true
        else
            value
        end
    else
        default
    end
end
applyConfig( config ) click to toggle source

Merge config to base config.

@param config [Hash] Configuration Hash to merge.

# File lib/como.rb, line 1286
def applyConfig( config )
    @config.merge!( config )
end
argById( str ) click to toggle source

Select option object by name/opt/longOpt.

# File lib/como.rb, line 1737
def argById( str )
    if str == nil || str == :default
        @subopt.each do |o|
            if o.prim?( :default )
                return o
            end
        end
        nil
    else
        suball.each do |o|
            if str == o.name || str == o.opt || str == o.longOpt
                return o
            end
        end
        nil
    end
end
argByName( str ) click to toggle source

Select option object by name.

# File lib/como.rb, line 1717
def argByName( str )
    if str == nil || str == :default
        @subopt.each do |o|
            if o.prim?( :default )
                return o
            end
        end
        nil
    else
        suball.each do |o|
            if str == o.name
                return o
            end
        end
        nil
    end
end
check( argsState ) click to toggle source

Check provided args.

# File lib/como.rb, line 1303
def check( argsState )

    # Start at top.
    top = self

    parse = Proc.new do
        # Parse and check for invalid arguments.
        begin
            top = top.parse( argsState, top.config[ :check_invalid ] )
        end while( top )

        # Check for any missing valid arguments.
        checkMissing
    end

    error = Proc.new do |err|
        errornl( err.to_s )

        # Display subcmd specific usage info.
        err.data.usage

        exit( 1 )
    end

    begin
        parse.call
    rescue Opt::MissingArgument, Opt::InvalidOption => err
        error.call( err )
    end

    # Revert back to top after hierarchy travelsal.
    usageIfHelp

    # Check rules.
    cur = self
    while cur
        cur.checkRule
        cur = cur.givenSubcmd
    end

    self
end
checkAlso( opt, error, &check ) click to toggle source

Additional option check.

@param opt [String] Option name. @param error [String] Error string for false return values (from check). @param check [Proc] Checker proc run for the option. Either @return false or generate an exception when errors found.

# File lib/como.rb, line 1571
def checkAlso( opt, error, &check )
    begin
        if self[opt].evalCheck( &check ) != true
            raise Opt::InvalidOption.new( error, self )
        end
    rescue Opt::MissingArgument, Opt::InvalidOption => err
        @@io.puts
        errornl( err.to_s )
        err.data.usage
        exit( 1 )
    end
end
checkMissing() click to toggle source

Check for any non-given required arguments recursively through hierarchy of subcommands. MissingArgument Exception is generated if argument is missing.

# File lib/como.rb, line 1491
def checkMissing

    return unless config[ :check_missing ]

    # Full cmd name.
    cmd = ( getParents.map do |i| i.name end ).join( ' ' )

    # Check for any exclusive args first.
    @subopt.each do |o|
        if o.prim?( :mutex ) && o.given
            return
        end
    end


    # Check for required arguments for this level before
    # subcmds.
    @subopt.each do |o|
        if !o.prim?( :opt )
            unless o.given
                raise MissingArgument.new(
                    "Option \"#{o.opt}\" missing for \"#{cmd}\"...",
                    self )
            end
        end
    end

    if hasSubcmd
        if @config[ :subcheck ]
            # Compulsory Subcommand checking enabled.
            subcmdMissing = true
        else
            subcmdMissing = false
        end
    else
        subcmdMissing = false
    end

    # Check for any subcmd args.
    sub = givenSubcmd
    if sub
        subcmdMissing = false
        # Use recursion to examine the next level.
        return sub.checkMissing
    end

    # If no subcmds are given, issue error.
    raise MissingArgument.new(
        "Subcommand required for \"#{cmd}\"...",
        self ) if subcmdMissing

end
checkRule() click to toggle source

Check option combination rules.

# File lib/como.rb, line 1547
def checkRule

    return unless @rules

    begin
        raise Opt::InvalidOption.new( "Option combination mismatch!", self ) unless
            RuleCheck.check( self, &@rules )

    rescue Opt::MissingArgument, Opt::InvalidOption => err
        @@io.puts
        errornl( err.to_s )

        usage( nil, true )

    end
end
cmdline() click to toggle source

Return cmdline usage strings for options in an Array.

# File lib/como.rb, line 1857
def cmdline
    opts = []

    @subopt.each do |o|

        next if o.prim?( :hidden )

        prural = nil
        if o.prim?( :none ) && o.prim?( :many )
            prural = "*"
        elsif o.prim?( :one ) && !o.prim?( :many ) && o.prim?( :repeat )
            prural = "#"
        elsif o.prim?( :one ) && o.prim?( :many )
            prural = "+"
        else
            prural = ""
        end

        if !( o.hasSwitchStyleDoc )
            name = " <#{o.name}>#{prural}"
        else
            name = ""
        end

        if o.shortOpt == nil
            opt = o.longOpt
        else
            opt = o.shortOpt
        end

        if !o.prim?( :opt )
            opts.push "#{opt}#{name}"
        else
            opts.push "[#{opt}#{name}]"
        end
    end


    if hasSubcmd
        opts.push "<<subcommand>>"
    end

    opts

end
default() click to toggle source

Return default options.

# File lib/como.rb, line 1711
def default
    argByName( nil )
end
each( ) { |o| ... } click to toggle source

Options list iterator.

# File lib/como.rb, line 1613
def each( &blk )
    suball.each do |o|
        yield o
    end
end
each_given( ) { |o| ... } click to toggle source

Options iterator for given options.

# File lib/como.rb, line 1621
def each_given( &blk )
    suball.each do |o|
        yield o if o.given
    end
end
error( str, nl = false ) click to toggle source

Como error printout.

@param str [String] Error message. @param nl [Boolean] Prepend msg with newline.

# File lib/como.rb, line 1983
def error( str, nl = false )
    nl = nl ? "\n" : ""
    STDERR.puts( "#{nl}#{Opt.progname} error: #{str}" )
end
errornl( str ) click to toggle source

Como error printout with pre-newline.

# File lib/como.rb, line 1990
def errornl( str )
    error( str, true )
end
evalCheck( &check ) click to toggle source

Custom check for the option. User has to know some Como internals.

# File lib/como.rb, line 2014
def evalCheck( &check )
    instance_eval( &check )
end
fatal( str ) click to toggle source

Como error printout with immediate exit.

# File lib/como.rb, line 1996
def fatal( str )
    error( str )
    exit( false )
end
findOpt( str ) click to toggle source

Find option object by option str.

# File lib/como.rb, line 1930
def findOpt( str )
    if str == nil
        subopt.detect { |i| i.prim?( :default ) }
    elsif str[0..1] == "--"
        subopt.detect { |i| i.longOpt == str }
    elsif str[0..0] == "-"
        subopt.detect { |i| i.opt == str }
    else
        suball.detect { |i| i.name == str }
    end
end
given( optArg = false ) { |self| ... } click to toggle source

Returns true if option is given, and block is not present. When block is present, the block is executed (with value as parameter) if option has been given.

@param optArg [Boolean] Pass Opt to block instead of its

value.
# File lib/como.rb, line 1665
def given( optArg = false, &prog )
    if block_given?
        if @given
            if optArg
                yield( self )
            else
                yield( @value )
            end
        else
            false
        end
    else
        @given
    end
end
Also aliased as: given?
given?( optArg = false, &prog )

Alias for given.

Alias for: given
givenCount() click to toggle source

Number of given options.

# File lib/como.rb, line 1629
def givenCount
    cnt = 0
    each_given do |i|
        cnt += 1
    end
    cnt
end
givenSubcmd() click to toggle source

Return the selected subcommand.

# File lib/como.rb, line 1687
def givenSubcmd
    ( @subcmd.select do |o| o.given end )[0]
end
hasSwitchStyleDoc() click to toggle source

Test if option is of switch type.

# File lib/como.rb, line 1763
def hasSwitchStyleDoc
    if ( prim?( :none ) && !prim?( :many ) ) ||
       prim?( :default )
        true
    else
        false
    end
end
opt() click to toggle source

Option's opt id. Short if exists otherwise long.

# File lib/como.rb, line 1601
def opt
    @shortOpt ? @shortOpt : @longOpt
end
params() click to toggle source

Returns Hash of option value parameters. Example command line content:

-p rounds=10 length=5

Option value content in this case would be (Array of param settings):

[ "rounds=10", "length=5" ]

@return [Hash] Parameter settings included in the option.

# File lib/como.rb, line 1699
def params
    map = {}
    @value.each do |i|
        name, value = i.split('=')
        value = str_to_num( value )
        map[ name ] = value
    end
    map
end
parse( args, checkInvalids = true ) click to toggle source

Parse cmdline options from args.

# File lib/como.rb, line 1349
def parse( args, checkInvalids = true )

    while args.get

        # puts "Opt.parse (#{@name}): #{args.get}"

        if args.isOptTerm

            # Rest of the args do not belong to this program.
            args.next
            Opt.main.external = args.rest
            break

        elsif args.isOpt

            o = findOpt( args.get )

            if !o
                if checkInvalids
                    raise \
                    InvalidOption.new( "Unknown option \"#{args.get}\"...",
                        self )
                else
                    o = findOpt( nil )
                    if !o
                        raise \
                        InvalidOption.new(
                            "No default option specified to allow \"#{args.get}\"...",
                           self )
                    else
                        # Default option.
                        o.value.push args.toValue
                        args.next
                    end
                end

            elsif o && ( o.prim?( :one ) || o.prim?( :many ) )

                args.next

                if ( !args.get || args.isOpt ) &&
                   !o.prim?( :none )

                    raise MissingArgument.new(
                        "No argument given for \"#{o.opt}\"...",
                        self )

                else

                    if o.given && !o.prim?( :repeat )
                        raise \
                        InvalidOption.new(
                            "Option specified too multiple times (\"#{o.name}\")...",
                            self )
                    end

                    if o.prim?( :many )

                        # Get all argument for multi-option.
                        o.value = [] if !o.given
                        while args.get && !args.isOpt
                            o.value.push args.toValue
                            args.next
                        end

                    else

                        # Get one argument for single-option.

                        if o.prim?( :repeat )
                            o.value = [] if !o.given
                            o.value.push args.toValue
                        else
                            o.value = args.toValue
                        end

                        args.next
                    end
                end

                o.given = true

            else

                if !o
                    raise InvalidOption.new( "No valid options specified...",
                        self )
                else
                    o.given = true
                    args.next
                end
            end

        else

            # Subcmd or default. Check for Subcmd first.

            # Search for Subcmd.
            o = findOpt( args.get )

            if !o

                # Search for default option.
                o = findOpt( nil )
                if !o
                    if @subcmd.any?
                        raise \
                            InvalidOption.new(
                            "Unknown subcmd: \"#{args.get}\"...",
                            self )
                    else
                        raise \
                            InvalidOption.new(
                            "No default option specified to allow \"#{args.get}\"...",
                            self )
                    end
                else
                    # Default option.
                    o.given = true
                    o.value.push args.toValue
                    args.next
                end

            else

                # Subcmd.
                o.given = true
                args.next
                return o

            end

        end
    end

    nil
end
prim?( prim ) click to toggle source

Check for primitive.

# File lib/como.rb, line 1757
def prim?( prim )
    @type.index( prim )
end
setOptionSubcmd( opts, subs ) click to toggle source

Set command (subcommand) suboptions and subcmds.

@param opts [Array<Opt>]

# File lib/como.rb, line 1254
def setOptionSubcmd( opts, subs )
    opts.each do |i|
        addOption( i )
    end

    subs.each do |i|
        addSubcmd( i )
    end
end
setRuleCheck( &rule ) click to toggle source

Set rule checks for the option.

@param rule [Proc] Rule to check after command line parsing.

# File lib/como.rb, line 1294
def setRuleCheck( &rule )
    @rules = rule
end
setUsageFooter( str ) click to toggle source

Set optional footer for “usage”.

# File lib/como.rb, line 1783
def setUsageFooter( str )
    @config[ :footer ] = str
end
setUsageHeader( str ) click to toggle source

Set optional header for “usage”.

# File lib/como.rb, line 1777
def setUsageHeader( str )
    @config[ :header ] = str
end
suball() click to toggle source

All subcommand options, options and subcommands.

# File lib/como.rb, line 1607
def suball
    @subopt + @subcmd
end
suboptDoc() click to toggle source

Return document strings for options.

# File lib/como.rb, line 1905
def suboptDoc

    str = ""
    # format = Proc.new do |s,d| ( "  %-#{@config[ :tab ]}s%s\n" % [ s, d ] ) end

    str += "\n"

    str += "  Options:\n" if hasSubcmd && hasVisibleOptions

    @subopt.each do |o|
        next if o.prim?( :hidden )
        str += suboptDocFormat( o.opt, o.doc )
    end

    str += "\n" + suboptDocFormat( "Subcommands:", "" ) if hasSubcmd

    @subcmd.each do |o|
        str += suboptDocFormat( o.name, o.doc )
    end

    str
end
to_hash() click to toggle source

Convert to hash representation.

Keys are symbols: name, type, given, value, subopt, subcmd.

# File lib/como.rb, line 1946
def to_hash
    h = {}
    h[ :name ] = @name
    h[ :type ] = @type
    h[ :given ] = @given
    h[ :value ] = @value
    h[ :subopt ] = @subopt.map{|i| i.to_hash }
    h[ :subcmd ] = @subcmd.map{|i| i.to_hash }
    h
end
to_hopt() click to toggle source

Convert to hash representation with opt name keys.

Keys are symbols: name, type, given, value, subopt, subcmd.

# File lib/como.rb, line 1961
def to_hopt
    h = {}
    h[ :name ] = @name
    h[ :type ] = @type
    h[ :given ] = @given
    h[ :value ] = @value
    h[ :subopt ] = {}
    @subopt.each do |i|
        h[ :subopt ][ i.name ] = i.to_hopt
    end
    h[ :subcmd ] = {}
    @subcmd.each do |i|
        h[ :subcmd ][ i.name ] = i.to_hopt
    end
    h
end
usage( doExit = nil, ruleHelp = nil ) click to toggle source

Display program usage (and optionally exit).

@param doExit [Boolean] Exit program after help

display. Default to help_exit config
if nil.

@param ruleHelp [Boolean] Include rule help to help

display. Default to rulehelp config
if nil.
# File lib/como.rb, line 1796
def usage( doExit = nil, ruleHelp = nil )

    doExit = @config[ :help_exit ] if doExit == nil
    ruleHelp = @config[ :rulehelp ] if ruleHelp == nil

    @@io.puts usageNormal

    if ruleHelp
        @@io.puts "\n  Option Combinations:"
        @@io.puts RuleDisplay.print( &@rules )
    end

    exit( 1 ) if doExit
end
usageCommand() click to toggle source

Usage printout for command.

# File lib/como.rb, line 1823
        def usageCommand
            str = ""
            str += "\
  Subcommand \"#{@name}\" usage:
    #{fullCommand} #{cmdline.join(" ")}
"
            str += suboptDoc

            str += "\n"
        end
usageIfHelp() click to toggle source

Display program usage (and optionally exit).

# File lib/como.rb, line 1813
def usageIfHelp
    if self.argByName( 'help' ) && self['help'].given
        usage
    elsif hasSubcmd && givenSubcmd
        givenSubcmd.usageIfHelp
    end
end
usageNormal() click to toggle source

Usage info for Opt:s.

# File lib/como.rb, line 1835
def usageNormal
    str = ""

    if @config[ :header ]
        str += @config[ :header ]
    else
        str += "\n"
    end

    str += usageCommand

    if @config[ :footer ]
        str += @config[ :footer ]
    else
        str += "\n"
    end

    str
end
warn( str, nl = false ) click to toggle source

Como warning printout.

@param str [String] Warning message. @param nl [Boolean] Prepend msg with newline.

# File lib/como.rb, line 2006
def warn( str, nl = false )
    nl = nl ? "\n" : ""
    STDERR.puts( "#{nl}#{Opt.progname} warning: #{str}" )
end
~() click to toggle source

Short syntax for value reference. Example: “~Opt”.

# File lib/como.rb, line 1639
def ~()
    @value
end

Private Instance Methods

fullCommand() click to toggle source

Full command name.

# File lib/como.rb, line 2048
def fullCommand
    ( getParents.map do |i| i.name end ).join( ' ' )
end
getParents() click to toggle source

Return list of parents.

# File lib/como.rb, line 2035
def getParents
    list = []
    cur = self
    begin
        list.push cur
        cur = cur.parent
    end while cur

    list.reverse
end
hasSubcmd() click to toggle source

Test if option is of subcmd type.

# File lib/como.rb, line 2067
def hasSubcmd
    !@subcmd.empty?
end
hasVisibleOptions() click to toggle source

Test if option is of subcmd type.

# File lib/como.rb, line 2060
def hasVisibleOptions
    # Count non-silent options.
    ( @subopt.select do |i| !i.prim?( :hidden ) end ).length > 0
end
isSubcmd() click to toggle source

Test if option is of subcmd type.

# File lib/como.rb, line 2054
def isSubcmd
    @type == :subcmd
end
str_to_num( str ) click to toggle source

Convert string to number if possible. The order of checks: integer, float, and no-conversion.

# File lib/como.rb, line 2027
def str_to_num( str )
    begin return Integer( str ); rescue ; end
    begin return Float( str );   rescue ; end
    str
end
suboptDocFormat( switch, doc ) click to toggle source

Format option documentation. If newline is followed by tab, rest of the documentation is aligned with the description of previous line.

# File lib/como.rb, line 2075
def suboptDocFormat( switch, doc )

    # Format doc nicely to multiple lines if newline is
    # followed by tab stop.

    parts = doc.split( "\n" )
    lines = [ ( "  %-#{@config[ :tab ]}s%s\n" % [ switch, parts[0] ] ) ]

    if parts[1]
        parts[1..-1].each do |p|

            if p[0] == "\t"
                lines.push ( "  #{' '*@config[ :tab ]}%s\n" % [  p[1..-1] ] )
            else
                lines.push p
            end

        end
    end

    lines.join
end