--Bug fixes

-Allow for empty fields in template files.

--Code changes
 -When parsing, a boolean is not available to specify whether to use the default values if they are not present. This will be false for template files.
This commit is contained in:
mfeemster 2015-07-06 20:04:38 -07:00
parent fa3175aad1
commit 570331adb5
3 changed files with 17 additions and 9 deletions

View File

@ -253,8 +253,9 @@ public:
/// <param name="buf">The buffer to parse</param> /// <param name="buf">The buffer to parse</param>
/// <param name="filename">Full path and filename, optionally empty</param> /// <param name="filename">Full path and filename, optionally empty</param>
/// <param name="embers">The newly constructed embers based on what was parsed</param> /// <param name="embers">The newly constructed embers based on what was parsed</param>
/// <param name="useDefaults">True to use defaults if they are not present in the file, else false to use invalid values as placeholders to indicate the values were not present. Default: true.</param>
/// <returns>True if there were no errors, else false.</returns> /// <returns>True if there were no errors, else false.</returns>
bool Parse(byte* buf, const char* filename, vector<Ember<T>>& embers) bool Parse(byte* buf, const char* filename, vector<Ember<T>>& embers, bool useDefaults = true)
{ {
char* bn; char* bn;
const char* xmlPtr; const char* xmlPtr;
@ -286,7 +287,7 @@ public:
//Scan for <flame> nodes, starting with this node. //Scan for <flame> nodes, starting with this node.
//t.Tic(); //t.Tic();
bn = basename(const_cast<char*>(filename)); bn = basename(const_cast<char*>(filename));
ScanForEmberNodes(rootnode, bn, embers); ScanForEmberNodes(rootnode, bn, embers, useDefaults);
xmlFreeDoc(doc); xmlFreeDoc(doc);
emberSize = embers.size(); emberSize = embers.size();
//t.Toc("ScanForEmberNodes"); //t.Toc("ScanForEmberNodes");
@ -337,8 +338,9 @@ public:
/// </summary> /// </summary>
/// <param name="filename">Full path and filename</param> /// <param name="filename">Full path and filename</param>
/// <param name="embers">The newly constructed embers based on what was parsed</param> /// <param name="embers">The newly constructed embers based on what was parsed</param>
/// <param name="useDefaults">True to use defaults if they are not present in the file, else false to use invalid values as placeholders to indicate the values were not present. Default: true.</param>
/// <returns>True if there were no errors, else false.</returns> /// <returns>True if there were no errors, else false.</returns>
bool Parse(const char* filename, vector<Ember<T>>& embers) bool Parse(const char* filename, vector<Ember<T>>& embers, bool useDefaults = true)
{ {
const char* loc = __FUNCTION__; const char* loc = __FUNCTION__;
string buf; string buf;
@ -353,7 +355,7 @@ public:
if (ReadFile(filename, buf)) if (ReadFile(filename, buf))
{ {
std::replace(buf.begin(), buf.end(), '&', '+'); std::replace(buf.begin(), buf.end(), '&', '+');
return Parse(reinterpret_cast<byte*>(const_cast<char*>(buf.data())), filename, embers); return Parse(reinterpret_cast<byte*>(const_cast<char*>(buf.data())), filename, embers, useDefaults);
} }
else else
return false; return false;
@ -488,7 +490,8 @@ private:
/// <param name="curNode">The current node to parse</param> /// <param name="curNode">The current node to parse</param>
/// <param name="parentFile">The full path and filename</param> /// <param name="parentFile">The full path and filename</param>
/// <param name="embers">The newly constructed embers based on what was parsed</param> /// <param name="embers">The newly constructed embers based on what was parsed</param>
void ScanForEmberNodes(xmlNode* curNode, char* parentFile, vector<Ember<T>>& embers) /// <param name="useDefaults">True to use defaults if they are not present in the file, else false to use invalid values as placeholders to indicate the values were not present.</param>
void ScanForEmberNodes(xmlNode* curNode, char* parentFile, vector<Ember<T>>& embers, bool useDefaults)
{ {
bool parseEmberSuccess; bool parseEmberSuccess;
xmlNodePtr thisNode = nullptr; xmlNodePtr thisNode = nullptr;
@ -504,6 +507,10 @@ private:
{ {
Ember<T> currentEmber;//Place this inside here so its constructor is called each time. Ember<T> currentEmber;//Place this inside here so its constructor is called each time.
//Useful for parsing templates when not every member should be set.
if (!useDefaults)
currentEmber.Clear(false);
parseEmberSuccess = ParseEmberElement(thisNode, currentEmber); parseEmberSuccess = ParseEmberElement(thisNode, currentEmber);
if (!parseEmberSuccess) if (!parseEmberSuccess)
@ -532,7 +539,7 @@ private:
else else
{ {
//Check all of the children of this element. //Check all of the children of this element.
ScanForEmberNodes(thisNode->children, parentFile, embers); ScanForEmberNodes(thisNode->children, parentFile, embers, useDefaults);
} }
} }
} }

View File

@ -81,11 +81,12 @@ private:
/// <param name="parser">The parser to use</param> /// <param name="parser">The parser to use</param>
/// <param name="filename">The full path and name of the file</param> /// <param name="filename">The full path and name of the file</param>
/// <param name="embers">Storage for the embers read from the file</param> /// <param name="embers">Storage for the embers read from the file</param>
/// <param name="useDefaults">True to use defaults if they are not present in the file, else false to use invalid values as placeholders to indicate the values were not present. Default: true.</param>
/// <returns>True if success, else false.</returns> /// <returns>True if success, else false.</returns>
template <typename T> template <typename T>
static bool ParseEmberFile(XmlToEmber<T>& parser, string filename, vector<Ember<T>>& embers) static bool ParseEmberFile(XmlToEmber<T>& parser, string filename, vector<Ember<T>>& embers, bool useDefaults = true)
{ {
if (!parser.Parse(filename.c_str(), embers)) if (!parser.Parse(filename.c_str(), embers, useDefaults))
{ {
cout << "Error parsing flame file " << filename << ", returning without executing." << endl; cout << "Error parsing flame file " << filename << ", returning without executing." << endl;
return false; return false;

View File

@ -239,7 +239,7 @@ bool EmberGenome(EmberOptions& opt)
if (opt.TemplateFile() != "") if (opt.TemplateFile() != "")
{ {
if (!ParseEmberFile(parser, opt.TemplateFile(), templateEmbers)) if (!ParseEmberFile(parser, opt.TemplateFile(), templateEmbers, false))//Do not use defaults here to ensure only present fields get used when applying the template.
return false; return false;
if (templateEmbers.size() > 1) if (templateEmbers.size() > 1)