options.py revision 13709:dd6b7ac5801f
15647Sgblack@eecs.umich.edu# Copyright (c) 2005 The Regents of The University of Michigan 25647Sgblack@eecs.umich.edu# All rights reserved. 35647Sgblack@eecs.umich.edu# 45647Sgblack@eecs.umich.edu# Redistribution and use in source and binary forms, with or without 57087Snate@binkert.org# modification, are permitted provided that the following conditions are 67087Snate@binkert.org# met: redistributions of source code must retain the above copyright 77087Snate@binkert.org# notice, this list of conditions and the following disclaimer; 87087Snate@binkert.org# redistributions in binary form must reproduce the above copyright 97087Snate@binkert.org# notice, this list of conditions and the following disclaimer in the 107087Snate@binkert.org# documentation and/or other materials provided with the distribution; 117087Snate@binkert.org# neither the name of the copyright holders nor the names of its 127087Snate@binkert.org# contributors may be used to endorse or promote products derived from 135647Sgblack@eecs.umich.edu# this software without specific prior written permission. 147087Snate@binkert.org# 157087Snate@binkert.org# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 167087Snate@binkert.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 177087Snate@binkert.org# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 187087Snate@binkert.org# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 197087Snate@binkert.org# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 207087Snate@binkert.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 217087Snate@binkert.org# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 225647Sgblack@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 237087Snate@binkert.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 245647Sgblack@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 255647Sgblack@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 265647Sgblack@eecs.umich.edu# 275647Sgblack@eecs.umich.edu# Authors: Nathan Binkert 285647Sgblack@eecs.umich.edu 295647Sgblack@eecs.umich.eduimport optparse 305647Sgblack@eecs.umich.eduimport sys 315647Sgblack@eecs.umich.edu 325647Sgblack@eecs.umich.edufrom optparse import * 335647Sgblack@eecs.umich.edu 345647Sgblack@eecs.umich.educlass nodefault(object): pass 355647Sgblack@eecs.umich.edu 365647Sgblack@eecs.umich.educlass splitter(object): 375647Sgblack@eecs.umich.edu def __init__(self, split): 385647Sgblack@eecs.umich.edu self.split = split 395647Sgblack@eecs.umich.edu def __call__(self, option, opt_str, value, parser): 408229Snate@binkert.org values = value.split(self.split) 415647Sgblack@eecs.umich.edu dest = getattr(parser.values, option.dest) 425654Sgblack@eecs.umich.edu if dest is None: 435647Sgblack@eecs.umich.edu setattr(parser.values, option.dest, values) 446137Sgblack@eecs.umich.edu else: 456137Sgblack@eecs.umich.edu dest.extend(values) 466137Sgblack@eecs.umich.edu 475654Sgblack@eecs.umich.educlass OptionParser(dict): 486046Sgblack@eecs.umich.edu def __init__(self, *args, **kwargs): 495647Sgblack@eecs.umich.edu kwargs.setdefault('formatter', optparse.TitledHelpFormatter()) 505648Sgblack@eecs.umich.edu self._optparse = optparse.OptionParser(*args, **kwargs) 515648Sgblack@eecs.umich.edu self._optparse.disable_interspersed_args() 525647Sgblack@eecs.umich.edu 535647Sgblack@eecs.umich.edu self._allopts = {} 545647Sgblack@eecs.umich.edu 555647Sgblack@eecs.umich.edu # current option group 565647Sgblack@eecs.umich.edu self._group = self._optparse 575647Sgblack@eecs.umich.edu 585647Sgblack@eecs.umich.edu def set_defaults(self, *args, **kwargs): 595647Sgblack@eecs.umich.edu return self._optparse.set_defaults(*args, **kwargs) 605647Sgblack@eecs.umich.edu 615648Sgblack@eecs.umich.edu def set_group(self, *args, **kwargs): 625647Sgblack@eecs.umich.edu '''set the current option group''' 635648Sgblack@eecs.umich.edu if not args and not kwargs: 645648Sgblack@eecs.umich.edu self._group = self._optparse 655648Sgblack@eecs.umich.edu else: 665648Sgblack@eecs.umich.edu self._group = self._optparse.add_option_group(*args, **kwargs) 675648Sgblack@eecs.umich.edu 685648Sgblack@eecs.umich.edu def add_option(self, *args, **kwargs): 695648Sgblack@eecs.umich.edu '''add an option to the current option group, or global none set''' 705648Sgblack@eecs.umich.edu 715648Sgblack@eecs.umich.edu # if action=split, but allows the option arguments 725648Sgblack@eecs.umich.edu # themselves to be lists separated by the split variable''' 735648Sgblack@eecs.umich.edu 745648Sgblack@eecs.umich.edu if kwargs.get('action', None) == 'append' and 'split' in kwargs: 755648Sgblack@eecs.umich.edu split = kwargs.pop('split') 765648Sgblack@eecs.umich.edu kwargs['default'] = [] 775648Sgblack@eecs.umich.edu kwargs['type'] = 'string' 785648Sgblack@eecs.umich.edu kwargs['action'] = 'callback' 795648Sgblack@eecs.umich.edu kwargs['callback'] = splitter(split) 805648Sgblack@eecs.umich.edu 815648Sgblack@eecs.umich.edu option = self._group.add_option(*args, **kwargs) 825648Sgblack@eecs.umich.edu dest = option.dest 835648Sgblack@eecs.umich.edu if dest not in self._allopts: 845648Sgblack@eecs.umich.edu self._allopts[dest] = option 855648Sgblack@eecs.umich.edu 865648Sgblack@eecs.umich.edu return option 875648Sgblack@eecs.umich.edu 885648Sgblack@eecs.umich.edu def bool_option(self, name, default, help): 895648Sgblack@eecs.umich.edu '''add a boolean option called --name and --no-name. 905648Sgblack@eecs.umich.edu Display help depending on which is the default''' 915648Sgblack@eecs.umich.edu 925648Sgblack@eecs.umich.edu tname = '--%s' % name 935648Sgblack@eecs.umich.edu fname = '--no-%s' % name 945648Sgblack@eecs.umich.edu dest = name.replace('-', '_') 955648Sgblack@eecs.umich.edu if default: 965648Sgblack@eecs.umich.edu thelp = optparse.SUPPRESS_HELP 975648Sgblack@eecs.umich.edu fhelp = help 985648Sgblack@eecs.umich.edu else: 995648Sgblack@eecs.umich.edu thelp = help 1005648Sgblack@eecs.umich.edu fhelp = optparse.SUPPRESS_HELP 1015648Sgblack@eecs.umich.edu 1025648Sgblack@eecs.umich.edu topt = self.add_option(tname, action="store_true", default=default, 1035648Sgblack@eecs.umich.edu help=thelp) 1045648Sgblack@eecs.umich.edu fopt = self.add_option(fname, action="store_false", dest=dest, 1055648Sgblack@eecs.umich.edu help=fhelp) 1065648Sgblack@eecs.umich.edu 1075648Sgblack@eecs.umich.edu return topt,fopt 1085648Sgblack@eecs.umich.edu 1095648Sgblack@eecs.umich.edu def __getattr__(self, attr): 1105648Sgblack@eecs.umich.edu if attr.startswith('_'): 1115648Sgblack@eecs.umich.edu return super(OptionParser, self).__getattribute__(attr) 1125648Sgblack@eecs.umich.edu 1135648Sgblack@eecs.umich.edu if attr in self: 1145648Sgblack@eecs.umich.edu return self[attr] 1155648Sgblack@eecs.umich.edu 1165648Sgblack@eecs.umich.edu return super(OptionParser, self).__getattribute__(attr) 1175648Sgblack@eecs.umich.edu 1185648Sgblack@eecs.umich.edu def __setattr__(self, attr, value): 1195648Sgblack@eecs.umich.edu if attr.startswith('_'): 1205648Sgblack@eecs.umich.edu super(OptionParser, self).__setattr__(attr, value) 1215648Sgblack@eecs.umich.edu elif attr in self._allopts: 1225648Sgblack@eecs.umich.edu defaults = { attr : value } 1235648Sgblack@eecs.umich.edu self.set_defaults(**defaults) 1245648Sgblack@eecs.umich.edu if attr in self: 1255648Sgblack@eecs.umich.edu self[attr] = value 1265648Sgblack@eecs.umich.edu else: 1275648Sgblack@eecs.umich.edu super(OptionParser, self).__setattr__(attr, value) 1285648Sgblack@eecs.umich.edu 1295648Sgblack@eecs.umich.edu def parse_args(self): 1305648Sgblack@eecs.umich.edu opts,args = self._optparse.parse_args() 1315648Sgblack@eecs.umich.edu 1325648Sgblack@eecs.umich.edu for key,val in opts.__dict__.items(): 1335648Sgblack@eecs.umich.edu if val is not None or key not in self: 1345648Sgblack@eecs.umich.edu self[key] = val 1355648Sgblack@eecs.umich.edu 1365648Sgblack@eecs.umich.edu return args 1375648Sgblack@eecs.umich.edu 1385648Sgblack@eecs.umich.edu def usage(self, exitcode=None): 1395648Sgblack@eecs.umich.edu self._optparse.print_help() 1405648Sgblack@eecs.umich.edu if exitcode is not None: 1415648Sgblack@eecs.umich.edu sys.exit(exitcode) 1425648Sgblack@eecs.umich.edu 1435648Sgblack@eecs.umich.edu