config: Cleanup .json config file generation
authorAndrew Bardsley <Andrew.Bardsley@arm.com>
Sat, 20 Sep 2014 21:17:42 +0000 (17:17 -0400)
committerAndrew Bardsley <Andrew.Bardsley@arm.com>
Sat, 20 Sep 2014 21:17:42 +0000 (17:17 -0400)
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.

src/python/m5/SimObject.py
src/python/m5/params.py

index 81923ac7c6c647b9e68c6b3f26efff367b0e7e99..9f4c2c15533fa09ac422b7fd9a224b503f07e54c 100644 (file)
@@ -955,6 +955,9 @@ class SimObject(object):
     def __str__(self):
         return self.path()
 
+    def config_value(self):
+        return self.path()
+
     def ini_str(self):
         return self.path()
 
@@ -1077,18 +1080,7 @@ class SimObject(object):
         for param in sorted(self._params.keys()):
             value = self._values.get(param)
             if value != None:
-                try:
-                    # 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
+                d[param] = value.config_value()
 
         for n in sorted(self._children.keys()):
             child = self._children[n]
index db10a818f4ad297d7e729ce70cfcb0d5586e5b23..cf576453033ab45565e8fdbc6a5377c2ac139bd1 100644 (file)
@@ -114,6 +114,12 @@ class ParamValue(object):
     def ini_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
     # if they're really proxies or not
     def unproxy(self, base):
@@ -220,6 +226,9 @@ class VectorParamValue(list):
         raise AttributeError, \
               "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):
         return ' '.join([v.ini_str() for v in self])
 
@@ -488,6 +497,9 @@ class NumericParamValue(ParamValue):
         newobj._check()
         return newobj
 
+    def config_value(self):
+        return self.value
+
 # Metaclass for bounds-checked integer parameters.  See CheckedInt.
 class CheckedIntType(MetaParamValue):
     def __init__(cls, name, bases, dict):
@@ -598,6 +610,9 @@ class Float(ParamValue, float):
     def getValue(self):
         return float(self.value)
 
+    def config_value(self):
+        return self
+
 class MemorySize(CheckedInt):
     cxx_type = 'uint64_t'
     ex_str = '512MB'
@@ -765,6 +780,9 @@ class Bool(ParamValue):
             return 'true'
         return 'false'
 
+    def config_value(self):
+        return self.value
+
 def IncEthernetAddr(addr, val = 1):
     bytes = map(lambda x: int(x, 16), addr.split(':'))
     bytes[5] += val
@@ -1045,7 +1063,7 @@ class IpWithPort(IpAddress):
         return IpWithPort(self.ip, self.port)
 
 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",
                  "%Y/%m/%d",
@@ -1133,6 +1151,7 @@ class Time(ParamValue):
         return str(self)
 
     def get_config_as_dict(self):
+        assert false
         return str(self)
 
 # Enumerated types are a little more complex.  The user specifies the
@@ -1352,6 +1371,9 @@ class Latency(TickParamValue):
             value = ticks.fromSeconds(self.value)
         return long(value)
 
+    def config_value(self):
+        return self.getValue()
+
     # convert latency to ticks
     def ini_str(self):
         return '%d' % self.getValue()
@@ -1392,6 +1414,9 @@ class Frequency(TickParamValue):
             value = ticks.fromSeconds(1.0 / self.value)
         return long(value)
 
+    def config_value(self):
+        return self.getValue()
+
     def ini_str(self):
         return '%d' % self.getValue()
 
@@ -1429,6 +1454,9 @@ class Clock(TickParamValue):
     def getValue(self):
         return self.period.getValue()
 
+    def config_value(self):
+        return self.period.config_value()
+
     def ini_str(self):
         return self.period.ini_str()
 
@@ -1485,6 +1513,9 @@ class NetworkBandwidth(float,ParamValue):
     def ini_str(self):
         return '%f' % self.getValue()
 
+    def config_value(self):
+        return '%f' % self.getValue()
+
 class MemoryBandwidth(float,ParamValue):
     cxx_type = 'float'
     ex_str = "1GB/s"
@@ -1512,6 +1543,9 @@ class MemoryBandwidth(float,ParamValue):
     def ini_str(self):
         return '%f' % self.getValue()
 
+    def config_value(self):
+        return '%f' % self.getValue()
+
 #
 # "Constants"... handy aliases for various values.
 #
@@ -1541,6 +1575,9 @@ class NullSimObject(object):
     def __str__(self):
         return 'Null'
 
+    def config_value(self):
+        return None
+
     def getValue(self):
         return None