Mercurial > python-cmd2
diff flagReader.py @ 0:febfdc79550b
moved repository to Assembla
author | catherine@DellZilla.myhome.westell.com |
---|---|
date | Wed, 05 Mar 2008 12:16:19 -0500 |
parents | |
children | f807c5cfa0de |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flagReader.py Wed Mar 05 12:16:19 2008 -0500 @@ -0,0 +1,88 @@ +"""Defines and parses UNIX-style flags to modify command arguments. + +print flagReader.FlagSet.parse.__doc__ for usage examples. +""" + +import re + +class Flag(object): + def __init__(self, name, abbrev=None, nargs=0): + """Flag(name, abbrev=None, nargs=0) : Defines a flag. + + name: the full name of the flag (double-dash form) + abbrev: the single-letter abbreviated form of the flag; defaults to + nargs: number of arguments expected after the flag""" + + self.name = name + self.abbrev = abbrev or name[0] + self.fullabbrev = '-%s' % (self.abbrev) + self.fullname = '--%s' % (name) + self.nargs = nargs + +class FlagSet(object): + def __init__(self, flags): + if not issubclass(type(flags), list): + raise TypeError, 'Argument must be a list' + self.flags = flags + self.lookup = {} + for flag in self.flags: + self.lookup[flag.abbrev] = flag + self.lookup[flag.fullabbrev] = flag + self.lookup[flag.fullname] = flag + self.abbrevPattern = re.compile('^-([%s]+)$' % (''.join(f.abbrev for f in flags))) + def parse(self, arg): + """ + Finds flags; returns {flag: (values, if any)} and the remaining argument. + + >>> f = FlagSet([Flag('foo'), Flag('bar'), Flag('gimmea', nargs=1)]) + >>> f.parse('-fb') + ({'foo': [], 'bar': []}, '') + >>> f.parse('no flags') + ({}, 'no flags') + >>> f.parse('-f blah') + ({'foo': []}, 'blah') + >>> f.parse('--bar') + ({'bar': []}, '') + >>> f.parse('--bar -f') + ({'foo': [], 'bar': []}, '') + >>> f.parse('--notaflag') + ({}, '--notaflag') + >>> f.parse('') + ({}, '') + >>> f.parse('--gimmea bee -f and then some other stuff') + ({'gimmea': ['bee'], 'foo': []}, 'and then some other stuff') + >>> f.parse('hidden -bar') + ({}, 'hidden -bar') + >>> f.parse('-g myarg -b') + ({'gimmea': ['myarg'], 'bar': []}, '') + """ + result = {} + words = arg.split() + while words: + word = words[0] + flag = self.lookup.get(word) + if flag: + result[flag.name] = [] + words.pop(0) + for arg in range(flag.nargs): + try: + result[flag.name].append(words.pop(0)) + except IndexError: # there aren't as many args as we expect + raise IndexError, '%s expects %d arguments' % (word, flag.nargs) + continue # on to next word + smashedAbbrevs = self.abbrevPattern.search(word) + if smashedAbbrevs: + for abbrev in smashedAbbrevs.group(1): + result[self.lookup[abbrev].name] = [] + words.pop(0) + continue # on to next word + #if you get to here, word[0] does not denote options + break + return result, ' '.join(words) + +def _test(): + import doctest + doctest.testmod() + +if __name__ == '__main__': + _test() \ No newline at end of file