]> arthur.barton.de Git - bup.git/blob - options.py
cmd-index: skip merging the index if nothing was written to the new one.
[bup.git] / options.py
1 import textwrap, getopt, re
2 from helpers import *
3
4 class OptDict:
5     def __init__(self):
6         self._opts = {}
7
8     def __setitem__(self, k, v):
9         self._opts[k] = v
10         
11     def __getitem__(self, k):
12         return self._opts[k]
13
14     def __getattr__(self, k):
15         return self[k]
16
17
18 class Options:
19     def __init__(self, exe, optspec):
20         self.exe = exe
21         self.optspec = optspec
22         self._aliases = {}
23         self._shortopts = 'h?'
24         self._longopts = ['help']
25         self._hasparms = {}
26         self._usagestr = self._gen_usage()
27         
28     def _gen_usage(self):
29         out = []
30         lines = self.optspec.strip().split('\n')
31         lines.reverse()
32         first_syn = True
33         while lines:
34             l = lines.pop()
35             if l == '--': break
36             out.append('%s: %s\n' % (first_syn and 'usage' or '   or', l))
37             first_syn = False
38         out.append('\n')
39         while lines:
40             l = lines.pop()
41             if l.startswith(' '):
42                 out.append('\n%s\n' % l.lstrip())
43             elif l:
44                 (flags, extra) = l.split(' ', 1)
45                 extra = extra.strip()
46                 if flags.endswith('='):
47                     flags = flags[:-1]
48                     has_parm = 1
49                 else:
50                     has_parm = 0
51                 flagl = flags.split(',')
52                 flagl_nice = []
53                 for f in flagl:
54                     f_nice = re.sub(r'\W', '_', f)
55                     self._aliases[f] = flagl[0]
56                     self._aliases[f_nice] = flagl[0]
57                     self._hasparms[f] = has_parm
58                     if len(f) == 1:
59                         self._shortopts += f + (has_parm and ':' or '')
60                         flagl_nice.append('-' + f)
61                     else:
62                         assert(not f.startswith('no-')) # supported implicitly
63                         self._longopts.append(f + (has_parm and '=' or ''))
64                         self._longopts.append('no-' + f)
65                         flagl_nice.append('--' + f)
66                 flags_nice = ', '.join(flagl_nice)
67                 if has_parm:
68                     flags_nice += ' ...'
69                 prefix = '    %-20s  ' % flags_nice
70                 argtext = '\n'.join(textwrap.wrap(extra, width=70,
71                                                 initial_indent=prefix,
72                                                 subsequent_indent=' '*28))
73                 out.append(argtext + '\n')
74             else:
75                 out.append('\n')
76         return ''.join(out)
77     
78     def usage(self):
79         log(self._usagestr)
80         exit(97)
81         
82     def parse(self, args):
83         try:
84             (flags,extra) = getopt.gnu_getopt(args,
85                                               self._shortopts, self._longopts)
86         except getopt.GetoptError, e:
87             log('%s: %s\n' % (self.exe, e))
88             self.usage()
89
90         opt = OptDict()
91         for f in self._aliases.values():
92             opt[f] = None
93         for (k,v) in flags:
94             while k.startswith('-'):
95                 k = k[1:]
96             if k in ['h', '?', 'help']:
97                 self.usage()
98             if k.startswith('no-'):
99                 k = self._aliases[k[3:]]
100                 opt[k] = None
101             else:
102                 k = self._aliases[k]
103                 if not self._hasparms[k]:
104                     assert(v == '')
105                     opt[k] = (opt._opts.get(k) or 0) + 1
106                 else:
107                     opt[k] = v
108         for (f1,f2) in self._aliases.items():
109             opt[f1] = opt[f2]
110         return (opt,flags,extra)