1 import sys, textwrap, getopt, re
7 def __setitem__(self, k, v):
10 def __getitem__(self, k):
13 def __getattr__(self, k):
17 def _default_onabort(msg):
32 def __init__(self, exe, optspec, optfunc=getopt.gnu_getopt,
33 onabort=_default_onabort):
35 self.optspec = optspec
36 self._onabort = onabort
37 self.optfunc = optfunc
39 self._shortopts = 'h?'
40 self._longopts = ['help']
43 self._usagestr = self._gen_usage()
47 lines = self.optspec.strip().split('\n')
53 out.append('%s: %s\n' % (first_syn and 'usage' or ' or', l))
59 out.append('\n%s\n' % l.lstrip())
61 (flags, extra) = l.split(' ', 1)
63 if flags.endswith('='):
68 g = re.search(r'\[([^\]]*)\]', extra)
73 flagl = flags.split(',')
76 self._aliases[f] = flagl[0]
77 self._hasparms[f] = has_parm
78 self._defaults[f] = _intify(defval)
80 self._shortopts += f + (has_parm and ':' or '')
81 flagl_nice.append('-' + f)
83 f_nice = re.sub(r'\W', '_', f)
84 self._aliases[f_nice] = flagl[0]
85 assert(not f.startswith('no-')) # supported implicitly
86 self._longopts.append(f + (has_parm and '=' or ''))
87 self._longopts.append('no-' + f)
88 flagl_nice.append('--' + f)
89 flags_nice = ', '.join(flagl_nice)
92 prefix = ' %-20s ' % flags_nice
93 argtext = '\n'.join(textwrap.wrap(extra, width=70,
94 initial_indent=prefix,
95 subsequent_indent=' '*28))
96 out.append(argtext + '\n')
99 return ''.join(out).rstrip() + '\n'
101 def usage(self, msg=""):
102 sys.stderr.write(self._usagestr)
103 e = self._onabort and self._onabort(msg) or None
108 msg = 'error: %s\n' % s
109 sys.stderr.write(msg)
110 return self.usage(msg)
112 def parse(self, args):
114 (flags,extra) = self.optfunc(args, self._shortopts, self._longopts)
115 except getopt.GetoptError, e:
120 for k,v in self._defaults.iteritems():
126 if k in ('h', '?', 'help'):
128 if k.startswith('no-'):
129 k = self._aliases[k[3:]]
133 if not self._hasparms[k]:
135 v = (opt._opts.get(k) or 0) + 1
139 for (f1,f2) in self._aliases.iteritems():
140 opt[f1] = opt._opts.get(f2)
141 return (opt,flags,extra)