]> git.mxchange.org Git - simgear.git/blobdiff - simgear/props/props.cxx
fix a coredump situation, discovered by Melchior.
[simgear.git] / simgear / props / props.cxx
index 4404742216dd10b7d5f354fb6d29619bf1a5f048..dd8cb0c01fea7436eb50bf4be6bff8d733f0f48d 100644 (file)
@@ -30,8 +30,8 @@ SG_USING_STD(sort);
 SG_USING_STD(find);
 SG_USING_STD(vector);
 
-#ifdef _MSC_VER
-// MSVC is buggy, and needs something strange here
+#if ( _MSC_VER == 1200 )
+// MSVC is buggy, and needs something strange here
 SG_USING_STD(vector<SGPropertyNode_ptr>);
 SG_USING_STD(vector<SGPropertyChangeListener *>);
 SG_USING_STD(vector<SGPropertyNode *>);
@@ -275,7 +275,7 @@ find_node (SGPropertyNode * current,
 
                                // Success! This is the one we want.
   else if (position >= (int)components.size()) {
-    return current;
+    return (current->getAttribute(SGPropertyNode::REMOVED) ? 0 : current);
   }
 
                                // Empty component means root.
@@ -471,7 +471,7 @@ SGPropertyNode::set_string (const char * val)
 }
 
 void
-SGPropertyNode::clear_value ()
+SGPropertyNode::clearValue ()
 {
   switch (_type) {
   case NONE:
@@ -762,7 +762,7 @@ SGPropertyNode::~SGPropertyNode ()
   delete [] _display_name;
   delete [] _path;
   delete _path_cache;
-  clear_value();
+  clearValue();
   delete _listeners;
 }
 
@@ -775,7 +775,7 @@ SGPropertyNode::alias (SGPropertyNode * target)
 {
   if (target == 0 || _type == ALIAS || _tied)
     return false;
-  clear_value();
+  clearValue();
   _value.alias = target;
   _type = ALIAS;
   return true;
@@ -927,7 +927,10 @@ SGPropertyNode::removeChild (const char * name, int index, bool keep)
     if (keep) {
       _removedChildren.push_back(node);
     }
+    if (_path_cache)
+       _path_cache->erase(name); // EMH - TODO: Take "index" into account!
     node->setAttribute(REMOVED, true);
+    node->clearValue();
     ret = node;
     fireChildRemoved(node);
   }
@@ -1168,7 +1171,7 @@ SGPropertyNode::setBoolValue (bool value)
   bool result = false;
   TEST_WRITE;
   if (_type == NONE || _type == UNSPECIFIED) {
-    clear_value();
+    clearValue();
     _tied = false;
     _type = BOOL;
   }
@@ -1216,7 +1219,7 @@ SGPropertyNode::setIntValue (int value)
   bool result = false;
   TEST_WRITE;
   if (_type == NONE || _type == UNSPECIFIED) {
-    clear_value();
+    clearValue();
     _type = INT;
     _local_val.int_val = 0;
   }
@@ -1267,7 +1270,7 @@ SGPropertyNode::setLongValue (long value)
   bool result = false;
   TEST_WRITE;
   if (_type == NONE || _type == UNSPECIFIED) {
-    clear_value();
+    clearValue();
     _type = LONG;
     _local_val.long_val = 0L;
   }
@@ -1318,7 +1321,7 @@ SGPropertyNode::setFloatValue (float value)
   bool result = false;
   TEST_WRITE;
   if (_type == NONE || _type == UNSPECIFIED) {
-    clear_value();
+    clearValue();
     _type = FLOAT;
     _local_val.float_val = 0;
   }
@@ -1369,7 +1372,7 @@ SGPropertyNode::setDoubleValue (double value)
   bool result = false;
   TEST_WRITE;
   if (_type == NONE || _type == UNSPECIFIED) {
-    clear_value();
+    clearValue();
     _local_val.double_val = value;
     _type = DOUBLE;
   }
@@ -1420,7 +1423,7 @@ SGPropertyNode::setStringValue (const char * value)
   bool result = false;
   TEST_WRITE;
   if (_type == NONE || _type == UNSPECIFIED) {
-    clear_value();
+    clearValue();
     _type = STRING;
   }
 
@@ -1464,7 +1467,7 @@ SGPropertyNode::setUnspecifiedValue (const char * value)
   bool result = false;
   TEST_WRITE;
   if (_type == NONE) {
-    clear_value();
+    clearValue();
     _type = UNSPECIFIED;
   }
 
@@ -1513,7 +1516,7 @@ SGPropertyNode::tie (const SGRawValue<bool> &rawValue, bool useDefault)
   if (useDefault)
     old_val = getBoolValue();
 
-  clear_value();
+  clearValue();
   _type = BOOL;
   _tied = true;
   _value.bool_val = rawValue.clone();
@@ -1535,7 +1538,7 @@ SGPropertyNode::tie (const SGRawValue<int> &rawValue, bool useDefault)
   if (useDefault)
     old_val = getIntValue();
 
-  clear_value();
+  clearValue();
   _type = INT;
   _tied = true;
   _value.int_val = rawValue.clone();
@@ -1557,7 +1560,7 @@ SGPropertyNode::tie (const SGRawValue<long> &rawValue, bool useDefault)
   if (useDefault)
     old_val = getLongValue();
 
-  clear_value();
+  clearValue();
   _type = LONG;
   _tied = true;
   _value.long_val = rawValue.clone();
@@ -1579,7 +1582,7 @@ SGPropertyNode::tie (const SGRawValue<float> &rawValue, bool useDefault)
   if (useDefault)
     old_val = getFloatValue();
 
-  clear_value();
+  clearValue();
   _type = FLOAT;
   _tied = true;
   _value.float_val = rawValue.clone();
@@ -1601,7 +1604,7 @@ SGPropertyNode::tie (const SGRawValue<double> &rawValue, bool useDefault)
   if (useDefault)
     old_val = getDoubleValue();
 
-  clear_value();
+  clearValue();
   _type = DOUBLE;
   _tied = true;
   _value.double_val = rawValue.clone();
@@ -1624,7 +1627,7 @@ SGPropertyNode::tie (const SGRawValue<const char *> &rawValue, bool useDefault)
   if (useDefault)
     old_val = getStringValue();
 
-  clear_value();
+  clearValue();
   _type = STRING;
   _tied = true;
   _value.string_val = rawValue.clone();
@@ -1644,35 +1647,35 @@ SGPropertyNode::untie ()
   switch (_type) {
   case BOOL: {
     bool val = getBoolValue();
-    clear_value();
+    clearValue();
     _type = BOOL;
     _local_val.bool_val = val;
     break;
   }
   case INT: {
     int val = getIntValue();
-    clear_value();
+    clearValue();
     _type = INT;
     _local_val.int_val = val;
     break;
   }
   case LONG: {
     long val = getLongValue();
-    clear_value();
+    clearValue();
     _type = LONG;
     _local_val.long_val = val;
     break;
   }
   case FLOAT: {
     float val = getFloatValue();
-    clear_value();
+    clearValue();
     _type = FLOAT;
     _local_val.float_val = val;
     break;
   }
   case DOUBLE: {
     double val = getDoubleValue();
-    clear_value();
+    clearValue();
     _type = DOUBLE;
     _local_val.double_val = val;
     break;
@@ -1680,7 +1683,7 @@ SGPropertyNode::untie ()
   case STRING:
   case UNSPECIFIED: {
     string val = getStringValue();
-    clear_value();
+    clearValue();
     _type = STRING;
     _local_val.string_val = copy_string(val.c_str());
     break;
@@ -1736,7 +1739,7 @@ SGPropertyNode::getNode (const char * relative_path, int index, bool create)
   vector<PathComponent> components;
   parse_path(relative_path, components);
   if (components.size() > 0)
-    components[components.size()-1].index = index;
+    components.back().index = index;
   return find_node(this, components, 0, create);
 }
 
@@ -2166,6 +2169,23 @@ SGPropertyNode::hash_table::bucket::get_entry (const char * key, bool create)
   }
 }
 
+void
+SGPropertyNode::hash_table::bucket::erase (const char * key)
+{
+  int i;
+  for (i = 0; i < _length; i++) {
+    if (!strcmp(_entries[i]->get_key(), key))
+       break;
+  }
+
+  if (i < _length) {
+    for (++i; i < _length; i++) {
+      _entries[i-1] = _entries[i];
+    }
+     _length--;
+  }
+}
+
 
 SGPropertyNode::hash_table::hash_table ()
   : _data_length(0),
@@ -2211,6 +2231,17 @@ SGPropertyNode::hash_table::put (const char * key, SGPropertyNode * value)
   e->set_value(value);
 }
 
+void
+SGPropertyNode::hash_table::erase (const char * key)
+{
+   if (_data_length == 0)
+    return;
+  unsigned int index = hashcode(key) % _data_length;
+  if (_data[index] == 0)
+    return;
+  _data[index]->erase(key);
+}
+
 unsigned int
 SGPropertyNode::hash_table::hashcode (const char * key)
 {