python: Move more code into m5.util allow SCons to use that code.
Get rid of misc.py and just stick misc things in __init__.py Move utility functions out of SCons files and into m5.util Move utility type stuff from m5/__init__.py to m5/util/__init__.py Remove buildEnv from m5 and allow access only from m5.defines Rename AddToPath to addToPath while we're moving it to m5.util Rename read_command to readCommand while we're moving it Rename compare_versions to compareVersions while we're moving it. --HG-- rename : src/python/m5/convert.py => src/python/m5/util/convert.py rename : src/python/m5/smartdict.py => src/python/m5/util/smartdict.py
This commit is contained in:
@@ -38,7 +38,6 @@ PySource('', 'importer.py')
|
||||
PySource('m5', 'm5/__init__.py')
|
||||
PySource('m5', 'm5/SimObject.py')
|
||||
PySource('m5', 'm5/config.py')
|
||||
PySource('m5', 'm5/convert.py')
|
||||
PySource('m5', 'm5/core.py')
|
||||
PySource('m5', 'm5/debug.py')
|
||||
PySource('m5', 'm5/event.py')
|
||||
@@ -47,18 +46,18 @@ PySource('m5', 'm5/options.py')
|
||||
PySource('m5', 'm5/params.py')
|
||||
PySource('m5', 'm5/proxy.py')
|
||||
PySource('m5', 'm5/simulate.py')
|
||||
PySource('m5', 'm5/smartdict.py')
|
||||
PySource('m5', 'm5/stats.py')
|
||||
PySource('m5', 'm5/ticks.py')
|
||||
PySource('m5', 'm5/trace.py')
|
||||
PySource('m5.util', 'm5/util/__init__.py')
|
||||
PySource('m5.util', 'm5/util/attrdict.py')
|
||||
PySource('m5.util', 'm5/util/code_formatter.py')
|
||||
PySource('m5.util', 'm5/util/convert.py')
|
||||
PySource('m5.util', 'm5/util/grammar.py')
|
||||
PySource('m5.util', 'm5/util/jobfile.py')
|
||||
PySource('m5.util', 'm5/util/misc.py')
|
||||
PySource('m5.util', 'm5/util/multidict.py')
|
||||
PySource('m5.util', 'm5/util/orderdict.py')
|
||||
PySource('m5.util', 'm5/util/smartdict.py')
|
||||
|
||||
SwigSource('m5.internal', 'swig/core.i')
|
||||
SwigSource('m5.internal', 'swig/debug.i')
|
||||
|
||||
@@ -31,47 +31,24 @@ import math
|
||||
import sys
|
||||
import types
|
||||
|
||||
import proxy
|
||||
try:
|
||||
import pydot
|
||||
except:
|
||||
pydot = False
|
||||
|
||||
import m5
|
||||
from util import *
|
||||
|
||||
# These utility functions have to come first because they're
|
||||
# referenced in params.py... otherwise they won't be defined when we
|
||||
# import params below, and the recursive import of this file from
|
||||
# params.py will not find these names.
|
||||
def isSimObject(value):
|
||||
return isinstance(value, SimObject)
|
||||
|
||||
def isSimObjectClass(value):
|
||||
return issubclass(value, SimObject)
|
||||
|
||||
def isSimObjectSequence(value):
|
||||
if not isinstance(value, (list, tuple)) or len(value) == 0:
|
||||
return False
|
||||
|
||||
for val in value:
|
||||
if not isNullPointer(val) and not isSimObject(val):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def isSimObjectOrSequence(value):
|
||||
return isSimObject(value) or isSimObjectSequence(value)
|
||||
from m5.util import *
|
||||
|
||||
# Have to import params up top since Param is referenced on initial
|
||||
# load (when SimObject class references Param to create a class
|
||||
# variable, the 'name' param)...
|
||||
from params import *
|
||||
from m5.params import *
|
||||
# There are a few things we need that aren't in params.__all__ since
|
||||
# normal users don't need them
|
||||
from params import ParamDesc, VectorParamDesc, isNullPointer, SimObjVector
|
||||
from proxy import *
|
||||
from m5.params import ParamDesc, VectorParamDesc, isNullPointer, SimObjVector
|
||||
|
||||
noDot = False
|
||||
try:
|
||||
import pydot
|
||||
except:
|
||||
noDot = True
|
||||
from m5.proxy import *
|
||||
from m5.proxy import isproxy
|
||||
|
||||
#####################################################################
|
||||
#
|
||||
@@ -141,7 +118,7 @@ class MetaSimObject(type):
|
||||
# and only allow "private" attributes to be passed to the base
|
||||
# __new__ (starting with underscore).
|
||||
def __new__(mcls, name, bases, dict):
|
||||
assert name not in allClasses
|
||||
assert name not in allClasses, "SimObject %s already present" % name
|
||||
|
||||
# Copy "private" attributes, functions, and classes to the
|
||||
# official dict. Everything else goes in _init_dict to be
|
||||
@@ -678,7 +655,7 @@ class SimObject(object):
|
||||
def unproxy_all(self):
|
||||
for param in self._params.iterkeys():
|
||||
value = self._values.get(param)
|
||||
if value != None and proxy.isproxy(value):
|
||||
if value != None and isproxy(value):
|
||||
try:
|
||||
value = value.unproxy(self)
|
||||
except:
|
||||
@@ -749,8 +726,8 @@ class SimObject(object):
|
||||
for param in param_names:
|
||||
value = self._values.get(param)
|
||||
if value is None:
|
||||
m5.fatal("%s.%s without default or user set value",
|
||||
self.path(), param)
|
||||
fatal("%s.%s without default or user set value",
|
||||
self.path(), param)
|
||||
|
||||
value = value.getValue()
|
||||
if isinstance(self._params[param], VectorParamDesc):
|
||||
@@ -886,6 +863,34 @@ def resolveSimObject(name):
|
||||
obj = instanceDict[name]
|
||||
return obj.getCCObject()
|
||||
|
||||
def isSimObject(value):
|
||||
return isinstance(value, SimObject)
|
||||
|
||||
def isSimObjectClass(value):
|
||||
return issubclass(value, SimObject)
|
||||
|
||||
def isSimObjectSequence(value):
|
||||
if not isinstance(value, (list, tuple)) or len(value) == 0:
|
||||
return False
|
||||
|
||||
for val in value:
|
||||
if not isNullPointer(val) and not isSimObject(val):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def isSimObjectOrSequence(value):
|
||||
return isSimObject(value) or isSimObjectSequence(value)
|
||||
|
||||
baseClasses = allClasses.copy()
|
||||
baseInstances = instanceDict.copy()
|
||||
|
||||
def clear():
|
||||
global allClasses, instanceDict
|
||||
|
||||
allClasses = baseClasses.copy()
|
||||
instanceDict = baseInstances.copy()
|
||||
|
||||
# __all__ defines the list of symbols that get exported when
|
||||
# 'from config import *' is invoked. Try to keep this reasonably
|
||||
# short to avoid polluting other namespaces.
|
||||
|
||||
@@ -25,106 +25,24 @@
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Authors: Nathan Binkert
|
||||
# Steve Reinhardt
|
||||
|
||||
import os
|
||||
import sys
|
||||
# Import useful subpackages of M5, but *only* when run as an m5
|
||||
# script. This is mostly to keep backward compatibility with existing
|
||||
# scripts while allowing new SCons code to operate properly.
|
||||
|
||||
import smartdict
|
||||
|
||||
# define a MaxTick parameter
|
||||
MaxTick = 2**63 - 1
|
||||
|
||||
# define this here so we can use it right away if necessary
|
||||
|
||||
def errorURL(prefix, s):
|
||||
try:
|
||||
import zlib
|
||||
hashstr = "%x" % zlib.crc32(s)
|
||||
except:
|
||||
hashstr = "UnableToHash"
|
||||
return "For more information see: http://www.m5sim.org/%s/%s" % \
|
||||
(prefix, hashstr)
|
||||
|
||||
|
||||
# panic() should be called when something happens that should never
|
||||
# ever happen regardless of what the user does (i.e., an acutal m5
|
||||
# bug).
|
||||
def panic(fmt, *args):
|
||||
print >>sys.stderr, 'panic:', fmt % args
|
||||
print >>sys.stderr, errorURL('panic',fmt)
|
||||
sys.exit(1)
|
||||
|
||||
# fatal() should be called when the simulation cannot continue due to
|
||||
# some condition that is the user's fault (bad configuration, invalid
|
||||
# arguments, etc.) and not a simulator bug.
|
||||
def fatal(fmt, *args):
|
||||
print >>sys.stderr, 'fatal:', fmt % args
|
||||
print >>sys.stderr, errorURL('fatal',fmt)
|
||||
sys.exit(1)
|
||||
|
||||
# force scalars to one-element lists for uniformity
|
||||
def makeList(objOrList):
|
||||
if isinstance(objOrList, list):
|
||||
return objOrList
|
||||
return [objOrList]
|
||||
|
||||
# Prepend given directory to system module search path. We may not
|
||||
# need this anymore if we can structure our config library more like a
|
||||
# Python package.
|
||||
def AddToPath(path):
|
||||
# if it's a relative path and we know what directory the current
|
||||
# python script is in, make the path relative to that directory.
|
||||
if not os.path.isabs(path) and sys.path[0]:
|
||||
path = os.path.join(sys.path[0], path)
|
||||
path = os.path.realpath(path)
|
||||
# sys.path[0] should always refer to the current script's directory,
|
||||
# so place the new dir right after that.
|
||||
sys.path.insert(1, path)
|
||||
|
||||
# make a SmartDict out of the build options for our local use
|
||||
build_env = smartdict.SmartDict()
|
||||
|
||||
# make a SmartDict out of the OS environment too
|
||||
env = smartdict.SmartDict()
|
||||
env.update(os.environ)
|
||||
|
||||
# Since we have so many mutual imports in this package, we should:
|
||||
# 1. Put all intra-package imports at the *bottom* of the file, unless
|
||||
# they're absolutely needed before that (for top-level statements
|
||||
# or class attributes). Imports of "trivial" packages that don't
|
||||
# import other packages (e.g., 'smartdict') can be at the top.
|
||||
# 2. Never use 'from foo import *' on an intra-package import since
|
||||
# you can get the wrong result if foo is only partially imported
|
||||
# at the point you do that (i.e., because foo is in the middle of
|
||||
# importing *you*).
|
||||
try:
|
||||
import internal
|
||||
except ImportError:
|
||||
internal = None
|
||||
|
||||
try:
|
||||
import defines
|
||||
build_env.update(defines.buildEnv)
|
||||
except ImportError:
|
||||
defines = None
|
||||
|
||||
if internal:
|
||||
defines.compileDate = internal.core.compileDate
|
||||
for k,v in internal.core.__dict__.iteritems():
|
||||
if k.startswith('flag_'):
|
||||
setattr(defines, k[5:], v)
|
||||
import SimObject
|
||||
import core
|
||||
import objects
|
||||
import params
|
||||
import stats
|
||||
import util
|
||||
|
||||
from event import *
|
||||
from simulate import *
|
||||
from main import options, main
|
||||
import stats
|
||||
import core
|
||||
|
||||
import SimObject
|
||||
import params
|
||||
|
||||
try:
|
||||
import objects
|
||||
except ImportError:
|
||||
objects = None
|
||||
from simulate import *
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
# 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
|
||||
# Steve Reinhardt
|
||||
|
||||
import os
|
||||
|
||||
# import the m5 compile options
|
||||
import defines
|
||||
|
||||
# make a SmartDict out of the build options for our local use
|
||||
import smartdict
|
||||
build_env = smartdict.SmartDict()
|
||||
build_env.update(defines.m5_build_env)
|
||||
|
||||
# make a SmartDict out of the OS environment too
|
||||
env = smartdict.SmartDict()
|
||||
env.update(os.environ)
|
||||
|
||||
@@ -32,7 +32,7 @@ import os
|
||||
import socket
|
||||
import sys
|
||||
|
||||
from util import attrdict
|
||||
from util import attrdict, fatal
|
||||
import config
|
||||
from options import OptionParser
|
||||
|
||||
|
||||
@@ -50,13 +50,10 @@ import re
|
||||
import sys
|
||||
import time
|
||||
|
||||
import convert
|
||||
import proxy
|
||||
import ticks
|
||||
from util import *
|
||||
|
||||
import SimObject
|
||||
|
||||
def isSimObject(*args, **kwargs):
|
||||
return SimObject.isSimObject(*args, **kwargs)
|
||||
|
||||
@@ -711,32 +708,31 @@ class MetaEnum(MetaParamValue):
|
||||
|
||||
super(MetaEnum, cls).__init__(name, bases, init_dict)
|
||||
|
||||
def __str__(cls):
|
||||
return cls.__name__
|
||||
|
||||
# Generate C++ class declaration for this enum type.
|
||||
# Note that we wrap the enum in a class/struct to act as a namespace,
|
||||
# so that the enum strings can be brief w/o worrying about collisions.
|
||||
def cxx_decl(cls):
|
||||
code = "#ifndef __ENUM__%s\n" % cls
|
||||
code += '#define __ENUM__%s\n' % cls
|
||||
name = cls.__name__
|
||||
code = "#ifndef __ENUM__%s\n" % name
|
||||
code += '#define __ENUM__%s\n' % name
|
||||
code += '\n'
|
||||
code += 'namespace Enums {\n'
|
||||
code += ' enum %s {\n' % cls
|
||||
code += ' enum %s {\n' % name
|
||||
for val in cls.vals:
|
||||
code += ' %s = %d,\n' % (val, cls.map[val])
|
||||
code += ' Num_%s = %d,\n' % (cls, len(cls.vals))
|
||||
code += ' Num_%s = %d,\n' % (name, len(cls.vals))
|
||||
code += ' };\n'
|
||||
code += ' extern const char *%sStrings[Num_%s];\n' % (cls, cls)
|
||||
code += ' extern const char *%sStrings[Num_%s];\n' % (name, name)
|
||||
code += '}\n'
|
||||
code += '\n'
|
||||
code += '#endif\n'
|
||||
return code
|
||||
|
||||
def cxx_def(cls):
|
||||
code = '#include "enums/%s.hh"\n' % cls
|
||||
name = cls.__name__
|
||||
code = '#include "enums/%s.hh"\n' % name
|
||||
code += 'namespace Enums {\n'
|
||||
code += ' const char *%sStrings[Num_%s] =\n' % (cls, cls)
|
||||
code += ' const char *%sStrings[Num_%s] =\n' % (name, name)
|
||||
code += ' {\n'
|
||||
for val in cls.vals:
|
||||
code += ' "%s",\n' % val
|
||||
@@ -1170,6 +1166,15 @@ class PortParamDesc(object):
|
||||
ptype_str = 'Port'
|
||||
ptype = Port
|
||||
|
||||
baseEnums = allEnums.copy()
|
||||
baseParams = allParams.copy()
|
||||
|
||||
def clear():
|
||||
global allEnums, allParams
|
||||
|
||||
allEnums = baseEnums.copy()
|
||||
allParams = baseParams.copy()
|
||||
|
||||
__all__ = ['Param', 'VectorParam',
|
||||
'Enum', 'Bool', 'String', 'Float',
|
||||
'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16',
|
||||
@@ -1184,3 +1189,5 @@ __all__ = ['Param', 'VectorParam',
|
||||
'Time',
|
||||
'NextEthernetAddr', 'NULL',
|
||||
'Port', 'VectorPort']
|
||||
|
||||
import SimObject
|
||||
|
||||
@@ -40,6 +40,9 @@ import SimObject
|
||||
import ticks
|
||||
import objects
|
||||
|
||||
# define a MaxTick parameter
|
||||
MaxTick = 2**63 - 1
|
||||
|
||||
# The final hook to generate .ini files. Called from the user script
|
||||
# once the config is built.
|
||||
def instantiate(root):
|
||||
|
||||
@@ -41,7 +41,7 @@ def fixGlobalFrequency():
|
||||
print "Global frequency set at %d ticks per second" % int(tps)
|
||||
|
||||
def setGlobalFrequency(ticksPerSecond):
|
||||
import convert
|
||||
from m5.util import convert
|
||||
|
||||
global tps, tps_fixed
|
||||
|
||||
|
||||
@@ -48,5 +48,5 @@ def help():
|
||||
if flag == 'All':
|
||||
continue
|
||||
print " %s: %s" % (flag, flags.descriptions[flag])
|
||||
util.print_list(flags.compoundMap[flag], indent=8)
|
||||
util.printList(flags.compoundMap[flag], indent=8)
|
||||
print
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# Copyright (c) 2008 The Hewlett-Packard Development Company
|
||||
# Copyright (c) 2008-2009 The Hewlett-Packard Development Company
|
||||
# Copyright (c) 2004-2006 The Regents of The University of Michigan
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -26,14 +27,130 @@
|
||||
#
|
||||
# Authors: Nathan Binkert
|
||||
|
||||
from attrdict import attrdict, optiondict
|
||||
from code_formatter import code_formatter
|
||||
from misc import *
|
||||
from multidict import multidict
|
||||
from orderdict import orderdict
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
import convert
|
||||
import jobfile
|
||||
|
||||
def print_list(items, indent=4):
|
||||
from attrdict import attrdict, optiondict
|
||||
from code_formatter import code_formatter
|
||||
from multidict import multidict
|
||||
from orderdict import orderdict
|
||||
from smartdict import SmartDict
|
||||
|
||||
# define this here so we can use it right away if necessary
|
||||
def errorURL(prefix, s):
|
||||
try:
|
||||
import zlib
|
||||
hashstr = "%x" % zlib.crc32(s)
|
||||
except:
|
||||
hashstr = "UnableToHash"
|
||||
return "For more information see: http://www.m5sim.org/%s/%s" % \
|
||||
(prefix, hashstr)
|
||||
|
||||
# panic() should be called when something happens that should never
|
||||
# ever happen regardless of what the user does (i.e., an acutal m5
|
||||
# bug).
|
||||
def panic(fmt, *args):
|
||||
print >>sys.stderr, 'panic:', fmt % args
|
||||
print >>sys.stderr, errorURL('panic',fmt)
|
||||
sys.exit(1)
|
||||
|
||||
# fatal() should be called when the simulation cannot continue due to
|
||||
# some condition that is the user's fault (bad configuration, invalid
|
||||
# arguments, etc.) and not a simulator bug.
|
||||
def fatal(fmt, *args):
|
||||
print >>sys.stderr, 'fatal:', fmt % args
|
||||
print >>sys.stderr, errorURL('fatal',fmt)
|
||||
sys.exit(1)
|
||||
|
||||
class Singleton(type):
|
||||
def __call__(cls, *args, **kwargs):
|
||||
if hasattr(cls, '_instance'):
|
||||
return cls._instance
|
||||
|
||||
cls._instance = super(Singleton, cls).__call__(*args, **kwargs)
|
||||
return cls._instance
|
||||
|
||||
def addToPath(path):
|
||||
"""Prepend given directory to system module search path. We may not
|
||||
need this anymore if we can structure our config library more like a
|
||||
Python package."""
|
||||
|
||||
# if it's a relative path and we know what directory the current
|
||||
# python script is in, make the path relative to that directory.
|
||||
if not os.path.isabs(path) and sys.path[0]:
|
||||
path = os.path.join(sys.path[0], path)
|
||||
path = os.path.realpath(path)
|
||||
# sys.path[0] should always refer to the current script's directory,
|
||||
# so place the new dir right after that.
|
||||
sys.path.insert(1, path)
|
||||
|
||||
# Apply method to object.
|
||||
# applyMethod(obj, 'meth', <args>) is equivalent to obj.meth(<args>)
|
||||
def applyMethod(obj, meth, *args, **kwargs):
|
||||
return getattr(obj, meth)(*args, **kwargs)
|
||||
|
||||
# If the first argument is an (non-sequence) object, apply the named
|
||||
# method with the given arguments. If the first argument is a
|
||||
# sequence, apply the method to each element of the sequence (a la
|
||||
# 'map').
|
||||
def applyOrMap(objOrSeq, meth, *args, **kwargs):
|
||||
if not isinstance(objOrSeq, (list, tuple)):
|
||||
return applyMethod(objOrSeq, meth, *args, **kwargs)
|
||||
else:
|
||||
return [applyMethod(o, meth, *args, **kwargs) for o in objOrSeq]
|
||||
|
||||
def compareVersions(v1, v2):
|
||||
"""helper function: compare arrays or strings of version numbers.
|
||||
E.g., compare_version((1,3,25), (1,4,1)')
|
||||
returns -1, 0, 1 if v1 is <, ==, > v2
|
||||
"""
|
||||
def make_version_list(v):
|
||||
if isinstance(v, (list,tuple)):
|
||||
return v
|
||||
elif isinstance(v, str):
|
||||
return map(lambda x: int(re.match('\d+', x).group()), v.split('.'))
|
||||
else:
|
||||
raise TypeError
|
||||
|
||||
v1 = make_version_list(v1)
|
||||
v2 = make_version_list(v2)
|
||||
# Compare corresponding elements of lists
|
||||
for n1,n2 in zip(v1, v2):
|
||||
if n1 < n2: return -1
|
||||
if n1 > n2: return 1
|
||||
# all corresponding values are equal... see if one has extra values
|
||||
if len(v1) < len(v2): return -1
|
||||
if len(v1) > len(v2): return 1
|
||||
return 0
|
||||
|
||||
def crossproduct(items):
|
||||
if len(items) == 1:
|
||||
for i in items[0]:
|
||||
yield (i,)
|
||||
else:
|
||||
for i in items[0]:
|
||||
for j in crossproduct(items[1:]):
|
||||
yield (i,) + j
|
||||
|
||||
def flatten(items):
|
||||
while items:
|
||||
item = items.pop(0)
|
||||
if isinstance(item, (list, tuple)):
|
||||
items[0:0] = item
|
||||
else:
|
||||
yield item
|
||||
|
||||
# force scalars to one-element lists for uniformity
|
||||
def makeList(objOrList):
|
||||
if isinstance(objOrList, list):
|
||||
return objOrList
|
||||
return [objOrList]
|
||||
|
||||
def printList(items, indent=4):
|
||||
line = ' ' * indent
|
||||
for i,item in enumerate(items):
|
||||
if len(line) + len(item) > 76:
|
||||
@@ -45,3 +162,27 @@ def print_list(items, indent=4):
|
||||
else:
|
||||
line += item
|
||||
print line
|
||||
|
||||
def readCommand(cmd, **kwargs):
|
||||
"""run the command cmd, read the results and return them
|
||||
this is sorta like `cmd` in shell"""
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
|
||||
if isinstance(cmd, str):
|
||||
cmd = cmd.split()
|
||||
|
||||
no_exception = 'exception' in kwargs
|
||||
exception = kwargs.pop('exception', None)
|
||||
|
||||
kwargs.setdefault('shell', False)
|
||||
kwargs.setdefault('stdout', PIPE)
|
||||
kwargs.setdefault('stderr', STDOUT)
|
||||
kwargs.setdefault('close_fds', True)
|
||||
try:
|
||||
subp = Popen(cmd, **kwargs)
|
||||
except Exception, e:
|
||||
if no_exception:
|
||||
return exception
|
||||
raise
|
||||
|
||||
return subp.communicate()[0]
|
||||
|
||||
@@ -28,9 +28,6 @@
|
||||
|
||||
import sys
|
||||
|
||||
from attrdict import optiondict
|
||||
from misc import crossproduct
|
||||
|
||||
class Data(object):
|
||||
def __init__(self, name, desc, **kwargs):
|
||||
self.name = name
|
||||
@@ -108,7 +105,8 @@ class Data(object):
|
||||
yield key
|
||||
|
||||
def optiondict(self):
|
||||
result = optiondict()
|
||||
import m5.util
|
||||
result = m5.util.optiondict()
|
||||
for key in self:
|
||||
result[key] = self[key]
|
||||
return result
|
||||
@@ -328,7 +326,9 @@ class Configuration(Data):
|
||||
optgroups = [ g.subopts() for g in groups ]
|
||||
if not optgroups:
|
||||
return
|
||||
for options in crossproduct(optgroups):
|
||||
|
||||
import m5.util
|
||||
for options in m5.util.crossproduct(optgroups):
|
||||
for opt in options:
|
||||
cpt = opt._group._checkpoint
|
||||
if not isinstance(cpt, bool) and cpt != opt:
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
# Copyright (c) 2004-2006 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: Steve Reinhardt
|
||||
# Nathan Binkert
|
||||
|
||||
#############################
|
||||
#
|
||||
# Utility classes & methods
|
||||
#
|
||||
#############################
|
||||
|
||||
class Singleton(type):
|
||||
def __call__(cls, *args, **kwargs):
|
||||
if hasattr(cls, '_instance'):
|
||||
return cls._instance
|
||||
|
||||
cls._instance = super(Singleton, cls).__call__(*args, **kwargs)
|
||||
return cls._instance
|
||||
|
||||
# Apply method to object.
|
||||
# applyMethod(obj, 'meth', <args>) is equivalent to obj.meth(<args>)
|
||||
def applyMethod(obj, meth, *args, **kwargs):
|
||||
return getattr(obj, meth)(*args, **kwargs)
|
||||
|
||||
# If the first argument is an (non-sequence) object, apply the named
|
||||
# method with the given arguments. If the first argument is a
|
||||
# sequence, apply the method to each element of the sequence (a la
|
||||
# 'map').
|
||||
def applyOrMap(objOrSeq, meth, *args, **kwargs):
|
||||
if not isinstance(objOrSeq, (list, tuple)):
|
||||
return applyMethod(objOrSeq, meth, *args, **kwargs)
|
||||
else:
|
||||
return [applyMethod(o, meth, *args, **kwargs) for o in objOrSeq]
|
||||
|
||||
def crossproduct(items):
|
||||
if not isinstance(items, (list, tuple)):
|
||||
raise AttributeError, 'crossproduct works only on sequences'
|
||||
|
||||
if not items:
|
||||
yield None
|
||||
return
|
||||
|
||||
current = items[0]
|
||||
remainder = items[1:]
|
||||
|
||||
if not hasattr(current, '__iter__'):
|
||||
current = [ current ]
|
||||
|
||||
for item in current:
|
||||
for rem in crossproduct(remainder):
|
||||
data = [ item ]
|
||||
if rem:
|
||||
data += rem
|
||||
yield data
|
||||
|
||||
def flatten(items):
|
||||
if not isinstance(items, (list, tuple)):
|
||||
yield items
|
||||
return
|
||||
|
||||
for item in items:
|
||||
for flat in flatten(item):
|
||||
yield flat
|
||||
Reference in New Issue
Block a user