Added more explicit error messages to the property lists parser.

More specifically, each time an error or a warning is issued the location of the corresponding XML tag (file name an line number) is reported.
This commit is contained in:
bcoconni 2013-11-24 12:20:26 +01:00
parent 7bbec8dbcb
commit 8e01acaa12

View File

@ -138,7 +138,8 @@ PropsVisitor::endXML ()
* Check a yes/no flag, with default. * Check a yes/no flag, with default.
*/ */
static bool static bool
checkFlag (const char * flag, bool defaultState = true) checkFlag (const char * flag, const sg_location& location,
bool defaultState = true)
{ {
if (flag == 0) if (flag == 0)
return defaultState; return defaultState;
@ -151,7 +152,7 @@ checkFlag (const char * flag, bool defaultState = true)
message += flag; message += flag;
message += '\''; message += '\'';
// FIXME: add location info // FIXME: add location info
throw sg_io_exception(message, "SimGear Property Reader"); throw sg_io_exception(message, location, "SimGear Property Reader");
} }
} }
@ -159,13 +160,14 @@ void
PropsVisitor::startElement (const char * name, const XMLAttributes &atts) PropsVisitor::startElement (const char * name, const XMLAttributes &atts)
{ {
const char * attval; const char * attval;
const sg_location location(getPath(), getLine(), getColumn());
if (_level == 0) { if (_level == 0) {
if (strcmp(name, "PropertyList")) { if (strcmp(name, "PropertyList")) {
string message = "Root element name is "; string message = "Root element name is ";
message += name; message += name;
message += "; expected PropertyList"; message += "; expected PropertyList";
throw sg_io_exception(message, "SimGear Property Reader"); throw sg_io_exception(message, location, "SimGear Property Reader");
} }
// Check for an include. // Check for an include.
@ -175,7 +177,10 @@ PropsVisitor::startElement (const char * name, const XMLAttributes &atts)
SGPath path = simgear::ResourceManager::instance()->findPath(attval, SGPath(_base).dir()); SGPath path = simgear::ResourceManager::instance()->findPath(attval, SGPath(_base).dir());
if (path.isNull()) if (path.isNull())
{ {
throw sg_io_exception("Cannot open file", sg_location(attval)); string message ="Cannot open file ";
message += attval;
throw sg_io_exception(message, location,
"SimGear Property Reader");
} }
readProperties(path.str(), _root, 0, _extended); readProperties(path.str(), _root, 0, _extended);
} catch (sg_io_exception &e) { } catch (sg_io_exception &e) {
@ -204,7 +209,7 @@ PropsVisitor::startElement (const char * name, const XMLAttributes &atts)
SGPropertyNode * node = st.node->getChild(strName, index, true); SGPropertyNode * node = st.node->getChild(strName, index, true);
if (!node->getAttribute(SGPropertyNode::WRITE)) { if (!node->getAttribute(SGPropertyNode::WRITE)) {
SG_LOG(SG_INPUT, SG_ALERT, "Not overwriting write-protected property " SG_LOG(SG_INPUT, SG_ALERT, "Not overwriting write-protected property "
<< node->getPath(true)); << node->getPath(true) << "\n at " << location.asString());
node = &null; node = &null;
} }
@ -214,32 +219,33 @@ PropsVisitor::startElement (const char * name, const XMLAttributes &atts)
int mode = _default_mode; int mode = _default_mode;
attval = atts.getValue("read"); attval = atts.getValue("read");
if (checkFlag(attval, true)) if (checkFlag(attval, location, true))
mode |= SGPropertyNode::READ; mode |= SGPropertyNode::READ;
attval = atts.getValue("write"); attval = atts.getValue("write");
if (checkFlag(attval, true)) if (checkFlag(attval, location, true))
mode |= SGPropertyNode::WRITE; mode |= SGPropertyNode::WRITE;
attval = atts.getValue("archive"); attval = atts.getValue("archive");
if (checkFlag(attval, false)) if (checkFlag(attval, location, false))
mode |= SGPropertyNode::ARCHIVE; mode |= SGPropertyNode::ARCHIVE;
attval = atts.getValue("trace-read"); attval = atts.getValue("trace-read");
if (checkFlag(attval, false)) if (checkFlag(attval, location, false))
mode |= SGPropertyNode::TRACE_READ; mode |= SGPropertyNode::TRACE_READ;
attval = atts.getValue("trace-write"); attval = atts.getValue("trace-write");
if (checkFlag(attval, false)) if (checkFlag(attval, location, false))
mode |= SGPropertyNode::TRACE_WRITE; mode |= SGPropertyNode::TRACE_WRITE;
attval = atts.getValue("userarchive"); attval = atts.getValue("userarchive");
if (checkFlag(attval, false)) if (checkFlag(attval, location, false))
mode |= SGPropertyNode::USERARCHIVE; mode |= SGPropertyNode::USERARCHIVE;
attval = atts.getValue("preserve"); attval = atts.getValue("preserve");
if (checkFlag(attval, false)) if (checkFlag(attval, location, false))
mode |= SGPropertyNode::PRESERVE; mode |= SGPropertyNode::PRESERVE;
// Check for an alias. // Check for an alias.
attval = atts.getValue("alias"); attval = atts.getValue("alias");
if (attval != 0) { if (attval != 0) {
if (!node->alias(attval)) if (!node->alias(attval))
SG_LOG(SG_INPUT, SG_ALERT, "Failed to set alias to " << attval); SG_LOG(SG_INPUT, SG_ALERT, "Failed to set alias to " << attval
<< "\n at " << location.asString());
} }
// Check for an include. // Check for an include.
@ -250,7 +256,10 @@ PropsVisitor::startElement (const char * name, const XMLAttributes &atts)
SGPath path = simgear::ResourceManager::instance()->findPath(attval, SGPath(_base).dir()); SGPath path = simgear::ResourceManager::instance()->findPath(attval, SGPath(_base).dir());
if (path.isNull()) if (path.isNull())
{ {
throw sg_io_exception("Cannot open file", sg_location(attval)); string message ="Cannot open file ";
message += attval;
throw sg_io_exception(message, location,
"SimGear Property Reader");
} }
readProperties(path.str(), node, 0, _extended); readProperties(path.str(), node, 0, _extended);
} catch (sg_io_exception &e) { } catch (sg_io_exception &e) {
@ -258,7 +267,7 @@ PropsVisitor::startElement (const char * name, const XMLAttributes &atts)
} }
attval = atts.getValue("omit-node"); attval = atts.getValue("omit-node");
omit = checkFlag(attval, false); omit = checkFlag(attval, location, false);
} }
const char *type = atts.getValue("type"); const char *type = atts.getValue("type");
@ -276,6 +285,7 @@ PropsVisitor::endElement (const char * name)
{ {
State &st = state(); State &st = state();
bool ret; bool ret;
const sg_location location(getPath(), getLine(), getColumn());
// If there are no children and it's // If there are no children and it's
// not an alias, then it's a leaf value. // not an alias, then it's a leaf value.
@ -310,12 +320,13 @@ PropsVisitor::endElement (const char * name)
message += st.type; message += st.type;
message += '\''; message += '\'';
// FIXME: add location information // FIXME: add location information
throw sg_io_exception(message, "SimGear Property Reader"); throw sg_io_exception(message, location, "SimGear Property Reader");
} }
if (!ret) if (!ret)
SG_LOG(SG_INPUT, SG_ALERT, "readProperties: Failed to set " SG_LOG(SG_INPUT, SG_ALERT, "readProperties: Failed to set "
<< st.node->getPath() << " to value \"" << st.node->getPath() << " to value \""
<< _data << "\" with type " << st.type); << _data << "\" with type " << st.type << "\n at "
<< location.asString());
} }
// Set the access-mode attributes now, // Set the access-mode attributes now,