diff --git a/core/GameConfigs.cpp b/core/GameConfigs.cpp index 3811c3fa..cb96c655 100644 --- a/core/GameConfigs.cpp +++ b/core/GameConfigs.cpp @@ -508,14 +508,9 @@ bool CGameConfig::Reparse(char *error, size_t maxlength) sm_trie_clear(m_pProps); sm_trie_clear(m_pKeys); - if ((err=textparsers->ParseFile_SMC(path, this, NULL)) + if ((err=textparsers->ParseSMCFile(path, this, NULL, error, maxlength)) != SMCError_Okay) { - if (error && (err != SMCError_Custom)) - { - const char *str = textparsers->GetSMCErrorString(err); - snprintf(error, maxlength, "%s", str); - } return false; } diff --git a/core/TextParsers.cpp b/core/TextParsers.cpp index 51c23227..781ada22 100644 --- a/core/TextParsers.cpp +++ b/core/TextParsers.cpp @@ -37,6 +37,8 @@ #include #include "TextParsers.h" #include "ShareSys.h" +#include "sm_stringutil.h" +#include "LibrarySys.h" TextParsers g_TextParser; ITextParsers *textparsers = &g_TextParser; @@ -155,6 +157,38 @@ SMCError TextParsers::ParseFile_SMC(const char *file, ITextListener_SMC *smc, SM return result; } +SMCError TextParsers::ParseSMCFile(const char *file, + ITextListener_SMC *smc_listener, + SMCStates *states, + char *buffer, + size_t maxsize) +{ + const char *errstr; + FILE *fp = fopen(file, "rt"); + + if (fp == NULL) + { + char error[256] = "unknown"; + if (states != NULL) + { + states->line = 0; + states->col = 0; + } + g_LibSys.GetPlatformError(error, sizeof(error)); + UTIL_Format(buffer, maxsize, "File could not be opened: %s", error); + return SMCError_StreamOpen; + } + + SMCError result = ParseStream_SMC(fp, FileStreamReader, smc_listener, states); + + fclose(fp); + + errstr = GetSMCErrorString(result); + UTIL_Format(buffer, maxsize, "%s", errstr != NULL ? errstr : "Unknown error"); + + return result; +} + /** * Raw parsing of streams with helper functions */ diff --git a/core/TextParsers.h b/core/TextParsers.h index 6065b0cf..7762c263 100644 --- a/core/TextParsers.h +++ b/core/TextParsers.h @@ -64,6 +64,12 @@ public: ITextListener_SMC *smc_listener, SMCStates *states); + SMCError ParseSMCFile(const char *file, + ITextListener_SMC *smc_listener, + SMCStates *states, + char *buffer, + size_t maxsize); + unsigned int GetUTF8CharBytes(const char *stream); const char *GetSMCErrorString(SMCError err); diff --git a/public/ITextParsers.h b/public/ITextParsers.h index 85f675e3..6cbdac95 100644 --- a/public/ITextParsers.h +++ b/public/ITextParsers.h @@ -43,7 +43,7 @@ namespace SourceMod { #define SMINTERFACE_TEXTPARSERS_NAME "ITextParsers" - #define SMINTERFACE_TEXTPARSERS_VERSION 2 + #define SMINTERFACE_TEXTPARSERS_VERSION 3 /** * The INI file format is defined as: @@ -390,6 +390,21 @@ namespace SourceMod * @return True if first character is whitespace, false otherwise. */ virtual bool IsWhitespace(const char *stream) =0; + + /** + * @brief Same as ParseFile_SMC, but with an extended error buffer. + * + * @param file Path to file. + * @param smc_listener Event handler for reading file. + * @param states Optional pointer to store last known states. + * @param buffer Error message buffer. + * @param maxsize Maximum size of the error buffer. + */ + virtual SMCError ParseSMCFile(const char *file, + ITextListener_SMC *smc_listener, + SMCStates *states, + char *buffer, + size_t maxsize) =0; }; inline unsigned int _GetUTF8CharBytes(const char *stream)