Whamcloud - gitweb
- merge 0.7rc1 from b_devel to HEAD (20030612 merge point)
[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     def __init__(self, cmd, remain_help, options):
32         self.options = options
33         shorts = ""
34         longs = []
35         options.append(('help,h', "Print this help")) 
36         for opt in options:
37             long = self.long(opt)
38             short = self.short(opt)
39             if self.type(opt) in (Options.PARAM, Options.INTPARAM):
40                 if short:  short = short + ':'
41                 if long: long = long + '='
42             shorts = shorts + short
43             longs.append(long)
44         self.short_opts = shorts
45         self.long_opts = longs
46         self.cmd = cmd
47         self.remain_help = remain_help
48
49     def init_values(self):
50         values = {}
51         for opt in self.options:
52             values[self.key(opt)] = self.default(opt)
53         return values
54
55     def long(self, option):
56         n = string.find(option[0], ',')
57         if n < 0: return option[0]
58         else:     return option[0][0:n]
59
60     def key(self, option):
61         key = self.long(option)
62         return string.replace(key, '-', '_')
63         
64     def short(self, option):
65         n = string.find(option[0], ',')
66         if n < 0: return ''
67         else:     return option[0][n+1:]
68
69     def help(self, option):
70         return option[1]
71     
72     def type(self, option):
73         if len(option) >= 3:
74             return option[2]
75         return Options.FLAG
76     
77     def default(self, option):
78         if len(option) >= 4:
79             return option[3]
80         return None
81
82     def lookup_option(self, key, key_func):
83         for opt in self.options:
84             if key_func(opt) == key:
85                 return opt
86
87     def lookup_short(self, key):
88         return self.lookup_option(key, self.short)
89
90     def lookup_long(self, key):
91         return self.lookup_option(key, self.long)
92
93     def handle_opts(self, opts):
94         values = self.init_values()
95         for o, a in opts:
96             if o[0:2] != '--':
97                 option = self.lookup_short(o[1:])
98             else:
99                 option = self.lookup_long(o[2:])
100             if self.type(option) == Options.PARAM:
101                 val = a
102             elif self.type(option) == Options.INTPARAM:
103                 try: 
104                     val = int(a)
105                 except ValueError, e:
106                     raise error.OptionError("option: '%s' expects integer value, got '%s' "  % (o,a))
107             else:
108                 val = 1
109             values[self.key(option)] = val
110         return values
111                 
112         
113     class option_wrapper:
114         def __init__(self, values):
115             self.__dict__['values'] = values
116         def __getattr__(self, name):
117             if self.values.has_key(name):
118                 return self.values[name]
119             else:
120                 raise error.OptionError("bad option name: " + name)
121         def __setattr__(self, name, value):
122             self.values[name] = value
123
124     def parse(self, argv):
125         try:
126             opts, args = getopt.getopt(argv, self.short_opts, self.long_opts)
127             values = self.handle_opts(opts)
128             if values["help"]:
129                 self.usage()
130                 sys.exit(0)
131             return self.option_wrapper(values), args
132         except getopt.error, e:
133             raise error.OptionError(str(e))
134
135     def usage(self):
136         ret = 'usage: %s [options] %s\n' % (self.cmd, self.remain_help)
137         for opt in self.options:
138             s = self.short(opt)
139             if s: str = "-%s|--%s" % (s,self.long(opt))
140             else: str = "--%s" % (self.long(opt),)
141             if self.type(opt) in (Options.PARAM, Options.INTPARAM):
142                 str = "%s <arg>" % (str,)
143             help = self.help(opt)
144             n = string.find(help, '\n')
145             if self.default(opt) != None:
146                 if n < 0:
147                     str = "%-15s  %s (default=%s)" %(str, help,
148                                                      self.default(opt))
149                 else:
150                     str = "%-15s  %s (default=%s)%s" %(str, help[0:n],
151                                                        self.default(opt),
152                                                        help[n:])
153             else:
154                 str = "%-15s  %s" %(str, help)
155             ret = ret + str + "\n"
156         print ret
157
158 # Test driver
159 if __name__ == "__main__":
160     cl = Options("test", "xml_file", [
161                   ('verbose,v', "verbose ", Options.FLAG, 0),
162                   ('cleanup,d', "shutdown"),
163                   ('gdb',     "Display gdb module file ", Options.FLAG, 0),
164                   ('device', "device path ", Options.PARAM),
165                   ('ldapurl', "LDAP server URL ", Options.PARAM),
166                   ('lustre', "Lustre source dir ", Options.PARAM),
167                   ('portals', "Portals source dir ", Options.PARAM),
168                   ('maxlevel', """Specify the maximum level
169                     Levels are aproximatly like:
170                             70 - mountpoint, echo_client, osc, mdc, lov""",
171                    Options.INTPARAM, 100),
172
173                   ])
174
175     conf, args = cl.parse(sys.argv[1:])
176
177     for key in conf.values.keys():
178         print "%-10s = %s" % (key, conf.values[key])