Merge pull request #173 from alliedmodders/tr-smc

Port SMC parsing API to transitional syntax.
This commit is contained in:
David Anderson
2014-11-19 22:38:19 -08:00
8 changed files with 281 additions and 228 deletions
+20 -22
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 {
+30 -33
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 {
+11 -12
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);
}
+11 -11
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]);
}
+12 -12
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)
{
}
+120 -77
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);