43 : m_parentComponent(NULL)
44 , m_className(className)
45 , m_visibleClassName(visibleClassName)
62 return m_visibleClassName;
86 std::cerr <<
"INTERNAL ERROR in Component::Clone(): "
88 throw std::exception();
92 StateVariableMap::const_iterator varIt = m_stateVariables.begin();
93 for ( ; varIt != m_stateVariables.end(); ++varIt) {
94 const string& varName = varIt->first;
97 StateVariableMap::iterator cloneVarIt =
98 clone->m_stateVariables.find(varName);
100 if (cloneVarIt == clone->m_stateVariables.end()) {
101 std::cerr <<
"INTERNAL ERROR in Component::Clone(): "
102 "could not copy variable " << varName <<
"'s "
103 <<
" value to the clone: clone is missing"
106 }
else if (!(cloneVarIt->second).CopyValueFrom(variable)) {
107 std::cerr <<
"INTERNAL ERROR in Component::Clone(): "
108 "could not copy variable " << varName <<
"'s "
109 <<
" value to the clone.\n";
114 for (Components::const_iterator it = m_childComponents.begin();
115 it != m_childComponents.end(); ++it) {
118 std::cerr <<
"INTERNAL ERROR in Component::Clone(): "
119 "could not clone child of class '" <<
141 std::cerr <<
"INTERNAL ERROR in Component::LightCloneInternal(): "
143 throw std::exception();
147 StateVariableMap::const_iterator varIt = m_stateVariables.begin();
148 for ( ; varIt != m_stateVariables.end(); ++varIt) {
149 const string& varName = varIt->first;
152 StateVariableMap::iterator cloneVarIt =
153 clone->m_stateVariables.find(varName);
155 if (cloneVarIt == clone->m_stateVariables.end()) {
156 std::cerr <<
"INTERNAL ERROR in Component::LightCloneInternal(): "
157 "could not copy variable " << varName <<
"'s "
158 <<
" value to the clone: clone is missing"
160 throw std::exception();
167 if (!(cloneVarIt->second).CopyValueFrom(variable)) {
168 std::cerr <<
"INTERNAL ERROR in Component::LightCloneInternal(): "
169 "could not copy variable " << varName <<
"'s "
170 <<
" value to the clone.\n";
171 throw std::exception();
175 for (Components::const_iterator it = m_childComponents.begin();
176 it != m_childComponents.end(); ++it) {
179 std::cerr <<
"INTERNAL ERROR in Component::LightCloneInternal(): "
180 "could not clone child of class '" <<
182 throw std::exception();
194 return LightCloneInternal();
199 ostream& changeMessages)
const
212 StateVariableMap::const_iterator varIt = m_stateVariables.begin();
213 for ( ; varIt != m_stateVariables.end(); ++varIt) {
214 const string& varName = varIt->first;
218 if (varName ==
"step")
233 string varOld = oldVariable->
ToString();
237 << varName <<
": " << varOld <<
" -> " << var <<
"\n";
242 for (
size_t i = 0; i < m_childComponents.size(); ++ i) {
243 string myName = m_childComponents[i]->GetVariable(
"name")->ToString();
248 for (j=0; j<oldChildren.size(); ++j)
249 if (oldChildren[j]->
GetVariable(
"name")->ToString() == myName) {
250 m_childComponents[i]->DetectChanges(oldChildren[j], changeMessages);
256 changeMessages << m_childComponents[i]->
262 for (
size_t j=0; j<oldChildren.size(); ++j) {
263 string oldName = oldChildren[j]->GetVariable(
"name")->ToString();
266 for (
size_t k=0; k<m_childComponents.size(); ++k) {
267 string newName = m_childComponents[k]->GetVariable(
"name")->ToString();
268 if (newName == oldName) {
275 changeMessages << oldChildren[j]->
286 for (
size_t i = 0; i < m_childComponents.size(); ++ i)
287 m_childComponents[i]->
Reset();
303 for (
size_t i = 0; i < m_childComponents.size(); ++ i)
304 everythingOk &= m_childComponents[i]->
PreRunCheck(gxemul);
322 for (
size_t i = 0; i < m_childComponents.size(); ++ i)
377 m_parentComponent = parentComponent;
383 return m_parentComponent;
389 return m_parentComponent;
407 const string& methodName,
408 const vector<string>& arguments)
410 std::cerr <<
"Internal error: someone tried to execute "
411 "method '" << methodName <<
"' on the Component base"
412 " class. Perhaps you are missing an override?\n";
413 throw std::exception();
423 if (model != NULL && !model->
ToString().empty()) {
424 if (!ss.str().empty())
433 if (!ss.str().empty())
437 ss << freq/1e9 <<
" GHz";
438 else if (freq >= 1e6)
439 ss << freq/1e6 <<
" MHz";
440 else if (freq >= 1e3)
441 ss << freq/1e3 <<
" kHz";
448 if (paused != NULL && paused->
ToInteger() > 0) {
449 if (!ss.str().empty())
460 bool htmlLinksForClassNames,
string prefixForComponentUrls)
const
472 for (
size_t pos=0; pos<branchTemplate.length(); pos++) {
475 if (pos < branchTemplate.length() - 4)
480 if (pos == branchTemplate.length() - 3 ||
481 pos == branchTemplate.length() - 2)
489 string name =
"(unnamed " + className +
")";
498 if (htmlLinksForClassNames) {
500 std::ifstream documentationComponentFile((
501 "doc/components/component_"
502 + className +
".html").c_str());
504 if (documentationComponentFile.is_open())
505 str +=
"<a href=\"" + prefixForComponentUrls +
506 "components/component_" +
507 className +
".html\">" + name +
"</a>";
517 if ((templateName =
GetVariable(
"template")) != NULL &&
520 string tName = templateName->
ToString();
524 if (htmlLinksForClassNames) {
527 std::ifstream documentationMachineFile((
528 "doc/machines/machine_"
529 + tName +
".html").c_str());
531 if (documentationMachineFile.is_open())
532 str +=
"<a href=\"" + prefixForComponentUrls +
533 "machines/machine_" +
534 tName +
".html\">" + tName +
"</a>";
546 if (!details.empty())
547 str +=
" (" + details +
")";
550 string result =
" " + str +
"\n";
554 for (
size_t i=0, n=children.size(); i<n; ++i) {
555 string subBranch = branchTemplate;
561 result += children[i]->GenerateTreeDump(subBranch,
562 htmlLinksForClassNames, prefixForComponentUrls);
576 if (rootComponent == NULL)
591 return gxemul->
GetUI();
596 size_t insertPosition)
598 if (insertPosition == (
size_t) -1) {
599 insertPosition = m_childComponents.size();
600 m_childComponents.push_back(childComponent);
602 m_childComponents.insert(
603 m_childComponents.begin() + insertPosition,
608 assert(childComponent->
GetParent() == NULL);
616 bool collision =
false;
620 if (name->
ToString().empty() || collision) {
633 for (
size_t i=0; i<m_childComponents.size(); ++i) {
634 if (i == insertPosition)
639 m_childComponents[i]->GetVariable(
"name");
640 if (otherName != NULL) {
658 for (Components::iterator it = m_childComponents.begin();
659 it != m_childComponents.end(); ++it, ++index) {
660 if (childToRemove == (*it)) {
662 m_childComponents.erase(it);
676 return m_childComponents;
682 return m_childComponents;
692 if (m_parentComponent != NULL)
699 static vector<string> SplitPathStringIntoVector(
const string &path)
702 vector<string> pathStrings;
705 for (
size_t i=0, n=path.length(); i<n; i++) {
708 pathStrings.push_back(word);
715 pathStrings.push_back(word);
724 vector<string> allComponentPaths;
730 root->AddAllComponentPaths(allComponentPaths);
734 vector<string> myPathParts = SplitPathStringIntoVector(myPath);
736 for (
size_t n=1; n<=myPathParts.size(); ++n) {
738 for (
size_t i=myPathParts.size()-n; i<myPathParts.size(); i++) {
739 if (attempt.length() > 0)
741 attempt += myPathParts[i];
752 string dotAttempt =
"." + attempt;
753 size_t dotAttemptLength = dotAttempt.length();
754 for (
size_t j=0; j<allComponentPaths.size(); ++j) {
755 const string& s = allComponentPaths[j];
756 if (s.length() < attempt.length())
761 else if (s.length() > dotAttemptLength &&
762 s.substr(s.length() - dotAttemptLength, dotAttemptLength) == dotAttempt)
781 while (path.length() > 0 && path[path.length() - 1] ==
' ')
782 path = path.substr(0, path.length() - 1);
790 vector<string> allComponentPaths;
791 AddAllComponentPaths(allComponentPaths);
798 string strToFind =
"." + path;
799 for (
size_t i=0, n=allComponentPaths.size(); i<n; i++) {
800 if (allComponentPaths[i].length() > strToFind.length()) {
801 string subs = allComponentPaths[i].substr(
802 allComponentPaths[i].length() - strToFind.length());
803 if (strToFind == subs) {
805 component = root->
LookupPath(allComponentPaths[i]);
823 if (index > path.size()) {
829 StateVariableMap::const_iterator it = m_stateVariables.find(
"name");
830 if (it == m_stateVariables.end()) {
835 string nameOfThisComponent = (it->second).ToString();
836 bool match = (path[index] == nameOfThisComponent);
839 if (!match || index == path.size() - 1) {
847 const string& pathPartToLookup = path[index+1];
848 for (
size_t i=0, n=m_childComponents.size(); i<n; i++) {
850 m_childComponents[i]->GetVariable(
"name");
851 if (childName != NULL) {
852 if (childName->
ToString() == pathPartToLookup) {
853 component = m_childComponents[i]->
864 void Component::AddAllComponentPaths(vector<string>& allComponentPaths)
const
870 for (
size_t i=0, n=m_childComponents.size(); i<n; i++)
871 m_childComponents[i]->AddAllComponentPaths(allComponentPaths);
875 static bool PartialMatch(
const string& partialPath,
const string& path)
877 if (partialPath.empty())
880 const size_t partialPathLength = partialPath.length();
881 const size_t pathLength = path.length();
886 if (partialPathLength + pathPos > pathLength)
890 if (path.substr(pathPos, partialPathLength) == partialPath) {
893 if (path.find(
'.', pathPos + partialPathLength) ==
901 }
while (pathPos < pathLength && path[pathPos] !=
'.');
903 if (pathPos < pathLength)
906 }
while (pathPos < pathLength);
913 const string& partialPath,
bool shortestPossible)
const
915 vector<string> allComponentPaths;
916 vector<string> matches;
918 AddAllComponentPaths(allComponentPaths);
920 for (
size_t i=0, n=allComponentPaths.size(); i<n; i++)
921 if (PartialMatch(partialPath, allComponentPaths[i])) {
922 string match = allComponentPaths[i];
924 if (shortestPossible) {
934 matches.push_back(match);
943 for (StateVariableMap::const_iterator it = m_stateVariables.begin();
944 it != m_stateVariables.end(); ++it)
945 names.push_back(it->first);
951 StateVariableMap::iterator it = m_stateVariables.find(name);
952 if (it == m_stateVariables.end())
955 return &(it->second);
961 StateVariableMap::const_iterator it = m_stateVariables.find(name);
962 if (it == m_stateVariables.end())
965 return &(it->second);
974 if (gxemul != NULL) {
975 const string& name = var.
GetName();
977 if (name ==
"step") {
986 if (newStep == oldStep)
993 " not be set to lower than zero.\n");
998 if (newStep < oldStep) {
1002 " not be decreased; snapshotting"
1003 " was not enabled prior to\nstarting"
1004 " the emulation. (-B command line"
1019 "this component cannot be set manually.\n");
1034 StateVariableMap::iterator it = m_stateVariables.find(name);
1035 if (it == m_stateVariables.end()) {
1043 stringstream oldValue;
1046 bool success = var.
SetValue(expression);
1050 " not be assigned; type mismatch?\n");
1054 stringstream newValue;
1057 if (oldValue.str() != newValue.str()) {
1073 string tabs = context.
Tabs();
1075 ss << tabs <<
"component " << m_className <<
"\n" << tabs <<
"{\n";
1077 for (StateVariableMap::const_iterator it = m_stateVariables.begin();
1078 it != m_stateVariables.end(); ++it)
1081 for (
size_t i = 0, n = m_childComponents.size(); i < n; ++ i)
1082 m_childComponents[i]->
Serialize(ss, subContext);
1084 ss << tabs <<
"}\n";
1088 static bool GetNextToken(
const string& str,
size_t& pos,
string& token)
1092 size_t len = str.length();
1096 (str[pos] ==
' ' || str[pos] ==
'\t' ||
1097 str[pos] ==
'\r' || str[pos] ==
'\n'))
1104 bool quoted =
false;
1111 if (ch ==
' ' || ch ==
'\t' ||
1112 ch ==
'\r' || ch ==
'\n')
1119 if (ch ==
'\\' && pos < len-1)
1120 token += str[++pos];
1124 }
while (pos < len);
1135 if (!GetNextToken(str, pos, token) || token !=
"component") {
1136 messages <<
"Expecting \"component\".\n";
1137 return deserializedTree;
1141 if (!GetNextToken(str, pos, className)) {
1142 messages <<
"Expecting a class name.\n";
1143 return deserializedTree;
1146 if (!GetNextToken(str, pos, token) || token !=
"{") {
1147 messages <<
"Expecting {.\n";
1148 return deserializedTree;
1153 if (className ==
"root") {
1157 if (deserializedTree.
IsNULL()) {
1158 messages <<
"Could not create a '" << className <<
"' component.\n";
1159 return deserializedTree;
1163 while (pos < str.length()) {
1164 size_t savedPos = pos;
1170 if (!GetNextToken(str, pos, token)) {
1172 messages <<
"Failure. (0)\n";
1173 deserializedTree = NULL;
1182 if (!GetNextToken(str, pos, name)) {
1184 messages <<
"Failure. (1)\n";
1185 deserializedTree = NULL;
1189 if (token ==
"component") {
1195 messages <<
"Failure. (2)\n";
1196 deserializedTree = NULL;
1204 string varType = token;
1206 if (!GetNextToken(str, pos, varValue)) {
1208 messages <<
"Failure. (3)\n";
1209 deserializedTree = NULL;
1215 messages <<
"Warning: variable '" << name <<
1216 "' for component class " << className <<
1217 " could not be deserialized; skipping.\n";
1222 return deserializedTree;
1233 string result = ss.str();
1240 stringstream messages;
1242 if (tmpDeserializedTree.
IsNULL())
1246 tmpDeserializedTree->
AddChecksum(checksumDeserialized);
1249 return checksumOriginal == checksumDeserialized;
1260 checksum.
Add(((uint64_t) 0x12491725 << 32) | 0xabcef011);
1261 checksum.
Add(m_className);
1266 for (StateVariableMap::const_iterator it = m_stateVariables.begin();
1267 it != m_stateVariables.end();
1269 checksum.
Add(((uint64_t) 0x019fb879 << 32) | 0x25addae1);
1272 (it->second).
Serialize(ss, dummyContext);
1273 checksum.
Add(ss.str());
1277 for (
size_t i = 0; i < m_childComponents.size(); ++ i) {
1278 checksum.
Add((((uint64_t) 0xf98a7c7c << 32) | 0x109f0000)
1280 m_childComponents[i]->AddChecksum(checksum);
1283 checksum.
Add(((uint64_t) 0x90a10224 << 32) | 0x97defa7a);