summaryrefslogtreecommitdiff
path: root/src/python
diff options
context:
space:
mode:
authorDerek Hower <drh5@cs.wisc.edu>2010-01-19 15:48:12 -0600
committerDerek Hower <drh5@cs.wisc.edu>2010-01-19 15:48:12 -0600
commit279f179babc9e5663156777c533c06edc91bce9a (patch)
treee6718ee514cc81678491b50562ce8c463c0b20fd /src/python
parent5aa104e072eb20f6aca49b169521b0c2da33c844 (diff)
parent295516a590b6e47c9a881f193027447e500c749c (diff)
downloadgem5-279f179babc9e5663156777c533c06edc91bce9a.tar.xz
merge
Diffstat (limited to 'src/python')
-rw-r--r--src/python/SConscript5
-rw-r--r--src/python/m5/SimObject.py79
-rw-r--r--src/python/m5/__init__.py102
-rw-r--r--src/python/m5/environment.py43
-rw-r--r--src/python/m5/main.py2
-rw-r--r--src/python/m5/params.py39
-rw-r--r--src/python/m5/simulate.py3
-rw-r--r--src/python/m5/ticks.py2
-rw-r--r--src/python/m5/trace.py2
-rw-r--r--src/python/m5/util/__init__.py149
-rw-r--r--src/python/m5/util/attrdict.py12
-rw-r--r--src/python/m5/util/code_formatter.py5
-rw-r--r--src/python/m5/util/convert.py (renamed from src/python/m5/convert.py)0
-rw-r--r--src/python/m5/util/grammar.py4
-rw-r--r--src/python/m5/util/jobfile.py10
-rw-r--r--src/python/m5/util/misc.py87
-rw-r--r--src/python/m5/util/smartdict.py (renamed from src/python/m5/smartdict.py)0
17 files changed, 253 insertions, 291 deletions
diff --git a/src/python/SConscript b/src/python/SConscript
index bb892f376..935986a12 100644
--- a/src/python/SConscript
+++ b/src/python/SConscript
@@ -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')
diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py
index 8ef22be4e..0e0ffaea9 100644
--- a/src/python/m5/SimObject.py
+++ b/src/python/m5/SimObject.py
@@ -31,47 +31,24 @@ import math
import sys
import types
-import proxy
-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
+try:
+ import pydot
+except:
+ pydot = False
-def isSimObjectOrSequence(value):
- return isSimObject(value) or isSimObjectSequence(value)
+import m5
+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.
diff --git a/src/python/m5/__init__.py b/src/python/m5/__init__.py
index c3512cd0d..9f9459ae8 100644
--- a/src/python/m5/__init__.py
+++ b/src/python/m5/__init__.py
@@ -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 *
diff --git a/src/python/m5/environment.py b/src/python/m5/environment.py
deleted file mode 100644
index bea0bc1d0..000000000
--- a/src/python/m5/environment.py
+++ /dev/null
@@ -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)
-
diff --git a/src/python/m5/main.py b/src/python/m5/main.py
index 2a308ff09..29f8cc976 100644
--- a/src/python/m5/main.py
+++ b/src/python/m5/main.py
@@ -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
diff --git a/src/python/m5/params.py b/src/python/m5/params.py
index edd78fa28..cf64070c5 100644
--- a/src/python/m5/params.py
+++ b/src/python/m5/params.py
@@ -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)
@@ -96,6 +93,8 @@ class ParamValue(object):
# Regular parameter description.
class ParamDesc(object):
+ file_ext = 'ptype'
+
def __init__(self, ptype_str, ptype, *args, **kwargs):
self.ptype_str = ptype_str
# remember ptype only if it is provided
@@ -130,7 +129,7 @@ class ParamDesc(object):
def __getattr__(self, attr):
if attr == 'ptype':
ptype = SimObject.allClasses[self.ptype_str]
- assert issubclass(ptype, SimObject.SimObject)
+ assert isSimObjectClass(ptype)
self.ptype = ptype
return ptype
@@ -185,6 +184,8 @@ class SimObjVector(VectorParamValue):
v.print_ini(ini_file)
class VectorParamDesc(ParamDesc):
+ file_ext = 'vptype'
+
# Convert assigned value to appropriate type. If the RHS is not a
# list or tuple, it generates a single-element list.
def convert(self, value):
@@ -711,32 +712,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 +1170,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 +1193,5 @@ __all__ = ['Param', 'VectorParam',
'Time',
'NextEthernetAddr', 'NULL',
'Port', 'VectorPort']
+
+import SimObject
diff --git a/src/python/m5/simulate.py b/src/python/m5/simulate.py
index 45992fe85..092bd0339 100644
--- a/src/python/m5/simulate.py
+++ b/src/python/m5/simulate.py
@@ -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):
diff --git a/src/python/m5/ticks.py b/src/python/m5/ticks.py
index 91834c9c8..181a65eba 100644
--- a/src/python/m5/ticks.py
+++ b/src/python/m5/ticks.py
@@ -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
diff --git a/src/python/m5/trace.py b/src/python/m5/trace.py
index 17aa6196c..db239040a 100644
--- a/src/python/m5/trace.py
+++ b/src/python/m5/trace.py
@@ -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
diff --git a/src/python/m5/util/__init__.py b/src/python/m5/util/__init__.py
index 3930c8b6f..7a674dd2d 100644
--- a/src/python/m5/util/__init__.py
+++ b/src/python/m5/util/__init__.py
@@ -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
+import os
+import re
+import sys
+
+import convert
+import jobfile
+
from attrdict import attrdict, optiondict
from code_formatter import code_formatter
-from misc import *
from multidict import multidict
from orderdict import orderdict
-import jobfile
+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)
-def print_list(items, indent=4):
+# 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]
diff --git a/src/python/m5/util/attrdict.py b/src/python/m5/util/attrdict.py
index 0b30258b9..8f7d59698 100644
--- a/src/python/m5/util/attrdict.py
+++ b/src/python/m5/util/attrdict.py
@@ -45,6 +45,12 @@ class attrdict(dict):
return self.__delitem__(attr)
return super(attrdict, self).__delattr__(attr)
+ def __getstate__(self):
+ return dict(self)
+
+ def __setstate__(self, state):
+ self.update(state)
+
class multiattrdict(attrdict):
"""Wrap attrdict so that nested attribute accesses automatically create
nested dictionaries."""
@@ -52,7 +58,7 @@ class multiattrdict(attrdict):
try:
return super(multiattrdict, self).__getattr__(attr)
except AttributeError:
- d = optiondict()
+ d = multiattrdict()
setattr(self, attr, d)
return d
@@ -80,8 +86,12 @@ if __name__ == '__main__':
print dir(x)
print(x)
+ print
+ print "multiattrdict"
x = multiattrdict()
+ x.x.x.x = 9
x.y.z = 9
print x
print x.y
print x.y.z
+ print x.z.z
diff --git a/src/python/m5/util/code_formatter.py b/src/python/m5/util/code_formatter.py
index 919a6423b..396fe0e52 100644
--- a/src/python/m5/util/code_formatter.py
+++ b/src/python/m5/util/code_formatter.py
@@ -24,6 +24,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+import __builtin__
import inspect
import os
import re
@@ -64,8 +65,8 @@ class lookup(object):
if self.formatter.globals and item in self.frame.f_globals:
return self.frame.f_globals[item]
- if item in __builtins__:
- return __builtins__[item]
+ if item in __builtin__.__dict__:
+ return __builtin__.__dict__[item]
try:
item = int(item)
diff --git a/src/python/m5/convert.py b/src/python/m5/util/convert.py
index bb9e3e1f1..bb9e3e1f1 100644
--- a/src/python/m5/convert.py
+++ b/src/python/m5/util/convert.py
diff --git a/src/python/m5/util/grammar.py b/src/python/m5/util/grammar.py
index 93c2c84c4..ab5f35868 100644
--- a/src/python/m5/util/grammar.py
+++ b/src/python/m5/util/grammar.py
@@ -55,6 +55,7 @@ class Tokenizer(object):
break
yield tok
self.input = _input()
+ self.lexer = lexer
def next(self):
return self.input.next()
@@ -68,6 +69,9 @@ class Tokenizer(object):
except StopIteration:
return None
+ def __getattr__(self, attr):
+ return getattr(self.lexer, attr)
+
class Grammar(object):
def __init__(self, output=None, debug=False):
self.yacc_args = {}
diff --git a/src/python/m5/util/jobfile.py b/src/python/m5/util/jobfile.py
index c830895f6..9c59778e5 100644
--- a/src/python/m5/util/jobfile.py
+++ b/src/python/m5/util/jobfile.py
@@ -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:
diff --git a/src/python/m5/util/misc.py b/src/python/m5/util/misc.py
deleted file mode 100644
index 094e3ed9a..000000000
--- a/src/python/m5/util/misc.py
+++ /dev/null
@@ -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
diff --git a/src/python/m5/smartdict.py b/src/python/m5/util/smartdict.py
index d85dbd517..d85dbd517 100644
--- a/src/python/m5/smartdict.py
+++ b/src/python/m5/util/smartdict.py