config: Cleanup .json config file generation
This patch 'completes' .json config files generation by adding in the SimObject references and String-valued parameters not currently printed. TickParamValues are also changed to print in the same tick-value format as in .ini files. This allows .json files to describe a system as fully as the .ini files currently do. This patch adds a new function config_value (which mirrors ini_str) to each ParamValue and to SimObject. This function can then be explicitly changed to give different .json and .ini printing behaviour rather than being written in terms of ini_str.
This commit is contained in:
parent
41fc8a573e
commit
7329c0e20b
2 changed files with 42 additions and 13 deletions
|
@ -955,6 +955,9 @@ class SimObject(object):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.path()
|
return self.path()
|
||||||
|
|
||||||
|
def config_value(self):
|
||||||
|
return self.path()
|
||||||
|
|
||||||
def ini_str(self):
|
def ini_str(self):
|
||||||
return self.path()
|
return self.path()
|
||||||
|
|
||||||
|
@ -1077,18 +1080,7 @@ class SimObject(object):
|
||||||
for param in sorted(self._params.keys()):
|
for param in sorted(self._params.keys()):
|
||||||
value = self._values.get(param)
|
value = self._values.get(param)
|
||||||
if value != None:
|
if value != None:
|
||||||
try:
|
d[param] = value.config_value()
|
||||||
# Use native type for those supported by JSON and
|
|
||||||
# strings for everything else. skipkeys=True seems
|
|
||||||
# to not work as well as one would hope
|
|
||||||
if type(self._values[param].value) in \
|
|
||||||
[str, unicode, int, long, float, bool, None]:
|
|
||||||
d[param] = self._values[param].value
|
|
||||||
else:
|
|
||||||
d[param] = str(self._values[param])
|
|
||||||
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
for n in sorted(self._children.keys()):
|
for n in sorted(self._children.keys()):
|
||||||
child = self._children[n]
|
child = self._children[n]
|
||||||
|
|
|
@ -114,6 +114,12 @@ class ParamValue(object):
|
||||||
def ini_str(self):
|
def ini_str(self):
|
||||||
return str(self)
|
return str(self)
|
||||||
|
|
||||||
|
# default for printing to .json file is regular string conversion.
|
||||||
|
# will be overridden in some cases, mostly to use native Python
|
||||||
|
# types where there are similar JSON types
|
||||||
|
def config_value(self):
|
||||||
|
return str(self)
|
||||||
|
|
||||||
# allows us to blithely call unproxy() on things without checking
|
# allows us to blithely call unproxy() on things without checking
|
||||||
# if they're really proxies or not
|
# if they're really proxies or not
|
||||||
def unproxy(self, base):
|
def unproxy(self, base):
|
||||||
|
@ -220,6 +226,9 @@ class VectorParamValue(list):
|
||||||
raise AttributeError, \
|
raise AttributeError, \
|
||||||
"Not allowed to set %s on '%s'" % (attr, type(self).__name__)
|
"Not allowed to set %s on '%s'" % (attr, type(self).__name__)
|
||||||
|
|
||||||
|
def config_value(self):
|
||||||
|
return [v.config_value() for v in self]
|
||||||
|
|
||||||
def ini_str(self):
|
def ini_str(self):
|
||||||
return ' '.join([v.ini_str() for v in self])
|
return ' '.join([v.ini_str() for v in self])
|
||||||
|
|
||||||
|
@ -488,6 +497,9 @@ class NumericParamValue(ParamValue):
|
||||||
newobj._check()
|
newobj._check()
|
||||||
return newobj
|
return newobj
|
||||||
|
|
||||||
|
def config_value(self):
|
||||||
|
return self.value
|
||||||
|
|
||||||
# Metaclass for bounds-checked integer parameters. See CheckedInt.
|
# Metaclass for bounds-checked integer parameters. See CheckedInt.
|
||||||
class CheckedIntType(MetaParamValue):
|
class CheckedIntType(MetaParamValue):
|
||||||
def __init__(cls, name, bases, dict):
|
def __init__(cls, name, bases, dict):
|
||||||
|
@ -598,6 +610,9 @@ class Float(ParamValue, float):
|
||||||
def getValue(self):
|
def getValue(self):
|
||||||
return float(self.value)
|
return float(self.value)
|
||||||
|
|
||||||
|
def config_value(self):
|
||||||
|
return self
|
||||||
|
|
||||||
class MemorySize(CheckedInt):
|
class MemorySize(CheckedInt):
|
||||||
cxx_type = 'uint64_t'
|
cxx_type = 'uint64_t'
|
||||||
ex_str = '512MB'
|
ex_str = '512MB'
|
||||||
|
@ -765,6 +780,9 @@ class Bool(ParamValue):
|
||||||
return 'true'
|
return 'true'
|
||||||
return 'false'
|
return 'false'
|
||||||
|
|
||||||
|
def config_value(self):
|
||||||
|
return self.value
|
||||||
|
|
||||||
def IncEthernetAddr(addr, val = 1):
|
def IncEthernetAddr(addr, val = 1):
|
||||||
bytes = map(lambda x: int(x, 16), addr.split(':'))
|
bytes = map(lambda x: int(x, 16), addr.split(':'))
|
||||||
bytes[5] += val
|
bytes[5] += val
|
||||||
|
@ -1045,7 +1063,7 @@ class IpWithPort(IpAddress):
|
||||||
return IpWithPort(self.ip, self.port)
|
return IpWithPort(self.ip, self.port)
|
||||||
|
|
||||||
time_formats = [ "%a %b %d %H:%M:%S %Z %Y",
|
time_formats = [ "%a %b %d %H:%M:%S %Z %Y",
|
||||||
"%a %b %d %H:%M:%S %Z %Y",
|
"%a %b %d %H:%M:%S %Y",
|
||||||
"%Y/%m/%d %H:%M:%S",
|
"%Y/%m/%d %H:%M:%S",
|
||||||
"%Y/%m/%d %H:%M",
|
"%Y/%m/%d %H:%M",
|
||||||
"%Y/%m/%d",
|
"%Y/%m/%d",
|
||||||
|
@ -1133,6 +1151,7 @@ class Time(ParamValue):
|
||||||
return str(self)
|
return str(self)
|
||||||
|
|
||||||
def get_config_as_dict(self):
|
def get_config_as_dict(self):
|
||||||
|
assert false
|
||||||
return str(self)
|
return str(self)
|
||||||
|
|
||||||
# Enumerated types are a little more complex. The user specifies the
|
# Enumerated types are a little more complex. The user specifies the
|
||||||
|
@ -1352,6 +1371,9 @@ class Latency(TickParamValue):
|
||||||
value = ticks.fromSeconds(self.value)
|
value = ticks.fromSeconds(self.value)
|
||||||
return long(value)
|
return long(value)
|
||||||
|
|
||||||
|
def config_value(self):
|
||||||
|
return self.getValue()
|
||||||
|
|
||||||
# convert latency to ticks
|
# convert latency to ticks
|
||||||
def ini_str(self):
|
def ini_str(self):
|
||||||
return '%d' % self.getValue()
|
return '%d' % self.getValue()
|
||||||
|
@ -1392,6 +1414,9 @@ class Frequency(TickParamValue):
|
||||||
value = ticks.fromSeconds(1.0 / self.value)
|
value = ticks.fromSeconds(1.0 / self.value)
|
||||||
return long(value)
|
return long(value)
|
||||||
|
|
||||||
|
def config_value(self):
|
||||||
|
return self.getValue()
|
||||||
|
|
||||||
def ini_str(self):
|
def ini_str(self):
|
||||||
return '%d' % self.getValue()
|
return '%d' % self.getValue()
|
||||||
|
|
||||||
|
@ -1429,6 +1454,9 @@ class Clock(TickParamValue):
|
||||||
def getValue(self):
|
def getValue(self):
|
||||||
return self.period.getValue()
|
return self.period.getValue()
|
||||||
|
|
||||||
|
def config_value(self):
|
||||||
|
return self.period.config_value()
|
||||||
|
|
||||||
def ini_str(self):
|
def ini_str(self):
|
||||||
return self.period.ini_str()
|
return self.period.ini_str()
|
||||||
|
|
||||||
|
@ -1485,6 +1513,9 @@ class NetworkBandwidth(float,ParamValue):
|
||||||
def ini_str(self):
|
def ini_str(self):
|
||||||
return '%f' % self.getValue()
|
return '%f' % self.getValue()
|
||||||
|
|
||||||
|
def config_value(self):
|
||||||
|
return '%f' % self.getValue()
|
||||||
|
|
||||||
class MemoryBandwidth(float,ParamValue):
|
class MemoryBandwidth(float,ParamValue):
|
||||||
cxx_type = 'float'
|
cxx_type = 'float'
|
||||||
ex_str = "1GB/s"
|
ex_str = "1GB/s"
|
||||||
|
@ -1512,6 +1543,9 @@ class MemoryBandwidth(float,ParamValue):
|
||||||
def ini_str(self):
|
def ini_str(self):
|
||||||
return '%f' % self.getValue()
|
return '%f' % self.getValue()
|
||||||
|
|
||||||
|
def config_value(self):
|
||||||
|
return '%f' % self.getValue()
|
||||||
|
|
||||||
#
|
#
|
||||||
# "Constants"... handy aliases for various values.
|
# "Constants"... handy aliases for various values.
|
||||||
#
|
#
|
||||||
|
@ -1541,6 +1575,9 @@ class NullSimObject(object):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Null'
|
return 'Null'
|
||||||
|
|
||||||
|
def config_value(self):
|
||||||
|
return None
|
||||||
|
|
||||||
def getValue(self):
|
def getValue(self):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue