ia64/xen-unstable

view tools/python/xen/xm/opts.py @ 6552:a9873d384da4

Merge.
author adsharma@los-vmm.sc.intel.com
date Thu Aug 25 12:24:48 2005 -0700 (2005-08-25)
parents 112d44270733 fa0754a9f64f
children dfaf788ab18c
line source
1 #============================================================================
2 # This library is free software; you can redistribute it and/or
3 # modify it under the terms of version 2.1 of the GNU Lesser General Public
4 # License as published by the Free Software Foundation.
5 #
6 # This library is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 # Lesser General Public License for more details.
10 #
11 # You should have received a copy of the GNU Lesser General Public
12 # License along with this library; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 #============================================================================
15 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
16 #============================================================================
18 """Object-oriented command-line option support.
19 """
20 from getopt import getopt, GetoptError
21 import os
22 import os.path
23 import sys
24 import types
26 class Opt:
27 """An individual option.
28 """
29 def __init__(self, opts, name, short=None, long=None,
30 val=None, fn=None, use=None, default=None):
31 """Create an option.
33 opts parent options object
34 name name of the field it controls
35 short short (1-char) command line switch (optional)
36 long long command-line switch. Defaults to option name.
37 val string used to print option args in help.
38 If val is not specified the option has no arg.
39 fn function to call when the option is specified.
40 use usage (help) string
41 default default value if not specified on command-line
42 """
43 self.opts = opts
44 self.name = name
45 self.short = short
46 if long is None:
47 long = name
48 self.long = long
49 self.val = val
50 self.use = use
51 self.default = default
52 self.optkeys = []
53 if self.short:
54 self.optkeys.append('-' + self.short)
55 if self.long:
56 self.optkeys.append('--' + self.long)
57 self.fn = fn
58 self.specified_opt = None
59 self.specified_val = None
60 self.value = None
61 self.set(default)
63 def __repr__(self):
64 return self.name + '=' + str(self.specified_val)
66 __str__ = __repr__
68 def set(self, value):
69 """Set the option value.
70 """
71 self.opts.setopt(self.name, value)
73 def get(self):
74 """Get the option value.
75 """
76 return self.opts.getopt(self.name)
78 def append(self, value):
79 """Append a value to the option value.
80 """
81 v = self.get() or []
82 v.append(value)
83 self.set(v)
85 def short_opt(self):
86 """Short option spec.
87 """
88 if self.short:
89 if self.val:
90 return self.short + ':'
91 else:
92 return self.short
93 else:
94 return None
96 def long_opt(self):
97 """Long option spec.
98 """
99 if self.long:
100 if self.val:
101 return self.long + '='
102 else:
103 return self.long
104 else:
105 return None
107 def format(self, str, start=' ', out=sys.stdout):
108 """Print a string, with consistent indentation at the start of lines.
109 """
110 lines = str.split('\n')
111 for l in lines:
112 l = l.strip()
113 if start:
114 out.write(start)
115 out.write(l)
116 out.write('\n')
118 def show(self, out=sys.stdout):
119 sep = ' '
120 for x in self.optkeys:
121 out.write(sep)
122 out.write(x)
123 sep = ', '
124 if self.val:
125 out.write(' ')
126 out.write(self.val)
127 out.write('\n')
128 if self.use:
129 self.format(self.use, out=out);
130 if self.val:
131 self.format('Default ' + str(self.default or 'None'), out=out)
133 def specify(self, k, v):
134 """Specify the option. Called when the option is set
135 from the command line.
137 k option switch used
138 v optional value given (if any)
139 """
140 if k in self.optkeys:
141 if self.val is None and v:
142 self.opts.err("Option '%s' does not take a value" % k)
143 self.specified_opt = k
144 self.specified_val = v
145 if self.fn:
146 self.fn(self, k, v)
147 return 1
148 else:
149 return 0
151 def specified(self):
152 """Test whether the option has been specified: set
153 from the command line.
154 """
155 return self.specified_opt
157 class OptVar(Opt):
158 """An individual option variable.
159 """
160 def __init__(self, opts, name,
161 val=None, fn=None, use=None, default=None):
162 """Create an option.
164 opts parent options object
165 name name of the field it controls
166 val string used to print option args in help.
167 If val is not specified the option has no arg.
168 fn function to call when the option is specified.
169 use usage (help) string
170 default default value if not specified on command-line
171 """
172 if val is None:
173 val = name.upper()
174 Opt.__init__(self, opts, name, val=val, fn=fn, use=use, default=default)
175 self.optkeys = []
176 self.optkeys.append(self.long)
178 def short_opt(self):
179 return None
181 def long_opt(self):
182 return None
184 def show(self, out=sys.stdout):
185 print >>out, ' %s=%s' % (self.optkeys[0], self.val)
186 if self.use:
187 self.format(self.use, out=out);
188 if self.val:
189 self.format('Default ' + str(self.default or 'None'), out=out)
191 class OptVals:
192 """Class to hold option values.
193 """
194 pass
196 class Opts:
197 """Container for options.
198 """
200 imports = ["import sys",
201 "import os",
202 "import os.path",
203 "from xen.util.ip import *",
204 ]
206 def __init__(self, use=None):
207 """Options constructor.
209 use usage string
210 """
211 self.use = use
212 # List of options.
213 self.options = []
214 # Options indexed by name.
215 self.options_map = {}
216 # Command-line arguments.
217 self.argv = []
218 # Option values.
219 self.vals = OptVals()
220 self.vals.quiet = 0
221 # Variables for default scripts.
222 self.vars = {}
223 # Option to use for bare words.
224 self.default_opt = None
226 def __repr__(self):
227 return '\n'.join(map(str, self.options))
229 __str__ = __repr__
231 def opt(self, name, **args):
232 """Add an option.
234 name option name
235 **args keyword params for option constructor
236 """
237 x = Opt(self, name, **args)
238 self.options.append(x)
239 self.options_map[name] = x
240 return x
242 def default(self, name):
243 self.default_opt = name
245 def getdefault(self, val):
246 if self.default_opt is None:
247 return 0
248 opt = self.option(self.default_opt)
249 return opt.set(val)
251 def var(self, name, **args):
252 x = OptVar(self, name, **args)
253 self.options.append(x)
254 self.options_map[name] = x
255 return x
257 def setvar(self, var, val):
258 """Set a default script variable.
259 """
260 self.vars[var] = val
262 def getvar(self, var):
263 """Get a default script variable.
264 """
265 return self.vars.get(var)
267 def option(self, name):
268 """Get an option (object).
269 """
270 return self.options_map.get(name)
272 def setopt(self, name, val):
273 """Set an option value.
274 An option can also be set using 'opts.vals.name = val'.
275 """
276 setattr(self.vals, name, val)
278 def getopt(self, name):
279 """Get an option value.
280 An option value can also be got using 'opts.vals.name'.
281 """
282 return getattr(self.vals, name)
284 def specified(self, name):
285 """Test if an option has been specified.
286 """
287 opt = self.option(name)
288 return opt and opt.specified()
290 def err(self, msg):
291 """Print an error to stderr and exit.
292 """
293 print >>sys.stderr, "Error:", msg
294 sys.exit(1)
296 def info(self, msg):
297 """Print a message to stdout (unless quiet is set).
298 """
299 if self.vals.quiet: return
300 print msg
302 def warn(self, msg):
303 """Print a warning to stdout.
304 """
305 print >>sys.stderr, "Warning:", msg
307 def parse(self, argv):
308 """Parse arguments argv using the options.
310 return remaining arguments
311 """
312 self.argv = argv
314 # hack to work around lack of gnu getopts parsing in python 2.2
315 args = argv[1:]
316 xargs = []
317 while args:
318 # let getopt parse whatever it feels like -- if anything
319 try:
320 (xvals, args) = getopt(args[0:],
321 self.short_opts(), self.long_opts())
322 except GetoptError, err:
323 self.err(str(err))
325 for (k, v) in xvals:
326 for opt in self.options:
327 if opt.specify(k, v): break
328 else:
329 print >>sys.stderr, "Error: Unknown option:", k
330 self.usage()
332 if not args:
333 break
335 # then process the 1st arg
336 (arg,args) = (args[0], args[1:])
338 isvar = 0
339 if '=' in arg:
340 (k, v) = arg.split('=', 1)
341 for opt in self.options:
342 if opt.specify(k, v):
343 isvar = 1
344 break
345 elif self.getdefault(arg):
346 isvar = 1
347 if not isvar:
348 xargs.append(arg)
350 return xargs
352 def short_opts(self):
353 """Get short options specifier for getopt.
354 """
355 l = []
356 for x in self.options:
357 y = x.short_opt()
358 if not y: continue
359 l.append(y)
360 return ''.join(l)
362 def long_opts(self):
363 """Get long options specifier for getopt.
364 """
365 l = []
366 for x in self.options:
367 y = x.long_opt()
368 if not y: continue
369 l.append(y)
370 return l
372 def usage(self):
373 print 'Usage: ', self.argv[0], self.use or 'OPTIONS'
374 print
375 for opt in self.options:
376 opt.show()
377 print
378 if self.options:
379 print
381 def var_usage(self):
382 if self.vars:
383 print 'The config file defines the following variables:'
384 for var in self.vars:
385 var.show()
386 print
387 print
389 def config_usage(self):
390 if self.imports:
391 print 'The following are automically imported:'
392 for x in self.imports:
393 print ' ', x
394 print
395 self.var_usage()
397 def load_defconfig(self, help=0):
398 """Load a defconfig script. Assumes these options set:
399 'path' search path
400 'defconfig' script name
401 """
402 for x in [ '' ] + self.vals.path.split(':'):
403 if x:
404 p = os.path.join(x, self.vals.defconfig)
405 else:
406 p = self.vals.defconfig
407 if os.path.exists(p):
408 self.info('Using config file "%s".' % p)
409 self.load(p, help)
410 break
411 else:
412 self.err('Cannot open config file "%s"' % self.vals.defconfig)
414 def load(self, defconfig, help):
415 """Load a defconfig file. Local variables in the file
416 are used to set options with the same names.
417 Variables are not used to set options that are already specified.
418 """
419 # Create global and lobal dicts for the file.
420 # Initialize locals to the vars.
421 # Use exec to do the standard imports and
422 # define variables we are passing to the script.
423 globals = {}
424 locals = {}
425 locals.update(self.vars)
426 cmd = '\n'.join(self.imports +
427 [ "from xen.xm.help import Vars",
428 "xm_file = '%s'" % defconfig,
429 "xm_help = %d" % help,
430 "xm_vars = Vars(xm_file, xm_help, locals())"
431 ])
432 exec cmd in globals, locals
433 try:
434 execfile(defconfig, globals, locals)
435 except:
436 if not help: raise
437 if help:
438 self.config_usage()
439 return
440 # Extract the values set by the script and set the corresponding
441 # options, if not set on the command line.
442 vtypes = [ types.StringType,
443 types.ListType,
444 types.IntType,
445 types.FloatType
446 ]
447 for (k, v) in locals.items():
448 if self.specified(k): continue
449 if not(type(v) in vtypes): continue
450 self.setopt(k, v)
452 def set_true(opt, k, v):
453 """Set an option true."""
454 opt.set(1)
456 def set_false(opt, k, v):
457 """Set an option false."""
458 opt.set(0)
460 def set_bool(opt, k, v):
461 """Set a boolean option.
462 """
463 if v in ['yes']:
464 opt.set(1)
465 elif v in ['no']:
466 opt.set(0)
467 else:
468 opt.opts.err('Invalid value:' +v)
470 def set_u32(opt, k, v):
471 """Set an option to an u32 value."""
472 try:
473 v = u32(v)
474 except:
475 opt.opts.err('Invalid value: ' + str(v))
476 opt.set(v)
478 def set_value(opt, k, v):
479 """Set an option to a value."""
480 opt.set(v)
482 def set_int(opt, k, v):
483 """Set an option to an integer value."""
484 try:
485 v = int(v)
486 except:
487 opt.opts.err('Invalid value: ' + str(v))
488 opt.set(v)
490 def set_float(opt, k, v):
491 """Set an option to a float value."""
492 try:
493 v = float(v)
494 except:
495 opt.opts.err('Invalid value: ' + str(v))
496 opt.set(v)
498 def append_value(opt, k, v):
499 """Append a value to a list option."""
500 opt.append(v)
502 def set_var(opt, k, v):
503 """Set a default script variable.
504 """
505 (var, val) = v.strip().split('=', 1)
506 opt.opts.setvar(var.strip(), val.strip())