Expose ParseFile_INI to API.
Some minor changes have been made in parser: - Added ReadINI_ParseStart and ReadINI_ParseEnd call. - Function returns SMCResult instead of bool. To avoid unecessary complexity and duplicating natives, this feels more appropriate to let these functions to share some SMCResult and SMCParse constants. Since properly documented, this should be ok. - Made sure curtok is set to 0 when ptr_val is null, otherwise unexpected value would be passed into the forward.
This commit is contained in:
@ -778,7 +778,7 @@ failed:
|
||||
* INI parser
|
||||
*/
|
||||
|
||||
bool TextParsers::ParseFile_INI(const char *file, ITextListener_INI *ini_listener, unsigned int *line, unsigned int *col)
|
||||
SMCError TextParsers::ParseFile_INI(const char *file, ITextListener_INI *ini_listener, unsigned int *line, unsigned int *col)
|
||||
{
|
||||
FILE *fp = fopen(file, "rt");
|
||||
unsigned int curline = 0;
|
||||
@ -792,12 +792,16 @@ bool TextParsers::ParseFile_INI(const char *file, ITextListener_INI *ini_listene
|
||||
*line = 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
return SMCError_StreamOpen;
|
||||
}
|
||||
|
||||
ini_listener->ReadINI_ParseStart();
|
||||
|
||||
char buffer[2048];
|
||||
char *ptr, *save_ptr;
|
||||
bool in_quote;
|
||||
SMCError err = SMCError_Okay;
|
||||
SMCResult res = SMCResult_Continue;
|
||||
|
||||
while (!feof(fp))
|
||||
{
|
||||
@ -897,8 +901,9 @@ bool TextParsers::ParseFile_INI(const char *file, ITextListener_INI *ini_listene
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ini_listener->ReadINI_RawLine(ptr, &curtok))
|
||||
if ((res = ini_listener->ReadINI_RawLine(ptr, curline, &curtok)) != SMCResult_Continue)
|
||||
{
|
||||
err = (res == SMCResult_HaltFail) ? SMCError_Custom : SMCError_Okay;
|
||||
goto event_failed;
|
||||
}
|
||||
|
||||
@ -951,8 +956,9 @@ bool TextParsers::ParseFile_INI(const char *file, ITextListener_INI *ini_listene
|
||||
}
|
||||
|
||||
/* Tell the handler */
|
||||
if (!ini_listener->ReadINI_NewSection(&ptr[1], invalid_tokens, got_bracket, extra_tokens, &curtok))
|
||||
if ((res = ini_listener->ReadINI_NewSection(&ptr[1], invalid_tokens, got_bracket, extra_tokens, &curtok)) != SMCResult_Continue)
|
||||
{
|
||||
err = (res == SMCResult_HaltFail) ? SMCError_Custom : SMCError_Okay;
|
||||
goto event_failed;
|
||||
}
|
||||
}
|
||||
@ -1052,9 +1058,14 @@ bool TextParsers::ParseFile_INI(const char *file, ITextListener_INI *ini_listene
|
||||
}
|
||||
skip_value:
|
||||
/* We're done! */
|
||||
curtok = val_ptr - buffer;
|
||||
if (!ini_listener->ReadINI_KeyValue(key_ptr, val_ptr, invalid_tokens, equal_token, quotes, &curtok))
|
||||
if (val_ptr)
|
||||
curtok = val_ptr - buffer;
|
||||
else
|
||||
curtok = 0;
|
||||
|
||||
if ((res = ini_listener->ReadINI_KeyValue(key_ptr, val_ptr, invalid_tokens, equal_token, quotes, &curtok)) != SMCResult_Continue)
|
||||
{
|
||||
err = (res == SMCResult_HaltFail) ? SMCError_Custom : SMCError_Okay;
|
||||
curtok = 0;
|
||||
goto event_failed;
|
||||
}
|
||||
@ -1066,9 +1077,16 @@ bool TextParsers::ParseFile_INI(const char *file, ITextListener_INI *ini_listene
|
||||
*line = curline;
|
||||
}
|
||||
|
||||
if (col)
|
||||
{
|
||||
*col = curtok;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return true;
|
||||
ini_listener->ReadINI_ParseEnd(false, false);
|
||||
|
||||
return SMCError_Okay;
|
||||
|
||||
event_failed:
|
||||
if (line)
|
||||
@ -1083,7 +1101,9 @@ event_failed:
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return false;
|
||||
ini_listener->ReadINI_ParseEnd(true, (err == SMCError_Custom));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
const char *TextParsers::GetSMCErrorString(SMCError err)
|
||||
|
@ -51,7 +51,7 @@ class TextParsers : public ITextParsers
|
||||
public:
|
||||
TextParsers();
|
||||
public:
|
||||
bool ParseFile_INI(const char *file,
|
||||
SMCError ParseFile_INI(const char *file,
|
||||
ITextListener_INI *ini_listener,
|
||||
unsigned int *line,
|
||||
unsigned int *col);
|
||||
|
@ -392,6 +392,7 @@
|
||||
<ClInclude Include="..\sh_stack.h" />
|
||||
<ClInclude Include="..\sh_tinyhash.h" />
|
||||
<ClInclude Include="..\svn_version.h" />
|
||||
<ClInclude Include="..\textparse.h" />
|
||||
<ClInclude Include="..\trie_natives.h" />
|
||||
<ClInclude Include="..\zlib\zconf.h" />
|
||||
<ClInclude Include="..\zlib\zlib.h" />
|
||||
|
@ -323,18 +323,12 @@
|
||||
<ClInclude Include="..\CDataPack.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
<ClInclude Include="..\sm_stringhashmap.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\sm_memtable.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\CTextParsers.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
>>>>>>> Introduce TextParser API.
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\textparse.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\version.rc">
|
||||
|
@ -37,7 +37,12 @@ TextParserHandles<ParseInfo> g_TextParsersHandles;
|
||||
|
||||
static cell AMX_NATIVE_CALL SMC_CreateParser(AMX *amx, cell *params)
|
||||
{
|
||||
return static_cast<cell>(g_TextParsersHandles.create());
|
||||
int handle = g_TextParsersHandles.create();
|
||||
ParseInfo *p = g_TextParsersHandles.lookup(handle);
|
||||
|
||||
p->ini_format = params[1] > 0 ? true : false;
|
||||
|
||||
return static_cast<cell>(handle);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL SMC_SetParseStart(AMX *amx, cell *params)
|
||||
@ -77,7 +82,7 @@ static cell AMX_NATIVE_CALL SMC_SetParseEnd(AMX *amx, cell *params)
|
||||
|
||||
int length;
|
||||
const char* funcName = get_amxstring(amx, params[2], 0, length);
|
||||
int func = registerSPForwardByName(amx, funcName, FP_CELL, FP_DONE);
|
||||
int func = registerSPForwardByName(amx, funcName, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
|
||||
if (func == -1)
|
||||
{
|
||||
@ -101,34 +106,50 @@ static cell AMX_NATIVE_CALL SMC_SetReaders(AMX *amx, cell *params)
|
||||
}
|
||||
|
||||
int length;
|
||||
const char* NewSectionFuncName = get_amxstring(amx, params[2], 0, length);
|
||||
const char* KeyValueFuncName = get_amxstring(amx, params[3], 1, length);
|
||||
const char* EndSectionFuncName = get_amxstring(amx, params[4], 2, length);
|
||||
const char* newSectionFuncName = get_amxstring(amx, params[2], 0, length);
|
||||
const char* keyValueFuncName = get_amxstring(amx, params[3], 1, length);
|
||||
const char* endSectionFuncName = get_amxstring(amx, params[4], 2, length);
|
||||
|
||||
int NewSectionFunc = registerSPForwardByName(amx, NewSectionFuncName, FP_CELL, FP_STRING, FP_DONE);
|
||||
if (NewSectionFunc == -1)
|
||||
int newSectionFunc;
|
||||
int keyValueFunc;
|
||||
int endSectionFunc;
|
||||
|
||||
if (p->ini_format)
|
||||
newSectionFunc = registerSPForwardByName(amx, newSectionFuncName, FP_CELL, FP_STRING, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
else
|
||||
newSectionFunc = registerSPForwardByName(amx, newSectionFuncName, FP_CELL, FP_STRING, FP_DONE);
|
||||
|
||||
if (newSectionFunc == -1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Function is not present (function \"%s\") (plugin \"%s\")", NewSectionFuncName, g_plugins.findPluginFast(amx)->getName());
|
||||
LogError(amx, AMX_ERR_NATIVE, "Function is not present (function \"%s\") (plugin \"%s\")", newSectionFuncName, g_plugins.findPluginFast(amx)->getName());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int KeyValueFunc = registerSPForwardByName(amx, KeyValueFuncName, FP_CELL, FP_STRING, FP_STRING, FP_DONE);
|
||||
if (KeyValueFunc == -1)
|
||||
if (p->ini_format)
|
||||
keyValueFunc = registerSPForwardByName(amx, keyValueFuncName, FP_CELL, FP_STRING, FP_STRING, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
else
|
||||
keyValueFunc = registerSPForwardByName(amx, keyValueFuncName, FP_CELL, FP_STRING, FP_STRING, FP_DONE);
|
||||
|
||||
if (keyValueFunc == -1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Function is not present (function \"%s\") (plugin \"%s\")", KeyValueFuncName, g_plugins.findPluginFast(amx)->getName());
|
||||
LogError(amx, AMX_ERR_NATIVE, "Function is not present (function \"%s\") (plugin \"%s\")", keyValueFuncName, g_plugins.findPluginFast(amx)->getName());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EndSectionFunc = registerSPForwardByName(amx, EndSectionFuncName, FP_CELL, FP_DONE);
|
||||
if (EndSectionFunc == -1)
|
||||
if (!p->ini_format)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Function is not present (function \"%s\") (plugin \"%s\")", EndSectionFuncName, g_plugins.findPluginFast(amx)->getName());
|
||||
return 0;
|
||||
endSectionFunc = registerSPForwardByName(amx, endSectionFuncName, FP_CELL, FP_DONE);
|
||||
if (endSectionFunc == -1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Function is not present (function \"%s\") (plugin \"%s\")", endSectionFuncName, g_plugins.findPluginFast(amx)->getName());
|
||||
return 0;
|
||||
}
|
||||
|
||||
p->end_section = endSectionFunc;
|
||||
}
|
||||
|
||||
p->new_section = NewSectionFunc;
|
||||
p->key_value = KeyValueFunc;
|
||||
p->end_section = EndSectionFunc;
|
||||
p->new_section = newSectionFunc;
|
||||
p->key_value = keyValueFunc;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -146,7 +167,12 @@ static cell AMX_NATIVE_CALL SMC_SetRawLine(AMX *amx, cell *params)
|
||||
int length;
|
||||
const char* funcName = get_amxstring(amx, params[2], 0, length);
|
||||
|
||||
int func = registerSPForwardByName(amx, funcName, FP_CELL, FP_STRING, FP_CELL, FP_DONE);
|
||||
int func;
|
||||
if (p->ini_format)
|
||||
func = registerSPForwardByName(amx, funcName, FP_CELL, FP_STRING, FP_CELL, FP_CELL, FP_DONE);
|
||||
else
|
||||
func = registerSPForwardByName(amx, funcName, FP_CELL, FP_STRING, FP_CELL, FP_DONE);
|
||||
|
||||
if (func == -1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Function is not present (function \"%s\") (plugin \"%s\")", funcName, g_plugins.findPluginFast(amx)->getName());
|
||||
@ -171,13 +197,26 @@ static cell AMX_NATIVE_CALL SMC_ParseFile(AMX *amx, cell *params)
|
||||
int length;
|
||||
const char *file = build_pathname("%s", get_amxstring(amx, params[2], 0, length));
|
||||
|
||||
SMCStates states;
|
||||
SMCError p_err = textparsers->ParseFile_SMC(file, p, &states);
|
||||
SMCError p_err;
|
||||
|
||||
*get_amxaddr(amx, params[3]) = states.line;
|
||||
*get_amxaddr(amx, params[4]) = states.col;
|
||||
if (p->ini_format)
|
||||
{
|
||||
size_t line, col;
|
||||
p_err = textparsers->ParseFile_INI(file, p, &line, &col);
|
||||
|
||||
return (cell)p_err;
|
||||
*get_amxaddr(amx, params[3]) = line;
|
||||
*get_amxaddr(amx, params[4]) = col;
|
||||
}
|
||||
else
|
||||
{
|
||||
SMCStates states;
|
||||
p_err = textparsers->ParseFile_SMC(file, p, &states);
|
||||
|
||||
*get_amxaddr(amx, params[3]) = states.line;
|
||||
*get_amxaddr(amx, params[4]) = states.col;
|
||||
}
|
||||
|
||||
return static_cast<cell>(p_err);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL SMC_GetErrorString(AMX *amx, cell *params)
|
||||
|
@ -35,7 +35,9 @@
|
||||
#include "amxmodx.h"
|
||||
#include "CTextParsers.h"
|
||||
|
||||
class ParseInfo : public ITextListener_SMC
|
||||
class ParseInfo :
|
||||
public ITextListener_SMC,
|
||||
public ITextListener_INI
|
||||
{
|
||||
public:
|
||||
ParseInfo()
|
||||
@ -47,31 +49,43 @@ public:
|
||||
end_section = -1;
|
||||
raw_line = -1;
|
||||
handle = -1;
|
||||
ini_format = false;
|
||||
}
|
||||
~ParseInfo() {}
|
||||
|
||||
public:
|
||||
void ReadSMC_ParseStart()
|
||||
{
|
||||
if (parse_start != -1)
|
||||
{
|
||||
if (parse_start != -1)
|
||||
executeForwards(parse_start, handle);
|
||||
}
|
||||
void ReadINI_ParseStart()
|
||||
{
|
||||
if (parse_start != -1)
|
||||
executeForwards(parse_start, handle);
|
||||
}
|
||||
}
|
||||
|
||||
void ReadSMC_ParseEnd(bool halted, bool failed)
|
||||
{
|
||||
if (parse_end != -1)
|
||||
{
|
||||
if (parse_end != -1)
|
||||
executeForwards(parse_end, handle, halted ? 1 : 0, failed ? 1 : 0);
|
||||
}
|
||||
void ReadINI_ParseEnd(bool halted, bool failed)
|
||||
{
|
||||
if (parse_end != -1)
|
||||
executeForwards(parse_end, handle, halted ? 1 : 0, failed ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name)
|
||||
{
|
||||
if (new_section != -1)
|
||||
{
|
||||
return (SMCResult)executeForwards(new_section, handle, name);
|
||||
}
|
||||
|
||||
return SMCResult_Continue;
|
||||
}
|
||||
SMCResult ReadINI_NewSection(const char *section, bool invalid_tokens, bool close_bracket, bool extra_tokens, unsigned int *curtok)
|
||||
{
|
||||
if (new_section != -1)
|
||||
return (SMCResult)executeForwards(new_section, handle, section, invalid_tokens, close_bracket, extra_tokens, *curtok);
|
||||
|
||||
return SMCResult_Continue;
|
||||
}
|
||||
@ -79,9 +93,14 @@ public:
|
||||
SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
|
||||
{
|
||||
if (key_value != -1)
|
||||
{
|
||||
return (SMCResult)executeForwards(key_value, handle, key, value);
|
||||
}
|
||||
|
||||
return SMCResult_Continue;
|
||||
}
|
||||
SMCResult ReadINI_KeyValue(const char *key, const char *value, bool invalid_tokens, bool equal_token, bool quotes, unsigned int *curtok)
|
||||
{
|
||||
if (key_value != -1)
|
||||
return (SMCResult)executeForwards(key_value, handle, key, value, invalid_tokens, equal_token, quotes, *curtok);
|
||||
|
||||
return SMCResult_Continue;
|
||||
}
|
||||
@ -89,9 +108,7 @@ public:
|
||||
SMCResult ReadSMC_LeavingSection(const SMCStates *states)
|
||||
{
|
||||
if (end_section != -1)
|
||||
{
|
||||
return (SMCResult)executeForwards(end_section, handle, handle);
|
||||
}
|
||||
return (SMCResult)executeForwards(end_section, handle);
|
||||
|
||||
return SMCResult_Continue;
|
||||
}
|
||||
@ -99,9 +116,14 @@ public:
|
||||
SMCResult ReadSMC_RawLine(const SMCStates *states, const char *line)
|
||||
{
|
||||
if (raw_line != -1)
|
||||
{
|
||||
return (SMCResult)executeForwards(raw_line, handle, line, states->line);
|
||||
}
|
||||
|
||||
return SMCResult_Continue;
|
||||
}
|
||||
SMCResult ReadINI_RawLine(const char *line, unsigned int lineno, unsigned int *curtok)
|
||||
{
|
||||
if (raw_line != -1)
|
||||
return (SMCResult)executeForwards(raw_line, handle, line, lineno, *curtok);
|
||||
|
||||
return SMCResult_Continue;
|
||||
}
|
||||
@ -113,6 +135,7 @@ public:
|
||||
int end_section;
|
||||
int raw_line;
|
||||
int handle;
|
||||
bool ini_format;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
Reference in New Issue
Block a user