1
0

Suggestions

This commit is contained in:
Tiger Wang 2014-06-22 00:06:58 +01:00
parent 537467fe25
commit 4a01fba3aa
2 changed files with 30 additions and 40 deletions

View File

@ -54,21 +54,18 @@ void cFurnaceRecipe::ReloadRecipes(void)
ClearRecipes(); ClearRecipes();
LOGD("Loading furnace recipes..."); LOGD("Loading furnace recipes...");
std::ifstream F(FURNACE_RECIPE_FILE, std::ios::in); std::ifstream f(FURNACE_RECIPE_FILE, std::ios::in);
if (!F.good()) if (!f.good())
{ {
F.close(); f.close();
LOG("Could not open the furnace recipes file \"%s\"", FURNACE_RECIPE_FILE); LOG("Could not open the furnace recipes file \"%s\"", FURNACE_RECIPE_FILE);
return; return;
} }
AString SyntaxError;
unsigned int Line = 0; unsigned int Line = 0;
AString ParsingLine; AString ParsingLine;
ASSERT(ParsingLine.empty()); while (std::getline(f, ParsingLine))
while (std::getline(F, ParsingLine))
{ {
Line++; Line++;
ParsingLine.erase(std::remove_if(ParsingLine.begin(), ParsingLine.end(), isspace), ParsingLine.end()); // Remove whitespace ParsingLine.erase(std::remove_if(ParsingLine.begin(), ParsingLine.end(), isspace), ParsingLine.end()); // Remove whitespace
@ -89,12 +86,12 @@ void cFurnaceRecipe::ReloadRecipes(void)
AString::size_type BeginPos = 1; // Begin at one after exclamation mark (bang) AString::size_type BeginPos = 1; // Begin at one after exclamation mark (bang)
if ( if (
!ReadMandatoryNumber(BeginPos, ":", ParsingLine, SyntaxError, Line, IItemID) || // Read item ID !ReadMandatoryNumber(BeginPos, ":", ParsingLine, Line, IItemID) || // Read item ID
!ReadOptionalNumbers(BeginPos, ":", "=", ParsingLine, SyntaxError, Line, IItemCount, IItemHealth) || // Read item count (and optionally health) !ReadOptionalNumbers(BeginPos, ":", "=", ParsingLine, Line, IItemCount, IItemHealth) || // Read item count (and optionally health)
!ReadMandatoryNumber(BeginPos, "0123456789", ParsingLine, SyntaxError, Line, IBurnTime, true) // Read item burn time - last value !ReadMandatoryNumber(BeginPos, "0123456789", ParsingLine, Line, IBurnTime, true) // Read item burn time - last value
) )
{ {
break; return;
} }
// Add to fuel list // Add to fuel list
@ -111,14 +108,14 @@ void cFurnaceRecipe::ReloadRecipes(void)
AString::size_type BeginPos = 0; // Begin at start of line AString::size_type BeginPos = 0; // Begin at start of line
if ( if (
!ReadMandatoryNumber(BeginPos, ":", ParsingLine, SyntaxError, Line, IItemID) || // Read item ID !ReadMandatoryNumber(BeginPos, ":", ParsingLine, Line, IItemID) || // Read item ID
!ReadOptionalNumbers(BeginPos, ":", "@", ParsingLine, SyntaxError, Line, IItemCount, IItemHealth) || // Read item count (and optionally health) !ReadOptionalNumbers(BeginPos, ":", "@", ParsingLine, Line, IItemCount, IItemHealth) || // Read item count (and optionally health)
!ReadMandatoryNumber(BeginPos, "=", ParsingLine, SyntaxError, Line, IBurnTime) || // Read item burn time !ReadMandatoryNumber(BeginPos, "=", ParsingLine, Line, IBurnTime) || // Read item burn time
!ReadMandatoryNumber(BeginPos, ":", ParsingLine, SyntaxError, Line, OItemID) || // Read result ID !ReadMandatoryNumber(BeginPos, ":", ParsingLine, Line, OItemID) || // Read result ID
!ReadOptionalNumbers(BeginPos, ":", "012456789", ParsingLine, SyntaxError, Line, OItemCount, OItemHealth, true) // Read result count (and optionally health) - last value !ReadOptionalNumbers(BeginPos, ":", "012456789", ParsingLine, Line, OItemCount, OItemHealth, true) // Read result count (and optionally health) - last value
) )
{ {
break; return;
} }
// Add to recipe list // Add to recipe list
@ -129,32 +126,25 @@ void cFurnaceRecipe::ReloadRecipes(void)
m_pState->Recipes.push_back(R); m_pState->Recipes.push_back(R);
} }
} }
F.close(); f.close();
if (!SyntaxError.empty()) LOG("Loaded " SIZE_T_FMT " furnace recipes and " SIZE_T_FMT " fuels", m_pState->Recipes.size(), m_pState->Fuel.size());
{
LOGWARN("Error parsing furnace recipes at %s", SyntaxError.c_str());
}
else
{
LOG("Loaded " SIZE_T_FMT " furnace recipes and " SIZE_T_FMT " fuels", m_pState->Recipes.size(), m_pState->Fuel.size());
}
} }
void cFurnaceRecipe::SetParseError(AString & a_ErrorString, unsigned int a_Line, size_t a_Position, const AString & a_CharactersMissing) void cFurnaceRecipe::PrintParseError(unsigned int a_Line, size_t a_Position, const AString & a_CharactersMissing)
{ {
Printf(a_ErrorString, "line %i pos %i: missing '%s'", a_Line, a_Position, a_CharactersMissing.c_str()); LOGWARN("Error parsing furnace recipes at line %i pos %i: missing '%s'", a_Line, a_Position, a_CharactersMissing.c_str());
} }
bool cFurnaceRecipe::ReadMandatoryNumber(AString::size_type & a_Begin, const AString & a_Delimiter, const AString & a_Text, AString & a_ErrorString, unsigned int a_Line, int & a_Value, bool a_IsLastValue) bool cFurnaceRecipe::ReadMandatoryNumber(AString::size_type & a_Begin, const AString & a_Delimiter, const AString & a_Text, unsigned int a_Line, int & a_Value, bool a_IsLastValue)
{ {
AString::size_type End; AString::size_type End;
if (a_IsLastValue) if (a_IsLastValue)
@ -166,7 +156,7 @@ bool cFurnaceRecipe::ReadMandatoryNumber(AString::size_type & a_Begin, const ASt
End = a_Text.find_first_of(a_Delimiter, a_Begin); End = a_Text.find_first_of(a_Delimiter, a_Begin);
if (End == AString::npos) if (End == AString::npos)
{ {
SetParseError(a_ErrorString, a_Line, a_Begin, a_Delimiter); PrintParseError(a_Line, a_Begin, a_Delimiter);
return false; return false;
} }
} }
@ -174,7 +164,7 @@ bool cFurnaceRecipe::ReadMandatoryNumber(AString::size_type & a_Begin, const ASt
// stoi won't throw an exception if the string is alphanumeric, we should check for this // stoi won't throw an exception if the string is alphanumeric, we should check for this
if (!DoesStringContainOnlyNumbers(a_Text.substr(a_Begin, End - a_Begin))) if (!DoesStringContainOnlyNumbers(a_Text.substr(a_Begin, End - a_Begin)))
{ {
SetParseError(a_ErrorString, a_Line, a_Begin, "number"); PrintParseError(a_Line, a_Begin, "number");
return false; return false;
} }
a_Value = std::stoi(a_Text.substr(a_Begin, End - a_Begin)); a_Value = std::stoi(a_Text.substr(a_Begin, End - a_Begin));
@ -187,7 +177,7 @@ bool cFurnaceRecipe::ReadMandatoryNumber(AString::size_type & a_Begin, const ASt
bool cFurnaceRecipe::ReadOptionalNumbers(AString::size_type & a_Begin, const AString & a_DelimiterOne, const AString & a_DelimiterTwo, const AString & a_Text, AString & a_ErrorString, unsigned int a_Line, int & a_ValueOne, int & a_ValueTwo, bool a_IsLastValue) bool cFurnaceRecipe::ReadOptionalNumbers(AString::size_type & a_Begin, const AString & a_DelimiterOne, const AString & a_DelimiterTwo, const AString & a_Text, unsigned int a_Line, int & a_ValueOne, int & a_ValueTwo, bool a_IsLastValue)
{ {
unsigned int End, Begin = a_Begin; unsigned int End, Begin = a_Begin;
@ -208,7 +198,7 @@ bool cFurnaceRecipe::ReadOptionalNumbers(AString::size_type & a_Begin, const ASt
End = a_Text.find_first_of(a_DelimiterTwo, Begin); End = a_Text.find_first_of(a_DelimiterTwo, Begin);
if (End == AString::npos) if (End == AString::npos)
{ {
SetParseError(a_ErrorString, a_Line, Begin, a_DelimiterTwo); PrintParseError(a_Line, Begin, a_DelimiterTwo);
return false; return false;
} }
} }
@ -216,7 +206,7 @@ bool cFurnaceRecipe::ReadOptionalNumbers(AString::size_type & a_Begin, const ASt
// stoi won't throw an exception if the string is alphanumeric, we should check for this // stoi won't throw an exception if the string is alphanumeric, we should check for this
if (!DoesStringContainOnlyNumbers(a_Text.substr(Begin, End - Begin))) if (!DoesStringContainOnlyNumbers(a_Text.substr(Begin, End - Begin)))
{ {
SetParseError(a_ErrorString, a_Line, Begin, "number"); PrintParseError(a_Line, Begin, "number");
return false; return false;
} }
a_ValueTwo = std::stoi(a_Text.substr(Begin, End - Begin)); a_ValueTwo = std::stoi(a_Text.substr(Begin, End - Begin));
@ -226,11 +216,11 @@ bool cFurnaceRecipe::ReadOptionalNumbers(AString::size_type & a_Begin, const ASt
} }
else else
{ {
return ReadMandatoryNumber(a_Begin, a_DelimiterTwo, a_Text, a_ErrorString, a_Line, a_ValueOne, a_IsLastValue); return ReadMandatoryNumber(a_Begin, a_DelimiterTwo, a_Text, a_Line, a_ValueOne, a_IsLastValue);
} }
} }
return ReadMandatoryNumber(a_Begin, a_DelimiterTwo, a_Text, a_ErrorString, a_Line, a_ValueOne, a_IsLastValue); return ReadMandatoryNumber(a_Begin, a_DelimiterTwo, a_Text, a_Line, a_ValueOne, a_IsLastValue);
} }

View File

@ -41,15 +41,15 @@ public:
private: private:
void ClearRecipes(void); void ClearRecipes(void);
/** PrintFs the line, position, and error into an error string */ /** Calls LOGWARN with the line, position, and error */
inline static void SetParseError(AString & a_ErrorString, unsigned int a_Line, size_t a_Position, const AString & a_CharactersMissing); inline static void PrintParseError(unsigned int a_Line, size_t a_Position, const AString & a_CharactersMissing);
/** Reads a number from a string given, starting at a given position and ending at a delimiter given /** Reads a number from a string given, starting at a given position and ending at a delimiter given
Updates beginning position to the delimiter found + 1, and updates the value to the one read Updates beginning position to the delimiter found + 1, and updates the value to the one read
If it encounters a substring that is not fully numeric, it will call SetParseError() and return false; the caller should abort processing If it encounters a substring that is not fully numeric, it will call SetParseError() and return false; the caller should abort processing
Otherwise, the function will return true Otherwise, the function will return true
*/ */
static bool ReadMandatoryNumber(AString::size_type & a_Begin, const AString & a_Delimiter, const AString & a_Text, AString & a_ErrorString, unsigned int a_Line, int & a_Value, bool a_IsLastValue = false); static bool ReadMandatoryNumber(AString::size_type & a_Begin, const AString & a_Delimiter, const AString & a_Text, unsigned int a_Line, int & a_Value, bool a_IsLastValue = false);
/** Reads two numbers from a string given, starting at a given position and ending at the first delimiter given, then again (with an updated position) until the second delimiter given /** Reads two numbers from a string given, starting at a given position and ending at the first delimiter given, then again (with an updated position) until the second delimiter given
Updates beginning position to the second delimiter found + 1, and updates the values to the ones read Updates beginning position to the second delimiter found + 1, and updates the values to the ones read
@ -57,7 +57,7 @@ private:
If this happens whilst reading the first value, it will call ReadMandatoryNumber() with the appropriate position, as this may legitimately occur with the optional value and AString::find_first_of finding the incorrect delimiter. It will return the result of ReadMandatoryNumber() If this happens whilst reading the first value, it will call ReadMandatoryNumber() with the appropriate position, as this may legitimately occur with the optional value and AString::find_first_of finding the incorrect delimiter. It will return the result of ReadMandatoryNumber()
True will be returned definitively for an optional value that is valid True will be returned definitively for an optional value that is valid
*/ */
static bool ReadOptionalNumbers(AString::size_type & a_Begin, const AString & a_DelimiterOne, const AString & a_DelimiterTwo, const AString & a_Text, AString & a_ErrorString, unsigned int a_Line, int & a_ValueOne, int & a_ValueTwo, bool a_IsLastValue = false); static bool ReadOptionalNumbers(AString::size_type & a_Begin, const AString & a_DelimiterOne, const AString & a_DelimiterTwo, const AString & a_Text, unsigned int a_Line, int & a_ValueOne, int & a_ValueTwo, bool a_IsLastValue = false);
/** Uses std::all_of to determine if a string contains only digits */ /** Uses std::all_of to determine if a string contains only digits */
inline static bool DoesStringContainOnlyNumbers(const AString & a_String); inline static bool DoesStringContainOnlyNumbers(const AString & a_String);