config: Make parameter conversion handle integers in other bases.

Python's float() function/type can't handle hexadecimal notation, but
int() can. Since there are also cases where converting to a float and
then back to an int (or long) can cause rounding error, this change
splits toFloat and toInteger apart and makes them call a worker
function which accepts a conversion function which does the work of
converting a numeric string into an actual number.

in the case of toFloat, it still uses the standard float(), and in the
case of toInteger it uses a lambda which wraps int(x, 0).

Change-Id: Ic46cf4ae86b7eba6f55d731d1b25e3f84b8bb64c
Reviewed-on: https://gem5-review.googlesource.com/c/16504
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
diff --git a/src/python/m5/util/convert.py b/src/python/m5/util/convert.py
index 7b9cb38..acd1a24 100644
--- a/src/python/m5/util/convert.py
+++ b/src/python/m5/util/convert.py
@@ -93,26 +93,32 @@
 
 
 # memory size configuration stuff
-def toFloat(value, target_type='float', units=None, prefixes=[]):
+def toNum(value, target_type, units, prefixes, converter):
     assertStr(value)
 
+    def convert(val):
+        try:
+            return converter(val)
+        except ValueError:
+            raise ValueError(
+                "cannot convert '%s' to %s" % (value, target_type))
+
     if units and not value.endswith(units):
         units = None
     if not units:
-        try:
-            return float(value)
-        except ValueError:
-            raise ValueError("cannot convert '%s' to %s" % \
-                             (value, target_type))
+        return convert(value)
 
     value = value[:-len(units)]
 
     prefix = next((p for p in prefixes.keys() if value.endswith(p)), None)
     if not prefix:
-        return float(value)
+        return convert(value)
     value = value[:-len(prefix)]
 
-    return float(value) * prefixes[prefix]
+    return convert(value) * prefixes[prefix]
+
+def toFloat(value, target_type='float', units=None, prefixes=[]):
+    return toNum(value, target_type, units, prefixes, float)
 
 def toMetricFloat(value, target_type='float', units=None):
     return toFloat(value, target_type, units, metric_prefixes)
@@ -121,13 +127,8 @@
     return toFloat(value, target_type, units, binary_prefixes)
 
 def toInteger(value, target_type='integer', units=None, prefixes=[]):
-    value = toFloat(value, target_type, units, prefixes)
-    result = long(value)
-    if value != result:
-        raise ValueError("cannot convert '%s' to integer %s" % \
-                (value, target_type))
-
-    return result
+    intifier = lambda x: int(x, 0)
+    return toNum(value, target_type, units, prefixes, intifier)
 
 def toMetricInteger(value, target_type='integer', units=None):
     return toInteger(value, target_type, units, metric_prefixes)