diff --git a/core/logic/TextParsers.cpp b/core/logic/TextParsers.cpp index abe5bffa..4d817cc6 100644 --- a/core/logic/TextParsers.cpp +++ b/core/logic/TextParsers.cpp @@ -1077,7 +1077,7 @@ const char *TextParsers::GetSMCErrorString(SMCError err) NULL, "Stream failed to open", "Stream returned read error", - NULL, + "Callback error", "Un-quoted section has invalid tokens", "Section declared without header", "Section declared with unknown tokens", diff --git a/core/logic/smn_textparse.cpp b/core/logic/smn_textparse.cpp index 865ea5cd..0ba919c2 100644 --- a/core/logic/smn_textparse.cpp +++ b/core/logic/smn_textparse.cpp @@ -1,8 +1,8 @@ /** - * vim: set ts=4 : + * vim: set ts=4 sw=4 tw=99 noet : * ============================================================================= * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. + * Copyright (C) 2004-2014 AlliedModders LLC. All rights reserved. * ============================================================================= * * This program is free software; you can redistribute it and/or modify it under @@ -32,6 +32,7 @@ #include "common_logic.h" #include #include +#include "handle_helpers.h" HandleType_t g_TypeSMC = 0; @@ -199,90 +200,51 @@ static cell_t SMC_CreateParser(IPluginContext *pContext, const cell_t *params) static cell_t SMC_SetParseStart(IPluginContext *pContext, const cell_t *params) { - Handle_t hndl = (Handle_t)params[1]; - HandleError err; - ParseInfo *parse; - HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent); - - if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, &sec, (void **)&parse)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err); - } + OpenHandle parse(pContext, params[1], g_TypeSMC); + if (!parse.Ok()) + return 0; parse->parse_start = pContext->GetFunctionById((funcid_t)params[2]); - return 1; } static cell_t SMC_SetParseEnd(IPluginContext *pContext, const cell_t *params) { - Handle_t hndl = (Handle_t)params[1]; - HandleError err; - ParseInfo *parse; - HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent); - - if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, &sec, (void **)&parse)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err); - } + OpenHandle parse(pContext, params[1], g_TypeSMC); + if (!parse.Ok()) + return 0; parse->parse_end = pContext->GetFunctionById((funcid_t)params[2]); - return 1; } static cell_t SMC_SetReaders(IPluginContext *pContext, const cell_t *params) { - Handle_t hndl = (Handle_t)params[1]; - HandleError err; - ParseInfo *parse; - HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent); - - if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, &sec, (void **)&parse)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err); - } + OpenHandle parse(pContext, params[1], g_TypeSMC); + if (!parse.Ok()) + return 0; parse->new_section = pContext->GetFunctionById((funcid_t)params[2]); parse->key_value = pContext->GetFunctionById((funcid_t)params[3]); parse->end_section = pContext->GetFunctionById((funcid_t)params[4]); - return 1; } static cell_t SMC_SetRawLine(IPluginContext *pContext, const cell_t *params) { - Handle_t hndl = (Handle_t)params[1]; - HandleError err; - ParseInfo *parse; - HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent); - - if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, &sec, (void **)&parse)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err); - } + OpenHandle parse(pContext, params[1], g_TypeSMC); + if (!parse.Ok()) + return 0; parse->raw_line = pContext->GetFunctionById((funcid_t)params[2]); - return 1; } static cell_t SMC_ParseFile(IPluginContext *pContext, const cell_t *params) { - Handle_t hndl = (Handle_t)params[1]; - HandleError err; - ParseInfo *parse; - HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent); - - if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, &sec, (void **)&parse)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err); - } + OpenHandle parse(pContext, params[1], g_TypeSMC); + if (!parse.Ok()) + return 0; char *file; pContext->LocalToString(params[2], &file); @@ -299,21 +261,63 @@ static cell_t SMC_ParseFile(IPluginContext *pContext, const cell_t *params) *c_line = states.line; *c_col = states.col; - return (cell_t)p_err; } static cell_t SMC_GetErrorString(IPluginContext *pContext, const cell_t *params) { const char *str = textparsers->GetSMCErrorString((SMCError)params[1]); - if (!str) - { return 0; - } pContext->StringToLocal(params[2], params[3], str); + return 1; +} +static cell_t SMCParser_OnEnterSection_set(IPluginContext *pContext, const cell_t *params) +{ + OpenHandle parse(pContext, params[1], g_TypeSMC); + if (!parse.Ok()) + return 0; + + parse->new_section = pContext->GetFunctionById((funcid_t)params[2]); + return 1; +} + +static cell_t SMCParser_OnLeaveSection_set(IPluginContext *pContext, const cell_t *params) +{ + OpenHandle parse(pContext, params[1], g_TypeSMC); + if (!parse.Ok()) + return 0; + + parse->end_section = pContext->GetFunctionById((funcid_t)params[2]); + return 1; +} + +static cell_t SMCParser_OnKeyValue_set(IPluginContext *pContext, const cell_t *params) +{ + OpenHandle parse(pContext, params[1], g_TypeSMC); + if (!parse.Ok()) + return 0; + + parse->key_value = pContext->GetFunctionById((funcid_t)params[2]); + return 1; +} + +static cell_t SMCParser_GetErrorString(IPluginContext *pContext, const cell_t *params) +{ + OpenHandle parse(pContext, params[1], g_TypeSMC); + if (!parse.Ok()) + return 0; + + const char *str = "no error"; + if (params[2]) { + str = textparsers->GetSMCErrorString((SMCError)params[2]); + if (!str) + str = "unknown error"; + } + + pContext->StringToLocal(params[3], params[4], str); return 1; } @@ -326,5 +330,17 @@ REGISTER_NATIVES(textNatives) {"SMC_SetParseEnd", SMC_SetParseEnd}, {"SMC_SetReaders", SMC_SetReaders}, {"SMC_SetRawLine", SMC_SetRawLine}, + + // Transitional syntax support. + {"SMCParser.SMCParser", SMC_CreateParser}, + {"SMCParser.ParseFile", SMC_ParseFile}, + {"SMCParser.OnStart.set", SMC_SetParseStart}, + {"SMCParser.OnEnd.set", SMC_SetParseEnd}, + {"SMCParser.OnEnterSection.set", SMCParser_OnEnterSection_set}, + {"SMCParser.OnLeaveSection.set", SMCParser_OnLeaveSection_set}, + {"SMCParser.OnKeyValue.set", SMCParser_OnKeyValue_set}, + {"SMCParser.OnRawLine.set", SMC_SetRawLine}, + {"SMCParser.GetErrorString", SMCParser_GetErrorString}, + {NULL, NULL}, }; diff --git a/plugins/admin-flatfile/admin-groups.sp b/plugins/admin-flatfile/admin-groups.sp index 3ed5343f..4e5f1ee6 100644 --- a/plugins/admin-flatfile/admin-groups.sp +++ b/plugins/admin-flatfile/admin-groups.sp @@ -1,5 +1,5 @@ /** - * vim: set ts=4 : + * vim: set ts=4 sw=4 tw=99 noet : * ============================================================================= * SourceMod Admin File Reader Plugin * Reads the admin_groups.cfg file. Do not compile this directly. @@ -38,13 +38,13 @@ #define GROUP_PASS_FIRST 1 #define GROUP_PASS_SECOND 2 -static Handle:g_hGroupParser = INVALID_HANDLE; +static SMCParser g_hGroupParser; static GroupId:g_CurGrp = INVALID_GROUP_ID; static g_GroupState = GROUP_STATE_NONE; static g_GroupPass = 0; static bool:g_NeedReparse = false; -public SMCResult:ReadGroups_NewSection(Handle:smc, const String:name[], bool:opt_quotes) +public SMCResult ReadGroups_NewSection(SMCParser smc, const char[] name, bool opt_quotes) { if (g_IgnoreLevel) { @@ -80,14 +80,13 @@ public SMCResult:ReadGroups_NewSection(Handle:smc, const String:name[], bool:opt return SMCParse_Continue; } -public SMCResult:ReadGroups_KeyValue(Handle:smc, - const String:key[], - const String:value[], - bool:key_quotes, - bool:value_quotes) +public SMCResult ReadGroups_KeyValue(SMCParser smc, + const char[] key, + const char[] value, + bool key_quotes, + bool value_quotes) { - if (g_CurGrp == INVALID_GROUP_ID - || g_IgnoreLevel) + if (g_CurGrp == INVALID_GROUP_ID || g_IgnoreLevel) { return SMCParse_Continue; } @@ -165,7 +164,7 @@ public SMCResult:ReadGroups_KeyValue(Handle:smc, return SMCParse_Continue; } -public SMCResult:ReadGroups_EndSection(Handle:smc) +public SMCResult ReadGroups_EndSection(SMCParser smc) { /* If we're ignoring, skip out */ if (g_IgnoreLevel) @@ -187,7 +186,7 @@ public SMCResult:ReadGroups_EndSection(Handle:smc) return SMCParse_Continue; } -public SMCResult:ReadGroups_CurrentLine(Handle:smc, const String:line[], lineno) +public SMCResult ReadGroups_CurrentLine(SMCParser smc, const char[] line, int lineno) { g_CurrentLine = lineno; @@ -196,14 +195,13 @@ public SMCResult:ReadGroups_CurrentLine(Handle:smc, const String:line[], lineno) static InitializeGroupParser() { - if (g_hGroupParser == INVALID_HANDLE) + if (!g_hGroupParser) { - g_hGroupParser = SMC_CreateParser(); - SMC_SetReaders(g_hGroupParser, - ReadGroups_NewSection, - ReadGroups_KeyValue, - ReadGroups_EndSection); - SMC_SetRawLine(g_hGroupParser, ReadGroups_CurrentLine); + g_hGroupParser = SMCParser(); + g_hGroupParser.OnEnterSection = ReadGroups_NewSection; + g_hGroupParser.OnKeyValue = ReadGroups_KeyValue; + g_hGroupParser.OnLeaveSection = ReadGroups_EndSection; + g_hGroupParser.OnRawLine = ReadGroups_CurrentLine; } } @@ -216,11 +214,11 @@ static InternalReadGroups(const String:path[], pass) g_GroupPass = pass; g_NeedReparse = false; - new SMCError:err = SMC_ParseFile(g_hGroupParser, path); + SMCError err = g_hGroupParser.ParseFile(path); if (err != SMCError_Okay) { - decl String:buffer[64]; - if (SMC_GetErrorString(err, buffer, sizeof(buffer))) + char buffer[64]; + if (g_hGroupParser.GetErrorString(err, buffer, sizeof(buffer))) { ParseError("%s", buffer); } else { diff --git a/plugins/admin-flatfile/admin-overrides.sp b/plugins/admin-flatfile/admin-overrides.sp index a8adbdc1..b02ad058 100644 --- a/plugins/admin-flatfile/admin-overrides.sp +++ b/plugins/admin-flatfile/admin-overrides.sp @@ -36,11 +36,11 @@ #define OVERRIDE_STATE_LEVELS 1 #define OVERRIDE_STATE_OVERRIDES 2 -static Handle:g_hOldOverrideParser = INVALID_HANDLE; -static Handle:g_hNewOverrideParser = INVALID_HANDLE; +static SMCParser g_hOldOverrideParser; +static SMCParser g_hNewOverrideParser; static g_OverrideState = OVERRIDE_STATE_NONE; -public SMCResult:ReadOldOverrides_NewSection(Handle:smc, const String:name[], bool:opt_quotes) +public SMCResult ReadOldOverrides_NewSection(SMCParser smc, const char[] name, bool opt_quotes) { if (g_IgnoreLevel) { @@ -70,7 +70,7 @@ public SMCResult:ReadOldOverrides_NewSection(Handle:smc, const String:name[], bo return SMCParse_Continue; } -public SMCResult:ReadNewOverrides_NewSection(Handle:smc, const String:name[], bool:opt_quotes) +public SMCResult ReadNewOverrides_NewSection(SMCParser smc, const char[] name, bool opt_quotes) { if (g_IgnoreLevel) { @@ -93,19 +93,18 @@ public SMCResult:ReadNewOverrides_NewSection(Handle:smc, const String:name[], bo return SMCParse_Continue; } -public SMCResult:ReadOverrides_KeyValue(Handle:smc, - const String:key[], - const String:value[], - bool:key_quotes, - bool:value_quotes) +public SMCResult ReadOverrides_KeyValue(SMCParser smc, + const char[] key, + const char[] value, + bool key_quotes, + bool value_quotes) { - if (g_OverrideState != OVERRIDE_STATE_OVERRIDES - || g_IgnoreLevel) + if (g_OverrideState != OVERRIDE_STATE_OVERRIDES || g_IgnoreLevel) { return SMCParse_Continue; } - new flags = ReadFlagString(value); + int flags = ReadFlagString(value); if (key[0] == '@') { @@ -117,7 +116,7 @@ public SMCResult:ReadOverrides_KeyValue(Handle:smc, return SMCParse_Continue; } -public SMCResult:ReadOldOverrides_EndSection(Handle:smc) +public SMCResult ReadOldOverrides_EndSection(SMCParser smc) { /* If we're ignoring, skip out */ if (g_IgnoreLevel) @@ -138,7 +137,7 @@ public SMCResult:ReadOldOverrides_EndSection(Handle:smc) return SMCParse_Continue; } -public SMCResult:ReadNewOverrides_EndSection(Handle:smc) +public SMCResult ReadNewOverrides_EndSection(SMCParser smc) { /* If we're ignoring, skip out */ if (g_IgnoreLevel) @@ -155,7 +154,7 @@ public SMCResult:ReadNewOverrides_EndSection(Handle:smc) return SMCParse_Continue; } -public SMCResult:ReadOverrides_CurrentLine(Handle:smc, const String:line[], lineno) +public SMCResult ReadOverrides_CurrentLine(SMCParser smc, const char[] line, int lineno) { g_CurrentLine = lineno; @@ -164,27 +163,25 @@ public SMCResult:ReadOverrides_CurrentLine(Handle:smc, const String:line[], line static InitializeOverrideParsers() { - if (g_hOldOverrideParser == INVALID_HANDLE) + if (!g_hOldOverrideParser) { - g_hOldOverrideParser = SMC_CreateParser(); - SMC_SetReaders(g_hOldOverrideParser, - ReadOldOverrides_NewSection, - ReadOverrides_KeyValue, - ReadOldOverrides_EndSection); - SMC_SetRawLine(g_hOldOverrideParser, ReadOverrides_CurrentLine); + g_hOldOverrideParser = SMCParser(); + g_hOldOverrideParser.OnEnterSection = ReadOldOverrides_NewSection; + g_hOldOverrideParser.OnKeyValue = ReadOverrides_KeyValue; + g_hOldOverrideParser.OnLeaveSection = ReadOldOverrides_EndSection; + g_hOldOverrideParser.OnRawLine = ReadOverrides_CurrentLine; } - if (g_hNewOverrideParser == INVALID_HANDLE) + if (!g_hNewOverrideParser) { - g_hNewOverrideParser = SMC_CreateParser(); - SMC_SetReaders(g_hNewOverrideParser, - ReadNewOverrides_NewSection, - ReadOverrides_KeyValue, - ReadNewOverrides_EndSection); - SMC_SetRawLine(g_hNewOverrideParser, ReadOverrides_CurrentLine); + g_hNewOverrideParser = SMCParser(); + g_hNewOverrideParser.OnEnterSection = ReadNewOverrides_NewSection; + g_hNewOverrideParser.OnKeyValue = ReadOverrides_KeyValue; + g_hNewOverrideParser.OnLeaveSection = ReadNewOverrides_EndSection; + g_hNewOverrideParser.OnRawLine = ReadOverrides_CurrentLine; } } -InternalReadOverrides(Handle:parser, const String:file[]) +InternalReadOverrides(SMCParser parser, const char[] file) { BuildPath(Path_SM, g_Filename, sizeof(g_Filename), file); @@ -192,11 +189,11 @@ InternalReadOverrides(Handle:parser, const String:file[]) InitGlobalStates(); g_OverrideState = OVERRIDE_STATE_NONE; - new SMCError:err = SMC_ParseFile(parser, g_Filename); + SMCError err = parser.ParseFile(g_Filename); if (err != SMCError_Okay) { - decl String:buffer[64]; - if (SMC_GetErrorString(err, buffer, sizeof(buffer))) + char buffer[64]; + if (parser.GetErrorString(err, buffer, sizeof(buffer))) { ParseError("%s", buffer); } else { diff --git a/plugins/admin-flatfile/admin-users.sp b/plugins/admin-flatfile/admin-users.sp index c8c978e5..a47f2eb7 100644 --- a/plugins/admin-flatfile/admin-users.sp +++ b/plugins/admin-flatfile/admin-users.sp @@ -1,5 +1,5 @@ /** - * vim: set ts=4 : + * vim: set ts=4 sw=4 tw=99 noet : * ============================================================================= * SourceMod Admin File Reader Plugin * Reads the admins.cfg file. Do not compile this directly. @@ -35,7 +35,7 @@ #define USER_STATE_ADMINS 1 #define USER_STATE_INADMIN 2 -static Handle:g_hUserParser = INVALID_HANDLE; +static SMCParser g_hUserParser; static g_UserState = USER_STATE_NONE; static String:g_CurAuth[64]; static String:g_CurIdent[64]; @@ -210,14 +210,13 @@ public SMCResult:ReadUsers_CurrentLine(Handle:smc, const String:line[], lineno) static InitializeUserParser() { - if (g_hUserParser == INVALID_HANDLE) + if (!g_hUserParser) { - g_hUserParser = SMC_CreateParser(); - SMC_SetReaders(g_hUserParser, - ReadUsers_NewSection, - ReadUsers_KeyValue, - ReadUsers_EndSection); - SMC_SetRawLine(g_hUserParser, ReadUsers_CurrentLine); + g_hUserParser = SMCParser(); + g_hUserParser.OnEnterSection = ReadUsers_NewSection; + g_hUserParser.OnKeyValue = ReadUsers_KeyValue; + g_hUserParser.OnLeaveSection = ReadUsers_EndSection; + g_hUserParser.OnRawLine = ReadUsers_CurrentLine; g_GroupArray = CreateArray(); } @@ -233,11 +232,11 @@ ReadUsers() InitGlobalStates(); g_UserState = USER_STATE_NONE; - new SMCError:err = SMC_ParseFile(g_hUserParser, g_Filename); + SMCError err = g_hUserParser.ParseFile(g_Filename); if (err != SMCError_Okay) { - decl String:buffer[64]; - if (SMC_GetErrorString(err, buffer, sizeof(buffer))) + char buffer[64]; + if (g_hUserParser.GetErrorString(err, buffer, sizeof(buffer))) { ParseError("%s", buffer); } diff --git a/plugins/adminmenu/dynamicmenu.sp b/plugins/adminmenu/dynamicmenu.sp index 594b046c..966df030 100644 --- a/plugins/adminmenu/dynamicmenu.sp +++ b/plugins/adminmenu/dynamicmenu.sp @@ -13,7 +13,7 @@ enum GroupCommands new g_groupList[GroupCommands]; new g_groupCount; -new Handle:g_configParser = INVALID_HANDLE; +SMCParser g_configParser; enum Places { @@ -324,12 +324,12 @@ BuildDynamicMenu() ParseConfigs() { - if (g_configParser == INVALID_HANDLE) - { - g_configParser = SMC_CreateParser(); - } + if (!g_configParser) + g_configParser = SMCParser(); - SMC_SetReaders(g_configParser, NewSection, KeyValue, EndSection); + g_configParser.OnEnterSection = NewSection; + g_configParser.OnKeyValue = KeyValue; + g_configParser.OnLeaveSection = EndSection; if (g_groupList[groupListName] != INVALID_HANDLE) { @@ -363,8 +363,8 @@ ParseConfigs() return; } - new line; - new SMCError:err = SMC_ParseFile(g_configParser, configPath, line); + int line; + SMCError err = g_configParser.ParseFile(configPath, line); if (err != SMCError_Okay) { decl String:error[256]; @@ -376,18 +376,18 @@ ParseConfigs() return; } -public SMCResult:NewSection(Handle:smc, const String:name[], bool:opt_quotes) +public SMCResult NewSection(SMCParser smc, const char[] name, bool opt_quotes) { } -public SMCResult:KeyValue(Handle:smc, const String:key[], const String:value[], bool:key_quotes, bool:value_quotes) +public SMCResult KeyValue(SMCParser smc, const char[] key, const char[] value, bool key_quotes, bool value_quotes) { PushArrayString(g_groupList[groupListName], key); PushArrayString(g_groupList[groupListCommand], value); } -public SMCResult:EndSection(Handle:smc) +public SMCResult EndSection(SMCParser smc) { g_groupCount = GetArraySize(g_groupList[groupListName]); } diff --git a/plugins/basecommands/execcfg.sp b/plugins/basecommands/execcfg.sp index e7e2a384..afec934a 100644 --- a/plugins/basecommands/execcfg.sp +++ b/plugins/basecommands/execcfg.sp @@ -1,5 +1,5 @@ /** - * vim: set ts=4 : + * vim: set ts=4 sw=4 tw=99 noet : * ============================================================================= * SourceMod Basecommands Plugin * Provides exec cfg functionality @@ -106,15 +106,15 @@ public Action:Command_ExecCfg(client, args) return Plugin_Handled; } -new Handle:config_parser = INVALID_HANDLE; +SMCParser config_parser; ParseConfigs() { - if (config_parser == INVALID_HANDLE) - { - config_parser = SMC_CreateParser(); - } + if (!config_parser) + config_parser = SMCParser(); - SMC_SetReaders(config_parser, NewSection, KeyValue, EndSection); + config_parser.OnEnterSection = NewSection; + config_parser.OnLeaveSection = EndSection; + config_parser.OnKeyValue = KeyValue; if (g_ConfigMenu != INVALID_HANDLE) { @@ -135,8 +135,8 @@ ParseConfigs() return; } - new line; - new SMCError:err = SMC_ParseFile(config_parser, configPath, line); + int line; + SMCError err = config_parser.ParseFile(configPath, line); if (err != SMCError_Okay) { decl String:error[256]; @@ -148,17 +148,17 @@ ParseConfigs() return; } -public SMCResult:NewSection(Handle:smc, const String:name[], bool:opt_quotes) +public SMCResult NewSection(SMCParser smc, const char[] name, bool opt_quotes) { } -public SMCResult:KeyValue(Handle:smc, const String:key[], const String:value[], bool:key_quotes, bool:value_quotes) +public SMCResult KeyValue(SMCParser smc, const char[] key, const char[] value, bool key_quotes, bool value_quotes) { AddMenuItem(g_ConfigMenu, key, value); } -public SMCResult:EndSection(Handle:smc) +public SMCResult EndSection(SMCParser smc) { } diff --git a/plugins/include/textparse.inc b/plugins/include/textparse.inc index 95dcb4ed..7a88647a 100644 --- a/plugins/include/textparse.inc +++ b/plugins/include/textparse.inc @@ -1,7 +1,7 @@ /** - * vim: set ts=4 : + * vim: set ts=4 sw=4 tw=99 noet : * ============================================================================= - * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. + * SourceMod (C)2004-2014 AlliedModders LLC. All rights reserved. * ============================================================================= * * This file is part of the SourceMod/SourcePawn SDK. @@ -29,7 +29,7 @@ * * Version: $Id$ */ - + #if defined _textparse_included #endinput #endif @@ -45,7 +45,7 @@ /** * Parse result directive. */ -enum SMCResult +enum SMCResult: { SMCParse_Continue, /**< Continue parsing */ SMCParse_Halt, /**< Stop parsing here */ @@ -55,7 +55,7 @@ enum SMCResult /** * Parse error codes. */ -enum SMCError +enum SMCError: { SMCError_Okay = 0, /**< No error */ SMCError_StreamOpen, /**< Stream failed to open */ @@ -71,12 +71,117 @@ enum SMCError SMCError_InvalidProperty1, /**< A property was declared outside of any section */ }; +// Called when parsing is started. +// +// @param smc The SMC Parse Handle. +typedef SMC_ParseStart = function void (SMCParser smc); + +// Called when the parser is entering a new section or sub-section. +// +// Note: Enclosing quotes are always stripped. +// +// @param smc The SMC Parser. +// @param name String containing section name. +// @param opt_quotes True if the section name was quote-enclosed in the file. +// @return An SMCResult action to take. +typedef SMC_NewSection = function SMCResult (SMCParser smc, const char[] name, bool opt_quotes); + +// Called when the parser finds a new key/value pair. +// +// Note: Enclosing quotes are always stripped. +// +// @param smc The SMCParser. +// @param key String containing key name. +// @param value String containing value name. +// @param key_quotes Whether or not the key was enclosed in quotes. +// @param value_quotes Whether or not the value was enclosed in quotes. +// @return An SMCResult action to take. +typedef SMC_KeyValue = function SMCResult (SMCParser smc, const char[] key, const char[] value, bool key_quotes, bool value_quotes); + +// Called when the parser finds the end of the current section. +// +// @param smc The SMCParser. +// @return An SMCResult action to take. +typedef SMC_EndSection = function SMCResult (SMCParser smc); + +// Called when parsing is halted. +// +// @param smc The SMCParser. +// @param halted True if abnormally halted, false otherwise. +// @param failed True if parsing failed, false otherwise. +// @noreturn +typedef SMC_ParseEnd = function void (SMCParser smc, bool halted, bool failed); + +// Callback for whenever a new line of text is about to be parsed. +// +// @param smc The SMCParser. +// @param line A string containing the raw line from the file. +// @param lineno The line number it occurs on. +// @return An SMCResult action to take. +typedef SMC_RawLine = function SMCResult (SMCParser smc, const char[] line, int lineno); + +// An SMCParser is a callback-driven parser for SourceMod configuration files. +// SMC files are similar to Valve KeyValues format, with two key differences: +// (1) SMC cannot handle single-item entries (that is, a key with no value). +// (2) SMC files can have multi-line comment blocks, whereas KeyValues cannot. +methodmap SMCParser < Handle +{ + // Create a new SMC file format parser. + public native SMCParser(); + + // Parses an SMC file. + // + // @param file A string containing the file path. + // @param line An optional variable to store the last line number read. + // @param col An optional variable to store the last column number read. + // @return An SMCParseError result. + public native SMCError ParseFile(const char[] file, int &line = 0, int &col = 0); + + // Sets the callback for receiving SMC_ParseStart events. + property SMC_ParseStart OnStart { + public native set(SMC_ParseStart func); + } + + // Sets the callback for receiving SMC_ParseEnd events. + property SMC_ParseEnd OnEnd { + public native set(SMC_ParseEnd func); + } + + // Sets the callback for receiving SMC_NewSection events. + property SMC_NewSection OnEnterSection { + public native set(SMC_NewSection func); + } + + // Sets the callback for receiving SMC_EndSection events. + property SMC_EndSection OnLeaveSection { + public native set(SMC_EndSection func); + } + + // Sets the callback for receiving SMC_KeyValue events. + property SMC_KeyValue OnKeyValue { + public native set(SMC_KeyValue func); + } + + // Sets the callback for receiving SMC_RawLine events. + property SMC_RawLine OnRawLine { + public native set(SMC_RawLine func); + } + + // Gets an error string for an SMCError code. + // + // @param error The SMCParseError code. + // @param buffer A string buffer for the error (contents undefined on failure). + // @param buf_max The maximum size of the buffer. + // @return The number of characters written to buffer. + public native void GetErrorString(SMCError error, char[] buffer, int buf_max); +}; + /** * Creates a new SMC file format parser. This is used to set parse hooks. * * @return A new Handle to an SMC Parse structure. */ -native Handle:SMC_CreateParser(); +native SMCParser SMC_CreateParser(); /** * Parses an SMC file. @@ -86,9 +191,9 @@ native Handle:SMC_CreateParser(); * @param line An optional by reference cell to store the last line number read. * @param col An optional by reference cell to store the last column number read. * @return An SMCParseError result. - * @error Invalid or corrupt Handle. + * @error Invalid or corrupt Handle. */ -native SMCError:SMC_ParseFile(Handle:smc, const String:file[], &line=0, &col=0); +native SMCError SMC_ParseFile(Handle smc, const char[] file, int &line=0, int &col=0); /** * Gets an error string for an SMCError code. @@ -100,15 +205,7 @@ native SMCError:SMC_ParseFile(Handle:smc, const String:file[], &line=0, &col=0); * @param buf_max The maximum size of the buffer. * @return True on success, false otherwise. */ -native bool:SMC_GetErrorString(SMCError:error, String:buffer[], buf_max); - -/** - * Called when parsing is started. - * - * @param smc The SMC Parse Handle. - * @noreturn - */ -typedef SMC_ParseStart = function void (Handle smc); +native bool SMC_GetErrorString(SMCError error, char[] buffer, int buf_max); /** * Sets the SMC_ParseStart function of a parse Handle. @@ -116,19 +213,9 @@ typedef SMC_ParseStart = function void (Handle smc); * @param smc Handle to an SMC Parse. * @param func SMC_ParseStart function. * @noreturn - * @error Invalid or corrupt Handle. + * @error Invalid or corrupt Handle. */ -native SMC_SetParseStart(Handle:smc, SMC_ParseStart:func); - -/** - * Called when parsing is halted. - * - * @param smc The SMC Parse Handle. - * @param halted True if abnormally halted, false otherwise. - * @param failed True if parsing failed, false otherwise. - * @noreturn - */ -typedef SMC_ParseEnd = function void (Handle smc, bool halted, bool failed); +native SMC_SetParseStart(Handle smc, SMC_ParseStart func); /** * Sets the SMC_ParseEnd of a parse handle. @@ -136,41 +223,9 @@ typedef SMC_ParseEnd = function void (Handle smc, bool halted, bool failed); * @param smc Handle to an SMC Parse. * @param func SMC_ParseEnd function. * @noreturn - * @error Invalid or corrupt Handle. + * @error Invalid or corrupt Handle. */ -native SMC_SetParseEnd(Handle:smc, SMC_ParseEnd:func); - -/** - * Called when the parser is entering a new section or sub-section. - * @note Enclosing quotes are always stripped. - * - * @param smc The SMC Parse Handle. - * @param name String containing section name. - * @param opt_quotes True if the section name was quote-enclosed in the file. - * @return An SMCResult action to take. - */ -typedef SMC_NewSection = function SMCResult (Handle smc, const char[] name, bool opt_quotes); - -/** - * Called when the parser finds a new key/value pair. - * @note Enclosing quotes are always stripped. - * - * @param smc The SMC Parse Handle. - * @param key String containing key name. - * @param value String containing value name. - * @param key_quotes Whether or not the key was enclosed in quotes. - * @param value_quotes Whether or not the value was enclosed in quotes. - * @return An SMCResult action to take. - */ -typedef SMC_KeyValue = function SMCResult (Handle smc, const char[] key, const char[] value, bool key_quotes, bool value_quotes); - -/** - * Called when the parser finds the end of the current section. - * - * @param smc The SMC Parse Handle. - * @return An SMCResult action to take. - */ -typedef SMC_EndSection = function SMCResult (Handle smc); +native SMC_SetParseEnd(Handle smc, SMC_ParseEnd func); /** * Sets the three main reader functions. @@ -179,25 +234,13 @@ typedef SMC_EndSection = function SMCResult (Handle smc); * @param ns An SMC_NewSection function pointer. * @param kv An SMC_KeyValue function pointer. * @param es An SMC_EndSection function pointer. - * @noreturn */ -native SMC_SetReaders(Handle:smc, SMC_NewSection:ns, SMC_KeyValue:kv, SMC_EndSection:es); - -/** - * Called whenever a raw line is read. - * - * @param smc The SMC Parse Handle. - * @param line A string containing the raw line from the file. - * @param lineno The line number it occurs on. - * @return An SMCResult action to take. - */ -typedef SMC_RawLine = function SMCResult (Handle smc, const char[] line, int lineno); +native void SMC_SetReaders(Handle smc, SMC_NewSection ns, SMC_KeyValue kv, SMC_EndSection es); /** * Sets a raw line reader on an SMC parser Handle. * * @param smc Handle to an SMC Parse. * @param func SMC_RawLine function. - * @noreturn */ -native SMC_SetRawLine(Handle:smc, SMC_RawLine:func); +native void SMC_SetRawLine(Handle smc, SMC_RawLine func);