Mercurial > python-cmd2
view flagReader.py @ 3:4520a1a073ff
require terminator for redirection
author | catherine@cordelia |
---|---|
date | Tue, 13 May 2008 08:29:18 -0400 |
parents | febfdc79550b |
children | f807c5cfa0de |
line wrap: on
line source
"""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()