diff --git a/core/CTextParsers.cpp b/core/CTextParsers.cpp new file mode 100644 index 00000000..063d1f3b --- /dev/null +++ b/core/CTextParsers.cpp @@ -0,0 +1,286 @@ +#include +#include +#include +#include "CTextParsers.h" + +CTextParsers g_TextParse; + +static int g_ini_chartable1[255] = {0}; + +CTextParsers::CTextParsers() +{ + g_ini_chartable1['_'] = 1; + g_ini_chartable1['-'] = 1; + g_ini_chartable1[','] = 1; + g_ini_chartable1['+'] = 1; + g_ini_chartable1['.'] = 1; + g_ini_chartable1['$'] = 1; + g_ini_chartable1['?'] = 1; + g_ini_chartable1['/'] = 1; +} + +bool CTextParsers::ParseFile_SMC(const char *file, ITextListener_SMC *smc_listener, unsigned int *line, unsigned int *col) +{ + /* :TODO: Implement this */ + if (line) + { + *line = 0; + } + + return false; +} + +bool CTextParsers::ParseFile_INI(const char *file, ITextListener_INI *ini_listener, unsigned int *line, unsigned int *col) +{ + FILE *fp = fopen(file, "rt"); + unsigned int curline = 0; + unsigned int curtok; + size_t len; + + if (!fp) + { + if (line) + { + *line = 0; + } + + return false; + } + + char buffer[2048]; + char *ptr, *save_ptr; + bool in_quote; + while (!feof(fp)) + { + curline++; + curtok = 0; + buffer[0] = '\0'; + if (fgets(buffer, sizeof(buffer), fp) == NULL) + { + break; + } + + /* Preprocess the string before anything */ + ptr = buffer; + + /* First strip beginning whitespace */ + while ((*ptr != '\0') && isspace(*ptr)) + { + ptr++; + } + + len = strlen(ptr); + + if (!len) + { + continue; + } + + /* Now search for comment characters */ + in_quote = false; + save_ptr = ptr; + for (size_t i=0; i=0 && iReadINI_RawLine(ptr, &curtok)) + { + goto event_failed; + } + + if (*ptr == '[') + { + bool invalid_tokens = false; + bool got_bracket = false; + bool extra_tokens = false; + char c; + + for (size_t i=1; iReadINI_NewSection(&ptr[1], invalid_tokens, got_bracket, extra_tokens, &curtok)) + { + goto event_failed; + } + } else { + char *key_ptr = ptr; + char *val_ptr = NULL; + char c; + size_t first_space = 0; + bool invalid_tokens = false; + bool equal_token = false; + bool quotes = false; + + for (size_t i=0; iReadINI_KeyValue(key_ptr, val_ptr, invalid_tokens, equal_token, quotes, &curtok)) + { + curtok = 0; + goto event_failed; + } + } + } + + if (line) + { + *line = curline; + } + + fclose(fp); + + return true; + +event_failed: + if (line) + { + *line = curline; + } + + if (col) + { + *col = curtok; + } + + fclose(fp); + + return false; +} diff --git a/core/CTextParsers.h b/core/CTextParsers.h new file mode 100644 index 00000000..d6c255ae --- /dev/null +++ b/core/CTextParsers.h @@ -0,0 +1,27 @@ +#ifndef _INCLUDE_SOURCEMOD_TEXTPARSERS_H_ +#define _INCLUDE_SOURCEMOD_TEXTPARSERS_H_ + +#include "interfaces/ITextParsers.h" + +using namespace SourceMod; + +class CTextParsers : public ITextParsers +{ + +public: + CTextParsers(); +public: + virtual bool ParseFile_INI(const char *file, + ITextListener_INI *ini_listener, + unsigned int *line, + unsigned int *col); + + virtual bool ParseFile_SMC(const char *file, + ITextListener_SMC *smc_listener, + unsigned int *line, + unsigned int *col); +}; + +extern CTextParsers g_TextParse; + +#endif //_INCLUDE_SOURCEMOD_TEXTPARSERS_H_ diff --git a/core/interfaces/ITextParsers.h b/core/interfaces/ITextParsers.h index 6654e6be..11ac1ae3 100644 --- a/core/interfaces/ITextParsers.h +++ b/core/interfaces/ITextParsers.h @@ -1,5 +1,5 @@ -#ifndef _INCLUDE_SOURCEMOD_TEXTPARSERS_H_ -#define _INCLUDE_SOURCEMOD_TEXTPARSERS_H_ +#ifndef _INCLUDE_SOURCEMOD_TEXTPARSERS_INTERFACE_H_ +#define _INCLUDE_SOURCEMOD_TEXTPARSERS_INTERFACE_H_ #include @@ -50,9 +50,18 @@ namespace SourceMod * @brief Called when a new section is encountered in an INI file. * * @param section Name of section in between the [ and ] characters. + * @param invalid_tokens True if invalid tokens were detected in the name. + * @param close_bracket True if a closing bracket was detected, false otherwise. + * @param extra_tokens True if extra tokens were detected on the line. + * @param curtok Contains current token in the line where the section name starts. + * You can add to this offset when failing to point to a token. * @return True to keep parsing, false otherwise. */ - virtual bool ReadINI_NewSection(const char *section) + virtual bool ReadINI_NewSection(const char *section, + bool invalid_tokens, + bool close_bracket, + bool extra_tokens, + unsigned int *curtok) { return true; } @@ -61,11 +70,32 @@ namespace SourceMod * @brief Called when encountering a key/value pair in an INI file. * * @param key Name of key. - * @param value Name of value. + * @param value String containing value (with quotes stripped, if any). + * @param invalid_tokens Whether or not the key contained invalid tokens. + * @param equal_token There was an '=' sign present (in case the value is missing). * @param quotes Whether value was enclosed in quotes. + * @param curtoken Contains the token index of the start of the value string. + * This can be changed when returning false. * @return True to keep parsing, false otherwise. */ - virtual bool ReadINI_KeyValue(const char *key, const char *value, bool quotes) + virtual bool ReadINI_KeyValue(const char *key, + const char *value, + bool invalid_tokens, + bool equal_token, + bool quotes, + unsigned int *curtok) + { + return true; + } + + /** + * @brief Called after a line has been preprocessed, if it has text. + * + * @param line Contents of line. + * @param curtok Pointer to optionally store failed position in string. + * @return True to keep parsing, false otherwise. + */ + virtual bool ReadINI_RawLine(const char *line, unsigned int *cutok) { return true; } @@ -163,8 +193,20 @@ namespace SourceMod } }; + #define SMINTERFACE_TEXTPARSERS_NAME "ITextParsers" + #define SMINTERFACE_TEXTPARSERS_VERSION 1 + class ITextParsers : public SMInterface { + public: + virtual const char *GetInterfaceName() + { + return SMINTERFACE_TEXTPARSERS_NAME; + } + virtual unsigned int GetInterfaceVersion() + { + return SMINTERFACE_TEXTPARSERS_VERSION; + } public: /** * @brief Parses an INI-format file. @@ -199,4 +241,4 @@ namespace SourceMod }; }; -#endif //_INCLUDE_SOURCEMOD_TEXTPARSERS_H_ +#endif //_INCLUDE_SOURCEMOD_TEXTPARSERS_INTERFACE_H_ diff --git a/core/msvc8/sourcemod_mm.vcproj b/core/msvc8/sourcemod_mm.vcproj index 601f50e8..99938f78 100644 --- a/core/msvc8/sourcemod_mm.vcproj +++ b/core/msvc8/sourcemod_mm.vcproj @@ -179,7 +179,11 @@ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > + + @@ -189,7 +193,7 @@ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > + + -#include "mm_api.h" +#include "sourcemm_api.h" #include "sm_version.h" -#include "systems/LibrarySys.h" +#include "CTextParsers.h" SourceMod_Core g_SourceMod; PLUGIN_EXPOSE(SourceMod, g_SourceMod); +class Test : public ITextListener_INI +{ +public: +}; + bool SourceMod_Core::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late) { PLUGIN_SAVEVARS(); + Test test; + bool result = g_TextParse.ParseFile_INI("c:\\gaben.ini", &test, NULL, NULL); + return true; } diff --git a/core/mm_api.h b/core/sourcemm_api.h similarity index 100% rename from core/mm_api.h rename to core/sourcemm_api.h diff --git a/core/systems/LibrarySys.h b/core/systems/LibrarySys.h index f471745d..1937523c 100644 --- a/core/systems/LibrarySys.h +++ b/core/systems/LibrarySys.h @@ -48,7 +48,7 @@ private: LibraryHandle m_lib; }; -class LibrarySystem +class LibrarySystem : public ILibrarySys { public: virtual ILibrary *OpenLibrary(const char *path, char *error, size_t err_max);