]> arthur.barton.de Git - bup.git/blob - options.py
Use binary sha1 instead of hex sha1 whenever possible.
[bup.git] / options.py
1 import textwrap, getopt
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                     self._aliases[f] = flagl[0]
55                     self._hasparms[f] = has_parm
56                     if len(f) == 1:
57                         self._shortopts += f + (has_parm and ':' or '')
58                         flagl_nice.append('-' + f)
59                     else:
60                         assert(not f.startswith('no-')) # supported implicitly
61                         self._longopts.append(f + (has_parm and '=' or ''))
62                         self._longopts.append('no-' + f)
63                         flagl_nice.append('--' + f)
64                 flags_nice = ', '.join(flagl_nice)
65                 if has_parm:
66                     flags_nice += ' ...'
67                 prefix = '    %-20s  ' % flags_nice
68                 argtext = '\n'.join(textwrap.wrap(extra, width=70,
69                                                 initial_indent=prefix,
70                                                 subsequent_indent=' '*28))
71                 out.append(argtext + '\n')
72             else:
73                 out.append('\n')
74         return ''.join(out)
75     
76     def usage(self):
77         log(self._usagestr)
78         exit(97)
79         
80     def parse(self, args):
81         try:
82             (flags,extra) = getopt.gnu_getopt(args,
83                                               self._shortopts, self._longopts)
84         except getopt.GetoptError, e:
85             log('%s: %s\n' % (self.exe, e))
86             self.usage()
87
88         opt = OptDict()
89         for f in self._aliases.values():
90             opt[f] = None
91         for (k,v) in flags:
92             while k.startswith('-'):
93                 k = k[1:]
94             if k in ['h', '?', 'help']:
95                 self.usage()
96             if k.startswith('no-'):
97                 k = self._aliases[k[3:]]
98                 opt[k] = None
99             else:
100                 k = self._aliases[k]
101                 if not self._hasparms[k]:
102                     assert(v == '')
103                     opt[k] = (opt._opts.get(k) or 0) + 1
104                 else:
105                     opt[k] = v
106         for (f1,f2) in self._aliases.items():
107             opt[f1] = opt[f2]
108         return (opt,flags,extra)