X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fprops%2Fprops_io.cxx;h=0877390e8b2387eb28db66910ea0083b5c207e4c;hb=63a8209a839fcc142ab86ef16f323bb54c37521a;hp=f6aa8d78bafac220aa73079e641a6bc3903a90c6;hpb=d4c6530a7222deafd2a7dac67f3c88d461766235;p=simgear.git diff --git a/simgear/props/props_io.cxx b/simgear/props/props_io.cxx index f6aa8d78..0877390e 100644 --- a/simgear/props/props_io.cxx +++ b/simgear/props/props_io.cxx @@ -21,6 +21,7 @@ #include #include #include +#include #include "props.hxx" #include "props_io.hxx" @@ -170,12 +171,15 @@ PropsVisitor::startElement (const char * name, const XMLAttributes &atts) // Check for an include. attval = atts.getValue("include"); if (attval != 0) { - SGPath path(SGPath(_base).dir()); - path.append(attval); try { - readProperties(path.str(), _root, 0, _extended); + SGPath path = simgear::ResourceManager::instance()->findPath(attval, SGPath(_base).dir()); + if (path.isNull()) + { + throw sg_io_exception("Cannot open file", sg_location(attval)); + } + readProperties(path.str(), _root, 0, _extended); } catch (sg_io_exception &e) { - setException(e); + setException(e); } } @@ -187,16 +191,17 @@ PropsVisitor::startElement (const char * name, const XMLAttributes &atts) // 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)); @@ -226,6 +231,9 @@ PropsVisitor::startElement (const char * name, const XMLAttributes &atts) 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"); @@ -238,12 +246,15 @@ PropsVisitor::startElement (const char * name, const XMLAttributes &atts) bool omit = false; attval = atts.getValue("include"); if (attval != 0) { - SGPath path(SGPath(_base).dir()); - path.append(attval); try { - readProperties(path.str(), node, 0, _extended); + SGPath path = simgear::ResourceManager::instance()->findPath(attval, SGPath(_base).dir()); + if (path.isNull()) + { + throw sg_io_exception("Cannot open file", sg_location(attval)); + } + readProperties(path.str(), node, 0, _extended); } catch (sg_io_exception &e) { - setException(e); + setException(e); } attval = atts.getValue("omit-node"); @@ -414,29 +425,31 @@ void readProperties (const char *buf, const int size, 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 @@ -599,6 +612,13 @@ writeProperties (const string &file, const SGPropertyNode * start_node, } } +// Another variation, useful when called from gdb +void +writeProperties (const char* file, const SGPropertyNode * start_node) +{ + writeProperties(string(file), start_node, true); +} + //////////////////////////////////////////////////////////////////////// @@ -611,52 +631,57 @@ writeProperties (const string &file, const SGPropertyNode * start_node, * * @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())) retval = false; break; - case VEC4D: + case props::VEC4D: if (!out->setValue(in->getValue())) retval = false; break; @@ -669,18 +694,41 @@ copyProperties (const SGPropertyNode *in, SGPropertyNode *out) } } - // 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;