// Get the index.
attval = atts.getValue("n");
int index = 0;
+ string strName(name);
if (attval != 0) {
index = atoi(attval);
- st.counters[name] = SG_MAX2(st.counters[name], index+1);
+ st.counters[strName] = SG_MAX2(st.counters[strName], index+1);
} else {
- index = st.counters[name];
- st.counters[name]++;
+ index = st.counters[strName];
+ st.counters[strName]++;
}
// Got the index, so grab the node.
- SGPropertyNode * node = st.node->getChild(name, index, true);
+ SGPropertyNode * node = st.node->getChild(strName, index, true);
if (!node->getAttribute(SGPropertyNode::WRITE)) {
SG_LOG(SG_INPUT, SG_ALERT, "Not overwriting write-protected property "
<< node->getPath(true));
attval = atts.getValue("userarchive");
if (checkFlag(attval, false))
mode |= SGPropertyNode::USERARCHIVE;
+ attval = atts.getValue("preserve");
+ if (checkFlag(attval, false))
+ mode |= SGPropertyNode::PRESERVE;
// Check for an alias.
attval = atts.getValue("alias");
static const char *
getTypeName (simgear::props::Type type)
{
- using namespace simgear::props;
+ using namespace simgear;
switch (type) {
- case UNSPECIFIED:
+ case props::UNSPECIFIED:
return "unspecified";
- case BOOL:
+ case props::BOOL:
return "bool";
- case INT:
+ case props::INT:
return "int";
- case LONG:
+ case props::LONG:
return "long";
- case FLOAT:
+ case props::FLOAT:
return "float";
- case DOUBLE:
+ case props::DOUBLE:
return "double";
- case STRING:
+ case props::STRING:
return "string";
- case VEC3D:
+ case props::VEC3D:
return "vec3d";
- case VEC4D:
+ case props::VEC4D:
return "vec4d";
- case ALIAS:
- case NONE:
+ case props::ALIAS:
+ case props::NONE:
return "unspecified";
+ default: // avoid compiler warning
+ break;
}
// keep the compiler from squawking
}
}
+// Another variation, useful when called from gdb
+void
+writeProperties (const char* file, const SGPropertyNode * start_node)
+{
+ writeProperties(string(file), start_node, true);
+}
+
\f
////////////////////////////////////////////////////////////////////////
*
* @param in The source property tree.
* @param out The destination property tree.
+ * @param attr_value Only copy properties with given attribute values.
+ * @param attr_mask Mask for attributes to be considered by attr_value
+ * (default is 0 = attributes not considered, all
+ * properties copied).
* @return true if all properties were copied, false if some failed
* (for example, if the property's value is tied read-only).
*/
bool
-copyProperties (const SGPropertyNode *in, SGPropertyNode *out)
+copyProperties (const SGPropertyNode *in, SGPropertyNode *out,
+ int attr_value, int attr_mask)
{
- using namespace simgear::props;
+ using namespace simgear;
bool retval = true;
// First, copy the actual value,
// if any.
if (in->hasValue()) {
switch (in->getType()) {
- case BOOL:
+ case props::BOOL:
if (!out->setBoolValue(in->getBoolValue()))
retval = false;
break;
- case INT:
+ case props::INT:
if (!out->setIntValue(in->getIntValue()))
retval = false;
break;
- case LONG:
+ case props::LONG:
if (!out->setLongValue(in->getLongValue()))
retval = false;
break;
- case FLOAT:
+ case props::FLOAT:
if (!out->setFloatValue(in->getFloatValue()))
retval = false;
break;
- case DOUBLE:
+ case props::DOUBLE:
if (!out->setDoubleValue(in->getDoubleValue()))
retval = false;
break;
- case STRING:
+ case props::STRING:
if (!out->setStringValue(in->getStringValue()))
retval = false;
break;
- case UNSPECIFIED:
+ case props::UNSPECIFIED:
if (!out->setUnspecifiedValue(in->getStringValue()))
retval = false;
break;
- case VEC3D:
+ case props::VEC3D:
if (!out->setValue(in->getValue<SGVec3d>()))
retval = false;
break;
- case VEC4D:
+ case props::VEC4D:
if (!out->setValue(in->getValue<SGVec4d>()))
retval = false;
break;
}
}
- // copy the attributes.
+ // copy the attributes.
out->setAttributes( in->getAttributes() );
- // Next, copy the children.
+ // Next, copy the children.
int nChildren = in->nChildren();
for (int i = 0; i < nChildren; i++) {
const SGPropertyNode * in_child = in->getChild(i);
- SGPropertyNode * out_child = out->getChild(in_child->getName(),
- in_child->getIndex(),
- true);
- if (!copyProperties(in_child, out_child))
- retval = false;
+ int mask = attr_mask;
+ /* attributes have no meaning for nodes without values - except
+ * the PRESERVE flag. So ignore them. */
+ if (!in_child->hasValue())
+ mask &= SGPropertyNode::PRESERVE;
+ if ((in_child->getAttributes() & mask) == (attr_value & mask))
+ {
+ SGPropertyNode * out_child = out->getChild(in_child->getNameString(),
+ in_child->getIndex(),
+ false);
+ if (!out_child)
+ {
+ out_child = out->getChild(in_child->getNameString(),
+ in_child->getIndex(),
+ true);
+ }
+ else
+ {
+ mask = attr_mask;
+ if (!out_child->hasValue())
+ mask &= SGPropertyNode::PRESERVE;
+ if ((out_child->getAttributes() & mask) != (attr_value & mask))
+ out_child = NULL;
+ }
+ if (out_child &&
+ (!copyProperties(in_child, out_child, attr_value, attr_mask)))
+ retval = false;
+ }
}
return retval;