diff --git a/core/AdminCache.cpp b/core/AdminCache.cpp index 552e56c8..57ca47cb 100644 --- a/core/AdminCache.cpp +++ b/core/AdminCache.cpp @@ -31,12 +31,12 @@ #include <string.h> #include <assert.h> +#include <ITextParsers.h> #include "AdminCache.h" #include "ShareSys.h" #include "ForwardSys.h" #include "PlayerManager.h" #include "ConCmdManager.h" -#include "TextParsers.h" #include "Logger.h" #include "sourcemod.h" #include "sm_stringutil.h" @@ -89,10 +89,10 @@ private: m_bFileNameLogged = false; g_SourceMod.BuildPath(Path_SM, m_File, sizeof(m_File), "configs/admin_levels.cfg"); - if ((error = g_TextParser.ParseFile_SMC(m_File, this, &line, NULL)) + if ((error = textparsers->ParseFile_SMC(m_File, this, &line, NULL)) != SMCParse_Okay) { - const char *err_string = g_TextParser.GetSMCErrorString(error); + const char *err_string = textparsers->GetSMCErrorString(error); if (!err_string) { err_string = "Unknown error"; diff --git a/core/ChatTriggers.cpp b/core/ChatTriggers.cpp index a5f2ace9..f0206607 100644 --- a/core/ChatTriggers.cpp +++ b/core/ChatTriggers.cpp @@ -29,9 +29,9 @@ * Version: $Id$ */ +#include <ITextParsers.h> #include "ChatTriggers.h" #include "sm_stringutil.h" -#include "TextParsers.h" #include "ConCmdManager.h" /* :HACKHACK: We can't SH_DECL here because ConCmdManager.cpp does */ @@ -228,7 +228,7 @@ bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args, bool is_ size_t cmd_len = 0; const char *inptr = args; while (*inptr != '\0' - && !IsWhitespace(inptr) + && !textparsers->IsWhitespace(inptr) && *inptr != '"' && cmd_len < sizeof(cmd_buf) - 1) { diff --git a/core/CoreConfig.cpp b/core/CoreConfig.cpp index 499e8a0a..7bf4fddc 100644 --- a/core/CoreConfig.cpp +++ b/core/CoreConfig.cpp @@ -29,6 +29,7 @@ * Version: $Id$ */ +#include <ITextParsers.h> #include "CoreConfig.h" #include "sourcemod.h" #include "sourcemm_api.h" @@ -36,7 +37,6 @@ #include "sm_version.h" #include "sm_stringutil.h" #include "LibrarySys.h" -#include "TextParsers.h" #include "Logger.h" #include "PluginSys.h" #include "ForwardSys.h" @@ -115,10 +115,10 @@ void CoreConfig::Initialize() g_LibSys.PathFormat(filePath, sizeof(filePath), "%s/%s", g_SourceMod.GetGamePath(), corecfg); /* Parse config file */ - if ((err=g_TextParser.ParseFile_SMC(filePath, this, NULL, NULL)) != SMCParse_Okay) + if ((err=textparsers->ParseFile_SMC(filePath, this, NULL, NULL)) != SMCParse_Okay) { /* :TODO: This won't actually log or print anything :( - So fix that somehow */ - const char *error = g_TextParser.GetSMCErrorString(err); + const char *error = textparsers->GetSMCErrorString(err); g_Logger.LogFatal("[SM] Error encountered parsing core config file: %s", error ? error : ""); } } diff --git a/core/Database.cpp b/core/Database.cpp index 2f4d02a6..a1e58631 100644 --- a/core/Database.cpp +++ b/core/Database.cpp @@ -34,7 +34,6 @@ #include "ShareSys.h" #include "sourcemod.h" #include "sm_stringutil.h" -#include "TextParsers.h" #include "Logger.h" #include "ExtensionSys.h" #include <stdlib.h> @@ -84,12 +83,12 @@ void DBManager::OnSourceModLevelChange(const char *mapName) * potentially empty/corrupt list, which would be very bad. */ m_pConfigLock->Lock(); - if ((err = g_TextParser.ParseFile_SMC(m_Filename, this, &line, NULL)) != SMCParse_Okay) + if ((err = textparsers->ParseFile_SMC(m_Filename, this, &line, NULL)) != SMCParse_Okay) { g_Logger.LogError("[SM] Detected parse error(s) in file \"%s\"", m_Filename); if (err != SMCParse_Custom) { - const char *txt = g_TextParser.GetSMCErrorString(err); + const char *txt = textparsers->GetSMCErrorString(err); g_Logger.LogError("[SM] Line %d: %s", line, txt); } } diff --git a/core/GameConfigs.cpp b/core/GameConfigs.cpp index 85a18484..7d559270 100644 --- a/core/GameConfigs.cpp +++ b/core/GameConfigs.cpp @@ -32,7 +32,6 @@ #include <string.h> #include <stdlib.h> #include "GameConfigs.h" -#include "TextParsers.h" #include "sm_stringutil.h" #include "sourcemod.h" #include "sourcemm_api.h" @@ -504,12 +503,12 @@ bool CGameConfig::Reparse(char *error, size_t maxlength) sm_trie_clear(m_pProps); sm_trie_clear(m_pKeys); - if ((err=g_TextParser.ParseFile_SMC(path, this, NULL, NULL)) + if ((err=textparsers->ParseFile_SMC(path, this, NULL, NULL)) != SMCParse_Okay) { if (error && (err != SMCParse_Custom)) { - const char *str = g_TextParser.GetSMCErrorString(err); + const char *str = textparsers->GetSMCErrorString(err); snprintf(error, maxlength, "%s", str); } return false; diff --git a/core/TextParsers.cpp b/core/TextParsers.cpp index 1e21f6e5..021ede39 100644 --- a/core/TextParsers.cpp +++ b/core/TextParsers.cpp @@ -39,11 +39,12 @@ #include "ShareSys.h" TextParsers g_TextParser; +ITextParsers *textparsers = &g_TextParser; static int g_ini_chartable1[255] = {0}; static int g_ws_chartable[255] = {0}; -bool IsWhitespace(const char *stream) +bool TextParsers::IsWhitespace(const char *stream) { return g_ws_chartable[(unsigned)*stream] == 1; } diff --git a/core/TextParsers.h b/core/TextParsers.h index 517d9bf4..2dfda119 100644 --- a/core/TextParsers.h +++ b/core/TextParsers.h @@ -37,26 +37,6 @@ using namespace SourceMod; -inline unsigned int _GetUTF8CharBytes(const char *stream) -{ - unsigned char c = *(unsigned char *)stream; - if (c & (1<<7)) - { - if (c & (1<<5)) - { - if (c & (1<<4)) - { - return 4; - } - return 3; - } - return 2; - } - return 1; -} - -bool IsWhitespace(const char *stream); - /** * @param void * IN: Stream pointer * @param char * IN/OUT: Stream buffer @@ -88,6 +68,7 @@ public: unsigned int GetUTF8CharBytes(const char *stream); const char *GetSMCErrorString(SMCParseError err); + bool IsWhitespace(const char *stream); private: SMCParseError ParseString_SMC(const char *stream, ITextListener_SMC *smc, diff --git a/core/Translator.cpp b/core/Translator.cpp index 9e6d0095..b2ea9659 100644 --- a/core/Translator.cpp +++ b/core/Translator.cpp @@ -34,7 +34,6 @@ #include <ctype.h> #include "Translator.h" #include "Logger.h" -#include "TextParsers.h" #include "LibrarySys.h" #include "sm_stringutil.h" #include "sourcemod.h" @@ -139,9 +138,9 @@ void CPhraseFile::ReparseFile() unsigned int line=0, col=0; - if ((err=g_TextParser.ParseFile_SMC(path, this, &line, &col)) != SMCParse_Okay) + if ((err=textparsers->ParseFile_SMC(path, this, &line, &col)) != SMCParse_Okay) { - const char *msg = g_TextParser.GetSMCErrorString(err); + const char *msg = textparsers->GetSMCErrorString(err); if (!msg) { msg = m_ParseError.c_str(); @@ -271,7 +270,7 @@ SMCParseResult CPhraseFile::ReadSMC_KeyValue(const char *key, const char *value, } else if (*value == ',') { /* Do nothing */ } else { - unsigned int bytes = g_TextParser.GetUTF8CharBytes(value); + unsigned int bytes = textparsers->GetUTF8CharBytes(value); if (bytes != 1 || !isalpha(*value)) { ParseWarning("Invalid token '%c' in #format property on line %d.", *value, m_CurLine); @@ -288,7 +287,7 @@ SMCParseResult CPhraseFile::ReadSMC_KeyValue(const char *key, const char *value, return SMCParse_Continue; } } else { - unsigned int bytes = g_TextParser.GetUTF8CharBytes(value); + unsigned int bytes = textparsers->GetUTF8CharBytes(value); if (bytes != 1 || !isdigit(*value)) { ParseWarning("Token '%c' in #format property on line %d is not a digit, phrase will be ignored.", @@ -521,7 +520,7 @@ SMCParseResult CPhraseFile::ReadSMC_KeyValue(const char *key, const char *value, unsigned int bytes; while (*in_ptr != '\0') { - bytes = g_TextParser.GetUTF8CharBytes(in_ptr); + bytes = textparsers->GetUTF8CharBytes(in_ptr); if (bytes != 1) { goto scrap_point; @@ -809,9 +808,9 @@ void Translator::RebuildLanguageDatabase(const char *lang_header_file) /* Start anew */ SMCParseError err; unsigned int line=0, col=0; - if ((err=g_TextParser.ParseFile_SMC(lang_header_file, this, &line, &col)) != SMCParse_Okay) + if ((err=textparsers->ParseFile_SMC(lang_header_file, this, &line, &col)) != SMCParse_Okay) { - const char *str_err = g_TextParser.GetSMCErrorString(err); + const char *str_err = textparsers->GetSMCErrorString(err); if (!str_err) { str_err = m_CustomError.c_str(); diff --git a/core/msvc8/sourcemod_mm.vcproj b/core/msvc8/sourcemod_mm.vcproj index f1485f69..92ac6164 100644 --- a/core/msvc8/sourcemod_mm.vcproj +++ b/core/msvc8/sourcemod_mm.vcproj @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="Windows-1252"?> <VisualStudioProject ProjectType="Visual C++" - Version="8,00" + Version="8.00" Name="sourcemod_mm" ProjectGUID="{E39527CD-7CAB-4420-97CC-DA1B93B260BC}" RootNamespace="sourcemod_mm" diff --git a/core/smn_string.cpp b/core/smn_string.cpp index 97ff08ee..8202deee 100644 --- a/core/smn_string.cpp +++ b/core/smn_string.cpp @@ -33,7 +33,7 @@ #include <stdlib.h> #include "sm_globals.h" #include "sm_stringutil.h" -#include "TextParsers.h" +#include <ITextParsers.h> #include <ctype.h> inline const char *_strstr(const char *str, const char *substr) @@ -294,7 +294,7 @@ static cell_t BreakString(IPluginContext *pContext, const cell_t *params) const char *inptr = input; /* Eat up whitespace */ - while (*inptr != '\0' && IsWhitespace(inptr)) + while (*inptr != '\0' && textparsers->IsWhitespace(inptr)) { inptr++; } @@ -329,7 +329,7 @@ static cell_t BreakString(IPluginContext *pContext, const cell_t *params) } else { start = inptr; /* Read input until we reach a space */ - while (*inptr != '\0' && !IsWhitespace(inptr)) + while (*inptr != '\0' && !textparsers->IsWhitespace(inptr)) { /* Update the end point, increment the stream. */ end = inptr++; @@ -356,7 +356,7 @@ static cell_t BreakString(IPluginContext *pContext, const cell_t *params) } /* Consume more of the string until we reach non-whitespace */ - while (*inptr != '\0' && IsWhitespace(inptr)) + while (*inptr != '\0' && textparsers->IsWhitespace(inptr)) { inptr++; } @@ -502,7 +502,7 @@ static cell_t TrimString(IPluginContext *pContext, const cell_t *params) char *end = str + chars - 1; /* Iterate backwards through string until we reach first non-whitespace char */ - while (end >= str && IsWhitespace(end)) + while (end >= str && textparsers->IsWhitespace(end)) { end--; } @@ -511,7 +511,7 @@ static cell_t TrimString(IPluginContext *pContext, const cell_t *params) *(end + 1) = '\0'; /* Iterate forwards through string until first non-whitespace char is reached */ - while (IsWhitespace(str)) + while (textparsers->IsWhitespace(str)) { str++; } diff --git a/core/smn_textparse.cpp b/core/smn_textparse.cpp index fd7753de..1c37fdc1 100644 --- a/core/smn_textparse.cpp +++ b/core/smn_textparse.cpp @@ -30,7 +30,7 @@ */ #include "sm_globals.h" -#include "TextParsers.h" +#include <ITextParsers.h> #include "HandleSys.h" HandleType_t g_TypeSMC = 0; @@ -280,7 +280,7 @@ static cell_t SMC_ParseFile(IPluginContext *pContext, const cell_t *params) g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "%s", file); unsigned int line = 0, col = 0; - SMCParseError p_err = g_TextParser.ParseFile_SMC(path, parse, &line, &col); + SMCParseError p_err = textparsers->ParseFile_SMC(path, parse, &line, &col); cell_t *c_line, *c_col; pContext->LocalToPhysAddr(params[3], &c_line); @@ -294,7 +294,7 @@ static cell_t SMC_ParseFile(IPluginContext *pContext, const cell_t *params) static cell_t SMC_GetErrorString(IPluginContext *pContext, const cell_t *params) { - const char *str = g_TextParser.GetSMCErrorString((SMCParseError)params[1]); + const char *str = textparsers->GetSMCErrorString((SMCParseError)params[1]); if (!str) { diff --git a/core/systems/PluginSys.cpp b/core/systems/PluginSys.cpp index 8e0c1e83..847b6c88 100644 --- a/core/systems/PluginSys.cpp +++ b/core/systems/PluginSys.cpp @@ -807,10 +807,10 @@ void CPluginManager::LoadAll_FirstPass(const char *config, const char *basedir) SMCParseError err; unsigned int line, col; m_AllPluginsLoaded = false; - if ((err=g_TextParser.ParseFile_SMC(config, &m_PluginInfo, &line, &col)) != SMCParse_Okay) + if ((err=textparsers->ParseFile_SMC(config, &m_PluginInfo, &line, &col)) != SMCParse_Okay) { g_Logger.LogError("[SM] Encountered fatal error parsing file \"%s\"", config); - const char *err_msg = g_TextParser.GetSMCErrorString(err); + const char *err_msg = textparsers->GetSMCErrorString(err); if (err_msg) { g_Logger.LogError("[SM] Parse error encountered: \"%s\"", err_msg); diff --git a/public/ITextParsers.h b/public/ITextParsers.h index c97959a5..16ccef62 100644 --- a/public/ITextParsers.h +++ b/public/ITextParsers.h @@ -362,7 +362,36 @@ namespace SourceMod * @return Number of bytes in current character. */ virtual unsigned int GetUTF8CharBytes(const char *stream) =0; + + /** + * @brief Returns whether the first multi-byte character in the given stream + * is a whitespace character. + * + * @param stream Pointer to multi-byte character string. + * @return True if first character is whitespace, false otherwise. + */ + virtual bool IsWhitespace(const char *stream) =0; }; + + inline unsigned int _GetUTF8CharBytes(const char *stream) + { + unsigned char c = *(unsigned char *)stream; + if (c & (1<<7)) + { + if (c & (1<<5)) + { + if (c & (1<<4)) + { + return 4; + } + return 3; + } + return 2; + } + return 1; + } } +extern SourceMod::ITextParsers *textparsers; + #endif //_INCLUDE_SOURCEMOD_TEXTPARSERS_INTERFACE_H_