From 34a9b8628f2a0b001a57deed73f887c92d5ffef6 Mon Sep 17 00:00:00 2001
From: Gabe Black <gabeblack@google.com>
Date: Thu, 27 Sep 2018 01:20:28 -0700
Subject: systemc: Add a non-standard sc_time constructor and from_string.

The sc_time constructor was being called, but because of implicit type
conversions, a const char * was being treated as a bool and totally
unrelated constructor was being called.

This change adds and implements the missing but non-standard
constructor. It also implements the from_string function which uses
that constructor.

Change-Id: I21e7e40fd1a8d1c579b1abdc2036d016501f510c
Reviewed-on: https://gem5-review.googlesource.com/c/13191
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
---
 src/systemc/core/sc_time.cc     | 34 ++++++++++++++++++++++++++++++++--
 src/systemc/core/time.cc        |  9 +++++++++
 src/systemc/core/time.hh        |  1 +
 src/systemc/ext/core/sc_time.hh |  3 +++
 4 files changed, 45 insertions(+), 2 deletions(-)

(limited to 'src')

diff --git a/src/systemc/core/sc_time.cc b/src/systemc/core/sc_time.cc
index acc3c0805..88058a733 100644
--- a/src/systemc/core/sc_time.cc
+++ b/src/systemc/core/sc_time.cc
@@ -153,6 +153,25 @@ sc_time::sc_time(const sc_time &t)
     val = t.val;
 }
 
+sc_time::sc_time(double d, const char *unit)
+{
+    sc_time_unit tu;
+    for (tu = SC_FS; tu <= SC_SEC; tu = (sc_time_unit)(tu + 1)) {
+        if (strcmp(unit, sc_gem5::TimeUnitNames[tu]) == 0 ||
+            strcmp(unit, sc_gem5::TimeUnitConstantNames[tu]) == 0) {
+            break;
+        }
+    }
+
+    if (tu > SC_SEC) {
+        SC_REPORT_ERROR("(E567) sc_time conversion failed",
+                "invalid unit given");
+        val = 0;
+        return;
+    }
+    set(this, d, tu);
+}
+
 sc_time::sc_time(double d, bool scale)
 {
     double scaler = scale ? defaultUnit : SimClock::Float::Hz;
@@ -288,8 +307,19 @@ sc_time::from_seconds(double d)
 sc_time
 sc_time::from_string(const char *str)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-    return sc_time();
+    char *end = nullptr;
+
+    double d = str ? std::strtod(str, &end) : 0.0;
+    if (str == end || d < 0.0) {
+        SC_REPORT_ERROR("(E567) sc_time conversion failed",
+                "invalid value given");
+        return SC_ZERO_TIME;
+    }
+
+    while (*end && std::isspace(*end))
+        end++;
+
+    return sc_time(d, end);
 }
 
 const sc_time
diff --git a/src/systemc/core/time.cc b/src/systemc/core/time.cc
index 4c9086447..587d8cbf4 100644
--- a/src/systemc/core/time.cc
+++ b/src/systemc/core/time.cc
@@ -43,6 +43,15 @@ const char *TimeUnitNames[] = {
     [::sc_core::SC_SEC] = "s"
 };
 
+const char *TimeUnitConstantNames[] = {
+    [::sc_core::SC_FS] = "SC_FS",
+    [::sc_core::SC_PS] = "SC_PS",
+    [::sc_core::SC_NS] = "SC_NS",
+    [::sc_core::SC_US] = "SC_US",
+    [::sc_core::SC_MS] = "SC_MS",
+    [::sc_core::SC_SEC] = "SC_SEC"
+};
+
 double TimeUnitScale[] = {
     [::sc_core::SC_FS] = 1.0e-15,
     [::sc_core::SC_PS] = 1.0e-12,
diff --git a/src/systemc/core/time.hh b/src/systemc/core/time.hh
index 4357fbd91..dca965e79 100644
--- a/src/systemc/core/time.hh
+++ b/src/systemc/core/time.hh
@@ -36,6 +36,7 @@ namespace sc_gem5
 {
 
 extern const char *TimeUnitNames[];
+extern const char *TimeUnitConstantNames[];
 extern double TimeUnitScale[];
 extern Tick TimeUnitFrequency[];
 
diff --git a/src/systemc/ext/core/sc_time.hh b/src/systemc/ext/core/sc_time.hh
index 0a31a655a..d2b1e985d 100644
--- a/src/systemc/ext/core/sc_time.hh
+++ b/src/systemc/ext/core/sc_time.hh
@@ -55,6 +55,9 @@ class sc_time
     sc_time(double, sc_time_unit);
     sc_time(const sc_time &);
 
+    // Nonstandard
+    sc_time(double, const char *);
+
     // Deprecated
     sc_time(double, bool);
     sc_time(sc_dt::uint64, bool);
-- 
cgit v1.2.3