All computer source code presented on this page, unless it includes attribution to another author, is provided by Ed Halley under the Artistic License. Use such code freely and without any expectation of support. I would like to know if you make anything cool with the code, or need questions answered.
python/
    bindings.py
    boards.py
    buzz.py
    cache.py
    cards.py
    constraints.py
    csql.py
    english.py
    getopts.py
    gizmos.py
    goals.py
    improv.py
    interpolations.py
    namespaces.py
    nihongo.py
    nodes.py
    octalplus.py
    patterns.py
    persist.py
    physics.py
    pids.py
    pieces.py
    quizzes.py
    recipes.py
    relays.py
    romaji.py
    ropen.py
    sheets.py
    strokes.py
    subscriptions.py
    svgbuild.py
    testing.py
    things.py
    timing.py
    ucsv.py
    useful.py
    uuid.py
    vectors.py
    weighted.py
java/
    CSVReader.java
    CSVWriter.java
    GlobFilenameFilter.java
    RegexFilenameFilter.java
    StringBufferOutputStream.java
    ThreadSet.java
    Throttle.java
    TracingThread.java
    Utf8ConsoleTest.java
    droid/
        ArrangeViewsTouchListener.java
        DownloadFileTask.java
perl/
    CVQM.pm
    Kana.pm
    Typo.pm
cxx/
    CCache.h
    equalish.cpp
Download getopts.py
# -*- python -*-

'''

An alternative to the standard Python getopt module.

SYNOPSIS

    >>> import getopts ; from getopts import *
    >>> import sys

    >>> options = { 'flag': False,   # -f, --flag, --flag=Yes, -f False
                    'number': 3,     # -n 2, -n=4, --number=6, +nnn, +number
                    'mode': 'fast',  # -m slow, --mode slow, --mode=slow
                    'Names': [],     # -N Mary, --names John,Bill
                  }

    >>> others = getopts(sys.argv, options)

    >>> options['flag']
    True

    >>> options['number']
    4

    >>> options['Names']
    [ 'Mary', 'John', 'Bill' ]

AUTHOR

    Ed Halley (ed@halley.cc) 14 November 2008

SEE ALSO

    The standard Python 'getopt' module, with GNU- and K&R-style options.

'''

import re
import sys

#----------------------------------------------------------------------------

"""An alternative to the standard Python getopt module."""

def boolify(value):
    '''Take a friendly user input value, and turn it into True or False.'''
    try: value = value.lower()
    except: pass
    if value in (True, 1, 'y', 'yes', 'on', 'enable'):
        return True
    if value in (None, False, 0, 'n', 'no', 'off', 'disable'):
        return False
    return True

def getopt(arg, tail, opt, default):
    '''Super-lightweight implementation of one --option=value parsing.
    Supports:
        -o       / --option        (returns True if default is a bool)
        -o=value / --option=value  (returns value in same type as default)
        -o value / --option value  (returns value in same type as default)
        +ooo     / +option         (returns int(default) plus each repeat)
    Lists append comma-separated values.  Integers can be incremented.
    Pops values from tail (usually remainder of argv list) only if required.
    '''
    value = None
    o = opt[0]
    opt = opt.lower()
    match = re.match(r"^(-%s|--%s)$" % (o, opt), arg)
    if match:
        if isinstance(default, (bool, type(None))):
            return True
        if not len(tail):
            raise ValueError, 'Option --%s needs an argument.' % opt
        value = tail.pop(0)
    else:
        match = re.match(r"^(-%s|--%s)=(.*)$" % (o, opt), arg)
        if match:
            value = match.group(2)
        else:
            match = re.match(r"^\+((%s+)|(%s))$" % (o, opt), arg)
            if match:
                try:
                    d = int(default)
                    if match.group(2): value = d+len(match.group(2))
                    if match.group(3): value = d+1
                except:
                    raise ValueError, 'Option --%s cannot be +counted.' % opt
    if value is None:
        return default
    if isinstance(default, (list, tuple)):
        return list(default) + value.split(',')
    if isinstance(default, bool):
        return boolify(value)
    if isinstance(default, int):
        return int(value)
    if isinstance(default, float):
        return float(value)
    return value

def usage(this, options):
    '''Super-lightweight implementation of command-line usage help.
    Does not have anything particularly wordy about the meanings of each
    option and inputfiles.
    '''
    err = sys.stderr
    print >>err, 'Usage: ', this, '<options>', '<inputfiles>'
    print >>err, 'Options and their (default) values:'
    for option in options:
        print >>err, '\t--%-15s\t(%s)' % (option, repr(options[option]))
    sys.exit(1)

def getopts(argv, options):
    '''Super-lightweight implementation of command-line argument parsing.
    Pass an argument list (usually the unmodified sys.argv), and a dict
    of default values, like:
        options = { 'flag': False,   # -f, --flag, --flag=Yes, -f False
                    'number': 3,     # -n 2, -n=4, --number=6, +nnn, +number
                    'mode': 'fast',  # -m slow, --mode slow, --mode=slow
                    'Names': [],     # -N Mary, --names John,Bill
                    }
    Assumes initial letters are unique and --options are lowercase.
    (Especially note the -n/--number and -N/--names examples above.)
    Does no fancy unique-prefix magic to determine useful abbreviations.
    Subsequent values overwrite earlier values, or are appended for lists.
    
    Non-options can be interspersed with options.  Anything after a lone
    '--' are non-option arguments.  Returns list of all non-option
    arguments in the order they were found.  Aborts with a usage
    statement on standard error output, and an error return code, if
    given an invalid option value.
    '''
    this = argv.pop(0)
    original = options.copy()
    while argv:
        arg = argv.pop(0)
        if arg == '--':
            break
        if arg in ('-h', '-?', '--help'):
            usage(this, original)
        elif len(arg) > 1 and arg[0] in ('-','+'):
            for opt in options:
                try:
                    options[opt] = getopt(arg, sys.argv, opt, options[opt])
                except ValueError, ex:
                    print >>sys.stderr, ex.message
                    usage(this, original)
        else:
            argv.insert(0, arg)
            break
    return argv[:]

#----------------------------------------------------------------------------

if __name__ == '__main__':
    import sys

    options = { 'flag': False,   # -f, --flag, --flag=Yes, -f False
                'number': 3,     # -n 2, -n=4, --number=6, +nnn, +number
                'mode': 'fast',  # -m slow, --mode slow, --mode=slow
                'Names': [],     # -N Mary, --names John,Bill
                }

    print 'Arguments: %r' % sys.argv

    others = getopts(sys.argv, options)

    print 'Options: %r' % options
    print 'Others:  %r' % others


Contact Ed Halley by email at ed@halley.cc.
Text, code, layout and artwork are Copyright © 1996-2013 Ed Halley.
Copying in whole or in part, with author attribution, is expressly allowed.
Any references to trademarks are illustrative and are controlled by their respective owners.
Make donations with PayPal - it's fast, free and secure!