From 779c31077c965e28575fca3c065d651fcc87c134 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 14 Jun 2008 21:15:58 -0700 Subject: python: Separate the options parsing stuff. Remove options parsing stuff from main.py so things are a bit more obvious. --- src/python/SConscript | 1 + src/python/m5/main.py | 114 +++++++------------------------------ src/python/m5/options.py | 145 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 166 insertions(+), 94 deletions(-) create mode 100644 src/python/m5/options.py (limited to 'src') diff --git a/src/python/SConscript b/src/python/SConscript index 0785b4307..cca9217b0 100644 --- a/src/python/SConscript +++ b/src/python/SConscript @@ -39,6 +39,7 @@ PySource('m5', 'm5/SimObject.py') PySource('m5', 'm5/convert.py') PySource('m5', 'm5/event.py') PySource('m5', 'm5/main.py') +PySource('m5', 'm5/options.py') PySource('m5', 'm5/params.py') PySource('m5', 'm5/proxy.py') PySource('m5', 'm5/simulate.py') diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 5c3324224..8011c64b8 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -28,25 +28,17 @@ import code import datetime -import optparse import os import socket import sys from util import attrdict import defines +from options import OptionParser import traceflags __all__ = [ 'options', 'arguments', 'main' ] -usage="%prog [m5 options] script.py [script options]" -version="%prog 2.0" -brief_copyright=''' -Copyright (c) 2001-2008 -The Regents of The University of Michigan -All Rights Reserved -''' - def print_list(items, indent=4): line = ' ' * indent for i,item in enumerate(items): @@ -60,64 +52,19 @@ def print_list(items, indent=4): line += item print line -# there's only one option parsing done, so make it global and add some -# helper functions to make it work well. -parser = optparse.OptionParser(usage=usage, version=version, - description=brief_copyright, - formatter=optparse.TitledHelpFormatter()) -parser.disable_interspersed_args() - -# current option group -group = None - -def set_group(*args, **kwargs): - '''set the current option group''' - global group - if not args and not kwargs: - group = None - else: - group = parser.add_option_group(*args, **kwargs) - -class splitter(object): - def __init__(self, split): - self.split = split - def __call__(self, option, opt_str, value, parser): - getattr(parser.values, option.dest).extend(value.split(self.split)) - -def add_option(*args, **kwargs): - '''add an option to the current option group, or global none set''' - - # if action=split, but allows the option arguments - # themselves to be lists separated by the split variable''' - - if kwargs.get('action', None) == 'append' and 'split' in kwargs: - split = kwargs.pop('split') - kwargs['default'] = [] - kwargs['type'] = 'string' - kwargs['action'] = 'callback' - kwargs['callback'] = splitter(split) - - if group: - return group.add_option(*args, **kwargs) - - return parser.add_option(*args, **kwargs) - -def bool_option(name, default, help): - '''add a boolean option called --name and --no-name. - Display help depending on which is the default''' - - tname = '--%s' % name - fname = '--no-%s' % name - dest = name.replace('-', '_') - if default: - thelp = optparse.SUPPRESS_HELP - fhelp = help - else: - thelp = help - fhelp = optparse.SUPPRESS_HELP +usage="%prog [m5 options] script.py [script options]" +version="%prog 2.0" +brief_copyright=''' +Copyright (c) 2001-2008 +The Regents of The University of Michigan +All Rights Reserved +''' - add_option(tname, action="store_true", default=default, help=thelp) - add_option(fname, action="store_false", dest=dest, help=fhelp) +options = OptionParser(usage=usage, version=version, + description=brief_copyright) +add_option = options.add_option +set_group = options.set_group +usage = options.usage # Help options add_option('-A', "--authors", action="store_true", default=False, @@ -168,39 +115,13 @@ add_option("--trace-file", metavar="FILE", default="cout", add_option("--trace-ignore", metavar="EXPR", action='append', split=':', help="Ignore EXPR sim objects") -options = attrdict() -arguments = [] - -def usage(exitcode=None): - parser.print_help() - if exitcode is not None: - sys.exit(exitcode) - -def parse_args(): - _opts,args = parser.parse_args() - opts = attrdict(_opts.__dict__) - - # setting verbose and quiet at the same time doesn't make sense - if opts.verbose > 0 and opts.quiet > 0: - usage(2) - - # store the verbosity in a single variable. 0 is default, - # negative numbers represent quiet and positive values indicate verbose - opts.verbose -= opts.quiet - - del opts.quiet - - options.update(opts) - arguments.extend(args) - return opts,args - def main(): import defines import event import info import internal - parse_args() + arguments = options.parse_args() done = False @@ -261,6 +182,11 @@ def main(): if done: sys.exit(0) + # setting verbose and quiet at the same time doesn't make sense + if options.verbose > 0 and options.quiet > 0: + options.usage(2) + + verbose = options.verbose - options.quiet if options.verbose >= 0: print "M5 Simulator System" print brief_copyright @@ -282,7 +208,7 @@ def main(): if arguments and not os.path.isfile(arguments[0]): print "Script %s not found" % arguments[0] - usage(2) + options.usage(2) # tell C++ about output directory internal.core.setOutputDir(options.outdir) diff --git a/src/python/m5/options.py b/src/python/m5/options.py new file mode 100644 index 000000000..50eea429c --- /dev/null +++ b/src/python/m5/options.py @@ -0,0 +1,145 @@ +# Copyright (c) 2005 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Nathan Binkert + +import optparse +import sys +import util + +from optparse import * + +class nodefault(object): pass + +class splitter(object): + def __init__(self, split): + self.split = split + def __call__(self, option, opt_str, value, parser): + values = value.split(self.split) + dest = getattr(parser.values, option.dest) + if dest is None: + setattr(parser.values, option.dest, values) + else: + dest.extend(values) + +class OptionParser(object): + def __init__(self, *args, **kwargs): + kwargs.setdefault('formatter', optparse.TitledHelpFormatter()) + self._optparse = optparse.OptionParser(*args, **kwargs) + self._optparse.disable_interspersed_args() + + self._allopts = {} + self._defaults = {} + self._options = util.attrdict() + + # current option group + self._group = self._optparse + + def set_group(self, *args, **kwargs): + '''set the current option group''' + if not args and not kwargs: + self._group = self._optparse + else: + self._group = self._optparse.add_option_group(*args, **kwargs) + + def add_option(self, *args, **kwargs): + '''add an option to the current option group, or global none set''' + + # if action=split, but allows the option arguments + # themselves to be lists separated by the split variable''' + + if kwargs.get('action', None) == 'append' and 'split' in kwargs: + split = kwargs.pop('split') + kwargs['default'] = [] + kwargs['type'] = 'string' + kwargs['action'] = 'callback' + kwargs['callback'] = splitter(split) + + default = kwargs.pop('default', nodefault) + option = self._group.add_option(*args, **kwargs) + dest = option.dest + if dest not in self._allopts: + self._allopts[dest] = option + + if default != nodefault: + if dest not in self._options: + self._options[dest] = default + + return option + + def bool_option(self, name, default, help): + '''add a boolean option called --name and --no-name. + Display help depending on which is the default''' + + tname = '--%s' % name + fname = '--no-%s' % name + dest = name.replace('-', '_') + if default: + thelp = optparse.SUPPRESS_HELP + fhelp = help + else: + thelp = help + fhelp = optparse.SUPPRESS_HELP + + topt = self.add_option(tname, action="store_true", default=default, + help=thelp) + fopt = self.add_option(fname, action="store_false", dest=dest, + help=fhelp) + + return topt,fopt + + def __getattr__(self, attr): + if attr.startswith('_'): + return super(OptionParser, self).__getattr__(attr) + + if attr in self._options: + return self._options[attr] + + raise AttributeError, "Option %s not found" % attr + + def __setattr__(self, attr, value): + if attr.startswith('_'): + return super(OptionParser, self).__setattr__(attr, value) + + if attr in self._options: + self._options[attr] = value + + return super(OptionParser, self).__setattr__(attr, value) + + def parse_args(self): + opts,args = self._optparse.parse_args() + + for key,val in opts.__dict__.iteritems(): + if val is not None or key not in self._options: + self._options[key] = val + + return args + + def usage(self, exitcode=None): + self._optparse.print_help() + if exitcode is not None: + sys.exit(exitcode) + -- cgit v1.2.3