diff -r a4010b64eb2f -r 9a93a6e6ac01 extensions/regex/extension.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/regex/extension.cpp Thu Jan 10 22:01:36 2008 +0000
@@ -0,0 +1,212 @@
+/**
+ * vim: set ts=4 :
+ * =============================================================================
+ * SourceMod Sample Extension
+ * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
+ * =============================================================================
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, version 3.0, as published by the
+ * Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
+ *
+ * As a special exception, AlliedModders LLC gives you permission to link the
+ * code of this program (as well as its derivative works) to "Half-Life 2," the
+ * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+ * by the Valve Corporation. You must obey the GNU General Public License in
+ * all respects for all other code used. Additionally, AlliedModders LLC grants
+ * this exception to all derivative works. AlliedModders LLC defines further
+ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+ * or .
+ *
+ * Version: $Id: extension.cpp 1336 2007-08-15 06:19:30Z damagedsoul $
+ */
+
+#include "extension.h"
+
+#include
+#include
+#include "pcre.h"
+#include "CRegEx.h"
+using namespace SourceHook;
+
+/**
+ * @file extension.cpp
+ * @brief Implement extension code here.
+ */
+
+RegexExtension g_RegexExtension; /**< Global singleton for extension's main interface */
+
+SMEXT_LINK(&g_RegexExtension);
+
+RegexHandler g_RegexHandler;
+HandleType_t g_RegexHandle=0;
+
+
+SourceHook::CVector PEL;
+
+int GetPEL()
+{
+ for (int i=0; i<(int)PEL.size(); i++)
+ {
+ if (PEL[i]->isFree())
+ return i;
+ }
+
+ RegEx *x = new RegEx();
+ PEL.push_back(x);
+
+ return (int)PEL.size() - 1;
+}
+
+bool RegexExtension::SDK_OnLoad(char *error, size_t err_max, bool late)
+{
+ g_pShareSys->AddNatives(myself,regex_natives);
+ g_RegexHandle = g_pHandleSys->CreateType("Regex", &g_RegexHandler, 0, NULL, NULL, myself->GetIdentity(), NULL);
+ return true;
+}
+
+void RegexExtension::SDK_OnUnload()
+{
+ g_pHandleSys->RemoveType(g_RegexHandle, myself->GetIdentity());
+ for(int i=0; i<(int)PEL.size(); i++)
+ {
+ if(PEL[i])
+ {
+ delete PEL[i];
+ PEL[i] = 0;
+ }
+ }
+ PEL.clear();
+}
+
+static cell_t CompileRegex(IPluginContext *pCtx, const cell_t *params)
+{
+ char *regex;
+ pCtx->LocalToString(params[1], ®ex);
+
+ int id = GetPEL();
+ RegEx *x = PEL[id];
+
+ if (x->Compile(regex, params[2]) == 0)
+ {
+ cell_t *eOff;
+ pCtx->LocalToPhysAddr(params[5], &eOff);
+ const char *err = x->mError;
+ *eOff = x->mErrorOffset;
+ pCtx->StringToLocal(params[3], params[4], err ? err:"unknown");
+ return 0;
+ }
+
+ return g_pHandleSys->CreateHandle(g_RegexHandle, (void*)x, pCtx->GetIdentity(), myself->GetIdentity(), NULL);
+}
+
+
+static cell_t MatchRegex(IPluginContext *pCtx, const cell_t *params)
+{
+ Handle_t hndl = static_cast(params[1]);
+ HandleError err;
+ HandleSecurity sec;
+ sec.pOwner = NULL;
+ sec.pIdentity = myself->GetIdentity();
+
+ RegEx *x;
+
+ if ((err=g_pHandleSys->ReadHandle(hndl, g_RegexHandle, &sec, (void **)&x)) != HandleError_None)
+ {
+ return pCtx->ThrowNativeError("Invalid file handle %x (error %d)", hndl, err);
+ }
+
+ if (!x)
+ {
+ pCtx->ThrowNativeError("Regex data not found\n");
+
+ return 0;
+ }
+
+ char *str;
+ pCtx->LocalToString(params[2], &str);
+
+ int e = x->Match(str);
+
+ if (e == -1)
+ {
+ /* there was a match error. move on. */
+ cell_t *res;
+ pCtx->LocalToPhysAddr(params[3], &res);
+ *res = x->mErrorOffset;
+ /* only clear the match results, since the regex object
+ may still be referenced later */
+ x->ClearMatch();
+
+ return -1;
+ }
+ else if (e == 0)
+ {
+ /* only clear the match results, since the regex object
+ may still be referenced later */
+ x->ClearMatch();
+
+ return 0;
+ }
+ else
+ {
+ return x->mSubStrings;
+ }
+}
+
+static cell_t GetRegexSubString(IPluginContext *pCtx, const cell_t *params)
+{
+ Handle_t hndl=static_cast(params[1]);
+ HandleError err;
+ HandleSecurity sec;
+ sec.pOwner=NULL;
+ sec.pIdentity=myself->GetIdentity();
+
+ RegEx *x;
+
+ if ((err=g_pHandleSys->ReadHandle(hndl, g_RegexHandle, &sec, (void **)&x)) != HandleError_None)
+ {
+ return pCtx->ThrowNativeError("Invalid file handle %x (error %d)", hndl, err);
+ }
+
+ if (!x)
+ {
+ pCtx->ThrowNativeError("Regex data not found\n");
+ return 0;
+ }
+
+ static char buffer[4096];
+ const char *ret=x->GetSubstring(params[2], buffer, sizeof(buffer));
+
+ if(!ret)
+ {
+ return 0;
+ }
+
+ pCtx->StringToLocalUTF8(params[3], params[4], ret, NULL);
+
+ return 1;
+}
+
+void RegexHandler::OnHandleDestroy(HandleType_t type, void *object)
+{
+ RegEx *x = (RegEx *)object;
+
+ x->Clear();
+}
+
+const sp_nativeinfo_t regex_natives[] =
+{
+ {"GetRegexSubString", GetRegexSubString},
+ {"MatchRegex", MatchRegex},
+ {"CompileRegex", CompileRegex},
+ {NULL, NULL},
+};