options.py revision 13714
12SN/A# Copyright (c) 2005 The Regents of The University of Michigan
212276Sanouk.vanlaer@arm.com# All rights reserved.
38707Sandreas.hansson@arm.com#
48707Sandreas.hansson@arm.com# Redistribution and use in source and binary forms, with or without
58707Sandreas.hansson@arm.com# modification, are permitted provided that the following conditions are
68707Sandreas.hansson@arm.com# met: redistributions of source code must retain the above copyright
78707Sandreas.hansson@arm.com# notice, this list of conditions and the following disclaimer;
88707Sandreas.hansson@arm.com# redistributions in binary form must reproduce the above copyright
98707Sandreas.hansson@arm.com# notice, this list of conditions and the following disclaimer in the
108707Sandreas.hansson@arm.com# documentation and/or other materials provided with the distribution;
118707Sandreas.hansson@arm.com# neither the name of the copyright holders nor the names of its
128707Sandreas.hansson@arm.com# contributors may be used to endorse or promote products derived from
138707Sandreas.hansson@arm.com# this software without specific prior written permission.
141762SN/A#
157897Shestness@cs.utexas.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
162SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
172SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
182SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
192SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
202SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
212SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
222SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
232SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
242SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
252SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
262SN/A#
272SN/A# Authors: Nathan Binkert
282SN/A
292SN/Afrom __future__ import print_function
302SN/Afrom __future__ import absolute_import
312SN/A
322SN/Aimport optparse
332SN/Aimport sys
342SN/A
352SN/Afrom optparse import *
362SN/A
372SN/Aclass nodefault(object): pass
382SN/A
392SN/Aclass splitter(object):
402665Ssaidi@eecs.umich.edu    def __init__(self, split):
412665Ssaidi@eecs.umich.edu        self.split = split
422665Ssaidi@eecs.umich.edu    def __call__(self, option, opt_str, value, parser):
437897Shestness@cs.utexas.edu        values = value.split(self.split)
442SN/A        dest = getattr(parser.values, option.dest)
452SN/A        if dest is None:
461717SN/A            setattr(parser.values, option.dest, values)
471717SN/A        else:
482SN/A            dest.extend(values)
492SN/A
502SN/Aclass OptionParser(dict):
519850Sandreas.hansson@arm.com    def __init__(self, *args, **kwargs):
529850Sandreas.hansson@arm.com        kwargs.setdefault('formatter', optparse.TitledHelpFormatter())
539850Sandreas.hansson@arm.com        self._optparse = optparse.OptionParser(*args, **kwargs)
549850Sandreas.hansson@arm.com        self._optparse.disable_interspersed_args()
559850Sandreas.hansson@arm.com
569850Sandreas.hansson@arm.com        self._allopts = {}
578745Sgblack@eecs.umich.edu
584182Sgblack@eecs.umich.edu        # current option group
595664Sgblack@eecs.umich.edu        self._group = self._optparse
60707SN/A
618229Snate@binkert.org    def set_defaults(self, *args, **kwargs):
6256SN/A        return self._optparse.set_defaults(*args, **kwargs)
638779Sgblack@eecs.umich.edu
644776Sgblack@eecs.umich.edu    def set_group(self, *args, **kwargs):
6510464SAndreas.Sandberg@ARM.com        '''set the current option group'''
6612284Sjose.marinho@arm.com        if not args and not kwargs:
679814Sandreas.hansson@arm.com            self._group = self._optparse
6810529Smorr@cs.wisc.edu        else:
692SN/A            self._group = self._optparse.add_option_group(*args, **kwargs)
7010529Smorr@cs.wisc.edu
718901Sandreas.hansson@arm.com    def add_option(self, *args, **kwargs):
722315SN/A        '''add an option to the current option group, or global none set'''
732680Sktlim@umich.edu
742SN/A        # if action=split, but allows the option arguments
7510529Smorr@cs.wisc.edu        # themselves to be lists separated by the split variable'''
7610529Smorr@cs.wisc.edu
7710529Smorr@cs.wisc.edu        if kwargs.get('action', None) == 'append' and 'split' in kwargs:
7810529Smorr@cs.wisc.edu            split = kwargs.pop('split')
7910529Smorr@cs.wisc.edu            kwargs['default'] = []
8010529Smorr@cs.wisc.edu            kwargs['type'] = 'string'
8110529Smorr@cs.wisc.edu            kwargs['action'] = 'callback'
8210529Smorr@cs.wisc.edu            kwargs['callback'] = splitter(split)
8310529Smorr@cs.wisc.edu
8410529Smorr@cs.wisc.edu        option = self._group.add_option(*args, **kwargs)
8510529Smorr@cs.wisc.edu        dest = option.dest
8610529Smorr@cs.wisc.edu        if dest not in self._allopts:
8710529Smorr@cs.wisc.edu            self._allopts[dest] = option
882356SN/A
892356SN/A        return option
902356SN/A
916144Sksewell@umich.edu    def bool_option(self, name, default, help):
922356SN/A        '''add a boolean option called --name and --no-name.
932356SN/A        Display help depending on which is the default'''
946144Sksewell@umich.edu
952356SN/A        tname = '--%s' % name
962356SN/A        fname = '--no-%s' % name
976144Sksewell@umich.edu        dest = name.replace('-', '_')
982356SN/A        if default:
992356SN/A            thelp = optparse.SUPPRESS_HELP
1002356SN/A            fhelp = help
1016144Sksewell@umich.edu        else:
1026144Sksewell@umich.edu            thelp = help
1036144Sksewell@umich.edu            fhelp = optparse.SUPPRESS_HELP
1046144Sksewell@umich.edu
1056144Sksewell@umich.edu        topt = self.add_option(tname, action="store_true", default=default,
1065336Shines@cs.fsu.edu                               help=thelp)
1072356SN/A        fopt = self.add_option(fname, action="store_false", dest=dest,
1082356SN/A                               help=fhelp)
1092856Srdreslin@umich.edu
1102SN/A        return topt,fopt
1111634SN/A
1129157Sandreas.hansson@arm.com    def __getattr__(self, attr):
11310662SAli.Saidi@ARM.com        if attr.startswith('_'):
11410662SAli.Saidi@ARM.com            return super(OptionParser, self).__getattribute__(attr)
1153814Ssaidi@eecs.umich.edu
11610662SAli.Saidi@ARM.com        if attr in self:
1175712Shsul@eecs.umich.edu            return self[attr]
1185712Shsul@eecs.umich.edu
1195715Shsul@eecs.umich.edu        return super(OptionParser, self).__getattribute__(attr)
1205712Shsul@eecs.umich.edu
1215712Shsul@eecs.umich.edu    def __setattr__(self, attr, value):
1221634SN/A        if attr.startswith('_'):
12310190Sakash.bagdia@arm.com            super(OptionParser, self).__setattr__(attr, value)
12410190Sakash.bagdia@arm.com        elif attr in self._allopts:
12510190Sakash.bagdia@arm.com            defaults = { attr : value }
12610190Sakash.bagdia@arm.com            self.set_defaults(**defaults)
12710190Sakash.bagdia@arm.com            if attr in self:
12810190Sakash.bagdia@arm.com                self[attr] = value
12910190Sakash.bagdia@arm.com        else:
1308832SAli.Saidi@ARM.com            super(OptionParser, self).__setattr__(attr, value)
1318832SAli.Saidi@ARM.com
1328832SAli.Saidi@ARM.com    def parse_args(self):
1338832SAli.Saidi@ARM.com        opts,args = self._optparse.parse_args()
1348832SAli.Saidi@ARM.com
1358832SAli.Saidi@ARM.com        for key,val in opts.__dict__.items():
1369332Sdam.sunwoo@arm.com            if val is not None or key not in self:
1379332Sdam.sunwoo@arm.com                self[key] = val
1389332Sdam.sunwoo@arm.com
1399332Sdam.sunwoo@arm.com        return args
1409332Sdam.sunwoo@arm.com
1419332Sdam.sunwoo@arm.com    def usage(self, exitcode=None):
1429332Sdam.sunwoo@arm.com        self._optparse.print_help()
1439332Sdam.sunwoo@arm.com        if exitcode is not None:
1449332Sdam.sunwoo@arm.com            sys.exit(exitcode)
1459332Sdam.sunwoo@arm.com
1469332Sdam.sunwoo@arm.com