Whamcloud - gitweb
land v0.9.1 on HEAD, in preparation for a 1.0.x branch
[fs/lustre-release.git] / lustre / utils / Lustre / cmdline.py
1 #!/usr/bin/env python
2 #
3 #  Copyright (C) 2002 Cluster File Systems, Inc.
4 #   Author: Robert Read <rread@clusterfs.com>
5 #   This file is part of Lustre, http://www.lustre.org.
6 #
7 #   Lustre is free software; you can redistribute it and/or
8 #   modify it under the terms of version 2 of the GNU General Public
9 #   License as published by the Free Software Foundation.
10 #
11 #   Lustre is distributed in the hope that it will be useful,
12 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
13 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 #   GNU General Public License for more details.
15 #
16 #   You should have received a copy of the GNU General Public License
17 #   along with Lustre; if not, write to the Free Software
18 #   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 #
20
21 # Standard the comand line handling for all the python tools.
22
23 import sys, getopt, types
24 import string
25 import error
26
27 class Options:
28     FLAG = 1
29     PARAM = 2
30     INTPARAM = 3
31     PARAMLIST = 4
32     def __init__(self, cmd, remain_help, options):
33         self.options = options
34         shorts = ""
35         longs = []
36         options.append(('help,h', "Print this help")) 
37         for opt in options:
38             long = self.long(opt)
39             short = self.short(opt)
40             if self.type(opt) in (Options.PARAM, Options.INTPARAM,
41                                   Options.PARAMLIST):
42                 if short: short = short + ':'
43                 if long:
44                     long = long + '='
45             if string.find(long, '_') >= 0:
46                 longs.append(string.replace(long, '_', '-'))
47             shorts = shorts + short
48             longs.append(long)
49         self.short_opts = shorts
50         self.long_opts = longs
51         self.cmd = cmd
52         self.remain_help = remain_help
53
54     def init_values(self):
55         values = {}
56         for opt in self.options:
57             values[self.key(opt)] = self.default(opt)
58         return values
59
60     def long(self, option):
61         n = string.find(option[0], ',')
62         if n < 0: return option[0]
63         else:     return option[0][0:n]
64
65     def key(self, option):
66         key = self.long(option)
67         return string.replace(key, '-', '_')
68         
69     def short(self, option):
70         n = string.find(option[0], ',')
71         if n < 0: return ''
72         else:     return option[0][n+1:]
73
74     def help(self, option):
75         return option[1]
76     
77     def type(self, option):
78         if len(option) >= 3:
79             return option[2]
80         return Options.FLAG
81     
82     def default(self, option):
83         if len(option) >= 4:
84             return option[3]
85         if self.type(option) == Options.PARAMLIST:
86             return []
87         return None
88
89     def lookup_option(self, key, key_func):
90         for opt in self.options:
91             if key_func(opt) == key:
92                 return opt
93
94     def lookup_short(self, key):
95         return self.lookup_option(key, self.short)
96
97     def lookup_long(self, key):
98         key = string.replace(key, '-', '_')
99         return self.lookup_option(key, self.long)
100
101     def handle_opts(self, opts):
102         values = self.init_values()
103         for o, a in opts:
104             if o[0:2] != '--':
105                 option = self.lookup_short(o[1:])
106             else:
107                 option = self.lookup_long(o[2:])
108             if self.type(option) == Options.PARAM:
109                 val = a
110             elif self.type(option) == Options.INTPARAM:
111                 try: 
112                     val = int(a)
113                 except ValueError, e:
114                     raise error.OptionError("option: '%s' expects integer value, got '%s' "  % (o,a))
115             elif self.type(option) == Options.PARAMLIST:
116                 val = values[self.key(option)];
117                 val.append(a)
118             else:
119                 val = 1
120             values[self.key(option)] = val
121         return values
122                 
123         
124     class option_wrapper:
125         def __init__(self, values):
126             self.__dict__['values'] = values
127         def __getattr__(self, name):
128             if self.values.has_key(name):
129                 return self.values[name]
130             else:
131                 raise error.OptionError("bad option name: " + name)
132         def __getitem__(self, name):
133             if self.values.has_key(name):
134                 return self.values[name]
135             else:
136                 raise error.OptionError("bad option name: " + name)
137         def __setattr__(self, name, value):
138             self.values[name] = value
139
140     def parse(self, argv):
141         try:
142             opts, args = getopt.getopt(argv, self.short_opts, self.long_opts)
143             values = self.handle_opts(opts)
144             if values["help"]:
145                 self.usage()
146                 sys.exit(0)
147             return self.option_wrapper(values), args
148         except getopt.error, e:
149             raise error.OptionError(str(e))
150
151     def usage(self):
152         ret = 'usage: %s [options] %s\n' % (self.cmd, self.remain_help)
153         for opt in self.options:
154             s = self.short(opt)
155             if s: str = "-%s|--%s" % (s,self.long(opt))
156             else: str = "--%s" % (self.long(opt),)
157             if self.type(opt) in (Options.PARAM, Options.INTPARAM):
158                 str = "%s <arg>" % (str,)
159             help = self.help(opt)
160             n = string.find(help, '\n')
161             if self.default(opt) != None:
162                 if n < 0:
163                     str = "%-15s  %s (default=%s)" %(str, help,
164                                                      self.default(opt))
165                 else:
166                     str = "%-15s  %s (default=%s)%s" %(str, help[0:n],
167                                                        self.default(opt),
168                                                        help[n:])
169             else:
170                 str = "%-15s  %s" %(str, help)
171             ret = ret + str + "\n"
172         print ret
173
174 # Test driver
175 if __name__ == "__main__":
176     cl = Options("test", "xml_file", [
177                   ('verbose,v', "verbose ", Options.FLAG, 0),
178                   ('cleanup,d', "shutdown"),
179                   ('gdb',     "Display gdb module file ", Options.FLAG, 0),
180                   ('device', "device path ", Options.PARAM),
181                   ('ldapurl', "LDAP server URL ", Options.PARAM),
182                   ('lustre', "Lustre source dir ", Options.PARAM),
183                   ('portals', "Portals source dir ", Options.PARAM),
184                   ('maxlevel', """Specify the maximum level
185                     Levels are aproximatly like:
186                             70 - mountpoint, echo_client, osc, mdc, lov""",
187                    Options.INTPARAM, 100),
188
189                   ])
190
191     conf, args = cl.parse(sys.argv[1:])
192
193     for key in conf.values.keys():
194         print "%-10s = %s" % (key, conf.values[key])