summaryrefslogtreecommitdiff
path: root/plugins/Variables/src/parse_alias.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Variables/src/parse_alias.cpp')
-rw-r--r--plugins/Variables/src/parse_alias.cpp224
1 files changed, 224 insertions, 0 deletions
diff --git a/plugins/Variables/src/parse_alias.cpp b/plugins/Variables/src/parse_alias.cpp
new file mode 100644
index 0000000000..49c2999595
--- /dev/null
+++ b/plugins/Variables/src/parse_alias.cpp
@@ -0,0 +1,224 @@
+/*
+ Variables Plugin for Miranda-IM (www.miranda-im.org)
+ Copyright 2003-2006 P. Boon
+
+ This program is mir_free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "variables.h"
+#include "parse_alias.h"
+
+static CRITICAL_SECTION csAliasRegister;
+static ALIASREGISTER *ar = NULL;
+static unsigned int arCount = 0;
+
+static ALIASREGISTER *searchAliasRegister(TCHAR *szAlias) {
+
+ ALIASREGISTER *res;
+ unsigned int i;
+
+ res = NULL;
+ if ((szAlias == NULL) || (_tcslen(szAlias) == 0)) {
+ return NULL;
+ }
+ EnterCriticalSection(&csAliasRegister);
+ for (i=0;i<arCount;i++) {
+ if (!_tcscmp(ar[i].szAlias, szAlias)) {
+ /* TODO: make a copy here? */
+ res = &ar[i];
+ LeaveCriticalSection(&csAliasRegister);
+ return res;
+ }
+ }
+ LeaveCriticalSection(&csAliasRegister);
+
+ return NULL;
+}
+
+static TCHAR *replaceArguments(TCHAR *res, TCHAR *tArg, TCHAR *rArg) {
+
+ unsigned int cur, ecur;
+
+ if ( _tcslen(tArg) == 0)
+ return res;
+
+ cur = ecur = 0;
+ while (*(res+cur) != _T('\0')) {
+ if ((*(res+cur) == _T('(')) || (*(res+cur) == _T(','))) {
+ ecur = ++cur;
+ while ( (*(res+ecur) != _T(')')) && (*(res+ecur) != _T(','))) {
+ ecur++;
+ }
+ if (((signed int)_tcslen(tArg) == (ecur-cur)) && (!_tcsncmp(tArg, res+cur, _tcslen(tArg)))) {
+ if ( _tcslen(rArg) > _tcslen(tArg)) {
+ res = (TCHAR*)mir_realloc(res, (_tcslen(res) + (_tcslen(rArg)-_tcslen(tArg)) + 1)*sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+ }
+ MoveMemory(res+ecur+(_tcslen(rArg)-_tcslen(tArg)), res+ecur, (_tcslen(res+ecur)+1)*sizeof(TCHAR));
+ _tcsncpy(res+cur, rArg, _tcslen(rArg));
+ }
+ }
+ cur++;
+ }
+
+ return res;
+}
+
+static TCHAR *parseTranslateAlias(ARGUMENTSINFO *ai) {
+
+ unsigned int i;
+ TCHAR *res;
+ ALIASREGISTER *areg;
+
+ areg = searchAliasRegister(ai->targv[0]);
+ if ((areg == NULL) || (areg->argc != ai->argc-1)) {
+ return NULL;
+ }
+ res = mir_tstrdup(areg->szTranslation);
+ for (i=0;i<areg->argc;i++) {
+ res = replaceArguments(res, areg->argv[i], ai->targv[i+1]);
+ if (res == NULL) {
+ return NULL;
+ }
+ }
+
+ return res;
+}
+
+static int addToAliasRegister(TCHAR *szAlias, unsigned int argc, TCHAR** argv, TCHAR *szTranslation) {
+
+ unsigned int i, j;
+
+ if (szAlias == NULL || szTranslation == NULL || _tcslen(szAlias) == 0 )
+ return -1;
+
+ EnterCriticalSection(&csAliasRegister);
+ for (i=0;i<arCount;i++) {
+ if (!_tcscmp(ar[i].szAlias, szAlias)) {
+ mir_free(ar[i].szTranslation);
+ ar[i].szTranslation = mir_tstrdup(szTranslation);
+ for (j=0;j<ar[i].argc;j++) {
+ if (ar[i].argv[j] != NULL) {
+ mir_free(ar[i].argv[j]);
+ }
+ }
+ ar[i].argc = argc;
+ ar[i].argv = ( TCHAR** )mir_realloc(ar[i].argv, argc * sizeof(TCHAR*));
+ if (ar[i].argv == NULL) {
+ LeaveCriticalSection(&csAliasRegister);
+ return -1;
+ }
+ for (j=0;j<argc;j++) {
+ if (argv[j] != NULL)
+ ar[i].argv[j] = mir_tstrdup(argv[j]);
+ else
+ ar[i].argv[j] = NULL;
+ }
+ LeaveCriticalSection(&csAliasRegister);
+ return 0;
+ }
+ }
+ ar = ( ALIASREGISTER* )mir_realloc(ar, (arCount+1)*sizeof(ALIASREGISTER));
+ if (ar == NULL) {
+ LeaveCriticalSection(&csAliasRegister);
+ return -1;
+ }
+ ar[arCount].szAlias = mir_tstrdup(szAlias);
+ ar[arCount].szTranslation = mir_tstrdup(szTranslation);
+ ar[arCount].argc = argc;
+ ar[arCount].argv = ( TCHAR** )mir_alloc(argc * sizeof(TCHAR*));
+ if (ar[arCount].argv == NULL) {
+ LeaveCriticalSection(&csAliasRegister);
+ return -1;
+ }
+ for (j=0;j<ar[arCount].argc;j++) {
+ if (argv[j] != NULL)
+ ar[arCount].argv[j] = mir_tstrdup(argv[j]);
+ else
+ ar[arCount].argv[j] = NULL;
+ }
+ arCount += 1;
+ LeaveCriticalSection(&csAliasRegister);
+
+ return 0;
+}
+
+static TCHAR *parseAddAlias(ARGUMENTSINFO *ai) {
+
+ int res;
+ int argc, i;
+ TCHAR *cur, *alias, **argv, *szArgs;
+ char *szHelp, *szArgsA;
+
+ if (ai->argc != 3)
+ return NULL;
+
+ cur = ai->targv[1];
+ while (isValidTokenChar(*cur))
+ cur++;
+
+ alias = (TCHAR*)mir_calloc(((cur-ai->targv[1])+1)*sizeof(TCHAR));
+ if (alias == NULL)
+ return NULL;
+
+ _tcsncpy(alias, ai->targv[1], (cur-ai->targv[1]));
+ getArguments(cur, &argv, &argc);
+ deRegisterToken(alias);
+ addToAliasRegister(alias, argc, argv, ai->targv[2]);
+ szArgs = NULL;
+ for (i=0;i<argc;i++) {
+ if (i == 0)
+ szArgs = (TCHAR*)mir_calloc(( _tcslen(argv[i])+2)*sizeof(TCHAR));
+ else
+ szArgs = (TCHAR*)mir_realloc(szArgs, (_tcslen(szArgs) + _tcslen(argv[i]) + 2)*sizeof(TCHAR));
+
+ _tcscat(szArgs, argv[i]);
+ if (i != argc-1)
+ _tcscat(szArgs, _T(","));
+ }
+ if ((szArgs != NULL) && (argc > 0)) {
+
+ szArgsA = mir_t2a(szArgs);
+
+ szHelp = ( char* )mir_alloc(32 + strlen(szArgsA));
+ memset(szHelp, '\0', 32 + strlen(szArgsA));
+ sprintf(szHelp, "Alias\t(%s)\tuser defined", szArgsA);
+ res = registerIntToken(alias, parseTranslateAlias, TRF_FUNCTION|TRF_UNPARSEDARGS, szHelp);
+ mir_free(szArgsA);
+ }
+ else {
+ szHelp = ( char* )mir_alloc(32);
+ memset(szHelp, '\0', 32);
+ sprintf(szHelp, "Alias\t\tuser defined");
+ res = registerIntToken(alias, parseTranslateAlias, TRF_FIELD|TRF_UNPARSEDARGS, szHelp);
+ }
+ mir_free(szArgs);
+ mir_free(szHelp);
+
+ return res==0?mir_tstrdup(_T("")):NULL;
+}
+
+int registerAliasTokens()
+{
+ registerIntToken(_T(ADDALIAS), parseAddAlias, TRF_FUNCTION|TRF_UNPARSEDARGS, "Variables\t(x,y)\tstores y as alias named x");//TRF_UNPARSEDARGS);
+ InitializeCriticalSection(&csAliasRegister);
+ return 0;
+}
+
+void unregisterAliasTokens()
+{
+ DeleteCriticalSection(&csAliasRegister);
+}
+