From a6d58bb6052ac8cb01805a48c4ad2f129126116f Mon Sep 17 00:00:00 2001 From: tpearson Date: Wed, 24 Feb 2010 02:13:59 +0000 Subject: Added KDE3 version of kvirc git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kvirc@1095341 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- src/modules/str/Makefile.am | 18 + src/modules/str/libkvistr.cpp | 2330 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 2348 insertions(+) create mode 100644 src/modules/str/Makefile.am create mode 100644 src/modules/str/libkvistr.cpp (limited to 'src/modules/str') diff --git a/src/modules/str/Makefile.am b/src/modules/str/Makefile.am new file mode 100644 index 00000000..7fe7e93a --- /dev/null +++ b/src/modules/str/Makefile.am @@ -0,0 +1,18 @@ +############################################################################### +# KVirc IRC client Makestr - 10.03.2000 Szymon Stefanek +############################################################################### + +AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \ +$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\" + +pluglib_LTLIBRARIES = libkvistr.la + +libkvistr_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS) + +libkvistr_la_SOURCES = libkvistr.cpp +libkvistr_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la + +# noinst_HEADERS= + +%.moc: %.h + $(SS_QT_MOC) $< -o $@ diff --git a/src/modules/str/libkvistr.cpp b/src/modules/str/libkvistr.cpp new file mode 100644 index 00000000..58549f57 --- /dev/null +++ b/src/modules/str/libkvistr.cpp @@ -0,0 +1,2330 @@ +//============================================================================= +// +// File : libkvistr.cpp +// Creation date : Thu Dec 27 2001 17:13:12 GMT by Szymon Stefanek +// +// This str is part of the KVirc irc client distribution +// Copyright (C) 2001-2005 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is 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 opinion) 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. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +//#warning: FIXME: Incomplete documentation ('seealso', 'example', etc) + +#include "kvi_module.h" + +#include "kvi_locale.h" +#include "kvi_mirccntrl.h" +#include "kvi_qstring.h" +#include "kvi_debug.h" +#include "kvi_settings.h" +#include "kvi_malloc.h" + +#include "kvi_kvs_arraycast.h" +#include +#include + +#ifdef COMPILE_SSL_SUPPORT + #include +#endif + +/* + @doc: str.section + @type: + function + @title: + $str.section + @short: + Returns a section of the string. + @syntax: + $str.section(,,,) + @description: + Returns a section of the string. + The is treated as a sequence of fields separated by .[br] + The returned string consists of the fields from position start to position end .[br] + Fields are numbered 0, 1, 2, etc., counting from the left, and -1, -2, etc., counting from right to left.[br] + @examples: + [example] + %s = $str.section( "forename**middlename**surname**phone","**", 2, 2 ); + %s is "surname". + [/example] +*/ + +static bool str_kvs_fnc_section(KviKvsModuleFunctionCall * c) +{ + QString szString, szSeparator,szSplittedString; + kvs_int_t iPosFrom, iPosTo; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("string_to_split",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("separator",KVS_PT_NONEMPTYSTRING,0,szSeparator) + KVSM_PARAMETER("pos_from",KVS_PT_INT,0,iPosFrom) + KVSM_PARAMETER("pos_to",KVS_PT_INT,0,iPosTo) + KVSM_PARAMETERS_END(c) + c->returnValue()->setString(szString.section(szSeparator,iPosFrom,iPosTo)); + return true; +} + +/* + @doc: str.fromClipboard + @type: + function + @title: + $str.fromClipboard + @short: + Returns a string from clipboard. + @syntax: + $str.fromClipboard() + @description: + Returns clipboard's contents. + @examples: + [example] + %s = $str.fromClipboard(); + [/example] + @seealso: + [cmd]str.toClipboard[/cmd] +*/ + +static bool str_kvs_fnc_fromclipboard(KviKvsModuleFunctionCall * c) +{ + QString szString; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETERS_END(c) + QClipboard *cb = QApplication::clipboard(); + szString = cb->text(QClipboard::Clipboard); + c->returnValue()->setString(szString); + return true; +} + +/* + @doc: system.toClipboard + @type: + command + @title: + system.toClipboard + @keyterms: + OS clipboard + @short: + Sets the OS clipboard contents + @syntax: + system.setenv + @description: + Sets the OS clipboard contents + @seealso: + [fnc]$str.fromClipboard[/fnc] +*/ + +static bool str_kvs_cmd_toClipboard(KviKvsModuleCommandCall * c) +{ + QString szValue; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("value",KVS_PT_STRING,KVS_PF_OPTIONAL,szValue) + KVSM_PARAMETERS_END(c) + QClipboard *cb = QApplication::clipboard(); + cb->setText(szValue, QClipboard::Clipboard ); + return true; +} + +/* + @doc: str.len + @type: + function + @title: + $str.len + @short: + Returns the lenght of the given string + @syntax: + $str.len() + @description: + Returns the lenght (that is, number of characters) of the given string. + This function is internally aliased to [fnc]$str.length[/fnc]() too. +*/ + +/* + @doc: str.length + @type: + function + @title: + $str.length + @short: + Returns the lenght of the given string + @syntax: + $str.length() + @description: + Returns the lenght (that is, number of characters) of the given string. + This function is internally aliased to [fnc]$str.len[/fnc]() too. +*/ + +static bool str_kvs_fnc_len(KviKvsModuleFunctionCall * c) +{ + QString szString; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("data",KVS_PT_STRING,0,szString) + KVSM_PARAMETERS_END(c) + c->returnValue()->setInteger(szString.length()); + return true; +} + +/* + @doc: str.lowcase + @type: + function + @title: + $str.lowcase + @short: + Returns the given string with all characters turned to lower case + @syntax: + $str.lowcase() + @description: + Returns the with all characters turned to lower case. + Warning: this function uses ISO-8859-1 locale to make the case translation. + If you want to use a locale aware translation mapping then please + use localelowcase. +*/ + +static bool str_kvs_fnc_lowcase(KviKvsModuleFunctionCall * c) +{ + QString szString; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("string_to_convert",KVS_PT_STRING,0,szString) + KVSM_PARAMETERS_END(c) + c->returnValue()->setString(KviQString::lowerISO88591(szString)); + return true; +} +/* + @doc: str.upcase + @type: + function + @title: + $str.upcase + @short: + Returns the given string with all characters turned to upper case + @syntax: + $str.upcase() + @description: + Returns the given with all characters turned to lower case. + Warning: this function uses ISO-8859-1 locale to make the case translation. + If you want to use a locale aware translation mapping then please + use $str.localeupcase. +*/ + +static bool str_kvs_fnc_upcase(KviKvsModuleFunctionCall * c) +{ + QString szString; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("string_to_convert",KVS_PT_STRING,0,szString) + KVSM_PARAMETERS_END(c) + c->returnValue()->setString(KviQString::upperISO88591(szString)); + return true; +} +/* + @doc: str.localelowcase + @type: + function + @title: + $str.localelowcase + @short: + Returns the given string with all characters turned to lower case + @syntax: + $str.localelowcase() + @description: + Returns the given with all characters turned to lower case. + Warning: this function is locale aware and it may produce unexpected + results in locales that contain strange exceptions (like Turkish which maps + i to Y with an accent). For IRC interaction you might prefer using $str.lowcase +*/ + +static bool str_kvs_fnc_localelowcase(KviKvsModuleFunctionCall * c) +{ + QString szString; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("string_to_convert",KVS_PT_STRING,0,szString) + KVSM_PARAMETERS_END(c) + c->returnValue()->setString(szString.lower()); + return true; +} + +/* + @doc: str.localeupcase + @type: + function + @title: + $str.localeupcase + @short: + Returns the given string with all characters turned to upper case + @syntax: + $str.localeupcase() + @description: + Returns the given with all characters turned to lower case. + Warning: this function is locale aware and it may produce unexpected + results in locales that contain strange exceptions (like Turkish which maps + i to Y with an accent). For IRC interaction you might prefer using $str.upcase +*/ + +static bool str_kvs_fnc_localeupcase(KviKvsModuleFunctionCall * c) +{ + QString szString; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("string_to_convert",KVS_PT_STRING,0,szString) + KVSM_PARAMETERS_END(c) + c->returnValue()->setString(szString.upper()); + return true; +} + +/* + @doc: str.isnumber + @type: + function + @title: + $str.isnumber + @short: + Returns 1 if the given string represents a number + @syntax: + $str.isnumber() + @description: + Returns 1 if the given string represents a number, 0 if not. +*/ + +static bool str_kvs_fnc_isnumber(KviKvsModuleFunctionCall * c) +{ + KviKvsVariant * v; + KviKvsNumber num; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("givenstring",KVS_PT_VARIANT,0,v) + KVSM_PARAMETERS_END(c) + c->returnValue()->setBoolean(v->asNumber(num)); + return true; +} + + +/* + @doc: str.isunsignednumber + @type: + function + @title: + $str.isunsignednumber + @short: + Returns 1 if the given string represents an unsigned number + @syntax: + $str.isunsignednumber() + @description: + Returns 1 if the given string represents an unsigned number, 0 if not. +*/ + +static bool str_kvs_fnc_isunsignednumber(KviKvsModuleFunctionCall * c) +{ + KviKvsVariant * v; + KviKvsNumber nNum; + bool bRet; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("givenstring",KVS_PT_VARIANT,0,v) + KVSM_PARAMETERS_END(c) + if(!v->asNumber(nNum)) bRet = false; + else + { + if(nNum.isInteger()) + { + bRet = nNum.integer() >= 0; + } + else + { + bRet = nNum.real() >= 0.0; + } + } + c->returnValue()->setBoolean(bRet); + return true; +} + +/* + @doc: str.isempty + @type: + function + @title: + $str.isempty + @short: + Returns 1 if the given string don't have any character. + @syntax: + $str.isEmpty() + @description: + Returns 1 if the given string don't have any character (that is, is empty). + This function is almost useless since it is equivalent to the + comparison with an empty string... +*/ + +static bool str_kvs_fnc_isempty(KviKvsModuleFunctionCall * c) +{ + QString v; + bool bRet; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("datastring",KVS_PT_STRING,0,v) + KVSM_PARAMETERS_END(c) + if(v.isEmpty()) bRet = true; + else bRet = false; + c->returnValue()->setBoolean(bRet); + return true; +} + +/* + @doc: str.contains + @type: + function + @title: + $str.contains + @short: + Returns 1 if the first parameter contains the second + @syntax: + $str.contains(,) + @description: + Returns 1 if the first string parameter contains the second string parameter. + This function is case sensitive. + @seealso: + [fnc]$str.containsnocase[/fnc]() +*/ + + +static bool str_kvs_fnc_contains(KviKvsModuleFunctionCall * c) +{ + QString szString,szSubString; + bool bIs; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("container",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("tofind",KVS_PT_STRING,0,szSubString) + KVSM_PARAMETERS_END(c) + bIs = szString.find(szSubString) != -1; + c->returnValue()->setBoolean(bIs); + return true; +} + +/* + @doc: str.containsnocase + @type: + function + @title: + $str.containsnocase + @short: + Returns 1 if the first parameter contains the second, case insensitive + @syntax: + $str.containsnocase(,) + @description: + Returns 1 if the first string parameter contains the second string parameter + whithout taking in consideration the case of the characters in the string. + @seealso: + [fnc]$str.contains[/fnc] +*/ + +static bool str_kvs_fnc_containsnocase(KviKvsModuleFunctionCall * c) +{ + QString szString,szSubString; + bool bIs; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("container",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("tofind",KVS_PT_STRING,0,szSubString) + KVSM_PARAMETERS_END(c) + bIs = szString.find(szSubString,0,false) != -1; + c->returnValue()->setBoolean(bIs); + return true; +} + +/* + @doc: str.equal + @type: + function + @title: + $str.equal + @short: + Returns 1 if the two string parameters are equal + @syntax: + $str.equal(,) + @description: + Returns 1 if the two string parameters are equal. This function is case sensitive. + @seealso: + [fnc]$str.equalnocase[/fnc]() +*/ + +static bool str_kvs_fnc_equal(KviKvsModuleFunctionCall * c) +{ + QString szString,szString2; + bool bIs; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("fromcompare",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("tocompare",KVS_PT_STRING,0,szString2) + KVSM_PARAMETERS_END(c) + bIs = KviQString::equalCS(szString,szString2); + c->returnValue()->setBoolean(bIs); + return true; +} +/* + @doc: str.equalnocase + @type: + function + @title: + $str.equalnocase + @short: + Returns 1 if the two string parameters are equal, case insensitive + @syntax: + $str.equalnocase(,) + @description: + Returns 1 if the two strngs parameters are equal, without taking the case of the + characters in consideration. + @seealso: + [fnc]$str.equal[/fnc]() +*/ + +static bool str_kvs_fnc_equalnocase(KviKvsModuleFunctionCall * c) +{ + QString szString,szString2; + bool bIs; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("fromcompare",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("tocompare",KVS_PT_STRING,0,szString2) + KVSM_PARAMETERS_END(c) + bIs = KviQString::equalCI(szString,szString2); + c->returnValue()->setBoolean(bIs); + return true; +} + +/* + @doc: str.cmp + @type: + function + @title: + $str.cmp + @short: + Compare two strings alphabetically + @syntax: + $str.cmp(,) + @description: + This function compares two strings alphabetically. If the first string is 'greater' + than the second, it will return a positive number, a negative number is the second is + greater and 0 if the two strings are equal. + @seealso: + [fnc]$str.cmpnocase[/fnc]() +*/ + +static bool str_kvs_fnc_cmp(KviKvsModuleFunctionCall * c) +{ + QString szString,szString2; + int iCmp; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("fromcompare",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("tocompare",KVS_PT_STRING,0,szString2) + KVSM_PARAMETERS_END(c) + iCmp = KviQString::cmpCS(szString,szString2); + c->returnValue()->setInteger(iCmp); + return true; +} + +/* + @doc: str.cmpnocase + @type: + function + @title: + $str.cmpnocase + @short: + Compare two strings alphabetically, case insensitive. + @syntax: + $str.cmpnocase(,) + @description: + This function compares two strings alphabetically. If the first string is 'greater' + than the second, it will return a positive number, a negative number is the second is + greater and 0 if the two strings are equal. This function is case insensitive. + @seealso: + [fnc]$str.cmp[/fnc]() +*/ +static bool str_kvs_fnc_cmpnocase(KviKvsModuleFunctionCall * c) +{ + QString szString,szString2; + int iCmp; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("fromcompare",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("tocompare",KVS_PT_STRING,0,szString2) + KVSM_PARAMETERS_END(c) + iCmp = KviQString::cmpCI(szString,szString2); + c->returnValue()->setInteger(iCmp); + return true; +} + +/* + @doc: str.find + @type: + function + @title: + $str.find + @short: + Find the index of the nth ocurrence of a substring in a string + @syntax: + $str.find(,[,ocurrence:int]) + @description: + This function search in the string given as the first parameter for the string + given as his second parameter, and will return the index where the nth ocurrence + given as the third parameter is found or -1 if it's not located. It starts + counting at 0. If occurence is not specified then the first occurence + is searched. WARNING: The occurente number starts from 1! (Yes, that's a bug, but + for backward compatibility it must remain as it is :( ).[br] + FIXME: The semantics of this function are totally broken :( +*/ + +static bool str_kvs_fnc_find(KviKvsModuleFunctionCall * c) +{ + QString szFindIn, szToFind; + kvs_int_t iOcurence; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("findIn",KVS_PT_STRING,0,szFindIn) + KVSM_PARAMETER("tofind",KVS_PT_STRING,0,szToFind) + KVSM_PARAMETER("ocurrence",KVS_PT_INTEGER,KVS_PF_OPTIONAL,iOcurence) + KVSM_PARAMETERS_END(c) + int pos = 1; + if(iOcurence!=0) + pos = iOcurence; + if(pos<1) + { + c->returnValue()->setInteger(-1); + return true; + } + if(szFindIn.isEmpty()) + { + c->returnValue()->setInteger(-1); + return true; + } + if(szToFind.isEmpty()) + { + c->returnValue()->setInteger(-1); + return true; + } + int cnt = 1; + int idx; + int totalIdx = 0; + + while (cnt<=pos) + { + idx = szFindIn.right(szFindIn.length() - totalIdx).find(szToFind); + if(idx == -1) + { + c->returnValue()->setInteger(-1); + return true; + } + //Idx only gives the index until the pos _before_ the matched string so if this is + //not the match we want (cont != 0) we skip it + totalIdx += (idx + (cnt == pos ? 0 : szToFind.length())); + ++cnt; + } + c->returnValue()->setInteger(totalIdx); + return true; +} +/* + @doc: str.findfirst + @type: + function + @title: + $str.findfirst + @short: + Find the index of a substring in a string + @syntax: + $str.findfirst(,) + @description: + This function search in the string given as the first parameter for the string + given as his second parameter, and will return the index where is first located or + -1 if it's not located. It starts counting at 0. +*/ + +static bool str_kvs_fnc_findfirst(KviKvsModuleFunctionCall * c) +{ + QString szString,szString2; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("findIn",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("toFind",KVS_PT_STRING,0,szString2) + KVSM_PARAMETERS_END(c) + c->returnValue()->setInteger(szString.find(szString2)); + return true; +} +/* + @doc: str.findfirstnocase + @type: + function + @title: + $str.findfirstnocase + @short: + Find the index of a substring in a string, case insensitive + @syntax: + $str.findfirstnocase(,) + @description: + This function search in the string given as the first parameter for the string + given as his second parameter, and will return the index where is first located or + -1 if it's not located. This function is case insensitive. +*/ + +static bool str_kvs_fnc_findfirstnocase(KviKvsModuleFunctionCall * c) +{ + QString szString,szString2; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("findIn",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("toFind",KVS_PT_STRING,0,szString2) + KVSM_PARAMETERS_END(c) + c->returnValue()->setInteger(szString.find(szString2,0,false)); + return true; +} +/* + @doc: str.findlast + @type: + function + @title: + $str.findlast + @short: + Find the last index of a substring in a string + @syntax: + $str.findlast(,) + @description: + This function search in the string given as the first parameter for the string + given as his second parameter, and will return the index where is last located or + -1 if it's not located. +*/ + +static bool str_kvs_fnc_findlast(KviKvsModuleFunctionCall * c) +{ + QString szString,szString2; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("findIn",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("toFind",KVS_PT_STRING,0,szString2) + KVSM_PARAMETERS_END(c) + c->returnValue()->setInteger(szString.findRev(szString2)); + return true; +} +/* + @doc: str.findlastnocase + @type: + function + @title: + $str.findlastnocase + @short: + Find the last index of a substring in a string, case insensitive + @syntax: + $str.findlastnocase(,) + @description: + This function search in the string given as the first parameter for the string + given as his second parameter, and will return the index where is last located or + -1 if it's not located. This function is case insensitive. +*/ + +static bool str_kvs_fnc_findlastnocase(KviKvsModuleFunctionCall * c) +{ + QString szString,szString2; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("findIn",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("toFind",KVS_PT_STRING,0,szString2) + KVSM_PARAMETERS_END(c) + c->returnValue()->setInteger(szString.findRev(szString2,-1,false)); + return true; +} +/* + @doc: str.left + @type: + function + @title: + $str.left + @short: + Returns a substring starting from the left until the given index. + @syntax: + $str.left(,) + @description: + This function returns a substring of the first string parameter which is the + string starting from the left until the index specified in the second parameter. +*/ + +static bool str_kvs_fnc_left(KviKvsModuleFunctionCall * c) +{ + QString szString; + kvs_int_t iIdx; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("data",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("index",KVS_PT_INTEGER,0,iIdx) + KVSM_PARAMETERS_END(c) + c->returnValue()->setString(szString.left(iIdx)); + return true; +} +/* + @doc: str.right + @type: + function + @title: + $str.right + @short: + Returns a substring starting from the right until the given index. + @syntax: + $str.right(,) + @description: + This function returns a substring of the first string parameter which is the + string starting from the right until the index specified in the second parameter. + The index start counting at the last character and increase until the first. +*/ + +static bool str_kvs_fnc_right(KviKvsModuleFunctionCall * c) +{ + QString szString; + kvs_int_t iIdx; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("data",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("index",KVS_PT_INTEGER,0,iIdx) + KVSM_PARAMETERS_END(c) + c->returnValue()->setString(szString.right(iIdx)); + return true; +} +/* + @doc: str.mid + @type: + function + @title: + $str.mid + @short: + Returns a substring starting from a given index. + @syntax: + $str.mid(,,) + @description: + This function returns a substring of the first string parameter wich is the + string starting at the (numeric) index given with startidx and counting nchars + forward. +*/ + +static bool str_kvs_fnc_mid(KviKvsModuleFunctionCall * c) +{ + QString szString; + kvs_int_t iIdx,iNchars; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("data",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("startidx",KVS_PT_INTEGER,0,iIdx) + KVSM_PARAMETER("nchars",KVS_PT_INTEGER,0,iNchars) + KVSM_PARAMETERS_END(c) + c->returnValue()->setString(szString.mid(iIdx,iNchars)); + return true; +} +/* + @doc: str.append + @type: + function + @title: + $str.append + @short: + Append one string to another. + @syntax: + $str.append(,) + @description: + This function returns a string created appending the second string parameter + to the end of the first string parameter. +*/ + +static bool str_kvs_fnc_append(KviKvsModuleFunctionCall * c) +{ + QString szString,szString2; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("string",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("toappend",KVS_PT_STRING,0,szString2) + KVSM_PARAMETERS_END(c) + c->returnValue()->setString(szString.append(szString2)); + return true; +} +/* + @doc: str.prepend + @type: + function + @title: + $str.prepend + @short: + Prepend one string to another. + @syntax: + $str.prepend(,) + @description: + This function returns a string created prepending the second string parameter + to the start of the first string parameter. +*/ + +static bool str_kvs_fnc_prepend(KviKvsModuleFunctionCall * c) +{ + QString szString,szString2; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("string",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("toprepend",KVS_PT_STRING,0,szString2) + KVSM_PARAMETERS_END(c) + c->returnValue()->setString(szString.prepend(szString2)); + return true; +} +/* + @doc: str.insert + @type: + function + @title: + $str.insert + @short: + Inserts a substring in a string at a given index + @syntax: + $str.insert(,,) + @description: + Inserts the substring given in the second parameter in the string given in the + first parameter at the index given in the third parameter, then returns the + resulting string. +*/ + +static bool str_kvs_fnc_insert(KviKvsModuleFunctionCall * c) +{ + QString szString,szString2; + kvs_int_t iIdx; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("string",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("substring",KVS_PT_STRING,0,szString2) + KVSM_PARAMETER("nchars",KVS_PT_INTEGER,0,iIdx) + KVSM_PARAMETERS_END(c) + c->returnValue()->setString(szString.insert(iIdx,szString2)); + return true; +} +/* + @doc: str.strip + @type: + function + @title: + $str.strip + @short: + Returns a whitespace stripped string + @syntax: + $str.strip() + @description: + Returns a left and right whitespace stripped version of the string given as the + first parameter. +*/ + +static bool str_kvs_fnc_strip(KviKvsModuleFunctionCall * c) +{ + QString szString; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("string",KVS_PT_STRING,0,szString) + KVSM_PARAMETERS_END(c) + c->returnValue()->setString(szString.stripWhiteSpace()); + return true; +} +/* + @doc: str.stripleft + @type: + function + @title: + $str.stripleft + @short: + Returns a left whitespace stripped string + @syntax: + $str.stripleft() + @description: + Returns a left whitespace stripped version of the string given as the + first parameter. +*/ + +static bool str_kvs_fnc_stripleft(KviKvsModuleFunctionCall * c) +{ + QString szString; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("string",KVS_PT_STRING,0,szString) + KVSM_PARAMETERS_END(c) + if(szString.length() > 0) + { + int idx = 0; + while(szString[idx].isSpace())idx++; + if(idx > 0)szString.remove(0,idx); + } + c->returnValue()->setString(szString); + return true; +} +/* + @doc: str.stripright + @type: + function + @title: + $str.stripright + @short: + Returns a right whitespace stripped string + @syntax: + $str.stripright() + @description: + Returns a right whitespace stripped version of the string given as the + first parameter. +*/ + +static bool str_kvs_fnc_stripright(KviKvsModuleFunctionCall * c) +{ + QString szString; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("string",KVS_PT_STRING,0,szString) + KVSM_PARAMETERS_END(c) + int iIdx = 0; + while(szString.at(szString.length() - (iIdx+1)).isSpace()) iIdx++; + if(iIdx > 0)szString.remove(szString.length() - iIdx,iIdx); + c->returnValue()->setString(szString); + return true; +} + +/* + @doc: str.stripcolors + @type: + function + @title: + $str.stripcolors + @short: + Returns a mirc color codes stripped string + @syntax: + $str.stripcolors() + @description: + Removes all mirc color codes from a string, including also bold, underline, reverse, + icon, crypting and ctcp control codes. +*/ + +static bool str_kvs_fnc_stripcolors(KviKvsModuleFunctionCall * c) +{ + QString szString; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("string",KVS_PT_STRING,0,szString) + KVSM_PARAMETERS_END(c) + c->returnValue()->setString(KviMircCntrl::stripControlBytes(szString)); + return true; +} + +/* + @doc: str.replace + @type: + function + @title: + $str.replace + @short: + Replace substrings in a string + @syntax: + $str.replace(,,) + @description: + This function returns a string created replacing all ocurrences of the third parameter + ('toreplace') in the string given as the first parameter ('string') with the string + given as the second parameter ('replacewith'). + The string replacement is case sensitive!. + FIXME: The order of the parameters in this function is illogical (and probably incompatible + with any other scripting language) :D + @examples: + [example] + echo $str.replace("I like big networks","neural","big") + [/example] +*/ + +static bool str_kvs_fnc_replace(KviKvsModuleFunctionCall * c) +{ + QString szString,szNewstr,szToreplace; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("string",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("newstr",KVS_PT_STRING,0,szNewstr) + KVSM_PARAMETER("toreplace",KVS_PT_STRING,0,szToreplace) + KVSM_PARAMETERS_END(c) + szString.replace(szToreplace,szNewstr); + c->returnValue()->setString(szString); + return true; +} + +/* + @doc: str.replacenocase + @type: + function + @title: + $str.replacenocase + @short: + Replace substrings in a string ignoring case + @syntax: + $str.replacenocase(,,) + @description: + This function returns a string created replacing all ocurrences of the third parameter + ('toreplace') in the string given as the first parameter ('string') with the string + given as the second parameter ('newstr').[br] + The replacement is case insensitive.[br] + FIXME: The order of the parameters in this function is illogical (and probably incompatible + with any other scripting language) :D +*/ + +static bool str_kvs_fnc_replacenocase(KviKvsModuleFunctionCall * c) +{ + QString szString,szNewstr,szToreplace; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("string",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("newstr",KVS_PT_STRING,0,szNewstr) + KVSM_PARAMETER("toreplace",KVS_PT_STRING,0,szToreplace) + KVSM_PARAMETERS_END(c) + szString.replace(szToreplace,szNewstr,false); + c->returnValue()->setString(szString); + return true; +} + +/* + @doc: str.urlencode + @type: + function + @title: + $str.urlencode + @short: + Returns a browser formatted string + @syntax: + $str.urlencode() + @description: + This function returns a string created replacing all ocurrences in the parameter ('string') with their respective html entities.[br] + The replacement is case insensitive.[br] + FIXME: This function use the same replace order as $str.replace so it incompatible + with any other scripting language) :D +*/ + +static bool str_kvs_fnc_urlencode(KviKvsModuleFunctionCall * c) +{ + QString szString,szNewstr; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("string",KVS_PT_STRING,0,szString) + KVSM_PARAMETERS_END(c) + + char * toReplace[]={" ", "#", "$", "&", "/", ":", "<", "=", ">", "?", "@", "[", "\\", "]", "^", "`", "{", "|", "}", "~"}; + char * newStr[]={"%20", "%23", "%24", "&", "%2F", "%3A", "<", "%3D", ">", "%3F", "%40", "%5B", "%5C", "%5D", "%5E", "%60", "%7B", "%7C", "%7D", "%7E"}; + + /* + for(int idx=0,idx<22,idx++) + szNewstr=szString.replace(toReplace[idx],newStr[idx],false); + */ + + int idx=0; + while(idx<20){ + szNewstr=szString.replace(toReplace[idx],newStr[idx],false); + idx++; + } + + c->returnValue()->setString(szNewstr); + return true; +} + +/* + @doc: str.lefttofirst + @type: + function + @title: + $str.lefttofirst + @short: + Returns the left part of a string until a given substring + @syntax: + $str.lefttofirst(,) + @description: + This function returns the left part of the string given as the first parameter + from the start until the string given as the second parameter is found. It don't + include the substring of the second parameter in the returned value. If the second + parameter is not found, the entire string is returned. + The match is case insensitive. +*/ + +static bool str_kvs_fnc_lefttofirst(KviKvsModuleFunctionCall * c) +{ + QString szString,szNewstr; + int where; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("string",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("substring",KVS_PT_STRING,0,szNewstr) + KVSM_PARAMETERS_END(c) + where = szString.find(szNewstr,false); + if(where != -1) c->returnValue()->setString(szString.left(where)); + else c->returnValue()->setString(szString); + return true; +} +/* + @doc: str.lefttolast + @type: + function + @title: + $str.lefttolast + @short: + Returns the left part of a string until the last ocurrence of a given substring + @syntax: + $str.lefttolast(,) + @description: + This function returns the left part of the string given as the first parameter + from the start until the last ocurrence of the string given as the second parameter + is found. It don't include the substring of the second parameter in the returned value. + If the second parameter is not found, the entire string is returned. + The match is case insensitive +*/ + +static bool str_kvs_fnc_lefttolast(KviKvsModuleFunctionCall * c) +{ + QString szString,szNewstr; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("string",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("substring",KVS_PT_STRING,0,szNewstr) + KVSM_PARAMETERS_END(c) + int where = szString.findRev(szNewstr,-1,false); + if(where != -1) c->returnValue()->setString(szString.left(where)); + else c->returnValue()->setString(szString); + return true; +} +/* + @doc: str.rightfromfirst + @type: + function + @title: + $str.rightfromfirst + @short: + Returns the right part of a string from the first ocurrence of a given substring + @syntax: + $str.rightfromfirst(,) + @description: + This function returns the right part of the string given as the first parameter + from the position where the first ocurrence of the string given as the second parameter + is found. It don't include the substring of the second parameter in the returned value. + If the second parameter is not found, an empty string is returned.. + The match is case insensitive +*/ + +static bool str_kvs_fnc_rightfromfirst(KviKvsModuleFunctionCall * c) +{ + QString szString,szNewstr; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("string",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("substring",KVS_PT_STRING,0,szNewstr) + KVSM_PARAMETERS_END(c) + int idx = szString.find(szNewstr,false); + if(idx != -1) c->returnValue()->setString(szString.right(szString.length()-(idx+szNewstr.length()))); + else c->returnValue()->setString(""); + return true; +} +/* + @doc: str.rightfromlast + @type: + function + @title: + $str.rightfromlast + @short: + Returns the right part of a string from the last ocurrence of a given substring + @syntax: + $str.rightfromlast(,) + @description: + This function returns the right part of the string given as the first parameter + from the position where the last ocurrence of the string given as the second parameter + is found. It don't include the substring of the second parameter in the returned value. + If the second parameter is not found, an empty string is returned.. + The match is case insensitive. +*/ + + +static bool str_kvs_fnc_rightfromlast(KviKvsModuleFunctionCall * c) +{ + QString szString,szNewstr; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("string",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("substring",KVS_PT_STRING,0,szNewstr) + KVSM_PARAMETERS_END(c) + int idx = szString.findRev(szNewstr,-1,false); + if(idx != -1) c->returnValue()->setString(szString.right(szString.length()-(idx+szNewstr.length()))); + else c->returnValue()->setString(""); + return true; +} + +/* + @doc: str.match + @type: + function + @title: + $str.match + @short: + Matches a fixed string against a wildcard expression + @syntax: + $str.match(,[,]) + @description: + Returns 1 if the fixed matches the , 0 otherwise.[br] + If contains the flag 'r' then is treated as a full + regular expression otherwise it is treated as a simple wildcard expression containing + the classic wildcards '*' and '?'.[br] + If contains the flag 'e' then only an exact match is considered (e.g. the full + is exactly matched by ), otherwise partial matches are allowed too (e.g. + is found inside ).[br] + The match is case sensitive.[br] + @examples: + [example] + %test = "Hello! My nickname is Pragma" + [cmd]if[/cmd]($str.match(Pragma*,%test))[cmd]echo[/cmd] "Matches Pragma*" + [cmd]if[/cmd]($str.match(*Pragma,%test))[cmd]echo[/cmd] "Matches *Pragma" + [cmd]if[/cmd]($str.match(H*y*i?k*a,%test))[cmd]echo[/cmd] "Matches H*y*i?k*a" + [cmd]if[/cmd]($str.match(H*y*i?K*a,%test))[cmd]echo[/cmd] "Matches H*y*i?K*a" + [/example] + @seealso: + [fnc]$str.matchnocase[/fnc] +*/ + +static bool str_kvs_fnc_match(KviKvsModuleFunctionCall * c) +{ + QString szWildcard,szString,szFlags; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("wildcard",KVS_PT_NONEMPTYSTRING,0,szWildcard) + KVSM_PARAMETER("string",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("flags",KVS_PT_STRING,KVS_PF_OPTIONAL,szFlags) + KVSM_PARAMETERS_END(c) + bool bRegExp = (szFlags.find(QChar('r')) != -1) || (szFlags.find(QChar('R')) != -1); + bool bExact = (szFlags.find(QChar('e')) != -1) || (szFlags.find(QChar('E')) != -1); + c->returnValue()->setBoolean(KviQString::matchStringCS(szWildcard,szString,bRegExp,bExact)); + return true; +} + +/* + @doc: str.matchnocase + @type: + function + @title: + $str.matchnocase + @short: + Matches a fixed string against a wildcard expression (case insensitive) + @syntax: + $str.matchnocase(,[,]) + @description: + Returns 1 if the fixed matches the , 0 otherwise.[br] + If contains the flag 'r' then is treated as a full + regular expression otherwise it is treated as a simple wildcard expression containing + the classic wildcards '*' and '?'.[br] + If contains the flag 'e' then only an exact match is considered (e.g. the full + is exactly matched by ), otherwise partial matches are allowed too (e.g. + is found inside ).[br] + The match is case insensitive.[br] + @examples: + [example] + %test = "Hello! My nickname is Pragma" + [cmd]if[/cmd]($str.match(pragma*,%test))[cmd]echo[/cmd] "Matches pragma*" + [cmd]if[/cmd]($str.match(*pragma,%test))[cmd]echo[/cmd] "Matches *pragma" + [cmd]if[/cmd]($str.match(H*y*i?k*a,%test))[cmd]echo[/cmd] "Matches H*y*i?k*a" + [cmd]if[/cmd]($str.match(H*y*i?K*a,%test))[cmd]echo[/cmd] "Matches H*y*i?K*a" + [cmd]if[/cmd]($str.match(G*if?sx,%test))[cmd]echo[/cmd] "Matches G*if?sx" + [/example] + @seealso: + [fnc]$str.match[/fnc] +*/ + +static bool str_kvs_fnc_matchnocase(KviKvsModuleFunctionCall * c) +{ + QString szWildcard,szString,szFlags; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("wildcard",KVS_PT_NONEMPTYSTRING,0,szWildcard) + KVSM_PARAMETER("string",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("flags",KVS_PT_STRING,KVS_PF_OPTIONAL,szFlags) + KVSM_PARAMETERS_END(c) + bool bRegExp = (szFlags.find(QChar('r')) != -1) || (szFlags.find(QChar('R')) != -1); + bool bExact = (szFlags.find(QChar('e')) != -1) || (szFlags.find(QChar('E')) != -1); + c->returnValue()->setBoolean(KviQString::matchStringCI(szWildcard,szString,bRegExp,bExact)); + return true; +} + +/* + + @doc: str.word + @type: + function + @title: + $str.word + @short: + Returns the nth word in a string + @syntax: + $str.word(,) + @description: + Returns the nth word inside the (with n starting from 0!)[br] + A word is a substring not containing spaces (ASCII chars 32, carriage returns , tabs etc...).[br] + If the string contains less than n+1 words then an empty string is returned.[br] + This function is faster than a call to [fnc]split[/fnc]() and array indexing + if you need a single word to be extracted from a complex string.[br] + If you need to manage more than one word from the string then the [fnc]split[/fnc]() + method is more efficient.[br] + This function is a special case of [fnc]$str.token[/fnc]() and it runs a bit faster. + @examples: + [example] + %test = "this is a string full of words" + [cmd]echo[/cmd] $str.word(4,%test) + [/example] + @seealso: + [fnc]$str.token[/fnc] +*/ + +static bool str_kvs_fnc_word(KviKvsModuleFunctionCall * c) +{ + QString szString; + kvs_int_t iOccurence; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("occurence",KVS_PT_INT,0,iOccurence) + KVSM_PARAMETER("string",KVS_PT_STRING,0,szString) + KVSM_PARAMETERS_END(c) + int idx = 0; + int cnt = 0; + int begin; + int len = szString.length(); + while (idxreturnValue()->setString(szString.mid(begin,idx-begin)); + return true; + } + cnt ++; + } + return true; + +} +/* + @doc: str.token + @type: + function + @title: + $str.token + @short: + Returns the nth token in a string + @syntax: + $str.token(,,) + @description: + Returns the nth token inside the (with n starting from 0!)[br] + A token is a substring not containing the characters listed in .[br] + If the string contains less than n+1 tokens then an empty string is returned.[br] + [fnc]$str.word[/fnc]() is an optimized function dedicated to the special case + in that is a string containing all the whitespace characters.[br] + Please note that this function is SLOW. You might want to take a look at [fnc]$str.word[/fnc]() + or even better to [fnc]$str.split[/fnc]().[br] + This function is case sensitive: you need to specify both cases in the string + if you want to do a case insensitive tokenization.[br] + @examples: + [example] + %test = "21 hours 10 minutes 15 seconds" + [cmd]echo[/cmd] $str.token(1," hoursmintecd",%test) + [/example] + @seealso: + [fnc]$str.word[/fnc][br] + [fnc]$str.split[/fnc][br] +*/ + +static bool str_kvs_fnc_token(KviKvsModuleFunctionCall * c) +{ + QString szString,sep; + kvs_uint_t n; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("n",KVS_PT_UINT,0,n) + KVSM_PARAMETER("separator",KVS_PT_STRING,0,sep) + KVSM_PARAMETER("string",KVS_PT_STRING,0,szString) + KVSM_PARAMETERS_END(c) + if(sep.isEmpty()) + { + c->returnValue()->setString(szString); + return true; + } + + int idx = 0; + int cnt = 0; + int begin; + int len = szString.length(); + while (idxreturnValue()->setString(szString.mid(begin,idx-begin)); + return true; + } + cnt ++; + } + return true; +} + +/* + @doc: str.charsum + @type: + function + @title: + $str.charsum + @short: + Returns the sum of the character codes of the string + @syntax: + $str.charsum([,]) + @description: + Returns the sum of the character codes of the parameter . + The sum is suitable for implementing a simple hashing algorithm.[br] + If is specified and $true then the string + will be converted to lowercase first. +*/ + + +static bool str_kvs_fnc_charsum(KviKvsModuleFunctionCall * c) +{ + QString szString; + bool bCaseInsensitive; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("data",KVS_PT_STRING,0,szString) + KVSM_PARAMETER("bCaseInsensitive",KVS_PT_BOOL,KVS_PF_OPTIONAL,bCaseInsensitive) + KVSM_PARAMETERS_END(c) + unsigned int sum = 0; + int idx = 0; + int len = szString.length(); + if(bCaseInsensitive) + { + while(idx < len) + { + sum += szString[idx].lower().unicode(); + idx++; + } + } else { + while(idx < len) + { + sum += szString[idx].unicode(); + idx++; + } + } + c->returnValue()->setInteger(sum); + return true; +} + + +/* + @doc: str.digest + @type: + function + @title: + $str.digest + @short: + Returns the sum of the character codes of the string + @syntax: + $str.digest([,]) + @description: + Calculates digest for given string using algorithm passed as 2nd argument. + Currently supported: md5, md4, md2, sha1, mdc2, ripemd160, dss1 + Default is md5. Requires OpenSSL support +*/ + + +static bool str_kvs_fnc_digest(KviKvsModuleFunctionCall * c) +{ +#ifdef COMPILE_SSL_SUPPORT + QString szString,szType,szResult; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("data",KVS_PT_NONEMPTYSTRING,0,szString) + KVSM_PARAMETER("algorythm",KVS_PT_NONEMPTYSTRING,KVS_PF_OPTIONAL,szType) + KVSM_PARAMETERS_END(c) + + if(szType.isEmpty()) szType="md5"; + + EVP_MD_CTX mdctx; + const EVP_MD *md; + unsigned char md_value[EVP_MAX_MD_SIZE]; + unsigned int md_len, i; + char buff[3]; + OpenSSL_add_all_digests(); + + md = EVP_get_digestbyname(szType.utf8().data()); + if(!md) { + c->warning(__tr2qs("%Q algorytm is not supported"),&szType); + return true; + } + + EVP_MD_CTX_init(&mdctx); + EVP_DigestInit_ex(&mdctx, md, NULL); + EVP_DigestUpdate(&mdctx, szString.utf8().data(), szString.utf8().length()); + EVP_DigestFinal_ex(&mdctx, md_value, &md_len); + EVP_MD_CTX_cleanup(&mdctx); + + for(i = 0; i < md_len; i++) + { +#ifdef COMPILE_ON_WINDOWS + _snprintf(buff,3,"%02x",md_value[i]); +#else + snprintf(buff,3,"%02x",md_value[i]); +#endif + szResult.append(buff); + } + + c->returnValue()->setString(szResult); +#else + c->warning(__tr2qs("KVIrc is compiled without OpenSSL support. $str.digest function disabled")); +#endif + + return true; +} + +/* + @doc: str.join + @type: + function + @title: + $str.join + @short: + Returns a string joined from several strings + @syntax: + $str.join(,[,]) + @description: + Joins all the string in the array by using + the specified and returns the result. + If contains the character "n" then empty strings in teh + array are skipped. + +*/ + + +static bool str_kvs_fnc_join(KviKvsModuleFunctionCall * c) +{ + QString szSep; + KviKvsArrayCast ac; + QString szFlags; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("separator",KVS_PT_STRING,0,szSep) + KVSM_PARAMETER("data",KVS_PT_ARRAYCAST,0,ac) + KVSM_PARAMETER("flags",KVS_PT_STRING,KVS_PF_OPTIONAL,szFlags) + KVSM_PARAMETERS_END(c) + + QString szRet; + bool bSkipEmpty = szFlags.find('n',0,false) != -1; + + bool bFirst = true; + + if(KviKvsArray * a = ac.array()) + { + kvs_uint_t uIdx = 0; + kvs_uint_t uSize = a->size(); + while(uIdx < uSize) + { + KviKvsVariant * v = a->at(uIdx); + if(v) + { + QString tmp; + v->asString(tmp); + if(bFirst) + { + szRet = tmp; + bFirst = false; + } else { + szRet += szSep; + szRet += tmp; + } + } else { + if(!bSkipEmpty) + { + if(bFirst) + { + bFirst = false; + } else { + szRet += szSep; + } + } + } + uIdx++; + } + } + + c->returnValue()->setString(szRet); + return true; +} + + +/* + @doc: str.grep + @type: + function + @title: + $str.grep + @short: + Emulates the GNU Regular Expression Parser + @syntax: + $str.grep(,[,]) + @description: + Returns an array with the elements of which match the string . + can be any combination of the characters 's','w' and 'r'.[br] + If the flag 'w' is specified then is assumed to be a wildcard regular + expression (with * and ? wildcards). If the flag 'r' is specified + then is assumed to be a standard regular expression. If none of + 'w' and 'r' is specified then is treated as a simple string to be + searched in each element of the array. 'r' takes precedence over 'w'. + If the flag 's' is specified the matches are case sensitive.[br] + Note that since almost any other variable type can be automatically cast + to an array, then you can use this function also on scalars or hashes. + @examples: + [example] + [comment]# Find all the nicknames starting with the letter A or a[/comment] + [cmd]echo[/cmd] $str.grep("^a",[fnc]$chan.users[/fnc],"r") + [comment]# Find the current CPU speed (on UNIX like machines only)[/comment] + [cmd]echo[/cmd] $str.grep("MHz",[fnc]$str.split[/fnc]([fnc]$lf[/fnc],[fnc]$file.read[/fnc]("/proc/cpuinfo"))) + [comment]# simply check if the specified string matches a regular expression[/comment] + [comment]# (this in fact is a little tricky, but you will probably not notice it :D)[/comment] + [cmd]if[/cmd]($str.grep("[st]+","test string","r"))[cmd]echo[/cmd] "Yeah, it matches!" + [/example] + @seealso: + [fnc]$array[/fnc] +*/ + +static bool str_kvs_fnc_grep(KviKvsModuleFunctionCall * c) +{ + KviKvsArrayCast ac; + QString szMatch,szFlags; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("match",KVS_PT_STRING,0,szMatch) + KVSM_PARAMETER("strings",KVS_PT_ARRAYCAST,0,ac) + KVSM_PARAMETER("flags",KVS_PT_STRING,KVS_PF_OPTIONAL,szFlags) + KVSM_PARAMETERS_END(c) + + KviKvsArray * n = new KviKvsArray(); + c->returnValue()->setArray(n); + + KviKvsArray * a = ac.array(); + + bool bCaseSensitive = szFlags.find('s',0,false) != -1; + bool bRegexp = szFlags.find('r',0,false) != -1; + bool bWild = szFlags.find('w',0,false) != -1; + int idx = 0; + int cnt = a->size(); + + int i = 0; + if(bRegexp || bWild) + { + QRegExp re(szMatch,bCaseSensitive,bWild); + while(idx < cnt) + { + KviKvsVariant * v = a->at(idx); + if(v) + { + QString sz; + v->asString(sz); + if(re.search(sz) != -1) + { + n->set(i,new KviKvsVariant(sz)); + i++; + } + } + idx++; + } + } else { + while(idx < cnt) + { + KviKvsVariant * v = a->at(idx); + if(v) + { + QString sz; + v->asString(sz); + if(sz.find(szMatch,0,bCaseSensitive) != -1) + { + n->set(i,new KviKvsVariant(sz)); + i++; + } + } + idx++; + } + } + + return true; +} + + +/* + @doc: str.split + @type: + function + @title: + $str.split + @short: + Splits a string to an array + @syntax: + $str.split(,[,[,]]) + @description: + Splits the string by and returns an array of substrings.[br] + may be a combination of the characters 's', 'w', 'r' and 'n'.[br] + If s is specified, matching is case sensitive, otherwise is case insensitive.[br] + If w is specified, is treated as a wildcard-type regular expression + (with * and ? wildcars).[br] + If r is specified, is treated as a extended-type regular expression + (with character classes, special escapes etc..).[br] + If both w and r are specified w takes precedence.[br] + If none of w and r are specified is treated as a simple string to be matched.[br] + If 'n' is specified then eventual empty fields are discarded.[br] + If is specified then at most items are returned in the array (i.e. the last + item may be not splitted completly). + @examples: + [example] + [comment]# Split the fields[/comment] + %test[] = $str.split(!,"Field0!Field1!Field2!Field3!!Field5") + echo %test[] + %i = 0 + [cmd]while[/cmd](%i < %test[]#) + { + [cmd]echo[/cmd] "Field %i: %test[%i]" + %i++; + } + [/example] + Regexp splitting: + [example] + %Test[] = $str.split("[ ]*[0-9][0-9]*-","AllOfThem: 1-Balboy 2-Pragma 3-Iakkolo 4-Crocodile",r) + echo %Test[] + %Test[] = $str.split("Y*H","hihiYeaHhohohoyeahYepYEAHhi",sw) + echo %Test[] + [/example] + If used in "non-array" context it returns just a comma separated list of substrings:[br] + [example] + [cmd]echo[/cmd] $str.split("[ ]*","Condense spaces and change     all       it in commas",r) + [/example] +*/ + +static bool str_kvs_fnc_split(KviKvsModuleFunctionCall * c) +{ + QString szSep,szStr,szFla; + kvs_int_t iMaxItems; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("separator",KVS_PT_STRING,0,szSep) + KVSM_PARAMETER("string",KVS_PT_STRING,0,szStr) + KVSM_PARAMETER("flags",KVS_PT_STRING,KVS_PF_OPTIONAL,szFla) + KVSM_PARAMETER("maxitems",KVS_PT_INTEGER,KVS_PF_OPTIONAL,iMaxItems) + KVSM_PARAMETERS_END(c) + + if(c->params()->count() < 4)iMaxItems = -1; + + KviKvsArray * a = new KviKvsArray(); + c->returnValue()->setArray(a); + + if(szSep.isEmpty()) + { + a->set(0,new KviKvsVariant(szStr)); + return true; + } + + if(iMaxItems == 0)return true; + + bool bWild = szFla.find('w',0,false) != -1; + bool bContainsR = szFla.find('r',0,false) != -1; + bool bCaseSensitive = szFla.find('s',0,false) != -1; + bool bNoEmpty = szFla.find('n',0,false) != -1; + + int id = 0; + + int iMatch = 0; + int iStrLen = szStr.length(); + int iBegin = 0; + + if(bContainsR || bWild) + { + QRegExp re(szSep,bCaseSensitive,bWild); + + while((iMatch != -1) && (iMatch < iStrLen) && ((id < (iMaxItems-1)) || (iMaxItems < 0))) + { + iMatch = re.search(szStr,iBegin); + if(iMatch != -1) + { + int len = re.matchedLength(); + if((len == 0) && (iBegin == iMatch))iMatch++; // safety measure for empty string matching + + QString tmp = szStr.mid(iBegin,iMatch - iBegin); + if(bNoEmpty) + { + if(!tmp.isEmpty()) + { + a->set(id,new KviKvsVariant(tmp)); + id++; + } + } else { + a->set(id,new KviKvsVariant(tmp)); + id++; + } + + iMatch += len; + iBegin = iMatch; + } + } + } else { + while((iMatch != -1) && (iMatch < iStrLen) && ((id < (iMaxItems-1)) || (iMaxItems < 0))) + { + iMatch = szStr.find(szSep,iBegin,bCaseSensitive); + if(iMatch != -1) + { + QString tmp = szStr.mid(iBegin,iMatch - iBegin); + if(bNoEmpty) + { + if(!tmp.isEmpty()) + { + a->set(id,new KviKvsVariant(tmp)); + id++; + } + } else { + a->set(id,new KviKvsVariant(tmp)); + id++; + } + + iMatch += szSep.length(); + iBegin = iMatch; + } + } + } + + if(iBegin < iStrLen) + { + QString tmpx = szStr.right(iStrLen-iBegin); + if(bNoEmpty) + { + if(!tmpx.isEmpty()) + a->set(id,new KviKvsVariant(tmpx)); + } else { + a->set(id,new KviKvsVariant(tmpx)); + } + } else { + if(!bNoEmpty) + a->set(id,new KviKvsVariant(QString::null)); // empty string at the end + } + + return true; +} + +/* + @doc: str.printf + @type: + function + @title: + $str.printf + @short: + Returns a formatted string in a C sprintf-like fashion. + @syntax: + $str.printf([,[...]]); + @description: + This function acts like the C sprintf(): it returns + a string formatted by following the specification in + and by using the following corresponding variadic parameters. + Since the percent sign is used as variable prefix in KVIrc, + this function uses the question mark '?' instead.[br] + The string can contain the following escape sequences:[br] + [br] + [table] + [tr][td][b]?s[/b][/td][td]The next parameter is evaluated as a string and substituted in place of ?s[/td][/tr] + [tr][td][b]?d[/b][/td][td]The next parameter is evaluated as a signed integer and substituted in place of ?d[/td][/tr] + [tr][td][b]?i[/b][/td][td]Same as ?d[/td][/tr] + [tr][td][b]?u[/b][/td][td]The next parameter is evaluated as an unsigned signed integer and substituted in place of ?d[/td][/tr] + [tr][td][b]?x[/b][/td][td]The next parameter is evaluated as an unsigned integer and its hexadecimal rappresentation + is substituted in place of ?x[/td][/tr] + [tr][td][b]?h[/b][/td][td]Same as ?x[/td][/tr] + [tr][td][b]?X[/b][/td][td]Same as ?x but uppercase hexadecimal digits are used[/td][/tr] + [tr][td][b]?H[/b][/td][td]Same as ?X[/td][/tr] + [tr][td][b]??[/b][/td][td]A literal question mark[/td][/tr] + [tr][td][b]?[.N]f[/b][/td][td]The next parameter is evaluated as a real floating point value + and its rappresentation substituted in place of ?f. The optional [.N] modifier, + where N is an unsigned integer, rappresents the desired precision.[/td][/tr] + [tr][td][b]?[.N]e[/b][/td][td]The next parameter is evaluated as a real floating point value + and its scientific rappresentation substituted in place of ?e. The optional [.N] modifier, + where N is an unsigned integer, rappresents the desired precision.[/td][/tr] + [tr][td][b]?[.N]E[/b][/td][td]Same as ?e but an uppercase E is used as the exponent prefix[/td][/tr] + [/table] + @examples: + [example] + %val = $(1.0 / 3.0); + $str.printf("1/3 with a precision of 3 digits is ?.3f, while in scientific notation it's ?e",%val,%val) + [/example] +*/ + + +static bool str_kvs_fnc_printf(KviKvsModuleFunctionCall * c) +{ + QString szFormat; + KviKvsVariantList vArgs; + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("format",KVS_PT_STRING,0,szFormat) + KVSM_PARAMETER("vArgs",KVS_PT_VARIANTLIST,0,vArgs) + KVSM_PARAMETERS_END(c) + + QString s; + +#define MEMINCREMENT 32 + + int reallen = 0; + int allocsize = MEMINCREMENT; + + //s.setLength(allocsize); + + const QChar * fmt = KviQString::nullTerminatedArray(szFormat); + + if(fmt) + { + QChar * buffer = (QChar *)kvi_malloc(sizeof(QChar) * allocsize); + //QChar * p = (QChar *)s.unicode(); + + //9999999999999999999999999999999\0 + char numberBuffer[1024]; + char *pNumBuf; + kvs_uint_t tmp; + kvs_int_t argValue; + kvs_uint_t argUValue; + kvs_real_t argRValue; + + QChar * p = buffer; + + #define INCREMENT_MEM \ + { \ + allocsize += MEMINCREMENT; \ + buffer = (QChar *)kvi_realloc(buffer,sizeof(QChar) * allocsize); \ + p = buffer + reallen; \ + } + + #define INCREMENT_MEM_BY(numchars) \ + { \ + allocsize += numchars + MEMINCREMENT; \ + buffer = (QChar *)kvi_realloc(buffer,sizeof(QChar) * allocsize); \ + p = buffer + reallen; \ + } + + KviKvsVariant * pVar; + + pVar = vArgs.first(); + + for(; fmt->unicode() ; ++fmt) + { + if(reallen == allocsize)INCREMENT_MEM + + //copy up to a '?' + if(fmt->unicode() != '?') + { + *p++ = *fmt; + reallen++; + continue; + } + + ++fmt; //skip this '?' + switch(fmt->unicode()) + { + case 's': + { + QString sz; + if(pVar)pVar->asString(sz); + if(sz.isEmpty())continue; + int len = sz.length(); + if((allocsize - reallen) < len)INCREMENT_MEM_BY(len) + const QChar * ch = sz.unicode(); + while(len--)*p++ = *ch++; + reallen += sz.length(); + pVar = vArgs.next(); + continue; + } + case 'd': //signed integer + { + if(pVar) + { + if(!pVar->asInteger(argValue)) + { + c->warning(__tr2qs("Invalid argument for ?d escape sequence, 0 assumed")); + argValue = 0; + } + } else { + c->warning(__tr2qs("Missing argument for ?d escape sequence, 0 assumed")); + argValue = 0; + } + argValue = 0; + if(argValue < 0) + { //negative integer + *p++ = '-'; + reallen++; + argValue = -argValue; //need to have it positive + // most negative integer exception (avoid completely senseless (non digit) responses) + if(argValue < 0)argValue = 0; //we get -0 here + } + //write the number in a temporary buffer + pNumBuf = numberBuffer; + do { + tmp = argValue / 10; + *pNumBuf++ = argValue - (tmp * 10) + '0'; + } while((argValue = tmp)); + //copy now.... + argUValue = pNumBuf - numberBuffer; //length of the number string + if((allocsize - reallen) < (int)argUValue)INCREMENT_MEM_BY(argUValue) + do { *p++ = QChar(*--pNumBuf); } while(pNumBuf != numberBuffer); + reallen += argUValue; + pVar = vArgs.next(); + continue; + } + case 'u': //unsigned integer + { + if(pVar) + { + if(!pVar->asInteger(argValue)) + { + c->warning(__tr2qs("Invalid argument for ?u escape sequence, 0 assumed")); + argValue = 0; + } + } else { + c->warning(__tr2qs("Missing argument for ?u escape sequence, 0 assumed")); + argValue = 0; + } + argUValue = (kvs_uint_t)argValue; + //write the number in a temporary buffer + pNumBuf = numberBuffer; + do { + tmp = argUValue / 10; + *pNumBuf++ = argUValue - (tmp * 10) + '0'; + } while((argUValue = tmp)); + //copy now.... + argValue = pNumBuf - numberBuffer; //length of the number string + if((allocsize - reallen) < argValue)INCREMENT_MEM_BY(argValue) + do { *p++ = *--pNumBuf; } while(pNumBuf != numberBuffer); + reallen += argValue; + pVar = vArgs.next(); + continue; + } + case 'h': + case 'x': // hexadecimal unsigned integer + { + static char hexsmalldigits[]="0123456789abcdef"; + + if(pVar) + { + if(!pVar->asInteger(argValue)) + { + c->warning(__tr2qs("Invalid argument for ?x escape sequence, 0 assumed")); + argValue = 0; + } + } else { + c->warning(__tr2qs("Missing argument for ?x escape sequence, 0 assumed")); + argValue = 0; + } + argUValue = (kvs_uint_t)argValue; + + //write the number in a temporary buffer + pNumBuf = numberBuffer; + do { + tmp = argUValue / 16; + *pNumBuf++ = hexsmalldigits[argUValue - (tmp * 16)]; + } while((argUValue = tmp)); + //copy now.... + argValue = pNumBuf - numberBuffer; //length of the number string + if((allocsize - reallen) < argValue)INCREMENT_MEM_BY(argValue) + do { *p++ = *--pNumBuf; } while(pNumBuf != numberBuffer); + reallen += argValue; + pVar = vArgs.next(); + continue; + } + case 'H': + case 'X': // hexadecimal unsigned integer + { + static char hexbigdigits[]="0123456789ABCDEF"; + if(pVar) + { + if(!pVar->asInteger(argValue)) + { + c->warning(__tr2qs("Invalid argument for ?X escape sequence, 0 assumed")); + argValue = 0; + } + } else { + c->warning(__tr2qs("Missing argument for ?X escape sequence, 0 assumed")); + argValue = 0; + } + argUValue = (kvs_uint_t)argValue; + //write the number in a temporary buffer + pNumBuf = numberBuffer; + do { + tmp = argUValue / 16; + *pNumBuf++ = hexbigdigits[argUValue - (tmp * 16)]; + } while((argUValue = tmp)); + //copy now.... + argValue = pNumBuf - numberBuffer; //length of the number string + if((allocsize - reallen) < argValue)INCREMENT_MEM_BY(argValue) + do { *p++ = *--pNumBuf; } while(pNumBuf != numberBuffer); + reallen += argValue; + pVar = vArgs.next(); + continue; + } + case '?': + { + if(fmt->unicode()) + { + if(reallen == allocsize)INCREMENT_MEM + *p++ = *fmt; + reallen++; + } + continue; + } + break; + case '.': + { + // precision mark + const QChar * save = fmt; + fmt++; + unsigned int uPrecision = 0; + + char fmtbuffer[8]; + fmtbuffer[0] = '%'; + fmtbuffer[1] = '.'; + + int idx = 2; + + while((fmt->unicode() >= '0') && (fmt->unicode() <= '9') && (idx < 6)) + { + uPrecision *= 10; + fmtbuffer[idx] = fmt->unicode(); + uPrecision += fmtbuffer[idx] - '0'; + fmt++; + idx++; + } + fmtbuffer[idx] = fmt->unicode(); + fmtbuffer[idx+1] = 0; + + if(pVar) + { + if(!pVar->asReal(argRValue)) + { + c->warning(__tr2qs("Invalid argument for a floating point escape sequence, 0.0 assumed")); + argRValue = 0.0; + } + } else { + c->warning(__tr2qs("Missing argument for a floating point escape sequence, 0.0 assumed")); + argRValue = 0; + } + switch(fmt->unicode()) + { + case 'e': + case 'E': + case 'F': + case 'f': + ::sprintf(numberBuffer,fmtbuffer,argRValue); + //copy now.... + argValue = kvi_strLen(numberBuffer); + if((allocsize - reallen) < argValue)INCREMENT_MEM_BY(argValue) + pNumBuf = numberBuffer; + while(*pNumBuf){ *p++ = *pNumBuf++; } + reallen += argValue; + break; + default: + // anything else is crap.. invalid format + fmt = save; + *p++ = '?'; //write it + reallen++; + if(fmt->unicode()) + { + if(reallen == allocsize)INCREMENT_MEM + *p++ = *fmt; + reallen++; + } + break; + } + pVar = vArgs.next(); + continue; + } + break; + default: //a normal ? followed by some char + { + *p++ = '?'; //write it + reallen++; + if(fmt->unicode()) + { + if(reallen == allocsize)INCREMENT_MEM + *p++ = *fmt; + reallen++; + } + continue; + } + } + } + + s.setUnicode(buffer,reallen); + kvi_free(buffer); + } + + c->returnValue()->setString(s); + return true; +} + + + +/*********************************************************************/ +// Module stuff +/********************************************************************/ + +static bool str_module_init(KviModule * m) +{ + KVSM_REGISTER_FUNCTION(m,"split",str_kvs_fnc_split); + KVSM_REGISTER_FUNCTION(m,"grep",str_kvs_fnc_grep); + KVSM_REGISTER_FUNCTION(m,"charsum",str_kvs_fnc_charsum); + KVSM_REGISTER_FUNCTION(m,"len",str_kvs_fnc_len); + KVSM_REGISTER_FUNCTION(m,"length",str_kvs_fnc_len); + KVSM_REGISTER_FUNCTION(m,"isempty",str_kvs_fnc_isempty); + KVSM_REGISTER_FUNCTION(m,"join",str_kvs_fnc_join); + + KVSM_REGISTER_FUNCTION(m,"section",str_kvs_fnc_section); + KVSM_REGISTER_FUNCTION(m,"lowcase",str_kvs_fnc_lowcase); + KVSM_REGISTER_FUNCTION(m,"upcase",str_kvs_fnc_upcase); + KVSM_REGISTER_FUNCTION(m,"localeupcase",str_kvs_fnc_localeupcase); + KVSM_REGISTER_FUNCTION(m,"localelowcase",str_kvs_fnc_localelowcase); + KVSM_REGISTER_FUNCTION(m,"isnumber",str_kvs_fnc_isnumber); + KVSM_REGISTER_FUNCTION(m,"isunsignednumber",str_kvs_fnc_isunsignednumber); + KVSM_REGISTER_FUNCTION(m,"contains",str_kvs_fnc_contains); + KVSM_REGISTER_FUNCTION(m,"containsnocase",str_kvs_fnc_containsnocase); + KVSM_REGISTER_FUNCTION(m,"equal",str_kvs_fnc_equal); + KVSM_REGISTER_FUNCTION(m,"equalnocase",str_kvs_fnc_equalnocase); + KVSM_REGISTER_FUNCTION(m,"cmp",str_kvs_fnc_cmp); + KVSM_REGISTER_FUNCTION(m,"cmpnocase",str_kvs_fnc_cmpnocase); + KVSM_REGISTER_FUNCTION(m,"find",str_kvs_fnc_find); + KVSM_REGISTER_FUNCTION(m,"findfirst",str_kvs_fnc_findfirst); + KVSM_REGISTER_FUNCTION(m,"findfirstnocase",str_kvs_fnc_findfirstnocase); + KVSM_REGISTER_FUNCTION(m,"findlast",str_kvs_fnc_findlast); + KVSM_REGISTER_FUNCTION(m,"findlastnocase",str_kvs_fnc_findlastnocase); + KVSM_REGISTER_FUNCTION(m,"left",str_kvs_fnc_left); + KVSM_REGISTER_FUNCTION(m,"right",str_kvs_fnc_right); + KVSM_REGISTER_FUNCTION(m,"mid",str_kvs_fnc_mid); + KVSM_REGISTER_FUNCTION(m,"append",str_kvs_fnc_append); + KVSM_REGISTER_FUNCTION(m,"prepend",str_kvs_fnc_prepend); + KVSM_REGISTER_FUNCTION(m,"insert",str_kvs_fnc_insert); + KVSM_REGISTER_FUNCTION(m,"strip",str_kvs_fnc_strip); + KVSM_REGISTER_FUNCTION(m,"stripright",str_kvs_fnc_stripright); + KVSM_REGISTER_FUNCTION(m,"stripleft",str_kvs_fnc_stripleft); + KVSM_REGISTER_FUNCTION(m,"stripcolors",str_kvs_fnc_stripcolors); + KVSM_REGISTER_FUNCTION(m,"replace",str_kvs_fnc_replace); + KVSM_REGISTER_FUNCTION(m,"replacenocase",str_kvs_fnc_replacenocase); + KVSM_REGISTER_FUNCTION(m,"urlencode",str_kvs_fnc_urlencode); + KVSM_REGISTER_FUNCTION(m,"lefttolast",str_kvs_fnc_lefttolast); + KVSM_REGISTER_FUNCTION(m,"lefttofirst",str_kvs_fnc_lefttofirst); + KVSM_REGISTER_FUNCTION(m,"rightfromfirst",str_kvs_fnc_rightfromfirst); + KVSM_REGISTER_FUNCTION(m,"rightfromlast",str_kvs_fnc_rightfromlast); + KVSM_REGISTER_FUNCTION(m,"match",str_kvs_fnc_match); + KVSM_REGISTER_FUNCTION(m,"matchnocase",str_kvs_fnc_matchnocase); + KVSM_REGISTER_FUNCTION(m,"word",str_kvs_fnc_word); + KVSM_REGISTER_FUNCTION(m,"token",str_kvs_fnc_token); + KVSM_REGISTER_FUNCTION(m,"fromClipboard",str_kvs_fnc_fromclipboard); + KVSM_REGISTER_FUNCTION(m,"digest",str_kvs_fnc_digest); + KVSM_REGISTER_FUNCTION(m,"printf",str_kvs_fnc_printf); + + KVSM_REGISTER_SIMPLE_COMMAND(m,"toClipboard",str_kvs_cmd_toClipboard); + return true; +} + +static bool str_module_cleanup(KviModule *m) +{ + return true; +} + +KVIRC_MODULE( + "File", // module name + "1.0.0", // module version + "Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)"\ + " (C) 2002 Juanjo Alvarez (juanjux@yahoo.es)" \ + " (C) 2005 Tonino Imbesi (grifisx at barmes dot org)" \ + " (C) 2005 Alessandro Carbone (noldor at barmes dot org)", // author & (C) + "Interface to the str system", + str_module_init, + 0, + 0, + str_module_cleanup +) -- cgit v1.2.1