diff --git a/src/date.h b/src/date.h index cf3a608c..5bc45b4e 100644 --- a/src/date.h +++ b/src/date.h @@ -75,13 +75,10 @@ date_GetDay (dateT date) return (uint32_t) (date & 31); } -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -//### date_GetMonthDay(): -// Get the month and day; used to check for year-only dates. S.A -inline uint32_t -date_GetMonthDay (dateT date) -{ - return (uint32_t) (date & 511); +// Return true if the date does not include the year, the month or the day. +inline bool date_isPartial(dateT date) { + return date_GetYear(date) == 0 || date_GetMonth(date) == 0 || + date_GetDay(date) == 0; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/pgnparse.h b/src/pgnparse.h index d470bcad..aced57a5 100644 --- a/src/pgnparse.h +++ b/src/pgnparse.h @@ -27,6 +27,7 @@ #include "game.h" #include "pgn_lexer.h" #include +#include #include /** @@ -160,12 +161,27 @@ class PgnVisitor { if (tagLen == 0 || tagLen + valueLen > 240 || !parseTagPair(tag.first, tagLen, value)) // Failure { - std::string err(tag.first, tag.second); - err.append(" \""); - err.append(value.first, value.second); - err.push_back('"'); - logErr("Error parsing the tag pair: ", - {err.c_str(), err.c_str() + err.size()}); + const auto tag_sv = std::string_view(tag.first, tagLen); + const auto value_sv = std::string_view(value.first, valueLen); + std::string tag_parsed; + std::string value_parsed; + game.viewTagPairs([&](auto game_tag, auto game_value) { + if (tag_sv == game_tag) { + tag_parsed = game_tag; + value_parsed = game_value; + } + }); + if (tag_sv != tag_parsed || value_sv != value_parsed) { + std::string err(tag_sv); + err.append(" \""); + err.append(value_sv); + err.append("\" ==> "); + err.append(tag_parsed); + err.append(" \""); + err.append(value_parsed); + err.push_back('"'); + logWarning("Error parsing the tag pair: ", err); + } } return true; } @@ -209,20 +225,18 @@ class PgnVisitor { } private: - bool logWarning(const char* str1, TView str2 = {nullptr, nullptr}) { + bool logWarning(const char* str1, std::string_view str2) { errors_.emplace_back(linenum_, str1); - if (std::distance(str2.first, str2.second) > 200) { - errors_.back().second.append(str2.first, 200); + errors_.back().second.append(str2.substr(0, 200)); + if (str2.size() > 200) { errors_.back().second.append("..."); - } else { - errors_.back().second.append(str2.first, str2.second); } return true; } bool logErr(const char* str1, TView str2 = {nullptr, nullptr}) { --nErrorsAllowed_; - return logWarning(str1, str2); + return logWarning(str1, {str2.first, str2.second}); } bool logFatalErr(const char* str1, TView str2 = {nullptr, nullptr}) { @@ -268,8 +282,9 @@ class PgnVisitor { break; case 4: if (std::equal(tag, tag + 4, "Date")) { - game.SetDate(date_parsePGNTag(value)); - return true; + const auto date = date_parsePGNTag(value); + game.SetDate(date); + return !date_isPartial(date); } break; case 6: @@ -280,13 +295,16 @@ class PgnVisitor { if (std::equal(tag, tag + 7, "UTCDate") && game.GetDate() == ZERO_DATE) { // Add two tags: "UTCDate" and the standard "Date". - game.SetDate(date_parsePGNTag(value)); + const auto date = date_parsePGNTag(value); + if (!date_isPartial(date)) + game.SetDate(date); } break; case 9: if (std::equal(tag, tag + 9, "EventDate")) { - game.SetEventDate(date_parsePGNTag(value)); - return true; + const auto date = date_parsePGNTag(value); + game.SetEventDate(date); + return !date_isPartial(date); } if (std::equal(tag, tag + 9, "ScidFlags")) { game.SetScidFlags(value.first,