Port SMC parsing API to transitional syntax.

This commit is contained in:
David Anderson 2014-10-29 20:41:36 -07:00
parent 53a1dbdafd
commit 8479c2f067
8 changed files with 281 additions and 228 deletions

View File

@ -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",

View File

@ -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 <ITextParsers.h>
#include <ISourceMod.h>
#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<ParseInfo> 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<ParseInfo> 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<ParseInfo> 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<ParseInfo> 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<ParseInfo> 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<ParseInfo> 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<ParseInfo> 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<ParseInfo> 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<ParseInfo> 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},
};

View File

@ -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 {

View File

@ -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 {

View File

@ -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);
}

View File

@ -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]);
}

View File

@ -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)
{
}

View File

@ -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);