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:
Andrew Bardsley 2014-09-20 17:17:42 -04:00
parent 41fc8a573e
commit 7329c0e20b
2 changed files with 42 additions and 13 deletions

View file

@ -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]

View file

@ -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