First steps toward getting full system to work with
[gem5.git] / sim / param.cc
index 4f9d0a577e57271dfa387e7b0e3f6a275a2926fe..8998d7d7722530bf3a308a3c182d8d3ea09b8add 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002-2004 The Regents of The University of Michigan
+ * Copyright (c) 2002-2005 The Regents of The University of Michigan
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  */
 
 #include <algorithm>
+#include <cassert>
 #include <list>
 #include <string>
 #include <vector>
-#include <stdio.h>     // for sscanf()
 
-#include <assert.h>
-
-#include "sim/param.hh"
-#include "sim/sim_object.hh"
 #include "base/inifile.hh"
-#include "sim/configfile.hh"
-#include "sim/config_node.hh"
 #include "base/misc.hh"
+#include "base/range.hh"
 #include "base/str.hh"
 #include "base/trace.hh"
+#include "sim/config_node.hh"
+#include "sim/configfile.hh"
+#include "sim/param.hh"
+#include "sim/sim_object.hh"
 
 using namespace std;
 
@@ -180,6 +179,22 @@ parseParam(const string &s, string &value)
     return true;
 }
 
+template <>
+bool
+parseParam(const string &s, Range<uint32_t> &value)
+{
+    value = s;
+    return value.valid();
+}
+
+template <>
+bool
+parseParam(const string &s, Range<uint64_t> &value)
+{
+    value = s;
+    return value.valid();
+}
+
 //
 // End of parseParam/showParam definitions.  Now we move on to
 // incorporate them into the Param/VectorParam parse() and showValue()
@@ -211,6 +226,11 @@ template <class T>
 void
 VectorParam<T>::parse(const string &s)
 {
+    if (s.empty()) {
+        wasSet = true;
+        return;
+    }
+
     vector<string> tokens;
 
     tokenize(tokens, s, ' ');
@@ -282,8 +302,8 @@ template void Param<type>::parse(const string &);                   \
 template void VectorParam<type>::parse(const string &);                        \
 template void Param<type>::showValue(ostream &) const;                 \
 template void VectorParam<type>::showValue(ostream &) const;           \
-void Param<type>::showType(ostream &os) const { os << typestr; }       \
-void VectorParam<type>::showType(ostream &os) const {                  \
+template <> void Param<type>::showType(ostream &os) const { os << typestr; }   \
+template <> void VectorParam<type>::showType(ostream &os) const {                      \
     os << "vector of " << typestr;                                     \
 }
 #endif
@@ -305,6 +325,9 @@ INSTANTIATE_PARAM_TEMPLATES(double, "double")
 INSTANTIATE_PARAM_TEMPLATES(bool, "bool")
 INSTANTIATE_PARAM_TEMPLATES(string, "string")
 
+INSTANTIATE_PARAM_TEMPLATES(Range<uint64_t>, "uint64 range")
+INSTANTIATE_PARAM_TEMPLATES(Range<uint32_t>, "uint32 range")
+
 #undef INSTANTIATE_PARAM_TEMPLATES
 
 //
@@ -417,6 +440,11 @@ EnumVectorParam<Map>::parse(const string &s)
 {
     vector<string> tokens;
 
+    if (s.empty()) {
+        wasSet = true;
+        return;
+    }
+
     tokenize(tokens, s, ' ');
 
     value.resize(tokens.size());
@@ -469,11 +497,11 @@ EnumVectorParam<Map>::showType(ostream &os) const
     showEnumType(os, map, num_values);
 }
 
-template EnumParam<const char *>;
-template EnumVectorParam<const char *>;
+template class EnumParam<const char *>;
+template class EnumVectorParam<const char *>;
 
-template EnumParam<EnumParamMap>;
-template EnumVectorParam<EnumParamMap>;
+template class EnumParam<EnumParamMap>;
+template class EnumVectorParam<EnumParamMap>;
 
 ////////////////////////////////////////////////////////////////////////
 //
@@ -555,15 +583,27 @@ SimObjectBaseParam::parse(const string &s, vector<SimObject *>&value)
 
 list<ParamContext *> *ParamContext::ctxList = NULL;
 
-ParamContext::ParamContext(const string &_iniSection, bool noAutoParse)
+ParamContext::ParamContext(const string &_iniSection, InitPhase _initPhase)
     : iniFilePtr(NULL),        // initialized on call to parseParams()
-      iniSection(_iniSection), paramList(NULL)
+      iniSection(_iniSection), paramList(NULL),
+      initPhase(_initPhase)
 {
-    if (!noAutoParse) {
+    // Put this context on global list for initialization
+    if (initPhase != NoAutoInit) {
         if (ctxList == NULL)
             ctxList = new list<ParamContext *>();
 
-        (*ctxList).push_back(this);
+        // keep list sorted by ascending initPhase values
+        list<ParamContext *>::iterator i = ctxList->begin();
+        list<ParamContext *>::iterator end = ctxList->end();
+        for (; i != end; ++i) {
+            if (initPhase <= (*i)->initPhase) {
+                // found where we want to insert
+                break;
+            }
+        }
+        // (fall through case: insert at end)
+        ctxList->insert(i, this);
     }
 }
 
@@ -585,9 +625,8 @@ ParamContext::parseParams(IniFile &iniFile)
     for (i = getParamList()->begin(); i != getParamList()->end(); ++i) {
         string string_value;
 
-        if (iniFile.findDefault(iniSection, (*i)->name, string_value)) {
+        if (iniFile.find(iniSection, (*i)->name, string_value))
             (*i)->parse(string_value);
-        }
     }
 }
 
@@ -663,18 +702,8 @@ ParamContext::printErrorProlog(ostream &os)
 // SimObjectBuilder objects, which return non-NULL for configNode()).
 //
 SimObject *
-ParamContext::resolveSimObject(const string &_name)
-{
-    // look for a colon
-    string::size_type i = _name.find(':');
-    string name = _name;
-    if (i != string::npos) {
-        // colon found: local object
-        // add as child to current node and create it
-        name = _name.substr(0, i);
-        string objConfigClassName = _name.substr(i + 1);
-        getConfigNode()->addChild(name, objConfigClassName);
-    }
+ParamContext::resolveSimObject(const string &name)
+{
     ConfigNode *n = getConfigNode();
     return n ? n->resolveSimObject(name) : NULL;
 }