summaryrefslogtreecommitdiff
path: root/plugins/Variables/src
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-07-24 11:48:31 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-07-24 11:48:31 +0000
commit171e81205e357e0d54283a63997ed58ff97d54a9 (patch)
tree2fe6f4cb440569e07d151564446433fb84b83839 /plugins/Variables/src
parent1e92bf5cf72665b5fec103a0a70d734340725539 (diff)
UserInfoEx, Variables: changed folder structure
git-svn-id: http://svn.miranda-ng.org/main/trunk@1160 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/Variables/src')
-rw-r--r--plugins/Variables/src/ac/ac.h183
-rw-r--r--plugins/Variables/src/action_variables.cpp157
-rw-r--r--plugins/Variables/src/buildnumber.h6
-rw-r--r--plugins/Variables/src/condition_variables.cpp129
-rw-r--r--plugins/Variables/src/contact.cpp555
-rw-r--r--plugins/Variables/src/contact.h78
-rw-r--r--plugins/Variables/src/dbhelpers.h119
-rw-r--r--plugins/Variables/src/enumprocs.cpp348
-rw-r--r--plugins/Variables/src/enumprocs.h21
-rw-r--r--plugins/Variables/src/help.cpp1339
-rw-r--r--plugins/Variables/src/libxml/DOCBparser.h73
-rw-r--r--plugins/Variables/src/libxml/HTMLparser.h159
-rw-r--r--plugins/Variables/src/libxml/HTMLtree.h117
-rw-r--r--plugins/Variables/src/libxml/SAX.h128
-rw-r--r--plugins/Variables/src/libxml/c14n.h91
-rw-r--r--plugins/Variables/src/libxml/catalog.h138
-rw-r--r--plugins/Variables/src/libxml/debugXML.h163
-rw-r--r--plugins/Variables/src/libxml/encoding.h230
-rw-r--r--plugins/Variables/src/libxml/entities.h110
-rw-r--r--plugins/Variables/src/libxml/globals.h363
-rw-r--r--plugins/Variables/src/libxml/hash.h166
-rw-r--r--plugins/Variables/src/libxml/list.h116
-rw-r--r--plugins/Variables/src/libxml/nanoftp.h117
-rw-r--r--plugins/Variables/src/libxml/nanohttp.h56
-rw-r--r--plugins/Variables/src/libxml/parser.h869
-rw-r--r--plugins/Variables/src/libxml/parserInternals.h413
-rw-r--r--plugins/Variables/src/libxml/schemasInternals.h354
-rw-r--r--plugins/Variables/src/libxml/threads.h62
-rw-r--r--plugins/Variables/src/libxml/tree.h905
-rw-r--r--plugins/Variables/src/libxml/uri.h68
-rw-r--r--plugins/Variables/src/libxml/valid.h330
-rw-r--r--plugins/Variables/src/libxml/xinclude.h26
-rw-r--r--plugins/Variables/src/libxml/xlink.h180
-rw-r--r--plugins/Variables/src/libxml/xmlIO.h287
-rw-r--r--plugins/Variables/src/libxml/xmlautomata.h94
-rw-r--r--plugins/Variables/src/libxml/xmlerror.h184
-rw-r--r--plugins/Variables/src/libxml/xmlmemory.h169
-rw-r--r--plugins/Variables/src/libxml/xmlregexp.h81
-rw-r--r--plugins/Variables/src/libxml/xmlschemas.h106
-rw-r--r--plugins/Variables/src/libxml/xmlschemastypes.h42
-rw-r--r--plugins/Variables/src/libxml/xmlunicode.h164
-rw-r--r--plugins/Variables/src/libxml/xmlversion.h272
-rw-r--r--plugins/Variables/src/libxml/xpath.h410
-rw-r--r--plugins/Variables/src/libxml/xpathInternals.h580
-rw-r--r--plugins/Variables/src/libxml/xpointer.h83
-rw-r--r--plugins/Variables/src/libxslt/numbersInternals.h69
-rw-r--r--plugins/Variables/src/libxslt/transform.h191
-rw-r--r--plugins/Variables/src/libxslt/win32config.h96
-rw-r--r--plugins/Variables/src/libxslt/xslt.h97
-rw-r--r--plugins/Variables/src/libxslt/xsltInternals.h609
-rw-r--r--plugins/Variables/src/libxslt/xsltexports.h106
-rw-r--r--plugins/Variables/src/libxslt/xsltutils.h240
-rw-r--r--plugins/Variables/src/libxslt/xsltwin32config.h84
-rw-r--r--plugins/Variables/src/lookup3.cpp640
-rw-r--r--plugins/Variables/src/main.cpp98
-rw-r--r--plugins/Variables/src/options.cpp148
-rw-r--r--plugins/Variables/src/parse_alias.cpp224
-rw-r--r--plugins/Variables/src/parse_alias.h29
-rw-r--r--plugins/Variables/src/parse_external.cpp258
-rw-r--r--plugins/Variables/src/parse_external.h25
-rw-r--r--plugins/Variables/src/parse_inet.cpp143
-rw-r--r--plugins/Variables/src/parse_inet.h22
-rw-r--r--plugins/Variables/src/parse_logic.cpp414
-rw-r--r--plugins/Variables/src/parse_logic.h34
-rw-r--r--plugins/Variables/src/parse_math.cpp225
-rw-r--r--plugins/Variables/src/parse_math.h29
-rw-r--r--plugins/Variables/src/parse_metacontacts.cpp216
-rw-r--r--plugins/Variables/src/parse_metacontacts.h22
-rw-r--r--plugins/Variables/src/parse_miranda.cpp829
-rw-r--r--plugins/Variables/src/parse_miranda.h88
-rw-r--r--plugins/Variables/src/parse_regexp.cpp139
-rw-r--r--plugins/Variables/src/parse_regexp.h20
-rw-r--r--plugins/Variables/src/parse_str.cpp887
-rw-r--r--plugins/Variables/src/parse_str.h56
-rw-r--r--plugins/Variables/src/parse_system.cpp1002
-rw-r--r--plugins/Variables/src/parse_system.h41
-rw-r--r--plugins/Variables/src/parse_variables.cpp173
-rw-r--r--plugins/Variables/src/parse_variables.h28
-rw-r--r--plugins/Variables/src/parse_xml.cpp283
-rw-r--r--plugins/Variables/src/parse_xml.h2
-rw-r--r--plugins/Variables/src/pcre/include/pcre.h503
-rw-r--r--plugins/Variables/src/pcre/include/pcreposix.h146
-rw-r--r--plugins/Variables/src/pcre/lib/pcre.libbin0 -> 129252 bytes
-rw-r--r--plugins/Variables/src/pcre/lib/pcred.libbin0 -> 353490 bytes
-rw-r--r--plugins/Variables/src/pcre/lib64/pcre.libbin0 -> 160500 bytes
-rw-r--r--plugins/Variables/src/pcre/lib64/pcred.libbin0 -> 405164 bytes
-rw-r--r--plugins/Variables/src/pcre/pcre_license.txt45
-rw-r--r--plugins/Variables/src/resource.h56
-rw-r--r--plugins/Variables/src/tokenregister.cpp319
-rw-r--r--plugins/Variables/src/trigger_variables.cpp232
-rw-r--r--plugins/Variables/src/trigger_variables.h36
-rw-r--r--plugins/Variables/src/variables.cpp642
-rw-r--r--plugins/Variables/src/variables.h175
93 files changed, 20362 insertions, 0 deletions
diff --git a/plugins/Variables/src/ac/ac.h b/plugins/Variables/src/ac/ac.h
new file mode 100644
index 0000000000..7d0790f32b
--- /dev/null
+++ b/plugins/Variables/src/ac/ac.h
@@ -0,0 +1,183 @@
+// AMIP public API
+#ifndef _AC_H_
+#define _AC_H_
+
+enum ac_StartMode {
+ AC_START_ALL = 0,
+ AC_START_CLIENT,
+ AC_START_SERVER,
+ AC_START_NONE
+};
+
+enum ac_ErrorCode {
+ AC_ERR_NOERROR = 0,
+ AC_ERR_CLIENTISNULL,
+ AC_ERR_EXCEPTION,
+ AC_ERR_CONNECTIONFAILED,
+ AC_ERR_SERVERNOTRUNNING
+};
+
+#define AC_BUFFER_SIZE 2048
+
+// flags for event listener
+#define AC_EVT_PLAY 0x0001
+#define AC_EVT_PAUSE 0x0002
+#define AC_EVT_STOP 0x0004
+#define AC_EVT_START 0x0008
+#define AC_EVT_EXIT 0x0010
+
+#define AC_EVT_TIMER 0x0020
+#define AC_EVT_MSG 0x0040
+
+#define AC_EVT_CHANGE 0x0080
+
+#define AC_EVT_PLCHANGE 0x0100
+#define AC_EVT_PLREADY 0x0200
+
+// doesn't include AC_EVT_TIMER, because it can be expensive and usually not necessary to use
+// doesn't include AC_EVT_MSG. It's delivered to the message callback function and is never delivered to
+// event callback function
+#define AC_EVT_ALL AC_EVT_PLAY | AC_EVT_PAUSE | AC_EVT_STOP | AC_EVT_START | AC_EVT_EXIT | AC_EVT_CHANGE | AC_EVT_PLCHANGE | AC_EVT_PLREADY
+
+typedef VOID (CALLBACK* AC_MSG_CALLBACK) (const char *);
+typedef VOID (CALLBACK* AC_EVT_CALLBACK) (int);
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+ // Initializes client part of the component. Parameters specify host and port client
+ // should connect to (where AMIP is running), connection timeout in milliseconds, number
+ // of seconds (dsec) to suspend connections for if failed to connect dcount times.
+ // returns 1 if client was initialized properly, 0 otherwise
+ int WINAPI ac_init_client(const char *host, int port, int timeout, int dsec, int dcount);
+
+ // Initializes and starts the server part of the component. Server part listens for
+ // incoming connections from AMIP, it receives messages and events on specified host and port.
+ // returns 1 if server was started successfully, 0 otherwise
+ int WINAPI ac_init_server(const char *host, int port);
+
+ // Alternative method to start services, differs from 2 specified above in the way
+ // where it gets the configuration data. Startup data is read from the ac.ini file.
+ // Don't use ac_init() together with ac_init_client() and ac_init_server()!
+ // Call to start services (AC_START_ALL to start both client and server)
+ // AC_START_CLIENT will start client only (you can query and control AMIP)
+ // AC_START_SERVER will start server only (you can accept song announcements from AMIP)
+ void WINAPI ac_init(int mode);
+
+ // Call when you finished working with AMIP (e.g. on exit)
+ void WINAPI ac_uninit();
+
+ // Useful if you need to uninit the client to init it later with different options
+ void WINAPI ac_uninit_client();
+
+ // Stops the server, you can start it again with different options later
+ // Subsequent calls to ac_uninit_client() and ac_stop_server() can be replaced with the
+ // single call to ac_uninit()
+ void WINAPI ac_stop_server();
+
+ // Passes command to AMIP. For the list of commands see AMIP Help.
+ // Remove '/dde mplug' prefix to get the real command, for instance
+ // in the help you see '/dde mplug announce preset 1' command, this
+ // function will accept 'announce preset 1' as the parameter
+ int WINAPI ac_exec(const char *cmd);
+
+ // Evaluates AMIP's variable and puts the result into the result buffer
+ // cmd can be var_<variable>, where variable is any of the AMIP variables
+ // without %, for instance %name becomes var_name. Also cfg_<parameter>
+ // variables are supported (cfg_enabled, cfg_rmienabled, etc.)
+ // Basically, all the $dde variables from help can be evaluated via this
+ // function ('$dde mplug format "%name"' becomes 'format "%name"')
+ // Warning: result buffer must have AC_BUFFER_SIZE capacity
+ int WINAPI ac_eval(const char *cmd, char *result);
+
+ // same as ac_eval but takes a format spec string and evaluates it all, the format
+ // spec may look like "%1 - %2 (%br~kbps)"
+ int WINAPI ac_format(const char *cmd, char *result);
+ // ac_exec and ac_eval return one of the AC_ERR_* codes
+ // if function succeeds, the return code is AC_ERR_NOERROR (0)
+ // if ac_eval fails, empty string is placed into the result buffer
+
+ // Registers callback function which will receive all messages from AMIP.
+ // Pass address of your function taking char* as an argument and it will
+ // be called every time AMIP has something to say you
+ void WINAPI ac_register_msg_callback(AC_MSG_CALLBACK);
+
+ // Event callback will accept events from AMIP if listener for events was added
+ void WINAPI ac_register_evt_callback(AC_EVT_CALLBACK);
+
+ // Adds listener to AMIP, AMIP will notify host:port about the events specified by flags
+ // until listener is removed or fail_count limit is reached. If notification fails
+ // fail_count times, AMIP automatically removes listener for the specified host:port.
+ // AMIP keeps listeners even between restarts (in plugin.ini file)
+ int WINAPI ac_add_event_listener(const char *host, int port, int timeout, UINT flags, UINT fail_count);
+
+ // You must unregister all listeners that you have registered before your application exits
+ int WINAPI ac_remove_event_listener(const char *host, int port);
+
+
+ // Ping server on the specified address and port
+ // returns true if there is AMIP server running
+ // returns false if server cannot be reached within the specified timeout (ms)
+ BOOL WINAPI ac_pingServer(const char *host, int port, int timeout);
+
+
+ // Playlist related functions:
+ // Gets playlist from AMIP and caches it, you should use this function every time playlist changes
+ // (AC_EVT_PLCHANGE event received) and before using any other playlist related functions.
+ // The correct usage sequence:
+ // 1. Register listener for AC_EVT_PLCHANGE and AC_EVT_PLREADY events
+ // 2. When you receive AC_EVT_PLCHANGE event via callback or upon first usage you must re-index playlist
+ // using ac_exec("reindexq") function call (AMIP builds playlist cache)
+ // 3. When playlist is re-indexed, you will receive AC_EVT_PLREADY event, only at this moment you should
+ // call ac_get_pl() function (this function gets cached playlist from AMIP)
+ // Return code is the same as for ac_exec and ac_eval functions, see ac_ErrorCode enum
+ int WINAPI ac_get_pl();
+
+ // Returns the size of playlist cached by client. You can compare it with the size of real playlist, the
+ // size of playlist cached by AMIP and do re-index and ac_get_pl to be in sync if necessary
+ int WINAPI ac_get_plsize();
+
+ // Returns 1 if title is not NULL and within playlist bounds, 0 otherwise
+ // Title with the specified zero-based idx is copied to buff. buff must have at least AC_BUFFER_SIZE size
+ // Make sure to prepare playlist first, see ac_get_pl() function comments, use ac_get_plsize() to determine
+ // playlist size
+ int WINAPI ac_get_title(UINT idx, char *buff);
+
+
+ // configuring Client
+ // AMIP port client will try to connect to (default 60333)
+ void WINAPI ac_setDestPort(int port);
+
+ // AMIP host client will try to connect to (default 127.0.0.1)
+ void WINAPI ac_setDestHost(const char *host);
+
+ // Client timeout
+ void WINAPI ac_setTimeout(int ms);
+
+ // Source port the client will listen for AMIP commands on (default 60334)
+ void WINAPI ac_setSrcPort(int port);
+
+ // Source host interface which will accept AMIP connections (default 127.0.0.1)
+ void WINAPI ac_setSrcHost(const char *host);
+
+ // get configuration
+ int WINAPI ac_getSrcPort();
+ int WINAPI ac_getDestPort();
+ void WINAPI ac_getSrcHost(char *out_host);
+ void WINAPI ac_getDestHost(char *out_host);
+
+ // Reload the configuration and restart services
+ void WINAPI ac_rehash();
+
+ // Returns the major part of API version (for ac 1.2 will return 1)
+ int WINAPI ac_version_major();
+
+ // Returns the mainor part of API version (for ac 1.2 will return 2)
+ int WINAPI ac_version_minor();
+
+#ifdef __cplusplus
+}
+#endif /*__cplusplus*/
+
+#endif /*_AC_H_*/
diff --git a/plugins/Variables/src/action_variables.cpp b/plugins/Variables/src/action_variables.cpp
new file mode 100644
index 0000000000..e4d1a17aa1
--- /dev/null
+++ b/plugins/Variables/src/action_variables.cpp
@@ -0,0 +1,157 @@
+/*
+ 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
+*/
+// This file has not been converted to unicode yet
+#include "variables.h"
+#include "m_trigger.h"
+#include "trigger_variables.h"
+#include "resource.h"
+
+static void parseStringThread(void *arg) {
+
+ TCHAR *tszParsed;
+ FORMATINFO *fi;
+
+ fi = (FORMATINFO *)arg;
+ if (arg == NULL) {
+ return;
+ }
+ tszParsed = (TCHAR*)CallService(MS_VARS_FORMATSTRING, (WPARAM)fi, 0);
+ log_debugA("parseStringThread: %s > %s", fi->tszFormat, tszParsed);
+ if (tszParsed != NULL) {
+ mir_free(tszParsed);
+ }
+ if (fi->tszFormat != NULL) {
+ mir_free(fi->tszFormat);
+ }
+ if (fi->tszExtraText != NULL) {
+ mir_free(fi->tszExtraText);
+ }
+ mir_free(fi);
+}
+
+
+int ParseStringAction(DWORD actionID, REPORTINFO *ri) {
+
+ if (ri->flags&ACT_PERFORM) {
+ DBVARIANT dbv;
+
+ if (!DBGetActionSettingTString(actionID, NULL, MODULENAME, SETTING_PARSESTRING, &dbv)) {
+ if (DBGetActionSettingByte(actionID, NULL, MODULENAME, SETTING_PARSEASYNC, 0)) {
+ FORMATINFO *fi;
+
+ fi = ( FORMATINFO* )mir_alloc(sizeof(FORMATINFO));
+ ZeroMemory(fi, sizeof(FORMATINFO));
+ fi->cbSize = sizeof(FORMATINFO);
+ fi->tszFormat = mir_tstrdup(dbv.ptszVal);
+ fi->tszExtraText = ((ri->td!=NULL)&&(ri->td->dFlags&DF_TEXT))?mir_tstrdup(ri->td->tszText):NULL;
+ fi->hContact = ((ri->td!=NULL)&&(ri->td->dFlags&DF_CONTACT))?ri->td->hContact:NULL;
+ fi->flags |= FIF_TCHAR;
+ //forkthread(parseStringThread, 0, fi);
+ mir_forkthread(parseStringThread, fi);
+ }
+ else {
+ mir_free(variables_parsedup(dbv.ptszVal, ((ri->td!=NULL)&&(ri->td->dFlags&DF_TEXT))?ri->td->tszText:NULL, ((ri->td!=NULL)&&(ri->td->dFlags&DF_CONTACT))?ri->td->hContact:NULL));
+ }
+ DBFreeVariant(&dbv);
+ }
+ }
+ if (ri->flags&ACT_CLEANUP) {
+ REMOVETRIGGERSETTINGS ras;
+
+ ras.cbSize = sizeof(REMOVETRIGGERSETTINGS);
+ ras.prefix = PREFIX_ACTIONID;
+ ras.id = actionID;
+ ras.szModule = MODULENAME;
+ ras.hContact = NULL;
+ CallService(MS_TRIGGER_REMOVESETTINGS, 0, (LPARAM)&ras);
+ }
+
+ return 0;
+}
+
+INT_PTR CALLBACK DlgProcOptsParseString(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
+
+ switch (msg) {
+ case WM_INITDIALOG: {
+ DBVARIANT dbv;
+ DWORD actionID;
+
+ TranslateDialogDefault(hwndDlg);
+ actionID = (DWORD)lParam;
+ if (!DBGetActionSettingTString(actionID, NULL, MODULENAME, SETTING_PARSESTRING, &dbv)) {
+ SetDlgItemText(hwndDlg, IDC_PARSESTRING, dbv.ptszVal);
+ DBFreeVariant(&dbv);
+ }
+ CheckDlgButton(hwndDlg, IDC_PARSEASYNC, DBGetActionSettingByte(actionID, NULL, MODULENAME, SETTING_PARSEASYNC, 0)?BST_CHECKED:BST_UNCHECKED);
+ variables_skin_helpbutton(hwndDlg, IDC_SHOWHELP);
+ break;
+ }
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDC_SHOWHELP: {
+ int flags;
+ VARHELPINFO vhi;
+ TRIGGERINFO ti;
+
+ ZeroMemory(&ti, sizeof(TRIGGERINFO));
+ SendMessage(GetParent(hwndDlg), TM_GETTRIGGERINFO, 0, (LPARAM)&ti);
+ ZeroMemory(&vhi, sizeof(VARHELPINFO));
+ vhi.cbSize = sizeof(VARHELPINFO);
+ vhi.flags = VHF_INPUT;
+ if (ti.dFlags&DF_TEXT) {
+ vhi.flags |= VHF_EXTRATEXT;
+ vhi.szExtraTextDesc = "TriggerData: Text";
+ }
+ else {
+ flags |= VHF_HIDESUBJECTTOKEN;
+ }
+ if (ti.dFlags&DF_CONTACT) {
+ flags |= VHF_SUBJECT;
+ vhi.szSubjectDesc = "TriggerData: Contact";
+ }
+ else {
+ flags |= VHF_HIDEEXTRATEXTTOKEN;
+ }
+ vhi.hwndCtrl = GetDlgItem(hwndDlg, IDC_PARSESTRING);
+ CallService(MS_VARS_SHOWHELPEX, (WPARAM)hwndDlg, (LPARAM)&vhi);
+ break;
+ }
+ }
+ break;
+
+ case TM_ADDACTION: {
+ // wParam = action ID
+ // lParam = 0
+ DWORD actionID = (DWORD)wParam;
+ TCHAR *tszText = Hlp_GetDlgItemText(hwndDlg, IDC_PARSESTRING);
+ if (tszText != NULL) {
+ DBWriteActionSettingTString(actionID, NULL, MODULENAME, SETTING_PARSESTRING, tszText);
+ mir_free(tszText);
+ }
+ DBWriteActionSettingByte(actionID, NULL, MODULENAME, SETTING_PARSEASYNC, (BYTE)IsDlgButtonChecked(hwndDlg, IDC_PARSEASYNC));
+ break;
+ }
+
+ case WM_DESTROY:
+ break;
+ }
+
+ return FALSE;
+} \ No newline at end of file
diff --git a/plugins/Variables/src/buildnumber.h b/plugins/Variables/src/buildnumber.h
new file mode 100644
index 0000000000..2e38a77fad
--- /dev/null
+++ b/plugins/Variables/src/buildnumber.h
@@ -0,0 +1,6 @@
+#ifndef _BUILDNUMBER_
+#define BUILDNUMBER 0
+#define __FILEVERSION_STRING 0,2,3,9
+#define __VERSION_STRING "0.2.3.9"
+#define __VERSION_DWORD 0x20309
+#endif //_BUILDNUMBER_
diff --git a/plugins/Variables/src/condition_variables.cpp b/plugins/Variables/src/condition_variables.cpp
new file mode 100644
index 0000000000..c58703cc54
--- /dev/null
+++ b/plugins/Variables/src/condition_variables.cpp
@@ -0,0 +1,129 @@
+/*
+ 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
+*/
+// This file has not been converted to unicode yet
+#include "variables.h"
+#include "m_trigger.h"
+#include "trigger_variables.h"
+#include "resource.h"
+
+int ParseStringCondition(DWORD conditionID, REPORTINFO *ri) {
+
+ int res;
+
+ res = CRV_TRUE;
+ if (ri->flags&CND_PERFORM) {
+ DBVARIANT dbv;
+
+ if (!DBGetConditionSettingTString(conditionID, NULL, MODULENAME, SETTING_PARSESTRING, &dbv)) {
+ FORMATINFO fi;
+
+ ZeroMemory(&fi, sizeof(FORMATINFO));
+ fi.cbSize = sizeof(FORMATINFO);
+ fi.tszFormat = dbv.ptszVal;
+ fi.tszExtraText = ((ri->td!=NULL)&&(ri->td->dFlags&DF_TEXT))?ri->td->tszText:NULL;
+ fi.hContact = ((ri->td!=NULL)&&(ri->td->dFlags&DF_CONTACT))?ri->td->hContact:NULL;
+ fi.flags |= FIF_TCHAR;
+ mir_free((TCHAR*)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0));
+ log_debugA("err: %d", fi.eCount);
+ res = fi.eCount==0?CRV_TRUE:CRV_FALSE;
+ DBFreeVariant(&dbv);
+ }
+ }
+ if (ri->flags&CND_CLEANUP) {
+ REMOVETRIGGERSETTINGS ras;
+
+ ras.cbSize = sizeof(REMOVETRIGGERSETTINGS);
+ ras.prefix = PREFIX_CONDITIONID;
+ ras.id = conditionID;
+ ras.szModule = MODULENAME;
+ ras.hContact = NULL;
+ CallService(MS_TRIGGER_REMOVESETTINGS, 0, (LPARAM)&ras);
+ }
+
+ return res;
+}
+
+INT_PTR CALLBACK DlgProcOptsCondition(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
+
+ switch (msg) {
+ case WM_INITDIALOG: {
+ DBVARIANT dbv;
+ DWORD conditionID;
+
+ TranslateDialogDefault(hwndDlg);
+ conditionID = (DWORD)lParam;
+ if (!DBGetConditionSettingTString(conditionID, NULL, MODULENAME, SETTING_PARSESTRING, &dbv)) {
+ SetDlgItemText(hwndDlg, IDC_PARSESTRING, dbv.ptszVal);
+ DBFreeVariant(&dbv);
+ }
+ break;
+ }
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDC_SHOWHELP: {
+ int flags;
+ VARHELPINFO vhi;
+ TRIGGERINFO ti;
+
+ ZeroMemory(&vhi, sizeof(VARHELPINFO));
+ vhi.cbSize = sizeof(VARHELPINFO);
+ ZeroMemory(&ti, sizeof(TRIGGERINFO));
+ SendMessage(GetParent(hwndDlg), TM_GETTRIGGERINFO, 0, (LPARAM)&ti);
+ vhi.flags = VHF_INPUT;
+ if (ti.dFlags&DF_TEXT) {
+ vhi.flags |= VHF_EXTRATEXT;
+ vhi.szExtraTextDesc = "TriggerData: Text";
+ }
+ else {
+ flags |= VHF_HIDEEXTRATEXTTOKEN;
+ }
+ if (ti.dFlags&DF_CONTACT) {
+ flags |= VHF_SUBJECT;
+ vhi.szSubjectDesc = "TriggerData: Contact";
+ }
+ else {
+ flags |= VHF_HIDESUBJECTTOKEN;
+ }
+ vhi.hwndCtrl = GetDlgItem(hwndDlg, IDC_PARSESTRING);
+ CallService(MS_VARS_SHOWHELPEX, (WPARAM)hwndDlg, (LPARAM)&vhi);
+ break;
+ }
+ }
+ break;
+
+ case TM_ADDCONDITION: {
+ DWORD conditionID;
+ TCHAR *tszText;
+
+ conditionID = (DWORD)wParam;
+ tszText = Hlp_GetDlgItemText(hwndDlg, IDC_PARSESTRING);
+ if (tszText != NULL) {
+ DBWriteConditionSettingTString(conditionID, NULL, MODULENAME, SETTING_PARSESTRING, tszText);
+ mir_free(tszText);
+ }
+ break;
+ }
+
+ case WM_DESTROY:
+ break;
+ }
+
+ return FALSE;
+} \ No newline at end of file
diff --git a/plugins/Variables/src/contact.cpp b/plugins/Variables/src/contact.cpp
new file mode 100644
index 0000000000..9e2f08c83e
--- /dev/null
+++ b/plugins/Variables/src/contact.cpp
@@ -0,0 +1,555 @@
+/*
+ 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 "contact.h"
+
+struct _tagType
+{
+ int cnfCode;
+ TCHAR* str;
+}
+static builtinCnfs[] =
+{
+ { CNF_FIRSTNAME, _T(STR_FIRSTNAME) },
+ { CNF_LASTNAME, _T(STR_LASTNAME) },
+ { CNF_NICK, _T(STR_NICK) },
+ { CNF_CUSTOMNICK, _T(STR_CUSTOMNICK) },
+ { CNF_EMAIL, _T(STR_EMAIL) },
+ { CNF_CITY, _T(STR_CITY) },
+ { CNF_STATE, _T(STR_STATE) },
+ { CNF_COUNTRY, _T(STR_COUNTRY) },
+ { CNF_PHONE, _T(STR_PHONE) },
+ { CNF_HOMEPAGE, _T(STR_HOMEPAGE) },
+ { CNF_ABOUT, _T(STR_ABOUT) },
+ { CNF_GENDER, _T(STR_GENDER) },
+ { CNF_AGE, _T(STR_AGE) },
+ { CNF_FIRSTLAST, _T(STR_FIRSTLAST) },
+ { CNF_UNIQUEID, _T(STR_UNIQUEID) },
+ { CNF_DISPLAY, _T(STR_DISPLAY) },
+ { CNF_FAX, _T(STR_FAX) },
+ { CNF_CELLULAR, _T(STR_CELLULAR) },
+ { CNF_TIMEZONE, _T(STR_TIMEZONE) },
+ { CNF_MYNOTES, _T(STR_MYNOTES) },
+ { CNF_BIRTHDAY, _T(STR_BIRTHDAY) },
+ { CNF_BIRTHMONTH, _T(STR_BIRTHMONTH) },
+ { CNF_BIRTHYEAR, _T(STR_BIRTHYEAR) },
+ { CNF_STREET, _T(STR_STREET) },
+ { CNF_ZIP, _T(STR_ZIP) },
+ { CNF_LANGUAGE1, _T(STR_LANGUAGE1) },
+ { CNF_LANGUAGE2, _T(STR_LANGUAGE2) },
+ { CNF_LANGUAGE3, _T(STR_LANGUAGE3) },
+ { CNF_CONAME, _T(STR_CONAME) },
+ { CNF_CODEPT, _T(STR_CODEPT) },
+ { CNF_COPOSITION, _T(STR_COPOSITION) },
+ { CNF_COSTREET, _T(STR_COSTREET) },
+ { CNF_COCITY, _T(STR_COCITY) },
+ { CNF_COSTATE, _T(STR_COSTATE) },
+ { CNF_COZIP, _T(STR_COZIP) },
+ { CNF_COCOUNTRY, _T(STR_COCOUNTRY) },
+ { CNF_COHOMEPAGE, _T(STR_COHOMEPAGE) },
+
+ { CCNF_ACCOUNT, _T(STR_ACCOUNT) },
+ { CCNF_PROTOCOL, _T(STR_PROTOCOL) },
+ { CCNF_STATUS, _T(STR_STATUS) },
+ { CCNF_INTERNALIP, _T(STR_INTERNALIP) },
+ { CCNF_EXTERNALIP, _T(STR_EXTERNALIP) },
+ { CCNF_GROUP, _T(STR_GROUP) },
+ { CCNF_PROTOID, _T(STR_PROTOID) }
+};
+
+typedef struct {
+ TCHAR* tszContact;
+ HANDLE hContact;
+ DWORD flags;
+} CONTACTCE; /* contact cache entry */
+
+/* cache for 'getcontactfromstring' service */
+static CONTACTCE *cce = NULL;
+static int cacheSize = 0;
+static CRITICAL_SECTION csContactCache;
+
+static HANDLE hContactSettingChangedHook;
+static HANDLE hGetContactFromStringService;
+
+/*
+ converts a string into a CNF_ type
+*/
+BYTE getContactInfoType(TCHAR* type) {
+
+ int i;
+
+ if (type == NULL || _tcslen(type) == 0 )
+ return 0;
+
+ for ( i=0; i < SIZEOF(builtinCnfs); i++ )
+ if (!_tcscmp( builtinCnfs[i].str, type ))
+ return builtinCnfs[i].cnfCode;
+
+ return 0;
+}
+
+/*
+ returns info about a contact as a string
+*/
+TCHAR* getContactInfoT(BYTE type, HANDLE hContact)
+{
+ /* returns dynamic allocated buffer with info, or NULL if failed */
+ CONTACTINFO ci;
+ TCHAR *res = NULL, *szStatus;
+ char *szProto, protoname[128], szVal[16];
+ DBVARIANT dbv;
+
+ if (hContact == NULL)
+ return NULL;
+
+ szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if (szProto == NULL)
+ return NULL;
+
+ switch (type)
+ {
+ case CCNF_PROTOID:
+ return (TCHAR*)mir_a2t(szProto);
+
+ case CCNF_ACCOUNT:
+ if (g_mirandaVersion < PLUGIN_MAKE_VERSION( 0,8,0,0 ))
+ return NULL;
+ {
+ PROTOACCOUNT* pa = ProtoGetAccount(szProto);
+ return pa ? mir_tstrdup(pa->tszAccountName) : NULL;
+ }
+
+ case CCNF_PROTOCOL:
+ if (CallProtoService(szProto, PS_GETNAME, (WPARAM)sizeof(protoname), (LPARAM)protoname))
+ return NULL;
+ return (TCHAR*)mir_a2t(protoname);
+
+ case CCNF_STATUS:
+ szStatus = (TCHAR*)CallService(
+ MS_CLIST_GETSTATUSMODEDESCRIPTION,
+ (WPARAM)DBGetContactSettingWord(hContact, szProto, "Status", ID_STATUS_OFFLINE),
+ (LPARAM)GSMDF_UNICODE);
+ if (szStatus == NULL)
+ return NULL;
+ return mir_tstrdup(szStatus);
+
+ case CCNF_INTERNALIP:
+ case CCNF_EXTERNALIP:
+ {
+ DWORD ip = DBGetContactSettingDword(hContact, szProto, (type == CCNF_INTERNALIP) ? "RealIP" : "IP", 0);
+ if (ip == 0)
+ return NULL;
+
+ struct in_addr in;
+ in.s_addr = htonl(ip);
+ char* dotted = inet_ntoa(in);
+ if (dotted == NULL)
+ return NULL;
+ return (TCHAR*)mir_a2t(dotted);
+ }
+
+ case CCNF_GROUP:
+ if (!DBGetContactSettingTString(hContact, "CList", "Group", &dbv))
+ {
+ res = (TCHAR*)mir_wstrdup(dbv.pwszVal);
+ DBFreeVariant(&dbv);
+ return res;
+ }
+ break;
+
+ case CNF_UNIQUEID:
+ //UID for ChatRoom
+ if (DBGetContactSettingByte(hContact, szProto, "ChatRoom", 0) == 1)
+ {
+ DBVARIANT dbv;
+ if (!DBGetContactSettingTString(hContact, szProto, "ChatRoomID", &dbv ))
+ {
+ res = mir_tstrdup( dbv.ptszVal );
+ DBFreeVariant( &dbv );
+ return res;
+
+ }
+ }
+
+ //UID for other contact
+ break;
+ }
+
+ ZeroMemory(&ci,sizeof(CONTACTINFO));
+ ci.cbSize = sizeof(CONTACTINFO);
+ ci.hContact = hContact;
+ ci.dwFlag = type | CNF_UNICODE;
+ CallService(MS_CONTACT_GETCONTACTINFO, (WPARAM)0, (LPARAM)&ci);
+
+ memset(szVal, '\0', sizeof(szVal));
+ switch(ci.type)
+ {
+ case CNFT_BYTE:
+ if (type != CNF_GENDER)
+ return itot(ci.bVal);
+
+ szVal[0] = (char)ci.bVal;
+ return (TCHAR*)mir_a2t(szVal);
+
+ case CNFT_WORD:
+ return itot(ci.wVal);
+
+ case CNFT_DWORD:
+ return itot(ci.dVal);
+
+ case CNFT_ASCIIZ:
+ if (ci.pszVal != NULL)
+ {
+ res = mir_tstrdup(ci.pszVal);
+ mir_free(ci.pszVal);
+ }
+ break;
+ }
+
+ return res;
+}
+
+/*
+ MS_VARS_GETCONTACTFROMSTRING
+*/
+int getContactFromString( CONTACTSINFO* ci )
+{
+ /* service to retrieve a contact's HANDLE from a given string */
+ char *szProto;
+ TCHAR *szFind, *cInfo, *tszContact, *tszProto;
+ BOOL bMatch;
+ DBVARIANT dbv;
+ HANDLE hContact;
+ int count, i;
+
+ if (ci == NULL)
+ return -1;
+
+ if (ci->flags&CI_UNICODE) {
+
+ tszContact = NEWTSTR_ALLOCA(ci->tszContact);
+
+ }
+ else {
+
+ WCHAR* tmp = mir_a2t(ci->szContact);
+ tszContact = NEWTSTR_ALLOCA(tmp);
+ mir_free(tmp);
+
+ }
+ if ((tszContact == NULL) || (_tcslen(tszContact) == 0))
+ return -1;
+
+ ci->hContacts = NULL;
+ count = 0;
+ /* search the cache */
+ EnterCriticalSection(&csContactCache);
+ for (i=0;i<cacheSize;i++) {
+ if ((!_tcscmp(cce[i].tszContact, tszContact)) && (ci->flags == cce[i].flags)) {
+ /* found in cache */
+ ci->hContacts = ( HANDLE* )mir_alloc(sizeof(HANDLE));
+ if (ci->hContacts == NULL) {
+ LeaveCriticalSection(&csContactCache);
+ return -1;
+ }
+ ci->hContacts[0] = cce[i].hContact;
+ LeaveCriticalSection(&csContactCache);
+ return 1;
+ }
+ }
+
+ LeaveCriticalSection(&csContactCache);
+ /* contact was not in cache, do a search */
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact != NULL) {
+ szFind = NULL;
+ bMatch = FALSE;
+ ZeroMemory(&dbv, sizeof(DBVARIANT));
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if (szProto == NULL) {
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact, 0);
+ continue;
+ }
+ // <proto:id> (exact)
+ if (ci->flags&CI_PROTOID)
+ {
+ cInfo = getContactInfoT(CNF_UNIQUEID, hContact);
+ if (cInfo == NULL)
+ {
+ // <HANDLE:hContact>
+ cInfo = (TCHAR*)mir_alloc(32);
+ _stprintf(cInfo, _T("%p"), hContact);
+ szFind = (TCHAR*)mir_alloc((_tcslen(cInfo) + _tcslen(_T(PROTOID_HANDLE)) + 4)*sizeof(TCHAR));
+ if (szFind != NULL)
+ {
+ wsprintf(szFind, _T("<%s:%s>"), _T(PROTOID_HANDLE), cInfo);
+ if (!_tcsncmp(tszContact, szFind, _tcslen(tszContact)))
+ {
+ bMatch = TRUE;
+ }
+ mir_free(cInfo);
+ mir_free(szFind);
+ }
+ }
+ else
+ {
+ szFind = (TCHAR*)mir_alloc((_tcslen(cInfo) + strlen(szProto) + 4)*sizeof(TCHAR));
+ if (szFind != NULL)
+ {
+ tszProto = mir_a2t(szProto);
+
+ if ((tszProto != NULL) && (szFind != NULL))
+ {
+ wsprintf(szFind, _T("<%s:%s>"), tszProto, cInfo);
+ mir_free(cInfo);
+ mir_free(tszProto);
+ if (!_tcsncmp(tszContact, szFind, _tcslen(tszContact)))
+ bMatch = TRUE;
+
+ mir_free(szFind);
+ }
+ }
+ }
+ }
+ // id (exact)
+ if ((ci->flags&CI_UNIQUEID) && (!bMatch)) {
+ szFind = getContactInfoT(CNF_UNIQUEID, hContact);
+ if (szFind != NULL) {
+ if (!_tcscmp(tszContact, szFind))
+ bMatch = TRUE;
+
+ mir_free(szFind);
+ }
+ }
+ // nick (not exact)
+ if ((ci->flags&CI_NICK) && (!bMatch)) {
+ szFind = getContactInfoT(CNF_NICK, hContact);
+ if (szFind != NULL) {
+ if (!_tcscmp(tszContact, szFind))
+ bMatch = TRUE;
+
+ mir_free(szFind);
+ }
+ }
+ // list name (not exact)
+ if ((ci->flags&CI_LISTNAME) && (!bMatch)) {
+ szFind = getContactInfoT(CNF_DISPLAY, hContact);
+ if (szFind != NULL) {
+ if (!_tcscmp(tszContact, szFind))
+ bMatch = TRUE;
+
+ mir_free(szFind);
+ }
+ }
+ // firstname (exact)
+ if ((ci->flags&CI_FIRSTNAME) && (!bMatch)) {
+ szFind = getContactInfoT(CNF_FIRSTNAME, hContact);
+ if (szFind != NULL) {
+ if (!_tcscmp(tszContact, szFind)) {
+ bMatch = TRUE;
+ }
+ mir_free(szFind);
+ }
+ }
+ // lastname (exact)
+ if ((ci->flags&CI_LASTNAME) && (!bMatch)) {
+ szFind = getContactInfoT(CNF_LASTNAME, hContact);
+ if (szFind != NULL) {
+ if (!_tcscmp(tszContact, szFind)) {
+ bMatch = TRUE;
+ }
+ mir_free(szFind);
+ }
+ }
+ // email (exact)
+ if ((ci->flags&CI_EMAIL) && (!bMatch)) {
+ szFind = getContactInfoT(CNF_EMAIL, hContact);
+ if (szFind != NULL) {
+ if (!_tcscmp(tszContact, szFind)) {
+ bMatch = TRUE;
+ }
+ mir_free(szFind);
+ }
+ }
+ // CNF_ (exact)
+ if ((ci->flags&CI_CNFINFO) && (!bMatch)) {
+ szFind = getContactInfoT((BYTE)(ci->flags&~(CI_CNFINFO|CI_TCHAR)), hContact);
+ if (szFind != NULL) {
+ if (!_tcscmp(tszContact, szFind)) {
+ bMatch = TRUE;
+ }
+ mir_free(szFind);
+ }
+ }
+ if (bMatch) {
+ ci->hContacts = ( HANDLE* )mir_realloc(ci->hContacts, (count+1)*sizeof(HANDLE));
+ if (ci->hContacts == NULL) {
+
+ return -1;
+ }
+ ci->hContacts[count] = hContact;
+ count += 1;
+ }
+ hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0);
+ }
+
+ if (count == 1) { /* cache the found result */
+ EnterCriticalSection(&csContactCache);
+ cce = ( CONTACTCE* )mir_realloc(cce, (cacheSize+1)*sizeof(CONTACTCE));
+ if (cce == NULL) {
+ LeaveCriticalSection(&csContactCache);
+ return count;
+ }
+
+ cce[cacheSize].hContact = ci->hContacts[0];
+ cce[cacheSize].flags = ci->flags;
+ cce[cacheSize].tszContact = mir_tstrdup(tszContact);
+ if (cce[cacheSize].tszContact != NULL)
+ cacheSize += 1;
+
+ LeaveCriticalSection(&csContactCache);
+ }
+
+ return count;
+}
+
+/* keep cache consistent */
+static int contactSettingChanged(WPARAM wParam, LPARAM lParam)
+{
+ int i;
+ DBCONTACTWRITESETTING *dbw;
+ char *szProto, *uid;
+
+ uid = NULL;
+ EnterCriticalSection(&csContactCache);
+ for (i=0;i<cacheSize;i++) {
+ if ((HANDLE)wParam != cce[i].hContact && (cce[i].flags & CI_CNFINFO) == 0 )
+ continue;
+
+ dbw = (DBCONTACTWRITESETTING*)lParam;
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam,0);
+ if (szProto == NULL)
+ continue;
+
+ uid = (char*)CallProtoService(szProto,PS_GETCAPS,PFLAG_UNIQUEIDSETTING,0);
+ if (((!strcmp(dbw->szSetting, "Nick")) && (cce[i].flags&CI_NICK)) ||
+ ((!strcmp(dbw->szSetting, "FirstName")) && (cce[i].flags&CI_FIRSTNAME)) ||
+ ((!strcmp(dbw->szSetting, "LastName")) && (cce[i].flags&CI_LASTNAME)) ||
+ ((!strcmp(dbw->szSetting, "e-mail")) && (cce[i].flags&CI_EMAIL)) ||
+ ((!strcmp(dbw->szSetting, "MyHandle")) && (cce[i].flags&CI_LISTNAME)) ||
+ (cce[i].flags & CI_CNFINFO) != 0 || // lazy; always invalidate CNF info cache entries
+ (( ((INT_PTR)uid != CALLSERVICE_NOTFOUND) && (uid != NULL)) && (!strcmp(dbw->szSetting, uid)) && (cce[i].flags & CI_UNIQUEID)))
+ {
+ /* remove from cache */
+ mir_free(cce[i].tszContact);
+ if (cacheSize > 1) {
+ MoveMemory(&cce[i], &cce[cacheSize-1], sizeof(CONTACTCE));
+ cce = ( CONTACTCE* )mir_realloc(cce, (cacheSize-1)*sizeof(CONTACTCE));
+ cacheSize -= 1;
+ }
+ else {
+ mir_free(cce);
+ cce = NULL;
+ cacheSize = 0;
+ }
+ break;
+ }
+ }
+ LeaveCriticalSection(&csContactCache);
+ return 0;
+}
+
+static INT_PTR getContactFromStringSvc( WPARAM wParam, LPARAM lParam)
+{
+ return getContactFromString(( CONTACTSINFO* )wParam );
+}
+
+int initContactModule()
+{
+ InitializeCriticalSection(&csContactCache);
+ hContactSettingChangedHook = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, contactSettingChanged);
+ hGetContactFromStringService = CreateServiceFunction(MS_VARS_GETCONTACTFROMSTRING, getContactFromStringSvc);
+ return 0;
+}
+
+int deinitContactModule()
+{
+ DestroyServiceFunction(hGetContactFromStringService);
+ UnhookEvent(hContactSettingChangedHook);
+ DeleteCriticalSection(&csContactCache);
+ return 0;
+}
+
+// returns a string in the form <PROTOID:UNIQUEID>, cannot be _HANDLE_!
+// result must be freed
+TCHAR *encodeContactToString(HANDLE hContact)
+{
+ char *szProto;
+ TCHAR *tszUniqueId, *tszResult, *tszProto;
+ DBVARIANT dbv;
+
+ ZeroMemory(&dbv, sizeof(DBVARIANT));
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ tszUniqueId = getContactInfoT(CNF_UNIQUEID, hContact);
+ if (szProto == NULL || tszUniqueId == NULL)
+ return NULL;
+
+ tszResult = (TCHAR*)mir_calloc((_tcslen(tszUniqueId) + strlen(szProto) + 4) * sizeof(TCHAR));
+ if (tszResult == NULL)
+ return NULL;
+
+ tszProto = mir_a2t(szProto);
+
+ if (tszProto == NULL)
+ return NULL;
+
+ wsprintf(tszResult, _T("<%s:%s>"), tszProto, tszUniqueId);
+
+ mir_free(tszProto);
+
+ return tszResult;
+}
+
+// returns a contact from a string in the form <PROTOID:UNIQUEID>
+// returns INVALID_HANDLE_VALUE in case of an error.
+HANDLE *decodeContactFromString(TCHAR *tszContact)
+{
+ int count;
+ HANDLE hContact;
+ CONTACTSINFO ci;
+
+ hContact = INVALID_HANDLE_VALUE;
+ ZeroMemory(&ci, sizeof(CONTACTSINFO));
+ ci.cbSize = sizeof(CONTACTSINFO);
+ ci.tszContact = tszContact;
+ ci.flags = CI_PROTOID|CI_TCHAR;
+ count = getContactFromString( &ci );
+ if (count != 1) {
+ if (ci.hContacts != NULL)
+ mir_free(ci.hContacts);
+
+ return ( HANDLE* )hContact;
+ }
+ if (ci.hContacts != NULL) {
+ hContact = ci.hContacts[0];
+ mir_free(ci.hContacts);
+ }
+
+ return ( HANDLE* )hContact;
+}
diff --git a/plugins/Variables/src/contact.h b/plugins/Variables/src/contact.h
new file mode 100644
index 0000000000..7d980801f3
--- /dev/null
+++ b/plugins/Variables/src/contact.h
@@ -0,0 +1,78 @@
+/*
+ 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
+*/
+
+#define STR_FIRSTNAME "first"
+#define STR_LASTNAME "last"
+#define STR_NICK "nick"
+#define STR_CUSTOMNICK "cnick"
+#define STR_EMAIL "email"
+#define STR_CITY "city"
+#define STR_STATE "state"
+#define STR_COUNTRY "country"
+#define STR_PHONE "phone"
+#define STR_HOMEPAGE "homepage"
+#define STR_ABOUT "about"
+#define STR_GENDER "gender"
+#define STR_AGE "age"
+#define STR_FIRSTLAST "firstlast"
+#define STR_UNIQUEID "id"
+#define STR_DISPLAY "display"
+
+#define STR_FAX "fax"
+#define STR_CELLULAR "cellular"
+#define STR_TIMEZONE "timezone"
+#define STR_MYNOTES "mynotes"
+#define STR_BIRTHDAY "bday"
+#define STR_BIRTHMONTH "bmonth"
+#define STR_BIRTHYEAR "byear"
+#define STR_STREET "street"
+#define STR_ZIP "zip"
+#define STR_LANGUAGE1 "lang1"
+#define STR_LANGUAGE2 "lang2"
+#define STR_LANGUAGE3 "lang3"
+#define STR_CONAME "coname"
+#define STR_CODEPT "codept"
+#define STR_COPOSITION "copos"
+#define STR_COSTREET "costreet"
+#define STR_COCITY "cocity"
+#define STR_COSTATE "costate"
+#define STR_COZIP "cozip"
+#define STR_COCOUNTRY "cocountry"
+#define STR_COHOMEPAGE "cohomepage"
+
+#define STR_ACCOUNT "account"
+#define STR_PROTOCOL "protocol"
+#define STR_STATUS "status"
+#define STR_INTERNALIP "intip"
+#define STR_EXTERNALIP "extip"
+#define STR_GROUP "group"
+#define STR_PROTOID "protoid"
+
+#define CCNF_ACCOUNT 51 // CUSTOM, returns contact's account name (0.8.0+)
+#define CCNF_PROTOCOL 50 // CUSTOM, returns the contact's protocol (human-readable)
+#define CCNF_STATUS 49 // CUSTOM, returns status mode description
+#define CCNF_INTERNALIP 48 // CUSTOM, returns the contact's internal IP
+#define CCNF_EXTERNALIP 47 // CUSTOM, returns the contact's external IP
+#define CCNF_GROUP 46 // CUSTOM, returns group name
+#define CCNF_PROTOID 45 // CUSTOM, returns protocol ID instead of name
+
+#define PROTOID_HANDLE "_HANDLE_"
+
+TCHAR *encodeContactToString(HANDLE hContact);
+HANDLE *decodeContactFromString(TCHAR *tszContact);
diff --git a/plugins/Variables/src/dbhelpers.h b/plugins/Variables/src/dbhelpers.h
new file mode 100644
index 0000000000..3eb3c7e330
--- /dev/null
+++ b/plugins/Variables/src/dbhelpers.h
@@ -0,0 +1,119 @@
+/*
+ Variables Plugin for Miranda-IM (www.miranda-im.org)
+ Copyright 2003-2006 P. Boon
+
+ 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 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
+*/
+#ifndef PREFIX_ITH
+#define PREFIX_ITH ""
+#endif
+
+// database helpers
+static int __inline DBWriteIthSettingByte(DWORD i, HANDLE hContact,const char *szModule,const char *szSetting,BYTE val) {
+
+ char dbSetting[128];
+
+ _snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ITH, i, szSetting);
+ return DBWriteContactSettingByte(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteIthSettingWord(DWORD i, HANDLE hContact,const char *szModule,const char *szSetting,WORD val) {
+
+ char dbSetting[128];
+
+ _snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ITH, i, szSetting);
+ return DBWriteContactSettingWord(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteIthSettingDword(DWORD i, HANDLE hContact,const char *szModule,const char *szSetting,DWORD val) {
+
+ char dbSetting[128];
+
+ _snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ITH, i, szSetting);
+ return DBWriteContactSettingDword(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteIthSettingString(DWORD i, HANDLE hContact,const char *szModule,const char *szSetting,const char *val) {
+
+ char dbSetting[128];
+
+ _snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ITH, i, szSetting);
+ return DBWriteContactSettingString(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBGetIthSettingByte(DWORD i, HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) {
+
+
+ char dbSetting[128];
+
+ _snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ITH, i, szSetting);
+ return DBGetContactSettingByte(hContact, szModule, dbSetting, errorValue);
+}
+
+static WORD __inline DBGetIthSettingWord(DWORD i, HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) {
+
+
+ char dbSetting[128];
+
+ _snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ITH, i, szSetting);
+ return DBGetContactSettingWord(hContact, szModule, dbSetting, errorValue);
+}
+
+static DWORD __inline DBGetIthSettingDword(DWORD i, HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) {
+
+
+ char dbSetting[128];
+
+ _snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ITH, i, szSetting);
+ return DBGetContactSettingDword(hContact, szModule, dbSetting, errorValue);
+}
+
+static int __inline DBGetIthSetting(DWORD i, HANDLE hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv) {
+
+
+ char dbSetting[128];
+
+ _snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ITH, i, szSetting);
+ return DBGetContactSetting(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBDeleteIthSetting(DWORD i, HANDLE hContact,const char *szModule,const char *szSetting) {
+
+ char dbSetting[128];
+
+ _snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ITH, i, szSetting);
+ return DBDeleteContactSetting(hContact, szModule, dbSetting);
+}
+
+#define db_getb(a,b) DBGetContactSettingByte(NULL, MODULENAME, a, b)
+#define db_getw(a,b) DBGetContactSettingWord(NULL, MODULENAME, a, b)
+#define db_getd(a,b) DBGetContactSettingDword(NULL, MODULENAME, a, b)
+#define db_gets(a,b) DBGetContactSetting(NULL, MODULENAME, a, b)
+#define db_setb(a,b) DBWriteContactSettingByte(NULL, MODULENAME, a, (BYTE)(b))
+#define db_sets(a,b) DBWriteContactSettingString(NULL, MODULENAME, a, b)
+#define db_setts(a,b) DBWriteContactSettingTString(NULL, MODULENAME, a, b)
+#define db_setw(a,b) DBWriteContactSettingWord(NULL, MODULENAME, a, (WORD)(b))
+#define db_setd(a,b) DBWriteContactSettingDword(NULL, MODULENAME, a, (DWORD)(b))
+#define db_del(a) DBDeleteContactSetting(NULL, MODULENAME, a);
+
+#define dbi_getb(a,b,c) DBGetIthSettingByte(a, NULL, MODULENAME, b, c)
+#define dbi_getw(a,b,c) DBGetIthSettingWord(a, NULL, MODULENAME, b, c)
+#define dbi_getd(a,b,c) DBGetIthSettingDword(a, NULL, MODULENAME, b, c)
+#define dbi_gets(a,b,c) DBGetIthSetting(a, NULL, MODULENAME, b, c)
+#define dbi_setb(a,b,c) DBWriteIthSettingByte(a, NULL, MODULENAME, b, (BYTE)(c))
+#define dbi_sets(a,b,c) DBWriteIthSettingString(a, NULL, MODULENAME, b, c)
+#define dbi_setw(a,b,c) DBWriteIthSettingWord(a, NULL, MODULENAME, b, (WORD)(c))
+#define dbi_setd(a,b,c) DBWriteIthSettingDword(a, NULL, MODULENAME, b, (DWORD)(c))
+#define dbi_del(a,b) DBDeleteIthSetting(a, NULL, MODULENAME, b);
diff --git a/plugins/Variables/src/enumprocs.cpp b/plugins/Variables/src/enumprocs.cpp
new file mode 100644
index 0000000000..56df0acfc8
--- /dev/null
+++ b/plugins/Variables/src/enumprocs.cpp
@@ -0,0 +1,348 @@
+/*
+ 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
+*/
+// This file has been copied from msdn.microsoft.com
+//
+// EnumProc.c
+//
+#include <windows.h>
+#include <stdio.h>
+#include <tlhelp32.h>
+#include <vdmdbg.h>
+#include "enumprocs.h"
+
+typedef struct {
+ DWORD dwPID;
+ PROCENUMPROC lpProc;
+ DWORD lParam;
+ BOOL bEnd;
+} EnumInfoStruct;
+
+BOOL WINAPI Enum16(DWORD dwThreadId, WORD hMod16, WORD hTask16,
+ PSZ pszModName, PSZ pszFileName, LPARAM lpUserDefined);
+
+//
+// The EnumProcs function takes a pointer to a callback function
+// that will be called once per process with the process filename
+// and process ID.
+//
+// lpProc -- Address of callback routine.
+//
+// lParam -- A user-defined LPARAM value to be passed to
+// the callback routine.
+//
+// Callback function definition:
+// BOOL CALLBACK Proc(DWORD dw, WORD w, LPCSTR lpstr, LPARAM lParam);
+//
+BOOL WINAPI EnumProcs(PROCENUMPROC lpProc, LPARAM lParam) {
+
+ OSVERSIONINFO osver;
+ HINSTANCE hInstLib = NULL;
+ HINSTANCE hInstLib2 = NULL;
+ HANDLE hSnapShot = NULL;
+ LPDWORD lpdwPIDs = NULL;
+ PROCESSENTRY32 procentry;
+ BOOL bFlag;
+ DWORD dwSize;
+ DWORD dwSize2;
+ DWORD dwIndex;
+ HMODULE hMod;
+ HANDLE hProcess;
+ char szFileName[MAX_PATH];
+ EnumInfoStruct sInfo;
+
+ // ToolHelp Function Pointers.
+ HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD, DWORD);
+ BOOL (WINAPI *lpfProcess32First)(HANDLE, LPPROCESSENTRY32);
+ BOOL (WINAPI *lpfProcess32Next)(HANDLE, LPPROCESSENTRY32);
+
+ // PSAPI Function Pointers.
+ BOOL (WINAPI *lpfEnumProcesses)(DWORD *, DWORD, DWORD *);
+ BOOL (WINAPI *lpfEnumProcessModules)(HANDLE, HMODULE *, DWORD,
+ LPDWORD);
+ DWORD (WINAPI *lpfGetModuleBaseName)(HANDLE, HMODULE, LPTSTR, DWORD);
+
+ // VDMDBG Function Pointers.
+ INT (WINAPI *lpfVDMEnumTaskWOWEx)(DWORD, TASKENUMPROCEX, LPARAM);
+
+ // Retrieve the OS version
+ osver.dwOSVersionInfoSize = sizeof(osver);
+ if (!GetVersionEx(&osver))
+ return FALSE;
+
+ // If Windows NT 4.0
+ if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT
+ && osver.dwMajorVersion == 4) {
+
+ __try {
+
+ // Get the procedure addresses explicitly. We do
+ // this so we don't have to worry about modules
+ // failing to load under OSes other than Windows NT 4.0
+ // because references to PSAPI.DLL can't be resolved.
+ hInstLib = LoadLibraryA("PSAPI.DLL");
+ if (hInstLib == NULL)
+ __leave;
+
+ hInstLib2 = LoadLibraryA("VDMDBG.DLL");
+ if (hInstLib2 == NULL)
+ __leave;
+
+ // Get procedure addresses.
+ lpfEnumProcesses = (BOOL (WINAPI *)(DWORD *, DWORD, DWORD*))
+ GetProcAddress(hInstLib, "EnumProcesses");
+
+ lpfEnumProcessModules = (BOOL (WINAPI *)(HANDLE, HMODULE *,
+ DWORD, LPDWORD)) GetProcAddress(hInstLib,
+ "EnumProcessModules");
+
+ lpfGetModuleBaseName = (DWORD (WINAPI *)(HANDLE, HMODULE,
+ LPTSTR, DWORD)) GetProcAddress(hInstLib,
+ "GetModuleBaseNameA");
+
+ lpfVDMEnumTaskWOWEx = (INT (WINAPI *)(DWORD, TASKENUMPROCEX,
+ LPARAM)) GetProcAddress(hInstLib2, "VDMEnumTaskWOWEx");
+
+ if (lpfEnumProcesses == NULL
+ || lpfEnumProcessModules == NULL
+ || lpfGetModuleBaseName == NULL
+ || lpfVDMEnumTaskWOWEx == NULL)
+ __leave;
+
+ //
+ // Call the PSAPI function EnumProcesses to get all of the
+ // ProcID's currently in the system.
+ //
+ // NOTE: In the documentation, the third parameter of
+ // EnumProcesses is named cbNeeded, which implies that you
+ // can call the function once to find out how much space to
+ // allocate for a buffer and again to fill the buffer.
+ // This is not the case. The cbNeeded parameter returns
+ // the number of PIDs returned, so if your buffer size is
+ // zero cbNeeded returns zero.
+ //
+ // NOTE: The "HeapAlloc" loop here ensures that we
+ // actually allocate a buffer large enough for all the
+ // PIDs in the system.
+ //
+ dwSize2 = 256 * sizeof(DWORD);
+ do {
+
+ if (lpdwPIDs) {
+ HeapFree(GetProcessHeap(), 0, lpdwPIDs);
+ dwSize2 *= 2;
+ }
+
+ lpdwPIDs = (LPDWORD) HeapAlloc(GetProcessHeap(), 0,
+ dwSize2);
+ if (lpdwPIDs == NULL)
+ __leave;
+
+ if (!lpfEnumProcesses(lpdwPIDs, dwSize2, &dwSize))
+ __leave;
+
+ } while (dwSize == dwSize2);
+
+ // How many ProcID's did we get?
+ dwSize /= sizeof(DWORD);
+
+ // Loop through each ProcID.
+ for (dwIndex = 0; dwIndex < dwSize; dwIndex++) {
+
+ szFileName[0] = 0;
+
+ // Open the process (if we can... security does not
+ // permit every process in the system to be opened).
+ hProcess = OpenProcess(
+ PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
+ FALSE, lpdwPIDs[dwIndex]);
+ if (hProcess != NULL) {
+
+ // Here we call EnumProcessModules to get only the
+ // first module in the process. This will be the
+ // EXE module for which we will retrieve the name.
+ if (lpfEnumProcessModules(hProcess, &hMod,
+ sizeof(hMod), &dwSize2)) {
+
+ // Get the module name
+ if (!lpfGetModuleBaseName(hProcess, hMod,
+ (TCHAR*)szFileName, sizeof(szFileName)))
+ szFileName[0] = 0;
+ }
+ CloseHandle(hProcess);
+ }
+ // Regardless of OpenProcess success or failure, we
+ // still call the enum func with the ProcID.
+ if (!lpProc(lpdwPIDs[dwIndex], 0, szFileName, lParam))
+ break;
+
+ // Did we just bump into an NTVDM?
+ if ( _stricmp(szFileName, "NTVDM.EXE") == 0) {
+
+ // Fill in some info for the 16-bit enum proc.
+ sInfo.dwPID = lpdwPIDs[dwIndex];
+ sInfo.lpProc = lpProc;
+ sInfo.lParam = (DWORD) lParam;
+ sInfo.bEnd = FALSE;
+
+ // Enum the 16-bit stuff.
+ lpfVDMEnumTaskWOWEx(lpdwPIDs[dwIndex],
+ (TASKENUMPROCEX) Enum16, (LPARAM) &sInfo);
+
+ // Did our main enum func say quit?
+ if (sInfo.bEnd)
+ break;
+ }
+ }
+
+ } __finally {
+
+ if (hInstLib)
+ FreeLibrary(hInstLib);
+
+ if (hInstLib2)
+ FreeLibrary(hInstLib2);
+
+ if (lpdwPIDs)
+ HeapFree(GetProcessHeap(), 0, lpdwPIDs);
+ }
+
+ // If any OS other than Windows NT 4.0.
+ } else if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS
+ || (osver.dwPlatformId == VER_PLATFORM_WIN32_NT
+ && osver.dwMajorVersion > 4)) {
+
+ __try {
+
+ hInstLib = LoadLibraryA("Kernel32.DLL");
+ if (hInstLib == NULL)
+ __leave;
+
+ // If NT-based OS, load VDMDBG.DLL.
+ if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) {
+ hInstLib2 = LoadLibraryA("VDMDBG.DLL");
+ if (hInstLib2 == NULL)
+ __leave;
+ }
+
+ // Get procedure addresses. We are linking to
+ // these functions explicitly, because a module using
+ // this code would fail to load under Windows NT,
+ // which does not have the Toolhelp32
+ // functions in KERNEL32.DLL.
+ lpfCreateToolhelp32Snapshot =
+ (HANDLE (WINAPI *)(DWORD,DWORD))
+ GetProcAddress(hInstLib, "CreateToolhelp32Snapshot");
+
+ lpfProcess32First =
+ (BOOL (WINAPI *)(HANDLE,LPPROCESSENTRY32))
+ GetProcAddress(hInstLib, "Process32First");
+
+ lpfProcess32Next =
+ (BOOL (WINAPI *)(HANDLE,LPPROCESSENTRY32))
+ GetProcAddress(hInstLib, "Process32Next");
+
+ if (lpfProcess32Next == NULL
+ || lpfProcess32First == NULL
+ || lpfCreateToolhelp32Snapshot == NULL)
+ __leave;
+
+ if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) {
+ lpfVDMEnumTaskWOWEx = (INT (WINAPI *)(DWORD, TASKENUMPROCEX,
+ LPARAM)) GetProcAddress(hInstLib2, "VDMEnumTaskWOWEx");
+ if (lpfVDMEnumTaskWOWEx == NULL)
+ __leave;
+ }
+
+ // Get a handle to a Toolhelp snapshot of all processes.
+ hSnapShot = lpfCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ if (hSnapShot == INVALID_HANDLE_VALUE) {
+ FreeLibrary(hInstLib);
+ return FALSE;
+ }
+
+ // Get the first process' information.
+ procentry.dwSize = sizeof(PROCESSENTRY32);
+ bFlag = lpfProcess32First(hSnapShot, &procentry);
+
+ // While there are processes, keep looping.
+ while (bFlag) {
+
+ // Call the enum func with the filename and ProcID.
+ if (lpProc(procentry.th32ProcessID, 0,
+ (char *)procentry.szExeFile, lParam)) {
+
+ // Did we just bump into an NTVDM?
+ if ( _stricmp((char *)procentry.szExeFile, "NTVDM.EXE") == 0) {
+
+ // Fill in some info for the 16-bit enum proc.
+ sInfo.dwPID = procentry.th32ProcessID;
+ sInfo.lpProc = lpProc;
+ sInfo.lParam = (DWORD) lParam;
+ sInfo.bEnd = FALSE;
+
+ // Enum the 16-bit stuff.
+ lpfVDMEnumTaskWOWEx(procentry.th32ProcessID,
+ (TASKENUMPROCEX) Enum16, (LPARAM) &sInfo);
+
+ // Did our main enum func say quit?
+ if (sInfo.bEnd)
+ break;
+ }
+
+ procentry.dwSize = sizeof(PROCESSENTRY32);
+ bFlag = lpfProcess32Next(hSnapShot, &procentry);
+
+ } else
+ bFlag = FALSE;
+ }
+
+ } __finally {
+
+ if (hInstLib)
+ FreeLibrary(hInstLib);
+
+ if (hInstLib2)
+ FreeLibrary(hInstLib2);
+ }
+
+ } else
+ return FALSE;
+
+ // Free the library.
+ FreeLibrary(hInstLib);
+
+ return TRUE;
+}
+
+
+BOOL WINAPI Enum16(DWORD dwThreadId, WORD hMod16, WORD hTask16,
+ PSZ pszModName, PSZ pszFileName, LPARAM lpUserDefined) {
+
+ BOOL bRet;
+
+ EnumInfoStruct *psInfo = (EnumInfoStruct *)lpUserDefined;
+
+ bRet = psInfo->lpProc(psInfo->dwPID, hTask16, pszFileName,
+ psInfo->lParam);
+
+ if (!bRet)
+ psInfo->bEnd = TRUE;
+
+ return !bRet;
+}
diff --git a/plugins/Variables/src/enumprocs.h b/plugins/Variables/src/enumprocs.h
new file mode 100644
index 0000000000..118c40b67c
--- /dev/null
+++ b/plugins/Variables/src/enumprocs.h
@@ -0,0 +1,21 @@
+/*
+ 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
+*/
+/*** Process names are ANSI only ***/
+typedef BOOL (CALLBACK *PROCENUMPROC)(DWORD, WORD, char *, LPARAM);
+BOOL WINAPI EnumProcs(PROCENUMPROC lpProc, LPARAM lParam);
diff --git a/plugins/Variables/src/help.cpp b/plugins/Variables/src/help.cpp
new file mode 100644
index 0000000000..8b852b7f6c
--- /dev/null
+++ b/plugins/Variables/src/help.cpp
@@ -0,0 +1,1339 @@
+/*
+ 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 "contact.h"
+#include <commctrl.h>
+#include <m_clui.h>
+#include <m_clc.h>
+
+extern BOOL (WINAPI *pfnEnableThemeDialogTexture)(HANDLE, DWORD);
+
+struct HELPDLGDATA
+{
+ VARHELPINFO *vhs;
+ HWND hwndSubjectDlg;
+ HWND hwndExtraTextDlg;
+ HWND hwndInputDlg;
+};
+
+static INT_PTR CALLBACK inputDlgProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam);
+
+extern HINSTANCE hInst;
+
+extern HCURSOR hCurSplitNS;
+static WNDPROC OldSplitterProc;
+
+static HWND hwndHelpDialog = NULL;
+
+static HICON hHelpIcon = NULL;
+
+static int defaultHelpDialogResize(HWND hwndDlg, LPARAM lParam, UTILRESIZECONTROL *urc) {
+
+ switch(urc->wId) {
+ case IDC_ABOUT:
+ case IDC_ABOUTFRAME:
+ return RD_ANCHORX_WIDTH|RD_ANCHORY_TOP;
+ }
+
+ return RD_ANCHORX_WIDTH|RD_ANCHORY_HEIGHT;
+}
+
+// dialog box for the %extratext% input
+static INT_PTR CALLBACK extratextDlgProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam) {
+
+ switch(msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ break;
+
+ case VARM_SETEXTRATEXT:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT,
+ SendMessage(GetDlgItem(hwndDlg, IDC_EXTRATEXT), WM_SETTEXT, wParam, lParam));
+ return TRUE;
+
+ case VARM_GETEXTRATEXTLENGTH:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT,
+ SendMessage(GetDlgItem(hwndDlg, IDC_EXTRATEXT), WM_GETTEXTLENGTH, wParam, lParam));
+ return TRUE;
+
+ case VARM_GETEXTRATEXT:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT,
+ SendMessage(GetDlgItem(hwndDlg, IDC_EXTRATEXT), WM_GETTEXT, wParam, lParam));
+ return TRUE;
+
+ case WM_SIZE:
+ if (!IsIconic( hwndDlg )) {
+ UTILRESIZEDIALOG urd = { 0 };
+ urd.cbSize = sizeof(urd);
+ urd.hInstance = hInst;
+ urd.hwndDlg = hwndDlg;
+ urd.lpTemplate = MAKEINTRESOURCEA(IDD_EXTRATEXT_DIALOG);
+ urd.pfnResizer = defaultHelpDialogResize;
+ CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd);
+
+ SendMessage(hwndDlg, WM_MOVE, 0, 0);
+ }
+ break;
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_EXTRATEXT:
+ SendMessage(GetParent(hwndDlg), VARM_PARSE, 0, 0);
+ break;
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+// dialog box for the %subject% selection
+void ResetCList(HWND hwndDlg) {
+
+ int i;
+
+ if ((CallService(MS_CLUI_GETCAPS, 0, 0) & CLUIF_DISABLEGROUPS && !DBGetContactSettingByte(NULL, "CList", "UseGroups", SETTING_USEGROUPS_DEFAULT)) || !(GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_CLIST), GWL_STYLE)&CLS_USEGROUPS))
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETUSEGROUPS, (WPARAM) FALSE, 0);
+ else
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETUSEGROUPS, (WPARAM) TRUE, 0);
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETHIDEEMPTYGROUPS, 1, 0);
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETGREYOUTFLAGS, 0, 0);
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETLEFTMARGIN, 2, 0);
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETBKBITMAP, 0, (LPARAM) (HBITMAP) NULL);
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETBKCOLOR, GetSysColor(COLOR_WINDOW), 0);
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETINDENT, 10, 0);
+ for (i = 0; i <= FONTID_MAX; i++)
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETTEXTCOLOR, i, GetSysColor(COLOR_WINDOWTEXT));
+}
+
+static int clistDialogResize(HWND hwndDlg, LPARAM lParam, UTILRESIZECONTROL *urc) {
+
+ switch(urc->wId) {
+ case IDC_ABOUT:
+ case IDC_ABOUTFRAME:
+ return RD_ANCHORX_WIDTH|RD_ANCHORY_TOP;
+ case IDC_NULL:
+ case IDC_CONTACT:
+ return RD_ANCHORX_LEFT|RD_ANCHORY_TOP;
+ }
+
+ return RD_ANCHORX_WIDTH|RD_ANCHORY_HEIGHT;
+}
+
+static INT_PTR CALLBACK clistDlgProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_CLIST), GWL_STYLE, (GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_CLIST), GWL_STYLE) | (CLS_SHOWHIDDEN) | (CLS_NOHIDEOFFLINE)) & ~CLS_CHECKBOXES & ~CLS_USEGROUPS );
+ ResetCList(hwndDlg);
+ CheckRadioButton(hwndDlg, IDC_NULL, IDC_CONTACT, IDC_NULL);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CLIST), IsDlgButtonChecked(hwndDlg, IDC_CONTACT));
+ break;
+
+ case VARM_SETSUBJECT: {
+ LPARAM res = 0;
+ HANDLE hContact, hItem;
+
+ hContact = (HANDLE)wParam;
+ log_debugA("VARM_SETSUBJECT: %u", hContact);
+ if (hContact == INVALID_HANDLE_VALUE) {
+ TCHAR *tszContact = db_get_tsa(NULL, MODULENAME, SETTING_SUBJECT);
+ log_debugA("VARM_SETSUBJECT: %s", tszContact);
+ if (tszContact != NULL) {
+ hContact = decodeContactFromString(tszContact);
+ log_debugA("VARM_SETSUBJECT decoded: %u", hContact);
+ mir_free(tszContact);
+ } }
+
+ if ((hContact != INVALID_HANDLE_VALUE) && (hContact != NULL))
+ hItem = (HANDLE)SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_FINDCONTACT, (WPARAM)hContact, 0);
+ else
+ hItem = NULL;
+
+ if (hItem != NULL)
+ res = (LPARAM)SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SELECTITEM, (WPARAM)hItem, 0);
+
+ CheckRadioButton(hwndDlg, IDC_NULL, IDC_CONTACT, hItem==NULL?IDC_NULL:IDC_CONTACT);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CLIST), IsDlgButtonChecked(hwndDlg, IDC_CONTACT));
+ SetFocus(GetDlgItem(hwndDlg, IDC_CLIST));
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LPARAM)res);
+ return TRUE;
+ }
+
+ case VARM_GETSUBJECT:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT,
+ (IsDlgButtonChecked(hwndDlg, IDC_CONTACT) ? SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_GETSELECTION, 0, 0) : 0));
+ return TRUE;
+
+ case WM_SIZE:
+ if (!IsIconic( hwndDlg )) {
+ UTILRESIZEDIALOG urd = { 0 };
+ urd.cbSize = sizeof(urd);
+ urd.hInstance = hInst;
+ urd.hwndDlg = hwndDlg;
+ urd.lParam = 0;
+ /* ! uses ANSI version ! */
+ urd.lpTemplate = MAKEINTRESOURCEA(IDD_CLIST_DIALOG);
+ urd.pfnResizer = clistDialogResize;
+ CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd);
+
+ SendMessage(hwndDlg, WM_MOVE, 0, 0);
+ }
+ break;
+
+ case WM_SHOWWINDOW:
+ if ((wParam) && (IsDlgButtonChecked(hwndDlg, IDC_CONTACT)))
+ SetFocus(GetDlgItem(hwndDlg, IDC_CLIST));
+ break;
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_NULL:
+ case IDC_CONTACT:
+ CheckRadioButton(hwndDlg, IDC_NULL, IDC_CONTACT, LOWORD(wParam));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CLIST), IsDlgButtonChecked(hwndDlg, IDC_CONTACT));
+ if (IsDlgButtonChecked(hwndDlg, IDC_CONTACT))
+ SetFocus(GetDlgItem(hwndDlg, IDC_CLIST));
+ break;
+ }
+ break;
+
+ case WM_NOTIFY:
+ switch (((NMHDR *) lParam)->idFrom) {
+ case IDC_CLIST:
+ switch (((NMHDR *) lParam)->code) {
+ case CLN_OPTIONSCHANGED:
+ ResetCList(hwndDlg);
+ break;
+ }
+ break;
+ }
+ break;
+
+ case WM_CLOSE:
+ DestroyWindow(hwndDlg);
+ break;
+
+ case WM_DESTROY:
+ db_unset(NULL, MODULENAME, SETTING_SUBJECT);
+ {
+ HANDLE hContact = (HANDLE)SendMessage(hwndDlg, VARM_GETSUBJECT, 0, 0);
+ if (hContact != NULL) {
+ TCHAR *tszContact = encodeContactToString(hContact);
+ if (tszContact != NULL) {
+ db_set_ts(NULL, MODULENAME, SETTING_SUBJECT, tszContact);
+ mir_free(tszContact);
+ } } }
+ break;
+ }
+
+ return FALSE;
+}
+
+// dialog box for the tokens
+static TCHAR *getTokenCategory(TOKENREGISTEREX *tr) {
+
+ TCHAR *res;
+
+ char *cat, *cur, *helpText;
+
+ if (tr == NULL) {
+ return NULL;
+ }
+ cat = NULL;
+ helpText = mir_strdup(tr->szHelpText);
+ if (helpText == NULL) {
+ return NULL;
+ }
+ cur = helpText;
+ while (*cur != _T('\0')) {
+ if (*cur == _T('\t')) {
+ *cur = _T('\0');
+ helpText = ( char* )mir_realloc(helpText, strlen(helpText)+1);
+
+ res = mir_a2t(helpText);
+ mir_free(helpText);
+ return res;
+
+ }
+ cur++;
+ }
+
+ res = mir_a2t(helpText);
+ mir_free(helpText);
+ return res;
+
+}
+
+static TCHAR *getHelpDescription(TOKENREGISTEREX *tr)
+{
+ if (tr == NULL)
+ return NULL;
+
+ char *cur = tr->szHelpText + strlen(tr->szHelpText);
+ while (cur > tr->szHelpText) {
+ if (*cur == _T('\t')) {
+
+ cur = mir_strdup(cur+1);
+ TCHAR *res = mir_a2t(cur);
+ mir_free(cur);
+ return res;
+
+ }
+ cur--;
+ }
+
+ return mir_a2t(tr->szHelpText);
+
+}
+
+static TCHAR *getTokenDescription(TOKENREGISTEREX *tr)
+{
+ int len;
+ char *args, *helpText, *cur, *first, *second;
+ TCHAR *desc, *tArgs;
+
+ if (tr == NULL)
+ return NULL;
+
+ args = NULL;
+ tArgs = NULL;
+ if (tr->szHelpText == NULL)
+ return mir_tstrdup(tr->tszTokenString);
+
+ helpText = mir_strdup(tr->szHelpText);
+ if (helpText == NULL)
+ return NULL;
+
+ cur = helpText;
+ first = second = NULL;
+ while (*cur != _T('\0')) {
+ if (*cur == _T('\t')) {
+ if (first == NULL)
+ first = cur;
+ else if (second == NULL)
+ second = cur;
+ }
+ cur++;
+ }
+
+ if ((first != NULL) && (second != NULL)) {
+ *second = _T('\0');
+ args = first+1;
+ }
+ else args = NULL;
+
+ len = _tcslen(tr->tszTokenString) + (args!=NULL?strlen(args):0) + 3;
+ desc = (TCHAR*)mir_calloc(len * sizeof(TCHAR));
+ if (desc == NULL)
+ return NULL;
+
+ if (tr->flags&TRF_FIELD)
+ mir_sntprintf(desc, len, _T("%c%s%c"), _T(FIELD_CHAR), tr->szTokenString, _T(FIELD_CHAR));
+ else {
+ if (args != NULL)
+
+ tArgs = mir_a2t(args);
+
+ mir_sntprintf(desc, len, _T("%c%s%s"), _T(FUNC_CHAR), tr->tszTokenString, (tArgs!=NULL?tArgs:_T("")));
+ }
+ if (tArgs != NULL)
+ mir_free(tArgs);
+
+ if (helpText != NULL)
+ mir_free(helpText);
+
+ return desc;
+}
+
+static int CALLBACK compareTokenHelp(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) {
+
+ TOKENREGISTEREX *tr1, *tr2;
+ TCHAR *cat1, *cat2;
+ int res;
+
+ res = 0;
+ tr1 = (TOKENREGISTEREX *)lParam1;
+ tr2 = (TOKENREGISTEREX *)lParam2;
+ if (tr1 == NULL || tr2 == NULL)
+ return 0;
+
+ cat1 = getTokenCategory(tr1);
+ cat2 = getTokenCategory(tr2);
+ if (cat1 != NULL && cat2 != NULL) {
+ res = _tcscmp(cat1, cat2);
+ mir_free(cat1);
+ mir_free(cat2);
+ cat1 = cat2 = NULL;
+ if (res != 0)
+ return res;
+
+ if (tr1->tszTokenString == NULL || tr2->tszTokenString == NULL)
+ return 0;
+
+ return _tcscmp(tr1->tszTokenString, tr2->tszTokenString);
+ }
+
+ if (cat1 != NULL)
+ mir_free(cat1);
+
+ if (cat2 != NULL)
+ mir_free(cat2);
+
+ return 0;
+}
+
+static BOOL CALLBACK processTokenListMessage(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam) {
+
+ /* hwndDlg must be a child of the help dialog */
+ switch(msg) {
+ case WM_INITDIALOG: {
+ HELPDLGDATA *hdd;
+ TOKENREGISTEREX *tr;
+ HWND hList;
+ LVCOLUMN lvCol;
+ LVITEM lvItem;
+ TCHAR *tszTokenDesc, *tszHelpDesc, *last, *cat, *text;
+ int i;
+
+ // token list things
+ hList = GetDlgItem(hwndDlg, IDC_TOKENLIST);
+ memset(&lvCol,0,sizeof(lvCol));
+ lvCol.mask = LVCF_TEXT;
+ lvCol.pszText=TranslateT("Token");
+ ListView_InsertColumn(hList, 0, &lvCol);
+ lvCol.pszText=TranslateT("Description");
+ ListView_InsertColumn(hList, 1, &lvCol);
+
+ hdd = (HELPDLGDATA *)GetWindowLongPtr(GetParent(hwndDlg), GWLP_USERDATA);
+ i = -1;
+ do {
+ i += 1;
+ tszHelpDesc = tszTokenDesc = NULL;
+ tr = getTokenRegister(i);
+ if ((tr == NULL) || (tr->tszTokenString == NULL)) {
+ continue;
+ }
+ else if (hdd != NULL) {
+ if (!_tcscmp(tr->tszTokenString, _T(SUBJECT))) {
+ if (hdd->vhs->flags&VHF_HIDESUBJECTTOKEN) {
+ continue;
+ }
+ else if (hdd->vhs->szSubjectDesc != NULL) {
+
+ tszHelpDesc = mir_a2t(hdd->vhs->szSubjectDesc);
+
+ }
+ }
+ if (!_tcscmp(tr->tszTokenString, _T(EXTRATEXT))) {
+ if (hdd->vhs->flags&VHF_HIDEEXTRATEXTTOKEN) {
+ continue;
+ }
+ else if (hdd->vhs->szExtraTextDesc != NULL) {
+
+ tszHelpDesc = mir_a2t(hdd->vhs->szExtraTextDesc);
+
+ }
+ }
+ }
+ memset(&lvItem,0,sizeof(lvItem));
+ lvItem.mask = LVIF_TEXT|LVIF_PARAM;
+ lvItem.iItem = ListView_GetItemCount(hList);
+ lvItem.iSubItem = 0;
+ lvItem.lParam = (LPARAM)tr;
+ tszTokenDesc = getTokenDescription(tr);
+ if (tszTokenDesc == NULL) {
+ continue;
+ }
+ lvItem.pszText = tszTokenDesc;
+ ListView_InsertItem(hList, &lvItem);
+ mir_free(tszTokenDesc);
+
+ lvItem.mask = LVIF_TEXT;
+ if (tszHelpDesc == NULL) {
+ tszHelpDesc = getHelpDescription(tr);
+ }
+ if (tszHelpDesc == NULL) {
+ tszHelpDesc = mir_tstrdup(_T("unknown"));
+ }
+ lvItem.iSubItem = 1;
+ lvItem.pszText = TranslateTS(tszHelpDesc);
+ ListView_SetItem(hList, &lvItem);
+ mir_free(tszHelpDesc);
+ } while (tr != NULL);
+ ListView_SetColumnWidth(hList, 0, LVSCW_AUTOSIZE);
+ ListView_SetColumnWidth(hList, 1, LVSCW_AUTOSIZE);
+ ListView_SortItems(hList, compareTokenHelp, 0);
+ last = text = NULL;
+ for (i=0;i<ListView_GetItemCount(hList);i++) {
+ lvItem.mask = LVIF_PARAM;
+ lvItem.iSubItem = 0;
+ lvItem.iItem = i;
+ if (ListView_GetItem(hList, &lvItem) == FALSE) {
+ continue;
+ }
+ cat = getTokenCategory((TOKENREGISTEREX *)lvItem.lParam);
+ if (cat != NULL) {
+ text = mir_tstrdup(TranslateTS(cat));
+ mir_free(cat);
+ }
+ else {
+ text = NULL;
+ }
+ if ((text != NULL) && ((last == NULL) || (_tcsicmp(last, text)))) {
+ lvItem.mask = LVIF_TEXT;
+ lvItem.pszText = text;
+ ListView_InsertItem(hList, &lvItem);
+ if (last != NULL) {
+ mir_free(last);
+ lvItem.iSubItem = 0;
+ lvItem.pszText = _T("");
+ ListView_InsertItem(hList, &lvItem);
+ }
+ last = text;
+ }
+ else {
+ mir_free(text);
+ }
+ }
+ if (last != NULL) {
+ mir_free(last);
+ }
+ break;
+ }
+
+ case WM_NOTIFY:
+ if ((((NMHDR*)lParam)->idFrom == IDC_TOKENLIST) && (((NMHDR*)lParam)->code == NM_DBLCLK)) {
+ HWND hList, hwndInputDlg;
+ LVITEM lvItem;
+ int len, item;
+ TCHAR *tokenString;
+ TOKENREGISTER *tr;
+
+ hwndInputDlg = (HWND)SendMessage(GetParent(hwndDlg), VARM_GETDIALOG, (WPARAM)VHF_INPUT, 0);
+ if (hwndInputDlg == NULL) {
+ break;
+ }
+ hList = GetDlgItem(hwndDlg, IDC_TOKENLIST);
+ item = ListView_GetNextItem(hList, -1, LVNI_SELECTED|LVNI_FOCUSED);
+ ZeroMemory(&lvItem, sizeof(lvItem));
+ lvItem.mask = LVIF_PARAM;
+ lvItem.iSubItem = 0;
+ lvItem.iItem = item;
+ if (ListView_GetItem(hList, &lvItem) == FALSE) {
+ break;
+ }
+ tr = (TOKENREGISTER *)lvItem.lParam;
+ if (tr == NULL) {
+ break;
+ }
+ len = _tcslen(tr->tszTokenString) + 2;
+ if (len < 0) {
+ break;
+ }
+ tokenString = (TCHAR*)mir_alloc((len+1)*sizeof(TCHAR));
+ if (tokenString == NULL) {
+ break;
+ }
+ ZeroMemory(tokenString, (len+1)*sizeof(TCHAR));
+ wsprintf(tokenString, _T("%c%s%c"), (tr->flags&TRF_FIELD?_T(FIELD_CHAR):_T(FUNC_CHAR)), tr->tszTokenString, (tr->flags&TRF_FIELD?_T(FIELD_CHAR):_T('(')));
+ SendDlgItemMessage(hwndInputDlg, IDC_TESTSTRING, EM_REPLACESEL, (WPARAM)TRUE, (LPARAM)tokenString);
+ mir_free(tokenString);
+ SetFocus(GetDlgItem(hwndInputDlg, IDC_TESTSTRING));
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+// "token only" dialog proc
+static INT_PTR CALLBACK tokenHelpDlgProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ processTokenListMessage(hwndDlg, msg, wParam, lParam);
+ switch(msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ break;
+
+ case WM_SIZE:
+ if (!IsIconic( hwndDlg )) {
+ UTILRESIZEDIALOG urd = { 0 };
+ urd.cbSize = sizeof(urd);
+ urd.hInstance = hInst;
+ urd.hwndDlg = hwndDlg;
+ urd.lpTemplate = MAKEINTRESOURCEA(IDD_TOKENS_DIALOG);
+ urd.pfnResizer = defaultHelpDialogResize;
+ CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd);
+
+ SendMessage(hwndDlg, WM_MOVE, 0, 0);
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+// token + input dialog proc
+// from SRMM
+static LRESULT CALLBACK SplitterSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_NCHITTEST:
+ return HTCLIENT;
+
+ case WM_SETCURSOR:
+ {
+ RECT rc;
+ GetClientRect(hwnd, &rc);
+ //SetCursor(rc.right > rc.bottom ? hCurSplitNS : hCurSplitWE);
+ if (rc.right > rc.bottom)
+ SetCursor(hCurSplitNS);
+
+ return TRUE;
+ }
+ case WM_LBUTTONDOWN:
+ SetCapture(hwnd);
+ return 0;
+
+ case WM_MOUSEMOVE:
+ if (GetCapture() == hwnd) {
+ RECT rc;
+ GetClientRect(hwnd, &rc);
+ SendMessage(GetParent(hwnd), DM_SPLITTERMOVED, rc.right > rc.bottom ? (short) HIWORD(GetMessagePos()) + rc.bottom / 2 : (short) LOWORD(GetMessagePos()) + rc.right / 2, (LPARAM) hwnd);
+ }
+ return 0;
+
+ case WM_LBUTTONUP:
+ ReleaseCapture();
+ return 0;
+ }
+ return CallWindowProc(OldSplitterProc, hwnd, msg, wParam, lParam);
+}
+
+struct INPUTDLGDATA
+{
+ int splitterPos;
+ int originalSplitterPos;
+ POINT minInputSize;
+ POINT minResultSize;
+ HWND hwndHelpDlg;
+};
+
+static int iFrameX, iFrameY;
+
+static int inputDialogResize(HWND hwndDlg, LPARAM lParam, UTILRESIZECONTROL *urc)
+{
+ INPUTDLGDATA *dat = (INPUTDLGDATA *)lParam;
+
+ switch(urc->wId) {
+ case IDC_TOKENLIST:
+ return RD_ANCHORX_WIDTH|RD_ANCHORY_TOP;
+
+ case IDC_TESTSTRING:
+ urc->rcItem.bottom -= dat->splitterPos - dat->originalSplitterPos;
+ return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT;
+
+ case IDC_SPLITTER:
+ urc->rcItem.top -= dat->splitterPos - dat->originalSplitterPos;
+ urc->rcItem.bottom -= dat->splitterPos - dat->originalSplitterPos;
+ return RD_ANCHORX_WIDTH | RD_ANCHORY_BOTTOM;
+
+ case IDC_RESULT:
+ urc->rcItem.top -= dat->splitterPos - dat->originalSplitterPos;
+ return RD_ANCHORX_WIDTH|RD_ANCHORY_BOTTOM;
+ }
+
+ return RD_ANCHORX_LEFT|RD_ANCHORY_TOP;
+}
+
+static INT_PTR CALLBACK inputDlgProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ static INPUTDLGDATA *dat = (INPUTDLGDATA *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+
+ processTokenListMessage(hwndDlg, msg, wParam, lParam);
+ switch(msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ dat = ( INPUTDLGDATA* )mir_alloc(sizeof(INPUTDLGDATA));
+ ZeroMemory(dat, sizeof(INPUTDLGDATA));
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat);
+ // splitter things
+ dat->splitterPos = (INT_PTR)db_get_dw(NULL, MODULENAME, SETTING_SPLITTERPOS, -1);
+ {
+ RECT rc;
+ POINT pt;
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_SPLITTER), &rc);
+ pt.y = (rc.top + rc.bottom) / 2;
+ pt.x = 0;
+ ScreenToClient(hwndDlg, &pt);
+ dat->originalSplitterPos = pt.y;
+
+ if (dat->splitterPos == -1)
+ dat->splitterPos = dat->originalSplitterPos;
+
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_SHOWHELP), &rc);
+ OldSplitterProc = (WNDPROC) SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_SPLITTER), GWLP_WNDPROC, (LONG_PTR) SplitterSubclassProc);
+
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_TESTSTRING), &rc);
+ dat->minInputSize.x = rc.right - rc.left;
+ dat->minInputSize.y = rc.bottom - rc.top;
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_RESULT), &rc);
+ dat->minResultSize.x = rc.right - rc.left;
+ dat->minResultSize.y = rc.bottom - rc.top;
+ }
+
+ dat->hwndHelpDlg = GetParent(hwndDlg);
+ SendMessage(hwndDlg, VARM_PARSE, 0, 0);
+ SetTimer(hwndDlg, IDT_PARSE, 1000, NULL);
+
+ SetFocus(GetDlgItem(hwndDlg, IDC_TESTSTRING));
+ break;
+
+ case DM_SPLITTERMOVED:
+ {
+ POINT pt;
+ RECT rc, rcTeststring, rcResult;
+ int oldSplitterY;
+
+ if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_SPLITTER)) {
+ GetClientRect(hwndDlg, &rc);
+ pt.x = 0;
+ pt.y = wParam;
+ ScreenToClient(hwndDlg, &pt);
+ oldSplitterY = dat->splitterPos;
+ dat->splitterPos = rc.bottom - pt.y + 223;
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_TESTSTRING), &rcTeststring);
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_RESULT), &rcResult);
+ if ((((rcTeststring.bottom - rcTeststring.top) - (dat->splitterPos - oldSplitterY)) < dat->minInputSize.y) || (((rcResult.bottom - rcResult.top) + (dat->splitterPos - oldSplitterY)) < dat->minResultSize.y))
+ dat->splitterPos = oldSplitterY;
+ } }
+
+ SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ break;
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_TESTSTRING:
+ if (HIWORD(wParam) == EN_CHANGE)
+ SendMessage(hwndDlg, VARM_PARSE, 0, 0);
+ break;
+ }
+ break;
+
+ case WM_GETMINMAXINFO:
+ {
+ RECT rc, rcTeststring;
+ GetWindowRect(GetParent(hwndDlg), &rc);
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_TESTSTRING), &rcTeststring);
+ ((MINMAXINFO*)lParam)->ptMinTrackSize.y = (rc.bottom - rc.top) - (((rcTeststring.bottom - rcTeststring.top) - dat->minResultSize.y));
+ }
+ break;
+
+ case WM_SIZE:
+ if (!IsIconic( hwndDlg )) {
+ UTILRESIZEDIALOG urd = { 0 };
+ urd.cbSize = sizeof(urd);
+ urd.hInstance = hInst;
+ urd.hwndDlg = hwndDlg;
+ urd.lParam = (LPARAM)dat;
+ urd.lpTemplate = MAKEINTRESOURCEA(IDD_INPUT_DIALOG);
+ urd.pfnResizer = inputDialogResize;
+ CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd);
+ }
+ SendMessage(hwndDlg, WM_MOVE, 0, 0);
+ break;
+
+ case WM_SHOWWINDOW:
+ if (wParam)
+ SendMessage(hwndDlg, VARM_PARSE, 0, 0);
+ break;
+
+ case WM_NOTIFY:
+ break;
+
+ case VARM_PARSE:
+ {
+ TCHAR *string = Hlp_GetDlgItemText(hwndDlg, IDC_TESTSTRING), *extraText;
+ int len = SendMessage(GetParent(hwndDlg), VARM_GETEXTRATEXTLENGTH, 0, 0);
+ if (len > 0) {
+ extraText = (TCHAR*)mir_calloc((len+1)* sizeof(TCHAR));
+ SendMessage(GetParent(hwndDlg), VARM_GETEXTRATEXT, (WPARAM)len+1, (LPARAM)extraText);
+ }
+ else extraText = NULL;
+
+ if (string != NULL) {
+ TCHAR *newString = variables_parsedup(string, extraText, (HANDLE)SendMessage(GetParent(hwndDlg), VARM_GETSUBJECT, 0, 0));
+ if (newString != NULL) {
+ TCHAR *oldString = Hlp_GetDlgItemText(hwndDlg, IDC_RESULT);
+ if (oldString == NULL || _tcscmp(oldString, newString))
+ SetWindowText(GetDlgItem(hwndDlg, IDC_RESULT), newString);
+
+ mir_free(newString);
+ if (oldString != NULL)
+ mir_free(oldString);
+ }
+ mir_free(string);
+ } }
+ break;
+
+ case VARM_SETINPUTTEXT:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT,
+ SendMessage(GetDlgItem(hwndDlg, IDC_TESTSTRING), WM_SETTEXT, wParam, lParam));
+ return TRUE;
+
+ case VARM_GETINPUTTEXTLENGTH:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT,
+ SendMessage(GetDlgItem(hwndDlg, IDC_TESTSTRING), WM_GETTEXTLENGTH, wParam, lParam));
+ return TRUE;
+
+ case VARM_GETINPUTTEXT:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT,
+ SendMessage(GetDlgItem(hwndDlg, IDC_TESTSTRING), WM_GETTEXT, wParam, lParam));
+ return TRUE;
+
+ case WM_TIMER:
+ SendMessage(hwndDlg, VARM_PARSE, 0, 0);
+ break;
+
+ case WM_DESTROY:
+ KillTimer(hwndDlg, IDT_PARSE);
+ db_set_dw(NULL, MODULENAME, SETTING_SPLITTERPOS, dat->splitterPos);
+ SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_SPLITTER), GWLP_WNDPROC, (LONG_PTR) OldSplitterProc);
+ if (dat != NULL) {
+ mir_free(dat);
+ dat = NULL;
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+// help info dialog
+static INT_PTR CALLBACK helpInfoDlgProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg) {
+ case WM_INITDIALOG:
+ SetDlgItemTextA(hwndDlg, IDC_HELPDESC, \
+"--- Special characters ---\r\n\r\n\
+The following characters have a special meaning in a formatting string:\r\n\r\n\
+?<function>(<arguments>)\r\n\
+This will parse the function given the arguments, the result will be parsed again. Example: Today is ?cdate(yyyy/MM/dd).\r\n\r\n\
+!<function>(<arguments>)\r\n\
+This will parse the function given the arguments, the result will not be parsed again. Example: Message waiting: !message(,first,rcvd,unread).\r\n\r\n\
+%<field>%\r\n\
+This will parse the given field. Example: I installed Miranda at: %mirandapath%.\r\n\r\n\
+`<string>`\r\n\
+This will not parse the given string, any function, field or special character in the string will shown in the result without being translated. Example: Use `%mirandapath%` to show the installation path.\r\n\r\n\
+#<comment>\r\n\
+This will add a comment in the formatting string. Everything from the # character to the end of the line will be removed. Example: %dbprofile% #this is a useless comment.\r\n\r\n\r\n\
+--- Contacts ---\r\n\r\n\
+Whenever a functions requires a contact as an argument, you can specify it in two ways:\r\n\r\n\
+(1) Using a unique id (UIN for ICQ, email for MSN) or, a protocol id followed by a unique id in the form <PROTOID:UNIQUEID>, for example <MSN:miranda@hotmail.com> or <ICQ:123456789>.\r\n\r\n\
+(2) Using the contact function:\r\n\
+?contact(x,y)\r\n\
+A contact will be searched which will have value x for its property y, y can be one of the following:\r\n\
+first, last, nick, email, id or display\r\n\r\n\
+For example: ?contact(miranda@hotmail.com,email) or ?contact(Miranda,nick). The contact function will return either a unique contact according to the arguments or nothing if none or multiple contacts exists with the given property.\
+");
+ TranslateDialogDefault(hwndDlg);
+ break;
+
+ case WM_SIZE:
+ if (!IsIconic( hwndDlg )) {
+ UTILRESIZEDIALOG urd = { 0 };
+ urd.cbSize = sizeof(urd);
+ urd.hInstance = hInst;
+ urd.hwndDlg = hwndDlg;
+ urd.lParam = 0;
+ urd.lpTemplate = MAKEINTRESOURCEA(IDD_HELPINFO_DIALOG);
+ urd.pfnResizer = defaultHelpDialogResize;
+ CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd);
+
+ SendMessage(hwndDlg, WM_MOVE, 0, 0);
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+// the parent page (tabs)
+static int helpDialogResize(HWND hwndDlg, LPARAM lParam, UTILRESIZECONTROL *urc)
+{
+ INPUTDLGDATA *dat = (INPUTDLGDATA *)lParam;
+ switch(urc->wId) {
+ case IDC_OK:
+ case IDC_CANCEL:
+ return RD_ANCHORX_RIGHT|RD_ANCHORY_BOTTOM;
+ }
+ return RD_ANCHORX_WIDTH|RD_ANCHORY_HEIGHT;
+}
+
+static INT_PTR CALLBACK helpDlgProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ HELPDLGDATA *dat = (HELPDLGDATA *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+
+ switch(msg) {
+ case WM_INITDIALOG: {
+ int tabCount;
+ HWND hTab, hShow, hPage;
+ TCITEM tci;
+ RECT rcTabs, rcParent;
+
+ hwndHelpDialog = hwndDlg;
+ TranslateDialogDefault(hwndDlg);
+ dat = ( HELPDLGDATA* )mir_alloc(sizeof(HELPDLGDATA));
+ ZeroMemory(dat, sizeof(HELPDLGDATA));
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat);
+ dat->vhs = (VARHELPINFO *)lParam;
+ // set tabs
+ tabCount = 0;
+ hTab = GetDlgItem(hwndDlg, IDC_TABS);
+ GetWindowRect(hTab, &rcTabs);
+ GetWindowRect(hwndDlg, &rcParent);
+ ZeroMemory(&tci, sizeof(TCITEM));
+ hShow = 0;
+ if (dat->vhs->flags&VHF_TOKENS) {
+ // token tab
+ tci.mask = TCIF_TEXT|TCIF_PARAM;
+ tci.pszText = TranslateT("Tokens");
+ hPage = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_TOKENS_DIALOG), hwndDlg, tokenHelpDlgProc, (LPARAM)GetParent(hwndDlg));
+ if (pfnEnableThemeDialogTexture)
+ pfnEnableThemeDialogTexture(hPage, ETDT_ENABLETAB);
+
+ tci.lParam = (LPARAM)hPage;
+ MoveWindow(hPage, (rcTabs.left - rcParent.left), (rcTabs.top - rcParent.top), (rcTabs.right - rcTabs.left) - 2*iFrameX, (rcTabs.bottom - rcTabs.top) - 2*iFrameY, TRUE);
+ ShowWindow(hPage, SW_HIDE);
+ TabCtrl_InsertItem(hTab, tabCount++, &tci);
+ hShow = hShow==0?hPage:hShow;
+ }
+ if (dat->vhs->flags&VHF_INPUT) {
+ // input tab
+ tci.mask = TCIF_TEXT|TCIF_PARAM;
+ tci.pszText = TranslateT("Input");
+ dat->hwndInputDlg = hPage = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_INPUT_DIALOG), hwndDlg, inputDlgProc, (LPARAM)GetParent(hwndDlg));
+ if (pfnEnableThemeDialogTexture) {
+ pfnEnableThemeDialogTexture(hPage, ETDT_ENABLETAB);
+ }
+ tci.lParam = (LPARAM)hPage;
+ MoveWindow(hPage, (rcTabs.left - rcParent.left), (rcTabs.top - rcParent.top), (rcTabs.right - rcTabs.left) - 2*iFrameX, (rcTabs.bottom - rcTabs.top) - 2*iFrameY, TRUE);
+ ShowWindow(hPage, SW_HIDE);
+ TabCtrl_InsertItem(hTab, tabCount++, &tci);
+ hShow = hShow==0?hPage:hShow;
+ if ((dat->vhs->fi != NULL) && (dat->vhs->fi->szFormat != NULL)) {
+ if (dat->vhs->fi->flags & FIF_UNICODE)
+ SendMessage(hwndDlg, VARM_SETINPUTTEXT, 0, (LPARAM)dat->vhs->fi->tszFormat);
+ else {
+
+ WCHAR *wszFormatString = mir_a2t(dat->vhs->fi->szFormat);
+ SendMessage(hwndDlg, VARM_SETINPUTTEXT, 0, (LPARAM)wszFormatString);
+ mir_free(wszFormatString);
+
+ }
+ }
+ else if (dat->vhs->hwndCtrl != NULL) {
+ TCHAR *tszText;
+
+ tszText = Hlp_GetWindowText(dat->vhs->hwndCtrl);
+ if (tszText != NULL) {
+ SendMessage(hwndDlg, VARM_SETINPUTTEXT, 0, (LPARAM)tszText);
+ mir_free(tszText);
+ }
+ }
+ if (dat->vhs->fi != NULL || dat->vhs->hwndCtrl != NULL) {
+ SetWindowText(GetDlgItem(hwndDlg, IDC_CANCEL), TranslateT("Cancel"));
+ ShowWindow(GetDlgItem(hwndDlg, IDC_OK), SW_SHOW);
+ }
+ }
+ if ((dat->vhs->flags&VHF_SUBJECT) ||
+ ((dat->vhs->flags&VHF_INPUT) && (((dat->vhs->fi != NULL) && (dat->vhs->fi->hContact != NULL)) || (dat->vhs->flags&VHF_SETLASTSUBJECT)))) {
+ // subject window is created, but not necessarily shown
+ dat->hwndSubjectDlg = hPage = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_CLIST_DIALOG), hwndDlg, clistDlgProc, (LPARAM)GetParent(hwndDlg));
+ if (pfnEnableThemeDialogTexture) {
+ pfnEnableThemeDialogTexture(hPage, ETDT_ENABLETAB);
+ }
+
+ MoveWindow(hPage, (rcTabs.left - rcParent.left), (rcTabs.top - rcParent.top), (rcTabs.right - rcTabs.left) - 2*iFrameX, (rcTabs.bottom - rcTabs.top) - 2*iFrameY, TRUE);
+ ShowWindow(hPage, SW_HIDE);
+
+ if ((dat->vhs->fi != NULL) && (dat->vhs->fi->hContact != NULL))
+ SendMessage(hwndDlg, VARM_SETSUBJECT, (WPARAM)dat->vhs->fi->hContact, 0);
+ else if (dat->vhs->flags&VHF_SETLASTSUBJECT)
+ SendMessage(hwndDlg, VARM_SETSUBJECT, (WPARAM)INVALID_HANDLE_VALUE, 0);
+
+ if (dat->vhs->flags&VHF_SUBJECT) {
+ // create subject tab
+ tci.lParam = (LPARAM)hPage;
+ tci.mask = TCIF_TEXT|TCIF_PARAM;
+ tci.pszText = TranslateT("%subject%");
+ TabCtrl_InsertItem(hTab, tabCount++, &tci);
+ hShow = hShow==0?hPage:hShow;
+ }
+ }
+ if ((dat->vhs->flags&VHF_EXTRATEXT) ||
+ ((dat->vhs->flags&VHF_INPUT) && (dat->vhs->fi != NULL) && (dat->vhs->fi->tszExtraText != NULL))) {
+ // extratext window is created, but not necessarily shown
+ dat->hwndExtraTextDlg = hPage = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_EXTRATEXT_DIALOG), hwndDlg, extratextDlgProc, (LPARAM)GetParent(hwndDlg));
+ if (pfnEnableThemeDialogTexture)
+ pfnEnableThemeDialogTexture(hPage, ETDT_ENABLETAB);
+
+ MoveWindow(hPage, (rcTabs.left - rcParent.left), (rcTabs.top - rcParent.top), (rcTabs.right - rcTabs.left) - 2*iFrameX, (rcTabs.bottom - rcTabs.top) - 2*iFrameY, TRUE);
+ ShowWindow(hPage, SW_HIDE);
+ if ((dat->vhs->fi != NULL) && (dat->vhs->fi->tszExtraText != NULL)) {
+ if (dat->vhs->fi->flags & FIF_UNICODE)
+ SendMessage(hwndDlg, VARM_SETEXTRATEXT, 0, (LPARAM)dat->vhs->fi->tszExtraText);
+ else {
+
+ WCHAR *wszSource = mir_a2t(dat->vhs->fi->szExtraText);
+ SendMessage(hwndDlg, VARM_SETEXTRATEXT, 0, (LPARAM)wszSource);
+ mir_free(wszSource);
+
+ }
+ }
+ if (dat->vhs->flags&VHF_EXTRATEXT) {
+ // create extratext tab
+ tci.mask = TCIF_TEXT|TCIF_PARAM;
+ tci.pszText = TranslateT("%extratext%");
+ tci.lParam = (LPARAM)hPage;
+ TabCtrl_InsertItem(hTab, tabCount++, &tci);
+ hShow = hShow==0?hPage:hShow;
+ }
+ }
+ if (dat->vhs->flags&VHF_HELP) {
+ // helpinfo tab
+ tci.mask = TCIF_TEXT|TCIF_PARAM;
+ tci.pszText = TranslateT("Help");
+ hPage = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_HELPINFO_DIALOG), hwndDlg, helpInfoDlgProc, (LPARAM)GetParent(hwndDlg));
+ if (pfnEnableThemeDialogTexture)
+ pfnEnableThemeDialogTexture(hPage, ETDT_ENABLETAB);
+
+ tci.lParam = (LPARAM)hPage;
+ MoveWindow(hPage, (rcTabs.left - rcParent.left), (rcTabs.top - rcParent.top), (rcTabs.right - rcTabs.left) - 2*iFrameX, (rcTabs.bottom - rcTabs.top) - 2*iFrameY, TRUE);
+ ShowWindow(hPage, SW_HIDE);
+ TabCtrl_InsertItem(hTab, tabCount++, &tci);
+ hShow = hShow==0?hPage:hShow;
+ }
+ Utils_RestoreWindowPositionNoMove(hwndDlg, NULL, MODULENAME, "help");
+ SetWindowText(hwndDlg, TranslateT("Variables Help"));
+ ShowWindow(hShow, SW_SHOW);
+ break;
+ }
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_OK:
+ if ((dat->vhs->fi != NULL) && (!(dat->vhs->flags&VHF_DONTFILLSTRUCT))) {
+ int len = SendMessage(hwndDlg, VARM_GETINPUTTEXTLENGTH, 0, 0);
+ if (len > 0) {
+ if ((dat->vhs->fi != NULL) && (!(dat->vhs->flags&VHF_DONTFILLSTRUCT))) {
+ if (dat->vhs->fi->flags&FIF_UNICODE) {
+ dat->vhs->fi->tszFormat = (TCHAR*)mir_calloc((len+1)*sizeof(WCHAR));
+ SendMessage(hwndDlg, VARM_GETINPUTTEXT, (WPARAM)len+1, (LPARAM)dat->vhs->fi->tszFormat);
+ }
+ else {
+ dat->vhs->fi->szFormat = ( char* )mir_calloc(len+1);
+ SendMessageA(hwndDlg, VARM_GETINPUTTEXT, (WPARAM)len+1, (LPARAM)dat->vhs->fi->szFormat);
+ }
+ }
+ }
+ }
+
+ if (dat->vhs->hwndCtrl != NULL) {
+ int len = SendMessage(hwndDlg, VARM_GETINPUTTEXTLENGTH, 0, 0);
+ if (len > 0) {
+ TCHAR *tszText;
+
+ tszText = (TCHAR*)mir_calloc((len+1)*sizeof(TCHAR));
+ if (tszText != NULL) {
+ SendMessage(hwndDlg, VARM_GETINPUTTEXT, (WPARAM)len+1, (LPARAM)tszText);
+ SetWindowText(dat->vhs->hwndCtrl, tszText);
+ mir_free(tszText);
+ }
+ }
+ SendMessage(GetParent(dat->vhs->hwndCtrl),
+ WM_COMMAND,
+ MAKEWPARAM(GetDlgCtrlID(dat->vhs->hwndCtrl),
+ EN_CHANGE),
+ (LPARAM)dat->vhs->hwndCtrl);
+ }
+
+ if ((dat->vhs->flags&VHF_FULLFILLSTRUCT) && (dat->vhs->fi != NULL)) {
+ int len = SendMessage(hwndDlg, VARM_GETEXTRATEXTLENGTH, 0, 0);
+ if (len > 0) {
+ if (dat->vhs->fi->flags&FIF_UNICODE) {
+ dat->vhs->fi->tszExtraText = (TCHAR*)mir_calloc((len+1)*sizeof(WCHAR));
+ SendMessage(hwndDlg, VARM_GETEXTRATEXT, (WPARAM)len+1, (LPARAM)dat->vhs->fi->tszExtraText);
+ }
+ else {
+ dat->vhs->fi->szExtraText = ( char* )mir_calloc(len+1);
+ SendMessageA(hwndDlg, VARM_GETEXTRATEXT, (WPARAM)len+1, (LPARAM)dat->vhs->fi->szExtraText);
+ }
+ }
+ dat->vhs->fi->hContact = (HANDLE)SendMessage(hwndDlg, VARM_GETSUBJECT, 0, 0);
+ }
+ // fall through
+
+ case IDC_CANCEL:
+ if (GetParent(hwndDlg) == NULL)
+ DestroyWindow(hwndDlg);
+ else
+ EndDialog(hwndDlg, 0);
+ break;
+ }
+ break;
+
+ case VARM_SETSUBJECT:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT,
+ SendMessage(dat->hwndSubjectDlg, VARM_SETSUBJECT, wParam, lParam));
+ return TRUE;
+
+ case VARM_GETSUBJECT:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT,
+ SendMessage(dat->hwndSubjectDlg, VARM_GETSUBJECT, wParam, lParam));
+ return TRUE;
+
+ case VARM_SETEXTRATEXT:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT,
+ SendMessage(dat->hwndExtraTextDlg, VARM_SETEXTRATEXT, wParam, lParam));
+ return TRUE;
+
+ case VARM_GETEXTRATEXTLENGTH:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT,
+ SendMessage(dat->hwndExtraTextDlg, VARM_GETEXTRATEXTLENGTH, wParam, lParam));
+ return TRUE;
+
+ case VARM_GETEXTRATEXT:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT,
+ SendMessage(dat->hwndExtraTextDlg, VARM_GETEXTRATEXT, wParam, lParam));
+ return TRUE;
+
+ case VARM_SETINPUTTEXT:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT,
+ SendMessage(dat->hwndInputDlg, VARM_SETINPUTTEXT, wParam, lParam));
+ return TRUE;
+
+ case VARM_GETINPUTTEXTLENGTH:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT,
+ SendMessage(dat->hwndInputDlg, VARM_GETINPUTTEXTLENGTH, wParam, lParam));
+ return TRUE;
+
+ case VARM_GETINPUTTEXT:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT,
+ SendMessage(dat->hwndInputDlg, VARM_GETINPUTTEXT, wParam, lParam));
+ return TRUE;
+
+ case VARM_GETDIALOG:
+ switch (wParam) {
+ case VHF_INPUT:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LPARAM)dat->hwndInputDlg);
+ return TRUE;
+ }
+ break;
+
+ case WM_GETMINMAXINFO:
+ {
+ int i, count;
+ TCITEM tci;
+ RECT rcParent;
+ HWND hTab;
+ MINMAXINFO pageMinMax;
+
+ GetWindowRect(hwndDlg, &rcParent);
+ // defaults
+ ((MINMAXINFO*)lParam)->ptMinTrackSize.x = 400;
+ ((MINMAXINFO*)lParam)->ptMinTrackSize.y = 400;
+ hTab = GetDlgItem(hwndDlg, IDC_TABS);
+ tci.mask = TCIF_PARAM;
+ count = TabCtrl_GetItemCount(hTab);
+ // return the largest of all pages
+ for (i=0;i<count;i++) {
+ TabCtrl_GetItem(hTab, i, &tci);
+ ZeroMemory(&pageMinMax, sizeof(pageMinMax));
+ SendMessage((HWND)tci.lParam, WM_GETMINMAXINFO, wParam, (LPARAM)&pageMinMax);
+ ((MINMAXINFO*)lParam)->ptMinTrackSize.x = max(((MINMAXINFO*)lParam)->ptMinTrackSize.x, pageMinMax.ptMinTrackSize.x);
+ ((MINMAXINFO*)lParam)->ptMinTrackSize.y = max(((MINMAXINFO*)lParam)->ptMinTrackSize.y, pageMinMax.ptMinTrackSize.y);
+ }
+ }
+ break;
+
+ case WM_SIZE: {
+ TCITEM tci;
+ int i, count;
+ HWND hTab;
+ RECT rcTabs, rcParent;
+
+ if(IsIconic(hwndDlg))
+ break;
+
+ UTILRESIZEDIALOG urd = { 0 };
+ urd.cbSize = sizeof(urd);
+ urd.hInstance = hInst;
+ urd.hwndDlg = hwndDlg;
+ urd.lParam = (LPARAM)0;
+ // ! uses ANSI version !
+ urd.lpTemplate = MAKEINTRESOURCEA(IDD_HELP_DIALOG);
+ urd.pfnResizer = helpDialogResize;
+ CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd);
+
+ SendMessage(hwndDlg, WM_MOVE, 0, 0);
+
+ hTab = GetDlgItem(hwndDlg, IDC_TABS);
+ GetWindowRect(hTab, &rcTabs);
+ GetWindowRect(hwndDlg, &rcParent);
+ tci.mask = TCIF_PARAM;
+ count = TabCtrl_GetItemCount(hTab);
+ for (i=0;i<count;i++) {
+ TabCtrl_GetItem(GetDlgItem(hwndDlg,IDC_TABS), i, &tci);
+ MoveWindow((HWND)tci.lParam, (rcTabs.left - rcParent.left), (rcTabs.top - rcParent.top), (rcTabs.right - rcTabs.left) - 2*iFrameX, (rcTabs.bottom - rcTabs.top) - 2*iFrameY, TRUE);
+ }
+ break;
+ }
+
+ case WM_NOTIFY:
+ if ((((NMHDR*)lParam)->idFrom == IDC_TABS)) {
+ if (((NMHDR*)lParam)->code == TCN_SELCHANGING) {
+ TCITEM tci;
+
+ tci.mask = TCIF_PARAM;
+ TabCtrl_GetItem(GetDlgItem(hwndDlg, IDC_TABS), TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_TABS)), &tci);
+ ShowWindow((HWND)tci.lParam, SW_HIDE);
+ }
+ else if (((NMHDR*)lParam)->code == TCN_SELCHANGE) {
+ TCITEM tci;
+
+ tci.mask = TCIF_PARAM;
+ TabCtrl_GetItem(GetDlgItem(hwndDlg, IDC_TABS), TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_TABS)), &tci);
+ ShowWindow((HWND)tci.lParam, SW_SHOW);
+ }
+ }
+ break;
+
+ case WM_CLOSE:
+ if (GetParent(hwndDlg) == NULL)
+ DestroyWindow(hwndDlg);
+ else
+ EndDialog(hwndDlg, 0);
+ break;
+
+ case WM_DESTROY:
+ Utils_SaveWindowPosition(hwndDlg, NULL, MODULENAME, "help");
+ {
+ HWND hTab = GetDlgItem(hwndDlg, IDC_TABS);
+
+ TCITEM tci;
+ tci.mask = TCIF_PARAM;
+ int count = TabCtrl_GetItemCount(hTab);
+ for ( int i=0; i < count; i++ ) {
+ TabCtrl_GetItem(hTab, i, &tci);
+ if (((HWND)tci.lParam != dat->hwndSubjectDlg) && ((HWND)tci.lParam != dat->hwndExtraTextDlg))
+ DestroyWindow((HWND)tci.lParam);
+ } }
+
+ // these windows might have been created, but not inserted as tabs
+ if (IsWindow(dat->hwndSubjectDlg))
+ DestroyWindow(dat->hwndSubjectDlg);
+
+ if (IsWindow(dat->hwndExtraTextDlg))
+ DestroyWindow(dat->hwndExtraTextDlg);
+
+ mir_free(dat);
+ dat = NULL;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG)NULL);
+ break;
+ }
+
+ return FALSE;
+}
+
+INT_PTR showHelpExService(WPARAM wParam, LPARAM lParam)
+{
+ if (IsWindow(hwndHelpDialog)) {
+ SetFocus(hwndHelpDialog);
+ return 0;
+ }
+ if (lParam == 0)
+ return -1;
+
+ iFrameX = GetSystemMetrics(SM_CXSIZEFRAME);
+ iFrameY = 3 * GetSystemMetrics(SM_CYSIZEFRAME);
+
+ if (wParam)
+ DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HELP_DIALOG), (HWND)wParam, helpDlgProc, (LPARAM)lParam);
+ else
+ CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_HELP_DIALOG), NULL, helpDlgProc, (LPARAM)lParam);
+
+ return 0;
+}
+
+INT_PTR showHelpService(WPARAM wParam, LPARAM lParam)
+{
+ static VARHELPINFO *vhs = NULL;
+ static FORMATINFO *fi = NULL;
+
+ if (fi == NULL)
+ fi = ( FORMATINFO* )mir_alloc(sizeof(FORMATINFO));
+
+ ZeroMemory(fi, sizeof(FORMATINFO));
+ fi->cbSize = sizeof(FORMATINFO);
+ fi->szFormat = (char *)lParam;
+ if (vhs == NULL)
+ vhs = ( VARHELPINFO* )mir_alloc(sizeof(VARHELPINFO));
+
+ ZeroMemory(vhs, sizeof(VARHELPINFO));
+ vhs->cbSize = sizeof(VARHELPINFO);
+ vhs->fi = fi;
+ vhs->hwndCtrl = (HWND)wParam;
+ vhs->flags = VHF_FULLDLG|VHF_DONTFILLSTRUCT;
+
+ return showHelpExService(0, (LPARAM)vhs);
+}
+
+INT_PTR getSkinItemService(WPARAM wParam, LPARAM lParam)
+{
+ int item = lParam;
+ if (item == 0)
+ return (INT_PTR)NULL;
+
+ switch (item) {
+ case VSI_HELPICON:
+ if (hHelpIcon == NULL) {
+ if (ServiceExists(MS_SKIN2_GETICON))
+ hHelpIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"vars_help");
+
+ if (hHelpIcon == NULL)
+ hHelpIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_V), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
+ }
+
+ return (INT_PTR)hHelpIcon;
+
+ case VSI_HELPTIPTEXT:
+ return (INT_PTR)Translate("Open String Formatting Help");
+ }
+
+ return (INT_PTR)NULL;
+}
+
+int iconsChanged(WPARAM wParam, LPARAM lParam)
+{
+ hHelpIcon = NULL;
+ return 0;
+}
diff --git a/plugins/Variables/src/libxml/DOCBparser.h b/plugins/Variables/src/libxml/DOCBparser.h
new file mode 100644
index 0000000000..75fb0b2ac8
--- /dev/null
+++ b/plugins/Variables/src/libxml/DOCBparser.h
@@ -0,0 +1,73 @@
+/*
+ * DOCBparser.h : interface for a DocBook SGML non-verifying parser
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifndef __DOCB_PARSER_H__
+#define __DOCB_PARSER_H__
+#include "libxml/parser.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Most of the back-end structures from XML and SGML are shared.
+ */
+typedef xmlParserCtxt docbParserCtxt;
+typedef xmlParserCtxtPtr docbParserCtxtPtr;
+typedef xmlParserNodeInfo docbParserNodeInfo;
+typedef xmlSAXHandler docbSAXHandler;
+typedef xmlSAXHandlerPtr docbSAXHandlerPtr;
+typedef xmlParserInput docbParserInput;
+typedef xmlParserInputPtr docbParserInputPtr;
+typedef xmlDocPtr docbDocPtr;
+typedef xmlNodePtr docbNodePtr;
+
+/*
+ * There is only few public functions.
+ */
+int docbEncodeEntities(unsigned char *out,
+ int *outlen,
+ const unsigned char *in,
+ int *inlen, int quoteChar);
+
+docbDocPtr docbSAXParseDoc (xmlChar *cur,
+ const char *encoding,
+ docbSAXHandlerPtr sax,
+ void *userData);
+docbDocPtr docbParseDoc (xmlChar *cur,
+ const char *encoding);
+docbDocPtr docbSAXParseFile(const char *filename,
+ const char *encoding,
+ docbSAXHandlerPtr sax,
+ void *userData);
+docbDocPtr docbParseFile (const char *filename,
+ const char *encoding);
+
+/**
+ * Interfaces for the Push mode.
+ */
+void docbFreeParserCtxt (docbParserCtxtPtr ctxt);
+docbParserCtxtPtr docbCreatePushParserCtxt(docbSAXHandlerPtr sax,
+ void *user_data,
+ const char *chunk,
+ int size,
+ const char *filename,
+ xmlCharEncoding enc);
+int docbParseChunk (docbParserCtxtPtr ctxt,
+ const char *chunk,
+ int size,
+ int terminate);
+docbParserCtxtPtr docbCreateFileParserCtxt(const char *filename,
+ const char *encoding);
+int docbParseDocument (docbParserCtxtPtr ctxt);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DOCB_PARSER_H__ */
diff --git a/plugins/Variables/src/libxml/HTMLparser.h b/plugins/Variables/src/libxml/HTMLparser.h
new file mode 100644
index 0000000000..a98ecbe8e6
--- /dev/null
+++ b/plugins/Variables/src/libxml/HTMLparser.h
@@ -0,0 +1,159 @@
+/*
+ * HTMLparser.h : interface for an HTML 4.0 non-verifying parser
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifndef __HTML_PARSER_H__
+#define __HTML_PARSER_H__
+#include "libxml/parser.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Most of the back-end structures from XML and HTML are shared.
+ */
+typedef xmlParserCtxt htmlParserCtxt;
+typedef xmlParserCtxtPtr htmlParserCtxtPtr;
+typedef xmlParserNodeInfo htmlParserNodeInfo;
+typedef xmlSAXHandler htmlSAXHandler;
+typedef xmlSAXHandlerPtr htmlSAXHandlerPtr;
+typedef xmlParserInput htmlParserInput;
+typedef xmlParserInputPtr htmlParserInputPtr;
+typedef xmlDocPtr htmlDocPtr;
+typedef xmlNodePtr htmlNodePtr;
+
+/*
+ * Internal description of an HTML element, representing HTML 4.01
+ * and XHTML 1.0 (which share the same structure).
+ */
+typedef struct _htmlElemDesc htmlElemDesc;
+typedef htmlElemDesc *htmlElemDescPtr;
+struct _htmlElemDesc {
+ const char *name; /* The tag name */
+ char startTag; /* Whether the start tag can be implied */
+ char endTag; /* Whether the end tag can be implied */
+ char saveEndTag; /* Whether the end tag should be saved */
+ char empty; /* Is this an empty element ? */
+ char depr; /* Is this a deprecated element ? */
+ char dtd; /* 1: only in Loose DTD, 2: only Frameset one */
+ char isinline; /* is this a block 0 or inline 1 element */
+ const char *desc; /* the description */
+
+/* NRK Jan.2003
+ * New fields encapsulating HTML structure
+ *
+ * Bugs:
+ * This is a very limited representation. It fails to tell us when
+ * an element *requires* subelements (we only have whether they're
+ * allowed or not), and it doesn't tell us where CDATA and PCDATA
+ * are allowed. Some element relationships are not fully represented:
+ * these are flagged with the word MODIFIER
+ */
+ const char** subelts; /* allowed sub-elements of this element */
+ const char* defaultsubelt; /* subelement for suggested auto-repair
+ if necessary or NULL */
+ const char** attrs_opt; /* Optional Attributes */
+ const char** attrs_depr; /* Additional deprecated attributes */
+ const char** attrs_req; /* Required attributes */
+};
+
+/*
+ * Internal description of an HTML entity.
+ */
+typedef struct _htmlEntityDesc htmlEntityDesc;
+typedef htmlEntityDesc *htmlEntityDescPtr;
+struct _htmlEntityDesc {
+ unsigned int value; /* the UNICODE value for the character */
+ const char *name; /* The entity name */
+ const char *desc; /* the description */
+};
+
+/*
+ * There is only few public functions.
+ */
+const htmlElemDesc * htmlTagLookup (const xmlChar *tag);
+const htmlEntityDesc * htmlEntityLookup(const xmlChar *name);
+const htmlEntityDesc * htmlEntityValueLookup(unsigned int value);
+
+int htmlIsAutoClosed(htmlDocPtr doc,
+ htmlNodePtr elem);
+int htmlAutoCloseTag(htmlDocPtr doc,
+ const xmlChar *name,
+ htmlNodePtr elem);
+const htmlEntityDesc * htmlParseEntityRef(htmlParserCtxtPtr ctxt,
+ xmlChar **str);
+int htmlParseCharRef(htmlParserCtxtPtr ctxt);
+void htmlParseElement(htmlParserCtxtPtr ctxt);
+
+int htmlParseDocument(htmlParserCtxtPtr ctxt);
+htmlDocPtr htmlSAXParseDoc (xmlChar *cur,
+ const char *encoding,
+ htmlSAXHandlerPtr sax,
+ void *userData);
+htmlDocPtr htmlParseDoc (xmlChar *cur,
+ const char *encoding);
+htmlDocPtr htmlSAXParseFile(const char *filename,
+ const char *encoding,
+ htmlSAXHandlerPtr sax,
+ void *userData);
+htmlDocPtr htmlParseFile (const char *filename,
+ const char *encoding);
+int UTF8ToHtml (unsigned char *out,
+ int *outlen,
+ const unsigned char *in,
+ int *inlen);
+int htmlEncodeEntities(unsigned char *out,
+ int *outlen,
+ const unsigned char *in,
+ int *inlen, int quoteChar);
+int htmlIsScriptAttribute(const xmlChar *name);
+int htmlHandleOmittedElem(int val);
+
+/**
+ * Interfaces for the Push mode.
+ */
+void htmlFreeParserCtxt (htmlParserCtxtPtr ctxt);
+htmlParserCtxtPtr htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax,
+ void *user_data,
+ const char *chunk,
+ int size,
+ const char *filename,
+ xmlCharEncoding enc);
+int htmlParseChunk (htmlParserCtxtPtr ctxt,
+ const char *chunk,
+ int size,
+ int terminate);
+
+/* NRK/Jan2003: further knowledge of HTML structure
+ */
+typedef enum {
+ HTML_NA = 0 , /* something we don't check at all */
+ HTML_INVALID = 0x1 ,
+ HTML_DEPRECATED = 0x2 ,
+ HTML_VALID = 0x4 ,
+ HTML_REQUIRED = 0xc /* VALID bit set so ( & HTML_VALID ) is TRUE */
+} htmlStatus ;
+
+/* Using htmlElemDesc rather than name here, to emphasise the fact
+ that otherwise there's a lookup overhead
+*/
+htmlStatus htmlAttrAllowed(const htmlElemDesc*, const xmlChar*, int) ;
+int htmlElementAllowedHere(const htmlElemDesc*, const xmlChar*) ;
+htmlStatus htmlElementStatusHere(const htmlElemDesc*, const htmlElemDesc*) ;
+htmlStatus htmlNodeStatus(const htmlNodePtr, int) ;
+#define htmlDefaultSubelement(elt) elt->defaultsubelt
+#define htmlElementAllowedHereDesc(parent,elt) \
+ htmlElementAllowedHere((parent), (elt)->name)
+#define htmlRequiredAttrs(elt) (elt)->attrs_req
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HTML_PARSER_H__ */
diff --git a/plugins/Variables/src/libxml/HTMLtree.h b/plugins/Variables/src/libxml/HTMLtree.h
new file mode 100644
index 0000000000..e9944b3b25
--- /dev/null
+++ b/plugins/Variables/src/libxml/HTMLtree.h
@@ -0,0 +1,117 @@
+/*
+ * HTMLtree.h : describes the structures found in an tree resulting
+ * from an XML parsing.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifndef __HTML_TREE_H__
+#define __HTML_TREE_H__
+
+#include <stdio.h>
+#include "libxml/tree.h"
+#include "libxml/HTMLparser.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * HTML_TEXT_NODE:
+ *
+ * Macro. A text node in a HTML document is really implemented
+ * the same way as a text node in an XML document.
+ */
+#define HTML_TEXT_NODE XML_TEXT_NODE
+/**
+ * HTML_ENTITY_REF_NODE:
+ *
+ * Macro. An entity reference in a HTML document is really implemented
+ * the same way as an entity reference in an XML document.
+ */
+#define HTML_ENTITY_REF_NODE XML_ENTITY_REF_NODE
+/**
+ * HTML_COMMENT_NODE:
+ *
+ * Macro. A comment in a HTML document is really implemented
+ * the same way as a comment in an XML document.
+ */
+#define HTML_COMMENT_NODE XML_COMMENT_NODE
+/**
+ * HTML_PRESERVE_NODE:
+ *
+ * Macro. A preserved node in a HTML document is really implemented
+ * the same way as a CDATA section in an XML document.
+ */
+#define HTML_PRESERVE_NODE XML_CDATA_SECTION_NODE
+/**
+ * HTML_PI_NODE:
+ *
+ * Macro. A processing instruction in a HTML document is really implemented
+ * the same way as a processing instruction in an XML document.
+ */
+#define HTML_PI_NODE XML_PI_NODE
+
+htmlDocPtr htmlNewDoc (const xmlChar *URI,
+ const xmlChar *ExternalID);
+htmlDocPtr htmlNewDocNoDtD (const xmlChar *URI,
+ const xmlChar *ExternalID);
+const xmlChar * htmlGetMetaEncoding (htmlDocPtr doc);
+int htmlSetMetaEncoding (htmlDocPtr doc,
+ const xmlChar *encoding);
+void htmlDocDumpMemory (xmlDocPtr cur,
+ xmlChar **mem,
+ int *size);
+int htmlDocDump (FILE *f,
+ xmlDocPtr cur);
+int htmlSaveFile (const char *filename,
+ xmlDocPtr cur);
+int htmlNodeDump (xmlBufferPtr buf,
+ xmlDocPtr doc,
+ xmlNodePtr cur);
+void htmlNodeDumpFile (FILE *out,
+ xmlDocPtr doc,
+ xmlNodePtr cur);
+int htmlNodeDumpFileFormat (FILE *out,
+ xmlDocPtr doc,
+ xmlNodePtr cur,
+ const char *encoding,
+ int format);
+int htmlSaveFileEnc (const char *filename,
+ xmlDocPtr cur,
+ const char *encoding);
+int htmlSaveFileFormat (const char *filename,
+ xmlDocPtr cur,
+ const char *encoding,
+ int format);
+
+void htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf,
+ xmlDocPtr doc,
+ xmlNodePtr cur,
+ const char *encoding,
+ int format);
+void htmlDocContentDumpOutput(xmlOutputBufferPtr buf,
+ xmlDocPtr cur,
+ const char *encoding);
+void htmlDocContentDumpFormatOutput(xmlOutputBufferPtr buf,
+ xmlDocPtr cur,
+ const char *encoding,
+ int format);
+
+int htmlIsBooleanAttr (const xmlChar *name);
+void htmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
+ xmlNodePtr cur, const char *encoding);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HTML_TREE_H__ */
+
diff --git a/plugins/Variables/src/libxml/SAX.h b/plugins/Variables/src/libxml/SAX.h
new file mode 100644
index 0000000000..a46e14c78e
--- /dev/null
+++ b/plugins/Variables/src/libxml/SAX.h
@@ -0,0 +1,128 @@
+/*
+ * SAX.h : Default SAX handler interfaces.
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel Veillard <daniel@veillard.com>
+ */
+
+
+#ifndef __XML_SAX_H__
+#define __XML_SAX_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "libxml/parser.h"
+#include "libxml/xlink.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+const xmlChar * getPublicId (void *ctx);
+const xmlChar * getSystemId (void *ctx);
+void setDocumentLocator (void *ctx,
+ xmlSAXLocatorPtr loc);
+
+int getLineNumber (void *ctx);
+int getColumnNumber (void *ctx);
+
+int isStandalone (void *ctx);
+int hasInternalSubset (void *ctx);
+int hasExternalSubset (void *ctx);
+
+void internalSubset (void *ctx,
+ const xmlChar *name,
+ const xmlChar *ExternalID,
+ const xmlChar *SystemID);
+void externalSubset (void *ctx,
+ const xmlChar *name,
+ const xmlChar *ExternalID,
+ const xmlChar *SystemID);
+xmlEntityPtr getEntity (void *ctx,
+ const xmlChar *name);
+xmlEntityPtr getParameterEntity (void *ctx,
+ const xmlChar *name);
+xmlParserInputPtr resolveEntity (void *ctx,
+ const xmlChar *publicId,
+ const xmlChar *systemId);
+
+void entityDecl (void *ctx,
+ const xmlChar *name,
+ int type,
+ const xmlChar *publicId,
+ const xmlChar *systemId,
+ xmlChar *content);
+void attributeDecl (void *ctx,
+ const xmlChar *elem,
+ const xmlChar *fullname,
+ int type,
+ int def,
+ const xmlChar *defaultValue,
+ xmlEnumerationPtr tree);
+void elementDecl (void *ctx,
+ const xmlChar *name,
+ int type,
+ xmlElementContentPtr content);
+void notationDecl (void *ctx,
+ const xmlChar *name,
+ const xmlChar *publicId,
+ const xmlChar *systemId);
+void unparsedEntityDecl (void *ctx,
+ const xmlChar *name,
+ const xmlChar *publicId,
+ const xmlChar *systemId,
+ const xmlChar *notationName);
+
+void startDocument (void *ctx);
+void endDocument (void *ctx);
+void attribute (void *ctx,
+ const xmlChar *fullname,
+ const xmlChar *value);
+void startElement (void *ctx,
+ const xmlChar *fullname,
+ const xmlChar **atts);
+void endElement (void *ctx,
+ const xmlChar *name);
+void reference (void *ctx,
+ const xmlChar *name);
+void characters (void *ctx,
+ const xmlChar *ch,
+ int len);
+void ignorableWhitespace (void *ctx,
+ const xmlChar *ch,
+ int len);
+void processingInstruction (void *ctx,
+ const xmlChar *target,
+ const xmlChar *data);
+void globalNamespace (void *ctx,
+ const xmlChar *href,
+ const xmlChar *prefix);
+void setNamespace (void *ctx,
+ const xmlChar *name);
+xmlNsPtr getNamespace (void *ctx);
+int checkNamespace (void *ctx,
+ xmlChar *nameSpace);
+void namespaceDecl (void *ctx,
+ const xmlChar *href,
+ const xmlChar *prefix);
+void comment (void *ctx,
+ const xmlChar *value);
+void cdataBlock (void *ctx,
+ const xmlChar *value,
+ int len);
+
+void initxmlDefaultSAXHandler (xmlSAXHandler *hdlr,
+ int warning);
+#ifdef LIBXML_HTML_ENABLED
+void inithtmlDefaultSAXHandler (xmlSAXHandler *hdlr);
+#endif
+#ifdef LIBXML_DOCB_ENABLED
+void initdocbDefaultSAXHandler (xmlSAXHandler *hdlr);
+#endif
+void xmlDefaultSAXHandlerInit (void);
+void htmlDefaultSAXHandlerInit (void);
+void docbDefaultSAXHandlerInit (void);
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_SAX_H__ */
diff --git a/plugins/Variables/src/libxml/c14n.h b/plugins/Variables/src/libxml/c14n.h
new file mode 100644
index 0000000000..75ace8a4a4
--- /dev/null
+++ b/plugins/Variables/src/libxml/c14n.h
@@ -0,0 +1,91 @@
+/*
+ * "Canonical XML" implementation
+ * http://www.w3.org/TR/xml-c14n
+ *
+ * "Exclusive XML Canonicalization" implementation
+ * http://www.w3.org/TR/xml-exc-c14n
+
+ * See Copyright for the status of this software.
+ *
+ * Author: Aleksey Sanin <aleksey@aleksey.com>
+ */
+#ifndef __XML_C14N_H__
+#define __XML_C14N_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <libxml/tree.h>
+#include <libxml/xpath.h>
+
+/*
+ * XML Canonicazation
+ * http://www.w3.org/TR/xml-c14n
+ *
+ * Exclusive XML Canonicazation
+ * http://www.w3.org/TR/xml-exc-c14n
+ *
+ * Canonical form of an XML document could be created if and only if
+ * a) default attributes (if any) are added to all nodes
+ * b) all character and parsed entity references are resolved
+ * In order to achive this in libxml2 the document MUST be loaded with
+ * following global setings:
+ *
+ * xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
+ * xmlSubstituteEntitiesDefault(1);
+ *
+ * or corresponding parser context setting:
+ * xmlParserCtxtPtr ctxt;
+ *
+ * ...
+ * ctxt->loadsubset = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
+ * ctxt->replaceEntities = 1;
+ * ...
+ */
+
+
+int xmlC14NDocSaveTo (xmlDocPtr doc,
+ xmlNodeSetPtr nodes,
+ int exclusive,
+ xmlChar **inclusive_ns_prefixes,
+ int with_comments,
+ xmlOutputBufferPtr buf);
+
+int xmlC14NDocDumpMemory (xmlDocPtr doc,
+ xmlNodeSetPtr nodes,
+ int exclusive,
+ xmlChar **inclusive_ns_prefixes,
+ int with_comments,
+ xmlChar **doc_txt_ptr);
+
+int xmlC14NDocSave (xmlDocPtr doc,
+ xmlNodeSetPtr nodes,
+ int exclusive,
+ xmlChar **inclusive_ns_prefixes,
+ int with_comments,
+ const char* filename,
+ int compression);
+
+
+/**
+ * This is the core C14N function
+ */
+typedef int (*xmlC14NIsVisibleCallback) (void* user_data,
+ xmlNodePtr node,
+ xmlNodePtr parent);
+
+int xmlC14NExecute (xmlDocPtr doc,
+ xmlC14NIsVisibleCallback is_visible_callback,
+ void* user_data,
+ int exclusive,
+ xmlChar **inclusive_ns_prefixes,
+ int with_comments,
+ xmlOutputBufferPtr buf);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __XML_C14N_H__ */
+
diff --git a/plugins/Variables/src/libxml/catalog.h b/plugins/Variables/src/libxml/catalog.h
new file mode 100644
index 0000000000..f6ee04815e
--- /dev/null
+++ b/plugins/Variables/src/libxml/catalog.h
@@ -0,0 +1,138 @@
+/**
+ * catalog.h: interfaces of the Catalog handling system
+ *
+ * Reference: SGML Open Technical Resolution TR9401:1997.
+ * http://www.jclark.com/sp/catalog.htm
+ *
+ * XML Catalogs Working Draft 12 Jun 2001
+ * http://www.oasis-open.org/committees/entity/spec-2001-06-12.html
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifndef __XML_CATALOG_H__
+#define __XML_CATALOG_H__
+
+#include <stdio.h>
+
+#include "libxml/xmlversion.h"
+
+#ifdef LIBXML_CATALOG_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * XML_CATALOGS_NAMESPACE:
+ *
+ * The namespace for the XML Catalogs elements.
+ */
+#define XML_CATALOGS_NAMESPACE \
+ (const xmlChar *) "urn:oasis:names:tc:entity:xmlns:xml:catalog"
+/**
+ * XML_CATALOG_PI:
+ *
+ * The specific XML Catalog Processing Instuction name.
+ */
+#define XML_CATALOG_PI \
+ (const xmlChar *) "oasis-xml-catalog"
+
+/*
+ * The API is voluntarily limited to general cataloging.
+ */
+typedef enum {
+ XML_CATA_PREFER_NONE = 0,
+ XML_CATA_PREFER_PUBLIC = 1,
+ XML_CATA_PREFER_SYSTEM
+} xmlCatalogPrefer;
+
+typedef enum {
+ XML_CATA_ALLOW_NONE = 0,
+ XML_CATA_ALLOW_GLOBAL = 1,
+ XML_CATA_ALLOW_DOCUMENT = 2,
+ XML_CATA_ALLOW_ALL = 3
+} xmlCatalogAllow;
+
+typedef struct _xmlCatalog xmlCatalog;
+typedef xmlCatalog *xmlCatalogPtr;
+
+/*
+ * Operations on a given catalog.
+ */
+xmlCatalogPtr xmlNewCatalog (int sgml);
+xmlCatalogPtr xmlLoadACatalog (const char *filename);
+xmlCatalogPtr xmlLoadSGMLSuperCatalog (const char *filename);
+int xmlConvertSGMLCatalog (xmlCatalogPtr catal);
+int xmlACatalogAdd (xmlCatalogPtr catal,
+ const xmlChar *type,
+ const xmlChar *orig,
+ const xmlChar *replace);
+int xmlACatalogRemove (xmlCatalogPtr catal,
+ const xmlChar *value);
+xmlChar * xmlACatalogResolve (xmlCatalogPtr catal,
+ const xmlChar *pubID,
+ const xmlChar *sysID);
+xmlChar * xmlACatalogResolveSystem(xmlCatalogPtr catal,
+ const xmlChar *sysID);
+xmlChar * xmlACatalogResolvePublic(xmlCatalogPtr catal,
+ const xmlChar *pubID);
+xmlChar * xmlACatalogResolveURI (xmlCatalogPtr catal,
+ const xmlChar *URI);
+void xmlACatalogDump (xmlCatalogPtr catal,
+ FILE *out);
+void xmlFreeCatalog (xmlCatalogPtr catal);
+int xmlCatalogIsEmpty (xmlCatalogPtr catal);
+
+/*
+ * Global operations.
+ */
+void xmlInitializeCatalog (void);
+int xmlLoadCatalog (const char *filename);
+void xmlLoadCatalogs (const char *paths);
+void xmlCatalogCleanup (void);
+void xmlCatalogDump (FILE *out);
+xmlChar * xmlCatalogResolve (const xmlChar *pubID,
+ const xmlChar *sysID);
+xmlChar * xmlCatalogResolveSystem (const xmlChar *sysID);
+xmlChar * xmlCatalogResolvePublic (const xmlChar *pubID);
+xmlChar * xmlCatalogResolveURI (const xmlChar *URI);
+int xmlCatalogAdd (const xmlChar *type,
+ const xmlChar *orig,
+ const xmlChar *replace);
+int xmlCatalogRemove (const xmlChar *value);
+xmlDocPtr xmlParseCatalogFile (const char *filename);
+int xmlCatalogConvert (void);
+
+/*
+ * Strictly minimal interfaces for per-document catalogs used
+ * by the parser.
+ */
+void xmlCatalogFreeLocal (void *catalogs);
+void * xmlCatalogAddLocal (void *catalogs,
+ const xmlChar *URL);
+xmlChar * xmlCatalogLocalResolve (void *catalogs,
+ const xmlChar *pubID,
+ const xmlChar *sysID);
+xmlChar * xmlCatalogLocalResolveURI(void *catalogs,
+ const xmlChar *URI);
+/*
+ * Preference settings.
+ */
+int xmlCatalogSetDebug (int level);
+xmlCatalogPrefer xmlCatalogSetDefaultPrefer(xmlCatalogPrefer prefer);
+void xmlCatalogSetDefaults (xmlCatalogAllow allow);
+xmlCatalogAllow xmlCatalogGetDefaults (void);
+
+
+/* DEPRECATED interfaces */
+const xmlChar * xmlCatalogGetSystem (const xmlChar *sysID);
+const xmlChar * xmlCatalogGetPublic (const xmlChar *pubID);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* LIBXML_CATALOG_ENABLED */
+#endif /* __XML_CATALOG_H__ */
diff --git a/plugins/Variables/src/libxml/debugXML.h b/plugins/Variables/src/libxml/debugXML.h
new file mode 100644
index 0000000000..444acb408e
--- /dev/null
+++ b/plugins/Variables/src/libxml/debugXML.h
@@ -0,0 +1,163 @@
+/*
+ * debugXML.h : Interfaces to a set of routines used for debugging the tree
+ * produced by the XML parser.
+ *
+ * Daniel Veillard <daniel@veillard.com>
+ */
+
+#ifndef __DEBUG_XML__
+#define __DEBUG_XML__
+#include <stdio.h>
+#include "libxml/tree.h"
+
+#ifdef LIBXML_DEBUG_ENABLED
+
+#include "libxml/xpath.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The standard Dump routines.
+ */
+void xmlDebugDumpString (FILE *output,
+ const xmlChar *str);
+void xmlDebugDumpAttr (FILE *output,
+ xmlAttrPtr attr,
+ int depth);
+void xmlDebugDumpAttrList (FILE *output,
+ xmlAttrPtr attr,
+ int depth);
+void xmlDebugDumpOneNode (FILE *output,
+ xmlNodePtr node,
+ int depth);
+void xmlDebugDumpNode (FILE *output,
+ xmlNodePtr node,
+ int depth);
+void xmlDebugDumpNodeList (FILE *output,
+ xmlNodePtr node,
+ int depth);
+void xmlDebugDumpDocumentHead(FILE *output,
+ xmlDocPtr doc);
+void xmlDebugDumpDocument (FILE *output,
+ xmlDocPtr doc);
+void xmlDebugDumpDTD (FILE *output,
+ xmlDtdPtr dtd);
+void xmlDebugDumpEntities (FILE *output,
+ xmlDocPtr doc);
+
+void xmlLsOneNode (FILE *output, xmlNodePtr node);
+int xmlLsCountNode (xmlNodePtr node);
+
+LIBXML_DLL_IMPORT const char *xmlBoolToText (int boolval);
+
+/****************************************************************
+ * *
+ * The XML shell related structures and functions *
+ * *
+ ****************************************************************/
+
+/**
+ * xmlShellReadlineFunc:
+ * @prompt: a string prompt
+ *
+ * This is a generic signature for the XML shell input function.
+ *
+ * Returns a string which will be freed by the Shell.
+ */
+typedef char * (* xmlShellReadlineFunc)(char *prompt);
+
+/**
+ * xmlShellCtxt:
+ *
+ * A debugging shell context.
+ * TODO: add the defined function tables.
+ */
+typedef struct _xmlShellCtxt xmlShellCtxt;
+typedef xmlShellCtxt *xmlShellCtxtPtr;
+struct _xmlShellCtxt {
+ char *filename;
+ xmlDocPtr doc;
+ xmlNodePtr node;
+ xmlXPathContextPtr pctxt;
+ int loaded;
+ FILE *output;
+ xmlShellReadlineFunc input;
+};
+
+/**
+ * xmlShellCmd:
+ * @ctxt: a shell context
+ * @arg: a string argument
+ * @node: a first node
+ * @node2: a second node
+ *
+ * This is a generic signature for the XML shell functions.
+ *
+ * Returns an int, negative returns indicating errors.
+ */
+typedef int (* xmlShellCmd) (xmlShellCtxtPtr ctxt,
+ char *arg,
+ xmlNodePtr node,
+ xmlNodePtr node2);
+
+void xmlShellPrintXPathError (int errorType,
+ const char *arg);
+void xmlShellPrintNode (xmlNodePtr node);
+void xmlShellPrintXPathResult(xmlXPathObjectPtr list);
+int xmlShellList (xmlShellCtxtPtr ctxt,
+ char *arg,
+ xmlNodePtr node,
+ xmlNodePtr node2);
+int xmlShellBase (xmlShellCtxtPtr ctxt,
+ char *arg,
+ xmlNodePtr node,
+ xmlNodePtr node2);
+int xmlShellDir (xmlShellCtxtPtr ctxt,
+ char *arg,
+ xmlNodePtr node,
+ xmlNodePtr node2);
+int xmlShellCat (xmlShellCtxtPtr ctxt,
+ char *arg,
+ xmlNodePtr node,
+ xmlNodePtr node2);
+int xmlShellLoad (xmlShellCtxtPtr ctxt,
+ char *filename,
+ xmlNodePtr node,
+ xmlNodePtr node2);
+int xmlShellWrite (xmlShellCtxtPtr ctxt,
+ char *filename,
+ xmlNodePtr node,
+ xmlNodePtr node2);
+int xmlShellSave (xmlShellCtxtPtr ctxt,
+ char *filename,
+ xmlNodePtr node,
+ xmlNodePtr node2);
+int xmlShellValidate (xmlShellCtxtPtr ctxt,
+ char *dtd,
+ xmlNodePtr node,
+ xmlNodePtr node2);
+int xmlShellDu (xmlShellCtxtPtr ctxt,
+ char *arg,
+ xmlNodePtr tree,
+ xmlNodePtr node2);
+int xmlShellPwd (xmlShellCtxtPtr ctxt,
+ char *buffer,
+ xmlNodePtr node,
+ xmlNodePtr node2);
+
+/*
+ * The Shell interface.
+ */
+void xmlShell (xmlDocPtr doc,
+ char *filename,
+ xmlShellReadlineFunc input,
+ FILE *output);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_DEBUG_ENABLED */
+#endif /* __DEBUG_XML__ */
diff --git a/plugins/Variables/src/libxml/encoding.h b/plugins/Variables/src/libxml/encoding.h
new file mode 100644
index 0000000000..012f6d9cf6
--- /dev/null
+++ b/plugins/Variables/src/libxml/encoding.h
@@ -0,0 +1,230 @@
+/*
+ * encoding.h : interface for the encoding conversion functions needed for
+ * XML
+ *
+ * Related specs:
+ * rfc2044 (UTF-8 and UTF-16) F. Yergeau Alis Technologies
+ * [ISO-10646] UTF-8 and UTF-16 in Annexes
+ * [ISO-8859-1] ISO Latin-1 characters codes.
+ * [UNICODE] The Unicode Consortium, "The Unicode Standard --
+ * Worldwide Character Encoding -- Version 1.0", Addison-
+ * Wesley, Volume 1, 1991, Volume 2, 1992. UTF-8 is
+ * described in Unicode Technical Report #4.
+ * [US-ASCII] Coded Character Set--7-bit American Standard Code for
+ * Information Interchange, ANSI X3.4-1986.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifndef __XML_CHAR_ENCODING_H__
+#define __XML_CHAR_ENCODING_H__
+
+#include "libxml/xmlversion.h"
+
+#ifdef LIBXML_ICONV_ENABLED
+#include <iconv.h>
+#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * xmlCharEncoding:
+ *
+ * Predefined values for some standard encodings.
+ * Libxml don't do beforehand translation on UTF8, ISOLatinX.
+ * It also support UTF16 (LE and BE) by default.
+ *
+ * Anything else would have to be translated to UTF8 before being
+ * given to the parser itself. The BOM for UTF16 and the encoding
+ * declaration are looked at and a converter is looked for at that
+ * point. If not found the parser stops here as asked by the XML REC
+ * Converter can be registered by the user using xmlRegisterCharEncodingHandler
+ * but the current form doesn't allow stateful transcoding (a serious
+ * problem agreed !). If iconv has been found it will be used
+ * automatically and allow stateful transcoding, the simplest is then
+ * to be sure to enable icon and to provide iconv libs for the encoding
+ * support needed.
+ */
+typedef enum {
+ XML_CHAR_ENCODING_ERROR= -1, /* No char encoding detected */
+ XML_CHAR_ENCODING_NONE= 0, /* No char encoding detected */
+ XML_CHAR_ENCODING_UTF8= 1, /* UTF-8 */
+ XML_CHAR_ENCODING_UTF16LE= 2, /* UTF-16 little endian */
+ XML_CHAR_ENCODING_UTF16BE= 3, /* UTF-16 big endian */
+ XML_CHAR_ENCODING_UCS4LE= 4, /* UCS-4 little endian */
+ XML_CHAR_ENCODING_UCS4BE= 5, /* UCS-4 big endian */
+ XML_CHAR_ENCODING_EBCDIC= 6, /* EBCDIC uh! */
+ XML_CHAR_ENCODING_UCS4_2143=7, /* UCS-4 unusual ordering */
+ XML_CHAR_ENCODING_UCS4_3412=8, /* UCS-4 unusual ordering */
+ XML_CHAR_ENCODING_UCS2= 9, /* UCS-2 */
+ XML_CHAR_ENCODING_8859_1= 10,/* ISO-8859-1 ISO Latin 1 */
+ XML_CHAR_ENCODING_8859_2= 11,/* ISO-8859-2 ISO Latin 2 */
+ XML_CHAR_ENCODING_8859_3= 12,/* ISO-8859-3 */
+ XML_CHAR_ENCODING_8859_4= 13,/* ISO-8859-4 */
+ XML_CHAR_ENCODING_8859_5= 14,/* ISO-8859-5 */
+ XML_CHAR_ENCODING_8859_6= 15,/* ISO-8859-6 */
+ XML_CHAR_ENCODING_8859_7= 16,/* ISO-8859-7 */
+ XML_CHAR_ENCODING_8859_8= 17,/* ISO-8859-8 */
+ XML_CHAR_ENCODING_8859_9= 18,/* ISO-8859-9 */
+ XML_CHAR_ENCODING_2022_JP= 19,/* ISO-2022-JP */
+ XML_CHAR_ENCODING_SHIFT_JIS=20,/* Shift_JIS */
+ XML_CHAR_ENCODING_EUC_JP= 21,/* EUC-JP */
+ XML_CHAR_ENCODING_ASCII= 22 /* pure ASCII */
+} xmlCharEncoding;
+
+/**
+ * xmlCharEncodingInputFunc:
+ * @out: a pointer to an array of bytes to store the UTF-8 result
+ * @outlen: the length of @out
+ * @in: a pointer to an array of chars in the original encoding
+ * @inlen: the length of @in
+ *
+ * Take a block of chars in the original encoding and try to convert
+ * it to an UTF-8 block of chars out.
+ *
+ * Returns the number of byte written, or -1 by lack of space, or -2
+ * if the transcoding failed.
+ * The value of @inlen after return is the number of octets consumed
+ * as the return value is positive, else unpredictiable.
+ * The value of @outlen after return is the number of octets consumed.
+ */
+typedef int (* xmlCharEncodingInputFunc)(unsigned char *out, int *outlen,
+ const unsigned char *in, int *inlen);
+
+
+/**
+ * xmlCharEncodingOutputFunc:
+ * @out: a pointer to an array of bytes to store the result
+ * @outlen: the length of @out
+ * @in: a pointer to an array of UTF-8 chars
+ * @inlen: the length of @in
+ *
+ * Take a block of UTF-8 chars in and try to convert it to an other
+ * encoding.
+ * Note: a first call designed to produce heading info is called with
+ * in = NULL. If stateful this should also initialize the encoder state.
+ *
+ * Returns the number of byte written, or -1 by lack of space, or -2
+ * if the transcoding failed.
+ * The value of @inlen after return is the number of octets consumed
+ * as the return value is positive, else unpredictiable.
+ * The value of @outlen after return is the number of ocetes consumed.
+ */
+typedef int (* xmlCharEncodingOutputFunc)(unsigned char *out, int *outlen,
+ const unsigned char *in, int *inlen);
+
+
+/*
+ * Block defining the handlers for non UTF-8 encodings.
+ * If iconv is supported, there is two extra fields.
+ */
+
+typedef struct _xmlCharEncodingHandler xmlCharEncodingHandler;
+typedef xmlCharEncodingHandler *xmlCharEncodingHandlerPtr;
+struct _xmlCharEncodingHandler {
+ char *name;
+ xmlCharEncodingInputFunc input;
+ xmlCharEncodingOutputFunc output;
+#ifdef LIBXML_ICONV_ENABLED
+ iconv_t iconv_in;
+ iconv_t iconv_out;
+#endif /* LIBXML_ICONV_ENABLED */
+};
+
+#ifdef __cplusplus
+}
+#endif
+#include "libxml/tree.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Interfaces for encoding handlers.
+ */
+void xmlInitCharEncodingHandlers (void);
+void xmlCleanupCharEncodingHandlers (void);
+void xmlRegisterCharEncodingHandler (xmlCharEncodingHandlerPtr handler);
+xmlCharEncodingHandlerPtr
+ xmlGetCharEncodingHandler (xmlCharEncoding enc);
+xmlCharEncodingHandlerPtr
+ xmlFindCharEncodingHandler (const char *name);
+xmlCharEncodingHandlerPtr
+ xmlNewCharEncodingHandler (const char *name,
+ xmlCharEncodingInputFunc input,
+ xmlCharEncodingOutputFunc output);
+
+/*
+ * Interfaces for encoding names and aliases.
+ */
+int xmlAddEncodingAlias (const char *name,
+ const char *alias);
+int xmlDelEncodingAlias (const char *alias);
+const char *
+ xmlGetEncodingAlias (const char *alias);
+void xmlCleanupEncodingAliases (void);
+xmlCharEncoding
+ xmlParseCharEncoding (const char *name);
+const char *
+ xmlGetCharEncodingName (xmlCharEncoding enc);
+
+/*
+ * Interfaces directly used by the parsers.
+ */
+xmlCharEncoding
+ xmlDetectCharEncoding (const unsigned char *in,
+ int len);
+
+int xmlCharEncOutFunc (xmlCharEncodingHandler *handler,
+ xmlBufferPtr out,
+ xmlBufferPtr in);
+
+int xmlCharEncInFunc (xmlCharEncodingHandler *handler,
+ xmlBufferPtr out,
+ xmlBufferPtr in);
+int xmlCharEncFirstLine (xmlCharEncodingHandler *handler,
+ xmlBufferPtr out,
+ xmlBufferPtr in);
+int xmlCharEncCloseFunc (xmlCharEncodingHandler *handler);
+
+/*
+ * Export a few useful functions
+ */
+int UTF8Toisolat1 (unsigned char *out,
+ int *outlen,
+ const unsigned char *in,
+ int *inlen);
+int isolat1ToUTF8 (unsigned char *out,
+ int *outlen,
+ const unsigned char *in,
+ int *inlen);
+int xmlGetUTF8Char (const unsigned char *utf,
+ int *len);
+/*
+ * exports additional "UTF-8 aware" string routines which are.
+ */
+
+int xmlCheckUTF8 (const unsigned char *utf);
+
+int xmlUTF8Strsize (const xmlChar *utf,
+ int len);
+xmlChar * xmlUTF8Strndup (const xmlChar *utf,
+ int len);
+xmlChar * xmlUTF8Strpos (const xmlChar *utf,
+ int pos);
+int xmlUTF8Strloc (const xmlChar *utf,
+ const xmlChar *utfchar);
+xmlChar * xmlUTF8Strsub (const xmlChar *utf,
+ int start,
+ int len);
+
+int xmlUTF8Strlen (const xmlChar *utf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_CHAR_ENCODING_H__ */
diff --git a/plugins/Variables/src/libxml/entities.h b/plugins/Variables/src/libxml/entities.h
new file mode 100644
index 0000000000..3dfc4deba1
--- /dev/null
+++ b/plugins/Variables/src/libxml/entities.h
@@ -0,0 +1,110 @@
+/*
+ * entities.h : interface for the XML entities handling
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifndef __XML_ENTITIES_H__
+#define __XML_ENTITIES_H__
+
+#include "libxml/tree.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The different valid entity types.
+ */
+typedef enum {
+ XML_INTERNAL_GENERAL_ENTITY = 1,
+ XML_EXTERNAL_GENERAL_PARSED_ENTITY = 2,
+ XML_EXTERNAL_GENERAL_UNPARSED_ENTITY = 3,
+ XML_INTERNAL_PARAMETER_ENTITY = 4,
+ XML_EXTERNAL_PARAMETER_ENTITY = 5,
+ XML_INTERNAL_PREDEFINED_ENTITY = 6
+} xmlEntityType;
+
+/*
+ * An unit of storage for an entity, contains the string, the value
+ * and the linkind data needed for the linking in the hash table.
+ */
+
+struct _xmlEntity {
+ void *_private; /* application data */
+ xmlElementType type; /* XML_ENTITY_DECL, must be second ! */
+ const xmlChar *name; /* Entity name */
+ struct _xmlNode *children; /* First child link */
+ struct _xmlNode *last; /* Last child link */
+ struct _xmlDtd *parent; /* -> DTD */
+ struct _xmlNode *next; /* next sibling link */
+ struct _xmlNode *prev; /* previous sibling link */
+ struct _xmlDoc *doc; /* the containing document */
+
+ xmlChar *orig; /* content without ref substitution */
+ xmlChar *content; /* content or ndata if unparsed */
+ int length; /* the content length */
+ xmlEntityType etype; /* The entity type */
+ const xmlChar *ExternalID; /* External identifier for PUBLIC */
+ const xmlChar *SystemID; /* URI for a SYSTEM or PUBLIC Entity */
+
+ struct _xmlEntity *nexte; /* unused */
+ const xmlChar *URI; /* the full URI as computed */
+ int owner; /* does the entity own the childrens */
+};
+
+/*
+ * All entities are stored in an hash table.
+ * There is 2 separate hash tables for global and parameter entities.
+ */
+
+typedef struct _xmlHashTable xmlEntitiesTable;
+typedef xmlEntitiesTable *xmlEntitiesTablePtr;
+
+/*
+ * External functions:
+ */
+
+void xmlInitializePredefinedEntities (void);
+xmlEntityPtr xmlAddDocEntity (xmlDocPtr doc,
+ const xmlChar *name,
+ int type,
+ const xmlChar *ExternalID,
+ const xmlChar *SystemID,
+ const xmlChar *content);
+xmlEntityPtr xmlAddDtdEntity (xmlDocPtr doc,
+ const xmlChar *name,
+ int type,
+ const xmlChar *ExternalID,
+ const xmlChar *SystemID,
+ const xmlChar *content);
+xmlEntityPtr xmlGetPredefinedEntity (const xmlChar *name);
+xmlEntityPtr xmlGetDocEntity (xmlDocPtr doc,
+ const xmlChar *name);
+xmlEntityPtr xmlGetDtdEntity (xmlDocPtr doc,
+ const xmlChar *name);
+xmlEntityPtr xmlGetParameterEntity (xmlDocPtr doc,
+ const xmlChar *name);
+const xmlChar * xmlEncodeEntities (xmlDocPtr doc,
+ const xmlChar *input);
+xmlChar * xmlEncodeEntitiesReentrant(xmlDocPtr doc,
+ const xmlChar *input);
+xmlChar * xmlEncodeSpecialChars (xmlDocPtr doc,
+ const xmlChar *input);
+xmlEntitiesTablePtr xmlCreateEntitiesTable (void);
+xmlEntitiesTablePtr xmlCopyEntitiesTable (xmlEntitiesTablePtr table);
+void xmlFreeEntitiesTable (xmlEntitiesTablePtr table);
+void xmlDumpEntitiesTable (xmlBufferPtr buf,
+ xmlEntitiesTablePtr table);
+void xmlDumpEntityDecl (xmlBufferPtr buf,
+ xmlEntityPtr ent);
+void xmlCleanupPredefinedEntities(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+# endif /* __XML_ENTITIES_H__ */
diff --git a/plugins/Variables/src/libxml/globals.h b/plugins/Variables/src/libxml/globals.h
new file mode 100644
index 0000000000..8a5e8c88e0
--- /dev/null
+++ b/plugins/Variables/src/libxml/globals.h
@@ -0,0 +1,363 @@
+/*
+ * globals.h: interface for all global variables of the library
+ *
+ * The bottom of this file is automatically generated by build_glob.py
+ * based on the description file global.data
+ *
+ * See Copyright for the status of this software.
+ *
+ * Gary Pennington <Gary.Pennington@uk.sun.com>
+ * daniel@veillard.com
+ */
+
+#ifndef __XML_GLOBALS_H
+#define __XML_GLOBALS_H
+
+#include "libxml/parser.h"
+#include "libxml/xmlerror.h"
+#include "libxml/SAX.h"
+#include "libxml/xmlmemory.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Externally global symbols which need to be protected for backwards
+ * compatibility support.
+ */
+
+#undef docbDefaultSAXHandler
+#undef htmlDefaultSAXHandler
+#undef oldXMLWDcompatibility
+#undef xmlBufferAllocScheme
+#undef xmlDefaultBufferSize
+#undef xmlDefaultSAXHandler
+#undef xmlDefaultSAXLocator
+#undef xmlDoValidityCheckingDefaultValue
+#undef xmlFree
+#undef xmlGenericError
+#undef xmlGenericErrorContext
+#undef xmlGetWarningsDefaultValue
+#undef xmlIndentTreeOutput
+#undef xmlTreeIndentString
+#undef xmlKeepBlanksDefaultValue
+#undef xmlLineNumbersDefaultValue
+#undef xmlLoadExtDtdDefaultValue
+#undef xmlMalloc
+#undef xmlMemStrdup
+#undef xmlParserDebugEntities
+#undef xmlParserVersion
+#undef xmlPedanticParserDefaultValue
+#undef xmlRealloc
+#undef xmlSaveNoEmptyTags
+#undef xmlSubstituteEntitiesDefaultValue
+#undef xmlRegisterNodeDefaultValue
+#undef xmlDeregisterNodeDefaultValue
+
+typedef void (*xmlRegisterNodeFunc) (xmlNodePtr node);
+typedef void (*xmlDeregisterNodeFunc) (xmlNodePtr node);
+
+typedef struct _xmlGlobalState xmlGlobalState;
+typedef xmlGlobalState *xmlGlobalStatePtr;
+struct _xmlGlobalState
+{
+ const char *xmlParserVersion;
+
+ xmlSAXLocator xmlDefaultSAXLocator;
+ xmlSAXHandler xmlDefaultSAXHandler;
+ xmlSAXHandler docbDefaultSAXHandler;
+ xmlSAXHandler htmlDefaultSAXHandler;
+
+ xmlFreeFunc xmlFree;
+ xmlMallocFunc xmlMalloc;
+ xmlStrdupFunc xmlMemStrdup;
+ xmlReallocFunc xmlRealloc;
+
+ xmlGenericErrorFunc xmlGenericError;
+ void *xmlGenericErrorContext;
+
+ int oldXMLWDcompatibility;
+
+ xmlBufferAllocationScheme xmlBufferAllocScheme;
+ int xmlDefaultBufferSize;
+
+ int xmlSubstituteEntitiesDefaultValue;
+ int xmlDoValidityCheckingDefaultValue;
+ int xmlGetWarningsDefaultValue;
+ int xmlKeepBlanksDefaultValue;
+ int xmlLineNumbersDefaultValue;
+ int xmlLoadExtDtdDefaultValue;
+ int xmlParserDebugEntities;
+ int xmlPedanticParserDefaultValue;
+
+ int xmlSaveNoEmptyTags;
+ int xmlIndentTreeOutput;
+ const char *xmlTreeIndentString;
+
+ xmlRegisterNodeFunc xmlRegisterNodeDefaultValue;
+ xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue;
+};
+
+#ifdef __cplusplus
+}
+#endif
+#include "libxml/threads.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void xmlInitializeGlobalState(xmlGlobalStatePtr gs);
+
+xmlRegisterNodeFunc xmlRegisterNodeDefault(xmlRegisterNodeFunc func);
+xmlDeregisterNodeFunc xmlDeregisterNodeDefault(xmlDeregisterNodeFunc func);
+
+/*
+ * In general the memory allocation entry points are not kept
+ * thread specific but this can be overridden by LIBXML_THREAD_ALLOC_ENABLED
+ * - xmlMalloc
+ * - xmlRealloc
+ * - xmlMemStrdup
+ * - xmlFree
+ */
+
+#ifdef LIBXML_THREAD_ALLOC_ENABLED
+#ifdef LIBXML_THREAD_ENABLED
+extern xmlMallocFunc *__xmlMalloc(void);
+#define xmlMalloc \
+(*(__xmlMalloc()))
+#else
+LIBXML_DLL_IMPORT extern xmlMallocFunc xmlMalloc;
+#endif
+
+#ifdef LIBXML_THREAD_ENABLED
+extern xmlReallocFunc *__xmlRealloc(void);
+#define xmlRealloc \
+(*(__xmlRealloc()))
+#else
+LIBXML_DLL_IMPORT extern xmlReallocFunc xmlRealloc;
+#endif
+
+#ifdef LIBXML_THREAD_ENABLED
+extern xmlFreeFunc *__xmlFree(void);
+#define xmlFree \
+(*(__xmlFree()))
+#else
+LIBXML_DLL_IMPORT extern xmlFreeFunc xmlFree;
+#endif
+
+#ifdef LIBXML_THREAD_ENABLED
+extern xmlStrdupFunc *__xmlMemStrdup(void);
+#define xmlMemStrdup \
+(*(__xmlMemStrdup()))
+#else
+LIBXML_DLL_IMPORT extern xmlStrdupFunc xmlMemStrdup;
+#endif
+#else /* !LIBXML_THREAD_ALLOC_ENABLED */
+LIBXML_DLL_IMPORT extern xmlMallocFunc xmlMalloc;
+LIBXML_DLL_IMPORT extern xmlReallocFunc xmlRealloc;
+LIBXML_DLL_IMPORT extern xmlFreeFunc xmlFree;
+LIBXML_DLL_IMPORT extern xmlStrdupFunc xmlMemStrdup;
+#endif /* LIBXML_THREAD_ALLOC_ENABLED */
+
+#ifdef LIBXML_DOCB_ENABLED
+extern xmlSAXHandler *__docbDefaultSAXHandler(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define docbDefaultSAXHandler \
+(*(__docbDefaultSAXHandler()))
+#else
+LIBXML_DLL_IMPORT extern xmlSAXHandler docbDefaultSAXHandler;
+#endif
+#endif
+
+#ifdef LIBXML_HTML_ENABLED
+extern xmlSAXHandler *__htmlDefaultSAXHandler(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define htmlDefaultSAXHandler \
+(*(__htmlDefaultSAXHandler()))
+#else
+LIBXML_DLL_IMPORT extern xmlSAXHandler htmlDefaultSAXHandler;
+#endif
+#endif
+
+
+/*
+ * Everything starting from the line below is
+ * Automatically generated by build_glob.py.
+ * Do not modify the previous line.
+ */
+
+
+extern int *__oldXMLWDcompatibility(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define oldXMLWDcompatibility \
+(*(__oldXMLWDcompatibility()))
+#else
+LIBXML_DLL_IMPORT extern int oldXMLWDcompatibility;
+#endif
+
+extern xmlBufferAllocationScheme *__xmlBufferAllocScheme(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlBufferAllocScheme \
+(*(__xmlBufferAllocScheme()))
+#else
+LIBXML_DLL_IMPORT extern xmlBufferAllocationScheme xmlBufferAllocScheme;
+#endif
+
+extern int *__xmlDefaultBufferSize(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlDefaultBufferSize \
+(*(__xmlDefaultBufferSize()))
+#else
+LIBXML_DLL_IMPORT extern int xmlDefaultBufferSize;
+#endif
+
+extern xmlSAXHandler *__xmlDefaultSAXHandler(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlDefaultSAXHandler \
+(*(__xmlDefaultSAXHandler()))
+#else
+LIBXML_DLL_IMPORT extern xmlSAXHandler xmlDefaultSAXHandler;
+#endif
+
+extern xmlSAXLocator *__xmlDefaultSAXLocator(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlDefaultSAXLocator \
+(*(__xmlDefaultSAXLocator()))
+#else
+LIBXML_DLL_IMPORT extern xmlSAXLocator xmlDefaultSAXLocator;
+#endif
+
+extern int *__xmlDoValidityCheckingDefaultValue(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlDoValidityCheckingDefaultValue \
+(*(__xmlDoValidityCheckingDefaultValue()))
+#else
+LIBXML_DLL_IMPORT extern int xmlDoValidityCheckingDefaultValue;
+#endif
+
+extern xmlGenericErrorFunc *__xmlGenericError(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlGenericError \
+(*(__xmlGenericError()))
+#else
+LIBXML_DLL_IMPORT extern xmlGenericErrorFunc xmlGenericError;
+#endif
+
+extern void * *__xmlGenericErrorContext(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlGenericErrorContext \
+(*(__xmlGenericErrorContext()))
+#else
+LIBXML_DLL_IMPORT extern void * xmlGenericErrorContext;
+#endif
+
+extern int *__xmlGetWarningsDefaultValue(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlGetWarningsDefaultValue \
+(*(__xmlGetWarningsDefaultValue()))
+#else
+LIBXML_DLL_IMPORT extern int xmlGetWarningsDefaultValue;
+#endif
+
+extern int *__xmlIndentTreeOutput(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlIndentTreeOutput \
+(*(__xmlIndentTreeOutput()))
+#else
+LIBXML_DLL_IMPORT extern int xmlIndentTreeOutput;
+#endif
+
+extern const char * *__xmlTreeIndentString(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlTreeIndentString \
+(*(__xmlTreeIndentString()))
+#else
+LIBXML_DLL_IMPORT extern const char * xmlTreeIndentString;
+#endif
+
+extern int *__xmlKeepBlanksDefaultValue(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlKeepBlanksDefaultValue \
+(*(__xmlKeepBlanksDefaultValue()))
+#else
+LIBXML_DLL_IMPORT extern int xmlKeepBlanksDefaultValue;
+#endif
+
+extern int *__xmlLineNumbersDefaultValue(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlLineNumbersDefaultValue \
+(*(__xmlLineNumbersDefaultValue()))
+#else
+LIBXML_DLL_IMPORT extern int xmlLineNumbersDefaultValue;
+#endif
+
+extern int *__xmlLoadExtDtdDefaultValue(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlLoadExtDtdDefaultValue \
+(*(__xmlLoadExtDtdDefaultValue()))
+#else
+LIBXML_DLL_IMPORT extern int xmlLoadExtDtdDefaultValue;
+#endif
+
+extern int *__xmlParserDebugEntities(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlParserDebugEntities \
+(*(__xmlParserDebugEntities()))
+#else
+LIBXML_DLL_IMPORT extern int xmlParserDebugEntities;
+#endif
+
+extern const char * *__xmlParserVersion(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlParserVersion \
+(*(__xmlParserVersion()))
+#else
+LIBXML_DLL_IMPORT extern const char * xmlParserVersion;
+#endif
+
+extern int *__xmlPedanticParserDefaultValue(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlPedanticParserDefaultValue \
+(*(__xmlPedanticParserDefaultValue()))
+#else
+LIBXML_DLL_IMPORT extern int xmlPedanticParserDefaultValue;
+#endif
+
+extern int *__xmlSaveNoEmptyTags(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlSaveNoEmptyTags \
+(*(__xmlSaveNoEmptyTags()))
+#else
+LIBXML_DLL_IMPORT extern int xmlSaveNoEmptyTags;
+#endif
+
+extern int *__xmlSubstituteEntitiesDefaultValue(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlSubstituteEntitiesDefaultValue \
+(*(__xmlSubstituteEntitiesDefaultValue()))
+#else
+LIBXML_DLL_IMPORT extern int xmlSubstituteEntitiesDefaultValue;
+#endif
+
+extern xmlRegisterNodeFunc *__xmlRegisterNodeDefaultValue(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlRegisterNodeDefaultValue \
+(*(__xmlRegisterNodeDefaultValue()))
+#else
+LIBXML_DLL_IMPORT extern xmlRegisterNodeFunc xmlRegisterNodeDefaultValue;
+#endif
+
+extern xmlDeregisterNodeFunc *__xmlDeregisterNodeDefaultValue(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlDeregisterNodeDefaultValue \
+(*(__xmlDeregisterNodeDefaultValue()))
+#else
+LIBXML_DLL_IMPORT extern xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_GLOBALS_H */
diff --git a/plugins/Variables/src/libxml/hash.h b/plugins/Variables/src/libxml/hash.h
new file mode 100644
index 0000000000..24c5f214c3
--- /dev/null
+++ b/plugins/Variables/src/libxml/hash.h
@@ -0,0 +1,166 @@
+/*
+ * hash.h: chained hash tables
+ *
+ * Copyright (C) 2000 Bjorn Reese and Daniel Veillard.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
+ * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
+ *
+ * Author: bjorn.reese@systematic.dk
+ */
+
+#ifndef __XML_HASH_H__
+#define __XML_HASH_H__
+
+#include "libxml/parser.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The hash table.
+ */
+typedef struct _xmlHashTable xmlHashTable;
+typedef xmlHashTable *xmlHashTablePtr;
+
+/*
+ * function types:
+ */
+/**
+ * xmlHashDeallocator:
+ * @payload: the data in the hash
+ * @name: the name associated
+ *
+ * Callback to free data from a hash.
+ */
+typedef void (*xmlHashDeallocator)(void *payload, xmlChar *name);
+/**
+ * xmlHashCopier:
+ * @payload: the data in the hash
+ * @name: the name associated
+ *
+ * Callback to copy data from a hash.
+ *
+ * Returns a copy of the data or NULL in case of error.
+ */
+typedef void *(*xmlHashCopier)(void *payload, xmlChar *name);
+/**
+ * xmlHashScanner:
+ * @payload: the data in the hash
+ * @data: extra scannner data
+ * @name: the name associated
+ *
+ * Callback when scanning data in a hash with the simple scanner.
+ */
+typedef void (*xmlHashScanner)(void *payload, void *data, xmlChar *name);
+/**
+ * xmlHashScannerFull:
+ * @payload: the data in the hash
+ * @data: extra scannner data
+ * @name: the name associated
+ * @name2: the second name associated
+ * @name3: the third name associated
+ *
+ * Callback when scanning data in a hash with the full scanner.
+ */
+typedef void (*xmlHashScannerFull)(void *payload, void *data,
+ const xmlChar *name, const xmlChar *name2,
+ const xmlChar *name3);
+
+/*
+ * Constructor and destructor.
+ */
+xmlHashTablePtr xmlHashCreate (int size);
+void xmlHashFree (xmlHashTablePtr table,
+ xmlHashDeallocator f);
+
+/*
+ * Add a new entry to the hash table.
+ */
+int xmlHashAddEntry (xmlHashTablePtr table,
+ const xmlChar *name,
+ void *userdata);
+int xmlHashUpdateEntry(xmlHashTablePtr table,
+ const xmlChar *name,
+ void *userdata,
+ xmlHashDeallocator f);
+int xmlHashAddEntry2(xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2,
+ void *userdata);
+int xmlHashUpdateEntry2(xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2,
+ void *userdata,
+ xmlHashDeallocator f);
+int xmlHashAddEntry3(xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2,
+ const xmlChar *name3,
+ void *userdata);
+int xmlHashUpdateEntry3(xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2,
+ const xmlChar *name3,
+ void *userdata,
+ xmlHashDeallocator f);
+
+/*
+ * Remove an entry from the hash table.
+ */
+int xmlHashRemoveEntry(xmlHashTablePtr table, const xmlChar *name,
+ xmlHashDeallocator f);
+int xmlHashRemoveEntry2(xmlHashTablePtr table, const xmlChar *name,
+ const xmlChar *name2, xmlHashDeallocator f);
+int xmlHashRemoveEntry3(xmlHashTablePtr table, const xmlChar *name,
+ const xmlChar *name2, const xmlChar *name3,
+ xmlHashDeallocator f);
+
+/*
+ * Retrieve the userdata.
+ */
+void * xmlHashLookup (xmlHashTablePtr table,
+ const xmlChar *name);
+void * xmlHashLookup2 (xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2);
+void * xmlHashLookup3 (xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2,
+ const xmlChar *name3);
+
+/*
+ * Helpers.
+ */
+xmlHashTablePtr xmlHashCopy (xmlHashTablePtr table,
+ xmlHashCopier f);
+int xmlHashSize (xmlHashTablePtr table);
+void xmlHashScan (xmlHashTablePtr table,
+ xmlHashScanner f,
+ void *data);
+void xmlHashScan3 (xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2,
+ const xmlChar *name3,
+ xmlHashScanner f,
+ void *data);
+void xmlHashScanFull (xmlHashTablePtr table,
+ xmlHashScannerFull f,
+ void *data);
+void xmlHashScanFull3(xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2,
+ const xmlChar *name3,
+ xmlHashScannerFull f,
+ void *data);
+#ifdef __cplusplus
+}
+#endif
+#endif /* ! __XML_HASH_H__ */
diff --git a/plugins/Variables/src/libxml/list.h b/plugins/Variables/src/libxml/list.h
new file mode 100644
index 0000000000..8c9515fe1d
--- /dev/null
+++ b/plugins/Variables/src/libxml/list.h
@@ -0,0 +1,116 @@
+/*
+ * list.h: lists interfaces
+ *
+ * Copyright (C) 2000 Gary Pennington and Daniel Veillard.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
+ * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
+ *
+ * Author: Gary.Pennington@uk.sun.com
+ */
+
+#ifndef __XML_LINK_INCLUDE__
+#define __XML_LINK_INCLUDE__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _xmlLink xmlLink;
+typedef xmlLink *xmlLinkPtr;
+
+typedef struct _xmlList xmlList;
+typedef xmlList *xmlListPtr;
+
+/**
+ * xmlListDeallocator:
+ * @lk: the data to deallocate
+ *
+ * Callback function used to free data from a list.
+ */
+typedef void (*xmlListDeallocator) (xmlLinkPtr lk);
+/**
+ * xmlListDataCompare:
+ * @data0: the first data
+ * @data1: the second data
+ *
+ * Callback function used to compare 2 data.
+ *
+ * Returns 0 is equality, -1 or 1 otherwise depending on the ordering.
+ */
+typedef int (*xmlListDataCompare) (const void *data0, const void *data1);
+/**
+ * xmlListWalker:
+ * @data: the data found in the list
+ * @user: extra user provided data to the walker
+ *
+ * Callback function used when walking a list with xmlListWalk().
+ *
+ * Returns 0 to stop walking the list, 1 otherwise.
+ */
+typedef int (*xmlListWalker) (const void *data, const void *user);
+
+/* Creation/Deletion */
+xmlListPtr xmlListCreate (xmlListDeallocator deallocator,
+ xmlListDataCompare compare);
+void xmlListDelete (xmlListPtr l);
+
+/* Basic Operators */
+void * xmlListSearch (xmlListPtr l,
+ void *data);
+void * xmlListReverseSearch (xmlListPtr l,
+ void *data);
+int xmlListInsert (xmlListPtr l,
+ void *data) ;
+int xmlListAppend (xmlListPtr l,
+ void *data) ;
+int xmlListRemoveFirst (xmlListPtr l,
+ void *data);
+int xmlListRemoveLast (xmlListPtr l,
+ void *data);
+int xmlListRemoveAll (xmlListPtr l,
+ void *data);
+void xmlListClear (xmlListPtr l);
+int xmlListEmpty (xmlListPtr l);
+xmlLinkPtr xmlListFront (xmlListPtr l);
+xmlLinkPtr xmlListEnd (xmlListPtr l);
+int xmlListSize (xmlListPtr l);
+
+void xmlListPopFront (xmlListPtr l);
+void xmlListPopBack (xmlListPtr l);
+int xmlListPushFront (xmlListPtr l,
+ void *data);
+int xmlListPushBack (xmlListPtr l,
+ void *data);
+
+/* Advanced Operators */
+void xmlListReverse (xmlListPtr l);
+void xmlListSort (xmlListPtr l);
+void xmlListWalk (xmlListPtr l,
+ xmlListWalker walker,
+ const void *user);
+void xmlListReverseWalk (xmlListPtr l,
+ xmlListWalker walker,
+ const void *user);
+void xmlListMerge (xmlListPtr l1,
+ xmlListPtr l2);
+xmlListPtr xmlListDup (const xmlListPtr old);
+int xmlListCopy (xmlListPtr cur,
+ const xmlListPtr old);
+/* Link operators */
+void * xmlLinkGetData (xmlLinkPtr lk);
+
+/* xmlListUnique() */
+/* xmlListSwap */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_LINK_INCLUDE__ */
diff --git a/plugins/Variables/src/libxml/nanoftp.h b/plugins/Variables/src/libxml/nanoftp.h
new file mode 100644
index 0000000000..a0ba2ceeb3
--- /dev/null
+++ b/plugins/Variables/src/libxml/nanoftp.h
@@ -0,0 +1,117 @@
+/*
+ * nanohttp.c: minimalist FTP implementation to fetch external subsets.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifndef __NANO_FTP_H__
+#define __NANO_FTP_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_FTP_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * ftpListCallback:
+ * @userData: user provided data for the callback
+ * @filename: the file name (including "->" when links are shown)
+ * @attrib: the attribute string
+ * @owner: the owner string
+ * @group: the group string
+ * @size: the file size
+ * @links: the link count
+ * @year: the year
+ * @month: the month
+ * @day: the day
+ * @hour: the hour
+ * @minute: the minute
+ *
+ * A callback for the xmlNanoFTPList command.
+ * Note that only one of year and day:minute are specified.
+ */
+typedef void (*ftpListCallback) (void *userData,
+ const char *filename, const char *attrib,
+ const char *owner, const char *group,
+ unsigned long size, int links, int year,
+ const char *month, int day, int hour,
+ int minute);
+/**
+ * ftpDataCallback:
+ * @userData: the user provided context
+ * @data: the data received
+ * @len: its size in bytes
+ *
+ * A callback for the xmlNanoFTPGet command.
+ */
+typedef void (*ftpDataCallback) (void *userData,
+ const char *data,
+ int len);
+
+/*
+ * Init
+ */
+void xmlNanoFTPInit (void);
+void xmlNanoFTPCleanup (void);
+
+/*
+ * Creating/freeing contexts.
+ */
+void * xmlNanoFTPNewCtxt (const char *URL);
+void xmlNanoFTPFreeCtxt (void * ctx);
+void * xmlNanoFTPConnectTo (const char *server,
+ int port);
+/*
+ * Opening/closing session connections.
+ */
+void * xmlNanoFTPOpen (const char *URL);
+int xmlNanoFTPConnect (void *ctx);
+int xmlNanoFTPClose (void *ctx);
+int xmlNanoFTPQuit (void *ctx);
+void xmlNanoFTPScanProxy (const char *URL);
+void xmlNanoFTPProxy (const char *host,
+ int port,
+ const char *user,
+ const char *passwd,
+ int type);
+int xmlNanoFTPUpdateURL (void *ctx,
+ const char *URL);
+
+/*
+ * Rather internal commands.
+ */
+int xmlNanoFTPGetResponse (void *ctx);
+int xmlNanoFTPCheckResponse (void *ctx);
+
+/*
+ * CD/DIR/GET handlers.
+ */
+int xmlNanoFTPCwd (void *ctx,
+ char *directory);
+
+int xmlNanoFTPGetConnection (void *ctx);
+int xmlNanoFTPCloseConnection(void *ctx);
+int xmlNanoFTPList (void *ctx,
+ ftpListCallback callback,
+ void *userData,
+ char *filename);
+int xmlNanoFTPGetSocket (void *ctx,
+ const char *filename);
+int xmlNanoFTPGet (void *ctx,
+ ftpDataCallback callback,
+ void *userData,
+ const char *filename);
+int xmlNanoFTPRead (void *ctx,
+ void *dest,
+ int len);
+
+#ifdef __cplusplus
+}
+#endif /* LIBXML_FTP_ENABLED */
+#endif
+#endif /* __NANO_FTP_H__ */
diff --git a/plugins/Variables/src/libxml/nanohttp.h b/plugins/Variables/src/libxml/nanohttp.h
new file mode 100644
index 0000000000..4fb4e1d256
--- /dev/null
+++ b/plugins/Variables/src/libxml/nanohttp.h
@@ -0,0 +1,56 @@
+/*
+ * nanohttp.c: minimalist HTTP implementation to fetch external subsets.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifndef __NANO_HTTP_H__
+#define __NANO_HTTP_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_HTTP_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void xmlNanoHTTPInit (void);
+void xmlNanoHTTPCleanup (void);
+void xmlNanoHTTPScanProxy (const char *URL);
+int xmlNanoHTTPFetch (const char *URL,
+ const char *filename,
+ char **contentType);
+void * xmlNanoHTTPMethod (const char *URL,
+ const char *method,
+ const char *input,
+ char **contentType,
+ const char *headers,
+ int ilen);
+void * xmlNanoHTTPMethodRedir (const char *URL,
+ const char *method,
+ const char *input,
+ char **contentType,
+ char **redir,
+ const char *headers,
+ int ilen);
+void * xmlNanoHTTPOpen (const char *URL,
+ char **contentType);
+void * xmlNanoHTTPOpenRedir (const char *URL,
+ char **contentType,
+ char **redir);
+int xmlNanoHTTPReturnCode (void *ctx);
+const char * xmlNanoHTTPAuthHeader(void *ctx);
+int xmlNanoHTTPRead (void *ctx,
+ void *dest,
+ int len);
+int xmlNanoHTTPSave (void *ctxt,
+ const char *filename);
+void xmlNanoHTTPClose (void *ctx);
+#ifdef __cplusplus
+}
+
+#endif /* LIBXML_HTTP_ENABLED */
+#endif
+#endif /* __NANO_HTTP_H__ */
diff --git a/plugins/Variables/src/libxml/parser.h b/plugins/Variables/src/libxml/parser.h
new file mode 100644
index 0000000000..ac98f4b944
--- /dev/null
+++ b/plugins/Variables/src/libxml/parser.h
@@ -0,0 +1,869 @@
+/*
+ * parser.h : Interfaces, constants and types related to the XML parser.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifndef __XML_PARSER_H__
+#define __XML_PARSER_H__
+
+#include "libxml/tree.h"
+#include "libxml/valid.h"
+#include "libxml/entities.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * XML_DEFAULT_VERSION:
+ *
+ * The default version of XML used: 1.0
+ */
+#define XML_DEFAULT_VERSION "1.0"
+
+/**
+ * xmlParserInput:
+ *
+ * An xmlParserInput is an input flow for the XML processor.
+ * Each entity parsed is associated an xmlParserInput (except the
+ * few predefined ones). This is the case both for internal entities
+ * - in which case the flow is already completely in memory - or
+ * external entities - in which case we use the buf structure for
+ * progressive reading and I18N conversions to the internal UTF-8 format.
+ */
+
+/**
+ * xmlParserInputDeallocate:
+ * @str: the string to deallocate
+ *
+ * Callback for freeing some parser input allocations.
+ */
+typedef void (* xmlParserInputDeallocate)(xmlChar *str);
+
+struct _xmlParserInput {
+ /* Input buffer */
+ xmlParserInputBufferPtr buf; /* UTF-8 encoded buffer */
+
+ const char *filename; /* The file analyzed, if any */
+ const char *directory; /* the directory/base of the file */
+ const xmlChar *base; /* Base of the array to parse */
+ const xmlChar *cur; /* Current char being parsed */
+ const xmlChar *end; /* end of the array to parse */
+ int length; /* length if known */
+ int line; /* Current line */
+ int col; /* Current column */
+ int consumed; /* How many xmlChars already consumed */
+ xmlParserInputDeallocate free; /* function to deallocate the base */
+ const xmlChar *encoding; /* the encoding string for entity */
+ const xmlChar *version; /* the version string for entity */
+ int standalone; /* Was that entity marked standalone */
+};
+
+/**
+ * xmlParserNodeInfo:
+ *
+ * The parser can be asked to collect Node informations, i.e. at what
+ * place in the file they were detected.
+ * NOTE: This is off by default and not very well tested.
+ */
+typedef struct _xmlParserNodeInfo xmlParserNodeInfo;
+typedef xmlParserNodeInfo *xmlParserNodeInfoPtr;
+
+struct _xmlParserNodeInfo {
+ const struct _xmlNode* node;
+ /* Position & line # that text that created the node begins & ends on */
+ unsigned long begin_pos;
+ unsigned long begin_line;
+ unsigned long end_pos;
+ unsigned long end_line;
+};
+
+typedef struct _xmlParserNodeInfoSeq xmlParserNodeInfoSeq;
+typedef xmlParserNodeInfoSeq *xmlParserNodeInfoSeqPtr;
+struct _xmlParserNodeInfoSeq {
+ unsigned long maximum;
+ unsigned long length;
+ xmlParserNodeInfo* buffer;
+};
+
+/**
+ * xmlParserInputState:
+ *
+ * The parser is now working also as a state based parser.
+ * The recursive one use the state info for entities processing.
+ */
+typedef enum {
+ XML_PARSER_EOF = -1, /* nothing is to be parsed */
+ XML_PARSER_START = 0, /* nothing has been parsed */
+ XML_PARSER_MISC, /* Misc* before int subset */
+ XML_PARSER_PI, /* Within a processing instruction */
+ XML_PARSER_DTD, /* within some DTD content */
+ XML_PARSER_PROLOG, /* Misc* after internal subset */
+ XML_PARSER_COMMENT, /* within a comment */
+ XML_PARSER_START_TAG, /* within a start tag */
+ XML_PARSER_CONTENT, /* within the content */
+ XML_PARSER_CDATA_SECTION, /* within a CDATA section */
+ XML_PARSER_END_TAG, /* within a closing tag */
+ XML_PARSER_ENTITY_DECL, /* within an entity declaration */
+ XML_PARSER_ENTITY_VALUE, /* within an entity value in a decl */
+ XML_PARSER_ATTRIBUTE_VALUE, /* within an attribute value */
+ XML_PARSER_SYSTEM_LITERAL, /* within a SYSTEM value */
+ XML_PARSER_EPILOG, /* the Misc* after the last end tag */
+ XML_PARSER_IGNORE, /* within an IGNORED section */
+ XML_PARSER_PUBLIC_LITERAL /* within a PUBLIC value */
+} xmlParserInputState;
+
+/**
+ * XML_DETECT_IDS:
+ *
+ * Bit in the loadsubset context field to tell to do ID/REFs lookups.
+ * Use it to initialize xmlLoadExtDtdDefaultValue.
+ */
+#define XML_DETECT_IDS 2
+
+/**
+ * XML_COMPLETE_ATTRS:
+ *
+ * Bit in the loadsubset context field to tell to do complete the
+ * elements attributes lists with the ones defaulted from the DTDs.
+ * Use it to initialize xmlLoadExtDtdDefaultValue.
+ */
+#define XML_COMPLETE_ATTRS 4
+
+/**
+ * xmlParserCtxt:
+ *
+ * The parser context.
+ * NOTE This doesn't completely define the parser state, the (current ?)
+ * design of the parser uses recursive function calls since this allow
+ * and easy mapping from the production rules of the specification
+ * to the actual code. The drawback is that the actual function call
+ * also reflect the parser state. However most of the parsing routines
+ * takes as the only argument the parser context pointer, so migrating
+ * to a state based parser for progressive parsing shouldn't be too hard.
+ */
+struct _xmlParserCtxt {
+ struct _xmlSAXHandler *sax; /* The SAX handler */
+ void *userData; /* For SAX interface only, used by DOM build */
+ xmlDocPtr myDoc; /* the document being built */
+ int wellFormed; /* is the document well formed */
+ int replaceEntities; /* shall we replace entities ? */
+ const xmlChar *version; /* the XML version string */
+ const xmlChar *encoding; /* the declared encoding, if any */
+ int standalone; /* standalone document */
+ int html; /* an HTML(1)/Docbook(2) document */
+
+ /* Input stream stack */
+ xmlParserInputPtr input; /* Current input stream */
+ int inputNr; /* Number of current input streams */
+ int inputMax; /* Max number of input streams */
+ xmlParserInputPtr *inputTab; /* stack of inputs */
+
+ /* Node analysis stack only used for DOM building */
+ xmlNodePtr node; /* Current parsed Node */
+ int nodeNr; /* Depth of the parsing stack */
+ int nodeMax; /* Max depth of the parsing stack */
+ xmlNodePtr *nodeTab; /* array of nodes */
+
+ int record_info; /* Whether node info should be kept */
+ xmlParserNodeInfoSeq node_seq; /* info about each node parsed */
+
+ int errNo; /* error code */
+
+ int hasExternalSubset; /* reference and external subset */
+ int hasPErefs; /* the internal subset has PE refs */
+ int external; /* are we parsing an external entity */
+
+ int valid; /* is the document valid */
+ int validate; /* shall we try to validate ? */
+ xmlValidCtxt vctxt; /* The validity context */
+
+ xmlParserInputState instate; /* current type of input */
+ int token; /* next char look-ahead */
+
+ char *directory; /* the data directory */
+
+ /* Node name stack */
+ xmlChar *name; /* Current parsed Node */
+ int nameNr; /* Depth of the parsing stack */
+ int nameMax; /* Max depth of the parsing stack */
+ xmlChar * *nameTab; /* array of nodes */
+
+ long nbChars; /* number of xmlChar processed */
+ long checkIndex; /* used by progressive parsing lookup */
+ int keepBlanks; /* ugly but ... */
+ int disableSAX; /* SAX callbacks are disabled */
+ int inSubset; /* Parsing is in int 1/ext 2 subset */
+ xmlChar * intSubName; /* name of subset */
+ xmlChar * extSubURI; /* URI of external subset */
+ xmlChar * extSubSystem; /* SYSTEM ID of external subset */
+
+ /* xml:space values */
+ int * space; /* Should the parser preserve spaces */
+ int spaceNr; /* Depth of the parsing stack */
+ int spaceMax; /* Max depth of the parsing stack */
+ int * spaceTab; /* array of space infos */
+
+ int depth; /* to prevent entity substitution loops */
+ xmlParserInputPtr entity; /* used to check entities boundaries */
+ int charset; /* encoding of the in-memory content
+ actually an xmlCharEncoding */
+ int nodelen; /* Those two fields are there to */
+ int nodemem; /* Speed up large node parsing */
+ int pedantic; /* signal pedantic warnings */
+ void *_private; /* For user data, libxml won't touch it */
+
+ int loadsubset; /* should the external subset be loaded */
+ int linenumbers; /* set line number in element content */
+ void *catalogs; /* document's own catalog */
+ int recovery; /* run in recovery mode */
+};
+
+/**
+ * xmlSAXLocator:
+ *
+ * A SAX Locator.
+ */
+struct _xmlSAXLocator {
+ const xmlChar *(*getPublicId)(void *ctx);
+ const xmlChar *(*getSystemId)(void *ctx);
+ int (*getLineNumber)(void *ctx);
+ int (*getColumnNumber)(void *ctx);
+};
+
+/**
+ * xmlSAXHandler:
+ *
+ * A SAX handler is bunch of callbacks called by the parser when processing
+ * of the input generate data or structure informations.
+ */
+
+/**
+ * resolveEntitySAXFunc:
+ * @ctx: the user data (XML parser context)
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ *
+ * Callback:
+ * The entity loader, to control the loading of external entities,
+ * the application can either:
+ * - override this resolveEntity() callback in the SAX block
+ * - or better use the xmlSetExternalEntityLoader() function to
+ * set up it's own entity resolution routine
+ *
+ * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
+ */
+typedef xmlParserInputPtr (*resolveEntitySAXFunc) (void *ctx,
+ const xmlChar *publicId,
+ const xmlChar *systemId);
+/**
+ * internalSubsetSAXFunc:
+ * @ctx: the user data (XML parser context)
+ * @name: the root element name
+ * @ExternalID: the external ID
+ * @SystemID: the SYSTEM ID (e.g. filename or URL)
+ *
+ * Callback on internal subset declaration.
+ */
+typedef void (*internalSubsetSAXFunc) (void *ctx,
+ const xmlChar *name,
+ const xmlChar *ExternalID,
+ const xmlChar *SystemID);
+/**
+ * externalSubsetSAXFunc:
+ * @ctx: the user data (XML parser context)
+ * @name: the root element name
+ * @ExternalID: the external ID
+ * @SystemID: the SYSTEM ID (e.g. filename or URL)
+ *
+ * Callback on external subset declaration.
+ */
+typedef void (*externalSubsetSAXFunc) (void *ctx,
+ const xmlChar *name,
+ const xmlChar *ExternalID,
+ const xmlChar *SystemID);
+/**
+ * getEntitySAXFunc:
+ * @ctx: the user data (XML parser context)
+ * @name: The entity name
+ *
+ * Get an entity by name.
+ *
+ * Returns the xmlEntityPtr if found.
+ */
+typedef xmlEntityPtr (*getEntitySAXFunc) (void *ctx,
+ const xmlChar *name);
+/**
+ * getParameterEntitySAXFunc:
+ * @ctx: the user data (XML parser context)
+ * @name: The entity name
+ *
+ * Get a parameter entity by name.
+ *
+ * Returns the xmlEntityPtr if found.
+ */
+typedef xmlEntityPtr (*getParameterEntitySAXFunc) (void *ctx,
+ const xmlChar *name);
+/**
+ * entityDeclSAXFunc:
+ * @ctx: the user data (XML parser context)
+ * @name: the entity name
+ * @type: the entity type
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ * @content: the entity value (without processing).
+ *
+ * An entity definition has been parsed.
+ */
+typedef void (*entityDeclSAXFunc) (void *ctx,
+ const xmlChar *name,
+ int type,
+ const xmlChar *publicId,
+ const xmlChar *systemId,
+ xmlChar *content);
+/**
+ * notationDeclSAXFunc:
+ * @ctx: the user data (XML parser context)
+ * @name: The name of the notation
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ *
+ * What to do when a notation declaration has been parsed.
+ */
+typedef void (*notationDeclSAXFunc)(void *ctx,
+ const xmlChar *name,
+ const xmlChar *publicId,
+ const xmlChar *systemId);
+/**
+ * attributeDeclSAXFunc:
+ * @ctx: the user data (XML parser context)
+ * @elem: the name of the element
+ * @fullname: the attribute name
+ * @type: the attribute type
+ * @def: the type of default value
+ * @defaultValue: the attribute default value
+ * @tree: the tree of enumerated value set
+ *
+ * An attribute definition has been parsed.
+ */
+typedef void (*attributeDeclSAXFunc)(void *ctx,
+ const xmlChar *elem,
+ const xmlChar *fullname,
+ int type,
+ int def,
+ const xmlChar *defaultValue,
+ xmlEnumerationPtr tree);
+/**
+ * elementDeclSAXFunc:
+ * @ctx: the user data (XML parser context)
+ * @name: the element name
+ * @type: the element type
+ * @content: the element value tree
+ *
+ * An element definition has been parsed.
+ */
+typedef void (*elementDeclSAXFunc)(void *ctx,
+ const xmlChar *name,
+ int type,
+ xmlElementContentPtr content);
+/**
+ * unparsedEntityDeclSAXFunc:
+ * @ctx: the user data (XML parser context)
+ * @name: The name of the entity
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ * @notationName: the name of the notation
+ *
+ * What to do when an unparsed entity declaration is parsed.
+ */
+typedef void (*unparsedEntityDeclSAXFunc)(void *ctx,
+ const xmlChar *name,
+ const xmlChar *publicId,
+ const xmlChar *systemId,
+ const xmlChar *notationName);
+/**
+ * setDocumentLocatorSAXFunc:
+ * @ctx: the user data (XML parser context)
+ * @loc: A SAX Locator
+ *
+ * Receive the document locator at startup, actually xmlDefaultSAXLocator.
+ * Everything is available on the context, so this is useless in our case.
+ */
+typedef void (*setDocumentLocatorSAXFunc) (void *ctx,
+ xmlSAXLocatorPtr loc);
+/**
+ * startDocumentSAXFunc:
+ * @ctx: the user data (XML parser context)
+ *
+ * Called when the document start being processed.
+ */
+typedef void (*startDocumentSAXFunc) (void *ctx);
+/**
+ * endDocumentSAXFunc:
+ * @ctx: the user data (XML parser context)
+ *
+ * Called when the document end has been detected.
+ */
+typedef void (*endDocumentSAXFunc) (void *ctx);
+/**
+ * startElementSAXFunc:
+ * @ctx: the user data (XML parser context)
+ * @name: The element name, including namespace prefix
+ * @atts: An array of name/value attributes pairs, NULL terminated
+ *
+ * Called when an opening tag has been processed.
+ */
+typedef void (*startElementSAXFunc) (void *ctx,
+ const xmlChar *name,
+ const xmlChar **atts);
+/**
+ * endElementSAXFunc:
+ * @ctx: the user data (XML parser context)
+ * @name: The element name
+ *
+ * Called when the end of an element has been detected.
+ */
+typedef void (*endElementSAXFunc) (void *ctx,
+ const xmlChar *name);
+/**
+ * attributeSAXFunc:
+ * @ctx: the user data (XML parser context)
+ * @name: The attribute name, including namespace prefix
+ * @value: The attribute value
+ *
+ * Handle an attribute that has been read by the parser.
+ * The default handling is to convert the attribute into an
+ * DOM subtree and past it in a new xmlAttr element added to
+ * the element.
+ */
+typedef void (*attributeSAXFunc) (void *ctx,
+ const xmlChar *name,
+ const xmlChar *value);
+/**
+ * referenceSAXFunc:
+ * @ctx: the user data (XML parser context)
+ * @name: The entity name
+ *
+ * Called when an entity reference is detected.
+ */
+typedef void (*referenceSAXFunc) (void *ctx,
+ const xmlChar *name);
+/**
+ * charactersSAXFunc:
+ * @ctx: the user data (XML parser context)
+ * @ch: a xmlChar string
+ * @len: the number of xmlChar
+ *
+ * Receiving some chars from the parser.
+ */
+typedef void (*charactersSAXFunc) (void *ctx,
+ const xmlChar *ch,
+ int len);
+/**
+ * ignorableWhitespaceSAXFunc:
+ * @ctx: the user data (XML parser context)
+ * @ch: a xmlChar string
+ * @len: the number of xmlChar
+ *
+ * Receiving some ignorable whitespaces from the parser.
+ * UNUSED: by default the DOM building will use characters.
+ */
+typedef void (*ignorableWhitespaceSAXFunc) (void *ctx,
+ const xmlChar *ch,
+ int len);
+/**
+ * processingInstructionSAXFunc:
+ * @ctx: the user data (XML parser context)
+ * @target: the target name
+ * @data: the PI data's
+ *
+ * A processing instruction has been parsed.
+ */
+typedef void (*processingInstructionSAXFunc) (void *ctx,
+ const xmlChar *target,
+ const xmlChar *data);
+/**
+ * commentSAXFunc:
+ * @ctx: the user data (XML parser context)
+ * @value: the comment content
+ *
+ * A comment has been parsed.
+ */
+typedef void (*commentSAXFunc) (void *ctx,
+ const xmlChar *value);
+/**
+ * cdataBlockSAXFunc:
+ * @ctx: the user data (XML parser context)
+ * @value: The pcdata content
+ * @len: the block length
+ *
+ * Called when a pcdata block has been parsed.
+ */
+typedef void (*cdataBlockSAXFunc) (
+ void *ctx,
+ const xmlChar *value,
+ int len);
+/**
+ * warningSAXFunc:
+ * @ctx: an XML parser context
+ * @msg: the message to display/transmit
+ * @...: extra parameters for the message display
+ *
+ * Display and format a warning messages, callback.
+ */
+typedef void (*warningSAXFunc) (void *ctx,
+ const char *msg, ...);
+/**
+ * errorSAXFunc:
+ * @ctx: an XML parser context
+ * @msg: the message to display/transmit
+ * @...: extra parameters for the message display
+ *
+ * Display and format an error messages, callback.
+ */
+typedef void (*errorSAXFunc) (void *ctx,
+ const char *msg, ...);
+/**
+ * fatalErrorSAXFunc:
+ * @ctx: an XML parser context
+ * @msg: the message to display/transmit
+ * @...: extra parameters for the message display
+ *
+ * Display and format fatal error messages, callback.
+ * Note: so far fatalError() SAX callbacks are not used, error()
+ * get all the callbacks for errors.
+ */
+typedef void (*fatalErrorSAXFunc) (void *ctx,
+ const char *msg, ...);
+/**
+ * isStandaloneSAXFunc:
+ * @ctx: the user data (XML parser context)
+ *
+ * Is this document tagged standalone?
+ *
+ * Returns 1 if true
+ */
+typedef int (*isStandaloneSAXFunc) (void *ctx);
+/**
+ * hasInternalSubsetSAXFunc:
+ * @ctx: the user data (XML parser context)
+ *
+ * Does this document has an internal subset.
+ *
+ * Returns 1 if true
+ */
+typedef int (*hasInternalSubsetSAXFunc) (void *ctx);
+/**
+ * hasExternalSubsetSAXFunc:
+ * @ctx: the user data (XML parser context)
+ *
+ * Does this document has an external subset?
+ *
+ * Returns 1 if true
+ */
+typedef int (*hasExternalSubsetSAXFunc) (void *ctx);
+
+struct _xmlSAXHandler {
+ internalSubsetSAXFunc internalSubset;
+ isStandaloneSAXFunc isStandalone;
+ hasInternalSubsetSAXFunc hasInternalSubset;
+ hasExternalSubsetSAXFunc hasExternalSubset;
+ resolveEntitySAXFunc resolveEntity;
+ getEntitySAXFunc getEntity;
+ entityDeclSAXFunc entityDecl;
+ notationDeclSAXFunc notationDecl;
+ attributeDeclSAXFunc attributeDecl;
+ elementDeclSAXFunc elementDecl;
+ unparsedEntityDeclSAXFunc unparsedEntityDecl;
+ setDocumentLocatorSAXFunc setDocumentLocator;
+ startDocumentSAXFunc startDocument;
+ endDocumentSAXFunc endDocument;
+ startElementSAXFunc startElement;
+ endElementSAXFunc endElement;
+ referenceSAXFunc reference;
+ charactersSAXFunc characters;
+ ignorableWhitespaceSAXFunc ignorableWhitespace;
+ processingInstructionSAXFunc processingInstruction;
+ commentSAXFunc comment;
+ warningSAXFunc warning;
+ errorSAXFunc error;
+ fatalErrorSAXFunc fatalError; /* unused error() get all the errors */
+ getParameterEntitySAXFunc getParameterEntity;
+ cdataBlockSAXFunc cdataBlock;
+ externalSubsetSAXFunc externalSubset;
+ int initialized;
+};
+
+/**
+ * xmlExternalEntityLoader:
+ * @URL: The System ID of the resource requested
+ * @ID: The Public ID of the resource requested
+ * @context: the XML parser context
+ *
+ * External entity loaders types.
+ *
+ * Returns the entity input parser.
+ */
+typedef xmlParserInputPtr (*xmlExternalEntityLoader) (const char *URL,
+ const char *ID,
+ xmlParserCtxtPtr context);
+
+/*
+ * Global variables: just the default SAX interface tables and XML
+ * version infos.
+ */
+#if 0
+LIBXML_DLL_IMPORT extern const char *xmlParserVersion;
+#endif
+
+/*
+LIBXML_DLL_IMPORT extern xmlSAXLocator xmlDefaultSAXLocator;
+LIBXML_DLL_IMPORT extern xmlSAXHandler xmlDefaultSAXHandler;
+LIBXML_DLL_IMPORT extern xmlSAXHandler htmlDefaultSAXHandler;
+LIBXML_DLL_IMPORT extern xmlSAXHandler docbDefaultSAXHandler;
+ */
+
+/*
+ * Entity substitution default behavior.
+ */
+
+#if 0
+LIBXML_DLL_IMPORT extern int xmlSubstituteEntitiesDefaultValue;
+LIBXML_DLL_IMPORT extern int xmlGetWarningsDefaultValue;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#include "libxml/encoding.h"
+#include "libxml/xmlIO.h"
+#include "libxml/globals.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * Init/Cleanup
+ */
+void xmlInitParser (void);
+void xmlCleanupParser (void);
+
+/*
+ * Input functions
+ */
+int xmlParserInputRead (xmlParserInputPtr in,
+ int len);
+int xmlParserInputGrow (xmlParserInputPtr in,
+ int len);
+
+/*
+ * xmlChar handling
+ */
+xmlChar * xmlStrdup (const xmlChar *cur);
+xmlChar * xmlStrndup (const xmlChar *cur,
+ int len);
+xmlChar * xmlCharStrndup (const char *cur,
+ int len);
+xmlChar * xmlCharStrdup (const char *cur);
+xmlChar * xmlStrsub (const xmlChar *str,
+ int start,
+ int len);
+const xmlChar * xmlStrchr (const xmlChar *str,
+ xmlChar val);
+const xmlChar * xmlStrstr (const xmlChar *str,
+ const xmlChar *val);
+const xmlChar * xmlStrcasestr (const xmlChar *str,
+ xmlChar *val);
+int xmlStrcmp (const xmlChar *str1,
+ const xmlChar *str2);
+int xmlStrncmp (const xmlChar *str1,
+ const xmlChar *str2,
+ int len);
+int xmlStrcasecmp (const xmlChar *str1,
+ const xmlChar *str2);
+int xmlStrncasecmp (const xmlChar *str1,
+ const xmlChar *str2,
+ int len);
+int xmlStrEqual (const xmlChar *str1,
+ const xmlChar *str2);
+int xmlStrlen (const xmlChar *str);
+xmlChar * xmlStrcat (xmlChar *cur,
+ const xmlChar *add);
+xmlChar * xmlStrncat (xmlChar *cur,
+ const xmlChar *add,
+ int len);
+
+/*
+ * Basic parsing Interfaces
+ */
+xmlDocPtr xmlParseDoc (xmlChar *cur);
+xmlDocPtr xmlParseMemory (const char *buffer,
+ int size);
+xmlDocPtr xmlParseFile (const char *filename);
+int xmlSubstituteEntitiesDefault(int val);
+int xmlKeepBlanksDefault (int val);
+void xmlStopParser (xmlParserCtxtPtr ctxt);
+int xmlPedanticParserDefault(int val);
+int xmlLineNumbersDefault (int val);
+
+/*
+ * Recovery mode
+ */
+xmlDocPtr xmlRecoverDoc (xmlChar *cur);
+xmlDocPtr xmlRecoverMemory (const char *buffer,
+ int size);
+xmlDocPtr xmlRecoverFile (const char *filename);
+
+/*
+ * Less common routines and SAX interfaces
+ */
+int xmlParseDocument (xmlParserCtxtPtr ctxt);
+int xmlParseExtParsedEnt (xmlParserCtxtPtr ctxt);
+xmlDocPtr xmlSAXParseDoc (xmlSAXHandlerPtr sax,
+ xmlChar *cur,
+ int recovery);
+int xmlSAXUserParseFile (xmlSAXHandlerPtr sax,
+ void *user_data,
+ const char *filename);
+int xmlSAXUserParseMemory (xmlSAXHandlerPtr sax,
+ void *user_data,
+ const char *buffer,
+ int size);
+xmlDocPtr xmlSAXParseMemory (xmlSAXHandlerPtr sax,
+ const char *buffer,
+ int size,
+ int recovery);
+xmlDocPtr xmlSAXParseMemoryWithData (xmlSAXHandlerPtr sax,
+ const char *buffer,
+ int size,
+ int recovery,
+ void *data);
+xmlDocPtr xmlSAXParseFile (xmlSAXHandlerPtr sax,
+ const char *filename,
+ int recovery);
+xmlDocPtr xmlSAXParseFileWithData (xmlSAXHandlerPtr sax,
+ const char *filename,
+ int recovery,
+ void *data);
+xmlDocPtr xmlSAXParseEntity (xmlSAXHandlerPtr sax,
+ const char *filename);
+xmlDocPtr xmlParseEntity (const char *filename);
+xmlDtdPtr xmlParseDTD (const xmlChar *ExternalID,
+ const xmlChar *SystemID);
+xmlDtdPtr xmlSAXParseDTD (xmlSAXHandlerPtr sax,
+ const xmlChar *ExternalID,
+ const xmlChar *SystemID);
+xmlDtdPtr xmlIOParseDTD (xmlSAXHandlerPtr sax,
+ xmlParserInputBufferPtr input,
+ xmlCharEncoding enc);
+int xmlParseBalancedChunkMemory(xmlDocPtr doc,
+ xmlSAXHandlerPtr sax,
+ void *user_data,
+ int depth,
+ const xmlChar *string,
+ xmlNodePtr *lst);
+int xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc,
+ xmlSAXHandlerPtr sax,
+ void *user_data,
+ int depth,
+ const xmlChar *string,
+ xmlNodePtr *lst,
+ int recover);
+int xmlParseExternalEntity (xmlDocPtr doc,
+ xmlSAXHandlerPtr sax,
+ void *user_data,
+ int depth,
+ const xmlChar *URL,
+ const xmlChar *ID,
+ xmlNodePtr *lst);
+int xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx,
+ const xmlChar *URL,
+ const xmlChar *ID,
+ xmlNodePtr *lst);
+
+/*
+ * Parser contexts handling.
+ */
+void xmlInitParserCtxt (xmlParserCtxtPtr ctxt);
+void xmlClearParserCtxt (xmlParserCtxtPtr ctxt);
+void xmlFreeParserCtxt (xmlParserCtxtPtr ctxt);
+void xmlSetupParserForBuffer (xmlParserCtxtPtr ctxt,
+ const xmlChar* buffer,
+ const char *filename);
+xmlParserCtxtPtr xmlCreateDocParserCtxt (xmlChar *cur);
+
+/*
+ * Reading/setting optional parsing features.
+ */
+
+int xmlGetFeaturesList (int *len,
+ const char **result);
+int xmlGetFeature (xmlParserCtxtPtr ctxt,
+ const char *name,
+ void *result);
+int xmlSetFeature (xmlParserCtxtPtr ctxt,
+ const char *name,
+ void *value);
+
+/*
+ * Interfaces for the Push mode.
+ */
+xmlParserCtxtPtr xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax,
+ void *user_data,
+ const char *chunk,
+ int size,
+ const char *filename);
+int xmlParseChunk (xmlParserCtxtPtr ctxt,
+ const char *chunk,
+ int size,
+ int terminate);
+
+/*
+ * Special I/O mode.
+ */
+
+xmlParserCtxtPtr xmlCreateIOParserCtxt (xmlSAXHandlerPtr sax,
+ void *user_data,
+ xmlInputReadCallback ioread,
+ xmlInputCloseCallback ioclose,
+ void *ioctx,
+ xmlCharEncoding enc);
+
+xmlParserInputPtr xmlNewIOInputStream (xmlParserCtxtPtr ctxt,
+ xmlParserInputBufferPtr input,
+ xmlCharEncoding enc);
+
+/*
+ * Node infos.
+ */
+const xmlParserNodeInfo*
+ xmlParserFindNodeInfo (const xmlParserCtxtPtr ctxt,
+ const xmlNodePtr node);
+void xmlInitNodeInfoSeq (xmlParserNodeInfoSeqPtr seq);
+void xmlClearNodeInfoSeq (xmlParserNodeInfoSeqPtr seq);
+unsigned long xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeqPtr seq,
+ const xmlNodePtr node);
+void xmlParserAddNodeInfo (xmlParserCtxtPtr ctxt,
+ const xmlParserNodeInfoPtr info);
+
+/*
+ * External entities handling actually implemented in xmlIO.
+ */
+
+void xmlSetExternalEntityLoader(xmlExternalEntityLoader f);
+xmlExternalEntityLoader
+ xmlGetExternalEntityLoader(void);
+xmlParserInputPtr
+ xmlLoadExternalEntity (const char *URL,
+ const char *ID,
+ xmlParserCtxtPtr ctxt);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_PARSER_H__ */
+
diff --git a/plugins/Variables/src/libxml/parserInternals.h b/plugins/Variables/src/libxml/parserInternals.h
new file mode 100644
index 0000000000..8507442be8
--- /dev/null
+++ b/plugins/Variables/src/libxml/parserInternals.h
@@ -0,0 +1,413 @@
+/*
+ * parserInternals.h : internals routines exported by the parser.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ *
+ */
+
+#ifndef __XML_PARSER_INTERNALS_H__
+#define __XML_PARSER_INTERNALS_H__
+
+#include <libxml/parser.h>
+#include <libxml/HTMLparser.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /**
+ * XML_MAX_NAMELEN:
+ *
+ * Identifiers can be longer, but this will be more costly
+ * at runtime.
+ */
+#define XML_MAX_NAMELEN 100
+
+/**
+ * INPUT_CHUNK:
+ *
+ * The parser tries to always have that amount of input ready.
+ * One of the point is providing context when reporting errors.
+ */
+#define INPUT_CHUNK 250
+
+/************************************************************************
+ * *
+ * UNICODE version of the macros. *
+ * *
+ ************************************************************************/
+/**
+ * IS_CHAR:
+ * @c: an UNICODE value (int)
+ *
+ * Macro to check the following production in the XML spec:
+ *
+ * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
+ * | [#x10000-#x10FFFF]
+ * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
+ */
+#define IS_CHAR(c) \
+ ((((c) >= 0x20) && ((c) <= 0xD7FF)) || \
+ ((c) == 0x09) || ((c) == 0x0A) || ((c) == 0x0D) || \
+ (((c) >= 0xE000) && ((c) <= 0xFFFD)) || \
+ (((c) >= 0x10000) && ((c) <= 0x10FFFF)))
+
+/**
+ * IS_BLANK:
+ * @c: an UNICODE value (int)
+ *
+ * Macro to check the following production in the XML spec:
+ *
+ * [3] S ::= (#x20 | #x9 | #xD | #xA)+
+ */
+#define IS_BLANK(c) (((c) == 0x20) || ((c) == 0x09) || ((c) == 0xA) || \
+ ((c) == 0x0D))
+
+/**
+ * IS_BASECHAR:
+ * @c: an UNICODE value (int)
+ *
+ * Macro to check the following production in the XML spec:
+ *
+ * [85] BaseChar ::= ... long list see REC ...
+ */
+#define IS_BASECHAR(c) xmlIsBaseChar(c)
+
+/**
+ * IS_DIGIT:
+ * @c: an UNICODE value (int)
+ *
+ * Macro to check the following production in the XML spec:
+ *
+ * [88] Digit ::= ... long list see REC ...
+ */
+#define IS_DIGIT(c) xmlIsDigit(c)
+
+/**
+ * IS_COMBINING:
+ * @c: an UNICODE value (int)
+ *
+ * Macro to check the following production in the XML spec:
+ *
+ * [87] CombiningChar ::= ... long list see REC ...
+ */
+#define IS_COMBINING(c) xmlIsCombining(c)
+
+/**
+ * IS_EXTENDER:
+ * @c: an UNICODE value (int)
+ *
+ * Macro to check the following production in the XML spec:
+ *
+ *
+ * [89] Extender ::= #x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 |
+ * #x0E46 | #x0EC6 | #x3005 | [#x3031-#x3035] |
+ * [#x309D-#x309E] | [#x30FC-#x30FE]
+ */
+#define IS_EXTENDER(c) xmlIsExtender(c)
+
+/**
+ * IS_IDEOGRAPHIC:
+ * @c: an UNICODE value (int)
+ *
+ * Macro to check the following production in the XML spec:
+ *
+ *
+ * [86] Ideographic ::= [#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029]
+ */
+#define IS_IDEOGRAPHIC(c) xmlIsIdeographic(c)
+
+/**
+ * IS_LETTER:
+ * @c: an UNICODE value (int)
+ *
+ * Macro to check the following production in the XML spec:
+ *
+ *
+ * [84] Letter ::= BaseChar | Ideographic
+ */
+#define IS_LETTER(c) (IS_BASECHAR(c) || IS_IDEOGRAPHIC(c))
+
+
+/**
+ * IS_PUBIDCHAR:
+ * @c: an UNICODE value (int)
+ *
+ * Macro to check the following production in the XML spec:
+ *
+ *
+ * [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
+ */
+#define IS_PUBIDCHAR(c) xmlIsPubidChar(c)
+
+/**
+ * SKIP_EOL:
+ * @p: and UTF8 string pointer
+ *
+ * Skips the end of line chars.
+ */
+#define SKIP_EOL(p) \
+ if (*(p) == 0x13) { p++ ; if (*(p) == 0x10) p++; } \
+ if (*(p) == 0x10) { p++ ; if (*(p) == 0x13) p++; }
+
+/**
+ * MOVETO_ENDTAG:
+ * @p: and UTF8 string pointer
+ *
+ * Skips to the next '>' char.
+ */
+#define MOVETO_ENDTAG(p) \
+ while ((*p) && (*(p) != '>')) (p)++
+
+/**
+ * MOVETO_STARTTAG:
+ * @p: and UTF8 string pointer
+ *
+ * Skips to the next '<' char.
+ */
+#define MOVETO_STARTTAG(p) \
+ while ((*p) && (*(p) != '<')) (p)++
+
+/**
+ * Global variables used for predefined strings.
+ */
+LIBXML_DLL_IMPORT extern const xmlChar xmlStringText[];
+LIBXML_DLL_IMPORT extern const xmlChar xmlStringTextNoenc[];
+LIBXML_DLL_IMPORT extern const xmlChar xmlStringComment[];
+
+/*
+ * Function to finish the work of the macros where needed.
+ */
+int xmlIsBaseChar (int c);
+int xmlIsBlank (int c);
+int xmlIsPubidChar (int c);
+int xmlIsLetter (int c);
+int xmlIsDigit (int c);
+int xmlIsIdeographic(int c);
+int xmlIsExtender (int c);
+int xmlIsCombining (int c);
+int xmlIsChar (int c);
+
+/**
+ * Parser context.
+ */
+xmlParserCtxtPtr xmlCreateFileParserCtxt (const char *filename);
+xmlParserCtxtPtr xmlCreateMemoryParserCtxt(const char *buffer,
+ int size);
+xmlParserCtxtPtr xmlNewParserCtxt (void);
+xmlParserCtxtPtr xmlCreateEntityParserCtxt(const xmlChar *URL,
+ const xmlChar *ID,
+ const xmlChar *base);
+int xmlSwitchEncoding (xmlParserCtxtPtr ctxt,
+ xmlCharEncoding enc);
+int xmlSwitchToEncoding (xmlParserCtxtPtr ctxt,
+ xmlCharEncodingHandlerPtr handler);
+
+/**
+ * Entities
+ */
+void xmlHandleEntity (xmlParserCtxtPtr ctxt,
+ xmlEntityPtr entity);
+
+/**
+ * Input Streams.
+ */
+xmlParserInputPtr xmlNewStringInputStream (xmlParserCtxtPtr ctxt,
+ const xmlChar *buffer);
+xmlParserInputPtr xmlNewEntityInputStream (xmlParserCtxtPtr ctxt,
+ xmlEntityPtr entity);
+void xmlPushInput (xmlParserCtxtPtr ctxt,
+ xmlParserInputPtr input);
+xmlChar xmlPopInput (xmlParserCtxtPtr ctxt);
+void xmlFreeInputStream (xmlParserInputPtr input);
+xmlParserInputPtr xmlNewInputFromFile (xmlParserCtxtPtr ctxt,
+ const char *filename);
+xmlParserInputPtr xmlNewInputStream (xmlParserCtxtPtr ctxt);
+
+/**
+ * Namespaces.
+ */
+xmlChar * xmlSplitQName (xmlParserCtxtPtr ctxt,
+ const xmlChar *name,
+ xmlChar **prefix);
+xmlChar * xmlNamespaceParseNCName (xmlParserCtxtPtr ctxt);
+xmlChar * xmlNamespaceParseQName (xmlParserCtxtPtr ctxt,
+ xmlChar **prefix);
+xmlChar * xmlNamespaceParseNSDef (xmlParserCtxtPtr ctxt);
+xmlChar * xmlParseQuotedString (xmlParserCtxtPtr ctxt);
+void xmlParseNamespace (xmlParserCtxtPtr ctxt);
+
+/**
+ * Generic production rules.
+ */
+xmlChar * xmlScanName (xmlParserCtxtPtr ctxt);
+xmlChar * xmlParseName (xmlParserCtxtPtr ctxt);
+xmlChar * xmlParseNmtoken (xmlParserCtxtPtr ctxt);
+xmlChar * xmlParseEntityValue (xmlParserCtxtPtr ctxt,
+ xmlChar **orig);
+xmlChar * xmlParseAttValue (xmlParserCtxtPtr ctxt);
+xmlChar * xmlParseSystemLiteral (xmlParserCtxtPtr ctxt);
+xmlChar * xmlParsePubidLiteral (xmlParserCtxtPtr ctxt);
+void xmlParseCharData (xmlParserCtxtPtr ctxt,
+ int cdata);
+xmlChar * xmlParseExternalID (xmlParserCtxtPtr ctxt,
+ xmlChar **publicID,
+ int strict);
+void xmlParseComment (xmlParserCtxtPtr ctxt);
+xmlChar * xmlParsePITarget (xmlParserCtxtPtr ctxt);
+void xmlParsePI (xmlParserCtxtPtr ctxt);
+void xmlParseNotationDecl (xmlParserCtxtPtr ctxt);
+void xmlParseEntityDecl (xmlParserCtxtPtr ctxt);
+int xmlParseDefaultDecl (xmlParserCtxtPtr ctxt,
+ xmlChar **value);
+xmlEnumerationPtr xmlParseNotationType (xmlParserCtxtPtr ctxt);
+xmlEnumerationPtr xmlParseEnumerationType (xmlParserCtxtPtr ctxt);
+int xmlParseEnumeratedType (xmlParserCtxtPtr ctxt,
+ xmlEnumerationPtr *tree);
+int xmlParseAttributeType (xmlParserCtxtPtr ctxt,
+ xmlEnumerationPtr *tree);
+void xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt);
+xmlElementContentPtr xmlParseElementMixedContentDecl
+ (xmlParserCtxtPtr ctxt,
+ xmlParserInputPtr inputchk);
+xmlElementContentPtr xmlParseElementChildrenContentDecl
+ (xmlParserCtxtPtr ctxt,
+ xmlParserInputPtr inputchk);
+int xmlParseElementContentDecl(xmlParserCtxtPtr ctxt,
+ xmlChar *name,
+ xmlElementContentPtr *result);
+int xmlParseElementDecl (xmlParserCtxtPtr ctxt);
+void xmlParseMarkupDecl (xmlParserCtxtPtr ctxt);
+int xmlParseCharRef (xmlParserCtxtPtr ctxt);
+xmlEntityPtr xmlParseEntityRef (xmlParserCtxtPtr ctxt);
+void xmlParseReference (xmlParserCtxtPtr ctxt);
+void xmlParsePEReference (xmlParserCtxtPtr ctxt);
+void xmlParseDocTypeDecl (xmlParserCtxtPtr ctxt);
+xmlChar * xmlParseAttribute (xmlParserCtxtPtr ctxt,
+ xmlChar **value);
+xmlChar * xmlParseStartTag (xmlParserCtxtPtr ctxt);
+void xmlParseEndTag (xmlParserCtxtPtr ctxt);
+void xmlParseCDSect (xmlParserCtxtPtr ctxt);
+void xmlParseContent (xmlParserCtxtPtr ctxt);
+void xmlParseElement (xmlParserCtxtPtr ctxt);
+xmlChar * xmlParseVersionNum (xmlParserCtxtPtr ctxt);
+xmlChar * xmlParseVersionInfo (xmlParserCtxtPtr ctxt);
+xmlChar * xmlParseEncName (xmlParserCtxtPtr ctxt);
+xmlChar * xmlParseEncodingDecl (xmlParserCtxtPtr ctxt);
+int xmlParseSDDecl (xmlParserCtxtPtr ctxt);
+void xmlParseXMLDecl (xmlParserCtxtPtr ctxt);
+void xmlParseTextDecl (xmlParserCtxtPtr ctxt);
+void xmlParseMisc (xmlParserCtxtPtr ctxt);
+void xmlParseExternalSubset (xmlParserCtxtPtr ctxt,
+ const xmlChar *ExternalID,
+ const xmlChar *SystemID);
+/**
+ * XML_SUBSTITUTE_NONE:
+ *
+ * If no entities need to be substituted.
+ */
+#define XML_SUBSTITUTE_NONE 0
+/**
+ * XML_SUBSTITUTE_REF:
+ *
+ * Whether general entities need to be substituted.
+ */
+#define XML_SUBSTITUTE_REF 1
+/**
+ * XML_SUBSTITUTE_PEREF:
+ *
+ * Whether parameter entities need to be substituted.
+ */
+#define XML_SUBSTITUTE_PEREF 2
+/**
+ * XML_SUBSTITUTE_BOTH:
+ *
+ * Both general and parameter entities need to be substituted.
+ */
+#define XML_SUBSTITUTE_BOTH 3
+
+xmlChar * xmlDecodeEntities (xmlParserCtxtPtr ctxt,
+ int len,
+ int what,
+ xmlChar end,
+ xmlChar end2,
+ xmlChar end3);
+xmlChar * xmlStringDecodeEntities (xmlParserCtxtPtr ctxt,
+ const xmlChar *str,
+ int what,
+ xmlChar end,
+ xmlChar end2,
+ xmlChar end3);
+
+/*
+ * Generated by MACROS on top of parser.c c.f. PUSH_AND_POP.
+ */
+int nodePush (xmlParserCtxtPtr ctxt,
+ xmlNodePtr value);
+xmlNodePtr nodePop (xmlParserCtxtPtr ctxt);
+int inputPush (xmlParserCtxtPtr ctxt,
+ xmlParserInputPtr value);
+xmlParserInputPtr inputPop (xmlParserCtxtPtr ctxt);
+xmlChar *namePop (xmlParserCtxtPtr ctxt);
+int namePush (xmlParserCtxtPtr ctxt,
+ xmlChar *value);
+
+/*
+ * other commodities shared between parser.c and parserInternals.
+ */
+int xmlSkipBlankChars (xmlParserCtxtPtr ctxt);
+int xmlStringCurrentChar (xmlParserCtxtPtr ctxt,
+ const xmlChar *cur,
+ int *len);
+void xmlParserHandlePEReference(xmlParserCtxtPtr ctxt);
+void xmlParserHandleReference(xmlParserCtxtPtr ctxt);
+int xmlCheckLanguageID (const xmlChar *lang);
+
+/*
+ * Really core function shared with HTML parser.
+ */
+int xmlCurrentChar (xmlParserCtxtPtr ctxt,
+ int *len);
+int xmlCopyCharMultiByte (xmlChar *out,
+ int val);
+int xmlCopyChar (int len,
+ xmlChar *out,
+ int val);
+void xmlNextChar (xmlParserCtxtPtr ctxt);
+void xmlParserInputShrink (xmlParserInputPtr in);
+
+#ifdef LIBXML_HTML_ENABLED
+/*
+ * Actually comes from the HTML parser but launched from the init stuff.
+ */
+void htmlInitAutoClose (void);
+htmlParserCtxtPtr htmlCreateFileParserCtxt(const char *filename,
+ const char *encoding);
+#endif
+
+/*
+ * Specific function to keep track of entities references
+ * and used by the XSLT debugger.
+ */
+/**
+ * xmlEntityReferenceFunc:
+ * @ent: the entity
+ * @firstNode: the fist node in the chunk
+ * @lastNode: the last nod in the chunk
+ *
+ * Callback function used when one needs to be able to track back the
+ * provenance of a chunk of nodes inherited from an entity replacement.
+ */
+typedef void (*xmlEntityReferenceFunc) (xmlEntityPtr ent,
+ xmlNodePtr firstNode,
+ xmlNodePtr lastNode);
+
+void xmlSetEntityReferenceFunc (xmlEntityReferenceFunc func);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_PARSER_INTERNALS_H__ */
diff --git a/plugins/Variables/src/libxml/schemasInternals.h b/plugins/Variables/src/libxml/schemasInternals.h
new file mode 100644
index 0000000000..fb1f7eeb39
--- /dev/null
+++ b/plugins/Variables/src/libxml/schemasInternals.h
@@ -0,0 +1,354 @@
+/*
+ * schemasInternals.h : internal interfaces for the XML Schemas handling
+ * and schema validity checking
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel.Veillard@w3.org
+ */
+
+
+#ifndef __XML_SCHEMA_INTERNALS_H__
+#define __XML_SCHEMA_INTERNALS_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#include <libxml/xmlregexp.h>
+#include <libxml/hash.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * XML Schemas defines multiple type of types.
+ */
+typedef enum {
+ XML_SCHEMA_TYPE_BASIC = 1,
+ XML_SCHEMA_TYPE_ANY,
+ XML_SCHEMA_TYPE_FACET,
+ XML_SCHEMA_TYPE_SIMPLE,
+ XML_SCHEMA_TYPE_COMPLEX,
+ XML_SCHEMA_TYPE_SEQUENCE,
+ XML_SCHEMA_TYPE_CHOICE,
+ XML_SCHEMA_TYPE_ALL,
+ XML_SCHEMA_TYPE_SIMPLE_CONTENT,
+ XML_SCHEMA_TYPE_COMPLEX_CONTENT,
+ XML_SCHEMA_TYPE_UR,
+ XML_SCHEMA_TYPE_RESTRICTION,
+ XML_SCHEMA_TYPE_EXTENSION,
+ XML_SCHEMA_TYPE_ELEMENT,
+ XML_SCHEMA_TYPE_ATTRIBUTE,
+ XML_SCHEMA_TYPE_ATTRIBUTEGROUP,
+ XML_SCHEMA_TYPE_GROUP,
+ XML_SCHEMA_TYPE_NOTATION,
+ XML_SCHEMA_TYPE_LIST,
+ XML_SCHEMA_TYPE_UNION,
+ XML_SCHEMA_FACET_MININCLUSIVE = 1000,
+ XML_SCHEMA_FACET_MINEXCLUSIVE,
+ XML_SCHEMA_FACET_MAXINCLUSIVE,
+ XML_SCHEMA_FACET_MAXEXCLUSIVE,
+ XML_SCHEMA_FACET_TOTALDIGITS,
+ XML_SCHEMA_FACET_FRACTIONDIGITS,
+ XML_SCHEMA_FACET_PATTERN,
+ XML_SCHEMA_FACET_ENUMERATION,
+ XML_SCHEMA_FACET_WHITESPACE,
+ XML_SCHEMA_FACET_LENGTH,
+ XML_SCHEMA_FACET_MAXLENGTH,
+ XML_SCHEMA_FACET_MINLENGTH
+} xmlSchemaTypeType;
+
+typedef enum {
+ XML_SCHEMA_CONTENT_UNKNOWN = 0,
+ XML_SCHEMA_CONTENT_EMPTY = 1,
+ XML_SCHEMA_CONTENT_ELEMENTS,
+ XML_SCHEMA_CONTENT_MIXED,
+ XML_SCHEMA_CONTENT_SIMPLE,
+ XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS,
+ XML_SCHEMA_CONTENT_BASIC,
+ XML_SCHEMA_CONTENT_ANY
+} xmlSchemaContentType;
+
+typedef struct _xmlSchemaVal xmlSchemaVal;
+typedef xmlSchemaVal *xmlSchemaValPtr;
+
+typedef struct _xmlSchemaType xmlSchemaType;
+typedef xmlSchemaType *xmlSchemaTypePtr;
+
+typedef struct _xmlSchemaFacet xmlSchemaFacet;
+typedef xmlSchemaFacet *xmlSchemaFacetPtr;
+
+/**
+ * Annotation
+ */
+typedef struct _xmlSchemaAnnot xmlSchemaAnnot;
+typedef xmlSchemaAnnot *xmlSchemaAnnotPtr;
+struct _xmlSchemaAnnot {
+ struct _xmlSchemaAnnot *next;
+ xmlNodePtr content; /* the annotation */
+};
+
+/**
+ * An attribute definition.
+ */
+
+#define XML_SCHEMAS_ANYATTR_SKIP 1
+#define XML_SCHEMAS_ANYATTR_LAX 2
+#define XML_SCHEMAS_ANYATTR_STRICT 3
+
+typedef struct _xmlSchemaAttribute xmlSchemaAttribute;
+typedef xmlSchemaAttribute *xmlSchemaAttributePtr;
+struct _xmlSchemaAttribute {
+ xmlSchemaTypeType type; /* The kind of type */
+ struct _xmlSchemaAttribute *next;/* the next attribute if in a group ... */
+ xmlChar *name;
+ xmlChar *id;
+ xmlChar *ref;
+ xmlChar *refNs;
+ xmlChar *typeName;
+ xmlChar *typeNs;
+ xmlSchemaAnnotPtr annot;
+
+ xmlSchemaTypePtr base;
+ int occurs;
+ xmlChar *defValue;
+ xmlSchemaTypePtr subtypes;
+};
+
+/**
+ * An attribute group definition.
+ *
+ * xmlSchemaAttribute and xmlSchemaAttributeGroup start of structures
+ * must be kept similar
+ */
+typedef struct _xmlSchemaAttributeGroup xmlSchemaAttributeGroup;
+typedef xmlSchemaAttributeGroup *xmlSchemaAttributeGroupPtr;
+struct _xmlSchemaAttributeGroup {
+ xmlSchemaTypeType type; /* The kind of type */
+ struct _xmlSchemaAttribute *next;/* the next attribute if in a group ... */
+ xmlChar *name;
+ xmlChar *id;
+ xmlChar *ref;
+ xmlChar *refNs;
+ xmlSchemaAnnotPtr annot;
+
+ xmlSchemaAttributePtr attributes;
+};
+
+
+/**
+ * XML_SCHEMAS_TYPE_MIXED:
+ *
+ * the element content type is mixed
+ */
+#define XML_SCHEMAS_TYPE_MIXED 1 << 0
+
+/**
+ * _xmlSchemaType:
+ *
+ * Schemas type definition.
+ */
+struct _xmlSchemaType {
+ xmlSchemaTypeType type; /* The kind of type */
+ struct _xmlSchemaType *next;/* the next type if in a sequence ... */
+ xmlChar *name;
+ xmlChar *id;
+ xmlChar *ref;
+ xmlChar *refNs;
+ xmlSchemaAnnotPtr annot;
+ xmlSchemaTypePtr subtypes;
+ xmlSchemaAttributePtr attributes;
+ xmlNodePtr node;
+ int minOccurs;
+ int maxOccurs;
+
+ int flags;
+ xmlSchemaContentType contentType;
+ xmlChar *base;
+ xmlChar *baseNs;
+ xmlSchemaTypePtr baseType;
+ xmlSchemaFacetPtr facets;
+};
+
+/**
+ * xmlSchemaElement:
+ * An element definition.
+ *
+ * xmlSchemaType, xmlSchemaFacet and xmlSchemaElement start of
+ * structures must be kept similar
+ */
+/**
+ * XML_SCHEMAS_ELEM_NILLABLE:
+ *
+ * the element is nillable
+ */
+#define XML_SCHEMAS_ELEM_NILLABLE 1 << 0
+/**
+ * XML_SCHEMAS_ELEM_GLOBAL:
+ *
+ * the element is global
+ */
+#define XML_SCHEMAS_ELEM_GLOBAL 1 << 1
+/**
+ * XML_SCHEMAS_ELEM_DEFAULT:
+ *
+ * the element has a default value
+ */
+#define XML_SCHEMAS_ELEM_DEFAULT 1 << 2
+/**
+ * XML_SCHEMAS_ELEM_FIXED:
+ *
+ * the element has a fixed value
+ */
+#define XML_SCHEMAS_ELEM_FIXED 1 << 3
+/**
+ * XML_SCHEMAS_ELEM_ABSTRACT:
+ *
+ * the element is abstract
+ */
+#define XML_SCHEMAS_ELEM_ABSTRACT 1 << 4
+/**
+ * XML_SCHEMAS_ELEM_TOPLEVEL:
+ *
+ * the element is top level
+ */
+#define XML_SCHEMAS_ELEM_TOPLEVEL 1 << 5
+/**
+ * XML_SCHEMAS_ELEM_REF:
+ *
+ * the element is a reference to a type
+ */
+#define XML_SCHEMAS_ELEM_REF 1 << 6
+
+typedef struct _xmlSchemaElement xmlSchemaElement;
+typedef xmlSchemaElement *xmlSchemaElementPtr;
+struct _xmlSchemaElement {
+ xmlSchemaTypeType type; /* The kind of type */
+ struct _xmlSchemaType *next;/* the next type if in a sequence ... */
+ xmlChar *name;
+ xmlChar *id;
+ xmlChar *ref;
+ xmlChar *refNs;
+ xmlSchemaAnnotPtr annot;
+ xmlSchemaTypePtr subtypes;
+ xmlSchemaAttributePtr attributes;
+ xmlNodePtr node;
+ int minOccurs;
+ int maxOccurs;
+
+ int flags;
+ xmlChar *targetNamespace;
+ xmlChar *namedType;
+ xmlChar *namedTypeNs;
+ xmlChar *substGroup;
+ xmlChar *substGroupNs;
+ xmlChar *scope;
+ xmlChar *value;
+ struct _xmlSchemaElement *refDecl;
+ xmlRegexpPtr contModel;
+ xmlSchemaContentType contentType;
+};
+
+/*
+ * XML_SCHEMAS_FACET_UNKNOWN:
+ *
+ * unknown facet handling
+ */
+#define XML_SCHEMAS_FACET_UNKNOWN 0
+/*
+ * XML_SCHEMAS_FACET_PRESERVE:
+ *
+ * preserve the type of the facet
+ */
+#define XML_SCHEMAS_FACET_PRESERVE 1
+/*
+ * XML_SCHEMAS_FACET_REPLACE:
+ *
+ * replace the type of the facet
+ */
+#define XML_SCHEMAS_FACET_REPLACE 2
+/*
+ * XML_SCHEMAS_FACET_COLLAPSE:
+ *
+ * collapse the types of the facet
+ */
+#define XML_SCHEMAS_FACET_COLLAPSE 3
+
+/**
+ * A facet definition.
+ */
+struct _xmlSchemaFacet {
+ xmlSchemaTypeType type; /* The kind of type */
+ struct _xmlSchemaFacet *next;/* the next type if in a sequence ... */
+ xmlChar *value;
+ xmlChar *id;
+ xmlSchemaAnnotPtr annot;
+ xmlNodePtr node;
+ int fixed;
+ int whitespace;
+ xmlSchemaValPtr val;
+ xmlRegexpPtr regexp;
+};
+
+/**
+ * A notation definition.
+ */
+typedef struct _xmlSchemaNotation xmlSchemaNotation;
+typedef xmlSchemaNotation *xmlSchemaNotationPtr;
+struct _xmlSchemaNotation {
+ xmlSchemaTypeType type; /* The kind of type */
+ xmlChar *name;
+ xmlSchemaAnnotPtr annot;
+ xmlChar *identifier;
+};
+
+/**
+ * XML_SCHEMAS_QUALIF_ELEM:
+ *
+ * the shemas requires qualified elements
+ */
+#define XML_SCHEMAS_QUALIF_ELEM 1 << 0
+/**
+ * XML_SCHEMAS_QUALIF_ATTR:
+ *
+ * the shemas requires qualified attributes
+ */
+#define XML_SCHEMAS_QUALIF_ATTR 1 << 1
+/**
+ * _xmlSchema:
+ *
+ * A Schemas definition
+ */
+struct _xmlSchema {
+ xmlChar *name; /* schema name */
+ xmlChar *targetNamespace; /* the target namespace */
+ xmlChar *version;
+ xmlChar *id;
+ xmlDocPtr doc;
+ xmlSchemaAnnotPtr annot;
+ int flags;
+
+ xmlHashTablePtr typeDecl;
+ xmlHashTablePtr attrDecl;
+ xmlHashTablePtr attrgrpDecl;
+ xmlHashTablePtr elemDecl;
+ xmlHashTablePtr notaDecl;
+
+ xmlHashTablePtr schemasImports;
+
+ void *_private; /* unused by the library for users or bindings */
+};
+
+void xmlSchemaFreeType (xmlSchemaTypePtr type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_SCHEMAS_ENABLED */
+#endif /* __XML_SCHEMA_INTERNALS_H__ */
+
+
diff --git a/plugins/Variables/src/libxml/threads.h b/plugins/Variables/src/libxml/threads.h
new file mode 100644
index 0000000000..4ef7a17386
--- /dev/null
+++ b/plugins/Variables/src/libxml/threads.h
@@ -0,0 +1,62 @@
+/**
+ * threads.c: set of generic threading related routines
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifndef __XML_THREADS_H__
+#define __XML_THREADS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * xmlMutex are a simple mutual exception locks.
+ */
+typedef struct _xmlMutex xmlMutex;
+typedef xmlMutex *xmlMutexPtr;
+
+/*
+ * xmlRMutex are reentrant mutual exception locks.
+ */
+typedef struct _xmlRMutex xmlRMutex;
+typedef xmlRMutex *xmlRMutexPtr;
+
+#ifdef __cplusplus
+}
+#endif
+#include "libxml/globals.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+xmlMutexPtr xmlNewMutex (void);
+void xmlMutexLock (xmlMutexPtr tok);
+void xmlMutexUnlock (xmlMutexPtr tok);
+void xmlFreeMutex (xmlMutexPtr tok);
+
+xmlRMutexPtr xmlNewRMutex (void);
+void xmlRMutexLock (xmlRMutexPtr tok);
+void xmlRMutexUnlock (xmlRMutexPtr tok);
+void xmlFreeRMutex (xmlRMutexPtr tok);
+
+/*
+ * Library wide APIs.
+ */
+void xmlInitThreads (void);
+void xmlLockLibrary (void);
+void xmlUnlockLibrary(void);
+int xmlGetThreadId (void);
+int xmlIsMainThread (void);
+void xmlCleanupThreads(void);
+xmlGlobalStatePtr xmlGetGlobalState(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __XML_THREADS_H__ */
diff --git a/plugins/Variables/src/libxml/tree.h b/plugins/Variables/src/libxml/tree.h
new file mode 100644
index 0000000000..1a9fb0036d
--- /dev/null
+++ b/plugins/Variables/src/libxml/tree.h
@@ -0,0 +1,905 @@
+/*
+ * tree.h : describes the structures found in an tree resulting
+ * from an XML parsing.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ *
+ */
+
+#ifndef __XML_TREE_H__
+#define __XML_TREE_H__
+
+#include <stdio.h>
+#include "libxml/xmlversion.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Some of the basic types pointer to structures:
+ */
+/* xmlIO.h */
+typedef struct _xmlParserInputBuffer xmlParserInputBuffer;
+typedef xmlParserInputBuffer *xmlParserInputBufferPtr;
+
+typedef struct _xmlOutputBuffer xmlOutputBuffer;
+typedef xmlOutputBuffer *xmlOutputBufferPtr;
+
+/* parser.h */
+typedef struct _xmlParserInput xmlParserInput;
+typedef xmlParserInput *xmlParserInputPtr;
+
+typedef struct _xmlParserCtxt xmlParserCtxt;
+typedef xmlParserCtxt *xmlParserCtxtPtr;
+
+typedef struct _xmlSAXLocator xmlSAXLocator;
+typedef xmlSAXLocator *xmlSAXLocatorPtr;
+
+typedef struct _xmlSAXHandler xmlSAXHandler;
+typedef xmlSAXHandler *xmlSAXHandlerPtr;
+
+/* entities.h */
+typedef struct _xmlEntity xmlEntity;
+typedef xmlEntity *xmlEntityPtr;
+
+/**
+ * BASE_BUFFER_SIZE:
+ *
+ * default buffer size 4000.
+ */
+#define BASE_BUFFER_SIZE 4000
+
+/**
+ * XML_XML_NAMESPACE:
+ *
+ * This is the namespace for the special xml: prefix predefined in the
+ * XML Namespace specification.
+ */
+#define XML_XML_NAMESPACE \
+ (const xmlChar *) "http://www.w3.org/XML/1998/namespace"
+
+/*
+ * The different element types carried by an XML tree.
+ *
+ * NOTE: This is synchronized with DOM Level1 values
+ * See http://www.w3.org/TR/REC-DOM-Level-1/
+ *
+ * Actually this had diverged a bit, and now XML_DOCUMENT_TYPE_NODE should
+ * be deprecated to use an XML_DTD_NODE.
+ */
+typedef enum {
+ XML_ELEMENT_NODE= 1,
+ XML_ATTRIBUTE_NODE= 2,
+ XML_TEXT_NODE= 3,
+ XML_CDATA_SECTION_NODE= 4,
+ XML_ENTITY_REF_NODE= 5,
+ XML_ENTITY_NODE= 6,
+ XML_PI_NODE= 7,
+ XML_COMMENT_NODE= 8,
+ XML_DOCUMENT_NODE= 9,
+ XML_DOCUMENT_TYPE_NODE= 10,
+ XML_DOCUMENT_FRAG_NODE= 11,
+ XML_NOTATION_NODE= 12,
+ XML_HTML_DOCUMENT_NODE= 13,
+ XML_DTD_NODE= 14,
+ XML_ELEMENT_DECL= 15,
+ XML_ATTRIBUTE_DECL= 16,
+ XML_ENTITY_DECL= 17,
+ XML_NAMESPACE_DECL= 18,
+ XML_XINCLUDE_START= 19,
+ XML_XINCLUDE_END= 20
+#ifdef LIBXML_DOCB_ENABLED
+ ,XML_DOCB_DOCUMENT_NODE= 21
+#endif
+} xmlElementType;
+
+/**
+ * xmlChar:
+ *
+ * This is a basic byte in an UTF-8 encoded string.
+ * It's unsigned allowing to pinpoint case where char * are assigned
+ * to xmlChar * (possibly making serialization back impossible).
+ */
+
+typedef unsigned char xmlChar;
+
+/**
+ * BAD_CAST:
+ *
+ * Macro to cast a string to an xmlChar * when one know its safe.
+ */
+#define BAD_CAST (xmlChar *)
+
+/**
+ * xmlNotation:
+ *
+ * A DTD Notation definition.
+ */
+
+typedef struct _xmlNotation xmlNotation;
+typedef xmlNotation *xmlNotationPtr;
+struct _xmlNotation {
+ const xmlChar *name; /* Notation name */
+ const xmlChar *PublicID; /* Public identifier, if any */
+ const xmlChar *SystemID; /* System identifier, if any */
+};
+
+/**
+ * xmlAttributeType:
+ *
+ * A DTD Attribute type definition.
+ */
+
+typedef enum {
+ XML_ATTRIBUTE_CDATA = 1,
+ XML_ATTRIBUTE_ID,
+ XML_ATTRIBUTE_IDREF ,
+ XML_ATTRIBUTE_IDREFS,
+ XML_ATTRIBUTE_ENTITY,
+ XML_ATTRIBUTE_ENTITIES,
+ XML_ATTRIBUTE_NMTOKEN,
+ XML_ATTRIBUTE_NMTOKENS,
+ XML_ATTRIBUTE_ENUMERATION,
+ XML_ATTRIBUTE_NOTATION
+} xmlAttributeType;
+
+/**
+ * xmlAttributeDefault:
+ *
+ * A DTD Attribute default definition.
+ */
+
+typedef enum {
+ XML_ATTRIBUTE_NONE = 1,
+ XML_ATTRIBUTE_REQUIRED,
+ XML_ATTRIBUTE_IMPLIED,
+ XML_ATTRIBUTE_FIXED
+} xmlAttributeDefault;
+
+/**
+ * xmlEnumeration:
+ *
+ * List structure used when there is an enumeration in DTDs.
+ */
+
+typedef struct _xmlEnumeration xmlEnumeration;
+typedef xmlEnumeration *xmlEnumerationPtr;
+struct _xmlEnumeration {
+ struct _xmlEnumeration *next; /* next one */
+ const xmlChar *name; /* Enumeration name */
+};
+
+/**
+ * xmlAttribute:
+ *
+ * An Attribute declaration in a DTD.
+ */
+
+typedef struct _xmlAttribute xmlAttribute;
+typedef xmlAttribute *xmlAttributePtr;
+struct _xmlAttribute {
+ void *_private; /* application data */
+ xmlElementType type; /* XML_ATTRIBUTE_DECL, must be second ! */
+ const xmlChar *name; /* Attribute name */
+ struct _xmlNode *children; /* NULL */
+ struct _xmlNode *last; /* NULL */
+ struct _xmlDtd *parent; /* -> DTD */
+ struct _xmlNode *next; /* next sibling link */
+ struct _xmlNode *prev; /* previous sibling link */
+ struct _xmlDoc *doc; /* the containing document */
+
+ struct _xmlAttribute *nexth; /* next in hash table */
+ xmlAttributeType atype; /* The attribute type */
+ xmlAttributeDefault def; /* the default */
+ const xmlChar *defaultValue; /* or the default value */
+ xmlEnumerationPtr tree; /* or the enumeration tree if any */
+ const xmlChar *prefix; /* the namespace prefix if any */
+ const xmlChar *elem; /* Element holding the attribute */
+};
+
+/**
+ * xmlElementContentType:
+ *
+ * Possible definitions of element content types.
+ */
+typedef enum {
+ XML_ELEMENT_CONTENT_PCDATA = 1,
+ XML_ELEMENT_CONTENT_ELEMENT,
+ XML_ELEMENT_CONTENT_SEQ,
+ XML_ELEMENT_CONTENT_OR
+} xmlElementContentType;
+
+/**
+ * xmlElementContentOccur:
+ *
+ * Possible definitions of element content occurrences.
+ */
+typedef enum {
+ XML_ELEMENT_CONTENT_ONCE = 1,
+ XML_ELEMENT_CONTENT_OPT,
+ XML_ELEMENT_CONTENT_MULT,
+ XML_ELEMENT_CONTENT_PLUS
+} xmlElementContentOccur;
+
+/**
+ * xmlElementContent:
+ *
+ * An XML Element content as stored after parsing an element definition
+ * in a DTD.
+ */
+
+typedef struct _xmlElementContent xmlElementContent;
+typedef xmlElementContent *xmlElementContentPtr;
+struct _xmlElementContent {
+ xmlElementContentType type; /* PCDATA, ELEMENT, SEQ or OR */
+ xmlElementContentOccur ocur; /* ONCE, OPT, MULT or PLUS */
+ const xmlChar *name; /* Element name */
+ struct _xmlElementContent *c1; /* first child */
+ struct _xmlElementContent *c2; /* second child */
+ struct _xmlElementContent *parent; /* parent */
+ const xmlChar *prefix; /* Namespace prefix */
+};
+
+/**
+ * xmlElementTypeVal:
+ *
+ * The different possibilities for an element content type.
+ */
+
+typedef enum {
+ XML_ELEMENT_TYPE_UNDEFINED = 0,
+ XML_ELEMENT_TYPE_EMPTY = 1,
+ XML_ELEMENT_TYPE_ANY,
+ XML_ELEMENT_TYPE_MIXED,
+ XML_ELEMENT_TYPE_ELEMENT
+} xmlElementTypeVal;
+
+
+#ifdef __cplusplus
+}
+#endif
+#include "libxml/xmlregexp.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * xmlElement:
+ *
+ * An XML Element declaration from a DTD.
+ */
+
+typedef struct _xmlElement xmlElement;
+typedef xmlElement *xmlElementPtr;
+struct _xmlElement {
+ void *_private; /* application data */
+ xmlElementType type; /* XML_ELEMENT_DECL, must be second ! */
+ const xmlChar *name; /* Element name */
+ struct _xmlNode *children; /* NULL */
+ struct _xmlNode *last; /* NULL */
+ struct _xmlDtd *parent; /* -> DTD */
+ struct _xmlNode *next; /* next sibling link */
+ struct _xmlNode *prev; /* previous sibling link */
+ struct _xmlDoc *doc; /* the containing document */
+
+ xmlElementTypeVal etype; /* The type */
+ xmlElementContentPtr content; /* the allowed element content */
+ xmlAttributePtr attributes; /* List of the declared attributes */
+ const xmlChar *prefix; /* the namespace prefix if any */
+#ifdef LIBXML_REGEXP_ENABLED
+ xmlRegexpPtr contModel; /* the validating regexp */
+#else
+ void *contModel;
+#endif
+};
+
+
+/**
+ * XML_LOCAL_NAMESPACE:
+ *
+ * A namespace declaration node.
+ */
+#define XML_LOCAL_NAMESPACE XML_NAMESPACE_DECL
+typedef xmlElementType xmlNsType;
+
+/**
+ * xmlNs:
+ *
+ * An XML namespace.
+ * Note that prefix == NULL is valid, it defines the default namespace
+ * within the subtree (until overridden).
+ *
+ * xmlNsType is unified with xmlElementType.
+ */
+
+typedef struct _xmlNs xmlNs;
+typedef xmlNs *xmlNsPtr;
+struct _xmlNs {
+ struct _xmlNs *next; /* next Ns link for this node */
+ xmlNsType type; /* global or local */
+ const xmlChar *href; /* URL for the namespace */
+ const xmlChar *prefix; /* prefix for the namespace */
+ void *_private; /* application data */
+};
+
+/**
+ * xmlDtd:
+ *
+ * An XML DTD, as defined by <!DOCTYPE ... There is actually one for
+ * the internal subset and for the external subset.
+ */
+typedef struct _xmlDtd xmlDtd;
+typedef xmlDtd *xmlDtdPtr;
+struct _xmlDtd {
+ void *_private; /* application data */
+ xmlElementType type; /* XML_DTD_NODE, must be second ! */
+ const xmlChar *name; /* Name of the DTD */
+ struct _xmlNode *children; /* the value of the property link */
+ struct _xmlNode *last; /* last child link */
+ struct _xmlDoc *parent; /* child->parent link */
+ struct _xmlNode *next; /* next sibling link */
+ struct _xmlNode *prev; /* previous sibling link */
+ struct _xmlDoc *doc; /* the containing document */
+
+ /* End of common part */
+ void *notations; /* Hash table for notations if any */
+ void *elements; /* Hash table for elements if any */
+ void *attributes; /* Hash table for attributes if any */
+ void *entities; /* Hash table for entities if any */
+ const xmlChar *ExternalID; /* External identifier for PUBLIC DTD */
+ const xmlChar *SystemID; /* URI for a SYSTEM or PUBLIC DTD */
+ void *pentities; /* Hash table for param entities if any */
+};
+
+/**
+ * xmlAttr:
+ *
+ * An attribute on an XML node.
+ */
+typedef struct _xmlAttr xmlAttr;
+typedef xmlAttr *xmlAttrPtr;
+struct _xmlAttr {
+ void *_private; /* application data */
+ xmlElementType type; /* XML_ATTRIBUTE_NODE, must be second ! */
+ const xmlChar *name; /* the name of the property */
+ struct _xmlNode *children; /* the value of the property */
+ struct _xmlNode *last; /* NULL */
+ struct _xmlNode *parent; /* child->parent link */
+ struct _xmlAttr *next; /* next sibling link */
+ struct _xmlAttr *prev; /* previous sibling link */
+ struct _xmlDoc *doc; /* the containing document */
+ xmlNs *ns; /* pointer to the associated namespace */
+ xmlAttributeType atype; /* the attribute type if validating */
+};
+
+/**
+ * xmlID:
+ *
+ * An XML ID instance.
+ */
+
+typedef struct _xmlID xmlID;
+typedef xmlID *xmlIDPtr;
+struct _xmlID {
+ struct _xmlID *next; /* next ID */
+ const xmlChar *value; /* The ID name */
+ xmlAttrPtr attr; /* The attribute holding it */
+ const xmlChar *name; /* The attribute if attr is not available */
+ int lineno; /* The line number if attr is not available */
+};
+
+/**
+ * xmlRef:
+ *
+ * An XML IDREF instance.
+ */
+
+typedef struct _xmlRef xmlRef;
+typedef xmlRef *xmlRefPtr;
+struct _xmlRef {
+ struct _xmlRef *next; /* next Ref */
+ const xmlChar *value; /* The Ref name */
+ xmlAttrPtr attr; /* The attribute holding it */
+ const xmlChar *name; /* The attribute if attr is not available */
+ int lineno; /* The line number if attr is not available */
+};
+
+/**
+ * xmlBufferAllocationScheme:
+ *
+ * A buffer allocation scheme can be defined to either match exactly the
+ * need or double it's allocated size each time it is found too small.
+ */
+
+typedef enum {
+ XML_BUFFER_ALLOC_DOUBLEIT,
+ XML_BUFFER_ALLOC_EXACT
+} xmlBufferAllocationScheme;
+
+/**
+ * xmlBuffer:
+ *
+ * A buffer structure.
+ */
+typedef struct _xmlBuffer xmlBuffer;
+typedef xmlBuffer *xmlBufferPtr;
+struct _xmlBuffer {
+ xmlChar *content; /* The buffer content UTF8 */
+ unsigned int use; /* The buffer size used */
+ unsigned int size; /* The buffer size */
+ xmlBufferAllocationScheme alloc; /* The realloc method */
+};
+
+/**
+ * xmlNode:
+ *
+ * A node in an XML tree.
+ */
+typedef struct _xmlNode xmlNode;
+typedef xmlNode *xmlNodePtr;
+struct _xmlNode {
+ void *_private; /* application data */
+ xmlElementType type; /* type number, must be second ! */
+ const xmlChar *name; /* the name of the node, or the entity */
+ struct _xmlNode *children; /* parent->childs link */
+ struct _xmlNode *last; /* last child link */
+ struct _xmlNode *parent; /* child->parent link */
+ struct _xmlNode *next; /* next sibling link */
+ struct _xmlNode *prev; /* previous sibling link */
+ struct _xmlDoc *doc; /* the containing document */
+
+ /* End of common part */
+ xmlNs *ns; /* pointer to the associated namespace */
+ xmlChar *content; /* the content */
+ struct _xmlAttr *properties;/* properties list */
+ xmlNs *nsDef; /* namespace definitions on this node */
+};
+
+/**
+ * XML_GET_CONTENT:
+ *
+ * Macro to extract the content pointer of a node.
+ */
+#define XML_GET_CONTENT(n) \
+ ((n)->type == XML_ELEMENT_NODE ? NULL : (n)->content)
+
+/**
+ * XML_GET_LINE:
+ *
+ * Macro to extract the line number of an element node.
+ * This will work only if line numbering is activated by
+ * calling xmlLineNumbersDefault(1) before parsing.
+ */
+#define XML_GET_LINE(n) \
+ ((n)->type == XML_ELEMENT_NODE ? (int) (n)->content : 0)
+
+/**
+ * xmlDoc:
+ *
+ * An XML document.
+ */
+typedef struct _xmlDoc xmlDoc;
+typedef xmlDoc *xmlDocPtr;
+struct _xmlDoc {
+ void *_private; /* application data */
+ xmlElementType type; /* XML_DOCUMENT_NODE, must be second ! */
+ char *name; /* name/filename/URI of the document */
+ struct _xmlNode *children; /* the document tree */
+ struct _xmlNode *last; /* last child link */
+ struct _xmlNode *parent; /* child->parent link */
+ struct _xmlNode *next; /* next sibling link */
+ struct _xmlNode *prev; /* previous sibling link */
+ struct _xmlDoc *doc; /* autoreference to itself */
+
+ /* End of common part */
+ int compression;/* level of zlib compression */
+ int standalone; /* standalone document (no external refs) */
+ struct _xmlDtd *intSubset; /* the document internal subset */
+ struct _xmlDtd *extSubset; /* the document external subset */
+ struct _xmlNs *oldNs; /* Global namespace, the old way */
+ const xmlChar *version; /* the XML version string */
+ const xmlChar *encoding; /* external initial encoding, if any */
+ void *ids; /* Hash table for ID attributes if any */
+ void *refs; /* Hash table for IDREFs attributes if any */
+ const xmlChar *URL; /* The URI for that document */
+ int charset; /* encoding of the in-memory content
+ actually an xmlCharEncoding */
+};
+
+/**
+ * xmlChildrenNode:
+ *
+ * Macro for compatibility naming layer with libxml1.
+ */
+#ifndef xmlChildrenNode
+#define xmlChildrenNode children
+#endif
+
+/**
+ * xmlRootNode:
+ *
+ * Macro for compatibility naming layer with libxml1.
+ */
+#ifndef xmlRootNode
+#define xmlRootNode children
+#endif
+
+/*
+ * Variables.
+ */
+#if 0
+LIBXML_DLL_IMPORT extern int oldXMLWDcompatibility;/* maintain compatibility with old WD */
+LIBXML_DLL_IMPORT extern int xmlIndentTreeOutput; /* try to indent the tree dumps */
+LIBXML_DLL_IMPORT extern xmlBufferAllocationScheme xmlBufferAllocScheme; /* alloc scheme to use */
+LIBXML_DLL_IMPORT extern int xmlSaveNoEmptyTags; /* save empty tags as <empty></empty> */
+LIBXML_DLL_IMPORT extern int xmlDefaultBufferSize; /* default buffer size */
+#endif
+
+int xmlValidateNCName (const xmlChar *value, int space);
+int xmlValidateQName (const xmlChar *value, int space);
+int xmlValidateName (const xmlChar *value, int space);
+int xmlValidateNMToken (const xmlChar *value, int space);
+
+/*
+ * Handling Buffers.
+ */
+
+void xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme);
+xmlBufferAllocationScheme xmlGetBufferAllocationScheme(void);
+
+xmlBufferPtr xmlBufferCreate (void);
+xmlBufferPtr xmlBufferCreateSize (size_t size);
+int xmlBufferResize (xmlBufferPtr buf,
+ unsigned int size);
+void xmlBufferFree (xmlBufferPtr buf);
+int xmlBufferDump (FILE *file,
+ xmlBufferPtr buf);
+void xmlBufferAdd (xmlBufferPtr buf,
+ const xmlChar *str,
+ int len);
+void xmlBufferAddHead (xmlBufferPtr buf,
+ const xmlChar *str,
+ int len);
+void xmlBufferCat (xmlBufferPtr buf,
+ const xmlChar *str);
+void xmlBufferCCat (xmlBufferPtr buf,
+ const char *str);
+int xmlBufferShrink (xmlBufferPtr buf,
+ unsigned int len);
+int xmlBufferGrow (xmlBufferPtr buf,
+ unsigned int len);
+void xmlBufferEmpty (xmlBufferPtr buf);
+const xmlChar* xmlBufferContent (const xmlBufferPtr buf);
+void xmlBufferSetAllocationScheme(xmlBufferPtr buf,
+ xmlBufferAllocationScheme scheme);
+int xmlBufferLength (const xmlBufferPtr buf);
+
+/*
+ * Creating/freeing new structures.
+ */
+xmlDtdPtr xmlCreateIntSubset (xmlDocPtr doc,
+ const xmlChar *name,
+ const xmlChar *ExternalID,
+ const xmlChar *SystemID);
+xmlDtdPtr xmlNewDtd (xmlDocPtr doc,
+ const xmlChar *name,
+ const xmlChar *ExternalID,
+ const xmlChar *SystemID);
+xmlDtdPtr xmlGetIntSubset (xmlDocPtr doc);
+void xmlFreeDtd (xmlDtdPtr cur);
+xmlNsPtr xmlNewGlobalNs (xmlDocPtr doc,
+ const xmlChar *href,
+ const xmlChar *prefix);
+xmlNsPtr xmlNewNs (xmlNodePtr node,
+ const xmlChar *href,
+ const xmlChar *prefix);
+void xmlFreeNs (xmlNsPtr cur);
+void xmlFreeNsList (xmlNsPtr cur);
+xmlDocPtr xmlNewDoc (const xmlChar *version);
+void xmlFreeDoc (xmlDocPtr cur);
+xmlAttrPtr xmlNewDocProp (xmlDocPtr doc,
+ const xmlChar *name,
+ const xmlChar *value);
+xmlAttrPtr xmlNewProp (xmlNodePtr node,
+ const xmlChar *name,
+ const xmlChar *value);
+xmlAttrPtr xmlNewNsProp (xmlNodePtr node,
+ xmlNsPtr ns,
+ const xmlChar *name,
+ const xmlChar *value);
+xmlAttrPtr xmlNewNsPropEatName (xmlNodePtr node,
+ xmlNsPtr ns,
+ xmlChar *name,
+ const xmlChar *value);
+void xmlFreePropList (xmlAttrPtr cur);
+void xmlFreeProp (xmlAttrPtr cur);
+xmlAttrPtr xmlCopyProp (xmlNodePtr target,
+ xmlAttrPtr cur);
+xmlAttrPtr xmlCopyPropList (xmlNodePtr target,
+ xmlAttrPtr cur);
+xmlDtdPtr xmlCopyDtd (xmlDtdPtr dtd);
+xmlDocPtr xmlCopyDoc (xmlDocPtr doc,
+ int recursive);
+
+/*
+ * Creating new nodes.
+ */
+xmlNodePtr xmlNewDocNode (xmlDocPtr doc,
+ xmlNsPtr ns,
+ const xmlChar *name,
+ const xmlChar *content);
+xmlNodePtr xmlNewDocNodeEatName (xmlDocPtr doc,
+ xmlNsPtr ns,
+ xmlChar *name,
+ const xmlChar *content);
+xmlNodePtr xmlNewDocRawNode (xmlDocPtr doc,
+ xmlNsPtr ns,
+ const xmlChar *name,
+ const xmlChar *content);
+xmlNodePtr xmlNewNode (xmlNsPtr ns,
+ const xmlChar *name);
+xmlNodePtr xmlNewNodeEatName (xmlNsPtr ns,
+ xmlChar *name);
+xmlNodePtr xmlNewChild (xmlNodePtr parent,
+ xmlNsPtr ns,
+ const xmlChar *name,
+ const xmlChar *content);
+xmlNodePtr xmlNewTextChild (xmlNodePtr parent,
+ xmlNsPtr ns,
+ const xmlChar *name,
+ const xmlChar *content);
+xmlNodePtr xmlNewDocText (xmlDocPtr doc,
+ const xmlChar *content);
+xmlNodePtr xmlNewText (const xmlChar *content);
+xmlNodePtr xmlNewPI (const xmlChar *name,
+ const xmlChar *content);
+xmlNodePtr xmlNewDocTextLen (xmlDocPtr doc,
+ const xmlChar *content,
+ int len);
+xmlNodePtr xmlNewTextLen (const xmlChar *content,
+ int len);
+xmlNodePtr xmlNewDocComment (xmlDocPtr doc,
+ const xmlChar *content);
+xmlNodePtr xmlNewComment (const xmlChar *content);
+xmlNodePtr xmlNewCDataBlock (xmlDocPtr doc,
+ const xmlChar *content,
+ int len);
+xmlNodePtr xmlNewCharRef (xmlDocPtr doc,
+ const xmlChar *name);
+xmlNodePtr xmlNewReference (xmlDocPtr doc,
+ const xmlChar *name);
+xmlNodePtr xmlCopyNode (const xmlNodePtr node,
+ int recursive);
+xmlNodePtr xmlDocCopyNode (const xmlNodePtr node,
+ xmlDocPtr doc,
+ int recursive);
+xmlNodePtr xmlCopyNodeList (const xmlNodePtr node);
+xmlNodePtr xmlNewDocFragment (xmlDocPtr doc);
+
+/*
+ * Navigating.
+ */
+long xmlGetLineNo (xmlNodePtr node);
+xmlChar * xmlGetNodePath (xmlNodePtr node);
+xmlNodePtr xmlDocGetRootElement (xmlDocPtr doc);
+xmlNodePtr xmlGetLastChild (xmlNodePtr parent);
+int xmlNodeIsText (xmlNodePtr node);
+int xmlIsBlankNode (xmlNodePtr node);
+
+/*
+ * Changing the structure.
+ */
+xmlNodePtr xmlDocSetRootElement (xmlDocPtr doc,
+ xmlNodePtr root);
+void xmlNodeSetName (xmlNodePtr cur,
+ const xmlChar *name);
+xmlNodePtr xmlAddChild (xmlNodePtr parent,
+ xmlNodePtr cur);
+xmlNodePtr xmlAddChildList (xmlNodePtr parent,
+ xmlNodePtr cur);
+xmlNodePtr xmlReplaceNode (xmlNodePtr old,
+ xmlNodePtr cur);
+xmlNodePtr xmlAddSibling (xmlNodePtr cur,
+ xmlNodePtr elem);
+xmlNodePtr xmlAddPrevSibling (xmlNodePtr cur,
+ xmlNodePtr elem);
+xmlNodePtr xmlAddNextSibling (xmlNodePtr cur,
+ xmlNodePtr elem);
+void xmlUnlinkNode (xmlNodePtr cur);
+xmlNodePtr xmlTextMerge (xmlNodePtr first,
+ xmlNodePtr second);
+void xmlTextConcat (xmlNodePtr node,
+ const xmlChar *content,
+ int len);
+void xmlFreeNodeList (xmlNodePtr cur);
+void xmlFreeNode (xmlNodePtr cur);
+void xmlSetTreeDoc (xmlNodePtr tree,
+ xmlDocPtr doc);
+void xmlSetListDoc (xmlNodePtr list,
+ xmlDocPtr doc);
+
+/*
+ * Namespaces.
+ */
+xmlNsPtr xmlSearchNs (xmlDocPtr doc,
+ xmlNodePtr node,
+ const xmlChar *nameSpace);
+xmlNsPtr xmlSearchNsByHref (xmlDocPtr doc,
+ xmlNodePtr node,
+ const xmlChar *href);
+xmlNsPtr * xmlGetNsList (xmlDocPtr doc,
+ xmlNodePtr node);
+void xmlSetNs (xmlNodePtr node,
+ xmlNsPtr ns);
+xmlNsPtr xmlCopyNamespace (xmlNsPtr cur);
+xmlNsPtr xmlCopyNamespaceList (xmlNsPtr cur);
+
+/*
+ * Changing the content.
+ */
+xmlAttrPtr xmlSetProp (xmlNodePtr node,
+ const xmlChar *name,
+ const xmlChar *value);
+xmlChar * xmlGetProp (xmlNodePtr node,
+ const xmlChar *name);
+xmlChar * xmlGetNoNsProp (xmlNodePtr node,
+ const xmlChar *name);
+xmlAttrPtr xmlHasProp (xmlNodePtr node,
+ const xmlChar *name);
+xmlAttrPtr xmlHasNsProp (xmlNodePtr node,
+ const xmlChar *name,
+ const xmlChar *nameSpace);
+xmlAttrPtr xmlSetNsProp (xmlNodePtr node,
+ xmlNsPtr ns,
+ const xmlChar *name,
+ const xmlChar *value);
+xmlChar * xmlGetNsProp (xmlNodePtr node,
+ const xmlChar *name,
+ const xmlChar *nameSpace);
+xmlNodePtr xmlStringGetNodeList (xmlDocPtr doc,
+ const xmlChar *value);
+xmlNodePtr xmlStringLenGetNodeList (xmlDocPtr doc,
+ const xmlChar *value,
+ int len);
+xmlChar * xmlNodeListGetString (xmlDocPtr doc,
+ xmlNodePtr list,
+ int inLine);
+xmlChar * xmlNodeListGetRawString (xmlDocPtr doc,
+ xmlNodePtr list,
+ int inLine);
+void xmlNodeSetContent (xmlNodePtr cur,
+ const xmlChar *content);
+void xmlNodeSetContentLen (xmlNodePtr cur,
+ const xmlChar *content,
+ int len);
+void xmlNodeAddContent (xmlNodePtr cur,
+ const xmlChar *content);
+void xmlNodeAddContentLen (xmlNodePtr cur,
+ const xmlChar *content,
+ int len);
+xmlChar * xmlNodeGetContent (xmlNodePtr cur);
+xmlChar * xmlNodeGetLang (xmlNodePtr cur);
+void xmlNodeSetLang (xmlNodePtr cur,
+ const xmlChar *lang);
+int xmlNodeGetSpacePreserve (xmlNodePtr cur);
+void xmlNodeSetSpacePreserve (xmlNodePtr cur,
+ int val);
+xmlChar * xmlNodeGetBase (xmlDocPtr doc,
+ xmlNodePtr cur);
+void xmlNodeSetBase (xmlNodePtr cur,
+ xmlChar *uri);
+
+/*
+ * Removing content.
+ */
+int xmlRemoveProp (xmlAttrPtr cur);
+int xmlUnsetProp (xmlNodePtr node,
+ const xmlChar *name);
+int xmlUnsetNsProp (xmlNodePtr node,
+ xmlNsPtr ns,
+ const xmlChar *name);
+
+/*
+ * Internal, don't use.
+ */
+void xmlBufferWriteCHAR (xmlBufferPtr buf,
+ const xmlChar *string);
+void xmlBufferWriteChar (xmlBufferPtr buf,
+ const char *string);
+void xmlBufferWriteQuotedString(xmlBufferPtr buf,
+ const xmlChar *string);
+
+/*
+ * Namespace handling.
+ */
+int xmlReconciliateNs (xmlDocPtr doc,
+ xmlNodePtr tree);
+
+/*
+ * Saving.
+ */
+void xmlDocDumpFormatMemory (xmlDocPtr cur,
+ xmlChar **mem,
+ int *size,
+ int format);
+void xmlDocDumpMemory (xmlDocPtr cur,
+ xmlChar **mem,
+ int *size);
+void xmlDocDumpMemoryEnc (xmlDocPtr out_doc,
+ xmlChar **doc_txt_ptr,
+ int * doc_txt_len,
+ const char *txt_encoding);
+void xmlDocDumpFormatMemoryEnc(xmlDocPtr out_doc,
+ xmlChar **doc_txt_ptr,
+ int * doc_txt_len,
+ const char *txt_encoding,
+ int format);
+int xmlDocFormatDump(FILE *f,
+ xmlDocPtr cur,
+ int format);
+int xmlDocDump (FILE *f,
+ xmlDocPtr cur);
+void xmlElemDump (FILE *f,
+ xmlDocPtr doc,
+ xmlNodePtr cur);
+int xmlSaveFile (const char *filename,
+ xmlDocPtr cur);
+int xmlSaveFormatFile (const char *filename,
+ xmlDocPtr cur,
+ int format);
+int xmlNodeDump (xmlBufferPtr buf,
+ xmlDocPtr doc,
+ xmlNodePtr cur,
+ int level,
+ int format);
+
+int xmlSaveFileTo (xmlOutputBufferPtr buf,
+ xmlDocPtr cur,
+ const char *encoding);
+int xmlSaveFormatFileTo (xmlOutputBufferPtr buf,
+ xmlDocPtr cur,
+ const char *encoding,
+ int format);
+void xmlNodeDumpOutput (xmlOutputBufferPtr buf,
+ xmlDocPtr doc,
+ xmlNodePtr cur,
+ int level,
+ int format,
+ const char *encoding);
+
+int xmlSaveFormatFileEnc (const char *filename,
+ xmlDocPtr cur,
+ const char *encoding,
+ int format);
+
+int xmlSaveFileEnc (const char *filename,
+ xmlDocPtr cur,
+ const char *encoding);
+
+/*
+ * XHTML
+ */
+int xmlIsXHTML (const xmlChar *systemID,
+ const xmlChar *publicID);
+
+/*
+ * Compression.
+ */
+int xmlGetDocCompressMode (xmlDocPtr doc);
+void xmlSetDocCompressMode (xmlDocPtr doc,
+ int mode);
+int xmlGetCompressMode (void);
+void xmlSetCompressMode (int mode);
+
+#ifdef __cplusplus
+}
+#endif
+#ifndef __XML_PARSER_H__
+#include <libxml/xmlmemory.h>
+#endif
+
+#endif /* __XML_TREE_H__ */
+
diff --git a/plugins/Variables/src/libxml/uri.h b/plugins/Variables/src/libxml/uri.h
new file mode 100644
index 0000000000..319c509d1b
--- /dev/null
+++ b/plugins/Variables/src/libxml/uri.h
@@ -0,0 +1,68 @@
+/**
+ * uri.c: library of generic URI related routines
+ *
+ * Reference: RFC 2396
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifndef __XML_URI_H__
+#define __XML_URI_H__
+
+#include <libxml/tree.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * xmlURI:
+ *
+ * A parsed URI reference. This is a struct containing the various fields
+ * as described in RFC 2396 but separated for further processing.
+ */
+typedef struct _xmlURI xmlURI;
+typedef xmlURI *xmlURIPtr;
+struct _xmlURI {
+ char *scheme; /* the URI scheme */
+ char *opaque; /* opaque part */
+ char *authority; /* the authority part */
+ char *server; /* the server part */
+ char *user; /* the user part */
+ int port; /* the port number */
+ char *path; /* the path string */
+ char *query; /* the query string */
+ char *fragment; /* the fragment identifier */
+ int cleanup; /* parsing potentially unclean URI */
+};
+
+/*
+ * This function is in tree.h:
+ * xmlChar * xmlNodeGetBase (xmlDocPtr doc,
+ * xmlNodePtr cur);
+ */
+xmlURIPtr xmlCreateURI (void);
+xmlChar * xmlBuildURI (const xmlChar *URI,
+ const xmlChar *base);
+xmlURIPtr xmlParseURI (const char *str);
+int xmlParseURIReference (xmlURIPtr uri,
+ const char *str);
+xmlChar * xmlSaveUri (xmlURIPtr uri);
+void xmlPrintURI (FILE *stream,
+ xmlURIPtr uri);
+xmlChar * xmlURIEscapeStr (const xmlChar *str,
+ const xmlChar *list);
+char * xmlURIUnescapeString (const char *str,
+ int len,
+ char *target);
+int xmlNormalizeURIPath (char *path);
+xmlChar * xmlURIEscape (const xmlChar *str);
+void xmlFreeURI (xmlURIPtr uri);
+xmlChar* xmlCanonicPath (const xmlChar *path);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_URI_H__ */
diff --git a/plugins/Variables/src/libxml/valid.h b/plugins/Variables/src/libxml/valid.h
new file mode 100644
index 0000000000..dbf2aba562
--- /dev/null
+++ b/plugins/Variables/src/libxml/valid.h
@@ -0,0 +1,330 @@
+/*
+ * valid.h : interface to the DTD handling and the validity checking
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+
+#ifndef __XML_VALID_H__
+#define __XML_VALID_H__
+
+#include "libxml/tree.h"
+#include "libxml/list.h"
+#include "libxml/xmlautomata.h"
+#include "libxml/xmlregexp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Validation state added for non-determinist content model.
+ */
+typedef struct _xmlValidState xmlValidState;
+typedef xmlValidState *xmlValidStatePtr;
+
+/**
+ * xmlValidityErrorFunc:
+ * @ctx: an xmlValidCtxtPtr validity error context
+ * @msg: the string to format *printf like vararg
+ * @...: remaining arguments to the format
+ *
+ * Callback called when a validity error is found. This is a message
+ * oriented function similar to an *printf function.
+ */
+typedef void (*xmlValidityErrorFunc) (void *ctx,
+ const char *msg,
+ ...);
+
+/**
+ * xmlValidityWarningFunc:
+ * @ctx: an xmlValidCtxtPtr validity error context
+ * @msg: the string to format *printf like vararg
+ * @...: remaining arguments to the format
+ *
+ * Callback called when a validity warning is found. This is a message
+ * oriented function similar to an *printf function.
+ */
+typedef void (*xmlValidityWarningFunc) (void *ctx,
+ const char *msg,
+ ...);
+
+/**
+ * xmlValidCtxt:
+ * An xmlValidCtxt is used for error reporting when validating.
+ */
+typedef struct _xmlValidCtxt xmlValidCtxt;
+typedef xmlValidCtxt *xmlValidCtxtPtr;
+struct _xmlValidCtxt {
+ void *userData; /* user specific data block */
+ xmlValidityErrorFunc error; /* the callback in case of errors */
+ xmlValidityWarningFunc warning; /* the callback in case of warning */
+
+ /* Node analysis stack used when validating within entities */
+ xmlNodePtr node; /* Current parsed Node */
+ int nodeNr; /* Depth of the parsing stack */
+ int nodeMax; /* Max depth of the parsing stack */
+ xmlNodePtr *nodeTab; /* array of nodes */
+
+ int finishDtd; /* finished validating the Dtd ? */
+ xmlDocPtr doc; /* the document */
+ int valid; /* temporary validity check result */
+
+ /* state state used for non-determinist content validation */
+ xmlValidState *vstate; /* current state */
+ int vstateNr; /* Depth of the validation stack */
+ int vstateMax; /* Max depth of the validation stack */
+ xmlValidState *vstateTab; /* array of validation states */
+
+#ifdef LIBXML_REGEXP_ENABLED
+ xmlAutomataPtr am; /* the automata */
+ xmlAutomataStatePtr state; /* used to build the automata */
+#else
+ void *am;
+ void *state;
+#endif
+};
+
+/*
+ * ALL notation declarations are stored in a table.
+ * There is one table per DTD.
+ */
+
+typedef struct _xmlHashTable xmlNotationTable;
+typedef xmlNotationTable *xmlNotationTablePtr;
+
+/*
+ * ALL element declarations are stored in a table.
+ * There is one table per DTD.
+ */
+
+typedef struct _xmlHashTable xmlElementTable;
+typedef xmlElementTable *xmlElementTablePtr;
+
+/*
+ * ALL attribute declarations are stored in a table.
+ * There is one table per DTD.
+ */
+
+typedef struct _xmlHashTable xmlAttributeTable;
+typedef xmlAttributeTable *xmlAttributeTablePtr;
+
+/*
+ * ALL IDs attributes are stored in a table.
+ * There is one table per document.
+ */
+
+typedef struct _xmlHashTable xmlIDTable;
+typedef xmlIDTable *xmlIDTablePtr;
+
+/*
+ * ALL Refs attributes are stored in a table.
+ * There is one table per document.
+ */
+
+typedef struct _xmlHashTable xmlRefTable;
+typedef xmlRefTable *xmlRefTablePtr;
+
+/* helper */
+xmlChar * xmlSplitQName2 (const xmlChar *name,
+ xmlChar **prefix);
+
+/* Notation */
+xmlNotationPtr xmlAddNotationDecl (xmlValidCtxtPtr ctxt,
+ xmlDtdPtr dtd,
+ const xmlChar *name,
+ const xmlChar *PublicID,
+ const xmlChar *SystemID);
+xmlNotationTablePtr xmlCopyNotationTable(xmlNotationTablePtr table);
+void xmlFreeNotationTable(xmlNotationTablePtr table);
+void xmlDumpNotationDecl (xmlBufferPtr buf,
+ xmlNotationPtr nota);
+void xmlDumpNotationTable(xmlBufferPtr buf,
+ xmlNotationTablePtr table);
+
+/* Element Content */
+xmlElementContentPtr xmlNewElementContent (xmlChar *name,
+ xmlElementContentType type);
+xmlElementContentPtr xmlCopyElementContent(xmlElementContentPtr content);
+void xmlFreeElementContent(xmlElementContentPtr cur);
+void xmlSnprintfElementContent(char *buf,
+ int size,
+ xmlElementContentPtr content,
+ int glob);
+/* DEPRECATED */
+void xmlSprintfElementContent(char *buf,
+ xmlElementContentPtr content,
+ int glob);
+/* DEPRECATED */
+
+/* Element */
+xmlElementPtr xmlAddElementDecl (xmlValidCtxtPtr ctxt,
+ xmlDtdPtr dtd,
+ const xmlChar *name,
+ xmlElementTypeVal type,
+ xmlElementContentPtr content);
+xmlElementTablePtr xmlCopyElementTable (xmlElementTablePtr table);
+void xmlFreeElementTable (xmlElementTablePtr table);
+void xmlDumpElementTable (xmlBufferPtr buf,
+ xmlElementTablePtr table);
+void xmlDumpElementDecl (xmlBufferPtr buf,
+ xmlElementPtr elem);
+
+/* Enumeration */
+xmlEnumerationPtr xmlCreateEnumeration (xmlChar *name);
+void xmlFreeEnumeration (xmlEnumerationPtr cur);
+xmlEnumerationPtr xmlCopyEnumeration (xmlEnumerationPtr cur);
+
+/* Attribute */
+xmlAttributePtr xmlAddAttributeDecl (xmlValidCtxtPtr ctxt,
+ xmlDtdPtr dtd,
+ const xmlChar *elem,
+ const xmlChar *name,
+ const xmlChar *ns,
+ xmlAttributeType type,
+ xmlAttributeDefault def,
+ const xmlChar *defaultValue,
+ xmlEnumerationPtr tree);
+xmlAttributeTablePtr xmlCopyAttributeTable (xmlAttributeTablePtr table);
+void xmlFreeAttributeTable (xmlAttributeTablePtr table);
+void xmlDumpAttributeTable (xmlBufferPtr buf,
+ xmlAttributeTablePtr table);
+void xmlDumpAttributeDecl (xmlBufferPtr buf,
+ xmlAttributePtr attr);
+
+/* IDs */
+xmlIDPtr xmlAddID (xmlValidCtxtPtr ctxt,
+ xmlDocPtr doc,
+ const xmlChar *value,
+ xmlAttrPtr attr);
+void xmlFreeIDTable (xmlIDTablePtr table);
+xmlAttrPtr xmlGetID (xmlDocPtr doc,
+ const xmlChar *ID);
+int xmlIsID (xmlDocPtr doc,
+ xmlNodePtr elem,
+ xmlAttrPtr attr);
+int xmlRemoveID (xmlDocPtr doc, xmlAttrPtr attr);
+
+/* IDREFs */
+xmlRefPtr xmlAddRef (xmlValidCtxtPtr ctxt,
+ xmlDocPtr doc,
+ const xmlChar *value,
+ xmlAttrPtr attr);
+void xmlFreeRefTable (xmlRefTablePtr table);
+int xmlIsRef (xmlDocPtr doc,
+ xmlNodePtr elem,
+ xmlAttrPtr attr);
+int xmlRemoveRef (xmlDocPtr doc, xmlAttrPtr attr);
+xmlListPtr xmlGetRefs (xmlDocPtr doc,
+ const xmlChar *ID);
+
+/**
+ * The public function calls related to validity checking.
+ */
+
+int xmlValidateRoot (xmlValidCtxtPtr ctxt,
+ xmlDocPtr doc);
+int xmlValidateElementDecl (xmlValidCtxtPtr ctxt,
+ xmlDocPtr doc,
+ xmlElementPtr elem);
+xmlChar * xmlValidNormalizeAttributeValue(xmlDocPtr doc,
+ xmlNodePtr elem,
+ const xmlChar *name,
+ const xmlChar *value);
+xmlChar * xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt,
+ xmlDocPtr doc,
+ xmlNodePtr elem,
+ const xmlChar *name,
+ const xmlChar *value);
+int xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt,
+ xmlDocPtr doc,
+ xmlAttributePtr attr);
+int xmlValidateAttributeValue(xmlAttributeType type,
+ const xmlChar *value);
+int xmlValidateNotationDecl (xmlValidCtxtPtr ctxt,
+ xmlDocPtr doc,
+ xmlNotationPtr nota);
+int xmlValidateDtd (xmlValidCtxtPtr ctxt,
+ xmlDocPtr doc,
+ xmlDtdPtr dtd);
+int xmlValidateDtdFinal (xmlValidCtxtPtr ctxt,
+ xmlDocPtr doc);
+int xmlValidateDocument (xmlValidCtxtPtr ctxt,
+ xmlDocPtr doc);
+int xmlValidateElement (xmlValidCtxtPtr ctxt,
+ xmlDocPtr doc,
+ xmlNodePtr elem);
+int xmlValidateOneElement (xmlValidCtxtPtr ctxt,
+ xmlDocPtr doc,
+ xmlNodePtr elem);
+int xmlValidateOneAttribute (xmlValidCtxtPtr ctxt,
+ xmlDocPtr doc,
+ xmlNodePtr elem,
+ xmlAttrPtr attr,
+ const xmlChar *value);
+int xmlValidateOneNamespace (xmlValidCtxtPtr ctxt,
+ xmlDocPtr doc,
+ xmlNodePtr elem,
+ const xmlChar *prefix,
+ xmlNsPtr ns,
+ const xmlChar *value);
+int xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt,
+ xmlDocPtr doc);
+int xmlValidateNotationUse (xmlValidCtxtPtr ctxt,
+ xmlDocPtr doc,
+ const xmlChar *notationName);
+int xmlIsMixedElement (xmlDocPtr doc,
+ const xmlChar *name);
+xmlAttributePtr xmlGetDtdAttrDesc (xmlDtdPtr dtd,
+ const xmlChar *elem,
+ const xmlChar *name);
+xmlAttributePtr xmlGetDtdQAttrDesc (xmlDtdPtr dtd,
+ const xmlChar *elem,
+ const xmlChar *name,
+ const xmlChar *prefix);
+xmlNotationPtr xmlGetDtdNotationDesc (xmlDtdPtr dtd,
+ const xmlChar *name);
+xmlElementPtr xmlGetDtdQElementDesc (xmlDtdPtr dtd,
+ const xmlChar *name,
+ const xmlChar *prefix);
+xmlElementPtr xmlGetDtdElementDesc (xmlDtdPtr dtd,
+ const xmlChar *name);
+
+int xmlValidGetValidElements(xmlNode *prev,
+ xmlNode *next,
+ const xmlChar **list,
+ int max);
+int xmlValidGetPotentialChildren(xmlElementContent *ctree,
+ const xmlChar **list,
+ int *len,
+ int max);
+int xmlValidateNameValue (const xmlChar *value);
+int xmlValidateNamesValue (const xmlChar *value);
+int xmlValidateNmtokenValue (const xmlChar *value);
+int xmlValidateNmtokensValue(const xmlChar *value);
+
+#ifdef LIBXML_REGEXP_ENABLED
+/*
+ * Validation based on the regexp support
+ */
+int xmlValidBuildContentModel(xmlValidCtxtPtr ctxt,
+ xmlElementPtr elem);
+
+int xmlValidatePushElement (xmlValidCtxtPtr ctxt,
+ xmlDocPtr doc,
+ xmlNodePtr elem,
+ const xmlChar *qname);
+int xmlValidatePushCData (xmlValidCtxtPtr ctxt,
+ const xmlChar *data,
+ int len);
+int xmlValidatePopElement (xmlValidCtxtPtr ctxt,
+ xmlDocPtr doc,
+ xmlNodePtr elem,
+ const xmlChar *qname);
+#endif /* LIBXML_REGEXP_ENABLED */
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_VALID_H__ */
diff --git a/plugins/Variables/src/libxml/xinclude.h b/plugins/Variables/src/libxml/xinclude.h
new file mode 100644
index 0000000000..f59020f7a2
--- /dev/null
+++ b/plugins/Variables/src/libxml/xinclude.h
@@ -0,0 +1,26 @@
+/*
+ * xinclude.c : API to handle XInclude processing
+ *
+ * World Wide Web Consortium Working Draft 26 October 2000
+ * http://www.w3.org/TR/2000/WD-xinclude-20001026
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifndef __XML_XINCLUDE_H__
+#define __XML_XINCLUDE_H__
+
+#include "libxml/tree.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int xmlXIncludeProcess (xmlDocPtr doc);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_XINCLUDE_H__ */
diff --git a/plugins/Variables/src/libxml/xlink.h b/plugins/Variables/src/libxml/xlink.h
new file mode 100644
index 0000000000..b5a0f91067
--- /dev/null
+++ b/plugins/Variables/src/libxml/xlink.h
@@ -0,0 +1,180 @@
+/*
+ * xlink.h : interfaces to the hyperlinks detection module
+ *
+ * See Copyright for the status of this software.
+ *
+ * Related specification: http://www.w3.org/TR/xlink
+ * http://www.w3.org/HTML/
+ * and XBase
+ *
+ * daniel@veillard.com
+ */
+
+#ifndef __XML_XLINK_H__
+#define __XML_XLINK_H__
+
+#include "libxml/tree.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * Various defines for the various Link properties.
+ *
+ * NOTE: the link detection layer will try to resolve QName expansion
+ * of namespaces. If "foo" is the prefix for "http://foo.com/"
+ * then the link detection layer will expand role="foo:myrole"
+ * to "http://foo.com/:myrole".
+ * NOTE: the link detection layer will expand URI-Refences found on
+ * href attributes by using the base mechanism if found.
+ */
+typedef xmlChar *xlinkHRef;
+typedef xmlChar *xlinkRole;
+typedef xmlChar *xlinkTitle;
+
+typedef enum {
+ XLINK_TYPE_NONE = 0,
+ XLINK_TYPE_SIMPLE,
+ XLINK_TYPE_EXTENDED,
+ XLINK_TYPE_EXTENDED_SET
+} xlinkType;
+
+typedef enum {
+ XLINK_SHOW_NONE = 0,
+ XLINK_SHOW_NEW,
+ XLINK_SHOW_EMBED,
+ XLINK_SHOW_REPLACE
+} xlinkShow;
+
+typedef enum {
+ XLINK_ACTUATE_NONE = 0,
+ XLINK_ACTUATE_AUTO,
+ XLINK_ACTUATE_ONREQUEST
+} xlinkActuate;
+
+/**
+ * xlinkNodeDetectFunc:
+ * @ctx: user data pointer
+ * @node: the node to check
+ *
+ * This is the prototype for the link detection routine.
+ * It calls the default link detection callbacks upon link detection.
+ */
+typedef void (*xlinkNodeDetectFunc) (void *ctx, xmlNodePtr node);
+
+/**
+ * The link detection module interact with the upper layers using
+ * a set of callback registered at parsing time.
+ */
+
+/**
+ * xlinkSimpleLinkFunk:
+ * @ctx: user data pointer
+ * @node: the node carrying the link
+ * @href: the target of the link
+ * @role: the role string
+ * @title: the link title
+ *
+ * This is the prototype for a simple link detection callback.
+ */
+typedef void
+(*xlinkSimpleLinkFunk) (void *ctx,
+ xmlNodePtr node,
+ const xlinkHRef href,
+ const xlinkRole role,
+ const xlinkTitle title);
+
+/**
+ * xlinkExtendedLinkFunk:
+ * @ctx: user data pointer
+ * @node: the node carrying the link
+ * @nbLocators: the number of locators detected on the link
+ * @hrefs: pointer to the array of locator hrefs
+ * @roles: pointer to the array of locator roles
+ * @nbArcs: the number of arcs detected on the link
+ * @from: pointer to the array of source roles found on the arcs
+ * @to: pointer to the array of target roles found on the arcs
+ * @show: array of values for the show attributes found on the arcs
+ * @actuate: array of values for the actuate attributes found on the arcs
+ * @nbTitles: the number of titles detected on the link
+ * @title: array of titles detected on the link
+ * @langs: array of xml:lang values for the titles
+ *
+ * This is the prototype for a extended link detection callback.
+ */
+typedef void
+(*xlinkExtendedLinkFunk)(void *ctx,
+ xmlNodePtr node,
+ int nbLocators,
+ const xlinkHRef *hrefs,
+ const xlinkRole *roles,
+ int nbArcs,
+ const xlinkRole *from,
+ const xlinkRole *to,
+ xlinkShow *show,
+ xlinkActuate *actuate,
+ int nbTitles,
+ const xlinkTitle *titles,
+ const xmlChar **langs);
+
+/**
+ * xlinkExtendedLinkSetFunk:
+ * @ctx: user data pointer
+ * @node: the node carrying the link
+ * @nbLocators: the number of locators detected on the link
+ * @hrefs: pointer to the array of locator hrefs
+ * @roles: pointer to the array of locator roles
+ * @nbTitles: the number of titles detected on the link
+ * @title: array of titles detected on the link
+ * @langs: array of xml:lang values for the titles
+ *
+ * This is the prototype for a extended link set detection callback.
+ */
+typedef void
+(*xlinkExtendedLinkSetFunk) (void *ctx,
+ xmlNodePtr node,
+ int nbLocators,
+ const xlinkHRef *hrefs,
+ const xlinkRole *roles,
+ int nbTitles,
+ const xlinkTitle *titles,
+ const xmlChar **langs);
+
+/**
+ * This is the structure containing a set of Links detection callbacks.
+ *
+ * There is no default xlink callbacks, if one want to get link
+ * recognition activated, those call backs must be provided before parsing.
+ */
+typedef struct _xlinkHandler xlinkHandler;
+typedef xlinkHandler *xlinkHandlerPtr;
+struct _xlinkHandler {
+ xlinkSimpleLinkFunk simple;
+ xlinkExtendedLinkFunk extended;
+ xlinkExtendedLinkSetFunk set;
+};
+
+/*
+ * The default detection routine, can be overridden, they call the default
+ * detection callbacks.
+ */
+
+xlinkNodeDetectFunc xlinkGetDefaultDetect (void);
+void xlinkSetDefaultDetect (xlinkNodeDetectFunc func);
+
+/*
+ * Routines to set/get the default handlers.
+ */
+xlinkHandlerPtr xlinkGetDefaultHandler (void);
+void xlinkSetDefaultHandler (xlinkHandlerPtr handler);
+
+/*
+ * Link detection module itself.
+ */
+xlinkType xlinkIsLink (xmlDocPtr doc,
+ xmlNodePtr node);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_XLINK_H__ */
diff --git a/plugins/Variables/src/libxml/xmlIO.h b/plugins/Variables/src/libxml/xmlIO.h
new file mode 100644
index 0000000000..a6870fc51b
--- /dev/null
+++ b/plugins/Variables/src/libxml/xmlIO.h
@@ -0,0 +1,287 @@
+/*
+ * xmlIO.h : interface for the I/O interfaces used by the parser
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ *
+ */
+
+#ifndef __XML_IO_H__
+#define __XML_IO_H__
+
+#include <stdio.h>
+#include "libxml/xmlversion.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Those are the functions and datatypes for the parser input
+ * I/O structures.
+ */
+
+/**
+ * xmlInputMatchCallback:
+ * @filename: the filename or URI
+ *
+ * Callback used in the I/O Input API to detect if the current handler
+ * can provide input fonctionnalities for this resource.
+ *
+ * Returns 1 if yes and 0 if another Input module should be used
+ */
+typedef int (*xmlInputMatchCallback) (char const *filename);
+/**
+ * xmlInputOpenCallback:
+ * @filename: the filename or URI
+ *
+ * Callback used in the I/O Input API to open the resource
+ *
+ * Returns an Input context or NULL in case or error
+ */
+typedef void * (*xmlInputOpenCallback) (char const *filename);
+/**
+ * xmlInputReadCallback:
+ * @context: an Input context
+ * @buffer: the buffer to store data read
+ * @len: the length of the buffer in bytes
+ *
+ * Callback used in the I/O Input API to read the resource
+ *
+ * Returns the number of bytes read or -1 in case of error
+ */
+typedef int (*xmlInputReadCallback) (void * context, char * buffer, int len);
+/**
+ * xmlInputCloseCallback:
+ * @context: an Input context
+ *
+ * Callback used in the I/O Input API to close the resource
+ *
+ * Returns 0 or -1 in case of error
+ */
+typedef int (*xmlInputCloseCallback) (void * context);
+
+/*
+ * Those are the functions and datatypes for the library output
+ * I/O structures.
+ */
+
+/**
+ * xmlOutputMatchCallback:
+ * @filename: the filename or URI
+ *
+ * Callback used in the I/O Output API to detect if the current handler
+ * can provide output fonctionnalities for this resource.
+ *
+ * Returns 1 if yes and 0 if another Output module should be used
+ */
+typedef int (*xmlOutputMatchCallback) (char const *filename);
+/**
+ * xmlOutputOpenCallback:
+ * @filename: the filename or URI
+ *
+ * Callback used in the I/O Output API to open the resource
+ *
+ * Returns an Output context or NULL in case or error
+ */
+typedef void * (*xmlOutputOpenCallback) (char const *filename);
+/**
+ * xmlOutputWriteCallback:
+ * @context: an Output context
+ * @buffer: the buffer of data to write
+ * @len: the length of the buffer in bytes
+ *
+ * Callback used in the I/O Output API to write to the resource
+ *
+ * Returns the number of bytes written or -1 in case of error
+ */
+typedef int (*xmlOutputWriteCallback) (void * context, const char * buffer,
+ int len);
+/**
+ * xmlOutputCloseCallback:
+ * @context: an Output context
+ *
+ * Callback used in the I/O Output API to close the resource
+ *
+ * Returns 0 or -1 in case of error
+ */
+typedef int (*xmlOutputCloseCallback) (void * context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "libxml/globals.h"
+#include "libxml/tree.h"
+#include "libxml/parser.h"
+#include "libxml/encoding.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+struct _xmlParserInputBuffer {
+ void* context;
+ xmlInputReadCallback readcallback;
+ xmlInputCloseCallback closecallback;
+
+ xmlCharEncodingHandlerPtr encoder; /* I18N conversions to UTF-8 */
+
+ xmlBufferPtr buffer; /* Local buffer encoded in UTF-8 */
+ xmlBufferPtr raw; /* if encoder != NULL buffer for raw input */
+};
+
+
+struct _xmlOutputBuffer {
+ void* context;
+ xmlOutputWriteCallback writecallback;
+ xmlOutputCloseCallback closecallback;
+
+ xmlCharEncodingHandlerPtr encoder; /* I18N conversions to UTF-8 */
+
+ xmlBufferPtr buffer; /* Local buffer encoded in UTF-8 or ISOLatin */
+ xmlBufferPtr conv; /* if encoder != NULL buffer for output */
+ int written; /* total number of byte written */
+};
+
+/*
+ * Interfaces for input
+ */
+void xmlCleanupInputCallbacks (void);
+void xmlCleanupOutputCallbacks (void);
+
+void xmlRegisterDefaultInputCallbacks (void);
+xmlParserInputBufferPtr
+ xmlAllocParserInputBuffer (xmlCharEncoding enc);
+
+xmlParserInputBufferPtr
+ xmlParserInputBufferCreateFilename (const char *URI,
+ xmlCharEncoding enc);
+xmlParserInputBufferPtr
+ xmlParserInputBufferCreateFile (FILE *file,
+ xmlCharEncoding enc);
+xmlParserInputBufferPtr
+ xmlParserInputBufferCreateFd (int fd,
+ xmlCharEncoding enc);
+xmlParserInputBufferPtr
+ xmlParserInputBufferCreateMem (const char *mem, int size,
+ xmlCharEncoding enc);
+xmlParserInputBufferPtr
+ xmlParserInputBufferCreateIO (xmlInputReadCallback ioread,
+ xmlInputCloseCallback ioclose,
+ void *ioctx,
+ xmlCharEncoding enc);
+int xmlParserInputBufferRead (xmlParserInputBufferPtr in,
+ int len);
+int xmlParserInputBufferGrow (xmlParserInputBufferPtr in,
+ int len);
+int xmlParserInputBufferPush (xmlParserInputBufferPtr in,
+ int len,
+ const char *buf);
+void xmlFreeParserInputBuffer (xmlParserInputBufferPtr in);
+char * xmlParserGetDirectory (const char *filename);
+
+int xmlRegisterInputCallbacks (xmlInputMatchCallback matchFunc,
+ xmlInputOpenCallback openFunc,
+ xmlInputReadCallback readFunc,
+ xmlInputCloseCallback closeFunc);
+/*
+ * Interfaces for output
+ */
+void xmlRegisterDefaultOutputCallbacks(void);
+xmlOutputBufferPtr
+ xmlAllocOutputBuffer (xmlCharEncodingHandlerPtr encoder);
+
+xmlOutputBufferPtr
+ xmlOutputBufferCreateFilename (const char *URI,
+ xmlCharEncodingHandlerPtr encoder,
+ int compression);
+
+xmlOutputBufferPtr
+ xmlOutputBufferCreateFile (FILE *file,
+ xmlCharEncodingHandlerPtr encoder);
+
+xmlOutputBufferPtr
+ xmlOutputBufferCreateFd (int fd,
+ xmlCharEncodingHandlerPtr encoder);
+
+xmlOutputBufferPtr
+ xmlOutputBufferCreateIO (xmlOutputWriteCallback iowrite,
+ xmlOutputCloseCallback ioclose,
+ void *ioctx,
+ xmlCharEncodingHandlerPtr encoder);
+
+int xmlOutputBufferWrite (xmlOutputBufferPtr out,
+ int len,
+ const char *buf);
+int xmlOutputBufferWriteString (xmlOutputBufferPtr out,
+ const char *str);
+
+int xmlOutputBufferFlush (xmlOutputBufferPtr out);
+int xmlOutputBufferClose (xmlOutputBufferPtr out);
+
+int xmlRegisterOutputCallbacks (xmlOutputMatchCallback matchFunc,
+ xmlOutputOpenCallback openFunc,
+ xmlOutputWriteCallback writeFunc,
+ xmlOutputCloseCallback closeFunc);
+
+/* This function only exists if HTTP support built into the library */
+#ifdef LIBXML_HTTP_ENABLED
+void * xmlIOHTTPOpenW (const char * post_uri,
+ int compression );
+void xmlRegisterHTTPPostCallbacks (void );
+#endif
+
+/*
+ * A predefined entity loader disabling network accesses
+ */
+xmlParserInputPtr xmlNoNetExternalEntityLoader(const char *URL,
+ const char *ID,
+ xmlParserCtxtPtr ctxt);
+
+/*
+ * xmlNormalizeWindowsPath is obsolete, don't use it.
+ * Check xmlCanonicPath in uri.h for a better alternative.
+ */
+xmlChar * xmlNormalizeWindowsPath (const xmlChar *path);
+
+int xmlCheckFilename (const char *path);
+/**
+ * Default 'file://' protocol callbacks
+ */
+int xmlFileMatch (const char *filename);
+void * xmlFileOpen (const char *filename);
+int xmlFileRead (void * context,
+ char * buffer,
+ int len);
+int xmlFileClose (void * context);
+
+/**
+ * Default 'http://' protocol callbacks
+ */
+#ifdef LIBXML_HTTP_ENABLED
+int xmlIOHTTPMatch (const char *filename);
+void * xmlIOHTTPOpen (const char *filename);
+int xmlIOHTTPRead (void * context,
+ char * buffer,
+ int len);
+int xmlIOHTTPClose (void * context);
+#endif /* LIBXML_HTTP_ENABLED */
+
+/**
+ * Default 'ftp://' protocol callbacks
+ */
+#ifdef LIBXML_FTP_ENABLED
+int xmlIOFTPMatch (const char *filename);
+void * xmlIOFTPOpen (const char *filename);
+int xmlIOFTPRead (void * context,
+ char * buffer,
+ int len);
+int xmlIOFTPClose (void * context);
+#endif /* LIBXML_FTP_ENABLED */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_IO_H__ */
diff --git a/plugins/Variables/src/libxml/xmlautomata.h b/plugins/Variables/src/libxml/xmlautomata.h
new file mode 100644
index 0000000000..cc25e0b715
--- /dev/null
+++ b/plugins/Variables/src/libxml/xmlautomata.h
@@ -0,0 +1,94 @@
+/*
+ * automata.h : description of the API to build regexp automats
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel Veillard <veillard@redhat.com>
+ */
+
+#ifndef __XML_AUTOMATA_H__
+#define __XML_AUTOMATA_H__
+
+#include "libxml/xmlversion.h"
+#include "libxml/tree.h"
+
+#ifdef LIBXML_AUTOMATA_ENABLED
+#include "libxml/xmlregexp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * xmlAutomataPtr:
+ *
+ * A libxml automata description, It can be compiled into a regexp
+ */
+typedef struct _xmlAutomata xmlAutomata;
+typedef xmlAutomata *xmlAutomataPtr;
+
+/**
+ * xmlAutomataStatePtr:
+ *
+ * A state int the automata description,
+ */
+typedef struct _xmlAutomataState xmlAutomataState;
+typedef xmlAutomataState *xmlAutomataStatePtr;
+
+/*
+ * Building API
+ */
+xmlAutomataPtr xmlNewAutomata (void);
+void xmlFreeAutomata (xmlAutomataPtr am);
+
+xmlAutomataStatePtr xmlAutomataGetInitState (xmlAutomataPtr am);
+int xmlAutomataSetFinalState(xmlAutomataPtr am,
+ xmlAutomataStatePtr state);
+xmlAutomataStatePtr xmlAutomataNewState (xmlAutomataPtr am);
+xmlAutomataStatePtr xmlAutomataNewTransition(xmlAutomataPtr am,
+ xmlAutomataStatePtr from,
+ xmlAutomataStatePtr to,
+ const xmlChar *token,
+ void *data);
+xmlAutomataStatePtr xmlAutomataNewCountTrans(xmlAutomataPtr am,
+ xmlAutomataStatePtr from,
+ xmlAutomataStatePtr to,
+ const xmlChar *token,
+ int min,
+ int max,
+ void *data);
+xmlAutomataStatePtr xmlAutomataNewOnceTrans (xmlAutomataPtr am,
+ xmlAutomataStatePtr from,
+ xmlAutomataStatePtr to,
+ const xmlChar *token,
+ int min,
+ int max,
+ void *data);
+xmlAutomataStatePtr xmlAutomataNewAllTrans (xmlAutomataPtr am,
+ xmlAutomataStatePtr from,
+ xmlAutomataStatePtr to,
+ int lax);
+xmlAutomataStatePtr xmlAutomataNewEpsilon (xmlAutomataPtr am,
+ xmlAutomataStatePtr from,
+ xmlAutomataStatePtr to);
+xmlAutomataStatePtr xmlAutomataNewCountedTrans(xmlAutomataPtr am,
+ xmlAutomataStatePtr from,
+ xmlAutomataStatePtr to,
+ int counter);
+xmlAutomataStatePtr xmlAutomataNewCounterTrans(xmlAutomataPtr am,
+ xmlAutomataStatePtr from,
+ xmlAutomataStatePtr to,
+ int counter);
+int xmlAutomataNewCounter (xmlAutomataPtr am,
+ int min,
+ int max);
+
+xmlRegexpPtr xmlAutomataCompile (xmlAutomataPtr am);
+int xmlAutomataIsDeterminist(xmlAutomataPtr am);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_AUTOMATA_ENABLED */
+#endif /* __XML_AUTOMATA_H__ */
diff --git a/plugins/Variables/src/libxml/xmlerror.h b/plugins/Variables/src/libxml/xmlerror.h
new file mode 100644
index 0000000000..a40a1ec7ab
--- /dev/null
+++ b/plugins/Variables/src/libxml/xmlerror.h
@@ -0,0 +1,184 @@
+#include "libxml/parser.h"
+
+#ifndef __XML_ERROR_H__
+#define __XML_ERROR_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ XML_ERR_OK = 0,
+ XML_ERR_INTERNAL_ERROR,
+ XML_ERR_NO_MEMORY,
+
+ XML_ERR_DOCUMENT_START, /* 3 */
+ XML_ERR_DOCUMENT_EMPTY,
+ XML_ERR_DOCUMENT_END,
+
+ XML_ERR_INVALID_HEX_CHARREF, /* 6 */
+ XML_ERR_INVALID_DEC_CHARREF,
+ XML_ERR_INVALID_CHARREF,
+ XML_ERR_INVALID_CHAR,
+
+ XML_ERR_CHARREF_AT_EOF, /* 10 */
+ XML_ERR_CHARREF_IN_PROLOG,
+ XML_ERR_CHARREF_IN_EPILOG,
+ XML_ERR_CHARREF_IN_DTD,
+ XML_ERR_ENTITYREF_AT_EOF,
+ XML_ERR_ENTITYREF_IN_PROLOG,
+ XML_ERR_ENTITYREF_IN_EPILOG,
+ XML_ERR_ENTITYREF_IN_DTD,
+ XML_ERR_PEREF_AT_EOF,
+ XML_ERR_PEREF_IN_PROLOG,
+ XML_ERR_PEREF_IN_EPILOG,
+ XML_ERR_PEREF_IN_INT_SUBSET,
+
+ XML_ERR_ENTITYREF_NO_NAME, /* 22 */
+ XML_ERR_ENTITYREF_SEMICOL_MISSING,
+
+ XML_ERR_PEREF_NO_NAME, /* 24 */
+ XML_ERR_PEREF_SEMICOL_MISSING,
+
+ XML_ERR_UNDECLARED_ENTITY, /* 26 */
+ XML_WAR_UNDECLARED_ENTITY,
+ XML_ERR_UNPARSED_ENTITY,
+ XML_ERR_ENTITY_IS_EXTERNAL,
+ XML_ERR_ENTITY_IS_PARAMETER,
+
+ XML_ERR_UNKNOWN_ENCODING, /* 31 */
+ XML_ERR_UNSUPPORTED_ENCODING,
+
+ XML_ERR_STRING_NOT_STARTED, /* 33 */
+ XML_ERR_STRING_NOT_CLOSED,
+ XML_ERR_NS_DECL_ERROR,
+
+ XML_ERR_ENTITY_NOT_STARTED, /* 36 */
+ XML_ERR_ENTITY_NOT_FINISHED,
+
+ XML_ERR_LT_IN_ATTRIBUTE, /* 38 */
+ XML_ERR_ATTRIBUTE_NOT_STARTED,
+ XML_ERR_ATTRIBUTE_NOT_FINISHED,
+ XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
+ XML_ERR_ATTRIBUTE_REDEFINED,
+
+ XML_ERR_LITERAL_NOT_STARTED, /* 43 */
+ XML_ERR_LITERAL_NOT_FINISHED,
+
+ XML_ERR_COMMENT_NOT_FINISHED, /* 45 */
+
+ XML_ERR_PI_NOT_STARTED, /* 47 */
+ XML_ERR_PI_NOT_FINISHED,
+
+ XML_ERR_NOTATION_NOT_STARTED, /* 49 */
+ XML_ERR_NOTATION_NOT_FINISHED,
+
+ XML_ERR_ATTLIST_NOT_STARTED, /* 51 */
+ XML_ERR_ATTLIST_NOT_FINISHED,
+
+ XML_ERR_MIXED_NOT_STARTED, /* 53 */
+ XML_ERR_MIXED_NOT_FINISHED,
+
+ XML_ERR_ELEMCONTENT_NOT_STARTED, /* 55 */
+ XML_ERR_ELEMCONTENT_NOT_FINISHED,
+
+ XML_ERR_XMLDECL_NOT_STARTED, /* 57 */
+ XML_ERR_XMLDECL_NOT_FINISHED,
+
+ XML_ERR_CONDSEC_NOT_STARTED, /* 59 */
+ XML_ERR_CONDSEC_NOT_FINISHED,
+
+ XML_ERR_EXT_SUBSET_NOT_FINISHED, /* 61 */
+
+ XML_ERR_DOCTYPE_NOT_FINISHED, /* 62 */
+
+ XML_ERR_MISPLACED_CDATA_END, /* 63 */
+ XML_ERR_CDATA_NOT_FINISHED,
+
+ XML_ERR_RESERVED_XML_NAME, /* 65 */
+
+ XML_ERR_SPACE_REQUIRED, /* 66 */
+ XML_ERR_SEPARATOR_REQUIRED,
+ XML_ERR_NMTOKEN_REQUIRED,
+ XML_ERR_NAME_REQUIRED,
+ XML_ERR_PCDATA_REQUIRED,
+ XML_ERR_URI_REQUIRED,
+ XML_ERR_PUBID_REQUIRED,
+ XML_ERR_LT_REQUIRED,
+ XML_ERR_GT_REQUIRED,
+ XML_ERR_LTSLASH_REQUIRED,
+ XML_ERR_EQUAL_REQUIRED,
+
+ XML_ERR_TAG_NAME_MISMATCH, /* 77 */
+ XML_ERR_TAG_NOT_FINISHED,
+
+ XML_ERR_STANDALONE_VALUE, /* 79 */
+
+ XML_ERR_ENCODING_NAME, /* 80 */
+
+ XML_ERR_HYPHEN_IN_COMMENT, /* 81 */
+
+ XML_ERR_INVALID_ENCODING, /* 82 */
+
+ XML_ERR_EXT_ENTITY_STANDALONE, /* 83 */
+
+ XML_ERR_CONDSEC_INVALID, /* 84 */
+
+ XML_ERR_VALUE_REQUIRED, /* 85 */
+
+ XML_ERR_NOT_WELL_BALANCED, /* 86 */
+ XML_ERR_EXTRA_CONTENT, /* 87 */
+ XML_ERR_ENTITY_CHAR_ERROR, /* 88 */
+ XML_ERR_ENTITY_PE_INTERNAL, /* 88 */
+ XML_ERR_ENTITY_LOOP, /* 89 */
+ XML_ERR_ENTITY_BOUNDARY, /* 90 */
+ XML_ERR_INVALID_URI, /* 91 */
+ XML_ERR_URI_FRAGMENT, /* 92 */
+ XML_WAR_CATALOG_PI, /* 93 */
+ XML_ERR_NO_DTD /* 94 */
+}xmlParserErrors;
+
+/**
+ * xmlGenericErrorFunc:
+ * @ctx: a parsing context
+ * @msg: the message
+ * @...: the extra arguments of the varags to format the message
+ *
+ * Signature of the function to use when there is an error and
+ * no parsing or validity context available .
+ */
+typedef void (*xmlGenericErrorFunc) (void *ctx,
+ const char *msg,
+ ...);
+
+/*
+ * Use the following function to reset the two global variables
+ * xmlGenericError and xmlGenericErrorContext.
+ */
+void xmlSetGenericErrorFunc (void *ctx,
+ xmlGenericErrorFunc handler);
+void initGenericErrorDefaultFunc(xmlGenericErrorFunc *handler);
+
+/*
+ * Default message routines used by SAX and Valid context for error
+ * and warning reporting.
+ */
+void xmlParserError (void *ctx,
+ const char *msg,
+ ...);
+void xmlParserWarning (void *ctx,
+ const char *msg,
+ ...);
+void xmlParserValidityError (void *ctx,
+ const char *msg,
+ ...);
+void xmlParserValidityWarning(void *ctx,
+ const char *msg,
+ ...);
+void xmlParserPrintFileInfo (xmlParserInputPtr input);
+void xmlParserPrintFileContext(xmlParserInputPtr input);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_ERROR_H__ */
diff --git a/plugins/Variables/src/libxml/xmlmemory.h b/plugins/Variables/src/libxml/xmlmemory.h
new file mode 100644
index 0000000000..314d8f8339
--- /dev/null
+++ b/plugins/Variables/src/libxml/xmlmemory.h
@@ -0,0 +1,169 @@
+/*
+ * xmlmemory.h: interface for the memory allocation debug.
+ *
+ * daniel@veillard.com
+ */
+
+
+#ifndef _DEBUG_MEMORY_ALLOC_
+#define _DEBUG_MEMORY_ALLOC_
+
+#include <stdio.h>
+#include "libxml/xmlversion.h"
+
+/**
+ * DEBUG_MEMORY:
+ *
+ * DEBUG_MEMORY replaces the allocator with a collect and debug
+ * shell to the libc allocator.
+ * DEBUG_MEMORY should only be activated when debugging
+ * libxml i.e. if libxml has been configured with --with-debug-mem too.
+ */
+/* #define DEBUG_MEMORY_FREED */
+/* #define DEBUG_MEMORY_LOCATION */
+
+#ifdef DEBUG
+#ifndef DEBUG_MEMORY
+#define DEBUG_MEMORY
+#endif
+#endif
+
+/**
+ * DEBUG_MEMORY_LOCATION:
+ *
+ * DEBUG_MEMORY_LOCATION should be activated only when debugging
+ * libxml i.e. if libxml has been configured with --with-debug-mem too.
+ */
+#ifdef DEBUG_MEMORY_LOCATION
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The XML memory wrapper support 4 basic overloadable functions.
+ */
+/**
+ * xmlFreeFunc:
+ * @mem: an already allocated block of memory
+ *
+ * Signature for a free() implementation.
+ */
+typedef void (*xmlFreeFunc)(void *mem);
+/**
+ * xmlMallocFunc:
+ * @size: the size requested in bytes
+ *
+ * Signature for a malloc() implementation.
+ *
+ * Returns a pointer to the newly allocated block or NULL in case of error.
+ */
+typedef void *(*xmlMallocFunc)(size_t size);
+
+/**
+ * xmlReallocFunc:
+ * @mem: an already allocated block of memory
+ * @size: the new size requested in bytes
+ *
+ * Signature for a realloc() implementation.
+ *
+ * Returns a pointer to the newly reallocated block or NULL in case of error.
+ */
+typedef void *(*xmlReallocFunc)(void *mem, size_t size);
+
+/**
+ * xmlStrdupFunc:
+ * @str: a zero terminated string
+ *
+ * Signature for an strdup() implementation.
+ *
+ * Returns the copy of the string or NULL in case of error.
+ */
+typedef char *(*xmlStrdupFunc)(const char *str);
+
+/*
+ * The 4 interfaces used for all memory handling within libxml.
+LIBXML_DLL_IMPORT extern xmlFreeFunc xmlFree;
+LIBXML_DLL_IMPORT extern xmlMallocFunc xmlMalloc;
+LIBXML_DLL_IMPORT extern xmlReallocFunc xmlRealloc;
+LIBXML_DLL_IMPORT extern xmlStrdupFunc xmlMemStrdup;
+ */
+
+/*
+ * The way to overload the existing functions.
+ */
+int xmlMemSetup (xmlFreeFunc freeFunc,
+ xmlMallocFunc mallocFunc,
+ xmlReallocFunc reallocFunc,
+ xmlStrdupFunc strdupFunc);
+int xmlMemGet (xmlFreeFunc *freeFunc,
+ xmlMallocFunc *mallocFunc,
+ xmlReallocFunc *reallocFunc,
+ xmlStrdupFunc *strdupFunc);
+
+/*
+ * Initialization of the memory layer.
+ */
+int xmlInitMemory (void);
+
+/*
+ * Those are specific to the XML debug memory wrapper.
+ */
+int xmlMemUsed (void);
+void xmlMemDisplay (FILE *fp);
+void xmlMemShow (FILE *fp, int nr);
+void xmlMemoryDump (void);
+void * xmlMemMalloc (size_t size);
+void * xmlMemRealloc (void *ptr,size_t size);
+void xmlMemFree (void *ptr);
+char * xmlMemoryStrdup (const char *str);
+
+#ifdef DEBUG_MEMORY_LOCATION
+/**
+ * xmlMalloc:
+ * @size: number of bytes to allocate
+ *
+ * Wrapper for the malloc() function used in the XML library.
+ *
+ * Returns the pointer to the allocated area or NULL in case of error.
+ */
+#define xmlMalloc(size) xmlMallocLoc((size), __FILE__, __LINE__)
+/**
+ * xmlRealloc:
+ * @ptr: pointer to the existing allocated area
+ * @size: number of bytes to allocate
+ *
+ * Wrapper for the realloc() function used in the XML library.
+ *
+ * Returns the pointer to the allocated area or NULL in case of error.
+ */
+#define xmlRealloc(ptr, size) xmlReallocLoc((ptr), (size), __FILE__, __LINE__)
+/**
+ * xmlMemStrdup:
+ * @str: pointer to the existing string
+ *
+ * Wrapper for the strdup() function, xmlStrdup() is usually preferred.
+ *
+ * Returns the pointer to the allocated area or NULL in case of error.
+ */
+#define xmlMemStrdup(str) xmlMemStrdupLoc((str), __FILE__, __LINE__)
+
+void * xmlMallocLoc(size_t size, const char *file, int line);
+void * xmlReallocLoc(void *ptr,size_t size, const char *file, int line);
+char * xmlMemStrdupLoc(const char *str, const char *file, int line);
+#endif /* DEBUG_MEMORY_LOCATION */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#ifndef __XML_GLOBALS_H
+#ifndef __XML_THREADS_H__
+#include "libxml/threads.h"
+#include "libxml/globals.h"
+#endif
+#endif
+
+#endif /* _DEBUG_MEMORY_ALLOC_ */
+
diff --git a/plugins/Variables/src/libxml/xmlregexp.h b/plugins/Variables/src/libxml/xmlregexp.h
new file mode 100644
index 0000000000..f15ead03ae
--- /dev/null
+++ b/plugins/Variables/src/libxml/xmlregexp.h
@@ -0,0 +1,81 @@
+/*
+ * regexp.h : describes the basic API for libxml regular expressions handling
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel Veillard <veillard@redhat.com>
+ */
+
+#ifndef __XML_REGEXP_H__
+#define __XML_REGEXP_H__
+
+#include "libxml/xmlversion.h"
+
+#ifdef LIBXML_REGEXP_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * xmlRegexpPtr:
+ *
+ * A libxml regular expression, they can actually be far more complex
+ * thank the POSIX regex expressions.
+ */
+typedef struct _xmlRegexp xmlRegexp;
+typedef xmlRegexp *xmlRegexpPtr;
+
+/**
+ * xmlRegExecCtxtPtr:
+ *
+ * A libxml progressive regular expression evaluation context
+ */
+typedef struct _xmlRegExecCtxt xmlRegExecCtxt;
+typedef xmlRegExecCtxt *xmlRegExecCtxtPtr;
+
+#ifdef __cplusplus
+}
+#endif
+#include "libxml/tree.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The POSIX like API
+ */
+xmlRegexpPtr xmlRegexpCompile(const xmlChar *regexp);
+void xmlRegFreeRegexp(xmlRegexpPtr regexp);
+int xmlRegexpExec (xmlRegexpPtr comp,
+ const xmlChar *value);
+void xmlRegexpPrint (FILE *output,
+ xmlRegexpPtr regexp);
+int xmlRegexpIsDeterminist(xmlRegexpPtr comp);
+
+/*
+ * Callback function when doing a transition in the automata
+ */
+typedef void (*xmlRegExecCallbacks) (xmlRegExecCtxtPtr exec,
+ const xmlChar *token,
+ void *transdata,
+ void *inputdata);
+
+/*
+ * The progressive API
+ */
+xmlRegExecCtxtPtr xmlRegNewExecCtxt (xmlRegexpPtr comp,
+ xmlRegExecCallbacks callback,
+ void *data);
+void xmlRegFreeExecCtxt (xmlRegExecCtxtPtr exec);
+int xmlRegExecPushString (xmlRegExecCtxtPtr exec,
+ const xmlChar *value,
+ void *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_REGEXP_ENABLED */
+
+#endif /*__XML_REGEXP_H__ */
diff --git a/plugins/Variables/src/libxml/xmlschemas.h b/plugins/Variables/src/libxml/xmlschemas.h
new file mode 100644
index 0000000000..14b9230832
--- /dev/null
+++ b/plugins/Variables/src/libxml/xmlschemas.h
@@ -0,0 +1,106 @@
+/*
+ * schemas.h : interface to the XML Schemas handling and schema validity
+ * checking
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel.Veillard@w3.org
+ */
+
+
+#ifndef __XML_SCHEMA_H__
+#define __XML_SCHEMA_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#include <libxml/tree.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ XML_SCHEMAS_ERR_OK = 0,
+ XML_SCHEMAS_ERR_NOROOT = 1,
+ XML_SCHEMAS_ERR_UNDECLAREDELEM,
+ XML_SCHEMAS_ERR_NOTTOPLEVEL,
+ XML_SCHEMAS_ERR_MISSING,
+ XML_SCHEMAS_ERR_WRONGELEM,
+ XML_SCHEMAS_ERR_NOTYPE,
+ XML_SCHEMAS_ERR_NOROLLBACK,
+ XML_SCHEMAS_ERR_ISABSTRACT,
+ XML_SCHEMAS_ERR_NOTEMPTY,
+ XML_SCHEMAS_ERR_ELEMCONT,
+ XML_SCHEMAS_ERR_HAVEDEFAULT,
+ XML_SCHEMAS_ERR_NOTNILLABLE,
+ XML_SCHEMAS_ERR_EXTRACONTENT,
+ XML_SCHEMAS_ERR_INVALIDATTR,
+ XML_SCHEMAS_ERR_INVALIDELEM,
+ XML_SCHEMAS_ERR_NOTDETERMINIST,
+ XML_SCHEMAS_ERR_CONSTRUCT,
+ XML_SCHEMAS_ERR_INTERNAL,
+ XML_SCHEMAS_ERR_NOTSIMPLE,
+ XML_SCHEMAS_ERR_ATTRUNKNOWN,
+ XML_SCHEMAS_ERR_ATTRINVALID,
+ XML_SCHEMAS_ERR_,
+ XML_SCHEMAS_ERR_XXX
+} xmlSchemaValidError;
+
+
+/**
+ * The schemas related types are kept internal
+ */
+typedef struct _xmlSchema xmlSchema;
+typedef xmlSchema *xmlSchemaPtr;
+
+/**
+ * A schemas validation context
+ */
+typedef void (*xmlSchemaValidityErrorFunc) (void *ctx, const char *msg, ...);
+typedef void (*xmlSchemaValidityWarningFunc) (void *ctx, const char *msg, ...);
+
+typedef struct _xmlSchemaParserCtxt xmlSchemaParserCtxt;
+typedef xmlSchemaParserCtxt *xmlSchemaParserCtxtPtr;
+
+typedef struct _xmlSchemaValidCtxt xmlSchemaValidCtxt;
+typedef xmlSchemaValidCtxt *xmlSchemaValidCtxtPtr;
+
+/*
+ * Interfaces for parsing.
+ */
+xmlSchemaParserCtxtPtr xmlSchemaNewParserCtxt (const char *URL);
+xmlSchemaParserCtxtPtr xmlSchemaNewMemParserCtxt(const char *buffer,
+ int size);
+void xmlSchemaFreeParserCtxt (xmlSchemaParserCtxtPtr ctxt);
+void xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
+ xmlSchemaValidityErrorFunc err,
+ xmlSchemaValidityWarningFunc warn,
+ void *ctx);
+xmlSchemaPtr xmlSchemaParse (xmlSchemaParserCtxtPtr ctxt);
+void xmlSchemaFree (xmlSchemaPtr schema);
+void xmlSchemaDump (FILE *output,
+ xmlSchemaPtr schema);
+/*
+ * Interfaces for validating
+ */
+void xmlSchemaSetValidErrors (xmlSchemaValidCtxtPtr ctxt,
+ xmlSchemaValidityErrorFunc err,
+ xmlSchemaValidityWarningFunc warn,
+ void *ctx);
+xmlSchemaValidCtxtPtr xmlSchemaNewValidCtxt (xmlSchemaPtr schema);
+void xmlSchemaFreeValidCtxt (xmlSchemaValidCtxtPtr ctxt);
+int xmlSchemaValidateDoc (xmlSchemaValidCtxtPtr ctxt,
+ xmlDocPtr instance);
+int xmlSchemaValidateStream (xmlSchemaValidCtxtPtr ctxt,
+ xmlParserInputBufferPtr input,
+ xmlCharEncoding enc,
+ xmlSAXHandlerPtr sax,
+ void *user_data);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_SCHEMAS_ENABLED */
+#endif /* __XML_SCHEMA_H__ */
diff --git a/plugins/Variables/src/libxml/xmlschemastypes.h b/plugins/Variables/src/libxml/xmlschemastypes.h
new file mode 100644
index 0000000000..a758c128e5
--- /dev/null
+++ b/plugins/Variables/src/libxml/xmlschemastypes.h
@@ -0,0 +1,42 @@
+/*
+ * schemastypes.c : interface of the XML Schema Datatypes
+ * definition and validity checking
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel Veillard <veillard@redhat.com>
+ */
+
+
+#ifndef __XML_SCHEMA_TYPES_H__
+#define __XML_SCHEMA_TYPES_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#include <libxml/schemasInternals.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void xmlSchemaInitTypes (void);
+void xmlSchemaCleanupTypes (void);
+xmlSchemaTypePtr xmlSchemaGetPredefinedType (const xmlChar *name,
+ const xmlChar *ns);
+int xmlSchemaValidatePredefinedType (xmlSchemaTypePtr type,
+ const xmlChar *value,
+ xmlSchemaValPtr *val);
+int xmlSchemaValidateFacet (xmlSchemaTypePtr base,
+ xmlSchemaFacetPtr facet,
+ const xmlChar *value,
+ xmlSchemaValPtr val);
+void xmlSchemaFreeValue (xmlSchemaValPtr val);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_SCHEMAS_ENABLED */
+#endif /* __XML_SCHEMA_TYPES_H__ */
diff --git a/plugins/Variables/src/libxml/xmlunicode.h b/plugins/Variables/src/libxml/xmlunicode.h
new file mode 100644
index 0000000000..f0f1fe9ce9
--- /dev/null
+++ b/plugins/Variables/src/libxml/xmlunicode.h
@@ -0,0 +1,164 @@
+/*
+ * xmlunicode.h: this header exports interfaces for the Unicode character APIs
+ *
+ * This file is automatically generated from the
+ * UCS description files of the Unicode Character Database
+ * http://www.unicode.org/Public/3.1-Update/UnicodeCharacterDatabase-3.1.0.html
+ * using the genUnicode.py Python script.
+ *
+ * Generation date: Tue Apr 16 17:28:05 2002
+ * Sources: Blocks-4.txt UnicodeData-3.1.0.txt
+ * Daniel Veillard <veillard@redhat.com>
+ */
+
+#ifndef __XML_UNICODE_H__
+#define __XML_UNICODE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int xmlUCSIsAlphabeticPresentationForms (int code);
+int xmlUCSIsArabic (int code);
+int xmlUCSIsArabicPresentationFormsA (int code);
+int xmlUCSIsArabicPresentationFormsB (int code);
+int xmlUCSIsArmenian (int code);
+int xmlUCSIsArrows (int code);
+int xmlUCSIsBasicLatin (int code);
+int xmlUCSIsBengali (int code);
+int xmlUCSIsBlockElements (int code);
+int xmlUCSIsBopomofo (int code);
+int xmlUCSIsBopomofoExtended (int code);
+int xmlUCSIsBoxDrawing (int code);
+int xmlUCSIsBraillePatterns (int code);
+int xmlUCSIsByzantineMusicalSymbols (int code);
+int xmlUCSIsCJKCompatibility (int code);
+int xmlUCSIsCJKCompatibilityForms (int code);
+int xmlUCSIsCJKCompatibilityIdeographs (int code);
+int xmlUCSIsCJKCompatibilityIdeographsSupplement (int code);
+int xmlUCSIsCJKRadicalsSupplement (int code);
+int xmlUCSIsCJKSymbolsandPunctuation (int code);
+int xmlUCSIsCJKUnifiedIdeographs (int code);
+int xmlUCSIsCJKUnifiedIdeographsExtensionA (int code);
+int xmlUCSIsCJKUnifiedIdeographsExtensionB (int code);
+int xmlUCSIsCherokee (int code);
+int xmlUCSIsCombiningDiacriticalMarks (int code);
+int xmlUCSIsCombiningHalfMarks (int code);
+int xmlUCSIsCombiningMarksforSymbols (int code);
+int xmlUCSIsControlPictures (int code);
+int xmlUCSIsCurrencySymbols (int code);
+int xmlUCSIsCyrillic (int code);
+int xmlUCSIsDeseret (int code);
+int xmlUCSIsDevanagari (int code);
+int xmlUCSIsDingbats (int code);
+int xmlUCSIsEnclosedAlphanumerics (int code);
+int xmlUCSIsEnclosedCJKLettersandMonths (int code);
+int xmlUCSIsEthiopic (int code);
+int xmlUCSIsGeneralPunctuation (int code);
+int xmlUCSIsGeometricShapes (int code);
+int xmlUCSIsGeorgian (int code);
+int xmlUCSIsGothic (int code);
+int xmlUCSIsGreek (int code);
+int xmlUCSIsGreekExtended (int code);
+int xmlUCSIsGujarati (int code);
+int xmlUCSIsGurmukhi (int code);
+int xmlUCSIsHalfwidthandFullwidthForms (int code);
+int xmlUCSIsHangulCompatibilityJamo (int code);
+int xmlUCSIsHangulJamo (int code);
+int xmlUCSIsHangulSyllables (int code);
+int xmlUCSIsHebrew (int code);
+int xmlUCSIsHighPrivateUseSurrogates (int code);
+int xmlUCSIsHighSurrogates (int code);
+int xmlUCSIsHiragana (int code);
+int xmlUCSIsIPAExtensions (int code);
+int xmlUCSIsIdeographicDescriptionCharacters (int code);
+int xmlUCSIsKanbun (int code);
+int xmlUCSIsKangxiRadicals (int code);
+int xmlUCSIsKannada (int code);
+int xmlUCSIsKatakana (int code);
+int xmlUCSIsKhmer (int code);
+int xmlUCSIsLao (int code);
+int xmlUCSIsLatin1Supplement (int code);
+int xmlUCSIsLatinExtendedA (int code);
+int xmlUCSIsLatinExtendedB (int code);
+int xmlUCSIsLatinExtendedAdditional (int code);
+int xmlUCSIsLetterlikeSymbols (int code);
+int xmlUCSIsLowSurrogates (int code);
+int xmlUCSIsMalayalam (int code);
+int xmlUCSIsMathematicalAlphanumericSymbols (int code);
+int xmlUCSIsMathematicalOperators (int code);
+int xmlUCSIsMiscellaneousSymbols (int code);
+int xmlUCSIsMiscellaneousTechnical (int code);
+int xmlUCSIsMongolian (int code);
+int xmlUCSIsMusicalSymbols (int code);
+int xmlUCSIsMyanmar (int code);
+int xmlUCSIsNumberForms (int code);
+int xmlUCSIsOgham (int code);
+int xmlUCSIsOldItalic (int code);
+int xmlUCSIsOpticalCharacterRecognition (int code);
+int xmlUCSIsOriya (int code);
+int xmlUCSIsPrivateUse (int code);
+int xmlUCSIsRunic (int code);
+int xmlUCSIsSinhala (int code);
+int xmlUCSIsSmallFormVariants (int code);
+int xmlUCSIsSpacingModifierLetters (int code);
+int xmlUCSIsSpecials (int code);
+int xmlUCSIsSuperscriptsandSubscripts (int code);
+int xmlUCSIsSyriac (int code);
+int xmlUCSIsTags (int code);
+int xmlUCSIsTamil (int code);
+int xmlUCSIsTelugu (int code);
+int xmlUCSIsThaana (int code);
+int xmlUCSIsThai (int code);
+int xmlUCSIsTibetan (int code);
+int xmlUCSIsUnifiedCanadianAboriginalSyllabics (int code);
+int xmlUCSIsYiRadicals (int code);
+int xmlUCSIsYiSyllables (int code);
+
+int xmlUCSIsBlock (int code,
+ const char *block);
+
+int xmlUCSIsCatC (int code);
+int xmlUCSIsCatCc (int code);
+int xmlUCSIsCatCf (int code);
+int xmlUCSIsCatCo (int code);
+int xmlUCSIsCatCs (int code);
+int xmlUCSIsCatL (int code);
+int xmlUCSIsCatLl (int code);
+int xmlUCSIsCatLm (int code);
+int xmlUCSIsCatLo (int code);
+int xmlUCSIsCatLt (int code);
+int xmlUCSIsCatLu (int code);
+int xmlUCSIsCatM (int code);
+int xmlUCSIsCatMc (int code);
+int xmlUCSIsCatMe (int code);
+int xmlUCSIsCatMn (int code);
+int xmlUCSIsCatN (int code);
+int xmlUCSIsCatNd (int code);
+int xmlUCSIsCatNl (int code);
+int xmlUCSIsCatNo (int code);
+int xmlUCSIsCatP (int code);
+int xmlUCSIsCatPc (int code);
+int xmlUCSIsCatPd (int code);
+int xmlUCSIsCatPe (int code);
+int xmlUCSIsCatPf (int code);
+int xmlUCSIsCatPi (int code);
+int xmlUCSIsCatPo (int code);
+int xmlUCSIsCatPs (int code);
+int xmlUCSIsCatS (int code);
+int xmlUCSIsCatSc (int code);
+int xmlUCSIsCatSk (int code);
+int xmlUCSIsCatSm (int code);
+int xmlUCSIsCatSo (int code);
+int xmlUCSIsCatZ (int code);
+int xmlUCSIsCatZl (int code);
+int xmlUCSIsCatZp (int code);
+int xmlUCSIsCatZs (int code);
+
+int xmlUCSIsCat (int code,
+ const char *cat);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_UNICODE_H__ */
diff --git a/plugins/Variables/src/libxml/xmlversion.h b/plugins/Variables/src/libxml/xmlversion.h
new file mode 100644
index 0000000000..1342eba969
--- /dev/null
+++ b/plugins/Variables/src/libxml/xmlversion.h
@@ -0,0 +1,272 @@
+/*
+ * xmlversion.h : compile-time version informations for the XML parser.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifndef __XML_VERSION_H__
+#define __XML_VERSION_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * use those to be sure nothing nasty will happen if
+ * your library and includes mismatch
+ */
+#ifndef LIBXML2_COMPILING_MSCCDEF
+extern void xmlCheckVersion(int version);
+#endif /* LIBXML2_COMPILING_MSCCDEF */
+
+/**
+ * LIBXML_DOTTED_VERSION:
+ *
+ * the version string like "1.2.3"
+ */
+#define LIBXML_DOTTED_VERSION "2.5.4"
+
+/**
+ * LIBXML_VERSION:
+ *
+ * the version number: 1.2.3 value is 1002003
+ */
+#define LIBXML_VERSION 20504
+
+/**
+ * LIBXML_VERSION_STRING:
+ *
+ * the version number string, 1.2.3 value is "1002003"
+ */
+#define LIBXML_VERSION_STRING "20504"
+
+/**
+ * LIBXML_TEST_VERSION:
+ *
+ * Macro to check that the libxml version in use is compatible with
+ * the version the software has been compiled against
+ */
+#define LIBXML_TEST_VERSION xmlCheckVersion(20504);
+
+#ifndef VMS
+#if 0
+/**
+ * WITH_TRIO:
+ *
+ * defined if the trio support need to be configured in
+ */
+#define WITH_TRIO
+#else
+/**
+ * WITHOUT_TRIO:
+ *
+ * defined if the trio support should not be configured in
+ */
+#define WITHOUT_TRIO
+#endif
+#else /* VMS */
+#define WITH_TRIO 1
+#endif /* VMS */
+
+/**
+ * LIBXML_THREAD_ENABLED:
+ *
+ * Whether the thread support is configured in
+ */
+#if 0
+#if defined(_REENTRANT) || (_POSIX_C_SOURCE - 0 >= 199506L)
+#define LIBXML_THREAD_ENABLED
+#endif
+#endif
+
+/**
+ * LIBXML_FTP_ENABLED:
+ *
+ * Whether the FTP support is configured in
+ */
+#if 1
+#define LIBXML_FTP_ENABLED
+#endif
+
+/**
+ * LIBXML_HTTP_ENABLED:
+ *
+ * Whether the HTTP support is configured in
+ */
+#if 1
+#define LIBXML_HTTP_ENABLED
+#endif
+
+/**
+ * LIBXML_HTML_ENABLED:
+ *
+ * Whether the HTML support is configured in
+ */
+#if 1
+#define LIBXML_HTML_ENABLED
+#endif
+
+/**
+ * LIBXML_C14N_ENABLED:
+ *
+ * Whether the Canonicalization support is configured in
+ */
+#if 1
+#define LIBXML_C14N_ENABLED
+#endif
+
+/**
+ * LIBXML_CATALOG_ENABLED:
+ *
+ * Whether the Catalog support is configured in
+ */
+#if 1
+#define LIBXML_CATALOG_ENABLED
+#endif
+
+/**
+ * LIBXML_DOCB_ENABLED:
+ *
+ * Whether the SGML Docbook support is configured in
+ */
+#if 1
+#define LIBXML_DOCB_ENABLED
+#endif
+
+/**
+ * LIBXML_XPATH_ENABLED:
+ *
+ * Whether XPath is configured in
+ */
+#if 1
+#define LIBXML_XPATH_ENABLED
+#endif
+
+/**
+ * LIBXML_XPTR_ENABLED:
+ *
+ * Whether XPointer is configured in
+ */
+#if 1
+#define LIBXML_XPTR_ENABLED
+#endif
+
+/**
+ * LIBXML_XINCLUDE_ENABLED:
+ *
+ * Whether XInclude is configured in
+ */
+#if 1
+#define LIBXML_XINCLUDE_ENABLED
+#endif
+
+/**
+ * LIBXML_ICONV_ENABLED:
+ *
+ * Whether iconv support is available
+ */
+#if 0
+#define LIBXML_ICONV_ENABLED
+#endif
+
+/**
+ * LIBXML_DEBUG_ENABLED:
+ *
+ * Whether Debugging module is configured in
+ */
+#if 1
+#define LIBXML_DEBUG_ENABLED
+#endif
+
+/**
+ * DEBUG_MEMORY_LOCATION:
+ *
+ * Whether the memory debugging is configured in
+ */
+#if 0
+#define DEBUG_MEMORY_LOCATION
+#endif
+
+/**
+ * LIBXML_UNICODE_ENABLED
+ *
+ * Whether the Unicode related interfaces are compiled in
+ */
+#if 1
+#define LIBXML_UNICODE_ENABLED
+#endif
+
+/**
+ * LIBXML_REGEXP_ENABLED
+ *
+ * Whether the regular expressions interfaces are compiled in
+ */
+#if 1
+#define LIBXML_REGEXP_ENABLED
+#endif
+
+/**
+ * LIBXML_AUTOMATA_ENABLED
+ *
+ * Whether the automata interfaces are compiled in
+ */
+#if 1
+#define LIBXML_AUTOMATA_ENABLED
+#endif
+
+/**
+ * LIBXML_SCHEMAS_ENABLED
+ *
+ * Whether the Schemas validation interfaces are compiled in
+ */
+#if 1
+#define LIBXML_SCHEMAS_ENABLED
+#endif
+
+/**
+ * LIBXML_DLL_IMPORT:
+ *
+ * Used on Windows (MS C compiler only) to declare a variable as
+ * imported from the library. This macro should be empty when compiling
+ * libxml itself. It should expand to __declspec(dllimport)
+ * when the client code includes this header, and that only if the client
+ * links dynamically against libxml.
+ * For this to work, we need three macros. One tells us which compiler is
+ * being used and luckily the compiler defines such a thing: _MSC_VER. The
+ * second macro tells us if we are compiling libxml or the client code and
+ * we define the macro IN_LIBXML on the compiler's command line for this
+ * purpose. The third macro, LIBXML_STATIC, must be defined by any client
+ * code which links against libxml statically.
+ */
+#ifndef LIBXML_DLL_IMPORT
+#if (defined(_MSC_VER) || defined(__CYGWIN__)) && !defined(IN_LIBXML) && !defined(LIBXML_STATIC)
+#define LIBXML_DLL_IMPORT __declspec(dllimport)
+#else
+#define LIBXML_DLL_IMPORT
+#endif
+#endif
+
+/**
+ * ATTRIBUTE_UNUSED:
+ *
+ * Macro used to signal to GCC unused function parameters
+ */
+#ifdef __GNUC__
+#ifdef HAVE_ANSIDECL_H
+#include <ansidecl.h>
+#endif
+#ifndef ATTRIBUTE_UNUSED
+#define ATTRIBUTE_UNUSED
+#endif
+#else
+#define ATTRIBUTE_UNUSED
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
+
+
diff --git a/plugins/Variables/src/libxml/xpath.h b/plugins/Variables/src/libxml/xpath.h
new file mode 100644
index 0000000000..9ec5453d88
--- /dev/null
+++ b/plugins/Variables/src/libxml/xpath.h
@@ -0,0 +1,410 @@
+/*
+ * xpath.c: interface for XML Path Language implementation
+ *
+ * Reference: W3C Working Draft 5 July 1999
+ * http://www.w3.org/Style/XSL/Group/1999/07/xpath-19990705.html
+ *
+ * See COPYRIGHT for the status of this software
+ *
+ * Author: daniel@veillard.com
+ */
+
+#ifndef __XML_XPATH_H__
+#define __XML_XPATH_H__
+
+#include "libxml/tree.h"
+#include "libxml/hash.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _xmlXPathContext xmlXPathContext;
+typedef xmlXPathContext *xmlXPathContextPtr;
+typedef struct _xmlXPathParserContext xmlXPathParserContext;
+typedef xmlXPathParserContext *xmlXPathParserContextPtr;
+
+/**
+ * The set of XPath error codes.
+ */
+
+typedef enum {
+ XPATH_EXPRESSION_OK = 0,
+ XPATH_NUMBER_ERROR,
+ XPATH_UNFINISHED_LITERAL_ERROR,
+ XPATH_START_LITERAL_ERROR,
+ XPATH_VARIABLE_REF_ERROR,
+ XPATH_UNDEF_VARIABLE_ERROR,
+ XPATH_INVALID_PREDICATE_ERROR,
+ XPATH_EXPR_ERROR,
+ XPATH_UNCLOSED_ERROR,
+ XPATH_UNKNOWN_FUNC_ERROR,
+ XPATH_INVALID_OPERAND,
+ XPATH_INVALID_TYPE,
+ XPATH_INVALID_ARITY,
+ XPATH_INVALID_CTXT_SIZE,
+ XPATH_INVALID_CTXT_POSITION,
+ XPATH_MEMORY_ERROR,
+ XPTR_SYNTAX_ERROR,
+ XPTR_RESOURCE_ERROR,
+ XPTR_SUB_RESOURCE_ERROR,
+ XPATH_UNDEF_PREFIX_ERROR,
+ XPATH_ENCODING_ERROR,
+ XPATH_INVALID_CHAR_ERROR
+} xmlXPathError;
+
+/*
+ * A node-set (an unordered collection of nodes without duplicates).
+ */
+typedef struct _xmlNodeSet xmlNodeSet;
+typedef xmlNodeSet *xmlNodeSetPtr;
+struct _xmlNodeSet {
+ int nodeNr; /* number of nodes in the set */
+ int nodeMax; /* size of the array as allocated */
+ xmlNodePtr *nodeTab; /* array of nodes in no particular order */
+ /* @@ with_ns to check wether namespace nodes should be looked at @@ */
+};
+
+/*
+ * An expression is evaluated to yield an object, which
+ * has one of the following four basic types:
+ * - node-set
+ * - boolean
+ * - number
+ * - string
+ *
+ * @@ XPointer will add more types !
+ */
+
+typedef enum {
+ XPATH_UNDEFINED = 0,
+ XPATH_NODESET = 1,
+ XPATH_BOOLEAN = 2,
+ XPATH_NUMBER = 3,
+ XPATH_STRING = 4,
+ XPATH_POINT = 5,
+ XPATH_RANGE = 6,
+ XPATH_LOCATIONSET = 7,
+ XPATH_USERS = 8,
+ XPATH_XSLT_TREE = 9 /* An XSLT value tree, non modifiable */
+} xmlXPathObjectType;
+
+typedef struct _xmlXPathObject xmlXPathObject;
+typedef xmlXPathObject *xmlXPathObjectPtr;
+struct _xmlXPathObject {
+ xmlXPathObjectType type;
+ xmlNodeSetPtr nodesetval;
+ int boolval;
+ double floatval;
+ xmlChar *stringval;
+ void *user;
+ int index;
+ void *user2;
+ int index2;
+};
+
+/**
+ * xmlXPathConvertFunc:
+ * @obj: an XPath object
+ * @type: the number of the target type
+ *
+ * A conversion function is associated to a type and used to cast
+ * the new type to primitive values.
+ *
+ * Returns -1 in case of error, 0 otherwise
+ */
+typedef int (*xmlXPathConvertFunc) (xmlXPathObjectPtr obj, int type);
+
+/*
+ * Extra type: a name and a conversion function.
+ */
+
+typedef struct _xmlXPathType xmlXPathType;
+typedef xmlXPathType *xmlXPathTypePtr;
+struct _xmlXPathType {
+ const xmlChar *name; /* the type name */
+ xmlXPathConvertFunc func; /* the conversion function */
+};
+
+/*
+ * Extra variable: a name and a value.
+ */
+
+typedef struct _xmlXPathVariable xmlXPathVariable;
+typedef xmlXPathVariable *xmlXPathVariablePtr;
+struct _xmlXPathVariable {
+ const xmlChar *name; /* the variable name */
+ xmlXPathObjectPtr value; /* the value */
+};
+
+/**
+ * xmlXPathEvalFunc:
+ * @ctxt: an XPath parser context
+ * @nargs: the number of arguments passed to the function
+ *
+ * An XPath evaluation function, the parameters are on the XPath context stack.
+ */
+
+typedef void (*xmlXPathEvalFunc)(xmlXPathParserContextPtr ctxt,
+ int nargs);
+
+/*
+ * Extra function: a name and a evaluation function.
+ */
+
+typedef struct _xmlXPathFunct xmlXPathFunct;
+typedef xmlXPathFunct *xmlXPathFuncPtr;
+struct _xmlXPathFunct {
+ const xmlChar *name; /* the function name */
+ xmlXPathEvalFunc func; /* the evaluation function */
+};
+
+/**
+ * xmlXPathAxisFunc:
+ * @ctxt: the XPath interpreter context
+ * @cur: the previous node being explored on that axis
+ *
+ * An axis traversal function. To traverse an axis, the engine calls
+ * the first time with cur == NULL and repeat until the function returns
+ * NULL indicating the end of the axis traversal.
+ *
+ * Returns the next node in that axis or NULL if at the end of the axis.
+ */
+
+typedef xmlXPathObjectPtr (*xmlXPathAxisFunc) (xmlXPathParserContextPtr ctxt,
+ xmlXPathObjectPtr cur);
+
+/*
+ * Extra axis: a name and an axis function.
+ */
+
+typedef struct _xmlXPathAxis xmlXPathAxis;
+typedef xmlXPathAxis *xmlXPathAxisPtr;
+struct _xmlXPathAxis {
+ const xmlChar *name; /* the axis name */
+ xmlXPathAxisFunc func; /* the search function */
+};
+
+/**
+ * xmlXPathContext:
+ *
+ * Expression evaluation occurs with respect to a context.
+ * he context consists of:
+ * - a node (the context node)
+ * - a node list (the context node list)
+ * - a set of variable bindings
+ * - a function library
+ * - the set of namespace declarations in scope for the expression
+ * Following the switch to hash tables, this need to be trimmed up at
+ * the next binary incompatible release.
+ */
+
+struct _xmlXPathContext {
+ xmlDocPtr doc; /* The current document */
+ xmlNodePtr node; /* The current node */
+
+ int nb_variables_unused; /* unused (hash table) */
+ int max_variables_unused; /* unused (hash table) */
+ xmlHashTablePtr varHash; /* Hash table of defined variables */
+
+ int nb_types; /* number of defined types */
+ int max_types; /* max number of types */
+ xmlXPathTypePtr types; /* Array of defined types */
+
+ int nb_funcs_unused; /* unused (hash table) */
+ int max_funcs_unused; /* unused (hash table) */
+ xmlHashTablePtr funcHash; /* Hash table of defined funcs */
+
+ int nb_axis; /* number of defined axis */
+ int max_axis; /* max number of axis */
+ xmlXPathAxisPtr axis; /* Array of defined axis */
+
+ /* the namespace nodes of the context node */
+ xmlNsPtr *namespaces; /* Array of namespaces */
+ int nsNr; /* number of namespace in scope */
+ void *user; /* function to free */
+
+ /* extra variables */
+ int contextSize; /* the context size */
+ int proximityPosition; /* the proximity position */
+
+ /* extra stuff for XPointer */
+ int xptr; /* it this an XPointer context */
+ xmlNodePtr here; /* for here() */
+ xmlNodePtr origin; /* for origin() */
+
+ /* the set of namespace declarations in scope for the expression */
+ xmlHashTablePtr nsHash; /* The namespaces hash table */
+ void *varLookupFunc; /* variable lookup func */
+ void *varLookupData; /* variable lookup data */
+
+ /* Possibility to link in an extra item */
+ void *extra; /* needed for XSLT */
+
+ /* The function name and URI when calling a function */
+ const xmlChar *function;
+ const xmlChar *functionURI;
+
+ /* function lookup function and data */
+ void *funcLookupFunc; /* function lookup func */
+ void *funcLookupData; /* function lookup data */
+
+ /* temporary namespace lists kept for walking the namespace axis */
+ xmlNsPtr *tmpNsList; /* Array of namespaces */
+ int tmpNsNr; /* number of namespace in scope */
+};
+
+/*
+ * The structure of a compiled expression form is not public.
+ */
+
+typedef struct _xmlXPathCompExpr xmlXPathCompExpr;
+typedef xmlXPathCompExpr *xmlXPathCompExprPtr;
+
+/**
+ * xmlXPathParserContext:
+ *
+ * An XPath parser context. It contains pure parsing informations,
+ * an xmlXPathContext, and the stack of objects.
+ */
+struct _xmlXPathParserContext {
+ const xmlChar *cur; /* the current char being parsed */
+ const xmlChar *base; /* the full expression */
+
+ int error; /* error code */
+
+ xmlXPathContextPtr context; /* the evaluation context */
+ xmlXPathObjectPtr value; /* the current value */
+ int valueNr; /* number of values stacked */
+ int valueMax; /* max number of values stacked */
+ xmlXPathObjectPtr *valueTab; /* stack of values */
+
+ xmlXPathCompExprPtr comp; /* the precompiled expression */
+ int xptr; /* it this an XPointer expression */
+ xmlNodePtr ancestor; /* used for walking preceding axis */
+};
+
+/**
+ * xmlXPathFunction:
+ * @ctxt: the XPath interprestation context
+ * @nargs: the number of arguments
+ *
+ * An XPath function.
+ * The arguments (if any) are popped out from the context stack
+ * and the result is pushed on the stack.
+ */
+
+typedef void (*xmlXPathFunction) (xmlXPathParserContextPtr ctxt, int nargs);
+
+/************************************************************************
+ * *
+ * Public API *
+ * *
+ ************************************************************************/
+
+/**
+ * Objects and Nodesets handling
+ */
+
+LIBXML_DLL_IMPORT extern double xmlXPathNAN;
+LIBXML_DLL_IMPORT extern double xmlXPathPINF;
+LIBXML_DLL_IMPORT extern double xmlXPathNINF;
+
+int xmlXPathIsNaN (double val);
+int xmlXPathIsInf (double val);
+
+/* These macros may later turn into functions */
+/**
+ * xmlXPathNodeSetGetLength:
+ * @ns: a node-set
+ *
+ * Implement a functionality similar to the DOM NodeList.length.
+ *
+ * Returns the number of nodes in the node-set.
+ */
+#define xmlXPathNodeSetGetLength(ns) ((ns) ? (ns)->nodeNr : 0)
+/**
+ * xmlXPathNodeSetItem:
+ * @ns: a node-set
+ * @index: index of a node in the set
+ *
+ * Implements a functionality similar to the DOM NodeList.item().
+ *
+ * Returns the xmlNodePtr at the given @index in @ns or NULL if
+ * @index is out of range (0 to length-1)
+ */
+#define xmlXPathNodeSetItem(ns, index) \
+ ((((ns) != NULL) && \
+ ((index) >= 0) && ((index) < (ns)->nodeNr)) ? \
+ (ns)->nodeTab[(index)] \
+ : NULL)
+/**
+ * xmlXPathNodeSetIsEmpty:
+ * @ns: a node-set
+ *
+ * Checks whether @ns is empty or not.
+ *
+ * Returns %TRUE if @ns is an empty node-set.
+ */
+#define xmlXPathNodeSetIsEmpty(ns) \
+ (((ns) == NULL) || ((ns)->nodeNr == 0) || ((ns)->nodeTab == NULL))
+
+
+void xmlXPathFreeObject (xmlXPathObjectPtr obj);
+xmlNodeSetPtr xmlXPathNodeSetCreate (xmlNodePtr val);
+void xmlXPathFreeNodeSetList (xmlXPathObjectPtr obj);
+void xmlXPathFreeNodeSet (xmlNodeSetPtr obj);
+xmlXPathObjectPtr xmlXPathObjectCopy (xmlXPathObjectPtr val);
+int xmlXPathCmpNodes (xmlNodePtr node1,
+ xmlNodePtr node2);
+/**
+ * Conversion functions to basic types.
+ */
+int xmlXPathCastNumberToBoolean (double val);
+int xmlXPathCastStringToBoolean (const xmlChar * val);
+int xmlXPathCastNodeSetToBoolean (xmlNodeSetPtr ns);
+int xmlXPathCastToBoolean (xmlXPathObjectPtr val);
+
+double xmlXPathCastBooleanToNumber (int val);
+double xmlXPathCastStringToNumber (const xmlChar * val);
+double xmlXPathCastNodeToNumber (xmlNodePtr node);
+double xmlXPathCastNodeSetToNumber (xmlNodeSetPtr ns);
+double xmlXPathCastToNumber (xmlXPathObjectPtr val);
+
+xmlChar * xmlXPathCastBooleanToString (int val);
+xmlChar * xmlXPathCastNumberToString (double val);
+xmlChar * xmlXPathCastNodeToString (xmlNodePtr node);
+xmlChar * xmlXPathCastNodeSetToString (xmlNodeSetPtr ns);
+xmlChar * xmlXPathCastToString (xmlXPathObjectPtr val);
+
+xmlXPathObjectPtr xmlXPathConvertBoolean (xmlXPathObjectPtr val);
+xmlXPathObjectPtr xmlXPathConvertNumber (xmlXPathObjectPtr val);
+xmlXPathObjectPtr xmlXPathConvertString (xmlXPathObjectPtr val);
+
+/**
+ * Context handling.
+ */
+void xmlXPathInit (void);
+xmlXPathContextPtr xmlXPathNewContext (xmlDocPtr doc);
+void xmlXPathFreeContext (xmlXPathContextPtr ctxt);
+
+/**
+ * Evaluation functions.
+ */
+xmlXPathObjectPtr xmlXPathEval (const xmlChar *str,
+ xmlXPathContextPtr ctx);
+xmlXPathObjectPtr xmlXPathEvalExpression (const xmlChar *str,
+ xmlXPathContextPtr ctxt);
+int xmlXPathEvalPredicate (xmlXPathContextPtr ctxt,
+ xmlXPathObjectPtr res);
+/**
+ * Separate compilation/evaluation entry points.
+ */
+xmlXPathCompExprPtr xmlXPathCompile (const xmlChar *str);
+xmlXPathObjectPtr xmlXPathCompiledEval (xmlXPathCompExprPtr comp,
+ xmlXPathContextPtr ctx);
+void xmlXPathFreeCompExpr (xmlXPathCompExprPtr comp);
+#ifdef __cplusplus
+}
+#endif
+#endif /* ! __XML_XPATH_H__ */
diff --git a/plugins/Variables/src/libxml/xpathInternals.h b/plugins/Variables/src/libxml/xpathInternals.h
new file mode 100644
index 0000000000..59a4e35d53
--- /dev/null
+++ b/plugins/Variables/src/libxml/xpathInternals.h
@@ -0,0 +1,580 @@
+/*
+ * xpathInternals.c: internal interfaces for XML Path Language implementation
+ * used to build new modules on top of XPath
+ *
+ * See COPYRIGHT for the status of this software
+ *
+ * Author: daniel@veillard.com
+ */
+
+#ifndef __XML_XPATH_INTERNALS_H__
+#define __XML_XPATH_INTERNALS_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/xpath.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/************************************************************************
+ * *
+ * Helpers *
+ * *
+ ************************************************************************/
+
+/**
+ * Many of these macros may later turn into functions. They
+ * shouldn't be used in #ifdef's preprocessor instructions.
+ */
+/**
+ * xmlXPathSetError:
+ * @ctxt: an XPath parser context
+ * @err: an xmlXPathError code
+ *
+ * Raises an error.
+ */
+#define xmlXPathSetError(ctxt, err) \
+ { xmlXPatherror((ctxt), __FILE__, __LINE__, (err)); \
+ (ctxt)->error = (err); }
+
+/**
+ * xmlXPathSetArityError:
+ * @ctxt: an XPath parser context
+ *
+ * Raises an XPATH_INVALID_ARITY error.
+ */
+#define xmlXPathSetArityError(ctxt) \
+ xmlXPathSetError((ctxt), XPATH_INVALID_ARITY)
+
+/**
+ * xmlXPathSetTypeError:
+ * @ctxt: an XPath parser context
+ *
+ * Raises an XPATH_INVALID_TYPE error.
+ */
+#define xmlXPathSetTypeError(ctxt) \
+ xmlXPathSetError((ctxt), XPATH_INVALID_TYPE)
+
+/**
+ * xmlXPathGetError:
+ * @ctxt: an XPath parser context
+ *
+ * Get the error code of an XPath context.
+ *
+ * Returns the context error.
+ */
+#define xmlXPathGetError(ctxt) ((ctxt)->error)
+
+/**
+ * xmlXPathCheckError:
+ * @ctxt: an XPath parser context
+ *
+ * Check if an XPath error was raised.
+ *
+ * Returns true if an error has been raised, false otherwise.
+ */
+#define xmlXPathCheckError(ctxt) ((ctxt)->error != XPATH_EXPRESSION_OK)
+
+/**
+ * xmlXPathGetDocument:
+ * @ctxt: an XPath parser context
+ *
+ * Get the document of an XPath context.
+ *
+ * Returns the context document.
+ */
+#define xmlXPathGetDocument(ctxt) ((ctxt)->context->doc)
+
+/**
+ * xmlXPathGetContextNode:
+ * @ctxt: an XPath parser context
+ *
+ * Get the context node of an XPath context.
+ *
+ * Returns the context node.
+ */
+#define xmlXPathGetContextNode(ctxt) ((ctxt)->context->node)
+
+int xmlXPathPopBoolean (xmlXPathParserContextPtr ctxt);
+double xmlXPathPopNumber (xmlXPathParserContextPtr ctxt);
+xmlChar * xmlXPathPopString (xmlXPathParserContextPtr ctxt);
+xmlNodeSetPtr xmlXPathPopNodeSet (xmlXPathParserContextPtr ctxt);
+void * xmlXPathPopExternal (xmlXPathParserContextPtr ctxt);
+
+/**
+ * xmlXPathReturnBoolean:
+ * @ctxt: an XPath parser context
+ * @val: a boolean
+ *
+ * Pushes the boolean @val on the context stack.
+ */
+#define xmlXPathReturnBoolean(ctxt, val) \
+ valuePush((ctxt), xmlXPathNewBoolean(val))
+
+/**
+ * xmlXPathReturnTrue:
+ * @ctxt: an XPath parser context
+ *
+ * Pushes true on the context stack.
+ */
+#define xmlXPathReturnTrue(ctxt) xmlXPathReturnBoolean((ctxt), 1)
+
+/**
+ * xmlXPathReturnFalse:
+ * @ctxt: an XPath parser context
+ *
+ * Pushes false on the context stack.
+ */
+#define xmlXPathReturnFalse(ctxt) xmlXPathReturnBoolean((ctxt), 0)
+
+/**
+ * xmlXPathReturnNumber:
+ * @ctxt: an XPath parser context
+ * @val: a double
+ *
+ * Pushes the double @val on the context stack.
+ */
+#define xmlXPathReturnNumber(ctxt, val) \
+ valuePush((ctxt), xmlXPathNewFloat(val))
+
+/**
+ * xmlXPathReturnString:
+ * @ctxt: an XPath parser context
+ * @str: a string
+ *
+ * Pushes the string @str on the context stack.
+ */
+#define xmlXPathReturnString(ctxt, str) \
+ valuePush((ctxt), xmlXPathWrapString(str))
+
+/**
+ * xmlXPathReturnEmptyString:
+ * @ctxt: an XPath parser context
+ *
+ * Pushes an empty string on the stack.
+ */
+#define xmlXPathReturnEmptyString(ctxt) \
+ valuePush((ctxt), xmlXPathNewCString(""))
+
+/**
+ * xmlXPathReturnNodeSet:
+ * @ctxt: an XPath parser context
+ * @ns: a node-set
+ *
+ * Pushes the node-set @ns on the context stack.
+ */
+#define xmlXPathReturnNodeSet(ctxt, ns) \
+ valuePush((ctxt), xmlXPathWrapNodeSet(ns))
+
+/**
+ * xmlXPathReturnEmptyNodeSet:
+ * @ctxt: an XPath parser context
+ *
+ * Pushes an empty node-set on the context stack.
+ */
+#define xmlXPathReturnEmptyNodeSet(ctxt) \
+ valuePush((ctxt), xmlXPathNewNodeSet(NULL))
+
+/**
+ * xmlXPathReturnExternal:
+ * @ctxt: an XPath parser context
+ * @val: user data
+ *
+ * Pushes user data on the context stack.
+ */
+#define xmlXPathReturnExternal(ctxt, val) \
+ valuePush((ctxt), xmlXPathWrapExternal(val))
+
+/**
+ * xmlXPathStackIsNodeSet:
+ * @ctxt: an XPath parser context
+ *
+ * Check if the current value on the XPath stack is a node set or
+ * an XSLT value tree.
+ *
+ * Returns true if the current object on the stack is a node-set.
+ */
+#define xmlXPathStackIsNodeSet(ctxt) \
+ (((ctxt)->value != NULL) \
+ && (((ctxt)->value->type == XPATH_NODESET) \
+ || ((ctxt)->value->type == XPATH_XSLT_TREE)))
+
+/**
+ * xmlXPathStackIsExternal:
+ * @ctxt: an XPath parser context
+ *
+ * Checks if the current value on the XPath stack is an external
+ * object.
+ *
+ * Returns true if the current object on the stack is an external
+ * object.
+ */
+#define xmlXPathStackIsExternal(ctxt) \
+ ((ctxt->value != NULL) && (ctxt->value->type == XPATH_USERS))
+
+/**
+ * xmlXPathEmptyNodeSet:
+ * @ns: a node-set
+ *
+ * Empties a node-set.
+ */
+#define xmlXPathEmptyNodeSet(ns) \
+ { while ((ns)->nodeNr > 0) (ns)->nodeTab[(ns)->nodeNr--] = NULL; }
+
+/**
+ * CHECK_ERROR:
+ *
+ * Macro to return from the function if an XPath error was detected.
+ */
+#define CHECK_ERROR \
+ if (ctxt->error != XPATH_EXPRESSION_OK) return
+
+/**
+ * CHECK_ERROR0:
+ *
+ * Macro to return 0 from the function if an XPath error was detected.
+ */
+#define CHECK_ERROR0 \
+ if (ctxt->error != XPATH_EXPRESSION_OK) return(0)
+
+/**
+ * XP_ERROR:
+ * @X: the error code
+ *
+ * Macro to raise an XPath error and return.
+ */
+#define XP_ERROR(X) \
+ { xmlXPatherror(ctxt, __FILE__, __LINE__, X); \
+ ctxt->error = (X); return; }
+
+/**
+ * XP_ERROR0:
+ * @X: the error code
+ *
+ * Macro to raise an XPath error and return 0.
+ */
+#define XP_ERROR0(X) \
+ { xmlXPatherror(ctxt, __FILE__, __LINE__, X); \
+ ctxt->error = (X); return(0); }
+
+/**
+ * CHECK_TYPE:
+ * @typeval: the XPath type
+ *
+ * Macro to check that the value on top of the XPath stack is of a given
+ * type.
+ */
+#define CHECK_TYPE(typeval) \
+ if ((ctxt->value == NULL) || (ctxt->value->type != typeval)) \
+ XP_ERROR(XPATH_INVALID_TYPE)
+
+/**
+ * CHECK_TYPE0:
+ * @typeval: the XPath type
+ *
+ * Macro to check that the value on top of the XPath stack is of a given
+ * type. Return(0) in case of failure
+ */
+#define CHECK_TYPE0(typeval) \
+ if ((ctxt->value == NULL) || (ctxt->value->type != typeval)) \
+ XP_ERROR0(XPATH_INVALID_TYPE)
+
+/**
+ * CHECK_ARITY:
+ * @x: the number of expected args
+ *
+ * Macro to check that the number of args passed to an XPath function matches.
+ */
+#define CHECK_ARITY(x) \
+ if (nargs != (x)) \
+ XP_ERROR(XPATH_INVALID_ARITY);
+
+/**
+ * CAST_TO_STRING:
+ *
+ * Macro to try to cast the value on the top of the XPath stack to a string.
+ */
+#define CAST_TO_STRING \
+ if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_STRING)) \
+ xmlXPathStringFunction(ctxt, 1);
+
+/**
+ * CAST_TO_NUMBER:
+ *
+ * Macro to try to cast the value on the top of the XPath stack to a number.
+ */
+#define CAST_TO_NUMBER \
+ if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_NUMBER)) \
+ xmlXPathNumberFunction(ctxt, 1);
+
+/**
+ * CAST_TO_BOOLEAN:
+ *
+ * Macro to try to cast the value on the top of the XPath stack to a boolean.
+ */
+#define CAST_TO_BOOLEAN \
+ if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_BOOLEAN)) \
+ xmlXPathBooleanFunction(ctxt, 1);
+
+/*
+ * Variable Lookup forwarding.
+ */
+/**
+ * xmlXPathVariableLookupFunc:
+ * @ctxt: an XPath context
+ * @name: name of the variable
+ * @ns_uri: the namespace name hosting this variable
+ *
+ * Prototype for callbacks used to plug variable lookup in the XPath
+ * engine.
+ *
+ * Returns the XPath object value or NULL if not found.
+ */
+typedef xmlXPathObjectPtr (*xmlXPathVariableLookupFunc) (void *ctxt,
+ const xmlChar *name,
+ const xmlChar *ns_uri);
+
+void xmlXPathRegisterVariableLookup (xmlXPathContextPtr ctxt,
+ xmlXPathVariableLookupFunc f,
+ void *data);
+
+/*
+ * Function Lookup forwarding.
+ */
+/**
+ * xmlXPathFuncLookupFunc:
+ * @ctxt: an XPath context
+ * @name: name of the function
+ * @ns_uri: the namespace name hosting this function
+ *
+ * Prototype for callbacks used to plug function lookup in the XPath
+ * engine.
+ *
+ * Returns the XPath function or NULL if not found.
+ */
+typedef xmlXPathFunction (*xmlXPathFuncLookupFunc) (void *ctxt,
+ const xmlChar *name,
+ const xmlChar *ns_uri);
+
+void xmlXPathRegisterFuncLookup (xmlXPathContextPtr ctxt,
+ xmlXPathFuncLookupFunc f,
+ void *funcCtxt);
+
+/*
+ * Error reporting.
+ */
+void xmlXPatherror (xmlXPathParserContextPtr ctxt,
+ const char *file,
+ int line,
+ int no);
+
+void xmlXPathDebugDumpObject (FILE *output,
+ xmlXPathObjectPtr cur,
+ int depth);
+void xmlXPathDebugDumpCompExpr(FILE *output,
+ xmlXPathCompExprPtr comp,
+ int depth);
+
+/**
+ * NodeSet handling.
+ */
+int xmlXPathNodeSetContains (xmlNodeSetPtr cur,
+ xmlNodePtr val);
+xmlNodeSetPtr xmlXPathDifference (xmlNodeSetPtr nodes1,
+ xmlNodeSetPtr nodes2);
+xmlNodeSetPtr xmlXPathIntersection (xmlNodeSetPtr nodes1,
+ xmlNodeSetPtr nodes2);
+
+xmlNodeSetPtr xmlXPathDistinctSorted (xmlNodeSetPtr nodes);
+xmlNodeSetPtr xmlXPathDistinct (xmlNodeSetPtr nodes);
+
+int xmlXPathHasSameNodes (xmlNodeSetPtr nodes1,
+ xmlNodeSetPtr nodes2);
+
+xmlNodeSetPtr xmlXPathNodeLeadingSorted (xmlNodeSetPtr nodes,
+ xmlNodePtr node);
+xmlNodeSetPtr xmlXPathLeadingSorted (xmlNodeSetPtr nodes1,
+ xmlNodeSetPtr nodes2);
+xmlNodeSetPtr xmlXPathNodeLeading (xmlNodeSetPtr nodes,
+ xmlNodePtr node);
+xmlNodeSetPtr xmlXPathLeading (xmlNodeSetPtr nodes1,
+ xmlNodeSetPtr nodes2);
+
+xmlNodeSetPtr xmlXPathNodeTrailingSorted (xmlNodeSetPtr nodes,
+ xmlNodePtr node);
+xmlNodeSetPtr xmlXPathTrailingSorted (xmlNodeSetPtr nodes1,
+ xmlNodeSetPtr nodes2);
+xmlNodeSetPtr xmlXPathNodeTrailing (xmlNodeSetPtr nodes,
+ xmlNodePtr node);
+xmlNodeSetPtr xmlXPathTrailing (xmlNodeSetPtr nodes1,
+ xmlNodeSetPtr nodes2);
+
+
+/**
+ * Extending a context.
+ */
+
+int xmlXPathRegisterNs (xmlXPathContextPtr ctxt,
+ const xmlChar *prefix,
+ const xmlChar *ns_uri);
+const xmlChar * xmlXPathNsLookup (xmlXPathContextPtr ctxt,
+ const xmlChar *prefix);
+void xmlXPathRegisteredNsCleanup (xmlXPathContextPtr ctxt);
+
+int xmlXPathRegisterFunc (xmlXPathContextPtr ctxt,
+ const xmlChar *name,
+ xmlXPathFunction f);
+int xmlXPathRegisterFuncNS (xmlXPathContextPtr ctxt,
+ const xmlChar *name,
+ const xmlChar *ns_uri,
+ xmlXPathFunction f);
+int xmlXPathRegisterVariable (xmlXPathContextPtr ctxt,
+ const xmlChar *name,
+ xmlXPathObjectPtr value);
+int xmlXPathRegisterVariableNS (xmlXPathContextPtr ctxt,
+ const xmlChar *name,
+ const xmlChar *ns_uri,
+ xmlXPathObjectPtr value);
+xmlXPathFunction xmlXPathFunctionLookup (xmlXPathContextPtr ctxt,
+ const xmlChar *name);
+xmlXPathFunction xmlXPathFunctionLookupNS (xmlXPathContextPtr ctxt,
+ const xmlChar *name,
+ const xmlChar *ns_uri);
+void xmlXPathRegisteredFuncsCleanup(xmlXPathContextPtr ctxt);
+xmlXPathObjectPtr xmlXPathVariableLookup (xmlXPathContextPtr ctxt,
+ const xmlChar *name);
+xmlXPathObjectPtr xmlXPathVariableLookupNS (xmlXPathContextPtr ctxt,
+ const xmlChar *name,
+ const xmlChar *ns_uri);
+void xmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt);
+
+/**
+ * Utilities to extend XPath.
+ */
+xmlXPathParserContextPtr
+ xmlXPathNewParserContext (const xmlChar *str,
+ xmlXPathContextPtr ctxt);
+void xmlXPathFreeParserContext (xmlXPathParserContextPtr ctxt);
+
+/* TODO: remap to xmlXPathValuePop and Push. */
+xmlXPathObjectPtr valuePop (xmlXPathParserContextPtr ctxt);
+int valuePush (xmlXPathParserContextPtr ctxt,
+ xmlXPathObjectPtr value);
+
+xmlXPathObjectPtr xmlXPathNewString (const xmlChar *val);
+xmlXPathObjectPtr xmlXPathNewCString (const char *val);
+xmlXPathObjectPtr xmlXPathWrapString (xmlChar *val);
+xmlXPathObjectPtr xmlXPathWrapCString (char * val);
+xmlXPathObjectPtr xmlXPathNewFloat (double val);
+xmlXPathObjectPtr xmlXPathNewBoolean (int val);
+xmlXPathObjectPtr xmlXPathNewNodeSet (xmlNodePtr val);
+xmlXPathObjectPtr xmlXPathNewValueTree (xmlNodePtr val);
+void xmlXPathNodeSetAdd (xmlNodeSetPtr cur,
+ xmlNodePtr val);
+void xmlXPathNodeSetAddUnique (xmlNodeSetPtr cur,
+ xmlNodePtr val);
+void xmlXPathNodeSetAddNs (xmlNodeSetPtr cur,
+ xmlNodePtr node,
+ xmlNsPtr ns);
+void xmlXPathNodeSetSort (xmlNodeSetPtr set);
+
+void xmlXPathRoot (xmlXPathParserContextPtr ctxt);
+void xmlXPathEvalExpr (xmlXPathParserContextPtr ctxt);
+xmlChar * xmlXPathParseName (xmlXPathParserContextPtr ctxt);
+xmlChar * xmlXPathParseNCName (xmlXPathParserContextPtr ctxt);
+
+/*
+ * Existing functions.
+ */
+double xmlXPathStringEvalNumber(const xmlChar *str);
+int xmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt,
+ xmlXPathObjectPtr res);
+void xmlXPathRegisterAllFunctions(xmlXPathContextPtr ctxt);
+xmlNodeSetPtr xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2);
+void xmlXPathNodeSetDel(xmlNodeSetPtr cur, xmlNodePtr val);
+void xmlXPathNodeSetRemove(xmlNodeSetPtr cur, int val);
+xmlXPathObjectPtr xmlXPathNewNodeSetList(xmlNodeSetPtr val);
+xmlXPathObjectPtr xmlXPathWrapNodeSet(xmlNodeSetPtr val);
+xmlXPathObjectPtr xmlXPathWrapExternal(void *val);
+
+int xmlXPathEqualValues(xmlXPathParserContextPtr ctxt);
+int xmlXPathNotEqualValues(xmlXPathParserContextPtr ctxt);
+int xmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict);
+void xmlXPathValueFlipSign(xmlXPathParserContextPtr ctxt);
+void xmlXPathAddValues(xmlXPathParserContextPtr ctxt);
+void xmlXPathSubValues(xmlXPathParserContextPtr ctxt);
+void xmlXPathMultValues(xmlXPathParserContextPtr ctxt);
+void xmlXPathDivValues(xmlXPathParserContextPtr ctxt);
+void xmlXPathModValues(xmlXPathParserContextPtr ctxt);
+
+int xmlXPathIsNodeType(const xmlChar *name);
+
+/*
+ * Some of the axis navigation routines.
+ */
+xmlNodePtr xmlXPathNextSelf(xmlXPathParserContextPtr ctxt,
+ xmlNodePtr cur);
+xmlNodePtr xmlXPathNextChild(xmlXPathParserContextPtr ctxt,
+ xmlNodePtr cur);
+xmlNodePtr xmlXPathNextDescendant(xmlXPathParserContextPtr ctxt,
+ xmlNodePtr cur);
+xmlNodePtr xmlXPathNextDescendantOrSelf(xmlXPathParserContextPtr ctxt,
+ xmlNodePtr cur);
+xmlNodePtr xmlXPathNextParent(xmlXPathParserContextPtr ctxt,
+ xmlNodePtr cur);
+xmlNodePtr xmlXPathNextAncestorOrSelf(xmlXPathParserContextPtr ctxt,
+ xmlNodePtr cur);
+xmlNodePtr xmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt,
+ xmlNodePtr cur);
+xmlNodePtr xmlXPathNextFollowing(xmlXPathParserContextPtr ctxt,
+ xmlNodePtr cur);
+xmlNodePtr xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt,
+ xmlNodePtr cur);
+xmlNodePtr xmlXPathNextAttribute(xmlXPathParserContextPtr ctxt,
+ xmlNodePtr cur);
+xmlNodePtr xmlXPathNextPreceding(xmlXPathParserContextPtr ctxt,
+ xmlNodePtr cur);
+xmlNodePtr xmlXPathNextAncestor(xmlXPathParserContextPtr ctxt,
+ xmlNodePtr cur);
+xmlNodePtr xmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt,
+ xmlNodePtr cur);
+/*
+ * The official core of XPath functions.
+ */
+void xmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathNamespaceURIFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathContainsFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathStartsWithFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathNotFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathTrueFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathFalseFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathLangFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs);
+void xmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs);
+
+/**
+ * Really internal functions
+ */
+void xmlXPathNodeSetFreeNs(xmlNsPtr ns);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* ! __XML_XPATH_INTERNALS_H__ */
diff --git a/plugins/Variables/src/libxml/xpointer.h b/plugins/Variables/src/libxml/xpointer.h
new file mode 100644
index 0000000000..80c465c70f
--- /dev/null
+++ b/plugins/Variables/src/libxml/xpointer.h
@@ -0,0 +1,83 @@
+/*
+ * xpointer.h : API to handle XML Pointers
+ *
+ * World Wide Web Consortium Working Draft 03-March-1998
+ * http://www.w3.org/TR/1998/WD-xptr-19980303
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifndef __XML_XPTR_H__
+#define __XML_XPTR_H__
+
+#include <libxml/tree.h>
+#include <libxml/xpath.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * A Location Set
+ */
+typedef struct _xmlLocationSet xmlLocationSet;
+typedef xmlLocationSet *xmlLocationSetPtr;
+struct _xmlLocationSet {
+ int locNr; /* number of locations in the set */
+ int locMax; /* size of the array as allocated */
+ xmlXPathObjectPtr *locTab;/* array of locations */
+};
+
+/*
+ * Handling of location sets.
+ */
+
+xmlLocationSetPtr xmlXPtrLocationSetCreate(xmlXPathObjectPtr val);
+void xmlXPtrFreeLocationSet (xmlLocationSetPtr obj);
+xmlLocationSetPtr xmlXPtrLocationSetMerge (xmlLocationSetPtr val1,
+ xmlLocationSetPtr val2);
+xmlXPathObjectPtr xmlXPtrNewRange (xmlNodePtr start,
+ int startindex,
+ xmlNodePtr end,
+ int endindex);
+xmlXPathObjectPtr xmlXPtrNewRangePoints (xmlXPathObjectPtr start,
+ xmlXPathObjectPtr end);
+xmlXPathObjectPtr xmlXPtrNewRangeNodePoint(xmlNodePtr start,
+ xmlXPathObjectPtr end);
+xmlXPathObjectPtr xmlXPtrNewRangePointNode(xmlXPathObjectPtr start,
+ xmlNodePtr end);
+xmlXPathObjectPtr xmlXPtrNewRangeNodes (xmlNodePtr start,
+ xmlNodePtr end);
+xmlXPathObjectPtr xmlXPtrNewLocationSetNodes(xmlNodePtr start,
+ xmlNodePtr end);
+xmlXPathObjectPtr xmlXPtrNewLocationSetNodeSet(xmlNodeSetPtr set);
+xmlXPathObjectPtr xmlXPtrNewRangeNodeObject(xmlNodePtr start,
+ xmlXPathObjectPtr end);
+xmlXPathObjectPtr xmlXPtrNewCollapsedRange(xmlNodePtr start);
+void xmlXPtrLocationSetAdd (xmlLocationSetPtr cur,
+ xmlXPathObjectPtr val);
+xmlXPathObjectPtr xmlXPtrWrapLocationSet (xmlLocationSetPtr val);
+void xmlXPtrLocationSetDel (xmlLocationSetPtr cur,
+ xmlXPathObjectPtr val);
+void xmlXPtrLocationSetRemove(xmlLocationSetPtr cur,
+ int val);
+
+/*
+ * Functions.
+ */
+xmlXPathContextPtr xmlXPtrNewContext (xmlDocPtr doc,
+ xmlNodePtr here,
+ xmlNodePtr origin);
+xmlXPathObjectPtr xmlXPtrEval (const xmlChar *str,
+ xmlXPathContextPtr ctx);
+void xmlXPtrRangeToFunction (xmlXPathParserContextPtr ctxt,
+ int nargs);
+xmlNodePtr xmlXPtrBuildNodeList (xmlXPathObjectPtr obj);
+void xmlXPtrEvalRangePredicate (xmlXPathParserContextPtr ctxt);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_XPTR_H__ */
diff --git a/plugins/Variables/src/libxslt/numbersInternals.h b/plugins/Variables/src/libxslt/numbersInternals.h
new file mode 100644
index 0000000000..8707789521
--- /dev/null
+++ b/plugins/Variables/src/libxslt/numbersInternals.h
@@ -0,0 +1,69 @@
+/*
+ * numbers.h: Implementation of the XSLT number functions
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ * Bjorn Reese <breese@users.sourceforge.net>
+ */
+
+#ifndef __XML_XSLT_NUMBERSINTERNALS_H__
+#define __XML_XSLT_NUMBERSINTERNALS_H__
+
+#include "libxml/tree.h"
+#include "xsltexports.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * xsltNumberData:
+ *
+ * This data structure is just a wrapper to pass xsl:number data in.
+ */
+typedef struct _xsltNumberData xsltNumberData;
+typedef xsltNumberData *xsltNumberDataPtr;
+
+struct _xsltNumberData {
+ xmlChar *level;
+ xmlChar *count;
+ xmlChar *from;
+ xmlChar *value;
+ xmlChar *format;
+ int has_format;
+ int digitsPerGroup;
+ int groupingCharacter;
+ int groupingCharacterLen;
+ xmlDocPtr doc;
+ xmlNodePtr node;
+
+ /*
+ * accelerators
+ */
+};
+
+/**
+ * xsltFormatNumberInfo,:
+ *
+ * This data structure lists the various parameters needed to format numbers.
+ */
+typedef struct _xsltFormatNumberInfo xsltFormatNumberInfo;
+typedef xsltFormatNumberInfo *xsltFormatNumberInfoPtr;
+
+struct _xsltFormatNumberInfo {
+ int integer_hash; /* Number of '#' in integer part */
+ int integer_digits; /* Number of '0' in integer part */
+ int frac_digits; /* Number of '0' in fractional part */
+ int frac_hash; /* Number of '#' in fractional part */
+ int group; /* Number of chars per display 'group' */
+ int multiplier; /* Scaling for percent or permille */
+ char add_decimal; /* Flag for whether decimal point appears in pattern */
+ char is_multiplier_set; /* Flag to catch multiple occurences of percent/permille */
+ char is_negative_pattern;/* Flag for processing -ve prefix/suffix */
+};
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_XSLT_NUMBERSINTERNALS_H__ */
diff --git a/plugins/Variables/src/libxslt/transform.h b/plugins/Variables/src/libxslt/transform.h
new file mode 100644
index 0000000000..10d3d2d55a
--- /dev/null
+++ b/plugins/Variables/src/libxslt/transform.h
@@ -0,0 +1,191 @@
+/*
+ * transform.h: Interfaces, constants and types related to the XSLT engine
+ * transform part.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifndef __XML_XSLT_TRANSFORM_H__
+#define __XML_XSLT_TRANSFORM_H__
+
+#include "libxml/parser.h"
+#include "libxml/xmlIO.h"
+#include "xsltexports.h"
+#include "libxslt/xsltInternals.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * XInclude default processing.
+ */
+XSLTPUBFUN void XSLTCALL
+ xsltSetXIncludeDefault (int xinclude);
+XSLTPUBFUN int XSLTCALL
+ xsltGetXIncludeDefault (void);
+
+/**
+ * Export context to users.
+ */
+XSLTPUBFUN xsltTransformContextPtr XSLTCALL
+ xsltNewTransformContext (xsltStylesheetPtr style,
+ xmlDocPtr doc);
+
+XSLTPUBFUN void XSLTCALL
+ xsltFreeTransformContext(xsltTransformContextPtr ctxt);
+
+XSLTPUBFUN xmlDocPtr XSLTCALL
+ xsltApplyStylesheetUser (xsltStylesheetPtr style,
+ xmlDocPtr doc,
+ const char **params,
+ const char *output,
+ FILE * profile,
+ xsltTransformContextPtr userCtxt);
+/**
+ * Private Interfaces.
+ */
+XSLTPUBFUN void XSLTCALL
+ xsltApplyStripSpaces (xsltTransformContextPtr ctxt,
+ xmlNodePtr node);
+XSLTPUBFUN xmlDocPtr XSLTCALL
+ xsltApplyStylesheet (xsltStylesheetPtr style,
+ xmlDocPtr doc,
+ const char **params);
+XSLTPUBFUN xmlDocPtr XSLTCALL
+ xsltProfileStylesheet (xsltStylesheetPtr style,
+ xmlDocPtr doc,
+ const char **params,
+ FILE * output);
+XSLTPUBFUN int XSLTCALL
+ xsltRunStylesheet (xsltStylesheetPtr style,
+ xmlDocPtr doc,
+ const char **params,
+ const char *output,
+ xmlSAXHandlerPtr SAX,
+ xmlOutputBufferPtr IObuf);
+XSLTPUBFUN int XSLTCALL
+ xsltRunStylesheetUser (xsltStylesheetPtr style,
+ xmlDocPtr doc,
+ const char **params,
+ const char *output,
+ xmlSAXHandlerPtr SAX,
+ xmlOutputBufferPtr IObuf,
+ FILE * profile,
+ xsltTransformContextPtr userCtxt);
+XSLTPUBFUN void XSLTCALL
+ xsltApplyOneTemplate (xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr list,
+ xsltTemplatePtr templ,
+ xsltStackElemPtr params);
+XSLTPUBFUN void XSLTCALL
+ xsltDocumentElem (xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr inst,
+ xsltStylePreCompPtr comp);
+XSLTPUBFUN void XSLTCALL
+ xsltSort (xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr inst,
+ xsltStylePreCompPtr comp);
+XSLTPUBFUN void XSLTCALL
+ xsltCopy (xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr inst,
+ xsltStylePreCompPtr comp);
+XSLTPUBFUN void XSLTCALL
+ xsltText (xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr inst,
+ xsltStylePreCompPtr comp);
+XSLTPUBFUN void XSLTCALL
+ xsltElement (xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr inst,
+ xsltStylePreCompPtr comp);
+XSLTPUBFUN void XSLTCALL
+ xsltComment (xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr inst,
+ xsltStylePreCompPtr comp);
+XSLTPUBFUN void XSLTCALL
+ xsltAttribute (xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr inst,
+ xsltStylePreCompPtr comp);
+XSLTPUBFUN void XSLTCALL
+ xsltProcessingInstruction(xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr inst,
+ xsltStylePreCompPtr comp);
+XSLTPUBFUN void XSLTCALL
+ xsltCopyOf (xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr inst,
+ xsltStylePreCompPtr comp);
+XSLTPUBFUN void XSLTCALL
+ xsltValueOf (xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr inst,
+ xsltStylePreCompPtr comp);
+XSLTPUBFUN void XSLTCALL
+ xsltNumber (xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr inst,
+ xsltStylePreCompPtr comp);
+XSLTPUBFUN void XSLTCALL
+ xsltApplyImports (xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr inst,
+ xsltStylePreCompPtr comp);
+XSLTPUBFUN void XSLTCALL
+ xsltCallTemplate (xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr inst,
+ xsltStylePreCompPtr comp);
+XSLTPUBFUN void XSLTCALL
+ xsltApplyTemplates (xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr inst,
+ xsltStylePreCompPtr comp);
+XSLTPUBFUN void XSLTCALL
+ xsltChoose (xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr inst,
+ xsltStylePreCompPtr comp);
+XSLTPUBFUN void XSLTCALL
+ xsltIf (xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr inst,
+ xsltStylePreCompPtr comp);
+XSLTPUBFUN void XSLTCALL
+ xsltForEach (xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr inst,
+ xsltStylePreCompPtr comp);
+XSLTPUBFUN void XSLTCALL
+ xsltRegisterAllElement (xsltTransformContextPtr ctxt);
+
+XSLTPUBFUN xmlNodePtr XSLTCALL
+ xsltCopyTextString (xsltTransformContextPtr ctxt,
+ xmlNodePtr target,
+ const xmlChar *string,
+ int noescape);
+/*
+ * Hook for the debugger if activated.
+ */
+XSLTPUBFUN void XSLTCALL
+ xslHandleDebugger (xmlNodePtr cur,
+ xmlNodePtr node,
+ xsltTemplatePtr templ,
+ xsltTransformContextPtr ctxt);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_XSLT_TRANSFORM_H__ */
+
diff --git a/plugins/Variables/src/libxslt/win32config.h b/plugins/Variables/src/libxslt/win32config.h
new file mode 100644
index 0000000000..249408b54a
--- /dev/null
+++ b/plugins/Variables/src/libxslt/win32config.h
@@ -0,0 +1,96 @@
+#ifndef __LIBXSLT_WIN32_CONFIG__
+#define __LIBXSLT_WIN32_CONFIG__
+
+#define HAVE_CTYPE_H 1
+#define HAVE_STDLIB_H 1
+#define HAVE_MALLOC_H 1
+#define HAVE_TIME_H 1
+#define HAVE_LOCALTIME 1
+#define HAVE_GMTIME 1
+#define HAVE_TIME 1
+#define HAVE_MATH_H 1
+#define HAVE_FCNTL_H 1
+
+#include <io.h>
+
+#define HAVE_ISINF
+#define HAVE_ISNAN
+
+#include <math.h>
+#ifdef _MSC_VER
+/* MS C-runtime has functions which can be used in order to determine if
+ a given floating-point variable contains NaN, (+-)INF. These are
+ preferred, because floating-point technology is considered propriatary
+ by MS and we can assume that their functions know more about their
+ oddities than we do. */
+#include <float.h>
+/* Bjorn Reese figured a quite nice construct for isinf() using the
+ _fpclass() function. */
+#ifndef isinf
+#define isinf(d) ((_fpclass(d) == _FPCLASS_PINF) ? 1 \
+ : ((_fpclass(d) == _FPCLASS_NINF) ? -1 : 0))
+#endif
+/* _isnan(x) returns nonzero if (x == NaN) and zero otherwise. */
+#ifndef isnan
+#define isnan(d) (_isnan(d))
+#endif
+#else /* _MSC_VER */
+static int isinf (double d) {
+ int expon = 0;
+ double val = frexp (d, &expon);
+ if (expon == 1025) {
+ if (val == 0.5) {
+ return 1;
+ } else if (val == -0.5) {
+ return -1;
+ } else {
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+}
+static int isnan (double d) {
+ int expon = 0;
+ double val = frexp (d, &expon);
+ if (expon == 1025) {
+ if (val == 0.5) {
+ return 0;
+ } else if (val == -0.5) {
+ return 0;
+ } else {
+ return 1;
+ }
+ } else {
+ return 0;
+ }
+}
+#endif /* _MSC_VER */
+
+#include <direct.h>
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#define mkdir(p,m) _mkdir(p)
+#define snprintf _snprintf
+#define vsnprintf(b,c,f,a) _vsnprintf(b,c,f,a)
+#endif
+
+#define HAVE_SYS_STAT_H
+#define HAVE__STAT
+#define HAVE_STRING_H
+
+#include "libxml/xmlversion.h"
+
+#if !defined LIBXSLT_PUBLIC
+#if defined _MSC_VER && !defined IN_LIBXSLT && !defined LIBXSLT_STATIC
+#define LIBXSLT_PUBLIC __declspec(dllimport)
+#else
+#define LIBXSLT_PUBLIC
+#endif
+#endif
+
+#ifndef ATTRIBUTE_UNUSED
+#define ATTRIBUTE_UNUSED
+#endif
+
+#endif /* __LIBXSLT_WIN32_CONFIG__ */
+
diff --git a/plugins/Variables/src/libxslt/xslt.h b/plugins/Variables/src/libxslt/xslt.h
new file mode 100644
index 0000000000..4d3462fd25
--- /dev/null
+++ b/plugins/Variables/src/libxslt/xslt.h
@@ -0,0 +1,97 @@
+/*
+ * xslt.h: Interfaces, constants and types related to the XSLT engine
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifndef __XML_XSLT_H__
+#define __XML_XSLT_H__
+
+#include "libxml/tree.h"
+#include "xsltexports.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * XSLT_DEFAULT_VERSION:
+ *
+ * The default version of XSLT supported.
+ */
+#define XSLT_DEFAULT_VERSION "1.0"
+
+/**
+ * XSLT_DEFAULT_VENDOR:
+ *
+ * The XSLT "vendor" string for this processor.
+ */
+#define XSLT_DEFAULT_VENDOR "libxslt"
+
+/**
+ * XSLT_DEFAULT_URL:
+ *
+ * The XSLT "vendor" URL for this processor.
+ */
+#define XSLT_DEFAULT_URL "http://xmlsoft.org/XSLT/"
+
+/**
+ * XSLT_NAMESPACE:
+ *
+ * The XSLT specification namespace.
+ */
+#define XSLT_NAMESPACE ((xmlChar *) "http://www.w3.org/1999/XSL/Transform")
+
+#if LIBXML_VERSION >= 20600
+/**
+ * XSLT_PARSE_OPTIONS:
+ *
+ * The set of options to pass to an xmlReadxxx when loading files for
+ * XSLT consumption.
+ */
+#define XSLT_PARSE_OPTIONS \
+ XML_PARSE_NOENT | XML_PARSE_DTDLOAD | XML_PARSE_DTDATTR | XML_PARSE_NOCDATA
+#endif
+
+/**
+ * xsltMaxDepth:
+ *
+ * This value is used to detect templates loops.
+ */
+XSLTPUBVAR int xsltMaxDepth;
+
+/**
+ * xsltEngineVersion:
+ *
+ * The version string for libxslt.
+ */
+XSLTPUBVAR const char *xsltEngineVersion;
+
+/**
+ * xsltLibxsltVersion:
+ *
+ * The version of libxslt compiled.
+ */
+XSLTPUBVAR const int xsltLibxsltVersion;
+
+/**
+ * xsltLibxmlVersion:
+ *
+ * The version of libxml libxslt was compiled against.
+ */
+XSLTPUBVAR const int xsltLibxmlVersion;
+
+/*
+ * Global cleanup function.
+ */
+XSLTPUBFUN void XSLTCALL
+ xsltCleanupGlobals (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_XSLT_H__ */
+
diff --git a/plugins/Variables/src/libxslt/xsltInternals.h b/plugins/Variables/src/libxslt/xsltInternals.h
new file mode 100644
index 0000000000..78b80661da
--- /dev/null
+++ b/plugins/Variables/src/libxslt/xsltInternals.h
@@ -0,0 +1,609 @@
+/*
+ * xsltInternals.h: internal data structures, constants and functions used
+ * by the XSLT engine.
+ * They are not part of the API or ABI, i.e. they can change
+ * without prior notice, use carefully.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifndef __XML_XSLT_INTERNALS_H__
+#define __XML_XSLT_INTERNALS_H__
+
+#include "libxml/tree.h"
+#include "libxml/hash.h"
+#include "libxml/xpath.h"
+#include "libxml/xmlerror.h"
+#include "libxslt/xslt.h"
+#include "xsltexports.h"
+#include "numbersInternals.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * XSLT_MAX_SORT:
+ *
+ * Max number of specified xsl:sort on an element.
+ */
+#define XSLT_MAX_SORT 15
+
+/**
+ * XSLT_PAT_NO_PRIORITY:
+ *
+ * Specific value for pattern without priority expressed.
+ */
+#define XSLT_PAT_NO_PRIORITY -12345789
+
+/**
+ * xsltRuntimeExtra:
+ *
+ * Extra information added to the transformation context.
+ */
+typedef struct _xsltRuntimeExtra xsltRuntimeExtra;
+typedef xsltRuntimeExtra *xsltRuntimeExtraPtr;
+struct _xsltRuntimeExtra {
+ void *info; /* pointer to the extra data */
+ xmlFreeFunc deallocate; /* pointer to the deallocation routine */
+ void *val; /* data not needing deallocation */
+};
+
+/**
+ * XSLT_RUNTIME_EXTRA_LST:
+ * @ctxt: the transformation context
+ * @nr: the index
+ *
+ * Macro used to access extra information stored in the context
+ */
+#define XSLT_RUNTIME_EXTRA_LST(ctxt, nr) (ctxt)->extras[(nr)].info
+/**
+ * XSLT_RUNTIME_EXTRA_FREE:
+ * @ctxt: the transformation context
+ * @nr: the index
+ *
+ * Macro used to free extra information stored in the context
+ */
+#define XSLT_RUNTIME_EXTRA_FREE(ctxt, nr) (ctxt)->extras[(nr)].deallocate
+/**
+ * XSLT_RUNTIME_EXTRA:
+ * @ctxt: the transformation context
+ * @nr: the index
+ *
+ * Macro used to define extra information stored in the context
+ */
+#define XSLT_RUNTIME_EXTRA(ctxt, nr) (ctxt)->extras[(nr)].val
+
+/**
+ * xsltTemplate:
+ *
+ * The in-memory structure corresponding to an XSLT Template.
+ */
+typedef struct _xsltTemplate xsltTemplate;
+typedef xsltTemplate *xsltTemplatePtr;
+struct _xsltTemplate {
+ struct _xsltTemplate *next;/* chained list sorted by priority */
+ struct _xsltStylesheet *style;/* the containing stylesheet */
+ xmlChar *match; /* the matching string */
+ float priority; /* as given from the stylesheet, not computed */
+ xmlChar *name; /* the local part of the name QName */
+ xmlChar *nameURI; /* the URI part of the name QName */
+ xmlChar *mode; /* the local part of the mode QName */
+ xmlChar *modeURI; /* the URI part of the mode QName */
+ xmlNodePtr content; /* the template replacement value */
+ xmlNodePtr elem; /* the source element */
+
+ int inheritedNsNr; /* number of inherited namespaces */
+ xmlNsPtr *inheritedNs;/* inherited non-excluded namespaces */
+
+ /* Profiling informations */
+ int nbCalls; /* the number of time the template was called */
+ unsigned long time; /* the time spent in this template */
+};
+
+/**
+ * xsltDecimalFormat:
+ *
+ * Data structure of decimal-format.
+ */
+typedef struct _xsltDecimalFormat xsltDecimalFormat;
+typedef xsltDecimalFormat *xsltDecimalFormatPtr;
+struct _xsltDecimalFormat {
+ struct _xsltDecimalFormat *next; /* chained list */
+ xmlChar *name;
+ /* Used for interpretation of pattern */
+ xmlChar *digit;
+ xmlChar *patternSeparator;
+ /* May appear in result */
+ xmlChar *minusSign;
+ xmlChar *infinity;
+ xmlChar *noNumber; /* Not-a-number */
+ /* Used for interpretation of pattern and may appear in result */
+ xmlChar *decimalPoint;
+ xmlChar *grouping;
+ xmlChar *percent;
+ xmlChar *permille;
+ xmlChar *zeroDigit;
+};
+
+/**
+ * xsltDocument:
+ *
+ * Data structure associated to a parsed document.
+ */
+
+typedef struct _xsltDocument xsltDocument;
+typedef xsltDocument *xsltDocumentPtr;
+struct _xsltDocument {
+ struct _xsltDocument *next; /* documents are kept in a chained list */
+ int main; /* is this the main document */
+ xmlDocPtr doc; /* the parsed document */
+ void *keys; /* key tables storage */
+};
+
+typedef struct _xsltTransformContext xsltTransformContext;
+typedef xsltTransformContext *xsltTransformContextPtr;
+
+/**
+ * xsltElemPreComp:
+ *
+ * The in-memory structure corresponding to element precomputed data,
+ * designed to be extended by extension implementors.
+ */
+typedef struct _xsltElemPreComp xsltElemPreComp;
+typedef xsltElemPreComp *xsltElemPreCompPtr;
+
+/**
+ * xsltTransformFunction:
+ * @ctxt: the XSLT transformation context
+ * @node: the input node
+ * @inst: the stylesheet node
+ * @comp: the compiled information from the stylesheet
+ *
+ * Signature of the function associated to elements part of the
+ * stylesheet language like xsl:if or xsl:apply-templates.
+ */
+typedef void (*xsltTransformFunction) (xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr inst,
+ xsltElemPreCompPtr comp);
+
+/**
+ * xsltSortFunc:
+ * @ctxt: a transformation context
+ * @sorts: the node-set to sort
+ * @nbsorts: the number of sorts
+ *
+ * Signature of the function to use during sorting
+ */
+typedef void (*xsltSortFunc) (xsltTransformContextPtr ctxt, xmlNodePtr *sorts,
+ int nbsorts);
+
+typedef enum {
+ XSLT_FUNC_COPY=1,
+ XSLT_FUNC_SORT,
+ XSLT_FUNC_TEXT,
+ XSLT_FUNC_ELEMENT,
+ XSLT_FUNC_ATTRIBUTE,
+ XSLT_FUNC_COMMENT,
+ XSLT_FUNC_PI,
+ XSLT_FUNC_COPYOF,
+ XSLT_FUNC_VALUEOF,
+ XSLT_FUNC_NUMBER,
+ XSLT_FUNC_APPLYIMPORTS,
+ XSLT_FUNC_CALLTEMPLATE,
+ XSLT_FUNC_APPLYTEMPLATES,
+ XSLT_FUNC_CHOOSE,
+ XSLT_FUNC_IF,
+ XSLT_FUNC_FOREACH,
+ XSLT_FUNC_DOCUMENT,
+ XSLT_FUNC_WITHPARAM,
+ XSLT_FUNC_PARAM,
+ XSLT_FUNC_VARIABLE,
+ XSLT_FUNC_WHEN,
+ XSLT_FUNC_EXTENSION
+} xsltStyleType;
+
+/**
+ * xsltElemPreCompDeallocator:
+ * @comp: the #xsltElemPreComp to free up
+ *
+ * Deallocates an #xsltElemPreComp structure.
+ */
+typedef void (*xsltElemPreCompDeallocator) (xsltElemPreCompPtr comp);
+
+/**
+ * xsltElemPreComp:
+ *
+ * The in-memory structure corresponding to element precomputed data,
+ * designed to be extended by extension implementors.
+ */
+struct _xsltElemPreComp {
+ xsltElemPreCompPtr next; /* chained list */
+ xsltStyleType type; /* type of the element */
+ xsltTransformFunction func; /* handling function */
+ xmlNodePtr inst; /* the instruction */
+
+ /* end of common part */
+ xsltElemPreCompDeallocator free; /* the deallocator */
+};
+
+/**
+ * xsltStylePreComp:
+ *
+ * The in-memory structure corresponding to XSLT stylesheet constructs
+ * precomputed data.
+ */
+typedef struct _xsltStylePreComp xsltStylePreComp;
+
+typedef xsltStylePreComp *xsltStylePreCompPtr;
+
+struct _xsltStylePreComp {
+ xsltElemPreCompPtr next; /* chained list */
+ xsltStyleType type; /* type of the element */
+ xsltTransformFunction func; /* handling function */
+ xmlNodePtr inst; /* the instruction */
+
+ /*
+ * Pre computed values.
+ */
+
+ xmlChar *stype; /* sort */
+ int has_stype; /* sort */
+ int number; /* sort */
+ xmlChar *order; /* sort */
+ int has_order; /* sort */
+ int descending; /* sort */
+ xmlChar *lang; /* sort */
+ int has_lang; /* sort */
+ xmlChar *case_order; /* sort */
+ int lower_first; /* sort */
+
+ xmlChar *use; /* copy, element */
+ int has_use; /* copy, element */
+
+ int noescape; /* text */
+
+ xmlChar *name; /* element, attribute, pi */
+ int has_name; /* element, attribute, pi */
+ xmlChar *ns; /* element */
+ int has_ns; /* element */
+
+ xmlChar *mode; /* apply-templates */
+ xmlChar *modeURI; /* apply-templates */
+
+ xmlChar *test; /* if */
+
+ xsltTemplatePtr templ; /* call-template */
+
+ xmlChar *select; /* sort, copy-of, value-of, apply-templates */
+
+ int ver11; /* document */
+ xmlChar *filename; /* document URL */
+ int has_filename; /* document */
+
+ xsltNumberData numdata; /* number */
+
+ xmlXPathCompExprPtr comp; /* a precompiled XPath expression */
+ xmlNsPtr *nsList; /* the namespaces in scope */
+ int nsNr; /* the number of namespaces in scope */
+};
+
+/*
+ * The in-memory structure corresponding to an XSLT Variable
+ * or Param.
+ */
+
+typedef struct _xsltStackElem xsltStackElem;
+typedef xsltStackElem *xsltStackElemPtr;
+struct _xsltStackElem {
+ struct _xsltStackElem *next;/* chained list */
+ xsltStylePreCompPtr comp; /* the compiled form */
+ int computed; /* was the evaluation done */
+ xmlChar *name; /* the local part of the name QName */
+ xmlChar *nameURI; /* the URI part of the name QName */
+ xmlChar *select; /* the eval string */
+ xmlNodePtr tree; /* the tree if no eval string or the location */
+ xmlXPathObjectPtr value; /* The value if computed */
+};
+
+/*
+ * The in-memory structure corresponding to an XSLT Stylesheet.
+ * NOTE: most of the content is simply linked from the doc tree
+ * structure, no specific allocation is made.
+ */
+typedef struct _xsltStylesheet xsltStylesheet;
+typedef xsltStylesheet *xsltStylesheetPtr;
+struct _xsltStylesheet {
+ /*
+ * The stylesheet import relation is kept as a tree.
+ */
+ struct _xsltStylesheet *parent;
+ struct _xsltStylesheet *next;
+ struct _xsltStylesheet *imports;
+
+ xsltDocumentPtr docList; /* the include document list */
+
+ /*
+ * General data on the style sheet document.
+ */
+ xmlDocPtr doc; /* the parsed XML stylesheet */
+ xmlHashTablePtr stripSpaces;/* the hash table of the strip-space and
+ preserve space elements */
+ int stripAll; /* strip-space * (1) preserve-space * (-1) */
+ xmlHashTablePtr cdataSection;/* the hash table of the cdata-section */
+
+ /*
+ * Global variable or parameters.
+ */
+ xsltStackElemPtr variables; /* linked list of param and variables */
+
+ /*
+ * Template descriptions.
+ */
+ xsltTemplatePtr templates; /* the ordered list of templates */
+ void *templatesHash; /* hash table or wherever compiled templates
+ informations are stored */
+ void *rootMatch; /* template based on / */
+ void *keyMatch; /* template based on key() */
+ void *elemMatch; /* template based on * */
+ void *attrMatch; /* template based on @* */
+ void *parentMatch; /* template based on .. */
+ void *textMatch; /* template based on text() */
+ void *piMatch; /* template based on processing-instruction() */
+ void *commentMatch; /* template based on comment() */
+
+ /*
+ * Namespace aliases.
+ */
+ xmlHashTablePtr nsAliases; /* the namespace alias hash tables */
+
+ /*
+ * Attribute sets.
+ */
+ xmlHashTablePtr attributeSets;/* the attribute sets hash tables */
+
+ /*
+ * Namespaces.
+ */
+ xmlHashTablePtr nsHash; /* the set of namespaces in use */
+ void *nsDefs; /* the namespaces defined */
+
+ /*
+ * Key definitions.
+ */
+ void *keys; /* key definitions */
+
+ /*
+ * Output related stuff.
+ */
+ xmlChar *method; /* the output method */
+ xmlChar *methodURI; /* associated namespace if any */
+ xmlChar *version; /* version string */
+ xmlChar *encoding; /* encoding string */
+ int omitXmlDeclaration; /* omit-xml-declaration = "yes" | "no" */
+
+ /*
+ * Number formatting.
+ */
+ xsltDecimalFormatPtr decimalFormat;
+ int standalone; /* standalone = "yes" | "no" */
+ xmlChar *doctypePublic; /* doctype-public string */
+ xmlChar *doctypeSystem; /* doctype-system string */
+ int indent; /* should output being indented */
+ xmlChar *mediaType; /* media-type string */
+
+ /*
+ * Precomputed blocks.
+ */
+ xsltElemPreCompPtr preComps;/* list of precomputed blocks */
+ int warnings; /* number of warnings found at compilation */
+ int errors; /* number of errors found at compilation */
+
+ xmlChar *exclPrefix; /* last excluded prefixes */
+ xmlChar **exclPrefixTab; /* array of excluded prefixes */
+ int exclPrefixNr; /* number of excluded prefixes in scope */
+ int exclPrefixMax; /* size of the array */
+
+ void *_private; /* user defined data */
+
+ /*
+ * Extensions.
+ */
+ xmlHashTablePtr extInfos; /* the extension data */
+ int extrasNr; /* the number of extras required */
+};
+
+/*
+ * The in-memory structure corresponding to an XSLT Transformation.
+ */
+typedef enum {
+ XSLT_OUTPUT_XML = 0,
+ XSLT_OUTPUT_HTML,
+ XSLT_OUTPUT_TEXT
+} xsltOutputType;
+
+typedef enum {
+ XSLT_STATE_OK = 0,
+ XSLT_STATE_ERROR,
+ XSLT_STATE_STOPPED
+} xsltTransformState;
+
+struct _xsltTransformContext {
+ xsltStylesheetPtr style; /* the stylesheet used */
+ xsltOutputType type; /* the type of output */
+
+ xsltTemplatePtr templ; /* the current template */
+ int templNr; /* Nb of templates in the stack */
+ int templMax; /* Size of the templtes stack */
+ xsltTemplatePtr *templTab; /* the template stack */
+
+ xsltStackElemPtr vars; /* the current variable list */
+ int varsNr; /* Nb of variable list in the stack */
+ int varsMax; /* Size of the variable list stack */
+ xsltStackElemPtr *varsTab; /* the variable list stack */
+ int varsBase; /* the var base for current templ */
+
+ /*
+ * Extensions
+ */
+ xmlHashTablePtr extFunctions; /* the extension functions */
+ xmlHashTablePtr extElements; /* the extension elements */
+ xmlHashTablePtr extInfos; /* the extension data */
+
+ const xmlChar *mode; /* the current mode */
+ const xmlChar *modeURI; /* the current mode URI */
+
+ xsltDocumentPtr docList; /* the document list */
+
+ xsltDocumentPtr document; /* the current document */
+ xmlNodePtr node; /* the current node being processed */
+ xmlNodeSetPtr nodeList; /* the current node list */
+ /* xmlNodePtr current; the node */
+
+ xmlDocPtr output; /* the resulting document */
+ xmlNodePtr insert; /* the insertion node */
+
+ xmlXPathContextPtr xpathCtxt; /* the XPath context */
+ xsltTransformState state; /* the current state */
+
+ /*
+ * Global variables
+ */
+ xmlHashTablePtr globalVars; /* the global variables and params */
+
+ xmlNodePtr inst; /* the instruction in the stylesheet */
+
+ int xinclude; /* should XInclude be processed */
+
+ const char * outputFile; /* the output URI if known */
+
+ int profile; /* is this run profiled */
+ long prof; /* the current profiled value */
+ int profNr; /* Nb of templates in the stack */
+ int profMax; /* Size of the templtaes stack */
+ long *profTab; /* the profile template stack */
+
+ void *_private; /* user defined data */
+
+ int extrasNr; /* the number of extras used */
+ int extrasMax; /* the number of extras allocated */
+ xsltRuntimeExtraPtr extras; /* extra per runtime informations */
+
+ xsltDocumentPtr styleList; /* the stylesheet docs list */
+ void * sec; /* the security preferences if any */
+
+ xmlGenericErrorFunc error; /* a specific error handler */
+ void * errctx; /* context for the error handler */
+
+ xsltSortFunc sortfunc; /* a ctxt specific sort routine */
+
+ /*
+ * handling of temporary Result Value Tree
+ */
+ xmlDocPtr tmpRVT; /* list of RVT without persistance */
+ xmlDocPtr persistRVT; /* list of persistant RVTs */
+ int ctxtflags; /* context processing flags */
+
+ /*
+ * Speed optimization when coalescing text nodes
+ */
+ const xmlChar *lasttext; /* last text node content */
+ unsigned int lasttsize; /* last text node size */
+ unsigned int lasttuse; /* last text node use */
+};
+
+/**
+ * CHECK_STOPPED:
+ *
+ * Macro to check if the XSLT processing should be stopped.
+ * Will return from the function.
+ */
+#define CHECK_STOPPED if (ctxt->state == XSLT_STATE_STOPPED) return;
+
+/**
+ * CHECK_STOPPEDE:
+ *
+ * Macro to check if the XSLT processing should be stopped.
+ * Will goto the error: label.
+ */
+#define CHECK_STOPPEDE if (ctxt->state == XSLT_STATE_STOPPED) goto error;
+
+/**
+ * CHECK_STOPPED0:
+ *
+ * Macro to check if the XSLT processing should be stopped.
+ * Will return from the function with a 0 value.
+ */
+#define CHECK_STOPPED0 if (ctxt->state == XSLT_STATE_STOPPED) return(0);
+
+/*
+ * Functions associated to the internal types
+xsltDecimalFormatPtr xsltDecimalFormatGetByName(xsltStylesheetPtr sheet,
+ xmlChar *name);
+ */
+XSLTPUBFUN xsltStylesheetPtr XSLTCALL
+ xsltNewStylesheet (void);
+XSLTPUBFUN xsltStylesheetPtr XSLTCALL
+ xsltParseStylesheetFile (const xmlChar* filename);
+XSLTPUBFUN void XSLTCALL
+ xsltFreeStylesheet (xsltStylesheetPtr sheet);
+XSLTPUBFUN int XSLTCALL
+ xsltIsBlank (xmlChar *str);
+XSLTPUBFUN void XSLTCALL
+ xsltFreeStackElemList (xsltStackElemPtr elem);
+XSLTPUBFUN xsltDecimalFormatPtr XSLTCALL
+ xsltDecimalFormatGetByName(xsltStylesheetPtr sheet,
+ xmlChar *name);
+
+XSLTPUBFUN xsltStylesheetPtr XSLTCALL
+ xsltParseStylesheetProcess(xsltStylesheetPtr ret,
+ xmlDocPtr doc);
+XSLTPUBFUN void XSLTCALL
+ xsltParseStylesheetOutput(xsltStylesheetPtr style,
+ xmlNodePtr cur);
+XSLTPUBFUN xsltStylesheetPtr XSLTCALL
+ xsltParseStylesheetDoc (xmlDocPtr doc);
+XSLTPUBFUN xsltStylesheetPtr XSLTCALL
+ xsltParseStylesheetImportedDoc(xmlDocPtr doc);
+XSLTPUBFUN xsltStylesheetPtr XSLTCALL
+ xsltLoadStylesheetPI (xmlDocPtr doc);
+XSLTPUBFUN void XSLTCALL
+ xsltNumberFormat (xsltTransformContextPtr ctxt,
+ xsltNumberDataPtr data,
+ xmlNodePtr node);
+XSLTPUBFUN xmlXPathError XSLTCALL
+ xsltFormatNumberConversion(xsltDecimalFormatPtr self,
+ xmlChar *format,
+ double number,
+ xmlChar **result);
+
+XSLTPUBFUN void XSLTCALL
+ xsltParseTemplateContent(xsltStylesheetPtr style,
+ xmlNodePtr templ);
+XSLTPUBFUN int XSLTCALL
+ xsltAllocateExtra (xsltStylesheetPtr style);
+XSLTPUBFUN int XSLTCALL
+ xsltAllocateExtraCtxt (xsltTransformContextPtr ctxt);
+/*
+ * Extra functions for Result Value Trees
+ */
+XSLTPUBFUN xmlDocPtr XSLTCALL
+ xsltCreateRVT (xsltTransformContextPtr ctxt);
+XSLTPUBFUN int XSLTCALL
+ xsltRegisterTmpRVT (xsltTransformContextPtr ctxt,
+ xmlDocPtr RVT);
+XSLTPUBFUN int XSLTCALL
+ xsltRegisterPersistRVT (xsltTransformContextPtr ctxt,
+ xmlDocPtr RVT);
+XSLTPUBFUN void XSLTCALL
+ xsltFreeRVTs (xsltTransformContextPtr ctxt);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_XSLT_H__ */
+
diff --git a/plugins/Variables/src/libxslt/xsltexports.h b/plugins/Variables/src/libxslt/xsltexports.h
new file mode 100644
index 0000000000..aab58025b8
--- /dev/null
+++ b/plugins/Variables/src/libxslt/xsltexports.h
@@ -0,0 +1,106 @@
+/*
+ * xsltexports.h : macros for marking symbols as exportable/importable.
+ *
+ * See Copyright for the status of this software.
+ *
+ * igor@zlatkovic.com
+ */
+
+#ifndef __XSLT_EXPORTS_H__
+#define __XSLT_EXPORTS_H__
+
+/**
+ * XSLTPUBFUN:
+ * XSLTPUBFUN, XSLTPUBVAR, XSLTCALL
+ *
+ * Macros which declare an exportable function, an exportable variable and
+ * the calling convention used for functions.
+ *
+ * Please use an extra block for every platform/compiler combination when
+ * modifying this, rather than overlong #ifdef lines. This helps
+ * readability as well as the fact that different compilers on the same
+ * platform might need different definitions.
+ */
+
+#define XSLTPUBFUN
+#define XSLTPUBVAR extern
+#define XSLTCALL
+
+/* Windows platform with MS compiler */
+#if defined(_WIN32) && defined(_MSC_VER)
+ #undef XSLTPUBFUN
+ #undef XSLTPUBVAR
+ #undef XSLTCALL
+ #if defined(IN_LIBXSLT) && !defined(LIBXSLT_STATIC)
+ #define XSLTPUBFUN __declspec(dllexport)
+ #define XSLTPUBVAR __declspec(dllexport)
+ #else
+ #define XSLTPUBFUN
+ #if !defined(LIBXSLT_STATIC)
+ #define XSLTPUBVAR __declspec(dllimport) extern
+ #else
+ #define XSLTPUBVAR extern
+ #endif
+ #endif
+ #define XSLTCALL __cdecl
+ #if !defined _REENTRANT
+ #define _REENTRANT
+ #endif
+#endif
+
+/* Windows platform with Borland compiler */
+#if defined(_WIN32) && defined(__BORLANDC__)
+ #undef XSLTPUBFUN
+ #undef XSLTPUBVAR
+ #undef XSLTCALL
+ #if defined(IN_LIBXSLT) && !defined(LIBXSLT_STATIC)
+ #define XSLTPUBFUN __declspec(dllexport)
+ #define XSLTPUBVAR __declspec(dllexport) extern
+ #else
+ #define XSLTPUBFUN
+ #if !defined(LIBXSLT_STATIC)
+ #define XSLTPUBVAR __declspec(dllimport) extern
+ #else
+ #define XSLTPUBVAR extern
+ #endif
+ #endif
+ #define XSLTCALL __cdecl
+ #if !defined _REENTRANT
+ #define _REENTRANT
+ #endif
+#endif
+
+/* Windows platform with GNU compiler (Mingw) */
+#if defined(_WIN32) && defined(__MINGW__)
+ #if !defined _REENTRANT
+ #define _REENTRANT
+ #endif
+#endif
+
+/* Cygwin platform, GNU compiler */
+#if defined(_WIN32) && defined(__CYGWIN__)
+ #undef XSLTPUBFUN
+ #undef XSLTPUBVAR
+ #undef XSLTCALL
+ #if defined(IN_LIBXSLT) && !defined(LIBXSLT_STATIC)
+ #define XSLTPUBFUN __declspec(dllexport)
+ #define XSLTPUBVAR __declspec(dllexport)
+ #else
+ #define XSLTPUBFUN
+ #if !defined(LIBXSLT_STATIC)
+ #define XSLTPUBVAR __declspec(dllimport) extern
+ #else
+ #define XSLTPUBVAR
+ #endif
+ #endif
+ #define XSLTCALL __cdecl
+#endif
+
+/* Compatibility */
+#if !defined(LIBXSLT_PUBLIC)
+#define LIBXSLT_PUBLIC XSLTPUBVAR
+#endif
+
+#endif /* __XSLT_EXPORTS_H__ */
+
+
diff --git a/plugins/Variables/src/libxslt/xsltutils.h b/plugins/Variables/src/libxslt/xsltutils.h
new file mode 100644
index 0000000000..699fd4ab1c
--- /dev/null
+++ b/plugins/Variables/src/libxslt/xsltutils.h
@@ -0,0 +1,240 @@
+/*
+ * xsltutils.h: interfaces for the utilities module of the XSLT engine.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifndef __XML_XSLTUTILS_H__
+#define __XML_XSLTUTILS_H__
+
+#if defined(WIN32) && defined(_MSC_VER)
+#include "libxslt/xsltwin32config.h"
+#else
+#include "libxslt/xsltconfig.h"
+#endif
+
+#include "libxml/xpath.h"
+#include "libxml/xmlerror.h"
+#include "xsltexports.h"
+#include "xsltInternals.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * XSLT_TODO:
+ *
+ * Macro to flag unimplemented blocks.
+ */
+#define XSLT_TODO \
+ xsltGenericError(xsltGenericErrorContext, \
+ "Unimplemented block at %s:%d\n", \
+ __FILE__, __LINE__);
+
+/**
+ * XSLT_STRANGE:
+ *
+ * Macro to flag that a problem was detected internally.
+ */
+#define XSLT_STRANGE \
+ xsltGenericError(xsltGenericErrorContext, \
+ "Internal error at %s:%d\n", \
+ __FILE__, __LINE__);
+
+/**
+ * IS_XSLT_ELEM:
+ *
+ * Checks that the element pertains to XSLT namespace.
+ */
+#define IS_XSLT_ELEM(n) \
+ (((n) != NULL) && ((n)->ns != NULL) && \
+ (xmlStrEqual((n)->ns->href, XSLT_NAMESPACE)))
+
+/**
+ * IS_XSLT_NAME:
+ *
+ * Checks the value of an element in XSLT namespace.
+ */
+#define IS_XSLT_NAME(n, val) \
+ (xmlStrEqual((n)->name, (const xmlChar *) (val)))
+
+/**
+ * IS_XSLT_REAL_NODE:
+ *
+ * Check that a node is a 'real' one: document, element, text or attribute.
+ */
+#define IS_XSLT_REAL_NODE(n) \
+ (((n) != NULL) && \
+ (((n)->type == XML_ELEMENT_NODE) || \
+ ((n)->type == XML_TEXT_NODE) || \
+ ((n)->type == XML_ATTRIBUTE_NODE) || \
+ ((n)->type == XML_DOCUMENT_NODE) || \
+ ((n)->type == XML_HTML_DOCUMENT_NODE) || \
+ ((n)->type == XML_PI_NODE)))
+
+/*
+ * Our own version of namespaced atributes lookup.
+ */
+XSLTPUBFUN xmlChar * XSLTCALL xsltGetNsProp (xmlNodePtr node,
+ const xmlChar *name,
+ const xmlChar *nameSpace);
+XSLTPUBFUN int XSLTCALL xsltGetUTF8Char (const unsigned char *utf,
+ int *len);
+
+/*
+ * XSLT specific error and debug reporting functions.
+ */
+XSLTPUBVAR xmlGenericErrorFunc xsltGenericError;
+XSLTPUBVAR void *xsltGenericErrorContext;
+XSLTPUBVAR xmlGenericErrorFunc xsltGenericDebug;
+XSLTPUBVAR void *xsltGenericDebugContext;
+
+XSLTPUBFUN void XSLTCALL
+ xsltPrintErrorContext (xsltTransformContextPtr ctxt,
+ xsltStylesheetPtr style,
+ xmlNodePtr node);
+XSLTPUBFUN void XSLTCALL
+ xsltMessage (xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr inst);
+XSLTPUBFUN void XSLTCALL
+ xsltSetGenericErrorFunc (void *ctx,
+ xmlGenericErrorFunc handler);
+XSLTPUBFUN void XSLTCALL
+ xsltSetGenericDebugFunc (void *ctx,
+ xmlGenericErrorFunc handler);
+XSLTPUBFUN void XSLTCALL
+ xsltSetTransformErrorFunc (xsltTransformContextPtr ctxt,
+ void *ctx,
+ xmlGenericErrorFunc handler);
+XSLTPUBFUN void XSLTCALL
+ xsltTransformError (xsltTransformContextPtr ctxt,
+ xsltStylesheetPtr style,
+ xmlNodePtr node,
+ const char *msg,
+ ...);
+
+/*
+ * Sorting.
+ */
+
+XSLTPUBFUN void XSLTCALL
+ xsltDocumentSortFunction (xmlNodeSetPtr list);
+XSLTPUBFUN void XSLTCALL
+ xsltSetSortFunc (xsltSortFunc handler);
+XSLTPUBFUN void XSLTCALL
+ xsltSetCtxtSortFunc (xsltTransformContextPtr ctxt,
+ xsltSortFunc handler);
+XSLTPUBFUN void XSLTCALL
+ xsltDefaultSortFunction (xsltTransformContextPtr ctxt,
+ xmlNodePtr *sorts,
+ int nbsorts);
+XSLTPUBFUN void XSLTCALL
+ xsltDoSortFunction (xsltTransformContextPtr ctxt,
+ xmlNodePtr * sorts,
+ int nbsorts);
+XSLTPUBFUN xmlXPathObjectPtr * XSLTCALL
+ xsltComputeSortResult (xsltTransformContextPtr ctxt,
+ xmlNodePtr sort);
+
+/*
+ * QNames handling.
+ */
+
+XSLTPUBFUN const xmlChar * XSLTCALL
+ xsltGetQNameURI (xmlNodePtr node,
+ xmlChar **name);
+
+/*
+ * Output, reuse libxml I/O buffers.
+ */
+XSLTPUBFUN int XSLTCALL
+ xsltSaveResultTo (xmlOutputBufferPtr buf,
+ xmlDocPtr result,
+ xsltStylesheetPtr style);
+XSLTPUBFUN int XSLTCALL
+ xsltSaveResultToFilename (const char *URI,
+ xmlDocPtr result,
+ xsltStylesheetPtr style,
+ int compression);
+XSLTPUBFUN int XSLTCALL
+ xsltSaveResultToFile (FILE *file,
+ xmlDocPtr result,
+ xsltStylesheetPtr style);
+XSLTPUBFUN int XSLTCALL
+ xsltSaveResultToFd (int fd,
+ xmlDocPtr result,
+ xsltStylesheetPtr style);
+XSLTPUBFUN int XSLTCALL
+ xsltSaveResultToString (xmlChar **doc_txt_ptr,
+ int * doc_txt_len,
+ xmlDocPtr result,
+ xsltStylesheetPtr style);
+
+/*
+ * Profiling.
+ */
+XSLTPUBFUN void XSLTCALL
+ xsltSaveProfiling (xsltTransformContextPtr ctxt,
+ FILE *output);
+XSLTPUBFUN xmlDocPtr XSLTCALL
+ xsltGetProfileInformation (xsltTransformContextPtr ctxt);
+
+XSLTPUBFUN long XSLTCALL
+ xsltTimestamp (void);
+XSLTPUBFUN void XSLTCALL
+ xsltCalibrateAdjust (long delta);
+
+/**
+ * XSLT_TIMESTAMP_TICS_PER_SEC:
+ *
+ * Sampling precision for profiling
+ */
+#define XSLT_TIMESTAMP_TICS_PER_SEC 100000l
+
+/*
+ * Hooks for the debugger.
+ */
+
+typedef enum {
+ XSLT_DEBUG_NONE = 0, /* no debugging allowed */
+ XSLT_DEBUG_INIT,
+ XSLT_DEBUG_STEP,
+ XSLT_DEBUG_STEPOUT,
+ XSLT_DEBUG_NEXT,
+ XSLT_DEBUG_STOP,
+ XSLT_DEBUG_CONT,
+ XSLT_DEBUG_RUN,
+ XSLT_DEBUG_RUN_RESTART,
+ XSLT_DEBUG_QUIT
+} xsltDebugStatusCodes;
+
+XSLTPUBVAR int xslDebugStatus;
+
+typedef void (*xsltHandleDebuggerCallback) (xmlNodePtr cur, xmlNodePtr node,
+ xsltTemplatePtr templ, xsltTransformContextPtr ctxt);
+typedef int (*xsltAddCallCallback) (xsltTemplatePtr templ, xmlNodePtr source);
+typedef void (*xsltDropCallCallback) (void);
+
+XSLTPUBFUN void XSLTCALL
+ xsltSetDebuggerStatus (int value);
+XSLTPUBFUN int XSLTCALL
+ xsltGetDebuggerStatus (void);
+XSLTPUBFUN int XSLTCALL
+ xsltSetDebuggerCallbacks (int no, void *block);
+XSLTPUBFUN int XSLTCALL
+ xslAddCall (xsltTemplatePtr templ,
+ xmlNodePtr source);
+XSLTPUBFUN void XSLTCALL
+ xslDropCall (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_XSLTUTILS_H__ */
+
+
diff --git a/plugins/Variables/src/libxslt/xsltwin32config.h b/plugins/Variables/src/libxslt/xsltwin32config.h
new file mode 100644
index 0000000000..985bfc71dc
--- /dev/null
+++ b/plugins/Variables/src/libxslt/xsltwin32config.h
@@ -0,0 +1,84 @@
+/*
+ * xsltwin32config.h: compile-time version informations for the XSLT engine
+ * when compiled on windows
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#ifndef __XML_XSLTWIN32CONFIG_H__
+#define __XML_XSLTWIN32CONFIG_H__
+
+#include "win32config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * LIBXSLT_DOTTED_VERSION:
+ *
+ * the version string like "1.2.3"
+ */
+#define LIBXSLT_DOTTED_VERSION "1.1.0"
+
+/**
+ * LIBXSLT_VERSION:
+ *
+ * the version number: 1.2.3 value is 1002003
+ */
+#define LIBXSLT_VERSION 10100
+
+/**
+ * LIBXSLT_VERSION_STRING:
+ *
+ * the version number string, 1.2.3 value is "1002003"
+ */
+#define LIBXSLT_VERSION_STRING "10100"
+
+/**
+ * WITH_XSLT_DEBUG:
+ *
+ * Activate the compilation of the debug reporting. Speed penalty
+ * is insignifiant and being able to run xsltpoc -v is useful. On
+ * by default
+ */
+#if 1
+#define WITH_XSLT_DEBUG
+#endif
+
+#if 0
+/**
+ * DEBUG_MEMORY:
+ *
+ * should be activated only when debugging libxslt. It replaces the
+ * allocator with a collect and debug shell to the libc allocator.
+ * Use configure --with-mem-debug to activate it on both library
+ */
+#define DEBUG_MEMORY
+
+/**
+ * DEBUG_MEMORY_LOCATION:
+ *
+ * should be activated only when debugging libxslt.
+ * DEBUG_MEMORY_LOCATION should be activated only when libxml has
+ * been configured with --with-debug-mem too
+ */
+#define DEBUG_MEMORY_LOCATION
+#endif
+
+/**
+ * ATTRIBUTE_UNUSED:
+ *
+ * This macro is used to flag unused function parameters to GCC, useless here
+ */
+#ifndef ATTRIBUTE_UNUSED
+#define ATTRIBUTE_UNUSED
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_XSLTWIN32CONFIG_H__ */
diff --git a/plugins/Variables/src/lookup3.cpp b/plugins/Variables/src/lookup3.cpp
new file mode 100644
index 0000000000..f2c930950c
--- /dev/null
+++ b/plugins/Variables/src/lookup3.cpp
@@ -0,0 +1,640 @@
+/*
+-------------------------------------------------------------------------------
+lookup3.c, by Bob Jenkins, May 2006, Public Domain.
+These are functions for producing 32-bit hashes for hash table lookup.
+hashword(), hashlittle(), hashbig(), mix(), and final() are externally
+useful functions. Routines to test the hash are included if SELF_TEST
+is defined. You can use this mir_free for any purpose. It has no warranty.
+
+You probably want to use hashlittle(). hashlittle() and hashbig()
+hash byte arrays. hashlittle() is is faster than hashbig() on
+little-endian machines. Intel and AMD are little-endian machines.
+
+If you want to find a hash of, say, exactly 7 integers, do
+ a = i1; b = i2; c = i3;
+ mix(a,b,c);
+ a += i4; b += i5; c += i6;
+ mix(a,b,c);
+ a += i7;
+ final(a,b,c);
+then use c as the hash value. If you have a variable length array of
+4-byte integers to hash, use hashword(). If you have a byte array (like
+a character string), use hashlittle(). If you have several byte arrays, or
+a mix of things, see the comments above hashlittle().
+-------------------------------------------------------------------------------
+*/
+//#define SELF_TEST 1
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <time.h>
+
+typedef unsigned long int uint32; /* unsigned 4-byte quantities */
+typedef unsigned short int uint16; /* unsigned 2-byte quantities */
+typedef unsigned char uint8; /* unsigned 1-byte quantities */
+
+/*
+ * My best guess at if you are big-endian or little-endian. This may
+ * need adjustment.
+ */
+#if defined(i386) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL)
+# define HASH_LITTLE_ENDIAN 1
+# define HASH_BIG_ENDIAN 0
+#elif defined(sparc)
+# define HASH_LITTLE_ENDIAN 0
+# define HASH_BIG_ENDIAN 1
+#else
+# define HASH_LITTLE_ENDIAN 0
+# define HASH_BIG_ENDIAN 0
+#endif
+
+#define hashsize(n) ((uint32)1<<(n))
+#define hashmask(n) (hashsize(n)-1)
+#define rot(x,k) (((x)<<(k)) ^ ((x)>>(32-(k))))
+
+/*
+-------------------------------------------------------------------------------
+mix -- mix 3 32-bit values reversibly.
+
+This is reversible, so any information in (a,b,c) before mix() is
+still in (a,b,c) after mix().
+
+If four pairs of (a,b,c) inputs are run through mix(), or through
+mix() in reverse, there are at least 32 bits of the output that
+are sometimes the same for one pair and different for another pair.
+This was tested for:
+* pairs that differed by one bit, by two bits, in any combination
+ of top bits of (a,b,c), or in any combination of bottom bits of
+ (a,b,c).
+* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
+ the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
+ is commonly produced by subtraction) look like a single 1-bit
+ difference.
+* the base values were pseudorandom, all zero but one bit set, or
+ all zero plus a counter that starts at zero.
+
+Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that
+satisfy this are
+ 4 6 8 16 19 4
+ 9 15 3 18 27 15
+ 14 9 3 7 17 3
+Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
+for "differ" defined as + with a one-bit base and a two-bit delta. I
+used http://burtleburtle.net/bob/hash/avalanche.html to choose
+the operations, constants, and arrangements of the variables.
+
+This does not achieve avalanche. There are input bits of (a,b,c)
+that fail to affect some output bits of (a,b,c), especially of a. The
+most thoroughly mixed value is c, but it doesn't really even achieve
+avalanche in c.
+
+This allows some parallelism. Read-after-writes are good at doubling
+the number of bits affected, so the goal of mixing pulls in the opposite
+direction as the goal of parallelism. I did what I could. Rotates
+seem to cost as much as shifts on every machine I could lay my hands
+on, and rotates are much kinder to the top and bottom bits, so I used
+rotates.
+-------------------------------------------------------------------------------
+*/
+#define mix(a,b,c) \
+{ \
+ a -= c; a ^= rot(c, 4); c += b; \
+ b -= a; b ^= rot(a, 6); a += c; \
+ c -= b; c ^= rot(b, 8); b += a; \
+ a -= c; a ^= rot(c,16); c += b; \
+ b -= a; b ^= rot(a,19); a += c; \
+ c -= b; c ^= rot(b, 4); b += a; \
+}
+
+/*
+-------------------------------------------------------------------------------
+final -- final mixing of 3 32-bit values (a,b,c) into c
+
+Pairs of (a,b,c) values differing in only a few bits will usually
+produce values of c that look totally different. This was tested for
+* pairs that differed by one bit, by two bits, in any combination
+ of top bits of (a,b,c), or in any combination of bottom bits of
+ (a,b,c).
+* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
+ the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
+ is commonly produced by subtraction) look like a single 1-bit
+ difference.
+* the base values were pseudorandom, all zero but one bit set, or
+ all zero plus a counter that starts at zero.
+
+These constants passed:
+ 14 11 25 16 4 14 24
+ 12 14 25 16 4 14 24
+and these came close:
+ 4 8 15 26 3 22 24
+ 10 8 15 26 3 22 24
+ 11 8 15 26 3 22 24
+-------------------------------------------------------------------------------
+*/
+#define final(a,b,c) \
+{ \
+ c ^= b; c -= rot(b,14); \
+ a ^= c; a -= rot(c,11); \
+ b ^= a; b -= rot(a,25); \
+ c ^= b; c -= rot(b,16); \
+ a ^= c; a -= rot(c,4); \
+ b ^= a; b -= rot(a,14); \
+ c ^= b; c -= rot(b,24); \
+}
+
+/*
+--------------------------------------------------------------------
+ This works on all machines. To be useful, it requires
+ -- that the key be an array of uint32's, and
+ -- that all your machines have the same endianness, and
+ -- that the length be the number of uint32's in the key
+
+ The function hashword() is identical to hashlittle() on little-endian
+ machines, and identical to hashbig() on big-endian machines,
+ except that the length has to be measured in uint32s rather than in
+ bytes. hashlittle() is more complicated than hashword() only because
+ hashlittle() has to dance around fitting the key bytes into registers.
+--------------------------------------------------------------------
+*/
+uint32 hashword( uint32 *k, size_t length, uint32 initval)
+{
+ uint32 a,b,c;
+
+ /* Set up the internal state */
+ a = b = c = 0xdeadbeef + (((uint32)length)<<2) + initval;
+
+ /*------------------------------------------------- handle most of the key */
+ while (length > 3)
+ {
+ a += k[0];
+ b += k[1];
+ c += k[2];
+ mix(a,b,c);
+ length -= 3;
+ k += 3;
+ }
+
+ /*--------------------------------------------- handle the last 3 uint32's */
+ switch(length) /* all the case statements fall through */
+ {
+ case 3 : c+=k[2];
+ case 2 : b+=k[1];
+ case 1 : a+=k[0];
+ final(a,b,c);
+ case 0: /* case 0: nothing left to add */
+ break;
+ }
+ /*------------------------------------------------------ report the result */
+ return c;
+}
+
+
+/*
+-------------------------------------------------------------------------------
+hashlittle() -- hash a variable-length key into a 32-bit value
+ k : the key (the unaligned variable-length array of bytes)
+ length : the length of the key, counting by bytes
+ initval : can be any 4-byte value
+Returns a 32-bit value. Every bit of the key affects every bit of
+the return value. Two keys differing by one or two bits will have
+totally different hash values.
+
+The best hash table sizes are powers of 2. There is no need to do
+mod a prime (mod is sooo slow!). If you need less than 32 bits,
+use a bitmask. For example, if you need only 10 bits, do
+ h = (h & hashmask(10));
+In which case, the hash table should have hashsize(10) elements.
+
+If you are hashing n strings (uint8 **)k, do it like this:
+ for (i=0, h=0; i<n; ++i) h = hashlittle( k[i], len[i], h);
+
+By Bob Jenkins, 2006. bob_jenkins@burtleburtle.net. You may use this
+code any way you wish, private, educational, or commercial. It's mir_free.
+
+Use for hash table lookup, or anything where one collision in 2^^32 is
+acceptable. Do NOT use for cryptographic purposes.
+-------------------------------------------------------------------------------
+*/
+
+uint32 hashlittle( void *key, size_t length, uint32 initval)
+{
+ uint32 a,b,c;
+
+ /* Set up the internal state */
+ a = b = c = 0xdeadbeef + ((uint32)length) + initval;
+
+ if (HASH_LITTLE_ENDIAN && !((((uint8 *)key)-(uint8 *)0) & 0x3)) {
+ uint32 *k = ( uint32 *)key; /* read 32-bit chunks */
+
+ /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
+ while (length > 12)
+ {
+ a += k[0];
+ b += k[1];
+ c += k[2];
+ mix(a,b,c);
+ length -= 12;
+ k += 3;
+ }
+
+ /*----------------------------- handle the last (probably partial) block */
+ switch(length)
+ {
+ case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
+ case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
+ case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
+ case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
+ case 8 : b+=k[1]; a+=k[0]; break;
+ case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
+ case 6 : b+=k[1]&0xffff; a+=k[0]; break;
+ case 5 : b+=k[1]&0xff; a+=k[0]; break;
+ case 4 : a+=k[0]; break;
+ case 3 : a+=k[0]&0xffffff; break;
+ case 2 : a+=k[0]&0xffff; break;
+ case 1 : a+=k[0]&0xff; break;
+ case 0 : return c; /* zero length strings require no mixing */
+ }
+
+ } else if (HASH_LITTLE_ENDIAN && !((((uint8 *)key)-(uint8 *)0) & 0x1)) {
+ uint16 *k = (uint16 *)key; /* read 16-bit chunks */
+
+ /*--------------- all but last block: aligned reads and different mixing */
+ while (length > 12)
+ {
+ a += k[0] + (((uint32)k[1])<<16);
+ b += k[2] + (((uint32)k[3])<<16);
+ c += k[4] + (((uint32)k[5])<<16);
+ mix(a,b,c);
+ length -= 12;
+ k += 6;
+ }
+
+ /*----------------------------- handle the last (probably partial) block */
+ switch(length)
+ {
+ case 12: c+=k[4]+(((uint32)k[5])<<16);
+ b+=k[2]+(((uint32)k[3])<<16);
+ a+=k[0]+(((uint32)k[1])<<16);
+ break;
+ case 11: c+=((uint32)(k[5]&0xff))<<16;/* fall through */
+ case 10: c+=k[4];
+ b+=k[2]+(((uint32)k[3])<<16);
+ a+=k[0]+(((uint32)k[1])<<16);
+ break;
+ case 9 : c+=k[4]&0xff; /* fall through */
+ case 8 : b+=k[2]+(((uint32)k[3])<<16);
+ a+=k[0]+(((uint32)k[1])<<16);
+ break;
+ case 7 : b+=((uint32)(k[3]&0xff))<<16;/* fall through */
+ case 6 : b+=k[2];
+ a+=k[0]+(((uint32)k[1])<<16);
+ break;
+ case 5 : b+=k[2]&0xff; /* fall through */
+ case 4 : a+=k[0]+(((uint32)k[1])<<16);
+ break;
+ case 3 : a+=((uint32)(k[1]&0xff))<<16;/* fall through */
+ case 2 : a+=k[0];
+ break;
+ case 1 : a+=k[0]&0xff;
+ break;
+ case 0 : return c; /* zero length requires no mixing */
+ }
+
+ } else { /* need to read the key one byte at a time */
+ uint8 *k = (uint8 *)key;
+
+ /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
+ while (length > 12)
+ {
+ a += k[0];
+ a += ((uint32)k[1])<<8;
+ a += ((uint32)k[2])<<16;
+ a += ((uint32)k[3])<<24;
+ b += k[4];
+ b += ((uint32)k[5])<<8;
+ b += ((uint32)k[6])<<16;
+ b += ((uint32)k[7])<<24;
+ c += k[8];
+ c += ((uint32)k[9])<<8;
+ c += ((uint32)k[10])<<16;
+ c += ((uint32)k[11])<<24;
+ mix(a,b,c);
+ length -= 12;
+ k += 12;
+ }
+
+ /*-------------------------------- last block: affect all 32 bits of (c) */
+ switch(length) /* all the case statements fall through */
+ {
+ case 12: c+=((uint32)k[11])<<24;
+ case 11: c+=((uint32)k[10])<<16;
+ case 10: c+=((uint32)k[9])<<8;
+ case 9 : c+=k[8];
+ case 8 : b+=((uint32)k[7])<<24;
+ case 7 : b+=((uint32)k[6])<<16;
+ case 6 : b+=((uint32)k[5])<<8;
+ case 5 : b+=k[4];
+ case 4 : a+=((uint32)k[3])<<24;
+ case 3 : a+=((uint32)k[2])<<16;
+ case 2 : a+=((uint32)k[1])<<8;
+ case 1 : a+=k[0];
+ break;
+ case 0 : return c;
+ }
+ }
+
+ final(a,b,c);
+ return c;
+}
+
+
+
+/*
+ * hashbig():
+ * This is the same as hashword() on big-endian machines. It is different
+ * from hashlittle() on all machines. hashbig() takes advantage of
+ * big-endian byte ordering.
+ */
+uint32 hashbig( void *key, size_t length, uint32 initval)
+{
+ uint32 a,b,c;
+
+ /* Set up the internal state */
+ a = b = c = 0xdeadbeef + ((uint32)length) + initval;
+
+ if (HASH_BIG_ENDIAN && !((((uint8 *)key)-(uint8 *)0) & 0x3)) {
+ uint32 *k = (uint32 *)key; /* read 32-bit chunks */
+
+ /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
+ while (length > 12)
+ {
+ a += k[0];
+ b += k[1];
+ c += k[2];
+ mix(a,b,c);
+ length -= 12;
+ k += 3;
+ }
+
+ /*----------------------------- handle the last (probably partial) block */
+ switch(length)
+ {
+ case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
+ case 11: c+=k[2]<<8; b+=k[1]; a+=k[0]; break;
+ case 10: c+=k[2]<<16; b+=k[1]; a+=k[0]; break;
+ case 9 : c+=k[2]<<24; b+=k[1]; a+=k[0]; break;
+ case 8 : b+=k[1]; a+=k[0]; break;
+ case 7 : b+=k[1]<<8; a+=k[0]; break;
+ case 6 : b+=k[1]<<16; a+=k[0]; break;
+ case 5 : b+=k[1]<<24; a+=k[0]; break;
+ case 4 : a+=k[0]; break;
+ case 3 : a+=k[0]<<8; break;
+ case 2 : a+=k[0]<<16; break;
+ case 1 : a+=k[0]<<24; break;
+ case 0 : return c; /* zero length strings require no mixing */
+ }
+
+ } else { /* need to read the key one byte at a time */
+ uint8 *k = (uint8 *)key;
+
+ /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
+ while (length > 12)
+ {
+ a += ((uint32)k[0])<<24;
+ a += ((uint32)k[1])<<16;
+ a += ((uint32)k[2])<<8;
+ a += ((uint32)k[3]);
+ b += ((uint32)k[4])<<24;
+ b += ((uint32)k[5])<<16;
+ b += ((uint32)k[6])<<8;
+ b += ((uint32)k[7]);
+ c += ((uint32)k[8])<<24;
+ c += ((uint32)k[9])<<16;
+ c += ((uint32)k[10])<<8;
+ c += ((uint32)k[11]);
+ mix(a,b,c);
+ length -= 12;
+ k += 12;
+ }
+
+ /*-------------------------------- last block: affect all 32 bits of (c) */
+ switch(length) /* all the case statements fall through */
+ {
+ case 12: c+=((uint32)k[11])<<24;
+ case 11: c+=((uint32)k[10])<<16;
+ case 10: c+=((uint32)k[9])<<8;
+ case 9 : c+=k[8];
+ case 8 : b+=((uint32)k[7])<<24;
+ case 7 : b+=((uint32)k[6])<<16;
+ case 6 : b+=((uint32)k[5])<<8;
+ case 5 : b+=k[4];
+ case 4 : a+=((uint32)k[3])<<24;
+ case 3 : a+=((uint32)k[2])<<16;
+ case 2 : a+=((uint32)k[1])<<8;
+ case 1 : a+=k[0];
+ break;
+ case 0 : return c;
+ }
+ }
+
+ final(a,b,c);
+ return c;
+}
+
+
+#ifdef SELF_TEST
+
+/* used for timings */
+void driver1()
+{
+ uint8 buf[256];
+ uint32 i;
+ uint32 h=0;
+ time_t a,z;
+
+ time(&a);
+ for (i=0; i<256; ++i) buf[i] = 'x';
+ for (i=0; i<1; ++i)
+ {
+ h = hashlittle(&buf[0],1,h);
+ }
+ time(&z);
+ if (z-a > 0) printf("time %ld %.8lx\n", z-a, h);
+}
+
+/* check that every input bit changes every output bit half the time */
+#define HASHSTATE 1
+#define HASHLEN 1
+#define MAXPAIR 60
+#define MAXLEN 70
+void driver2()
+{
+ uint8 qa[MAXLEN+1], qb[MAXLEN+2], *a = &qa[0], *b = &qb[1];
+ uint32 c[HASHSTATE], d[HASHSTATE], i, j=0, k, l, m, z;
+ uint32 e[HASHSTATE],f[HASHSTATE],g[HASHSTATE],h[HASHSTATE];
+ uint32 x[HASHSTATE],y[HASHSTATE];
+ uint32 hlen;
+
+ printf("No more than %d trials should ever be needed \n",MAXPAIR/2);
+ for (hlen=0; hlen < MAXLEN; ++hlen)
+ {
+ z=0;
+ for (i=0; i<hlen; ++i) /*----------------------- for each input byte, */
+ {
+ for (j=0; j<8; ++j) /*------------------------ for each input bit, */
+ {
+ for (m=1; m<8; ++m) /*------------ for serveral possible initvals, */
+ {
+ for (l=0; l<HASHSTATE; ++l) e[l]=f[l]=g[l]=h[l]=x[l]=y[l]=~((uint32)0);
+
+ /*---- check that every output bit is affected by that input bit */
+ for (k=0; k<MAXPAIR; k+=2)
+ {
+ uint32 finished=1;
+ /* keys have one bit different */
+ for (l=0; l<hlen+1; ++l) {a[l] = b[l] = (uint8)0;}
+ /* have a and b be two keys differing in only one bit */
+ a[i] ^= (k<<j);
+ a[i] ^= (k>>(8-j));
+ c[0] = hashlittle(a, hlen, m);
+ b[i] ^= ((k+1)<<j);
+ b[i] ^= ((k+1)>>(8-j));
+ d[0] = hashlittle(b, hlen, m);
+ /* check every bit is 1, 0, set, and not set at least once */
+ for (l=0; l<HASHSTATE; ++l)
+ {
+ e[l] &= (c[l]^d[l]);
+ f[l] &= ~(c[l]^d[l]);
+ g[l] &= c[l];
+ h[l] &= ~c[l];
+ x[l] &= d[l];
+ y[l] &= ~d[l];
+ if (e[l]|f[l]|g[l]|h[l]|x[l]|y[l]) finished=0;
+ }
+ if (finished) break;
+ }
+ if (k>z) z=k;
+ if (k==MAXPAIR)
+ {
+ printf("Some bit didn't change: ");
+ printf("%.8lx %.8lx %.8lx %.8lx %.8lx %.8lx ",
+ e[0],f[0],g[0],h[0],x[0],y[0]);
+ printf("i %ld j %ld m %ld len %ld\n",i,j,m,hlen);
+ }
+ if (z==MAXPAIR) goto done;
+ }
+ }
+ }
+ done:
+ if (z < MAXPAIR)
+ {
+ printf("Mix success %2ld bytes %2ld initvals ",i,m);
+ printf("required %ld trials\n",z/2);
+ }
+ }
+ printf("\n");
+}
+
+/* Check for reading beyond the end of the buffer and alignment problems */
+void driver3()
+{
+ uint8 buf[MAXLEN+20], *b;
+ uint32 len;
+ uint8 q[] = "This is the time for all good men to come to the aid of their country...";
+ //uint32 dummy1;
+ uint8 qq[] = "xThis is the time for all good men to come to the aid of their country...";
+ //uint32 dummy2;
+ uint8 qqq[] = "xxThis is the time for all good men to come to the aid of their country...";
+ //uint32 dummy3;
+ uint8 qqqq[] = "xxxThis is the time for all good men to come to the aid of their country...";
+ uint32 h,i,j,ref,x,y;
+ uint8 *p;
+
+ printf("Endianness. These lines should all be the same (for values filled in):\n");
+ printf("%.8lx %.8lx %.8lx\n",
+ hashword((uint32 *)q, (sizeof(q)-1)/4, 13),
+ hashword((uint32 *)q, (sizeof(q)-5)/4, 13),
+ hashword((uint32 *)q, (sizeof(q)-9)/4, 13));
+ p = q;
+ printf("%.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx\n",
+ hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13),
+ hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13),
+ hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13),
+ hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13),
+ hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13),
+ hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13));
+ p = &qq[1];
+ printf("%.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx\n",
+ hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13),
+ hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13),
+ hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13),
+ hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13),
+ hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13),
+ hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13));
+ p = &qqq[2];
+ printf("%.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx\n",
+ hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13),
+ hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13),
+ hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13),
+ hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13),
+ hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13),
+ hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13));
+ p = &qqqq[3];
+ printf("%.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx\n",
+ hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13),
+ hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13),
+ hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13),
+ hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13),
+ hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13),
+ hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13));
+ printf("\n");
+ for (h=0, b=buf+1; h<8; ++h, ++b)
+ {
+ for (i=0; i<MAXLEN; ++i)
+ {
+ len = i;
+ for (j=0; j<i; ++j) *(b+j)=0;
+
+ /* these should all be equal */
+ ref = hashlittle(b, len, (uint32)1);
+ *(b+i)=(uint8)~0;
+ *(b-1)=(uint8)~0;
+ x = hashlittle(b, len, (uint32)1);
+ y = hashlittle(b, len, (uint32)1);
+ if ((ref != x) || (ref != y))
+ {
+ printf("alignment error: %.8lx %.8lx %.8lx %ld %ld\n",ref,x,y,h,i);
+ }
+ }
+ }
+}
+
+/* check for problems with nulls */
+ void driver4()
+{
+ uint8 buf[1];
+ uint32 h,i,state[HASHSTATE];
+
+
+ buf[0] = ~0;
+ for (i=0; i<HASHSTATE; ++i) state[i] = 1;
+ printf("These should all be different\n");
+ for (i=0, h=0; i<8; ++i)
+ {
+ h = hashlittle(buf, (uint32)0, h);
+ printf("%2ld 0-byte strings, hash is %.8lx\n", i, h);
+ }
+}
+
+
+int main()
+{
+ driver1(); /* test that the key is hashed: used for timings */
+ driver2(); /* test that whole key is hashed thoroughly */
+ driver3(); /* test that nothing but the key is hashed */
+ driver4(); /* test hashing multiple buffers (all buffers are null) */
+ return 1;
+}
+
+#endif /* SELF_TEST */
diff --git a/plugins/Variables/src/main.cpp b/plugins/Variables/src/main.cpp
new file mode 100644
index 0000000000..b6330ce585
--- /dev/null
+++ b/plugins/Variables/src/main.cpp
@@ -0,0 +1,98 @@
+ /*
+ 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 "buildnumber.h"
+
+HINSTANCE hInst;
+
+DWORD g_mirandaVersion;
+int hLangpack = 0;
+
+// {59B0036E-5403-422e-883B-C9AAF425682B}
+#define MIID_VARIABLES { 0x59b0036e, 0x5403, 0x422e, { 0x88, 0x3b, 0xc9, 0xaa, 0xf4, 0x25, 0x68, 0x2b } }
+
+static HANDLE hExitHook, hModulesLoadedHook;
+
+static int Exit(WPARAM wParam, LPARAM lParam)
+{
+ UnhookEvent(hExitHook);
+ return 0;
+}
+
+static int ModulesLoaded(WPARAM wParam, LPARAM lParam) {
+
+ UnhookEvent(hModulesLoadedHook);
+ // trigger plugin
+#if !defined(WINE)
+ initTriggerModule();
+#endif
+
+ return 0;
+}
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
+{
+ hInst=hinstDLL;
+ return TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// MirandaPluginInfoEx - returns the extended information about a plugin
+
+PLUGININFOEX pluginInfoEx = {
+ sizeof(PLUGININFOEX),
+ "Variables",
+ __VERSION_DWORD,
+ "Adds support for dynamic variables in strings for plugins.",
+ "P Boon",
+ "unregistered@users.sourceforge.net",
+ "© 2003-2008 P. Boon, Ricardo Pescuma, George Hazan",
+ "http://nightly.miranda.im/",
+ UNICODE_AWARE,
+ MIID_VARIABLES
+};
+
+extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ g_mirandaVersion = mirandaVersion;
+ return &pluginInfoEx;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Load - plugin's entry point
+
+extern "C" int __declspec(dllexport) Load(void)
+{
+ mir_getLP( &pluginInfoEx );
+
+ hExitHook = HookEvent(ME_SYSTEM_OKTOEXIT, Exit);
+ hModulesLoadedHook = HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded);
+ LoadVarModule();
+
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Unload - destroys plugin from memory
+
+extern "C" int __declspec(dllexport) Unload(void)
+{
+ UnloadVarModule();
+ return 0;
+}
diff --git a/plugins/Variables/src/options.cpp b/plugins/Variables/src/options.cpp
new file mode 100644
index 0000000000..0220386564
--- /dev/null
+++ b/plugins/Variables/src/options.cpp
@@ -0,0 +1,148 @@
+/*
+ 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"
+
+extern HINSTANCE hInst;
+extern struct ParseOptions gParseOpts;
+extern int hLangpack;
+
+static INT_PTR CALLBACK SetOptsDlgProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch( msg ) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ {
+ DBVARIANT dbv;
+ if (!DBGetContactSettingTString( NULL, MODULENAME, SETTING_STARTUPTEXT, &dbv )) {
+ SetDlgItemText(hwndDlg, IDC_FORMATTEXT, dbv.ptszVal);
+ DBFreeVariant(&dbv);
+ }
+ }
+ CheckDlgButton(hwndDlg, IDC_PARSEATSTARTUP, db_get_b(NULL, MODULENAME, SETTING_PARSEATSTARTUP, 0));
+ CheckDlgButton(hwndDlg, IDC_STRIPCRLF, db_get_b(NULL, MODULENAME, SETTING_STRIPCRLF, 0));
+ CheckDlgButton(hwndDlg, IDC_STRIPWS, db_get_b(NULL, MODULENAME, SETTING_STRIPWS, 0));
+ CheckDlgButton(hwndDlg, IDC_STRIPALL, db_get_b(NULL, MODULENAME, SETTING_STRIPALL, 0));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPCRLF), IsDlgButtonChecked(hwndDlg, IDC_STRIPALL)?FALSE:TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPWS), IsDlgButtonChecked(hwndDlg, IDC_STRIPALL)?FALSE:TRUE);
+ variables_skin_helpbutton(hwndDlg, IDC_SHOWHELP);
+ break;
+
+ case WM_COMMAND:
+ if ((HIWORD(wParam) == EN_CHANGE) || (HIWORD(wParam) == BN_CLICKED)) {
+ switch (LOWORD(wParam)) {
+ case IDC_PARSEATSTARTUP:
+ case IDC_STRIPCRLF:
+ case IDC_STRIPWS:
+ case IDC_STRIPALL:
+ case IDC_FORMATTEXT:
+ SendMessage(GetParent(hwndDlg),PSM_CHANGED,0,0);
+ gParseOpts.bStripEOL = IsDlgButtonChecked(hwndDlg, IDC_STRIPCRLF);
+ gParseOpts.bStripWS = IsDlgButtonChecked(hwndDlg, IDC_STRIPWS);
+ gParseOpts.bStripAll = IsDlgButtonChecked(hwndDlg, IDC_STRIPALL);
+ break;
+ }
+ if (LOWORD(wParam) == IDC_FORMATTEXT && IsDlgButtonChecked( hwndDlg, IDC_AUTOPARSE ))
+ SendMessage(hwndDlg, VARM_PARSE, 0, 0);
+ }
+ switch (LOWORD(wParam)) {
+ case IDC_PARSE:
+ SendMessage(hwndDlg, VARM_PARSE, 0, 0);
+ break;
+
+ case IDC_AUTOPARSE:
+ SendMessage(hwndDlg, VARM_PARSE, 0, 0);
+ if (IsDlgButtonChecked( hwndDlg, IDC_AUTOPARSE ))
+ SetTimer(hwndDlg, IDT_PARSE, 1000, NULL);
+ else
+ KillTimer(hwndDlg, IDT_PARSE);
+ break;
+
+ case IDC_SHOWHELP:
+ variables_showhelp(hwndDlg, IDC_FORMATTEXT, VHF_FULLDLG|VHF_SETLASTSUBJECT, NULL, NULL);
+ break;
+
+ case IDC_STRIPALL:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPCRLF), IsDlgButtonChecked(hwndDlg, IDC_STRIPALL)?FALSE:TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STRIPWS), IsDlgButtonChecked(hwndDlg, IDC_STRIPALL)?FALSE:TRUE);
+ break;
+ }
+ break;
+
+ case WM_NOTIFY:
+ if (((LPNMHDR)lParam)->code == PSN_APPLY) {
+ int len = SendDlgItemMessage(hwndDlg, IDC_FORMATTEXT, WM_GETTEXTLENGTH, 0, 0);
+ if (len >= 0) {
+ TCHAR *szFormatText = (TCHAR*)mir_calloc((len+1)* sizeof(TCHAR));
+ if (szFormatText == NULL)
+ break;
+
+ if (GetDlgItemText(hwndDlg, IDC_FORMATTEXT, szFormatText, len+1) != 0)
+ db_set_ts(NULL, MODULENAME, SETTING_STARTUPTEXT, szFormatText);
+
+ mir_free(szFormatText);
+ }
+ db_set_b(NULL, MODULENAME, SETTING_PARSEATSTARTUP, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_PARSEATSTARTUP)?1:0));
+ db_set_b(NULL, MODULENAME, SETTING_STRIPCRLF, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_STRIPCRLF)?1:0));
+ db_set_b(NULL, MODULENAME, SETTING_STRIPWS, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_STRIPWS)?1:0));
+ db_set_b(NULL, MODULENAME, SETTING_STRIPALL, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_STRIPALL)?1:0));
+ }
+ break;
+
+ case VARM_PARSE:
+ {
+ TCHAR *string = Hlp_GetDlgItemText(hwndDlg, IDC_FORMATTEXT);
+ if (string != NULL) {
+ TCHAR *newString = variables_parsedup(string, NULL, NULL);
+ if (newString != NULL) {
+ SetWindowText(GetDlgItem(hwndDlg, IDC_RESULT), newString);
+ mir_free(newString);
+ }
+ mir_free(string);
+ } }
+ break;
+
+ case WM_TIMER:
+ if (IsDlgButtonChecked(hwndDlg, IDC_AUTOPARSE))
+ SendMessage(hwndDlg, VARM_PARSE, 0, 0);
+ break;
+
+ case WM_DESTROY:
+ setParseOptions(NULL);
+ break;
+ }
+
+ return FALSE;
+}
+
+int OptionsInit(WPARAM wParam, LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp = {0};
+ odp.cbSize = sizeof(odp);
+ odp.position = 150000000;
+ odp.pszGroup = LPGEN("Services");
+ odp.groupPosition = 910000000;
+ odp.hInstance = hInst;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTS_DIALOG);
+ odp.pszTitle = LPGEN("Variables");
+ odp.pfnDlgProc = SetOptsDlgProc;
+ odp.flags = ODPF_BOLDGROUPS;
+ Options_AddPage(wParam, &odp);
+
+ return 0;
+}
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);
+}
+
diff --git a/plugins/Variables/src/parse_alias.h b/plugins/Variables/src/parse_alias.h
new file mode 100644
index 0000000000..d868841fb8
--- /dev/null
+++ b/plugins/Variables/src/parse_alias.h
@@ -0,0 +1,29 @@
+/*
+ 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
+*/
+typedef struct {
+ TCHAR *szAlias;
+ unsigned int argc;
+ TCHAR **argv;
+ TCHAR *szTranslation;
+} ALIASREGISTER;
+
+#define ADDALIAS "alias"
+
+int isValidTokenChar(TCHAR tc);
+TCHAR *getArguments(TCHAR *string, TCHAR ***aargv, int *aargc);
diff --git a/plugins/Variables/src/parse_external.cpp b/plugins/Variables/src/parse_external.cpp
new file mode 100644
index 0000000000..42b7a12462
--- /dev/null
+++ b/plugins/Variables/src/parse_external.cpp
@@ -0,0 +1,258 @@
+/*
+ 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_external.h"
+#include "ac/ac.h"
+
+static int (WINAPI *acEval)(const char *, char *) = NULL;
+static int (WINAPI *acFormat)(const char *, char *) = NULL;
+static int (WINAPI *acInitClient)(const char *, int, int, int, int) = NULL;
+static void (WINAPI *acUninit)() = NULL;
+
+static unsigned int lastAMIPFailure = -1;
+
+static TCHAR *getFullWinampTitleText() {
+
+ TCHAR *szTitle, *szWinText;
+ HWND hwndWinamp;
+
+ hwndWinamp = FindWindow(_T("STUDIO"), NULL);
+ if (hwndWinamp == NULL)
+ hwndWinamp = FindWindow(_T("Winamp v1.x"),NULL);
+
+ if (hwndWinamp == NULL)
+ return NULL;
+
+ szWinText = (TCHAR*)mir_alloc((GetWindowTextLength(hwndWinamp) + 1)*sizeof(TCHAR));
+ if (szWinText == NULL)
+ return NULL;
+
+ if (GetWindowText(hwndWinamp, szWinText, GetWindowTextLength(hwndWinamp)+1) == 0) {
+ mir_free(szWinText);
+ return NULL;
+ }
+ szTitle = (TCHAR*)mir_alloc((2*_tcslen(szWinText)+1)*sizeof(TCHAR));
+ if (szTitle == NULL) {
+ mir_free(szWinText);
+ return NULL;
+ }
+ _tcscpy(szTitle, szWinText);
+ _tcscpy(szTitle+_tcslen(szTitle), szWinText);
+ mir_free(szWinText);
+
+ return szTitle;
+}
+
+static TCHAR *parseWinampSong(ARGUMENTSINFO *ai) {
+
+ TCHAR *szTitle, *scur, *cur, *res;
+
+ if (ai->argc != 1) {
+ return NULL;
+ }
+ res = NULL;
+ szTitle = getFullWinampTitleText();
+ if (szTitle == NULL) {
+ return NULL;
+ }
+ scur = _tcschr(szTitle, _T('.'));
+ cur = _tcsstr(scur, _T(" - Winamp"));
+ if ((scur == NULL) || (cur == NULL) || (scur >= cur) || (scur > (szTitle + _tcslen(szTitle) - 2)) || (cur > (szTitle + _tcslen(szTitle)))) {
+ mir_free(szTitle);
+ return NULL;
+ }
+ scur++;
+ scur++;
+ *cur = '\0';
+ res = mir_tstrdup(scur);
+ mir_free(szTitle);
+ ai->flags |= AIF_DONTPARSE;
+
+ return res;
+}
+
+static TCHAR *parseWinampState(ARGUMENTSINFO *ai) {
+
+ TCHAR *szTitle, *scur, *cur, *res;
+
+ if (ai->argc != 1) {
+ return NULL;
+ }
+ res = NULL;
+ szTitle = getFullWinampTitleText();
+ if (szTitle == NULL) {
+ return NULL;
+ }
+ scur = _tcschr(szTitle, _T('.'));
+ cur = _tcsstr(scur, _T(" - Winamp"));
+ if ((scur == NULL) || (cur == NULL)) {
+ mir_free(szTitle);
+ return mir_tstrdup(TranslateT("Stopped"));
+ }
+ if ((!_tcsncmp(cur+10, _T("[Stopped]"), 9))) {
+ mir_free(szTitle);
+ return mir_tstrdup(TranslateT("Stopped"));
+ }
+ if ((!_tcsncmp(cur+10, _T("[Paused]"), 8))) {
+ mir_free(szTitle);
+ return mir_tstrdup(TranslateT("Paused"));
+ }
+ mir_free(szTitle);
+ return mir_tstrdup(_T("Playing"));
+}
+
+static unsigned int checkAMIP() {
+
+ if (lastAMIPFailure == 0) {
+ log_debugA("AMIP initialized");
+ return 0;
+ }
+ if (GetTickCount() - lastAMIPFailure < AMIP_TIMEOUT) {
+ log_debugA("AMIP not initialized, not attempting");
+ return -1;
+ }
+ if (acInitClient("127.0.0.1", 60333, 1000, 5, 1)) {
+ lastAMIPFailure = 0;
+ log_debugA("AMIP now initialized");
+
+ return 0; // success
+ }
+ log_debugA("AMIP failed to initialized");
+ if (lastAMIPFailure == 0) {
+ /* if this is the first failure after a succesful init, call uninit for a cleanup (maybe it'll help for the next try ;)) */
+ acUninit();
+ }
+ lastAMIPFailure = GetTickCount();
+
+ return -1;
+}
+
+static TCHAR *parseAMIPEval(ARGUMENTSINFO *ai) {
+
+ TCHAR *tszRes;
+ char *cmd;
+ char szRes[AC_BUFFER_SIZE];
+
+ tszRes = NULL;
+ if (ai->argc != 2) {
+ return NULL;
+ }
+
+ cmd = mir_t2a(ai->targv[1]);
+
+ if (checkAMIP() != 0) {
+ log_debugA("checkAMIP failed");
+
+ return NULL;
+ }
+ ZeroMemory(&szRes, sizeof(szRes));
+ if (AC_ERR_NOERROR == acEval(cmd, szRes)) {
+
+ tszRes = mir_a2t(szRes);
+
+ }
+ else {
+ lastAMIPFailure = GetTickCount();
+ }
+ mir_free(cmd);
+
+ return tszRes;
+}
+
+static TCHAR *parseAMIPFormat(ARGUMENTSINFO *ai) {
+
+ TCHAR *tszRes;
+ char *cmd;
+ char szRes[AC_BUFFER_SIZE];
+
+ tszRes = NULL;
+ if (ai->argc != 2) {
+ return NULL;
+ }
+
+ cmd = mir_t2a(ai->targv[1]);
+
+ if (checkAMIP() != 0) {
+
+ return NULL;
+ }
+ if (AC_ERR_NOERROR == acFormat(cmd, szRes)) {
+
+ tszRes = mir_a2t(szRes);
+
+ }
+ else {
+ lastAMIPFailure = GetTickCount();
+ }
+ mir_free(cmd);
+
+ return tszRes;
+}
+
+static int initAMIP() {
+
+ HMODULE hModule;
+
+ hModule = LoadLibraryA("ac.dll");
+ if (hModule == NULL) {
+ char path[MAX_PATH];
+ char *cur;
+
+ GetModuleFileNameA(NULL, path, sizeof(path));
+ cur = strrchr(path, '\\');
+ if (cur != NULL)
+ strcpy(cur+1, "ac.dll");
+ else
+ strcpy(cur, "ac.dll");
+ hModule = LoadLibraryA(path);
+ }
+ if (hModule == NULL) {
+ return -1;
+ }
+ acInitClient = (int (__stdcall *)(const char *,int ,int ,int ,int ))GetProcAddress(hModule, "ac_init_client");
+ acEval = (int (__stdcall *)(const char *,char *))GetProcAddress(hModule, "ac_eval");
+ acFormat = (int (__stdcall *)(const char *,char *))GetProcAddress(hModule, "ac_format");
+ acUninit = (void (__stdcall *)())GetProcAddress(hModule, "ac_uninit");
+
+ return 0;
+}
+
+int registerExternalTokens() {
+
+ registerIntToken(_T(WINAMPSONG), parseWinampSong, TRF_FIELD, "External Applications\tretrieves song name of the song currently playing in Winamp");
+ registerIntToken(_T(WINAMPSTATE), parseWinampState, TRF_FIELD, "External Applications\tretrieves current Winamp state (Playing/Paused/Stopped)");
+ if (!initAMIP()) {
+ registerIntToken(_T(AMIPEVAL), parseAMIPEval, TRF_FUNCTION, "External Applications\t(x)\tretrieves info from AMIP (x is var_<variable> with any AMIP variable)");
+ registerIntToken(_T(AMIPFORMAT), parseAMIPFormat, TRF_FUNCTION|TRF_UNPARSEDARGS, "External Applications\t(x)\tretrieves info from AMIP (x is AMIP format string)");
+ }
+ else {
+ log_infoA("Variables: ac.dll for AMIP not found");
+ }
+
+ return 0;
+}
+
+int deInitExternal() {
+
+ if (acUninit != NULL) {
+ acUninit();
+ }
+
+ return 0;
+} \ No newline at end of file
diff --git a/plugins/Variables/src/parse_external.h b/plugins/Variables/src/parse_external.h
new file mode 100644
index 0000000000..201b1e26a3
--- /dev/null
+++ b/plugins/Variables/src/parse_external.h
@@ -0,0 +1,25 @@
+/*
+ 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
+*/
+#define WINAMPSONG "winampsong"
+#define WINAMPSTATE "winampstate"
+#define DEF_WINAMPTITLE "Winamp3"
+
+#define AMIPEVAL "amipvar"
+#define AMIPFORMAT "amipformat"
+#define AMIP_TIMEOUT 5000
diff --git a/plugins/Variables/src/parse_inet.cpp b/plugins/Variables/src/parse_inet.cpp
new file mode 100644
index 0000000000..4eabed3ccc
--- /dev/null
+++ b/plugins/Variables/src/parse_inet.cpp
@@ -0,0 +1,143 @@
+/*
+ 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_inet.h"
+#include <wininet.h>
+
+static TCHAR *parseUrlEnc(ARGUMENTSINFO *ai) {
+
+ TCHAR *tres;
+ char hex[8], *res;
+ unsigned int cur;
+
+ if (ai->argc != 2) {
+ return NULL;
+ }
+
+ res = mir_t2a(ai->targv[1]);
+
+ if (res == NULL) {
+ return NULL;
+ }
+ cur = 0;
+ while (cur < strlen(res)) {
+ if (( (*(res+cur) >= '0') && (*(res+cur) <= '9')) || ( (*(res+cur) >= 'a') && (*(res+cur) <= 'z')) || ( (*(res+cur) >= 'A') && (*(res+cur) <= 'Z')) ) {
+ cur++;
+ continue;
+ }
+ res = ( char* )mir_realloc(res, strlen(res)+4);
+ if (res == NULL)
+ return NULL;
+
+ MoveMemory(res+cur+3, res+cur+1, strlen(res+cur+1)+1);
+ _snprintf(hex, sizeof(hex), "%%%x", *(res+cur));
+ strncpy(res+cur, hex, strlen(hex));
+ cur+=strlen(hex);
+ }
+
+ tres = mir_a2t(res);
+
+ mir_free(res);
+
+ return tres;
+}
+
+static TCHAR *parseUrlDec(ARGUMENTSINFO *ai) {
+
+ char *res, hex[8];
+ TCHAR *tres;
+ unsigned int cur;
+
+ if (ai->argc != 2) {
+ return NULL;
+ }
+
+ res = mir_t2a(ai->targv[1]);
+
+ if (res == NULL) {
+ return NULL;
+ }
+ cur = 0;
+ while (cur < strlen(res)) {
+ if ((*(res+cur) == '%') && (strlen(res+cur) >= 3)) {
+ memset(hex, '\0', sizeof(hex));
+ strncpy(hex, res+cur+1, 2);
+ *(res+cur) = (char)strtol(hex, NULL, 16);
+ MoveMemory(res+cur+1, res+cur+3, strlen(res+cur+3)+1);
+ }
+ cur++;
+ }
+ res = ( char* )mir_realloc(res, strlen(res)+1);
+
+ tres = mir_a2t(res);
+
+ mir_free(res);
+
+ return tres;
+}
+
+static TCHAR *parseNToA(ARGUMENTSINFO *ai) {
+
+ char *res;
+ struct in_addr in;
+
+ if (ai->argc != 2) {
+ return NULL;
+ }
+
+ in.s_addr = ttoi(ai->targv[1]);
+ res = inet_ntoa(in);
+ if (res != NULL) {
+
+ return mir_a2t(res);
+
+ }
+
+ return NULL;
+}
+
+static TCHAR *parseHToA(ARGUMENTSINFO *ai) {
+
+ char *res;
+ struct in_addr in;
+
+ if (ai->argc != 2) {
+ return NULL;
+ }
+
+ in.s_addr = htonl(ttoi(ai->targv[1]));
+ res = inet_ntoa(in);
+ if (res != NULL) {
+
+ return mir_a2t(res);
+
+ }
+
+ return NULL;
+}
+
+int registerInetTokens() {
+
+ registerIntToken(_T(URLENC), parseUrlEnc, TRF_FUNCTION, "Internet Related\t(x)\tconverts each non-html character into hex format");
+ registerIntToken(_T(URLDEC), parseUrlDec, TRF_FUNCTION, "Internet Related\t(x)\tconverts each hex value into non-html character");
+ registerIntToken(_T(NTOA), parseNToA, TRF_FUNCTION, "Internet Related\t(x)\tconverts a 32-bit number to IPv4 dotted notation");
+ registerIntToken(_T(HTOA), parseHToA, TRF_FUNCTION, "Internet Related\t(x)\tconverts a 32-bit number (in host byte order) to IPv4 dotted notation");
+
+ return 0;
+}
diff --git a/plugins/Variables/src/parse_inet.h b/plugins/Variables/src/parse_inet.h
new file mode 100644
index 0000000000..8e9bf66e1b
--- /dev/null
+++ b/plugins/Variables/src/parse_inet.h
@@ -0,0 +1,22 @@
+/*
+ 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
+*/
+#define URLENC "urlenc"
+#define URLDEC "urldec"
+#define NTOA "ntoa"
+#define HTOA "htoa"
diff --git a/plugins/Variables/src/parse_logic.cpp b/plugins/Variables/src/parse_logic.cpp
new file mode 100644
index 0000000000..b375faab14
--- /dev/null
+++ b/plugins/Variables/src/parse_logic.cpp
@@ -0,0 +1,414 @@
+/*
+ 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_logic.h"
+
+static TCHAR *parseAnd(ARGUMENTSINFO *ai) {
+
+ FORMATINFO fi;
+ TCHAR *szCondition;
+ unsigned int i;
+
+ if (ai->argc < 3) {
+ return NULL;
+ }
+ ZeroMemory(&fi, sizeof(fi));
+ memcpy(&fi, ai->fi, sizeof(fi));
+ for (i=1;i<ai->argc;i++) {
+ fi.tszFormat = ai->targv[i];
+ szCondition = formatString(&fi);
+ mir_free(szCondition);
+ //if (fi.pCount <= 0) {
+ if (fi.eCount > 0) {
+ ai->flags |= AIF_FALSE;
+ return mir_tstrdup(_T(""));
+ }
+ }
+
+ return mir_tstrdup(_T(""));
+}
+
+static TCHAR *parseFalse(ARGUMENTSINFO *ai) {
+
+ if (ai->argc != 1) {
+ return NULL;
+ }
+ ai->flags |= AIF_FALSE;
+
+ return mir_tstrdup(_T(""));
+}
+
+static TCHAR *parseIf(ARGUMENTSINFO *ai) {
+
+ FORMATINFO fi;
+ TCHAR *szCondition;
+
+ if (ai->argc != 4) {
+ return NULL;
+ }
+ ZeroMemory(&fi, sizeof(fi));
+ memcpy(&fi, ai->fi, sizeof(fi));
+ fi.eCount = fi.pCount = 0;
+ fi.tszFormat = ai->targv[1];
+ szCondition = formatString(&fi);
+ mir_free(szCondition);
+ //if (fi.pCount > 0) {
+ if (fi.eCount == 0) {
+ return mir_tstrdup(ai->targv[2]);
+ }
+ else {
+ return mir_tstrdup(ai->targv[3]);
+ }
+}
+
+static TCHAR *parseIf2(ARGUMENTSINFO *ai) {
+
+ FORMATINFO fi;
+ TCHAR *szCondition;
+
+ if (ai->argc != 3) {
+ return NULL;
+ }
+ ZeroMemory(&fi, sizeof(fi));
+ memcpy(&fi, ai->fi, sizeof(fi));
+ fi.eCount = fi.pCount = 0;
+ fi.tszFormat = ai->targv[1];
+ szCondition = formatString(&fi);
+ //if (fi.pCount > 0) {
+ if (fi.eCount == 0) {
+ return szCondition;
+ }
+ else {
+ if (szCondition != NULL) {
+// ai->flags |= AIF_DONTPARSE;
+ mir_free(szCondition);
+ }
+ return mir_tstrdup(ai->targv[2]);
+ }
+}
+
+static TCHAR *parseIf3(ARGUMENTSINFO *ai) {
+
+ FORMATINFO fi;
+ TCHAR *szCondition;
+ unsigned int i;
+
+ ZeroMemory(&fi, sizeof(fi));
+ memcpy(&fi, ai->fi, sizeof(fi));
+ for (i=1;i<ai->argc;i++) {
+ fi.eCount = fi.pCount = 0;
+ fi.tszFormat = ai->targv[i];
+ szCondition = formatString(&fi);
+ //if (fi.pCount > 0) {
+ if (fi.eCount == 0) {
+// ai->flags |= AIF_DONTPARSE;
+ return szCondition;
+ }
+ if (szCondition != NULL) {
+ mir_free(szCondition);
+ }
+ }
+
+ return NULL;
+}
+
+static TCHAR *parseIfequal(ARGUMENTSINFO *ai)
+{
+ TCHAR *tszFirst, *tszSecond;
+
+ if (ai->argc != 5)
+ return NULL;
+
+ FORMATINFO fi = { 0 };
+ memcpy(&fi, ai->fi, sizeof(fi));
+ fi.szFormat = ai->argv[1];
+ tszFirst = formatString(&fi);
+ fi.szFormat = ai->argv[2];
+ tszSecond = formatString(&fi);
+ if ((tszFirst == NULL) || (tszSecond == NULL)) {
+ if (tszFirst != NULL)
+ mir_free(tszFirst);
+
+ if (tszSecond != NULL)
+ mir_free(tszSecond);
+
+ return NULL;
+ }
+ if ((ttoi(tszFirst)) == (ttoi(tszSecond))) {
+ mir_free(tszFirst);
+ mir_free(tszSecond);
+ return mir_tstrdup(ai->targv[3]);
+ }
+ mir_free(tszFirst);
+ mir_free(tszSecond);
+
+ return mir_tstrdup(ai->targv[4]);
+}
+
+static TCHAR *parseIfgreater(ARGUMENTSINFO *ai) {
+
+ FORMATINFO fi;
+ TCHAR *tszFirst, *tszSecond;
+
+ if (ai->argc != 5) {
+ return NULL;
+ }
+ //ai->flags |= AIF_DONTPARSE;
+ ZeroMemory(&fi, sizeof(fi));
+ memcpy(&fi, ai->fi, sizeof(fi));
+ fi.szFormat = ai->argv[1];
+ tszFirst = formatString(&fi);
+ fi.szFormat = ai->argv[2];
+ tszSecond = formatString(&fi);
+ if ((tszFirst == NULL) || (tszSecond == NULL)) {
+ if (tszFirst != NULL) {
+ mir_free(tszFirst);
+ }
+ if (tszSecond != NULL) {
+ mir_free(tszSecond);
+ }
+ return NULL;
+ }
+ if ((ttoi(tszFirst)) > (ttoi(tszSecond))) {
+ mir_free(tszFirst);
+ mir_free(tszSecond);
+ return mir_tstrdup(ai->targv[3]);
+ }
+ mir_free(tszFirst);
+ mir_free(tszSecond);
+
+ return mir_tstrdup(ai->targv[4]);
+}
+
+static TCHAR *parseIflonger(ARGUMENTSINFO *ai) {
+
+ FORMATINFO fi;
+ TCHAR *tszFirst, *tszSecond;
+
+ if (ai->argc != 5) {
+ return NULL;
+ }
+ ZeroMemory(&fi, sizeof(fi));
+ memcpy(&fi, ai->fi, sizeof(fi));
+ fi.szFormat = ai->argv[1];
+ tszFirst = formatString(&fi);
+ fi.szFormat = ai->argv[2];
+ tszSecond = formatString(&fi);
+ if ((tszFirst == NULL) || (tszSecond == NULL)) {
+ if (tszFirst != NULL) {
+ mir_free(tszFirst);
+ }
+ if (tszSecond != NULL) {
+ mir_free(tszSecond);
+ }
+ return NULL;
+ }
+ if ( _tcslen(tszFirst) > _tcslen(tszSecond)) {
+ mir_free(tszFirst);
+ mir_free(tszSecond);
+ return mir_tstrdup(ai->targv[3]);
+ }
+ mir_free(tszFirst);
+ mir_free(tszSecond);
+
+ return mir_tstrdup(ai->targv[4]);
+}
+
+/*
+
+ ?for(init, cond, incr, show)
+
+ */
+static TCHAR *parseFor(ARGUMENTSINFO *ai) {
+
+ TCHAR *parsed, *res;
+ FORMATINFO fi;
+
+ if (ai->argc != 5) {
+ return NULL;
+ }
+ res = mir_tstrdup(_T(""));
+// ai->flags |= AIF_DONTPARSE;
+ ZeroMemory(&fi, sizeof(fi));
+ CopyMemory(&fi, ai->fi, sizeof(fi));
+ fi.eCount = fi.pCount = 0;
+ fi.tszFormat = ai->targv[1];
+ mir_free(formatString(&fi));
+ fi.tszFormat = ai->targv[2];
+ mir_free(formatString(&fi));
+ while (fi.eCount == 0) {
+ fi.tszFormat = ai->targv[4];
+ parsed = formatString(&fi);
+ if (parsed != NULL) {
+ if (res == NULL) {
+ res = (TCHAR*)mir_alloc( _tcslen(parsed)+1 * sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+ }
+ else res = (TCHAR*)mir_realloc(res, (_tcslen(res)+_tcslen(parsed)+1)*sizeof(TCHAR));
+
+ _tcscat(res, parsed);
+ }
+ fi.tszFormat = ai->targv[3];
+ mir_free(formatString(&fi));
+ fi.eCount = 0;
+ fi.tszFormat = ai->targv[2];
+ mir_free(formatString(&fi));
+ }
+
+ return res;
+}
+
+static TCHAR *parseEqual(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 3)
+ return NULL;
+
+ if (ttoi(ai->targv[1]) != ttoi( ai->targv[2] ))
+ ai->flags |= AIF_FALSE;
+
+ return mir_tstrdup(_T(""));
+}
+
+static TCHAR *parseGreater(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 3)
+ return NULL;
+
+ if (ttoi(ai->targv[1]) <= ttoi(ai->targv[2] ))
+ ai->flags |= AIF_FALSE;
+
+ return mir_tstrdup(_T(""));
+}
+
+static TCHAR *parseLonger(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 3)
+ return NULL;
+
+ if ( _tcslen(ai->targv[1]) <= _tcslen(ai->targv[2]))
+ ai->flags |= AIF_FALSE;
+
+ return mir_tstrdup(_T(""));
+}
+
+static TCHAR *parseNot(ARGUMENTSINFO *ai) {
+
+ FORMATINFO fi;
+ TCHAR *szCondition;
+
+ if (ai->argc != 2) {
+ return NULL;
+ }
+ ZeroMemory(&fi, sizeof(fi));
+ memcpy(&fi, ai->fi, sizeof(fi));
+ fi.tszFormat = ai->targv[1];
+ szCondition = formatString(&fi);
+ mir_free(szCondition);
+ //if (fi.pCount > 0) {
+ if (fi.eCount == 0) {
+ ai->flags |= AIF_FALSE;
+ }
+
+ return mir_tstrdup(_T(""));
+}
+
+static TCHAR *parseOr(ARGUMENTSINFO *ai) {
+
+ unsigned int i;
+ FORMATINFO fi;
+ TCHAR *szCondition;
+
+ if (ai->argc < 2) {
+ return NULL;
+ }
+ ZeroMemory(&fi, sizeof(fi));
+ memcpy(&fi, ai->fi, sizeof(fi));
+ ai->flags |= AIF_FALSE;
+ for(i=1;(i<ai->argc)&&(ai->flags&AIF_FALSE);i++) {
+ fi.tszFormat = ai->targv[i];
+ fi.eCount = 0;
+ szCondition = formatString(&fi);
+ mir_free(szCondition);
+ //if (fi.pCount > 0) {
+ if (fi.eCount == 0) {
+ ai->flags &= ~AIF_FALSE;
+ }
+ }
+
+ return mir_tstrdup(_T(""));
+}
+
+static TCHAR *parseTrue(ARGUMENTSINFO *ai) {
+
+ if (ai->argc != 1) {
+ return NULL;
+ }
+
+ return mir_tstrdup(_T(""));
+}
+
+static TCHAR *parseXor(ARGUMENTSINFO *ai) {
+
+ int val1, val2;
+ FORMATINFO fi;
+ TCHAR *szCondition;
+
+ if (ai->argc != 3) {
+ return NULL;
+ }
+ ZeroMemory(&fi, sizeof(fi));
+ memcpy(&fi, ai->fi, sizeof(fi));
+ ai->flags = AIF_FALSE;
+ fi.tszFormat = ai->targv[0];
+ szCondition = formatString(&fi);
+ mir_free(szCondition);
+ //val1 = fi.pCount > 0;
+ val1 = fi.eCount == 0;
+ fi.tszFormat = ai->targv[1];
+ szCondition = formatString(&fi);
+ mir_free(szCondition);
+ //val2 = fi.pCount > 0;
+ val2 = fi.eCount == 0;
+ ai->flags |= ((val1&AIF_FALSE)==!(val2&AIF_FALSE))?0:AIF_FALSE;
+
+ return mir_tstrdup(_T(""));
+}
+
+int registerLogicTokens() {
+
+ registerIntToken(_T(AND), parseAnd, TRF_UNPARSEDARGS|TRF_FUNCTION, "Logical Expressions\t(x,y, ...)\tperforms logical AND (x && y && ...)");
+ registerIntToken(_T(STR_FALSE), parseFalse, TRF_FIELD, "Logical Expressions\tBoolean FALSE");
+ registerIntToken(_T(FOR), parseFor, TRF_UNPARSEDARGS|TRF_FUNCTION, "Logical Expressions\t(w,x,y,z)\tperforms w, then shows z and performs y while x is TRUE");
+ registerIntToken(_T(IF), parseIf, TRF_UNPARSEDARGS|TRF_FUNCTION, "Logical Expressions\t(x,y,z)\tshows y if x is TRUE, otherwise it shows z");
+ registerIntToken(_T(IF2), parseIf2, TRF_UNPARSEDARGS|TRF_FUNCTION, "Logical Expressions\t(x,y)\tshows x if x is TRUE, otherwise it shows y (if(x,x,y))");
+ registerIntToken(_T(IF3), parseIf3, TRF_UNPARSEDARGS|TRF_FUNCTION, "Logical Expressions\t(x,y, ...)\tthe first argument parsed successfully");
+ registerIntToken(_T(IFEQUAL), parseIfequal, TRF_UNPARSEDARGS|TRF_FUNCTION, "Logical Expressions\t(w,x,y,z)\ty if w = x, else z");
+ registerIntToken(_T(IFGREATER), parseIfgreater, TRF_UNPARSEDARGS|TRF_FUNCTION, "Logical Expressions\t(w,x,y,z)\ty if w > x, else z");
+ registerIntToken(_T(IFLONGER), parseIflonger, TRF_UNPARSEDARGS|TRF_FUNCTION, "Logical Expressions\t(w,x,y,z)\ty if string length of w > x, else z");
+ registerIntToken(_T(EQUAL), parseEqual, TRF_FUNCTION, "Logical Expressions\t(x,y)\tTRUE if x = y");
+ registerIntToken(_T(GREATER), parseGreater, TRF_FUNCTION, "Logical Expressions\t(x,y)\tTRUE if x > y");
+ registerIntToken(_T(LONGER), parseLonger, TRF_FUNCTION, "Logical Expressions\t(x,y)\tTRUE if x is longer than y");
+ registerIntToken(_T(NOT), parseNot, TRF_UNPARSEDARGS|TRF_FUNCTION, "Logical Expressions\t(x)\tperforms logical NOT (!x)");
+ registerIntToken(_T(OR), parseOr, TRF_UNPARSEDARGS|TRF_FUNCTION, "Logical Expressions\t(x,y,...)\tperforms logical OR (x || y || ...)");
+ registerIntToken(_T(STR_TRUE), parseTrue, TRF_FIELD, "Logical Expressions\tBoolean TRUE");
+ registerIntToken(_T(XOR), parseXor, TRF_UNPARSEDARGS|TRF_FUNCTION, "Logical Expressions\t(x,y)\tperforms logical XOR (x ^ y)");
+
+ return 0;
+}
diff --git a/plugins/Variables/src/parse_logic.h b/plugins/Variables/src/parse_logic.h
new file mode 100644
index 0000000000..774a94b670
--- /dev/null
+++ b/plugins/Variables/src/parse_logic.h
@@ -0,0 +1,34 @@
+/*
+ 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
+*/
+#define AND "and"
+#define STR_FALSE "false"
+#define FOR "for"
+#define EQUAL "equal"
+#define GREATER "greater"
+#define IF "if"
+#define IF2 "if2"
+#define IF3 "if3"
+#define IFEQUAL "ifequal"
+#define IFGREATER "ifgreater"
+#define IFLONGER "iflonger"
+#define LONGER "longer"
+#define NOT "not"
+#define OR "or"
+#define STR_TRUE "true"
+#define XOR "xor"
diff --git a/plugins/Variables/src/parse_math.cpp b/plugins/Variables/src/parse_math.cpp
new file mode 100644
index 0000000000..c214898b5d
--- /dev/null
+++ b/plugins/Variables/src/parse_math.cpp
@@ -0,0 +1,225 @@
+/*
+ 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_math.h"
+
+static TCHAR *parseAdd(ARGUMENTSINFO *ai) {
+
+ unsigned int i;
+ int result;
+
+ if (ai->argc < 3) {
+ return NULL;
+ }
+ result = 0;
+ for (i=1;i<ai->argc;i++) {
+ result += ttoi(ai->targv[i]);
+ }
+ return itot(result);
+}
+
+static TCHAR *parseDiv(ARGUMENTSINFO *ai) {
+
+ int val1, val2;
+
+ if (ai->argc != 3) {
+ return NULL;
+ }
+
+ val1 = ttoi(ai->targv[1]);
+ val2 = ttoi(ai->targv[2]);
+ if (val2 == 0) {
+ return NULL;
+ }
+ return itot(val1/val2);
+}
+
+static TCHAR *parseHex(ARGUMENTSINFO *ai) {
+
+ int val;
+ unsigned int i, zeros;
+ int padding;
+ TCHAR *res, szVal[34];
+
+ if (ai->argc != 3)
+ return NULL;
+
+ val = ttoi(ai->targv[1]);
+ padding = ttoi(ai->targv[2]);
+ mir_sntprintf(szVal, SIZEOF(szVal), _T("%x"), val);
+ zeros = max(padding - (signed int)_tcslen(szVal), 0);
+ res = (TCHAR*)mir_alloc((zeros + _tcslen(szVal) + 3)*sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ ZeroMemory(res, (zeros + _tcslen(szVal) + 3)*sizeof(TCHAR));
+ _tcscpy(res, _T("0x"));
+ for (i=0;i<zeros;i++)
+ *(res+2+i) = _T('0');
+
+ _tcscat(res, szVal);
+ return res;
+}
+
+static TCHAR *parseMod(ARGUMENTSINFO *ai) {
+
+ int val1, val2;
+
+ if (ai->argc != 3) {
+ return NULL;
+ }
+ val1 = ttoi(ai->targv[1]);
+ val2 = ttoi(ai->targv[2]);
+ if (val2 == 0) {
+ return NULL;
+ }
+
+ return itot(val1%val2);
+}
+
+static TCHAR *parseMul(ARGUMENTSINFO *ai) {
+
+ unsigned int i;
+ int result;
+
+ if (ai->argc < 3) {
+ return NULL;
+ }
+ result = ttoi(ai->targv[1]);
+ for (i=2;i<ai->argc;i++) {
+ result *= ttoi(ai->targv[i]);
+ }
+
+ return itot(result);
+}
+
+static TCHAR *parseMuldiv(ARGUMENTSINFO *ai) {
+
+ if (ai->argc != 4) {
+ return NULL;
+ }
+ if (ttoi(ai->targv[3]) == 0) {
+ return NULL;
+ }
+
+ return itot((ttoi(ai->targv[1])*ttoi(ai->targv[2]))/ttoi(ai->targv[3]));
+}
+
+static TCHAR *parseMin(ARGUMENTSINFO *ai) {
+
+ unsigned int i;
+ int minVal;
+
+ if (ai->argc < 2) {
+ return NULL;
+ }
+ minVal = ttoi(ai->targv[1]);
+ for (i=2;i<ai->argc;i++) {
+ minVal = min(ttoi(ai->targv[i]), minVal);
+ }
+
+ return itot(minVal);
+}
+
+static TCHAR *parseMax(ARGUMENTSINFO *ai) {
+
+ unsigned int i;
+ int maxVal;
+
+ if (ai->argc < 2) {
+ return NULL;
+ }
+ maxVal = ttoi(ai->targv[1]);
+ for (i=2;i<ai->argc;i++) {
+ maxVal = max(ttoi(ai->targv[i]), maxVal);
+ }
+
+ return itot(maxVal);
+}
+
+static TCHAR *parseNum(ARGUMENTSINFO *ai) {
+
+ int val;
+ unsigned int zeros, i;
+ int padding;
+ TCHAR *res, *szVal, *cur;
+
+ if (ai->argc != 3)
+ return NULL;
+
+ val = ttoi(ai->targv[1]);
+ padding = ttoi(ai->targv[2]);
+ szVal = itot(val);
+ if (szVal == NULL)
+ return NULL;
+
+ zeros = max(padding - (signed int)_tcslen(szVal), 0);
+ res = (TCHAR*)mir_alloc((zeros + _tcslen(szVal) + 1)*sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ ZeroMemory(res, (zeros + _tcslen(szVal) + 1)*sizeof(TCHAR));
+ cur = res;
+ for (i=0;i<zeros;i++)
+ *cur++ = _T('0');
+
+ _tcscat(res, szVal);
+ mir_free(szVal);
+
+ return res;
+}
+
+static TCHAR *parseRand(ARGUMENTSINFO *ai) {
+
+ return itot(rand());
+}
+
+static TCHAR *parseSub(ARGUMENTSINFO *ai) {
+
+ unsigned int i;
+ int result;
+
+ if (ai->argc < 3) {
+ return NULL;
+ }
+ result = ttoi(ai->targv[1]);
+ for (i=2;i<ai->argc;i++) {
+ result -= ttoi(ai->targv[i]);
+ }
+
+ return itot(result);
+}
+
+int registerMathTokens() {
+
+ registerIntToken(_T(ADD), parseAdd, TRF_FUNCTION, "Mathematical Functions\t(x,y ,...)\tx + y + ...");
+ registerIntToken(_T(DIV), parseDiv, TRF_FUNCTION, "Mathematical Functions\t(x,y)\tx divided by y");
+ registerIntToken(_T(HEX), parseHex, TRF_FUNCTION, "Mathematical Functions\t(x,y)\tconverts decimal value x to hex value and padds to length y");
+ registerIntToken(_T(MOD), parseMod, TRF_FUNCTION, "Mathematical Functions\t(x,y)\tx modulo y (remainder of x divided by y)");
+ registerIntToken(_T(MUL), parseMul, TRF_FUNCTION, "Mathematical Functions\t(x,y)\tx times y");
+ registerIntToken(_T(MULDIV), parseMuldiv, TRF_FUNCTION, "Mathematical Functions\t(x,y,z)\tx times y divided by z");
+ registerIntToken(_T(MIN), parseMin, TRF_FUNCTION, "Mathematical Functions\t(x,y,...)\tminimum value of (decimal) arguments");
+ registerIntToken(_T(MAX), parseMax, TRF_FUNCTION, "Mathematical Functions\t(x,y,...)\tmaximum value of (decimal) arguments");
+ registerIntToken(_T(NUM), parseNum, TRF_FUNCTION, "Mathematical Functions\t(x,y)\tpads decimal value x to length y with zeros");
+ registerIntToken(_T(RAND), parseRand, TRF_FUNCTION, "Mathematical Functions\t()\trandom number");
+ registerIntToken(_T(SUB), parseSub, TRF_FUNCTION, "Mathematical Functions\t(x,y,...)\tx - y - ...");
+ srand((unsigned int)GetTickCount());
+
+ return 0;
+}
diff --git a/plugins/Variables/src/parse_math.h b/plugins/Variables/src/parse_math.h
new file mode 100644
index 0000000000..f185749399
--- /dev/null
+++ b/plugins/Variables/src/parse_math.h
@@ -0,0 +1,29 @@
+/*
+ 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
+*/
+#define ADD "add"
+#define DIV "div"
+#define HEX "hex"
+#define MOD "mod"
+#define MUL "mul"
+#define MULDIV "muldiv"
+#define MIN "min"
+#define MAX "max"
+#define NUM "num"
+#define RAND "rand"
+#define SUB "sub"
diff --git a/plugins/Variables/src/parse_metacontacts.cpp b/plugins/Variables/src/parse_metacontacts.cpp
new file mode 100644
index 0000000000..8831e7a192
--- /dev/null
+++ b/plugins/Variables/src/parse_metacontacts.cpp
@@ -0,0 +1,216 @@
+/*
+ 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_metacontacts.h"
+#include "contact.h"
+
+#include "m_metacontacts.h"
+
+static TCHAR *parseGetParent(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 2)
+ return NULL;
+
+ HANDLE hContact = NULL;
+
+ CONTACTSINFO ci = { 0 };
+ ci.cbSize = sizeof(ci);
+ ci.tszContact = ai->targv[1];
+ ci.flags = 0xFFFFFFFF ^ (CI_TCHAR == 0 ? CI_UNICODE : 0);
+ int count = getContactFromString( &ci );
+ if (count == 1 && ci.hContacts != NULL) {
+ hContact = ci.hContacts[0];
+ mir_free(ci.hContacts);
+ }
+ else {
+ if (ci.hContacts != NULL)
+ mir_free(ci.hContacts);
+ return NULL;
+ }
+
+ hContact = (HANDLE)CallService(MS_MC_GETMETACONTACT, (WPARAM)hContact, 0);
+ if (hContact == NULL)
+ return NULL;
+
+ TCHAR* res = NULL;
+ TCHAR* szUniqueID = NULL;
+ char* szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if (szProto != NULL)
+ szUniqueID = getContactInfoT(CNF_UNIQUEID, hContact);
+
+ if (szUniqueID == NULL)
+ {
+ szProto = PROTOID_HANDLE;
+ szUniqueID = (TCHAR*)mir_alloc(32);
+ _stprintf(szUniqueID, _T("%p"), hContact);
+ if (szProto == NULL || szUniqueID == NULL)
+ return NULL;
+ }
+
+ res = (TCHAR*)mir_alloc((strlen(szProto) + _tcslen(szUniqueID) + 4)*sizeof(TCHAR));
+ if (res == NULL) {
+ mir_free(szUniqueID);
+ return NULL;
+ }
+
+ TCHAR* tszProto;
+
+ tszProto = mir_a2t(szProto);
+
+
+ if (tszProto != NULL && szUniqueID != NULL) {
+ wsprintf(res, _T("<%s:%s>"), tszProto, szUniqueID);
+ mir_free(szUniqueID);
+ mir_free(tszProto);
+ }
+
+ return res;
+}
+
+static TCHAR *parseGetDefault(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 2)
+ return NULL;
+
+ HANDLE hContact = NULL;
+
+ CONTACTSINFO ci = { 0 };
+ ci.cbSize = sizeof(ci);
+ ci.tszContact = ai->targv[1];
+ ci.flags = 0xFFFFFFFF ^ (CI_TCHAR == 0 ? CI_UNICODE : 0);
+ int count = getContactFromString( &ci );
+ if (count == 1 && ci.hContacts != NULL) {
+ hContact = ci.hContacts[0];
+ mir_free(ci.hContacts);
+ }
+ else {
+ if (ci.hContacts != NULL)
+ mir_free(ci.hContacts);
+ return NULL;
+ }
+
+ hContact = (HANDLE)CallService(MS_MC_GETDEFAULTCONTACT, (WPARAM)hContact, 0);
+ if (hContact == NULL)
+ return NULL;
+
+ TCHAR* res = NULL;
+ TCHAR* szUniqueID = NULL;
+ char* szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if (szProto != NULL)
+ szUniqueID = getContactInfoT(CNF_UNIQUEID, hContact);
+
+ if (szUniqueID == NULL) {
+ szProto = PROTOID_HANDLE;
+ szUniqueID = (TCHAR*)mir_alloc(32);
+ _stprintf(szUniqueID, _T("%p"), hContact);
+ if (szProto == NULL || szUniqueID == NULL)
+ return NULL;
+ }
+
+ res = (TCHAR*)mir_alloc((strlen(szProto) + _tcslen(szUniqueID) + 4)*sizeof(TCHAR));
+ if (res == NULL) {
+ mir_free(szUniqueID);
+ return NULL;
+ }
+
+ TCHAR* tszProto;
+
+ tszProto = mir_a2t(szProto);
+
+
+ if (tszProto != NULL && szUniqueID != NULL) {
+ wsprintf(res, _T("<%s:%s>"), tszProto, szUniqueID);
+ mir_free(szUniqueID);
+ mir_free(tszProto);
+ }
+
+ return res;
+}
+
+static TCHAR *parseGetMostOnline(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 2)
+ return NULL;
+
+ HANDLE hContact = NULL;
+
+ CONTACTSINFO ci = { 0 };
+ ci.cbSize = sizeof(ci);
+ ci.tszContact = ai->targv[1];
+ ci.flags = 0xFFFFFFFF ^ (CI_TCHAR == 0 ? CI_UNICODE : 0);
+ int count = getContactFromString( &ci );
+ if (count == 1 && ci.hContacts != NULL) {
+ hContact = ci.hContacts[0];
+ mir_free( ci.hContacts );
+ }
+ else {
+ if (ci.hContacts != NULL)
+ mir_free( ci.hContacts );
+ return NULL;
+ }
+
+ hContact = (HANDLE)CallService(MS_MC_GETMOSTONLINECONTACT, (WPARAM)hContact, 0);
+ if (hContact == NULL)
+ return NULL;
+
+ TCHAR* res = NULL;
+ TCHAR* szUniqueID = NULL;
+ char* szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if (szProto != NULL)
+ szUniqueID = getContactInfoT(CNF_UNIQUEID, hContact);
+
+ if (szUniqueID == NULL) {
+ szProto = PROTOID_HANDLE;
+ szUniqueID = (TCHAR*)mir_alloc(32);
+ _stprintf(szUniqueID, _T("%p"), hContact);
+ if (szProto == NULL || szUniqueID == NULL)
+ return NULL;
+ }
+
+ res = (TCHAR*)mir_alloc((strlen(szProto) + _tcslen(szUniqueID) + 4)*sizeof(TCHAR));
+ if (res == NULL) {
+ mir_free(szUniqueID);
+ return NULL;
+ }
+
+ TCHAR* tszProto;
+
+ tszProto = mir_a2t(szProto);
+
+
+ if (tszProto != NULL && szUniqueID != NULL) {
+ wsprintf(res, _T("<%s:%s>"), tszProto, szUniqueID);
+ mir_free(szUniqueID);
+ mir_free(tszProto);
+ }
+
+ return res;
+}
+
+int registerMetaContactsTokens()
+{
+ if (ServiceExists( MS_MC_GETPROTOCOLNAME )) {
+ registerIntToken( _T(MC_GETPARENT), parseGetParent, TRF_FUNCTION, "MetaContacts\t(x)\tget parent metacontact of contact x");
+ registerIntToken( _T(MC_GETDEFAULT), parseGetDefault, TRF_FUNCTION, "MetaContacts\t(x)\tget default subcontact x");
+ registerIntToken( _T(MC_GETMOSTONLINE), parseGetMostOnline, TRF_FUNCTION, "MetaContacts\t(x)\tget the 'most online' subcontact x");
+ }
+
+ return 0;
+}
diff --git a/plugins/Variables/src/parse_metacontacts.h b/plugins/Variables/src/parse_metacontacts.h
new file mode 100644
index 0000000000..8015d40413
--- /dev/null
+++ b/plugins/Variables/src/parse_metacontacts.h
@@ -0,0 +1,22 @@
+/*
+ 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
+*/
+
+#define MC_GETPARENT "mc_getparent"
+#define MC_GETDEFAULT "mc_getdefault"
+#define MC_GETMOSTONLINE "mc_getmostonline"
diff --git a/plugins/Variables/src/parse_miranda.cpp b/plugins/Variables/src/parse_miranda.cpp
new file mode 100644
index 0000000000..926f7fb67b
--- /dev/null
+++ b/plugins/Variables/src/parse_miranda.cpp
@@ -0,0 +1,829 @@
+/*
+ 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_miranda.h"
+#include "contact.h"
+
+static TCHAR *parseCodeToStatus(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 2)
+ return NULL;
+
+ unsigned int status = ttoi(ai->targv[1]);
+ TCHAR *szStatus = (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)status, GSMDF_TCHAR);
+ if (szStatus != NULL)
+ return mir_tstrdup(szStatus);
+
+ return NULL;
+}
+
+static int getContactInfoFlags(TCHAR *tszDesc)
+{
+ TCHAR *cur;
+ int flags = 0;
+ for (cur=tszDesc;(cur < (tszDesc+_tcslen(tszDesc)));cur++) {
+ if (!_tcsnicmp(cur, _T(STR_PROTOID), _tcslen(_T(STR_PROTOID)))) {
+ flags|=CI_PROTOID;
+ cur += _tcslen(_T(STR_PROTOID)) - 1;
+ }
+ else if (!_tcsnicmp(cur, _T(STR_NICK), _tcslen(_T(STR_NICK)))) {
+ flags|=CI_NICK;
+ cur += _tcslen(_T(STR_NICK)) - 1;
+ }
+ else if (!_tcsnicmp(cur, _T(STR_FIRSTNAME), _tcslen(_T(STR_FIRSTNAME)))) {
+ flags|=CI_FIRSTNAME;
+ cur += _tcslen(_T(STR_FIRSTNAME)) - 1;
+ }
+ else if (!_tcsnicmp(cur, _T(STR_LASTNAME), _tcslen(_T(STR_LASTNAME)))) {
+ flags|=CI_LASTNAME;
+ cur += _tcslen(_T(STR_LASTNAME)) - 1;
+ }
+ else if (!_tcsnicmp(cur, _T(STR_DISPLAY), _tcslen(_T(STR_DISPLAY)))) {
+ flags|=CI_LISTNAME;
+ cur += _tcslen(_T(STR_DISPLAY)) - 1;
+ }
+ else if (!_tcsnicmp(cur, _T(STR_EMAIL), _tcslen(_T(STR_EMAIL)))) {
+ flags|=CI_EMAIL;
+ cur += _tcslen(_T(STR_EMAIL)) - 1;
+ }
+ else if (!_tcsnicmp(cur, _T(STR_UNIQUEID), _tcslen(_T(STR_UNIQUEID)))) {
+ flags|=CI_UNIQUEID;
+ cur += _tcslen(_T(STR_UNIQUEID)) - 1;
+ }
+ }
+ if (flags == 0) {
+ flags = getContactInfoType(tszDesc);
+ if (flags != 0)
+ flags |= CI_CNFINFO;
+ }
+ flags |= CI_TCHAR;
+
+ return flags;
+}
+
+static TCHAR *parseContact(ARGUMENTSINFO *ai)
+{
+ if (ai->argc < 3 || ai->argc > 4 )
+ return NULL;
+
+ int n = 0;
+ if (ai->argc == 4 && *ai->targv[3] != _T('r'))
+ n = ttoi(ai->targv[3]) - 1;
+
+ CONTACTSINFO ci = { 0 };
+ ci.cbSize = sizeof(ci);
+ ci.tszContact = ai->targv[1];
+ ci.flags = getContactInfoFlags(ai->targv[2]);
+ int count = getContactFromString( &ci );
+ if (count == 0 || ci.hContacts == NULL)
+ return NULL;
+
+ if (ai->argc == 4 && *ai->targv[3] == _T('r'))
+ n = rand() % count;
+
+ if (count != 1 && ai->argc != 4 ) {
+ mir_free(ci.hContacts);
+ return NULL;
+ }
+ HANDLE hContact = ci.hContacts[n];
+ log_debugA("contact: %x", hContact);
+ mir_free(ci.hContacts);
+
+ return encodeContactToString(hContact);
+}
+
+static TCHAR *parseContactCount(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 3)
+ return NULL;
+
+ CONTACTSINFO ci = { 0 };
+ ci.cbSize = sizeof(ci);
+ ci.tszContact = ai->targv[1];
+ ci.flags = getContactInfoFlags(ai->targv[2]);
+ int count = getContactFromString( &ci );
+ if (count != 0 && ci.hContacts != NULL)
+ mir_free(ci.hContacts);
+
+ return itot(count);
+}
+
+static TCHAR *parseContactInfo(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 3)
+ return NULL;
+
+ HANDLE hContact = NULL;
+ CONTACTSINFO ci = { 0 };
+ ci.cbSize = sizeof(ci);
+ ci.tszContact = ai->targv[1];
+ ci.flags = 0xFFFFFFFF ^ (CI_TCHAR == 0 ? CI_UNICODE : 0);
+ int count = getContactFromString( &ci );
+ if (count == 1 && ci.hContacts != NULL) {
+ hContact = ci.hContacts[0];
+ mir_free(ci.hContacts);
+ }
+ else {
+ mir_free(ci.hContacts);
+ return NULL;
+ }
+ BYTE type = getContactInfoType(ai->targv[2]);
+ if (type == 0)
+ return NULL;
+
+ return getContactInfoT(type, hContact);
+}
+
+static TCHAR *parseDBProfileName(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 1)
+ return NULL;
+
+ TCHAR name[MAX_PATH];
+ if (CallService(MS_DB_GETPROFILENAMET, SIZEOF(name), (LPARAM)name))
+ return NULL;
+
+ return mir_tstrdup(name);
+}
+
+static TCHAR *parseDBProfilePath(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 1)
+ return NULL;
+
+ TCHAR path[MAX_PATH];
+ if (CallService(MS_DB_GETPROFILEPATHT, SIZEOF(path), (LPARAM)path))
+ return NULL;
+
+ return mir_tstrdup(path);
+}
+
+static TCHAR* getDBSetting(HANDLE hContact, char* module, char* setting, TCHAR* defaultValue)
+{
+ DBVARIANT dbv;
+ if (DBGetContactSettingW(hContact, module, setting, &dbv))
+ return defaultValue;
+
+ TCHAR* var = NULL;
+ switch (dbv.type) {
+ case DBVT_BYTE:
+ var = itot(dbv.bVal);
+ break;
+ case DBVT_WORD:
+ var = itot(dbv.wVal);
+ break;
+ case DBVT_DWORD:
+ var = itot(dbv.dVal);
+ break;
+ case DBVT_ASCIIZ:
+ var = mir_a2t(dbv.pszVal);
+ break;
+ case DBVT_WCHAR:
+ var = mir_wstrdup(dbv.pwszVal);
+ break;
+ case DBVT_UTF8:
+ Utf8Decode(dbv.pszVal, &var);
+ break;
+ }
+
+ DBFreeVariant(&dbv);
+ return var;
+}
+
+static TCHAR *parseDBSetting(ARGUMENTSINFO *ai)
+{
+ if (ai->argc < 4)
+ return NULL;
+
+ TCHAR *res = NULL, *szDefaultValue = NULL;
+ HANDLE hContact = NULL;
+
+ if ( _tcslen(ai->targv[1]) > 0) {
+ CONTACTSINFO ci = { 0 };
+ ci.cbSize = sizeof(ci);
+ ci.tszContact = ai->targv[1];
+ ci.flags = 0xFFFFFFFF^(CI_TCHAR==0?CI_UNICODE:0);
+ int count = getContactFromString( &ci );
+ if (count == 1 && ci.hContacts != NULL) {
+ hContact = ci.hContacts[0];
+ mir_free(ci.hContacts);
+ }
+ else {
+ mir_free(ci.hContacts);
+ return NULL;
+ }
+ }
+
+ char *szModule = mir_t2a(ai->targv[2]);
+ char *szSetting = mir_t2a(ai->targv[3]);
+
+ if (ai->argc > 4 && _tcslen(ai->targv[4]) > 0)
+ szDefaultValue = mir_tstrdup(ai->targv[4]);
+
+ if (szModule != NULL && szSetting != NULL) {
+ res = getDBSetting(hContact, szModule, szSetting, szDefaultValue);
+ mir_free(szModule);
+ mir_free(szSetting);
+ }
+ return res;
+}
+
+static TCHAR *parseLastSeenDate(ARGUMENTSINFO *ai)
+{
+ if (ai->argc <= 1)
+ return NULL;
+
+ HANDLE hContact = NULL;
+ CONTACTSINFO ci = { 0 };
+ ci.cbSize = sizeof(ci);
+ ci.tszContact = ai->targv[1];
+ ci.flags = 0xFFFFFFFF^(CI_TCHAR==0?CI_UNICODE:0);
+ int count = getContactFromString( &ci );
+ if (count == 1 && ci.hContacts != NULL) {
+ hContact = ci.hContacts[0];
+ mir_free(ci.hContacts);
+ }
+ else {
+ if (ci.hContacts != NULL)
+ mir_free(ci.hContacts);
+ return NULL;
+ }
+
+ TCHAR *szFormat;
+ if (ai->argc == 2 || (ai->argc > 2 && _tcslen(ai->targv[2]) == 0))
+ szFormat = NULL;
+ else
+ szFormat = ai->targv[2];
+
+ SYSTEMTIME lsTime = { 0 };
+ char *szModule = CEX_MODULE;
+ lsTime.wYear = DBGetContactSettingWord(hContact, szModule, "Year", 0);
+ if (lsTime.wYear == 0)
+ szModule = SEEN_MODULE;
+
+ lsTime.wYear = DBGetContactSettingWord(hContact, szModule, "Year", 0);
+ if (lsTime.wYear == 0)
+ return NULL;
+
+ lsTime.wMilliseconds = 0;
+ lsTime.wSecond = DBGetContactSettingWord(hContact, szModule, "Seconds", 0);
+ lsTime.wMinute = DBGetContactSettingWord(hContact, szModule, "Minutes", 0);
+ lsTime.wHour = DBGetContactSettingWord(hContact, szModule, "Hours", 0);
+ lsTime.wDay = DBGetContactSettingWord(hContact, szModule, "Day", 0);
+ lsTime.wDayOfWeek = DBGetContactSettingWord(hContact, szModule, "WeekDay", 0);
+ lsTime.wMonth = DBGetContactSettingWord(hContact, szModule, "Month", 0);
+
+ int len = GetDateFormat(LOCALE_USER_DEFAULT, 0, &lsTime, szFormat, NULL, 0);
+ TCHAR *res = (TCHAR*)mir_alloc((len+1)*sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &lsTime, szFormat, res, len) == 0) {
+ mir_free(res);
+ return NULL;
+ }
+
+ return res;
+}
+
+static TCHAR *parseLastSeenTime(ARGUMENTSINFO *ai)
+{
+ if (ai->argc <= 1)
+ return NULL;
+
+ HANDLE hContact = NULL;
+
+ CONTACTSINFO ci = { 0 };
+ ci.cbSize = sizeof(ci);
+ ci.tszContact = ai->targv[1];
+ ci.flags = 0xFFFFFFFF^(CI_TCHAR==0?CI_UNICODE:0);
+ int count = getContactFromString( &ci );
+ if (count == 1 && ci.hContacts != NULL) {
+ hContact = ci.hContacts[0];
+ mir_free(ci.hContacts);
+ }
+ else {
+ mir_free(ci.hContacts);
+ return NULL;
+ }
+
+ TCHAR *szFormat;
+ if (ai->argc == 2 || (ai->argc > 2 && _tcslen(ai->targv[2]) == 0))
+ szFormat = NULL;
+ else
+ szFormat = ai->targv[2];
+
+ SYSTEMTIME lsTime = { 0 };
+ char *szModule = CEX_MODULE;
+ lsTime.wYear = DBGetContactSettingWord(hContact, szModule, "Year", 0);
+ if (lsTime.wYear == 0)
+ szModule = SEEN_MODULE;
+
+ lsTime.wYear = DBGetContactSettingWord(hContact, szModule, "Year", 0);
+ if (lsTime.wYear == 0)
+ return NULL;
+
+ lsTime.wMilliseconds = 0;
+ lsTime.wSecond = DBGetContactSettingWord(hContact, szModule, "Seconds", 0);
+ lsTime.wMinute = DBGetContactSettingWord(hContact, szModule, "Minutes", 0);
+ lsTime.wHour = DBGetContactSettingWord(hContact, szModule, "Hours", 0);
+ lsTime.wDay = DBGetContactSettingWord(hContact, szModule, "Day", 0);
+ lsTime.wDayOfWeek = DBGetContactSettingWord(hContact, szModule, "WeekDay", 0);
+ lsTime.wMonth = DBGetContactSettingWord(hContact, szModule, "Month", 0);
+ lsTime.wYear = DBGetContactSettingWord(hContact, szModule, "Year", 0);
+
+ int len = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &lsTime, szFormat, NULL, 0);
+ TCHAR *res = (TCHAR*)mir_alloc((len+1)*sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ if (GetTimeFormat(LOCALE_USER_DEFAULT, 0, &lsTime, szFormat, res, len) == 0) {
+ mir_free(res);
+ return NULL;
+ }
+
+ return res;
+}
+
+static TCHAR *parseLastSeenStatus(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 2)
+ return NULL;
+
+ HANDLE hContact = NULL;
+ CONTACTSINFO ci = { 0 };
+ ci.cbSize = sizeof(ci);
+ ci.tszContact = ai->targv[1];
+ ci.flags = 0xFFFFFFFF^(CI_TCHAR==0?CI_UNICODE:0);
+ int count = getContactFromString( &ci );
+ if ((count == 1) && (ci.hContacts != NULL)) {
+ hContact = ci.hContacts[0];
+ mir_free(ci.hContacts);
+ }
+ else {
+ mir_free(ci.hContacts);
+ return NULL;
+ }
+ char *szModule = CEX_MODULE;
+ int status = DBGetContactSettingWord(hContact, szModule, "Status", 0);
+ if (status == 0)
+ szModule = SEEN_MODULE;
+
+ status = DBGetContactSettingWord(hContact, szModule, "Status", 0);
+ if (status == 0)
+ return NULL;
+
+ TCHAR *szStatus = (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)status, GSMDF_TCHAR);
+ if (szStatus != NULL)
+ return mir_tstrdup(szStatus);
+
+ return NULL;
+}
+
+static TCHAR *parseMirandaPath(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 1)
+ return NULL;
+
+ ai->flags |= AIF_DONTPARSE;
+ TCHAR path[MAX_PATH];
+ if (GetModuleFileName(NULL, path, SIZEOF(path)) == 0)
+ return NULL;
+
+ return mir_tstrdup(path);
+}
+
+static TCHAR *parseMyStatus(ARGUMENTSINFO *ai)
+{
+ if (ai->argc > 2)
+ return NULL;
+
+ int status;
+ if (ai->argc == 1 || _tcslen(ai->targv[1]) == 0 )
+ status = CallService(MS_CLIST_GETSTATUSMODE, 0, 0);
+ else
+ status = CallProtoService( _T2A(ai->targv[1]), PS_GETSTATUS, 0, 0);
+
+ TCHAR *szStatus = (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)status, GSMDF_UNICODE);
+ if (szStatus != NULL)
+ return mir_tstrdup(szStatus);
+
+ return NULL;
+}
+
+static TCHAR *parseProtoInfo(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 3)
+ return NULL;
+
+ char *szRes = NULL;
+ TCHAR *tszRes = NULL;
+ char *szProto = mir_t2a(ai->targv[1]);
+
+ if (!_tcscmp(ai->targv[2], _T(STR_PINAME)))
+ tszRes = Hlp_GetProtocolName(szProto);
+ else if (!_tcscmp(ai->targv[2], _T(STR_PIUIDTEXT))) {
+ if (!ProtoServiceExists(szProto, PS_GETCAPS))
+ return NULL;
+
+ char *szText = (char *)CallProtoService(szProto, PS_GETCAPS, (WPARAM)PFLAG_UNIQUEIDTEXT, 0);
+ if (szText != NULL)
+ szRes = _strdup(szText);
+ }
+ else if (!_tcscmp(ai->targv[2], _T(STR_PIUIDSETTING))) {
+ if (!ProtoServiceExists(szProto, PS_GETCAPS))
+ return NULL;
+
+ char *szText = (char *)CallProtoService(szProto, PS_GETCAPS, (WPARAM)PFLAG_UNIQUEIDSETTING, 0);
+ if (szText != NULL)
+ szRes = _strdup(szText);
+ }
+ mir_free(szProto);
+ if (szRes == NULL && tszRes == NULL)
+ return NULL;
+
+ if (szRes != NULL && tszRes == NULL) {
+ tszRes = mir_a2t(szRes);
+ mir_free(szRes);
+ }
+ else if (szRes != NULL && tszRes != NULL)
+ mir_free(szRes);
+
+ return tszRes;
+}
+
+static TCHAR *parseSpecialContact(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 1 || ai->fi->hContact == NULL)
+ return NULL;
+
+ ai->flags |= AIF_DONTPARSE;
+ TCHAR *res = NULL;
+ TCHAR *szUniqueID = NULL;
+ char *szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)ai->fi->hContact, 0);
+ if (szProto != NULL)
+ szUniqueID = getContactInfoT(CNF_UNIQUEID, ai->fi->hContact);
+
+ if (szUniqueID == NULL) {
+ szProto = PROTOID_HANDLE;
+ szUniqueID = (TCHAR*)mir_alloc(32);
+ _stprintf(szUniqueID, _T("%p"), ai->fi->hContact);
+ if (szProto == NULL || szUniqueID == NULL)
+ return NULL;
+ }
+
+ res = (TCHAR*)mir_alloc((strlen(szProto) + _tcslen(szUniqueID) + 4)*sizeof(TCHAR));
+ if (res == NULL) {
+ mir_free(szUniqueID);
+ return NULL;
+ }
+
+ TCHAR *tszProto = mir_a2t(szProto);
+ if (tszProto != NULL && szUniqueID != NULL) {
+ wsprintf(res, _T("<%s:%s>"), tszProto, szUniqueID);
+ mir_free(szUniqueID);
+ mir_free(tszProto);
+ }
+
+ return res;
+}
+
+static BOOL isValidDbEvent(DBEVENTINFO *dbe, int flags)
+{
+ BOOL bEventType, bEventFlags;
+
+ bEventType = ((dbe->eventType == EVENTTYPE_MESSAGE) && (flags&DBE_MESSAGE)) ||
+ ((dbe->eventType == EVENTTYPE_URL) && (flags&DBE_URL)) ||
+ ((dbe->eventType == EVENTTYPE_CONTACTS) && (flags&DBE_CONTACTS)) ||
+ ((dbe->eventType == EVENTTYPE_ADDED) && (flags&DBE_ADDED)) ||
+ ((dbe->eventType == EVENTTYPE_AUTHREQUEST) && (flags&DBE_AUTHREQUEST)) ||
+ ((dbe->eventType == EVENTTYPE_FILE) && (flags&DBE_FILE)) ||
+ ((dbe->eventType == EVENTTYPE_STATUSCHANGE) && (flags&DBE_STATUSCHANGE)) ||
+ ((flags&DBE_OTHER));
+ bEventFlags = (dbe->flags&DBEF_SENT)?(flags&DBE_SENT):(flags&DBE_RCVD);
+ bEventFlags = (bEventFlags && ((dbe->flags&DBEF_READ)?(flags&DBE_READ):(flags&DBE_UNREAD)));
+
+ return (bEventType && bEventFlags);
+}
+
+static HANDLE findDbEvent(HANDLE hContact, HANDLE hDbEvent, int flags)
+{
+ DBEVENTINFO dbe;
+ BOOL bEventOk;
+
+ do {
+ ZeroMemory(&dbe, sizeof(DBEVENTINFO));
+ dbe.cbSize = sizeof(DBEVENTINFO);
+ dbe.cbBlob = 0;
+ dbe.pBlob = NULL;
+ if (hContact != NULL) {
+ if ((flags & DBE_FIRST) && (flags & DBE_UNREAD)) {
+ hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDFIRSTUNREAD, (WPARAM)hContact, 0);
+ if (hDbEvent == NULL && (flags & DBE_READ))
+ hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDFIRST, (WPARAM)hContact, 0);
+ }
+ else if (flags & DBE_FIRST)
+ hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDFIRST, (WPARAM)hContact, 0);
+ else if (flags & DBE_LAST)
+ hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDLAST, (WPARAM)hContact, 0);
+ else if (flags & DBE_NEXT)
+ hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDNEXT, (WPARAM)hDbEvent, 0);
+ else if (flags & DBE_PREV)
+ hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDPREV, (WPARAM)hDbEvent, 0);
+ }
+ else {
+ HANDLE hMatchEvent, hSearchEvent, hSearchContact;
+ DWORD matchTimestamp, priorTimestamp;
+
+ hMatchEvent = hSearchEvent = hSearchContact = NULL;
+ matchTimestamp = priorTimestamp = 0;
+ if (flags & DBE_FIRST) {
+ hSearchContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ do {
+ hSearchEvent = findDbEvent(hSearchContact, NULL, flags);
+ dbe.cbBlob = 0;
+ if (!CallService(MS_DB_EVENT_GET, (WPARAM)hSearchEvent, (LPARAM)&dbe)) {
+ if ((dbe.timestamp < matchTimestamp) || (matchTimestamp == 0)) {
+ hMatchEvent = hSearchEvent;
+ matchTimestamp = dbe.timestamp;
+ }
+ }
+ hSearchContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hSearchContact, 0);
+ } while (hSearchContact);
+ hDbEvent = hMatchEvent;
+ }
+ else if (flags&DBE_LAST) {
+ hSearchContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ do {
+ hSearchEvent = findDbEvent(hSearchContact, NULL, flags);
+ dbe.cbBlob = 0;
+ if (!CallService(MS_DB_EVENT_GET, (WPARAM)hSearchEvent, (LPARAM)&dbe)) {
+ if ((dbe.timestamp > matchTimestamp) || (matchTimestamp == 0)) {
+ hMatchEvent = hSearchEvent;
+ matchTimestamp = dbe.timestamp;
+ }
+ }
+ hSearchContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hSearchContact, 0);
+ } while (hSearchContact);
+ hDbEvent = hMatchEvent;
+ }
+ else if (flags&DBE_NEXT) {
+ dbe.cbBlob = 0;
+ if (!CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbe)) {
+ priorTimestamp = dbe.timestamp;
+ hSearchContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ do {
+ hSearchEvent = findDbEvent(hSearchContact, hDbEvent, flags);
+ dbe.cbBlob = 0;
+ if (!CallService(MS_DB_EVENT_GET, (WPARAM)hSearchEvent, (LPARAM)&dbe)) {
+ if (((dbe.timestamp < matchTimestamp) || (matchTimestamp == 0)) && (dbe.timestamp > priorTimestamp)) {
+ hMatchEvent = hSearchEvent;
+ matchTimestamp = dbe.timestamp;
+ }
+ }
+ hSearchContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hSearchContact, 0);
+ } while (hSearchContact);
+ hDbEvent = hMatchEvent;
+ }
+ }
+ else if (flags&DBE_PREV) {
+ if (!CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbe)) {
+ priorTimestamp = dbe.timestamp;
+ hSearchContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ do {
+ hSearchEvent = findDbEvent(hSearchContact, hDbEvent, flags);
+ dbe.cbBlob = 0;
+ if (!CallService(MS_DB_EVENT_GET, (WPARAM)hSearchEvent, (LPARAM)&dbe)) {
+ if (((dbe.timestamp > matchTimestamp) || (matchTimestamp == 0)) && (dbe.timestamp < priorTimestamp)) {
+ hMatchEvent = hSearchEvent;
+ matchTimestamp = dbe.timestamp;
+ }
+ }
+ hSearchContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hSearchContact, 0);
+ } while (hSearchContact);
+ hDbEvent = hMatchEvent;
+ }
+ }
+ }
+ dbe.cbBlob = 0;
+ if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbe))
+ bEventOk = FALSE;
+ else
+ bEventOk = isValidDbEvent(&dbe, flags);
+ if (!bEventOk) {
+ if (flags&DBE_FIRST) {
+ flags |= DBE_NEXT;
+ flags &= ~DBE_FIRST;
+ }
+ else if (flags&DBE_LAST) {
+ flags |= DBE_PREV;
+ flags &= ~DBE_LAST;
+ }
+ }
+ }
+ while ( (!bEventOk) && (hDbEvent != NULL));
+
+ return hDbEvent;
+}
+
+// ?message(%subject%,last|first,sent|recv,read|unread)
+static TCHAR *parseDbEvent(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 5)
+ return NULL;
+
+ int flags = DBE_MESSAGE;
+ switch (*ai->targv[2]) {
+ case _T('f'):
+ flags |= DBE_FIRST;
+ break;
+ default:
+ flags |= DBE_LAST;
+ break;
+ }
+ switch (*ai->targv[3]) {
+ case _T('s'):
+ flags |= DBE_SENT;
+ break;
+ case _T('r'):
+ flags |= DBE_RCVD;
+ break;
+ default:
+ flags |= DBE_RCVD|DBE_SENT;
+ break;
+ }
+ switch (*ai->targv[4]) {
+ case _T('r'):
+ flags |= DBE_READ;
+ break;
+ case _T('u'):
+ flags |= DBE_UNREAD;
+ break;
+ default:
+ flags |= DBE_READ|DBE_UNREAD;
+ break;
+ }
+
+ HANDLE hContact = NULL;
+
+ CONTACTSINFO ci = { 0 };
+ ci.cbSize = sizeof(ci);
+ ci.tszContact = ai->targv[1];
+ ci.flags = 0xFFFFFFFF^(CI_TCHAR==0?CI_UNICODE:0);
+ int count = getContactFromString( &ci );
+ if ((count == 1) && (ci.hContacts != NULL)) {
+ hContact = ci.hContacts[0];
+ mir_free(ci.hContacts);
+ }
+ else if (ci.hContacts != NULL)
+ mir_free(ci.hContacts);
+
+ HANDLE hDbEvent = findDbEvent(hContact, NULL, flags);
+ if (hDbEvent == NULL)
+ return NULL;
+
+ DBEVENTINFO dbe = { 0 };
+ dbe.cbSize = sizeof(DBEVENTINFO);
+ dbe.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0);
+ dbe.pBlob = (PBYTE)mir_calloc(dbe.cbBlob);
+ if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbe)) {
+ mir_free(dbe.pBlob);
+ return NULL;
+ }
+
+ TCHAR *res = DbGetEventTextT(&dbe, CP_ACP);
+ mir_free(dbe.pBlob);
+ return res;
+}
+
+static TCHAR *parseTranslate(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 2)
+ return NULL;
+
+ TCHAR* res = TranslateTS(ai->targv[1]);
+ return (res == NULL) ? NULL : mir_tstrdup(res);
+}
+
+static TCHAR *parseVersionString(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 1)
+ return NULL;
+
+ ai->flags |= AIF_DONTPARSE;
+ char versionString[128];
+ if (CallService(MS_SYSTEM_GETVERSIONTEXT, (WPARAM)sizeof(versionString), (LPARAM)versionString))
+ return NULL;
+
+ return mir_a2t(versionString);
+}
+
+static TCHAR *parseContactNameString(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 1 || ai->fi->hContact == NULL)
+ return NULL;
+
+ ai->flags |= AIF_DONTPARSE;
+ TCHAR *ret = (TCHAR*) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) ai->fi->hContact, GCDNF_TCHAR);
+ if (ret == NULL)
+ return NULL;
+
+ return mir_tstrdup(ret);
+}
+
+static TCHAR *parseMirDateString(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 1)
+ return NULL;
+
+ ai->flags |= AIF_DONTPARSE;
+
+ TCHAR ret[128];
+ DBTIMETOSTRINGT tst = {0};
+ tst.szFormat = _T("d s");
+ tst.szDest = ret;
+ tst.cbDest = 128;
+ if (CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, (WPARAM) time(NULL), (LPARAM) &tst))
+ return NULL;
+
+ return mir_tstrdup(ret);
+}
+
+static TCHAR *parseMirandaCoreVar(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 1)
+ return NULL;
+
+ ai->flags |= AIF_DONTPARSE;
+
+ TCHAR corevar[MAX_PATH];
+ mir_sntprintf(corevar, MAX_PATH,_T("%%%s%%"), ai->targv[0]);
+ return Utils_ReplaceVarsT(corevar);
+}
+
+static TCHAR *parseMirSrvExists(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 2 )
+ return NULL;
+
+ if (!ServiceExists( _T2A( ai->targv[1] )))
+ ai->flags |= AIF_FALSE;
+
+ return mir_tstrdup(_T(""));
+}
+
+int registerMirandaTokens() {
+ if (ServiceExists(MS_UTILS_REPLACEVARS)) {
+ // global vars
+ registerIntToken(_T("miranda_path"), parseMirandaCoreVar , TRF_FIELD, "Miranda Core Global\tpath to root miranda folder");
+ registerIntToken(_T("miranda_profile"), parseMirandaCoreVar , TRF_FIELD, "Miranda Core Global\tpath to current miranda profile");
+ registerIntToken(_T("miranda_profilename"), parseMirandaCoreVar , TRF_FIELD, "Miranda Core Global\tname of current miranda profile (filename, without extension)");
+ registerIntToken(_T("miranda_userdata"), parseMirandaCoreVar , TRF_FIELD, "Miranda Core Global\twill return parsed string %miranda_profile%\\Profiles\\%miranda_profilename%");
+ registerIntToken(_T("miranda_avatarcache"), parseMirandaCoreVar , TRF_FIELD, "Miranda Core Global\twill return parsed string %miranda_profile%\\Profiles\\%miranda_profilename%\\AvatarCache");
+ registerIntToken(_T("miranda_logpath"), parseMirandaCoreVar , TRF_FIELD, "Miranda Core Global\twill return parsed string %miranda_profile%\\Profiles\\%miranda_profilename%\\Logs");
+
+ // OS vars
+ registerIntToken(_T("appdata"), parseMirandaCoreVar , TRF_FIELD, "Miranda Core OS\tsame as environment variable %APPDATA% for currently logged-on Windows user");
+ registerIntToken(_T("username"), parseMirandaCoreVar , TRF_FIELD, "Miranda Core OS\tusername for currently logged-on Windows user");
+ registerIntToken(_T("mydocuments"), parseMirandaCoreVar , TRF_FIELD, "Miranda Core OS\t\"My Documents\" folder for currently logged-on Windows user");
+ registerIntToken(_T("desktop"), parseMirandaCoreVar , TRF_FIELD, "Miranda Core OS\t\"Desktop\" folder for currently logged-on Windows user");
+ }
+ registerIntToken(_T(CODETOSTATUS), parseCodeToStatus, TRF_FUNCTION, "Miranda Related\t(x)\ttranslates status code x into a status description");
+ registerIntToken(_T(CONTACT), parseContact, TRF_FUNCTION, "Miranda Related\t(x,y,z)\tzth contact with property y described by x, example: (unregistered,nick) (z is optional)");
+ registerIntToken(_T(CONTACTCOUNT), parseContactCount, TRF_FUNCTION, "Miranda Related\t(x,y)\tnumber of contacts with property y described by x, example: (unregistered,nick)");
+ registerIntToken(_T(CONTACTINFO), parseContactInfo, TRF_FUNCTION, "Miranda Related\t(x,y)\tinfo property y of contact x");
+ registerIntToken(_T(DBPROFILENAME), parseDBProfileName, TRF_FIELD, "Miranda Related\tdb profile name");
+ registerIntToken(_T(DBPROFILEPATH), parseDBProfilePath, TRF_FIELD, "Miranda Related\tdb profile path");
+ registerIntToken(_T(DBSETTING), parseDBSetting, TRF_FUNCTION, "Miranda Related\t(x,y,z,w)\tdb setting z of module y of contact x and return w if z isn't exist (w is optional)");
+ registerIntToken(_T(DBEVENT), parseDbEvent, TRF_FUNCTION, "Miranda Related\t(x,y,z,w)\tget event for contact x (optional), according to y,z,w, see documentation");
+ registerIntToken(_T(LSTIME), parseLastSeenTime, TRF_FUNCTION, "Miranda Related\t(x,y)\tget last seen time of contact x in format y (y is optional)");
+ registerIntToken(_T(LSDATE), parseLastSeenDate, TRF_FUNCTION, "Miranda Related\t(x,y)\tget last seen date of contact x in format y (y is optional)");
+ registerIntToken(_T(LSSTATUS), parseLastSeenStatus, TRF_FUNCTION, "Miranda Related\t(x)\tget last seen status of contact x");
+ registerIntToken(_T(MIRANDAPATH), parseMirandaPath, TRF_FIELD, "Miranda Related\tpath to the Miranda-IM executable");
+ registerIntToken(_T(MYSTATUS), parseMyStatus, TRF_FUNCTION, "Miranda Related\t(x)\tcurrent status description of protocol x (without x, the global status is retrieved)");
+ registerIntToken(_T(PROTOINFO), parseProtoInfo, TRF_FUNCTION, "Miranda Related\t(x,y)\tinfo property y of protocol id x");
+ registerIntToken(_T(SUBJECT), parseSpecialContact, TRF_FIELD, "Miranda Related\tretrieves the subject, depending on situation");
+ registerIntToken(_T(TRANSLATE), parseTranslate, TRF_FUNCTION, "Miranda Related\t(x)\ttranslates x");
+ registerIntToken(_T(VERSIONSTRING), parseVersionString, TRF_FIELD, "Miranda Related\tget the version of Miranda");
+ registerIntToken(_T(CONTACT_NAME), parseContactNameString, TRF_FIELD, "Miranda Related\tget the contact display name");
+ registerIntToken(_T(MIR_DATE), parseMirDateString, TRF_FIELD, "Miranda Related\tget the date and time (using Miranda format)");
+ registerIntToken(_T(SRVEXISTS), parseMirSrvExists, TRF_FUNCTION, "Miranda Related\t(x)\tTRUE if service function is exists");
+
+ return 0;
+}
diff --git a/plugins/Variables/src/parse_miranda.h b/plugins/Variables/src/parse_miranda.h
new file mode 100644
index 0000000000..0d429d67bb
--- /dev/null
+++ b/plugins/Variables/src/parse_miranda.h
@@ -0,0 +1,88 @@
+/*
+ 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
+*/
+#define VERSIONSTRING "mirandaversion"
+#define CODETOSTATUS "code2status"
+#define CONTACT "contact"
+#define CONTACTCOUNT "ccount"
+#define CONTACTINFO "cinfo"
+#define DBPROFILENAME "dbprofile"
+#define DBPROFILEPATH "dbprofilepath"
+#define DBSETTING "dbsetting"
+#define LSDATE "lsdate"
+#define LSTIME "lstime"
+#define LSSTATUS "lsstatus"
+//#define SUBJECT "subject" // defined in variables.h
+#define MIRANDAPATH "mirandapath"
+#define MYSTATUS "mstatus"
+#define DBEVENT "message" // may be extended later
+//#define PROTONAME "protoname" // depreciated
+#define PROTOINFO "pinfo"
+#define TRANSLATE "translate"
+#define CONTACT_NAME "contactname"
+#define MIR_DATE "date"
+#define SRVEXISTS "srvexists"
+
+#define STR_PINAME "name"
+#define STR_PIUIDTEXT "uidtext"
+#define STR_PIUIDSETTING "uidsetting"
+
+#define CEX_MODULE "ContactsEx"
+#define SEEN_MODULE "SeenModule"
+
+#define STR_PROTOID "protoid"
+#define STR_FIRST "first"
+#define STR_LAST "last"
+#define STR_SENT "sent"
+#define STR_RCVD "recv"
+#define STR_READ "read"
+#define STR_UNREAD "unread"
+
+/* dbevent flags */
+/* these flags must contain:
+DBE_FIRST|DBE_LAST|DBE_NEXT|DBE_PREV
+and
+DBE_SENT|DBE_RCVD
+and
+DBE_READ|DBE_UNREAD
+and
+DBE_MESSAGE|DBE_URL|DBE_CONTACTS|DBE_ADDED|DBE_AUTHREQUEST|DBE_FILE|DBE_OTHER
+*/
+#define DBE_FIRST 0x00000001 // first event (conforming the rest of the flags)
+#define DBE_LAST 0x00000002 // last event (conforming the rest of the flags)
+#define DBE_NEXT 0x00000004 // next event (conforming the rest of the flags), hDbEvent must be set
+#define DBE_PREV 0x00000008 // prev event (conforming the rest of the flags), hDbEvent must be set
+#define DBE_SENT 0x00000010 // event was sent
+#define DBE_RCVD 0x00000020 // event was received
+#define DBE_READ 0x00000040 // event is read
+#define DBE_UNREAD 0x00000080 // event is not read
+/* type */
+#define DBE_MESSAGE 0x00000100 // event is a message, etc (pBlob = message)
+#define DBE_URL 0x00000200 // pBlob = message
+#define DBE_CONTACTS 0x00000400 // pBlob = 'some format', no string
+#define DBE_ADDED 0x00000800 // pBlob = 'some format', no string
+#define DBE_AUTHREQUEST 0x00001000 // pBlob = message
+#define DBE_FILE 0x00002000 // pBlob = DWORD + file + description
+#define DBE_STATUSCHANGE 0x00004000 // pBlob = description
+#define DBE_OTHER 0x00008000
+#define DBE_ANYTYPE (DBE_MESSAGE|DBE_URL|DBE_CONTACTS|DBE_ADDED|DBE_AUTHREQUEST|DBE_FILE|DBE_STATUSCHANGE|DBE_OTHER)
+#define DBE_ANYFIRSTUNREAD (DBE_ANYTYPE|DBE_UNREAD|DBE_RCVD)
+
+#ifndef EVENTTYPE_STATUSCHANGE
+#define EVENTTYPE_STATUSCHANGE 25368
+#endif
diff --git a/plugins/Variables/src/parse_regexp.cpp b/plugins/Variables/src/parse_regexp.cpp
new file mode 100644
index 0000000000..4460e41ca6
--- /dev/null
+++ b/plugins/Variables/src/parse_regexp.cpp
@@ -0,0 +1,139 @@
+/*
+ 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_regexp.h"
+#define PCRE_STATIC
+#include "pcre.h"
+
+/*
+ pattern, subject
+*/
+static TCHAR *parseRegExpCheck(ARGUMENTSINFO *ai) {
+
+ const char *err;
+ int erroffset, nmat;
+ pcre_extra *extra;
+ pcre *ppat;
+ char szVal[34], *arg1, *arg2;
+ int offsets[99];
+ TCHAR *res;
+
+ if (ai->argc != 3) {
+ return NULL;
+ }
+ ai->flags = AIF_FALSE;
+
+ arg1 = mir_t2a(ai->targv[1]);
+ arg2 = mir_t2a(ai->targv[2]);
+
+ ppat = pcre_compile(arg1, 0, &err, &erroffset, NULL);
+ if (ppat == NULL) {
+ mir_free(arg1);
+ mir_free(arg2);
+ return NULL;
+ }
+ extra = pcre_study(ppat, 0, &err);
+ nmat = pcre_exec(ppat, extra, arg2, strlen(arg2), 0, 0, offsets, 99);
+ mir_free(arg1);
+ mir_free(arg2);
+ if (nmat > 0) {
+ ai->flags &= ~AIF_FALSE;
+ _ltoa(nmat, szVal, 10);
+
+ res = mir_a2t(szVal);
+
+ return res;
+ }
+
+ return mir_tstrdup(_T("0"));
+}
+
+/*
+ pattern, subject, substring no (== PCRE string no (starting at 0))
+*/
+static TCHAR *parseRegExpSubstr(ARGUMENTSINFO *ai) {
+
+ const char *err, *substring;
+ char *res, *arg1, *arg2, *arg3;
+ int erroffset, nmat, number;
+ pcre_extra *extra;
+ pcre *ppat;
+ int offsets[99];
+ TCHAR *tres;
+
+ if (ai->argc != 4) {
+ return NULL;
+ }
+
+ arg1 = mir_t2a(ai->targv[1]);
+ arg2 = mir_t2a(ai->targv[2]);
+ arg3 = mir_t2a(ai->targv[3]);
+
+ number = atoi(arg3);
+ if (number < 0) {
+ mir_free(arg1);
+ mir_free(arg2);
+ mir_free(arg3);
+ return NULL;
+ }
+ ai->flags = AIF_FALSE;
+ ppat = pcre_compile(arg1, 0, &err, &erroffset, NULL);
+ if (ppat == NULL) {
+ mir_free(arg1);
+ mir_free(arg2);
+ mir_free(arg3);
+ return NULL;
+ }
+ extra = pcre_study(ppat, 0, &err);
+ nmat = pcre_exec(ppat, extra, arg2, strlen(arg2), 0, 0, offsets, 99);
+ if (nmat >= 0) {
+ ai->flags &= ~AIF_FALSE;
+ }
+ if (pcre_get_substring(arg2, offsets, nmat, number, &substring) < 0) {
+ ai->flags |= AIF_FALSE;
+ }
+ else {
+ res = mir_strdup(substring);
+ pcre_free_substring(substring);
+
+
+ tres = mir_a2t(res);
+
+ mir_free(res);
+ mir_free(arg1);
+ mir_free(arg2);
+ mir_free(arg3);
+
+ return tres;
+ }
+ mir_free(arg1);
+ mir_free(arg2);
+ mir_free(arg3);
+
+ return mir_tstrdup(_T(""));
+}
+
+int registerRegExpTokens() {
+
+ registerIntToken(_T(REGEXPCHECK), parseRegExpCheck, TRF_FUNCTION, "Regular Expressions\t(x,y)\t(ANSI input only) the number of substring matches found in y with pattern x");
+ registerIntToken(_T(REGEXPSUBSTR), parseRegExpSubstr, TRF_FUNCTION, "Regular Expressions\t(x,y,z)\t(ANSI input only) substring match number z found in subject y with pattern x");
+
+
+ return 0;
+} \ No newline at end of file
diff --git a/plugins/Variables/src/parse_regexp.h b/plugins/Variables/src/parse_regexp.h
new file mode 100644
index 0000000000..00d38cab59
--- /dev/null
+++ b/plugins/Variables/src/parse_regexp.h
@@ -0,0 +1,20 @@
+/*
+ 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
+*/
+#define REGEXPCHECK "regexp_check"
+#define REGEXPSUBSTR "regexp_substr"
diff --git a/plugins/Variables/src/parse_str.cpp b/plugins/Variables/src/parse_str.cpp
new file mode 100644
index 0000000000..112b064d1f
--- /dev/null
+++ b/plugins/Variables/src/parse_str.cpp
@@ -0,0 +1,887 @@
+/*
+ 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_str.h"
+
+static TCHAR *parseCaps(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 2)
+ return NULL;
+
+ TCHAR *res = mir_tstrdup(ai->targv[1]);
+ TCHAR *cur = res;
+ CharLower(res);
+ *cur = (TCHAR)CharUpper((LPTSTR)*cur);
+ cur++;
+ while (*cur != _T('\0')) {
+ if ((*cur == _T(' ')) && (*(cur+1) != _T('\0'))) {
+ cur++;
+ if (IsCharLower(*cur))
+ *cur = (TCHAR)CharUpper((LPTSTR)*cur);
+ }
+ else {
+ cur++;
+ if (IsCharUpper(*cur))
+ *cur = (TCHAR)CharLower((LPTSTR)*cur);
+ }
+ }
+ return res;
+}
+
+static TCHAR *parseCaps2(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 2)
+ return NULL;
+
+ TCHAR *res = mir_tstrdup(ai->targv[1]);
+ TCHAR *cur = res;
+ *cur = (TCHAR)CharUpper((LPTSTR)*cur);
+ cur++;
+ while (*cur != _T('\0')) {
+ if ((*cur == _T(' ')) && (*(cur+1) != _T('\0'))) {
+ cur++;
+ if (IsCharLower(*cur))
+ *cur = (TCHAR)CharUpper((LPTSTR)*cur);
+ }
+ else cur++;
+ }
+ return res;
+}
+
+static TCHAR *parseCrlf(ARGUMENTSINFO *ai)
+{
+ ai->flags |= AIF_DONTPARSE;
+ return mir_tstrdup(_T("\r\n"));
+}
+
+static TCHAR *parseEolToCrlf(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 2)
+ return NULL;
+
+ TCHAR *res = mir_tstrdup(ai->targv[1]);
+ TCHAR *cur = res;
+ do {
+ cur = _tcschr(cur, _T('\n'));
+ if ((cur == NULL) || ((cur > res) && (*(cur-1) == '\r')))
+ continue;
+
+ log_debug(cur);
+ int loc = cur - res;
+ res = (TCHAR*)mir_realloc(res, (_tcslen(res)+2)*sizeof(TCHAR));
+ cur = res + loc;
+ MoveMemory(cur+2, cur+1, (_tcslen(cur+1)+1)*sizeof(TCHAR));
+ CopyMemory(cur, _T("\r\n"), 2*sizeof(TCHAR));
+ cur += 2;
+ }
+ while (cur != NULL);
+
+ return res;
+}
+
+static TCHAR *parseFixeol(ARGUMENTSINFO *ai)
+{
+ TCHAR *szReplacement;
+ if (ai->argc == 2)
+ szReplacement = _T("(...)");
+ else if (ai->argc == 3)
+ szReplacement = ai->targv[2];
+ else
+ return NULL;
+
+ TCHAR *cur = ai->targv[1];
+ while ( (_tcscmp(cur, _T("\r\n"))) && (*cur != _T('\n')) && (*cur != _T('\0')))
+ cur++;
+
+ if (*cur == '\0')
+ return mir_tstrdup(ai->targv[1]);
+
+ cur--;
+ TCHAR *res = (TCHAR*)mir_alloc((cur-ai->targv[1] + _tcslen(szReplacement) + 1)*sizeof(TCHAR));
+ if (res == NULL)
+ return res;
+
+ ZeroMemory(res, ((cur - ai->targv[1]) + 1)*sizeof(TCHAR));
+ _tcsncpy(res, ai->targv[1], cur-ai->targv[1]);
+ _tcscat(res, szReplacement);
+ return res;
+}
+
+static TCHAR *parseFixeol2(ARGUMENTSINFO *ai)
+{
+ TCHAR *szReplacement;
+ switch( ai->argc ) {
+ case 2: szReplacement = _T(" "); break;
+ case 3: szReplacement = ai->targv[2]; break;
+ default: return NULL;
+ }
+
+ TCHAR *res = mir_tstrdup(ai->targv[1]);
+ for (unsigned int pos=0; pos < _tcslen(res); pos++ ) {
+ TCHAR *cur = res+pos;
+ TCHAR *szEol = NULL;
+ if (!_tcsncmp(cur, _T("\r\n"), _tcslen(_T("\r\n"))))
+ szEol = _T("\r\n");
+
+ if (*cur == _T('\n'))
+ szEol = _T("\n");
+
+ if (szEol != NULL) {
+ if ( _tcslen(szReplacement) > _tcslen(szEol)) {
+ res = (TCHAR*)mir_realloc(res, (_tcslen(res) + _tcslen(szReplacement) - _tcslen(szEol) + 1)*sizeof(TCHAR));
+ cur = res+pos;
+ }
+ MoveMemory(cur+_tcslen(szReplacement), cur+_tcslen(szEol), (_tcslen(cur+_tcslen(szEol))+1)*sizeof(TCHAR));
+ CopyMemory(cur, szReplacement, _tcslen(szReplacement)*sizeof(TCHAR));
+ pos += _tcslen(szReplacement) - 1;
+ }
+ }
+ return (TCHAR*)mir_realloc(res, (_tcslen(res)+1)*sizeof(TCHAR));
+}
+
+static TCHAR *parseInsert(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 4)
+ return NULL;
+
+ unsigned int pos = ttoi(ai->targv[3]);
+ if (pos > _tcslen(ai->targv[1]))
+ return NULL;
+
+ TCHAR *res = (TCHAR*)mir_alloc((_tcslen(ai->targv[1]) + _tcslen(ai->targv[2]) + 1)*sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ ZeroMemory(res, (_tcslen(ai->targv[1]) + _tcslen(ai->targv[2]) + 1)*sizeof(TCHAR));
+ _tcsncpy(res, ai->targv[1], pos);
+ _tcscpy(res + pos, ai->targv[2]);
+ _tcscpy(res+pos+_tcslen(ai->targv[2]), ai->targv[1]+pos);
+ return res;
+}
+
+static TCHAR *parseLeft(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 3)
+ return NULL;
+
+ int len = ttoi(ai->targv[2]);
+ if (len < 0)
+ return NULL;
+
+ len = min(len, (signed int)_tcslen(ai->targv[1]));
+ TCHAR *res = (TCHAR*)mir_alloc((len + 1)*sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ ZeroMemory(res, (len+1)*sizeof(TCHAR));
+ _tcsncpy(res, ai->targv[1], len);
+ return res;
+}
+
+static TCHAR *parseLen(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 2)
+ return NULL;
+
+ return itot( _tcslen( ai->targv[1] ));
+}
+
+static TCHAR *parseLineCount(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 2)
+ return NULL;
+
+ int count = 1;
+ TCHAR *cur = ai->targv[1];
+ while (cur < (ai->targv[1] + _tcslen(ai->targv[1]))) {
+ if (!_tcsncmp(cur, _T("\r\n"), 2)) {
+ count += 1;
+ cur++;
+ }
+ else if (*cur == _T('\n'))
+ count++;
+
+ cur++;
+ }
+
+ return itot(count);
+}
+
+static TCHAR *parseLower(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 2)
+ return NULL;
+
+ TCHAR *res = mir_tstrdup(ai->targv[1]);
+ if (res == NULL)
+ return NULL;
+
+ return CharLower(res);
+}
+
+static TCHAR *parseLongest(ARGUMENTSINFO *ai)
+{
+ if (ai->argc < 2)
+ return NULL;
+
+ unsigned int iLong = 1;
+ for (unsigned int i=2; i < ai->argc; i++)
+ if ( _tcslen(ai->targv[i]) > _tcslen(ai->targv[iLong]))
+ iLong = i;
+
+ return mir_tstrdup( ai->targv[iLong] );
+}
+
+static TCHAR *parseNoOp(ARGUMENTSINFO *ai)
+{
+ if (ai->argc != 2)
+ return NULL;
+
+ return mir_tstrdup( ai->targv[1] );
+}
+
+static TCHAR *parsePad(ARGUMENTSINFO *ai)
+{
+ TCHAR padchar;
+ switch( ai->argc ) {
+ case 3: padchar = _T(' '); break;
+ case 4: padchar = *ai->targv[3]; break;
+ default: return NULL;
+ }
+
+ int padding = ttoi(ai->targv[2]);
+ if (padding < 0)
+ return NULL;
+
+ unsigned int addcount = max(padding - (signed int)_tcslen(ai->targv[1]), 0);
+ TCHAR *res = (TCHAR*)mir_alloc((addcount + _tcslen(ai->targv[1]) + 1)*sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ ZeroMemory(res, (addcount + _tcslen(ai->targv[1]) + 1)*sizeof(TCHAR));
+ TCHAR *cur = res;
+ for ( unsigned int i=0; i < addcount; i++ )
+ *cur++ = padchar;
+
+ _tcscat(res, ai->targv[1]);
+ return res;
+}
+
+static TCHAR *parsePadright(ARGUMENTSINFO *ai)
+{
+ TCHAR padchar;
+ switch (ai->argc ) {
+ case 3: padchar = _T(' '); break;
+ case 4: padchar = *ai->targv[3]; break;
+ default: return NULL;
+ }
+
+ int padding = ttoi(ai->targv[2]);
+ if (padding < 0)
+ return NULL;
+
+ unsigned int addcount = max(padding - (signed int)_tcslen(ai->targv[1]), 0);
+ TCHAR *res = (TCHAR*)mir_alloc((addcount + _tcslen(ai->targv[1]) + 1)*sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ ZeroMemory(res, (addcount + _tcslen(ai->targv[1]) + 1)*sizeof(TCHAR));
+ _tcscpy(res, ai->targv[1]);
+ TCHAR *cur = res + _tcslen(ai->targv[1]);
+ for (unsigned int i=0; i < addcount; i++)
+ *cur++ = padchar;
+
+ return res;
+}
+
+static TCHAR *parsePadcut(ARGUMENTSINFO *ai)
+{
+ TCHAR padchar;
+ switch( ai->argc ) {
+ case 3: padchar = _T(' '); break;
+ case 4: padchar = *ai->targv[3]; break;
+ default: return NULL;
+ }
+
+ int padding = ttoi(ai->targv[2]);
+ if (padding < 0)
+ return NULL;
+
+ int addcount = max(padding - (signed int)_tcslen(ai->targv[1]), 0);
+ TCHAR *res = (TCHAR*)mir_alloc((padding + 1)*sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ ZeroMemory(res, (padding + 1)*sizeof(TCHAR));
+ TCHAR *cur = res;
+ for (int i=0; i < addcount; i++)
+ *cur++ = padchar;
+
+ if (padding > addcount)
+ _tcsncpy(res+addcount, ai->targv[1], padding-addcount);
+
+ return res;
+}
+
+static TCHAR *parsePadcutright(ARGUMENTSINFO *ai)
+{
+ TCHAR padchar;
+ switch( ai->argc ) {
+ case 3: padchar = _T(' '); break;
+ case 4: padchar = *ai->targv[3]; break;
+ default: return NULL;
+ }
+
+ int padding = ttoi(ai->targv[2]);
+ if (padding < 0)
+ return NULL;
+
+ int addcount = max(padding - (signed int)_tcslen(ai->targv[1]), 0);
+ TCHAR *res = (TCHAR*)mir_alloc((padding + 1)*sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ ZeroMemory(res, (padding + 1)*sizeof(TCHAR));
+ TCHAR *cur = res + padding - addcount;
+ for (int i=0; i < addcount; i++ )
+ *cur++ = padchar;
+
+ if (padding > addcount )
+ _tcsncpy(res, ai->targv[1], padding-addcount);
+
+ return res;
+}
+
+static TCHAR *parseRepeat(ARGUMENTSINFO *ai)
+{
+ TCHAR *res;
+ unsigned int i, count;
+
+ if (ai->argc != 3) {
+ return NULL;
+ }
+ count = ttoi(ai->targv[2]);
+ if (count < 0) {
+ return NULL;
+ }
+ res = (TCHAR*)mir_alloc((count * _tcslen(ai->targv[1]) + 1)*sizeof(TCHAR));
+ if (res == NULL) {
+ return NULL;
+ }
+ ZeroMemory(res, (count * _tcslen(ai->targv[1]) + 1)*sizeof(TCHAR));
+ for (i=0;i<count;i++) {
+ _tcscat(res, ai->targv[1]);
+ }
+
+ return res;
+}
+
+static TCHAR *parseReplace(ARGUMENTSINFO *ai) {
+
+ TCHAR *res, *cur;
+ unsigned int i, pos;
+
+ if ((ai->argc < 4) || (ai->argc%2 != 0)) {
+ return NULL;
+ }
+ pos = 0;
+ res = mir_tstrdup(ai->targv[1]);
+ for (i=2;i<ai->argc;i+=2) {
+ if ( _tcslen(ai->targv[i]) == 0) {
+ continue;
+ }
+ for (pos=0;pos<_tcslen(res);pos++) {
+ cur = res+pos;
+ if (!_tcsncmp(cur, ai->targv[i], _tcslen(ai->targv[i]))) {
+ if ( _tcslen(ai->targv[i+1]) > _tcslen(ai->targv[i])) {
+ res = (TCHAR*)mir_realloc(res, (_tcslen(res) + _tcslen(ai->targv[i+1]) - _tcslen(ai->targv[i]) + 1)*sizeof(TCHAR));
+ cur = res+pos;
+ }
+ MoveMemory(cur+_tcslen(ai->targv[i+1]), cur+_tcslen(ai->targv[i]), (_tcslen(cur+_tcslen(ai->targv[i]))+1)*sizeof(TCHAR));
+ CopyMemory(cur, ai->targv[i+1], _tcslen(ai->targv[i+1])*sizeof(TCHAR));
+ pos += _tcslen(ai->targv[i+1]) - 1;
+ }
+ }
+ res = (TCHAR*)mir_realloc(res, (_tcslen(res)+1)*sizeof(TCHAR));
+ }
+
+ return res;
+}
+
+static TCHAR *parseRight(ARGUMENTSINFO *ai) {
+
+ int len;
+ TCHAR *res;
+
+ if (ai->argc != 3) {
+ return NULL;
+ }
+ len = ttoi(ai->targv[2]);
+ if (len < 0) {
+ return NULL;
+ }
+ len = min(len, (signed int)_tcslen(ai->targv[1]));
+ res = (TCHAR*)mir_alloc((len+1)*sizeof(TCHAR));
+ if (res == NULL) {
+ return NULL;
+ }
+ ZeroMemory(res, (len+1)*sizeof(TCHAR));
+ _tcsncpy(res, ai->targv[1]+_tcslen(ai->targv[1])-len, len);
+
+ return res;
+}
+
+/*
+ string, display size, scroll amount
+*/
+static TCHAR *parseScroll(ARGUMENTSINFO *ai) {
+
+ unsigned int display, move;
+ TCHAR *res;
+
+ if (ai->argc != 4) {
+ return NULL;
+ }
+ if ( _tcslen(ai->targv[1]) == 0) {
+
+ return mir_tstrdup(ai->targv[1]);
+ }
+ move = ttoi(ai->targv[3])%_tcslen(ai->targv[1]);
+ display = ttoi(ai->targv[2]);
+ if (display > _tcslen(ai->targv[1])) {
+ display = _tcslen(ai->targv[1]);
+ }
+ res = (TCHAR*)mir_alloc((2*_tcslen(ai->targv[1])+1)*sizeof(TCHAR));
+ if (res == NULL) {
+ return NULL;
+ }
+ ZeroMemory(res, (2*_tcslen(ai->targv[1])+1)*sizeof(TCHAR));
+ _tcscpy(res, ai->targv[1]);
+ _tcscat(res, ai->targv[1]);
+ MoveMemory(res, res+move, (_tcslen(res+move)+1)*sizeof(TCHAR));
+ *(res + display) = _T('\0');
+ res = (TCHAR*)mir_realloc(res, (_tcslen(res)+1)*sizeof(TCHAR));
+
+ return res;
+}
+
+static TCHAR *parseShortest(ARGUMENTSINFO *ai) {
+
+ unsigned int i, iShort;
+
+ if (ai->argc <= 1) {
+ return NULL;
+ }
+ iShort = 1;
+ for (i=2;i<ai->argc;i++) {
+ if ( _tcslen(ai->targv[i]) < _tcslen(ai->targv[iShort])) {
+ iShort = i;
+ }
+ }
+
+ return mir_tstrdup(ai->targv[iShort]);
+}
+
+static TCHAR *parseStrchr(ARGUMENTSINFO *ai) {
+
+ TCHAR *c;
+ char *szVal[34];
+
+ if (ai->argc != 3) {
+ return NULL;
+ }
+ ZeroMemory(szVal, sizeof(szVal));
+ c = _tcschr(ai->targv[1], *ai->targv[2]);
+ if ((c == NULL) || (*c == _T('\0'))) {
+ return mir_tstrdup(_T("0"));
+ }
+
+ return itot(c-ai->targv[1]+1);
+}
+
+static TCHAR *parseStrcmp(ARGUMENTSINFO *ai) {
+
+ if (ai->argc != 3) {
+ return NULL;
+ }
+ if ( _tcscmp(ai->targv[1], ai->targv[2])) {
+ ai->flags |= AIF_FALSE;
+ }
+
+ return mir_tstrdup(_T(""));
+}
+
+static TCHAR *parseStrmcmp(ARGUMENTSINFO *ai) {
+
+ unsigned int i;
+
+ if (ai->argc < 3) {
+ return NULL;
+ }
+ ai->flags |= AIF_FALSE;
+ for (i=2;i<ai->argc;i++) {
+ if (!_tcscmp(ai->targv[1], ai->targv[i])) {
+ ai->flags &= ~AIF_FALSE;
+ break;
+ }
+ }
+
+ return mir_tstrdup(_T(""));
+}
+
+static TCHAR *parseStrncmp(ARGUMENTSINFO *ai) {
+
+ int n;
+
+ if (ai->argc != 4) {
+ return NULL;
+ }
+ n = ttoi(ai->targv[3]);
+ if (n <= 0) {
+ return NULL;
+ }
+ if ( _tcsncmp(ai->targv[1], ai->targv[2], n)) {
+ ai->flags |= AIF_FALSE;
+ }
+
+ return mir_tstrdup(_T(""));
+}
+
+static TCHAR *parseStricmp(ARGUMENTSINFO *ai) {
+
+ if (ai->argc != 3) {
+ return NULL;
+ }
+
+ if ( _tcsicmp(ai->targv[1], ai->targv[2])) {
+ ai->flags |= AIF_FALSE;
+ }
+
+ return mir_tstrdup(_T(""));
+}
+
+static TCHAR *parseStrnicmp(ARGUMENTSINFO *ai) {
+
+ int n;
+
+ if (ai->argc != 4) {
+ return NULL;
+ }
+ n = ttoi(ai->targv[3]);
+ if (n <= 0) {
+ return NULL;
+ }
+ if ( _tcsnicmp(ai->targv[1], ai->targv[2], n)) {
+ ai->flags |= AIF_FALSE;
+ }
+
+ return mir_tstrdup(_T(""));
+}
+
+static TCHAR *parseStrrchr(ARGUMENTSINFO *ai) {
+
+ TCHAR *c;
+
+ if (ai->argc != 3) {
+ return NULL;
+ }
+ c = _tcsrchr(ai->targv[1], *ai->targv[2]);
+ if ((c == NULL) || (*c == _T('\0'))) {
+ return mir_tstrdup(_T("0"));
+ }
+
+ return itot(c-ai->targv[1]+1);
+}
+
+static TCHAR *parseStrstr(ARGUMENTSINFO *ai) {
+
+ TCHAR *c;
+
+ if (ai->argc != 3) {
+ return NULL;
+ }
+ c = _tcsstr(ai->targv[1], ai->targv[2]);
+ if ((c == NULL) || (*c == _T('\0'))) {
+ return mir_tstrdup(_T("0"));
+ }
+
+ return itot(c-ai->targv[1]+1);
+}
+
+static TCHAR *parseSubstr(ARGUMENTSINFO *ai) {
+
+ int from, to;
+ TCHAR *res;
+
+ if (ai->argc < 3) {
+ return NULL;
+ }
+ from = max(ttoi(ai->targv[2])-1, 0);
+ if (ai->argc > 3) {
+ to = min(ttoi(ai->targv[3]), (signed int)_tcslen(ai->targv[1]));
+ }
+ else {
+ to = _tcslen(ai->targv[1]);
+ }
+ if (to < from) {
+ return NULL;
+ }
+ res = (TCHAR*)mir_alloc((to-from+1)*sizeof(TCHAR));
+ ZeroMemory(res, (to-from+1)*sizeof(TCHAR));
+ _tcsncpy(res, ai->targv[1]+from, to-from);
+
+ return res;
+}
+
+static TCHAR *parseSelect(ARGUMENTSINFO *ai) {
+
+ int n;
+
+ if (ai->argc <= 1) {
+ return NULL;
+ }
+ n = ttoi(ai->targv[1]);
+ if ((n > (signed int)ai->argc-2) || (n <= 0)) {
+ return NULL;
+ }
+
+ return mir_tstrdup(ai->targv[n+1]);
+}
+
+static TCHAR *parseSwitch(ARGUMENTSINFO *ai) {
+
+ unsigned int i;
+
+ if (ai->argc%2 != 0) {
+ return NULL;
+ }
+ for (i=2;i<ai->argc;i+=2) {
+ if (!_tcscmp(ai->targv[1], ai->targv[i])) {
+ return mir_tstrdup(ai->targv[i+1]);
+ }
+ }
+ return NULL;
+}
+
+static TCHAR *parseTrim(ARGUMENTSINFO *ai) {
+
+ TCHAR *scur, *ecur, *res;
+
+ if (ai->argc != 2) {
+ return NULL;
+ }
+ scur = ai->targv[1];
+ while (*scur == _T(' ')) {
+ scur++;
+ }
+ ecur = ai->targv[1] + _tcslen(ai->targv[1])-1;
+ while ( (*ecur == _T(' ')) && (ecur > ai->targv[1])) {
+ ecur--;
+ }
+ if (scur >= ecur) {
+ return mir_tstrdup(_T(""));
+ }
+ res = (TCHAR*)mir_alloc((ecur-scur+2)*sizeof(TCHAR));
+ if (res == NULL) {
+ return NULL;
+ }
+ ZeroMemory(res, (ecur-scur+2)*sizeof(TCHAR));
+ _tcsncpy(res, scur, ecur-scur+1);
+
+ return res;
+}
+
+static TCHAR *parseTab(ARGUMENTSINFO *ai) {
+
+ int count, i;
+ TCHAR *res, *cur;
+
+ count = 1;
+ if ((ai->argc == 2) && (_tcslen(ai->targv[1]) > 0)) {
+ count = ttoi(ai->targv[1]);
+ }
+ if (count < 0) {
+ return NULL;
+ }
+ res = (TCHAR*)mir_alloc((count+1)*sizeof(TCHAR));
+ if (res == NULL) {
+ return NULL;
+ }
+ memset(res, _T('\0'), (count+1)*sizeof(TCHAR));
+ cur = res;
+ for (i=0;i<count;i++) {
+ *cur++ = _T('\t');
+ }
+
+ return res;
+}
+
+static TCHAR *parseUpper(ARGUMENTSINFO *ai) {
+
+ TCHAR *res;
+
+ if (ai->argc != 2) {
+ return NULL;
+ }
+ res = mir_tstrdup(ai->targv[1]);
+ if (res == NULL) {
+ return NULL;
+ }
+
+ return CharUpper(res);
+}
+
+static TCHAR *getNthWord(TCHAR *szString, int w) {
+
+ int count;
+ TCHAR *res, *scur, *ecur;
+
+ if (szString == NULL) {
+ return NULL;
+ }
+ count = 0;
+ scur = szString;
+ while (*scur == _T(' ')) {
+ scur++;
+ }
+ count+=1;
+ while ( (count < w) && (scur < szString+_tcslen(szString))) {
+ if (*scur == _T(' ')) {
+ while (*scur == _T(' ')) {
+ scur++;
+ }
+ count+=1;
+ }
+ if (count < w) {
+ scur++;
+ }
+ }
+ if (count != w) {
+ return NULL;
+ }
+ ecur = scur;
+ while ( (*ecur != _T(' ')) && (*ecur != _T('\0'))) {
+ ecur++;
+ }
+ res = (TCHAR*)mir_alloc((ecur-scur+1)*sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ ZeroMemory(res, (ecur-scur+1)*sizeof(TCHAR));
+ _tcsncpy(res, scur, ecur-scur);
+
+ return res;
+}
+
+static TCHAR *parseWord(ARGUMENTSINFO *ai)
+{
+ int i, from, to;
+ TCHAR *res, *szWord;
+
+ if (ai->argc < 3 || ai->argc > 4 )
+ return NULL;
+
+ res = NULL;
+ from = ttoi(ai->targv[2]);
+ if (ai->argc == 4) {
+ if ( _tcslen(ai->targv[3]) > 0)
+ to = ttoi(ai->targv[3]);
+ else
+ to = 100000; // rework
+ }
+ else to = from;
+
+ if ((from == 0) || (to == 0) || (from > to))
+ return NULL;
+
+ for (i=from;i<=to;i++) {
+ szWord = getNthWord(ai->targv[1], i);
+ if (szWord == NULL)
+ return res;
+
+ if (res != NULL) {
+ res = (TCHAR*)mir_realloc(res, (_tcslen(res) + _tcslen(szWord) + 2)*sizeof(TCHAR));
+ if (res != NULL) {
+ _tcscat(res, _T(" "));
+ _tcscat(res, szWord);
+ }
+ }
+ else res = mir_tstrdup(szWord);
+
+ mir_free(szWord);
+ }
+
+ return res;
+}
+
+static TCHAR *parseExtratext(ARGUMENTSINFO *ai)
+{
+ if (ai->argc > 1)
+ return NULL;
+
+ ai->flags |= AIF_DONTPARSE;
+ if (ai->fi->szExtraText != NULL)
+ return mir_tstrdup(ai->fi->tszExtraText);
+
+ return NULL;
+}
+
+int registerStrTokens() {
+
+ registerIntToken(_T(CAPS), parseCaps, TRF_FUNCTION, "String Functions\t(x)\tconverts each first letter of a word to uppercase, all others to lowercase");
+ registerIntToken(_T(CAPS2), parseCaps2, TRF_FUNCTION, "String Functions\t(x)\tconverts each first letter of a word to uppercase");
+ registerIntToken(_T(CRLF), parseCrlf, TRF_FUNCTION, "String Functions\t()\tinserts 'end of line' character");
+ registerIntToken(_T(EXTRATEXT), parseExtratext, TRF_FIELD, "String Functions\tdepends on calling plugin");
+ registerIntToken(_T(EOL2CRLF), parseEolToCrlf, TRF_FUNCTION, "String Functions\t(x)\tReplace all occurrences of \\n (Unix) by \\r\\n (Windows)");
+ registerIntToken(_T(FIXEOL), parseFixeol, TRF_FUNCTION, "String Functions\t(x,y)\tcuts x after the first line and appends y (y is optional)");
+ registerIntToken(_T(FIXEOL2), parseFixeol2, TRF_FUNCTION, "String Functions\t(x,y)\treplaces all end of line characters by y (y is optional)");
+ registerIntToken(_T(INSERT), parseInsert, TRF_FUNCTION, "String Functions\t(x,y,z)\tinserts string y at position z in string x");
+ registerIntToken(_T(LEFT), parseLeft, TRF_FUNCTION, "String Functions\t(x,y)\ttrims x to length y, keeping first y characters");
+ registerIntToken(_T(LEN), parseLen, TRF_FUNCTION, "String Functions\t(x)\tlength of x");
+ registerIntToken(_T(LINECOUNT), parseLineCount, TRF_FUNCTION, "String Functions\t(x)\tthe number of lines in string x");
+ registerIntToken(_T(LONGEST), parseLongest, TRF_FUNCTION, "String Functions\t(x,y,...)\tthe longest string of the arguments");
+ registerIntToken(_T(LOWER), parseLower, TRF_FUNCTION, "String Functions\t(x)\tconverts x to lowercase");
+ registerIntToken(_T(NOOP), parseNoOp, TRF_FUNCTION, "String Functions\t(x)\tno operation, x as given");
+ registerIntToken(_T(PAD), parsePad, TRF_FUNCTION, "String Functions\t(x,y,z)\tpads x to length y prepending character z (z is optional)");
+ registerIntToken(_T(PADRIGHT), parsePadright, TRF_FUNCTION, "String Functions\t(x,y,z)\tpads x to length y appending character z (z is optional)");
+ registerIntToken(_T(PADCUT), parsePadcut, TRF_FUNCTION, "String Functions\t(x,y,z)\tpads x to length y prepending character z, or cut if x is longer (z is optional)");
+ registerIntToken(_T(PADCUTRIGHT), parsePadcutright, TRF_FUNCTION, "String Functions\t(x,y,z)\tpads x to length y appending character z, or cut if x is longer (z is optional)");
+ registerIntToken(_T(REPEAT), parseRepeat, TRF_FUNCTION, "String Functions\t(x,y)\trepeats x y times");
+ registerIntToken(_T(REPLACE), parseReplace, TRF_FUNCTION, "String Functions\t(x,y,z,...)\treplace all occurrences of y in x with z, multiple y and z arguments allowed");
+ registerIntToken(_T(RIGHT), parseRight, TRF_FUNCTION, "String Functions\t(x,y)\ttrims x to length y, keeping last y characters");
+ registerIntToken(_T(SCROLL), parseScroll, TRF_FUNCTION, "String Functions\t(x,y,z)\tmoves string x, z characters to the left and trims it to y characters");
+ registerIntToken(_T(STRCMP), parseStrcmp, TRF_FUNCTION, "String Functions\t(x,y)\tTRUE if x equals y");
+ registerIntToken(_T(STRMCMP), parseStrmcmp, TRF_FUNCTION, "String Functions\t(x,y,...)\tTRUE if x equals any of the following arguments");
+ registerIntToken(_T(STRNCMP), parseStrncmp, TRF_FUNCTION, "String Functions\t(x,y,z)\tTRUE if the first z characters of x equal y");
+ registerIntToken(_T(STRICMP), parseStricmp, TRF_FUNCTION, "String Functions\t(x,y)\tTRUE if x equals y, ignoring case");
+ registerIntToken(_T(STRNICMP), parseStrnicmp, TRF_FUNCTION, "String Functions\t(x,y)\tTRUE if the first z characters of x equal y, ignoring case");
+ registerIntToken(_T(SHORTEST), parseShortest, TRF_FUNCTION, "String Functions\t(x,y,...)\tthe shortest string of the arguments");
+ registerIntToken(_T(STRCHR), parseStrchr, TRF_FUNCTION, "String Functions\t(x,y)\tlocation of first occurrence of character y in string x");
+ registerIntToken(_T(STRRCHR), parseStrrchr, TRF_FUNCTION, "String Functions\t(x,y)\tlocation of last occurrence of character y in string x");
+ registerIntToken(_T(STRSTR), parseStrstr, TRF_FUNCTION, "String Functions\t(x,y)\tlocation of first occurrence of string y in x");
+ registerIntToken(_T(SUBSTR), parseSubstr, TRF_FUNCTION, "String Functions\t(x,y,z)\tsubstring of x starting from position y to z");
+ registerIntToken(_T(SELECT), parseSelect, TRF_FUNCTION, "String Functions\t(x,y,...)\tthe xth string of the arguments");
+ registerIntToken(_T(SWITCH), parseSwitch, TRF_FUNCTION, "String Functions\t(x,y,z,...)\tz if y equals x, multiple y and z arguments allowed");
+ registerIntToken(_T(TRIM), parseTrim, TRF_FUNCTION, "String Functions\t(x)\tremoves white spaces in before and after x");
+ registerIntToken(_T(TAB), parseTab, TRF_FUNCTION, "String Functions\t(x)\tinserts x tab characters (x is optional)");
+ registerIntToken(_T(UPPER), parseUpper, TRF_FUNCTION, "String Functions\t(x)\tconverts x to upper case");
+ registerIntToken(_T(WORD), parseWord, TRF_FUNCTION, "String Functions\t(x,y,z)\twords (separated by white spaces) number y to z from string x (z is optional)");
+
+ return 0;
+}
diff --git a/plugins/Variables/src/parse_str.h b/plugins/Variables/src/parse_str.h
new file mode 100644
index 0000000000..7942da455f
--- /dev/null
+++ b/plugins/Variables/src/parse_str.h
@@ -0,0 +1,56 @@
+/*
+ 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
+*/
+#define CAPS "caps"
+#define CAPS2 "caps2"
+#define CRLF "crlf"
+//#define EXTRATEXT "extratext" // defined in variables.h
+#define EOL2CRLF "eol2crlf"
+#define FIXEOL "fix_eol"
+#define FIXEOL2 "fix_eol2"
+#define INSERT "insert"
+#define LEFT "left"
+#define LEN "len"
+#define LINECOUNT "linecount"
+#define LONGEST "longest"
+#define LOWER "lower"
+#define NOOP "noop"
+#define PAD "pad"
+#define PADRIGHT "pad_right"
+#define PADCUT "padcut"
+#define PADCUTRIGHT "padcut_right"
+#define REPEAT "repeat"
+#define REPLACE "replace"
+#define RIGHT "right"
+#define SCROLL "scroll"
+#define SHORTEST "shortest"
+#define STRCHR "strchr"
+#define STRRCHR "strrchr"
+#define STRSTR "strstr"
+#define STRCMP "strcmp"
+#define STRNCMP "strncmp"
+#define STRMCMP "strmcmp"
+#define STRICMP "stricmp"
+#define STRNICMP "strnicmp"
+#define SUBSTR "substr"
+#define SELECT "select"
+#define SWITCH "switch"
+#define TRIM "trim"
+#define TAB "tab"
+#define UPPER "upper"
+#define WORD "word"
diff --git a/plugins/Variables/src/parse_system.cpp b/plugins/Variables/src/parse_system.cpp
new file mode 100644
index 0000000000..e5db6af03e
--- /dev/null
+++ b/plugins/Variables/src/parse_system.cpp
@@ -0,0 +1,1002 @@
+/*
+ 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_system.h"
+#include <tchar.h>
+#include <lmcons.h>
+#include <sys/stat.h>
+
+#ifdef WINE
+ #ifdef _WIN32_WINNT
+ #undef _WIN32_WINNT
+ #endif
+ #define _WIN32_WINNT 0x400
+#endif
+
+#ifndef WINE
+#include "enumprocs.h"
+#endif
+
+static TCHAR *parseComputerName(ARGUMENTSINFO *ai) {
+
+ DWORD len;
+ TCHAR *res;
+
+ if (ai->argc != 1)
+ return NULL;
+
+ ai->flags |= AIF_DONTPARSE;
+ len = MAX_COMPUTERNAME_LENGTH;
+ res = (TCHAR*)mir_calloc((len + 1) * sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ if (!GetComputerName(res, &len)) {
+ mir_free(res);
+ return NULL;
+ }
+ return res;
+}
+
+#if _WIN32_WINNT>=0x0500
+#include <pdh.h>
+#include <pdhmsg.h>
+
+static TCHAR *parseCpuLoad(ARGUMENTSINFO *ai) {
+
+ HQUERY hQuery;
+ PDH_STATUS pdhStatus;
+ PDH_FMT_COUNTERVALUE cValue;
+ HCOUNTER hCounter;
+ TCHAR *szCounter, szVal[32];
+
+ if (ai->argc != 2)
+ return NULL;
+
+ if ( _tcslen(ai->targv[1]) == 0)
+ szCounter = mir_tstrdup(_T("\\Processor(_Total)\\% Processor Time"));
+ else {
+ szCounter = (TCHAR*)mir_alloc((_tcslen(ai->targv[1]) + 32)*sizeof(TCHAR));
+ if (szCounter == NULL)
+ return NULL;
+
+ wsprintf(szCounter, _T("\\Process(%s)\\%% Processor Time"), ai->targv[1]);
+ }
+ pdhStatus = PdhValidatePath(szCounter);
+ if (pdhStatus != ERROR_SUCCESS) {
+ mir_free(szCounter);
+ return NULL;
+ }
+ pdhStatus = PdhOpenQuery(NULL, 0, &hQuery);
+ if (pdhStatus != ERROR_SUCCESS) {
+ mir_free(szCounter);
+ return NULL;
+ }
+ pdhStatus = PdhAddCounter(hQuery, szCounter, 0, &hCounter);
+ if (pdhStatus != ERROR_SUCCESS) {
+ mir_free(szCounter);
+ pdhStatus = PdhCloseQuery(hQuery);
+ return NULL;
+ }
+ pdhStatus = PdhCollectQueryData(hQuery);
+ if (pdhStatus != ERROR_SUCCESS) {
+ mir_free(szCounter);
+ PdhRemoveCounter(hCounter);
+ pdhStatus = PdhCloseQuery(hQuery);
+ return NULL;
+ }
+ Sleep(100);
+ pdhStatus = PdhCollectQueryData(hQuery);
+ if (pdhStatus != ERROR_SUCCESS) {
+ mir_free(szCounter);
+ PdhRemoveCounter(hCounter);
+ pdhStatus = PdhCloseQuery(hQuery);
+ return NULL;
+ }
+ pdhStatus = PdhGetFormattedCounterValue(hCounter, PDH_FMT_DOUBLE, (LPDWORD)NULL, &cValue);
+ if (pdhStatus != ERROR_SUCCESS) {
+ mir_free(szCounter);
+ PdhRemoveCounter(hCounter);
+ pdhStatus = PdhCloseQuery(hQuery);
+ return NULL;
+ }
+ if (cValue.CStatus != ERROR_SUCCESS) {
+ mir_free(szCounter);
+ PdhRemoveCounter(hCounter);
+ pdhStatus = PdhCloseQuery(hQuery);
+ return NULL;
+ }
+ mir_sntprintf(szVal, SIZEOF(szVal), _T("%.0f"), cValue.doubleValue);
+ //PdhRemoveCounter(*hCounter);
+ PdhCloseQuery(hQuery);
+ mir_free(szCounter);
+
+ return mir_tstrdup(szVal);
+}
+#endif
+
+static TCHAR *parseCurrentDate(ARGUMENTSINFO *ai) {
+
+ int len;
+ TCHAR *szFormat, *res;
+
+ if (ai->argc == 1 || (ai->argc > 1 && _tcslen(ai->targv[1]) == 0 ))
+ szFormat = NULL;
+ else
+ szFormat = ai->targv[1];
+
+ len = GetDateFormat(LOCALE_USER_DEFAULT, 0, NULL, szFormat, NULL, 0);
+ res = (TCHAR*)mir_alloc((len+1)*sizeof(TCHAR));
+ if (res == NULL) {
+ return NULL;
+ }
+ if (GetDateFormat(LOCALE_USER_DEFAULT, 0, NULL, szFormat, res, len) == 0) {
+ mir_free(res);
+ return NULL;
+ }
+
+ return res;
+}
+
+static TCHAR *parseCurrentTime(ARGUMENTSINFO *ai) {
+
+ int len;
+ TCHAR *szFormat, *res;
+
+ if (ai->argc == 1 || (ai->argc > 1) && (_tcslen(ai->targv[1]) == 0))
+ szFormat = NULL;
+ else
+ szFormat = ai->targv[1];
+
+ len = GetTimeFormat(LOCALE_USER_DEFAULT, 0, NULL, szFormat, NULL, 0);
+ res = (TCHAR*)mir_alloc((len+1)*sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ if (GetTimeFormat(LOCALE_USER_DEFAULT, 0, NULL, szFormat, res, len) == 0) {
+ mir_free(res);
+ return NULL;
+ }
+
+ return res;
+}
+
+static TCHAR *parseDirectory(ARGUMENTSINFO *ai) {
+
+ int depth, bi, ei;
+ TCHAR *res;
+
+ if (ai->argc < 2 || ai->argc > 3 )
+ return NULL;
+
+ depth = 0;
+ if (ai->argc == 3)
+ depth = ttoi(ai->targv[2]);
+
+ if (depth <= 0)
+ return ai->targv[1];
+
+ for (ei = 0; ei < _tcslen(ai->targv[1]); ei++)
+ {
+ if (ai->targv[1][ei] == '\\')
+ depth--;
+ if (!depth) break;
+ }
+ if (ei >= _tcslen(ai->targv[1]))
+ return ai->targv[1];
+ for (bi = ei - 1; bi > 0; bi--)
+ {
+ if (ai->targv[1][bi - 1] == '\\') break;
+ }
+
+ res = (TCHAR*)mir_alloc((ei - bi + 1) * sizeof(TCHAR));
+ _tcsncpy(res, ai->targv[1] + bi, ei - bi);
+ res[ei - bi] = 0;
+
+ return res;
+}
+
+/*
+ path, depth
+ returns complete path up to "path depth - depth"
+*/
+static TCHAR *parseDirectory2(ARGUMENTSINFO *ai)
+{
+ if (ai->argc < 2 || ai->argc > 3 )
+ return NULL;
+
+ int depth = 1;
+ if (ai->argc == 3)
+ depth = ttoi(ai->targv[2]);
+
+ if (depth <= 0)
+ return NULL;
+
+ TCHAR *ecur = ai->targv[1]+_tcslen(ai->targv[1]);
+ while (depth > 0) {
+ while ( (*ecur != _T('\\')) && (ecur > ai->targv[1]))
+ ecur--;
+
+ if (*ecur != _T('\\'))
+ return NULL;
+
+ depth -= 1;
+ ecur--;
+ }
+ TCHAR *res = (TCHAR*)mir_calloc((ecur-ai->targv[1]+2) * sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ _tcsncpy(res, ai->targv[1], (ecur-ai->targv[1])+1);
+ return res;
+}
+
+static int getTime(TCHAR *szTime, struct tm *date) {
+
+ TCHAR *cur;
+
+ // do some extra checks here
+ cur = szTime;
+ if (cur >= szTime+_tcslen(szTime))
+ return -1;
+
+ date->tm_mon = _tcstoul(cur, &cur, 10)-1;
+ cur++;
+ if (cur >= szTime+_tcslen(szTime)) {
+ return -1;
+ }
+ date->tm_mday = _tcstoul(cur, &cur, 10);
+ cur++;
+ if (cur >= szTime+_tcslen(szTime)) {
+ return -1;
+ }
+ date->tm_year = _tcstoul(cur, &cur, 10);
+ if (date->tm_year > 2000) {
+ date->tm_year -= 2000;
+ }
+ else if (date->tm_year > 1900) {
+ date->tm_year -= 1900;
+ }
+ date->tm_year = date->tm_year<38?date->tm_year+100:date->tm_year;
+ cur++;
+ if (cur >= szTime+_tcslen(szTime)) {
+ return -1;
+ }
+ date->tm_hour = _tcstoul(cur, &cur, 10);
+ cur++;
+ if (cur >= szTime+_tcslen(szTime)) {
+ return -1;
+ }
+ date->tm_min = _tcstoul(cur, &cur, 10);
+ cur++;
+ if (cur >= szTime+_tcslen(szTime)) {
+ return -1;
+ }
+ date->tm_sec = _tcstoul(cur, &cur, 10);
+
+ return 0;
+}
+/*
+ date,date
+ M/d/yy H:m:s
+*/
+static TCHAR *parseDiffTime(ARGUMENTSINFO *ai) {
+
+ struct tm t0, t1;
+ TCHAR szTime[32];
+ double diff;
+
+ if (ai->argc != 3)
+ return NULL;
+
+ ZeroMemory(&t0, sizeof(t0));
+ ZeroMemory(&t1, sizeof(t1));
+ if (getTime(ai->targv[1], &t0) != 0)
+ return NULL;
+
+ if (getTime(ai->targv[2], &t1) != 0)
+ return NULL;
+
+ diff = difftime(mktime(&t1), mktime(&t0));
+ mir_sntprintf(szTime, SIZEOF(szTime), _T("%.0f"), diff);
+
+ return mir_tstrdup(szTime);
+}
+
+static TCHAR *parseDirExists(ARGUMENTSINFO *ai) {
+
+ HANDLE hFile;
+
+ if (ai->argc != 2) {
+ return NULL;
+ }
+ hFile = CreateFile(ai->targv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ ai->flags |= AIF_FALSE;
+ }
+ else {
+ CloseHandle(hFile);
+ }
+
+ return mir_tstrdup(_T(""));
+}
+
+static TCHAR *parseEnvironmentVariable(ARGUMENTSINFO *ai) {
+
+ DWORD len;
+ TCHAR *res;
+
+ if (ai->argc != 2) {
+ return NULL;
+ }
+ len = ExpandEnvironmentStrings(ai->targv[1], NULL, 0);
+ if (len <= 0) {
+ return NULL;
+ }
+ res = (TCHAR*)mir_alloc((len+1)*sizeof(TCHAR));
+ if (res == NULL) {
+ return NULL;
+ }
+ ZeroMemory(res, (len+1)*sizeof(TCHAR));
+ if (ExpandEnvironmentStrings(ai->targv[1], res, len) == 0) {
+ mir_free(res);
+ return NULL;
+ }
+ return res;
+}
+
+static TCHAR *parseFileExists(ARGUMENTSINFO *ai) {
+
+ HANDLE hFile;
+
+ if (ai->argc != 2)
+ return NULL;
+
+ hFile = CreateFile(ai->targv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ ai->flags |= AIF_FALSE;
+ else
+ CloseHandle(hFile);
+
+ return mir_tstrdup(_T(""));
+}
+
+static TCHAR *parseFindWindow(ARGUMENTSINFO *ai) {
+
+ HWND hWin;
+ TCHAR *res;
+ int len;
+
+ if (ai->argc != 2)
+ return NULL;
+
+ hWin = FindWindow(ai->targv[1], NULL);
+ if (hWin == NULL)
+ return NULL;
+
+ len = SendMessage(hWin, WM_GETTEXTLENGTH, 0, 0);
+ if (len >= 0) {
+ res = (TCHAR*)mir_alloc((len+1)*sizeof(TCHAR));
+ ZeroMemory(res, (len+1)*sizeof(TCHAR));
+ GetWindowText(hWin, res, len+1);
+ return res;
+ }
+ return NULL;
+}
+
+// 1 = dir
+// 2 = filter
+// 3 = sperator
+// 4 = [f]iles, [d]irs
+static TCHAR *parseListDir(ARGUMENTSINFO *ai) {
+
+ HANDLE hFind;
+ BOOL bFiles, bDirs;
+ WIN32_FIND_DATA ffd;
+ TCHAR tszFirst[MAX_PATH], *tszRes, *tszSeperator, *tszFilter;
+
+ if (ai->argc < 2)
+ return NULL;
+
+ tszFirst[0] = 0;
+ tszSeperator = _T("\r\n");
+ tszFilter = _T("*");
+ tszRes = NULL;
+ bFiles = bDirs = TRUE;
+ if (ai->argc > 1) {
+ _tcsncpy(tszFirst, ai->targv[1], SIZEOF(tszFirst)-1);
+ }
+ if (ai->argc > 2) {
+ tszFilter = ai->targv[2];
+ }
+ if (ai->argc > 3) {
+ tszSeperator = ai->targv[3];
+ }
+ if (ai->argc > 4) {
+ if (*ai->targv[4] == _T('f')) {
+ bDirs = FALSE;
+ }
+ if (*ai->targv[4] == _T('d')) {
+ bFiles = FALSE;
+ }
+ }
+ if (tszFirst[_tcslen(tszFirst)-1] == _T('\\')) {
+ _tcsncat(tszFirst, tszFilter, SIZEOF(tszFirst) - _tcslen(tszFirst) - 1);
+ }
+ else {
+ _tcsncat(tszFirst, _T("\\"), SIZEOF(tszFirst) - _tcslen(tszFirst) - 1);
+ _tcsncat(tszFirst, tszFilter, SIZEOF(tszFirst) - _tcslen(tszFirst) - 1);
+ }
+ hFind = FindFirstFile(tszFirst, &ffd);
+ if (hFind == INVALID_HANDLE_VALUE) {
+ return NULL;
+ }
+ if (((ffd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) && (bDirs)) || ((!(ffd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)) && (bFiles))) {
+ tszRes = (TCHAR*)mir_alloc((_tcslen(ffd.cFileName) + _tcslen(tszSeperator) + 1)*sizeof(TCHAR));
+ _tcscpy(tszRes, ffd.cFileName);
+ }
+ while (FindNextFile(hFind, &ffd) != 0) {
+ if (((ffd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) && (bDirs)) || ((!(ffd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)) && (bFiles))) {
+ if (tszRes != NULL) {
+ _tcscat(tszRes, tszSeperator);
+ tszRes = (TCHAR*)mir_realloc(tszRes, (_tcslen(tszRes) + _tcslen(ffd.cFileName) + _tcslen(tszSeperator) + 1)*sizeof(TCHAR));
+ }
+ else {
+ tszRes = (TCHAR*)mir_alloc((_tcslen(ffd.cFileName) + _tcslen(tszSeperator) + 1)*sizeof(TCHAR));
+ _tcscpy(tszRes, _T(""));
+ }
+ _tcscat(tszRes, ffd.cFileName);
+ }
+ }
+ FindClose(hFind);
+
+ return tszRes;
+}
+
+#ifndef WINE
+static BOOL CALLBACK MyProcessEnumerator(DWORD dwPID, WORD wTask, char *szProcess, LPARAM lParam) {
+
+ char **szProc;
+
+ szProc = (char **)lParam;
+ if ((*szProc != NULL) && (!_stricmp(*szProc, szProcess))) {
+ *szProc = NULL;
+ }
+
+ return TRUE;
+}
+
+static TCHAR *parseProcessRunning(ARGUMENTSINFO *ai) {
+
+ char *szProc, *ref;
+
+ if (ai->argc != 2) {
+ return NULL;
+ }
+
+ szProc = ref = mir_u2a(ai->targv[1]);
+
+ EnumProcs((PROCENUMPROC) MyProcessEnumerator, (LPARAM)&szProc);
+ if (szProc != NULL) {
+ ai->flags |= AIF_FALSE;
+ }
+ mir_free(ref);
+ return mir_tstrdup(_T(""));
+}
+#endif
+
+static TCHAR *parseRegistryValue(ARGUMENTSINFO *ai) {
+
+ HKEY hKey;
+ TCHAR *key, *subKey, *cur, *res;
+ DWORD len, type;
+ int err;
+
+ if (ai->argc != 3) {
+ return NULL;
+ }
+ key = subKey = mir_tstrdup(ai->targv[1]);
+ if (subKey == NULL) {
+ return NULL;
+ }
+ cur = _tcschr(subKey, _T('\\'));
+ if (cur == NULL) {
+ return NULL;
+ }
+ *cur = _T('\0');
+ if (!_tcscmp(subKey, _T("HKEY_CLASSES_ROOT"))) {
+ hKey = HKEY_CLASSES_ROOT;
+ }
+ else if (!_tcscmp(subKey, _T("HKEY_CURRENT_USER"))) {
+ hKey = HKEY_CURRENT_USER;
+ }
+ else if (!_tcscmp(subKey, _T("HKEY_LOCAL_MACHINE"))) {
+ hKey = HKEY_LOCAL_MACHINE;
+ }
+ else if (!_tcscmp(subKey, _T("HKEY_USERS"))) {
+ hKey = HKEY_USERS;
+ }
+ else {
+ mir_free(key);
+ return NULL;
+ }
+ subKey = cur+1;
+ if (RegOpenKeyEx(hKey, subKey, 0, KEY_READ, &hKey) != ERROR_SUCCESS) {
+ mir_free(key);
+ return NULL;
+ }
+ mir_free(key);
+ len = MAX_REGVALUE_LENGTH+1;
+ res = (TCHAR*)mir_alloc(len*sizeof(TCHAR));
+ if (res == NULL) {
+ return NULL;
+ }
+ ZeroMemory(res, len);
+ err = RegQueryValueEx(hKey, ai->targv[2], NULL, &type, (BYTE*)res, &len);
+ if ((err != ERROR_SUCCESS) || (type != REG_SZ)) {
+ RegCloseKey(hKey);
+ mir_free(res);
+ return NULL;
+ }
+ RegCloseKey(hKey);
+
+ return res;
+}
+
+static int TsToSystemTime(SYSTEMTIME *sysTime, time_t timestamp) {
+
+ struct tm *pTime;
+
+ pTime = localtime(&timestamp);
+ if (pTime == NULL) {
+ return -1;
+ }
+ ZeroMemory(sysTime, sizeof(SYSTEMTIME));
+ sysTime->wDay = pTime->tm_mday;
+ sysTime->wDayOfWeek = pTime->tm_wday;
+ sysTime->wHour = pTime->tm_hour;
+ sysTime->wMinute = pTime->tm_min;
+ sysTime->wMonth = pTime->tm_mon + 1;
+ sysTime->wSecond = pTime->tm_sec;
+ sysTime->wYear = pTime->tm_year + 1900;
+
+ return 0;
+}
+
+static TCHAR *parseTimestamp2Date(ARGUMENTSINFO *ai) {
+
+ int len;
+ time_t timestamp;
+ SYSTEMTIME sysTime;
+ TCHAR *szFormat, *res;
+
+ if (ai->argc <= 1) {
+ return NULL;
+ }
+ timestamp = ttoi(ai->targv[1]);
+ if (timestamp == 0) {
+ return NULL;
+ }
+ if ((ai->argc == 2) || ((ai->argc > 2) && (_tcslen(ai->targv[2]) == 0))) {
+ szFormat = NULL;
+ }
+ else {
+ szFormat = ai->targv[2];
+ }
+ if (TsToSystemTime(&sysTime, timestamp) != 0) {
+ return NULL;
+ }
+ len = GetDateFormat(LOCALE_USER_DEFAULT, 0, &sysTime, szFormat, NULL, 0);
+ res = (TCHAR*)mir_calloc((len+1) * sizeof(TCHAR));
+ if (res == NULL) {
+ return NULL;
+ }
+ if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &sysTime, szFormat, res, len) == 0) {
+ mir_free(res);
+ return NULL;
+ }
+
+ return res;
+}
+
+static TCHAR *parseTimestamp2Time(ARGUMENTSINFO *ai) {
+
+ int len;
+ time_t timestamp;
+ SYSTEMTIME sysTime;
+ TCHAR *szFormat, *res;
+
+ if (ai->argc <= 1) {
+ return NULL;
+ }
+ timestamp = ttoi(ai->targv[1]);
+ if (timestamp == 0) {
+ return NULL;
+ }
+ if ((ai->argc == 2) || ((ai->argc > 2) && (_tcslen(ai->targv[2]) == 0))) {
+ szFormat = NULL;
+ }
+ else {
+ szFormat = ai->targv[2];
+ }
+ if (TsToSystemTime(&sysTime, timestamp) != 0) {
+ return NULL;
+ }
+ len = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &sysTime, szFormat, NULL, 0);
+ res = (TCHAR*)mir_alloc((len+1)*sizeof(TCHAR));
+ if (res == NULL) {
+ return NULL;
+ }
+ if (GetTimeFormat(LOCALE_USER_DEFAULT, 0, &sysTime, szFormat, res, len) == 0) {
+ mir_free(res);
+ return NULL;
+ }
+
+ return res;
+}
+
+static TCHAR *parseTextFile(ARGUMENTSINFO *ai) {
+
+ int lineNo, lineCount, csz;
+ unsigned int icur, bufSz;
+ HANDLE hFile;
+ DWORD fileSz, readSz, totalReadSz;
+ unsigned long linePos;
+ TCHAR tUC, *res;
+ BYTE *pBuf, *pCur;
+
+ if (ai->argc != 3) {
+ return NULL;
+ }
+ lineNo = ttoi(ai->targv[2]);
+ hFile = CreateFile(ai->targv[1], GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ return NULL;
+ }
+ fileSz = GetFileSize(hFile, NULL);
+ if (fileSz == INVALID_FILE_SIZE) {
+ CloseHandle(hFile);
+ return NULL;
+ }
+ ReadFile(hFile, &tUC, sizeof(TCHAR), &readSz, NULL);
+ if (tUC != (TCHAR)0xFEFF) {
+ tUC = 0;
+ csz = sizeof(char);
+ SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
+ }
+ else {
+
+ csz = sizeof(TCHAR);
+
+ }
+ totalReadSz = 0;
+ lineCount = 1;
+ if (*ai->targv[2] == _T('0')) {
+ // complete file
+ bufSz = fileSz + csz;
+ pBuf = (PBYTE)mir_calloc(bufSz);
+ if (pBuf == NULL)
+ return NULL;
+
+ if (ReadFile(hFile, pBuf, bufSz-csz, &readSz, NULL) == 0) {
+ CloseHandle(hFile);
+ mir_free(pBuf);
+ return NULL;
+ }
+ CloseHandle(hFile);
+
+ if (tUC) {
+ res = (TCHAR*)pBuf;
+ }
+ else {
+ res = mir_a2t((char *)pBuf);
+ mir_free(pBuf);
+ }
+
+
+ return res;
+ }
+ bufSz = TXTFILEBUFSZ*csz;
+ pBuf = (PBYTE)mir_calloc(bufSz);
+ if (pBuf == NULL) {
+ return NULL;
+ }
+ // count number of lines
+ do {
+ ZeroMemory(pBuf, bufSz);
+ if (ReadFile(hFile, pBuf, bufSz-csz, &readSz, NULL) == 0) {
+ CloseHandle(hFile);
+ mir_free(pBuf);
+ return NULL;
+ }
+ totalReadSz += readSz;
+ for (pCur = pBuf;*pCur != '\0';pCur += csz) {
+ if (tUC) {
+ if (!_tcsncmp((TCHAR*)pCur, _T("\r\n"), 2)) {
+ lineCount += 1;
+ pCur += csz;
+ }
+ else if (*(TCHAR*)pCur == _T('\n')) {
+ lineCount += 1;
+ }
+ }
+ else {
+ if (!strncmp((char *)pCur, "\r\n", 2)) {
+ lineCount += 1;
+ pCur += csz;
+ }
+ else if (*(char *)pCur == '\n') {
+ lineCount += 1;
+ }
+ }
+ }
+ } while ( (totalReadSz < fileSz) && (readSz > 0));
+ if (lineNo < 0) {
+ lineNo = lineCount + lineNo + 1;
+ }
+ else if (*ai->targv[2] == _T('r')) {
+ lineNo = (rand()%lineCount)+1;
+ }
+ totalReadSz = 0;
+ lineCount = 1;
+ linePos = 0xFFFFFFFF;
+ SetFilePointer(hFile, tUC?csz:0, NULL, FILE_BEGIN);
+ // find the position in the file where the requested line starts
+ do {
+ if (ReadFile(hFile, pBuf, bufSz-csz, &readSz, NULL) == 0) {
+ CloseHandle(hFile);
+ return NULL;
+ }
+ totalReadSz += readSz;
+ for (pCur = pBuf;((pCur < pBuf+bufSz) && (linePos == 0xFFFFFFFF));pCur+=csz) {
+ if (lineCount == lineNo) {
+ linePos = (tUC?csz:0) + totalReadSz - readSz + pCur - pBuf;
+ }
+ if (tUC) {
+ if (!_tcsncmp((TCHAR*)pCur, _T("\r\n"), 2)) {
+ lineCount += 1;
+ pCur += csz;
+ }
+ else if (*(TCHAR*)pCur == _T('\n')) {
+ lineCount += 1;
+ }
+ }
+ else {
+ if (!strncmp((char *)pCur, "\r\n", 2)) {
+ lineCount += 1;
+ pCur += csz;
+ }
+ else if (*(char *)pCur == '\n') {
+ lineCount += 1;
+ }
+ }
+ }
+ if (((tUC) && (*(TCHAR*)pCur == _T('\r'))) || ((!tUC) && (*(char *)pCur == '\r'))) {
+ // in case the \r was at the end of the buffer, \n could be next
+ SetFilePointer(hFile, -1*csz, NULL, FILE_CURRENT);
+ totalReadSz -= csz;
+ }
+ } while ( (totalReadSz < fileSz) && (readSz > 0));
+ if (linePos < 0) {
+ CloseHandle(hFile);
+ mir_free(pBuf);
+ return NULL;
+ }
+ if (SetFilePointer(hFile, linePos, NULL, FILE_BEGIN) != linePos) {
+ CloseHandle(hFile);
+ mir_free(pBuf);
+ return NULL;
+ }
+ ZeroMemory(pBuf, bufSz);
+ pCur = pBuf;
+ do {
+ icur = 0;
+ if (ReadFile(hFile, pBuf, bufSz-csz, &readSz, NULL) == 0) {
+ mir_free(pBuf);
+ CloseHandle(hFile);
+ return NULL;
+ }
+ for (pCur = pBuf;(pCur < pBuf+readSz);pCur+=csz) {
+ if ((tUC) && ((!_tcsncmp((TCHAR*)pCur, _T("\r\n"), 2)) || (*(TCHAR*)pCur == _T('\n'))) ||
+ ((!tUC) && (((!strncmp((char *)pCur, "\r\n", 2)) || (*(char *)pCur == '\n'))))) {
+ CloseHandle(hFile);
+ if (tUC) {
+ *(TCHAR*)pCur = _T('\0');
+ }
+ else {
+ *(char *)pCur = '\0';
+ }
+
+ if (tUC) {
+ res = (TCHAR*)pBuf;
+ }
+ else {
+ res = mir_a2t((char *)pBuf);
+ mir_free(pBuf);
+ }
+
+ return res;
+ }
+ }
+ if (((DWORD)(linePos+(pCur-pBuf)) == fileSz)) { // eof
+ CloseHandle(hFile);
+
+ if (tUC) {
+ res = (TCHAR*)pBuf;
+ }
+ else {
+ res = mir_a2t((char *)pBuf);
+ mir_free(pBuf);
+ }
+
+ return res;
+ }
+ if (readSz == bufSz-csz) {
+ // buffer must be increased
+ bufSz += TXTFILEBUFSZ*csz;
+ if (((tUC) && (*(TCHAR*)pCur == _T('\r'))) || ((!tUC) && (*(char *)pCur == '\r'))) {
+ pCur -= csz;
+ }
+ icur = pCur - pBuf;
+ pBuf = (PBYTE)mir_realloc(pBuf, bufSz);
+ pCur = pBuf+icur;
+ ZeroMemory(pCur+1, TXTFILEBUFSZ*csz);
+ }
+ } while (readSz > 0);
+ CloseHandle(hFile);
+
+ return NULL;
+}
+
+#if _WIN32_WINNT>=0x0500
+static TCHAR *parseUpTime(ARGUMENTSINFO *ai) {
+
+ HQUERY hQuery;
+ PDH_STATUS pdhStatus;
+ PDH_FMT_COUNTERVALUE cValue;
+ HCOUNTER hCounter;
+ TCHAR szVal[32];
+
+ if (ai->argc != 1) {
+ return NULL;
+ }
+
+ pdhStatus = PdhOpenQuery (NULL, 0, &hQuery);
+ if (pdhStatus != ERROR_SUCCESS) {
+ return NULL;
+ }
+ pdhStatus = PdhAddCounter(hQuery, _T("\\System\\System Up Time"), 0, &hCounter);
+ if (pdhStatus != ERROR_SUCCESS) {
+ pdhStatus = PdhCloseQuery(hQuery);
+ return NULL;
+ }
+ pdhStatus = PdhCollectQueryData(hQuery);
+ if (pdhStatus != ERROR_SUCCESS) {
+ PdhRemoveCounter(hCounter);
+ pdhStatus = PdhCloseQuery(hQuery);
+ return NULL;
+ }
+ pdhStatus = PdhGetFormattedCounterValue(hCounter, PDH_FMT_LARGE, (LPDWORD)NULL, &cValue);
+ if (pdhStatus != ERROR_SUCCESS) {
+ PdhRemoveCounter(hCounter);
+ pdhStatus = PdhCloseQuery(hQuery);
+ return NULL;
+ }
+ mir_sntprintf(szVal, SIZEOF(szVal), _T("%u"), cValue.largeValue);
+ PdhRemoveCounter(hCounter);
+ pdhStatus = PdhCloseQuery(hQuery);
+
+ return mir_tstrdup(szVal);
+}
+#endif
+
+static TCHAR *parseUserName(ARGUMENTSINFO *ai) {
+
+ DWORD len;
+ TCHAR *res;
+
+ if (ai->argc != 1) {
+ return NULL;
+ }
+ ai->flags |= AIF_DONTPARSE;
+ len = UNLEN;
+ res = (TCHAR*)mir_alloc(len + 1);
+ if (res == NULL) {
+ return NULL;
+ }
+ ZeroMemory(res, len + 1);
+ if (!GetUserName(res, &len)) {
+ mir_free(res);
+ return NULL;
+ }
+ return res;
+}
+
+// clipboard support
+static TCHAR *parseClipboard(ARGUMENTSINFO *ai) {
+
+ TCHAR *res;
+
+ if (ai->argc != 1)
+ return NULL;
+
+ ai->flags |= AIF_DONTPARSE;
+
+ res = NULL;
+
+ if (IsClipboardFormatAvailable(CF_TEXT)) {
+ if (OpenClipboard(NULL)) {
+ HANDLE hData = NULL;
+ TCHAR* tszText = NULL;
+ int len = 0;
+
+ hData = GetClipboardData(CF_UNICODETEXT);
+
+ if (hData != NULL) {
+ tszText = (TCHAR*)GlobalLock(hData);
+ len = _tcslen(tszText);
+ res = (TCHAR*)mir_alloc((len + 1) * sizeof(TCHAR));
+ _tcscpy(res, tszText);
+ res[len] = _T('\0');
+ GlobalUnlock(hData);
+ }
+ CloseClipboard();
+ } }
+
+ return res;
+}
+
+int registerSystemTokens() {
+
+ registerIntToken(_T(COMPUTERNAME), parseComputerName, TRF_FIELD, "System Functions\tcomputer name");
+#if _WIN32_WINNT>=0x0500
+ registerIntToken(_T(CPULOAD), parseCpuLoad, TRF_FUNCTION, "System Functions\t(x)\tcpu load of process x (without extension) (x is optional)");
+#endif
+ registerIntToken(_T(CDATE), parseCurrentDate, TRF_FUNCTION, "System Functions\t(x)\tcurrent date in format y (y is optional)");
+ registerIntToken(_T(CTIME), parseCurrentTime, TRF_FUNCTION, "System Functions\t(x)\tcurrent time in format y (y is optional)");
+ registerIntToken(_T(DIRECTORY), parseDirectory, TRF_FUNCTION, "System Functions\t(x,y)\tthe directory y directories above x");
+ registerIntToken(_T(DIRECTORY2), parseDirectory2, TRF_FUNCTION, "System Functions\t(x,y)\tstrips y directories from x");
+ registerIntToken(_T(DIFFTIME), parseDiffTime, TRF_FUNCTION, "System Functions\t(x,y)\tnumber of seconds between date x and y (x and y in format: M/d/yy H:m:s)");
+ registerIntToken(_T(DIREXISTS), parseDirExists, TRF_FUNCTION, "System Functions\t(x)\tTRUE if directory x exists");
+ registerIntToken(_T(FILEEXISTS), parseFileExists, TRF_FUNCTION, "System Functions\t(x)\tTRUE if file x exists");
+ registerIntToken(_T(FINDWINDOW), parseFindWindow, TRF_FUNCTION, "System Functions\t(x)\twindow title of first window of class x");
+ registerIntToken(_T(LISTDIR), parseListDir, TRF_FUNCTION, "System Functions\t(x,y,z)\tshows files and directories of directory z, with filter y, separated by z (y and z optional)");
+#ifndef WINE
+ registerIntToken(_T(PROCESSRUNNING), parseProcessRunning, TRF_FUNCTION, "System Functions\t(x)\tTRUE if process x is running");
+#endif
+ registerIntToken(_T(REGISTRYVALUE), parseRegistryValue, TRF_FUNCTION, "System Functions\t(x,y)\tvalue y from registry key x (REG_SZ (string) values only)");
+ registerIntToken(_T(TIMESTAMP2DATE), parseTimestamp2Date, TRF_FUNCTION, "System Functions\t(x,y)\tformats timestamp x (seconds since 1/1/1970) in date format y");
+ registerIntToken(_T(TIMESTAMP2TIME), parseTimestamp2Time, TRF_FUNCTION, "System Functions\t(x,y)\tformats timestamp x (seconds since 1/1/1970) in time format y");
+ registerIntToken(_T(TXTFILE), parseTextFile, TRF_FUNCTION, "System Functions\t(x,y)\ty > 0: line number y from file x, y = 0: the whole file, y < 0: line y counted from the end, y = r: random line");
+#if _WIN32_WINNT>=0x0500
+ registerIntToken(_T(UPTIME), parseUpTime, TRF_FIELD, "System Functions\tuptime in seconds");
+#endif
+ if (!ServiceExists( MS_UTILS_REPLACEVARS ))
+ registerIntToken(_T(ENVIRONMENTVARIABLE), parseEnvironmentVariable, TRF_FUNCTION , "Miranda Core OS\t(%xxxxxxx%)\tany environment variable defined in current Windows session (like %systemroot%, %allusersprofile%, etc.)");
+ else {
+ registerIntToken(_T(ENVIRONMENTVARIABLE), parseEnvironmentVariable, TRF_FUNCTION , "System Functions\t(x)\texpand environment variable x");
+ registerIntToken(_T(USERNAME), parseUserName, TRF_FIELD , "System Functions\tuser name");
+ }
+
+ srand((unsigned int)GetTickCount());
+
+ registerIntToken(_T(CLIPBOARD), parseClipboard, TRF_FIELD, "System Functions\ttext from clipboard");
+
+ return 0;
+}
diff --git a/plugins/Variables/src/parse_system.h b/plugins/Variables/src/parse_system.h
new file mode 100644
index 0000000000..d4349130f7
--- /dev/null
+++ b/plugins/Variables/src/parse_system.h
@@ -0,0 +1,41 @@
+/*
+ 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
+*/
+#define COMPUTERNAME "computername"
+#define CPULOAD "cpuload"
+#define CDATE "cdate"
+#define CTIME "ctime"
+#define DIRECTORY "directory"
+#define DIRECTORY2 "directory2"
+#define DIFFTIME "difftime"
+#define DIREXISTS "direxists"
+#define ENVIRONMENTVARIABLE "env_var"
+#define FILEEXISTS "fileexists"
+#define FINDWINDOW "findwindow"
+#define LISTDIR "ls"
+#define PROCESSRUNNING "processrunning"
+#define REGISTRYVALUE "regvalue"
+#define TIMESTAMP2DATE "ts2date"
+#define TIMESTAMP2TIME "ts2time"
+#define TXTFILE "txtfile"
+#define UPTIME "uptime"
+#define USERNAME "username"
+#define CLIPBOARD "clipboard"
+
+#define TXTFILEBUFSZ 4096
+#define MAX_REGVALUE_LENGTH 1024
diff --git a/plugins/Variables/src/parse_variables.cpp b/plugins/Variables/src/parse_variables.cpp
new file mode 100644
index 0000000000..1be98fdf5e
--- /dev/null
+++ b/plugins/Variables/src/parse_variables.cpp
@@ -0,0 +1,173 @@
+/*
+ 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_variables.h"
+
+// this is for get and put(s)
+static CRITICAL_SECTION csVarRegister;
+static VARIABLEREGISTER *vr = NULL;
+static int vrCount = 0;
+
+static int addToVariablesRegister(TCHAR *szName, TCHAR *szText) {
+
+ int i;
+
+ if ((szName == NULL) || (szText == NULL) || (_tcslen(szName) <= 0)) {
+ return -1;
+ }
+ EnterCriticalSection(&csVarRegister);
+ for (i=0;i<vrCount;i++) {
+ if ((!_tcscmp(vr[i].szName, szName))) { // && (vr[i].dwOwnerThread == GetCurrentThreadId())) {
+ mir_free(vr[i].szText);
+ vr[i].szText = mir_tstrdup(szText);
+ LeaveCriticalSection(&csVarRegister);
+
+ return 0;
+ }
+ }
+ vr = ( VARIABLEREGISTER* )mir_realloc(vr, (vrCount+1)*sizeof(VARIABLEREGISTER));
+ if (vr == NULL) {
+ LeaveCriticalSection(&csVarRegister);
+ return -1;
+ }
+ vr[vrCount].szName = mir_tstrdup(szName);
+ vr[vrCount].szText = mir_tstrdup(szText);
+ vr[vrCount].dwOwnerThread = GetCurrentThreadId();
+ vrCount += 1;
+ LeaveCriticalSection(&csVarRegister);
+
+ return 0;
+}
+
+static TCHAR *searchVariableRegister(TCHAR *szName) {
+
+ TCHAR *res;
+ int i;
+
+ res = NULL;
+ if ((szName == NULL) || (_tcslen(szName) <= 0)) {
+ return NULL;
+ }
+ EnterCriticalSection(&csVarRegister);
+ for (i=0;i<vrCount;i++) {
+ if ((!_tcscmp(vr[i].szName, szName))) { // && (vr[i].dwOwnerThread == GetCurrentThreadId())) {
+ res = mir_tstrdup(vr[i].szText);
+ LeaveCriticalSection(&csVarRegister);
+ return res;
+ }
+ }
+ LeaveCriticalSection(&csVarRegister);
+
+ return NULL;
+}
+
+int clearVariableRegister() {
+
+ int i, count;
+
+ count = 0;
+ EnterCriticalSection(&csVarRegister);
+ for (i=0;i<vrCount;i++) {
+ if (vr[i].dwOwnerThread == GetCurrentThreadId()) {
+ mir_free(vr[i].szName);
+ mir_free(vr[i].szText);
+ if (vrCount > 1) {
+ memcpy(&vr[i], &vr[vrCount-1], sizeof(VARIABLEREGISTER));
+ vr = ( VARIABLEREGISTER* )mir_realloc(vr, (vrCount-1)*sizeof(VARIABLEREGISTER));
+ if (vr == NULL) {
+ LeaveCriticalSection(&csVarRegister);
+ return -1;
+ }
+ vrCount -= 1;
+ }
+ else {
+ mir_free(vr);
+ vr = NULL;
+ vrCount = 0;
+ }
+ count += 1;
+ }
+ }
+ LeaveCriticalSection(&csVarRegister);
+
+ return count;
+}
+
+static TCHAR *parsePut(ARGUMENTSINFO *ai) {
+
+ FORMATINFO fi;
+
+ if (ai->argc != 3) {
+ return NULL;
+ }
+// ai->flags |= AIF_DONTPARSE;
+ if (addToVariablesRegister(ai->targv[1], ai->targv[2])) {
+ return NULL;
+ }
+
+ memcpy(&fi, ai->fi, sizeof(fi));
+ fi.tszFormat = ai->targv[2];
+ fi.flags |= FIF_TCHAR;
+
+ return formatString(&fi);
+}
+
+static TCHAR *parsePuts(ARGUMENTSINFO *ai) {
+
+ if (ai->argc != 3) {
+ return NULL;
+ }
+// ai->flags |= AIF_DONTPARSE;
+ if (addToVariablesRegister(ai->targv[1], ai->targv[2])) {
+ return NULL;
+ }
+
+ return mir_tstrdup(_T(""));
+}
+
+static TCHAR *parseGet(ARGUMENTSINFO *ai) {
+
+ TCHAR *szText;
+
+ if (ai->argc != 2) {
+ return NULL;
+ }
+// ai->flags |= AIF_DONTPARSE;
+ szText = searchVariableRegister(ai->targv[1]);
+ if (szText == NULL) {
+ return NULL;
+ }
+
+ return szText;
+}
+
+int registerVariablesTokens()
+{
+ registerIntToken(_T(GET), parseGet, TRF_FUNCTION, "Variables\t(x)\tvariable set by put(s) with name x");
+ registerIntToken(_T(PUT), parsePut, TRF_FUNCTION, "Variables\t(x,y)\tx, and stores y as variable named x");//TRF_UNPARSEDARGS);
+ registerIntToken(_T(PUTS), parsePuts, TRF_FUNCTION, "Variables\t(x,y)\tonly stores y as variables x");//TRF_UNPARSEDARGS);
+ InitializeCriticalSection(&csVarRegister);
+
+ return 0;
+}
+
+void unregisterVariablesTokens()
+{
+ DeleteCriticalSection(&csVarRegister);
+}
diff --git a/plugins/Variables/src/parse_variables.h b/plugins/Variables/src/parse_variables.h
new file mode 100644
index 0000000000..5bde654f5f
--- /dev/null
+++ b/plugins/Variables/src/parse_variables.h
@@ -0,0 +1,28 @@
+/*
+ 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
+*/
+typedef struct {
+ TCHAR *szName;
+ TCHAR *szText;
+ DWORD dwOwnerThread;
+} VARIABLEREGISTER;
+
+#define PUT "put"
+#define PUTS "puts"
+#define GET "get"
+
diff --git a/plugins/Variables/src/parse_xml.cpp b/plugins/Variables/src/parse_xml.cpp
new file mode 100644
index 0000000000..76f701e116
--- /dev/null
+++ b/plugins/Variables/src/parse_xml.cpp
@@ -0,0 +1,283 @@
+/*
+ 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_xml.h"
+
+#include <string.h>
+#include "libxml/xmlmemory.h"
+#include "libxml/debugXML.h"
+#include "libxml/HTMLtree.h"
+#include "libxml/xmlIO.h"
+#include "libxml/DOCBparser.h"
+#include "libxml/xinclude.h"
+#include "libxml/catalog.h"
+#include "libxslt/xslt.h"
+#include "libxslt/xsltInternals.h"
+#include "libxslt/transform.h"
+#include "libxslt/xsltutils.h"
+
+xsltStylesheetPtr (*pXsltParseStylesheetDoc)(xmlDocPtr doc);
+xmlDocPtr (*pXmlParseMemory)(const char * buffer, int size);
+
+void (*pXmlFree)(void *mem);
+xmlDocPtr (*pXmlParseFile)(const char * filename);
+void (*pXmlFreeDoc)(xmlDocPtr cur);
+void (*pXmlInitParser)(void);
+void (*pXmlCleanupParser)(void);
+int (*pXmlSubstituteEntitiesDefault)(int val);
+
+xsltStylesheetPtr (*pXsltParseStylesheetFile)(const xmlChar * filename);
+int (*pXsltSaveResultToString)(xmlChar ** doc_txt_ptr, int * doc_txt_len, xmlDocPtr result, xsltStylesheetPtr style);
+void (*pXsltFreeStylesheet)(xsltStylesheetPtr sheet);
+xmlDocPtr (*pXsltApplyStylesheet)(xsltStylesheetPtr style, xmlDocPtr doc, const char ** params);
+void (*pXsltCleanupGlobals)(void);
+
+/*
+ pattern, subject
+*/
+static TCHAR *parseXslts(ARGUMENTSINFO *ai) {
+
+ char *szStyleSheet, *szDoc;
+ TCHAR *tszRes;
+ xsltStylesheetPtr cur = NULL;
+ xmlDocPtr doc, res, sdoc;
+ xmlChar *xmlChRes = NULL;
+ int resLen;
+
+ if (ai->argc != 3) {
+ return NULL;
+ }
+
+ szStyleSheet = mir_t2a(ai->targv[1]);
+ szDoc = mir_t2a(ai->targv[2]);
+
+
+ log_debugA("calling xsltParseMemory");
+ sdoc = pXmlParseMemory(szStyleSheet, strlen(szStyleSheet));
+ if (sdoc == NULL) {
+
+ return NULL;
+ }
+
+ log_debugA("calling xsltParseStylesheetDoc");
+ cur = pXsltParseStylesheetDoc(sdoc);
+ if (cur == NULL) {
+ log_debugA("calling xsltFreeDoc");
+ pXmlFreeDoc(sdoc);
+
+ return NULL;
+ }
+
+ log_debugA("calling xsltParseMemory");
+ doc = pXmlParseMemory(szDoc, strlen(szDoc));
+ if (doc == NULL) {
+ log_debugA("calling xsltFreeDoc");
+ pXmlFreeDoc(sdoc);
+ log_debugA("calling xsltFreeStylesheet");
+ pXsltFreeStylesheet(cur);
+
+ return NULL;
+ }
+
+ log_debugA("calling xsltApplyStylesheet");
+ res = pXsltApplyStylesheet(cur, doc, NULL);
+ if (res == NULL) {
+ log_debugA("calling xsltFreeStylesheet");
+ pXsltFreeStylesheet(cur);
+ log_debugA("calling xsltFreeDoc");
+ pXmlFreeDoc(doc);
+ log_debugA("calling xsltFreeDoc");
+ pXmlFreeDoc(sdoc);
+
+ return NULL;
+ }
+
+ log_debugA("calling xsltSaveResultToString");
+ pXsltSaveResultToString(&xmlChRes, &resLen, res, cur);
+ log_debugA("calling xsltFreeStylesheet");
+ pXsltFreeStylesheet(cur);
+ log_debugA("calling xsltFreeDoc");
+ pXmlFreeDoc(res);
+ log_debugA("calling xsltFreeDoc");
+ pXmlFreeDoc(doc);
+ log_debugA("calling mir_free");
+ mir_free(szStyleSheet);
+ log_debugA("calling mir_free");
+ mir_free(szDoc);
+
+ tszRes = mir_a2t((char *)xmlChRes);
+
+ log_debugA("calling xmlFree");
+ pXmlFree(xmlChRes);
+
+ return tszRes;
+}
+
+/*
+ files
+*/
+static TCHAR *parseXsltf(ARGUMENTSINFO *ai) {
+
+ char *szStyleSheet, *szDoc;
+ TCHAR *tszRes;
+ xsltStylesheetPtr cur = NULL;
+ xmlDocPtr doc, res;
+ xmlChar *xmlChRes = NULL;
+ int resLen;
+
+ if (ai->argc != 3) {
+ return NULL;
+ }
+
+ szStyleSheet = mir_t2a(ai->targv[1]);
+ szDoc = mir_t2a(ai->targv[2]);
+
+
+ log_debugA("xslt with %s and %s", szStyleSheet, szDoc);
+
+ log_debugA("calling xsltParseStylesheetFile");
+ cur = pXsltParseStylesheetFile((const xmlChar *)szStyleSheet);
+ if (cur == NULL) {
+
+ return NULL;
+ }
+ log_debugA("result: %x", cur);
+
+ log_debugA("calling xmlParseFile");
+ doc = pXmlParseFile(szDoc);
+ if (doc == NULL) {
+ pXsltFreeStylesheet(cur);
+
+ return NULL;
+ }
+ log_debugA("result: %x", doc);
+
+ log_debugA("calling xsltApplyStylesheet");
+ res = pXsltApplyStylesheet(cur, doc, NULL);
+ if (res == NULL) {
+ pXsltFreeStylesheet(cur);
+ pXmlFreeDoc(doc);
+
+ return NULL;
+ }
+ log_debugA("result: %x", res);
+
+ log_debugA("calling xsltSaveResultToString");
+ pXsltSaveResultToString(&xmlChRes, &resLen, res, cur);
+
+ log_debugA("calling xsltFreeStylesheet(cur)");
+ pXsltFreeStylesheet(cur);
+
+ log_debugA("calling xmlFreeDoc(res)");
+ pXmlFreeDoc(res);
+
+ log_debugA("calling xmlFreeDoc(doc)");
+ pXmlFreeDoc(doc);
+
+ //log_debug("calling xsltCleanupGlobals");
+ //pXsltCleanupGlobals();
+
+ //log_debug("calling xmlCleanupParser");
+ //pXmlCleanupParser();
+
+ mir_free(szStyleSheet);
+ mir_free(szDoc);
+
+ tszRes = mir_a2t((char *)xmlChRes);
+
+ log_debugA("calling xmlFree");
+ pXmlFree(xmlChRes);
+
+ return tszRes;
+}
+
+int initXslt() {
+
+ HMODULE hModule;
+
+ hModule = LoadLibraryA("libxml2.dll");
+ if (hModule == NULL) {
+ char path[MAX_PATH];
+ char *cur;
+
+ GetModuleFileNameA(NULL, path, sizeof(path));
+ cur = strrchr(path, '\\');
+ if (cur != NULL)
+ strcpy(cur+1, "libxml2.dll");
+ else
+ strcpy(path, "libxml2.dll");
+ hModule = LoadLibraryA(path);
+ }
+ if (hModule == NULL) {
+ return -1;
+ }
+
+ pXmlParseFile = (struct _xmlDoc *(__cdecl *)(const char *))GetProcAddress(hModule, "xmlParseFile");
+ pXmlFreeDoc = (void (__cdecl *)(struct _xmlDoc *))GetProcAddress(hModule, "xmlFreeDoc");
+ pXmlCleanupParser = (void (__cdecl *)(void ))GetProcAddress(hModule, "xmlCleanupParser");
+ pXmlInitParser = (void (__cdecl *)(void ))GetProcAddress(hModule, "xmlInitParser");
+ pXmlParseMemory = (struct _xmlDoc *(__cdecl *)(const char *,int ))GetProcAddress(hModule, "xmlParseMemory");
+ pXmlFree = (void (__cdecl *)(void *))*((void (__cdecl **)(void *))GetProcAddress(hModule, "xmlFree"));
+ pXmlSubstituteEntitiesDefault = (int (__cdecl *)(int ))GetProcAddress(hModule, "xmlSubstituteEntitiesDefault");
+
+ hModule = LoadLibraryA("libxslt.dll");
+ if (hModule == NULL) {
+ char path[MAX_PATH];
+ char *cur;
+
+ GetModuleFileNameA(NULL, path, sizeof(path));
+ cur = strrchr(path, '\\');
+ if (cur != NULL)
+ strcpy(cur+1, "libxslt.dll");
+ else
+ strcpy(path, "libxslt.dll");
+ hModule = LoadLibraryA(path);
+ }
+ if (hModule == NULL) {
+ return -1;
+ }
+
+ /* xmlFree !!! pthreads? */
+
+ pXsltParseStylesheetFile = (struct _xsltStylesheet *(__cdecl *)(const unsigned char *))GetProcAddress(hModule, "xsltParseStylesheetFile");
+ pXsltFreeStylesheet = (void (__cdecl *)(struct _xsltStylesheet *))GetProcAddress(hModule, "xsltFreeStylesheet");
+ pXsltApplyStylesheet = (struct _xmlDoc *(__cdecl *)(struct _xsltStylesheet *,struct _xmlDoc *,const char ** ))GetProcAddress(hModule, "xsltApplyStylesheet");
+ pXsltSaveResultToString = (int (__cdecl *)(unsigned char ** ,int *,struct _xmlDoc *,struct _xsltStylesheet *))GetProcAddress(hModule, "xsltSaveResultToString");
+ pXsltCleanupGlobals = (void (__cdecl *)(void ))GetProcAddress(hModule, "xsltCleanupGlobals");
+ pXsltParseStylesheetDoc = (struct _xsltStylesheet *(__cdecl *)(struct _xmlDoc *))GetProcAddress(hModule, "xsltParseStylesheetDoc");
+
+ /* init */
+ pXmlInitParser();
+ pXmlSubstituteEntitiesDefault(1);
+
+ return 0;
+}
+
+int registerXsltTokens() {
+
+ if (initXslt() != 0) {
+ log_infoA("Variables: XSLT library not initialized");
+ return -1;
+ }
+
+ registerIntToken(_T(XSLTF), parseXsltf, TRF_FUNCTION, "XML\t(x,y)\tapply stylesheet file x to document file y");
+ registerIntToken(_T(XSLTS), parseXslts, TRF_FUNCTION, "XML\t(x,y)\tapply stylesheet x to document y");
+
+ return 0;
+}
diff --git a/plugins/Variables/src/parse_xml.h b/plugins/Variables/src/parse_xml.h
new file mode 100644
index 0000000000..51df56be79
--- /dev/null
+++ b/plugins/Variables/src/parse_xml.h
@@ -0,0 +1,2 @@
+#define XSLTF "xsltf"
+#define XSLTS "xslts" \ No newline at end of file
diff --git a/plugins/Variables/src/pcre/include/pcre.h b/plugins/Variables/src/pcre/include/pcre.h
new file mode 100644
index 0000000000..712bd3d714
--- /dev/null
+++ b/plugins/Variables/src/pcre/include/pcre.h
@@ -0,0 +1,503 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* This is the public header file for the PCRE library, to be #included by
+applications that call the PCRE functions.
+
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+#ifndef _PCRE_H
+#define _PCRE_H
+
+/* The current PCRE version information. */
+
+#define PCRE_MAJOR 8
+#define PCRE_MINOR 30
+#define PCRE_PRERELEASE
+#define PCRE_DATE 2012-02-04
+
+/* When an application links to a PCRE DLL in Windows, the symbols that are
+imported have to be identified as such. When building PCRE, the appropriate
+export setting is defined in pcre_internal.h, which includes this file. So we
+don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */
+
+#if defined(_WIN32) && !defined(PCRE_STATIC)
+# ifndef PCRE_EXP_DECL
+# define PCRE_EXP_DECL extern __declspec(dllimport)
+# endif
+# ifdef __cplusplus
+# ifndef PCRECPP_EXP_DECL
+# define PCRECPP_EXP_DECL extern __declspec(dllimport)
+# endif
+# ifndef PCRECPP_EXP_DEFN
+# define PCRECPP_EXP_DEFN __declspec(dllimport)
+# endif
+# endif
+#endif
+
+/* By default, we use the standard "extern" declarations. */
+
+#ifndef PCRE_EXP_DECL
+# ifdef __cplusplus
+# define PCRE_EXP_DECL extern "C"
+# else
+# define PCRE_EXP_DECL extern
+# endif
+#endif
+
+#ifdef __cplusplus
+# ifndef PCRECPP_EXP_DECL
+# define PCRECPP_EXP_DECL extern
+# endif
+# ifndef PCRECPP_EXP_DEFN
+# define PCRECPP_EXP_DEFN
+# endif
+#endif
+
+/* Have to include stdlib.h in order to ensure that size_t is defined;
+it is needed here for malloc. */
+
+#include <stdlib.h>
+
+/* Allow for C++ users */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Options. Some are compile-time only, some are run-time only, and some are
+both, so we keep them all distinct. However, almost all the bits in the options
+word are now used. In the long run, we may have to re-use some of the
+compile-time only bits for runtime options, or vice versa. In the comments
+below, "compile", "exec", and "DFA exec" mean that the option is permitted to
+be set for those functions; "used in" means that an option may be set only for
+compile, but is subsequently referenced in exec and/or DFA exec. Any of the
+compile-time options may be inspected during studying (and therefore JIT
+compiling). */
+
+#define PCRE_CASELESS 0x00000001 /* Compile */
+#define PCRE_MULTILINE 0x00000002 /* Compile */
+#define PCRE_DOTALL 0x00000004 /* Compile */
+#define PCRE_EXTENDED 0x00000008 /* Compile */
+#define PCRE_ANCHORED 0x00000010 /* Compile, exec, DFA exec */
+#define PCRE_DOLLAR_ENDONLY 0x00000020 /* Compile, used in exec, DFA exec */
+#define PCRE_EXTRA 0x00000040 /* Compile */
+#define PCRE_NOTBOL 0x00000080 /* Exec, DFA exec */
+#define PCRE_NOTEOL 0x00000100 /* Exec, DFA exec */
+#define PCRE_UNGREEDY 0x00000200 /* Compile */
+#define PCRE_NOTEMPTY 0x00000400 /* Exec, DFA exec */
+/* The next two are also used in exec and DFA exec */
+#define PCRE_UTF8 0x00000800 /* Compile (same as PCRE_UTF16) */
+#define PCRE_UTF16 0x00000800 /* Compile (same as PCRE_UTF8) */
+#define PCRE_NO_AUTO_CAPTURE 0x00001000 /* Compile */
+/* The next two are also used in exec and DFA exec */
+#define PCRE_NO_UTF8_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF16_CHECK) */
+#define PCRE_NO_UTF16_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF8_CHECK) */
+#define PCRE_AUTO_CALLOUT 0x00004000 /* Compile */
+#define PCRE_PARTIAL_SOFT 0x00008000 /* Exec, DFA exec */
+#define PCRE_PARTIAL 0x00008000 /* Backwards compatible synonym */
+#define PCRE_DFA_SHORTEST 0x00010000 /* DFA exec */
+#define PCRE_DFA_RESTART 0x00020000 /* DFA exec */
+#define PCRE_FIRSTLINE 0x00040000 /* Compile, used in exec, DFA exec */
+#define PCRE_DUPNAMES 0x00080000 /* Compile */
+#define PCRE_NEWLINE_CR 0x00100000 /* Compile, exec, DFA exec */
+#define PCRE_NEWLINE_LF 0x00200000 /* Compile, exec, DFA exec */
+#define PCRE_NEWLINE_CRLF 0x00300000 /* Compile, exec, DFA exec */
+#define PCRE_NEWLINE_ANY 0x00400000 /* Compile, exec, DFA exec */
+#define PCRE_NEWLINE_ANYCRLF 0x00500000 /* Compile, exec, DFA exec */
+#define PCRE_BSR_ANYCRLF 0x00800000 /* Compile, exec, DFA exec */
+#define PCRE_BSR_UNICODE 0x01000000 /* Compile, exec, DFA exec */
+#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* Compile, used in exec */
+#define PCRE_NO_START_OPTIMIZE 0x04000000 /* Compile, exec, DFA exec */
+#define PCRE_NO_START_OPTIMISE 0x04000000 /* Synonym */
+#define PCRE_PARTIAL_HARD 0x08000000 /* Exec, DFA exec */
+#define PCRE_NOTEMPTY_ATSTART 0x10000000 /* Exec, DFA exec */
+#define PCRE_UCP 0x20000000 /* Compile, used in exec, DFA exec */
+
+/* Exec-time and get/set-time error codes */
+
+#define PCRE_ERROR_NOMATCH (-1)
+#define PCRE_ERROR_NULL (-2)
+#define PCRE_ERROR_BADOPTION (-3)
+#define PCRE_ERROR_BADMAGIC (-4)
+#define PCRE_ERROR_UNKNOWN_OPCODE (-5)
+#define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */
+#define PCRE_ERROR_NOMEMORY (-6)
+#define PCRE_ERROR_NOSUBSTRING (-7)
+#define PCRE_ERROR_MATCHLIMIT (-8)
+#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */
+#define PCRE_ERROR_BADUTF8 (-10) /* Same for 8/16 */
+#define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16 */
+#define PCRE_ERROR_BADUTF8_OFFSET (-11) /* Same for 8/16 */
+#define PCRE_ERROR_BADUTF16_OFFSET (-11) /* Same for 8/16 */
+#define PCRE_ERROR_PARTIAL (-12)
+#define PCRE_ERROR_BADPARTIAL (-13)
+#define PCRE_ERROR_INTERNAL (-14)
+#define PCRE_ERROR_BADCOUNT (-15)
+#define PCRE_ERROR_DFA_UITEM (-16)
+#define PCRE_ERROR_DFA_UCOND (-17)
+#define PCRE_ERROR_DFA_UMLIMIT (-18)
+#define PCRE_ERROR_DFA_WSSIZE (-19)
+#define PCRE_ERROR_DFA_RECURSE (-20)
+#define PCRE_ERROR_RECURSIONLIMIT (-21)
+#define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */
+#define PCRE_ERROR_BADNEWLINE (-23)
+#define PCRE_ERROR_BADOFFSET (-24)
+#define PCRE_ERROR_SHORTUTF8 (-25)
+#define PCRE_ERROR_SHORTUTF16 (-25) /* Same for 8/16 */
+#define PCRE_ERROR_RECURSELOOP (-26)
+#define PCRE_ERROR_JIT_STACKLIMIT (-27)
+#define PCRE_ERROR_BADMODE (-28)
+#define PCRE_ERROR_BADENDIANNESS (-29)
+
+/* Specific error codes for UTF-8 validity checks */
+
+#define PCRE_UTF8_ERR0 0
+#define PCRE_UTF8_ERR1 1
+#define PCRE_UTF8_ERR2 2
+#define PCRE_UTF8_ERR3 3
+#define PCRE_UTF8_ERR4 4
+#define PCRE_UTF8_ERR5 5
+#define PCRE_UTF8_ERR6 6
+#define PCRE_UTF8_ERR7 7
+#define PCRE_UTF8_ERR8 8
+#define PCRE_UTF8_ERR9 9
+#define PCRE_UTF8_ERR10 10
+#define PCRE_UTF8_ERR11 11
+#define PCRE_UTF8_ERR12 12
+#define PCRE_UTF8_ERR13 13
+#define PCRE_UTF8_ERR14 14
+#define PCRE_UTF8_ERR15 15
+#define PCRE_UTF8_ERR16 16
+#define PCRE_UTF8_ERR17 17
+#define PCRE_UTF8_ERR18 18
+#define PCRE_UTF8_ERR19 19
+#define PCRE_UTF8_ERR20 20
+#define PCRE_UTF8_ERR21 21
+
+/* Specific error codes for UTF-16 validity checks */
+
+#define PCRE_UTF16_ERR0 0
+#define PCRE_UTF16_ERR1 1
+#define PCRE_UTF16_ERR2 2
+#define PCRE_UTF16_ERR3 3
+#define PCRE_UTF16_ERR4 4
+
+/* Request types for pcre_fullinfo() */
+
+#define PCRE_INFO_OPTIONS 0
+#define PCRE_INFO_SIZE 1
+#define PCRE_INFO_CAPTURECOUNT 2
+#define PCRE_INFO_BACKREFMAX 3
+#define PCRE_INFO_FIRSTBYTE 4
+#define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */
+#define PCRE_INFO_FIRSTTABLE 5
+#define PCRE_INFO_LASTLITERAL 6
+#define PCRE_INFO_NAMEENTRYSIZE 7
+#define PCRE_INFO_NAMECOUNT 8
+#define PCRE_INFO_NAMETABLE 9
+#define PCRE_INFO_STUDYSIZE 10
+#define PCRE_INFO_DEFAULT_TABLES 11
+#define PCRE_INFO_OKPARTIAL 12
+#define PCRE_INFO_JCHANGED 13
+#define PCRE_INFO_HASCRORLF 14
+#define PCRE_INFO_MINLENGTH 15
+#define PCRE_INFO_JIT 16
+#define PCRE_INFO_JITSIZE 17
+
+/* Request types for pcre_config(). Do not re-arrange, in order to remain
+compatible. */
+
+#define PCRE_CONFIG_UTF8 0
+#define PCRE_CONFIG_NEWLINE 1
+#define PCRE_CONFIG_LINK_SIZE 2
+#define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3
+#define PCRE_CONFIG_MATCH_LIMIT 4
+#define PCRE_CONFIG_STACKRECURSE 5
+#define PCRE_CONFIG_UNICODE_PROPERTIES 6
+#define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7
+#define PCRE_CONFIG_BSR 8
+#define PCRE_CONFIG_JIT 9
+#define PCRE_CONFIG_UTF16 10
+#define PCRE_CONFIG_JITTARGET 11
+
+/* Request types for pcre_study(). Do not re-arrange, in order to remain
+compatible. */
+
+#define PCRE_STUDY_JIT_COMPILE 0x0001
+
+/* Bit flags for the pcre[16]_extra structure. Do not re-arrange or redefine
+these bits, just add new ones on the end, in order to remain compatible. */
+
+#define PCRE_EXTRA_STUDY_DATA 0x0001
+#define PCRE_EXTRA_MATCH_LIMIT 0x0002
+#define PCRE_EXTRA_CALLOUT_DATA 0x0004
+#define PCRE_EXTRA_TABLES 0x0008
+#define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010
+#define PCRE_EXTRA_MARK 0x0020
+#define PCRE_EXTRA_EXECUTABLE_JIT 0x0040
+
+/* Types */
+
+struct real_pcre; /* declaration; the definition is private */
+typedef struct real_pcre pcre;
+
+struct real_pcre16; /* declaration; the definition is private */
+typedef struct real_pcre16 pcre16;
+
+struct real_pcre_jit_stack; /* declaration; the definition is private */
+typedef struct real_pcre_jit_stack pcre_jit_stack;
+
+struct real_pcre16_jit_stack; /* declaration; the definition is private */
+typedef struct real_pcre16_jit_stack pcre16_jit_stack;
+
+/* If PCRE is compiled with 16 bit character support, PCRE_UCHAR16 must contain
+a 16 bit wide signed data type. Otherwise it can be a dummy data type since
+pcre16 functions are not implemented. There is a check for this in pcre_internal.h. */
+#ifndef PCRE_UCHAR16
+#define PCRE_UCHAR16 unsigned short
+#endif
+
+#ifndef PCRE_SPTR16
+#define PCRE_SPTR16 const PCRE_UCHAR16 *
+#endif
+
+/* When PCRE is compiled as a C++ library, the subject pointer type can be
+replaced with a custom type. For conventional use, the public interface is a
+const char *. */
+
+#ifndef PCRE_SPTR
+#define PCRE_SPTR const char *
+#endif
+
+/* The structure for passing additional data to pcre_exec(). This is defined in
+such as way as to be extensible. Always add new fields at the end, in order to
+remain compatible. */
+
+typedef struct pcre_extra {
+ unsigned long int flags; /* Bits for which fields are set */
+ void *study_data; /* Opaque data from pcre_study() */
+ unsigned long int match_limit; /* Maximum number of calls to match() */
+ void *callout_data; /* Data passed back in callouts */
+ const unsigned char *tables; /* Pointer to character tables */
+ unsigned long int match_limit_recursion; /* Max recursive calls to match() */
+ unsigned char **mark; /* For passing back a mark pointer */
+ void *executable_jit; /* Contains a pointer to a compiled jit code */
+} pcre_extra;
+
+/* Same structure as above, but with 16 bit char pointers. */
+
+typedef struct pcre16_extra {
+ unsigned long int flags; /* Bits for which fields are set */
+ void *study_data; /* Opaque data from pcre_study() */
+ unsigned long int match_limit; /* Maximum number of calls to match() */
+ void *callout_data; /* Data passed back in callouts */
+ const unsigned char *tables; /* Pointer to character tables */
+ unsigned long int match_limit_recursion; /* Max recursive calls to match() */
+ PCRE_UCHAR16 **mark; /* For passing back a mark pointer */
+ void *executable_jit; /* Contains a pointer to a compiled jit code */
+} pcre16_extra;
+
+/* The structure for passing out data via the pcre_callout_function. We use a
+structure so that new fields can be added on the end in future versions,
+without changing the API of the function, thereby allowing old clients to work
+without modification. */
+
+typedef struct pcre_callout_block {
+ int version; /* Identifies version of block */
+ /* ------------------------ Version 0 ------------------------------- */
+ int callout_number; /* Number compiled into pattern */
+ int *offset_vector; /* The offset vector */
+ PCRE_SPTR subject; /* The subject being matched */
+ int subject_length; /* The length of the subject */
+ int start_match; /* Offset to start of this match attempt */
+ int current_position; /* Where we currently are in the subject */
+ int capture_top; /* Max current capture */
+ int capture_last; /* Most recently closed capture */
+ void *callout_data; /* Data passed in with the call */
+ /* ------------------- Added for Version 1 -------------------------- */
+ int pattern_position; /* Offset to next item in the pattern */
+ int next_item_length; /* Length of next item in the pattern */
+ /* ------------------- Added for Version 2 -------------------------- */
+ const unsigned char *mark; /* Pointer to current mark or NULL */
+ /* ------------------------------------------------------------------ */
+} pcre_callout_block;
+
+/* Same structure as above, but with 16 bit char pointers. */
+
+typedef struct pcre16_callout_block {
+ int version; /* Identifies version of block */
+ /* ------------------------ Version 0 ------------------------------- */
+ int callout_number; /* Number compiled into pattern */
+ int *offset_vector; /* The offset vector */
+ PCRE_SPTR16 subject; /* The subject being matched */
+ int subject_length; /* The length of the subject */
+ int start_match; /* Offset to start of this match attempt */
+ int current_position; /* Where we currently are in the subject */
+ int capture_top; /* Max current capture */
+ int capture_last; /* Most recently closed capture */
+ void *callout_data; /* Data passed in with the call */
+ /* ------------------- Added for Version 1 -------------------------- */
+ int pattern_position; /* Offset to next item in the pattern */
+ int next_item_length; /* Length of next item in the pattern */
+ /* ------------------- Added for Version 2 -------------------------- */
+ const PCRE_UCHAR16 *mark; /* Pointer to current mark or NULL */
+ /* ------------------------------------------------------------------ */
+} pcre16_callout_block;
+
+/* Indirection for store get and free functions. These can be set to
+alternative malloc/free functions if required. Special ones are used in the
+non-recursive case for "frames". There is also an optional callout function
+that is triggered by the (?) regex item. For Virtual Pascal, these definitions
+have to take another form. */
+
+#ifndef VPCOMPAT
+PCRE_EXP_DECL void *(*pcre_malloc)(size_t);
+PCRE_EXP_DECL void (*pcre_free)(void *);
+PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t);
+PCRE_EXP_DECL void (*pcre_stack_free)(void *);
+PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *);
+
+PCRE_EXP_DECL void *(*pcre16_malloc)(size_t);
+PCRE_EXP_DECL void (*pcre16_free)(void *);
+PCRE_EXP_DECL void *(*pcre16_stack_malloc)(size_t);
+PCRE_EXP_DECL void (*pcre16_stack_free)(void *);
+PCRE_EXP_DECL int (*pcre16_callout)(pcre16_callout_block *);
+#else /* VPCOMPAT */
+PCRE_EXP_DECL void *pcre_malloc(size_t);
+PCRE_EXP_DECL void pcre_free(void *);
+PCRE_EXP_DECL void *pcre_stack_malloc(size_t);
+PCRE_EXP_DECL void pcre_stack_free(void *);
+PCRE_EXP_DECL int pcre_callout(pcre_callout_block *);
+
+PCRE_EXP_DECL void *pcre16_malloc(size_t);
+PCRE_EXP_DECL void pcre16_free(void *);
+PCRE_EXP_DECL void *pcre16_stack_malloc(size_t);
+PCRE_EXP_DECL void pcre16_stack_free(void *);
+PCRE_EXP_DECL int pcre16_callout(pcre16_callout_block *);
+#endif /* VPCOMPAT */
+
+/* User defined callback which provides a stack just before the match starts. */
+
+typedef pcre_jit_stack *(*pcre_jit_callback)(void *);
+typedef pcre16_jit_stack *(*pcre16_jit_callback)(void *);
+
+/* Exported PCRE functions */
+
+PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *,
+ const unsigned char *);
+PCRE_EXP_DECL pcre16 *pcre16_compile(PCRE_SPTR16, int, const char **, int *,
+ const unsigned char *);
+PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **,
+ int *, const unsigned char *);
+PCRE_EXP_DECL pcre16 *pcre16_compile2(PCRE_SPTR16, int, int *, const char **,
+ int *, const unsigned char *);
+PCRE_EXP_DECL int pcre_config(int, void *);
+PCRE_EXP_DECL int pcre16_config(int, void *);
+PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *,
+ int *, int, const char *, char *, int);
+PCRE_EXP_DECL int pcre16_copy_named_substring(const pcre16 *, PCRE_SPTR16,
+ int *, int, PCRE_SPTR16, PCRE_UCHAR16 *, int);
+PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int,
+ char *, int);
+PCRE_EXP_DECL int pcre16_copy_substring(PCRE_SPTR16, int *, int, int,
+ PCRE_UCHAR16 *, int);
+PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *,
+ const char *, int, int, int, int *, int , int *, int);
+PCRE_EXP_DECL int pcre16_dfa_exec(const pcre16 *, const pcre16_extra *,
+ PCRE_SPTR16, int, int, int, int *, int , int *, int);
+PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR,
+ int, int, int, int *, int);
+PCRE_EXP_DECL int pcre16_exec(const pcre16 *, const pcre16_extra *,
+ PCRE_SPTR16, int, int, int, int *, int);
+PCRE_EXP_DECL void pcre_free_substring(const char *);
+PCRE_EXP_DECL void pcre16_free_substring(PCRE_SPTR16);
+PCRE_EXP_DECL void pcre_free_substring_list(const char **);
+PCRE_EXP_DECL void pcre16_free_substring_list(PCRE_SPTR16 *);
+PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int,
+ void *);
+PCRE_EXP_DECL int pcre16_fullinfo(const pcre16 *, const pcre16_extra *, int,
+ void *);
+PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *,
+ int *, int, const char *, const char **);
+PCRE_EXP_DECL int pcre16_get_named_substring(const pcre16 *, PCRE_SPTR16,
+ int *, int, PCRE_SPTR16, PCRE_SPTR16 *);
+PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *);
+PCRE_EXP_DECL int pcre16_get_stringnumber(const pcre16 *, PCRE_SPTR16);
+PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *,
+ char **, char **);
+PCRE_EXP_DECL int pcre16_get_stringtable_entries(const pcre16 *, PCRE_SPTR16,
+ PCRE_UCHAR16 **, PCRE_UCHAR16 **);
+PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int,
+ const char **);
+PCRE_EXP_DECL int pcre16_get_substring(PCRE_SPTR16, int *, int, int,
+ PCRE_SPTR16 *);
+PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int,
+ const char ***);
+PCRE_EXP_DECL int pcre16_get_substring_list(PCRE_SPTR16, int *, int,
+ PCRE_SPTR16 **);
+PCRE_EXP_DECL const unsigned char *pcre_maketables(void);
+PCRE_EXP_DECL const unsigned char *pcre16_maketables(void);
+PCRE_EXP_DECL int pcre_refcount(pcre *, int);
+PCRE_EXP_DECL int pcre16_refcount(pcre16 *, int);
+PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **);
+PCRE_EXP_DECL pcre16_extra *pcre16_study(const pcre16 *, int, const char **);
+PCRE_EXP_DECL void pcre_free_study(pcre_extra *);
+PCRE_EXP_DECL void pcre16_free_study(pcre16_extra *);
+PCRE_EXP_DECL const char *pcre_version(void);
+PCRE_EXP_DECL const char *pcre16_version(void);
+
+/* Utility functions for byte order swaps. */
+PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *, pcre_extra *,
+ const unsigned char *);
+PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *, pcre16_extra *,
+ const unsigned char *);
+PCRE_EXP_DECL int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *,
+ PCRE_SPTR16, int, int *, int);
+
+/* JIT compiler related functions. */
+
+PCRE_EXP_DECL pcre_jit_stack *pcre_jit_stack_alloc(int, int);
+PCRE_EXP_DECL pcre16_jit_stack *pcre16_jit_stack_alloc(int, int);
+PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *);
+PCRE_EXP_DECL void pcre16_jit_stack_free(pcre16_jit_stack *);
+PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *,
+ pcre_jit_callback, void *);
+PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *,
+ pcre16_jit_callback, void *);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* End of pcre.h */
diff --git a/plugins/Variables/src/pcre/include/pcreposix.h b/plugins/Variables/src/pcre/include/pcreposix.h
new file mode 100644
index 0000000000..c77c0b0523
--- /dev/null
+++ b/plugins/Variables/src/pcre/include/pcreposix.h
@@ -0,0 +1,146 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+#ifndef _PCREPOSIX_H
+#define _PCREPOSIX_H
+
+/* This is the header for the POSIX wrapper interface to the PCRE Perl-
+Compatible Regular Expression library. It defines the things POSIX says should
+be there. I hope.
+
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Have to include stdlib.h in order to ensure that size_t is defined. */
+
+#include <stdlib.h>
+
+/* Allow for C++ users */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Options, mostly defined by POSIX, but with some extras. */
+
+#define REG_ICASE 0x0001 /* Maps to PCRE_CASELESS */
+#define REG_NEWLINE 0x0002 /* Maps to PCRE_MULTILINE */
+#define REG_NOTBOL 0x0004 /* Maps to PCRE_NOTBOL */
+#define REG_NOTEOL 0x0008 /* Maps to PCRE_NOTEOL */
+#define REG_DOTALL 0x0010 /* NOT defined by POSIX; maps to PCRE_DOTALL */
+#define REG_NOSUB 0x0020 /* Maps to PCRE_NO_AUTO_CAPTURE */
+#define REG_UTF8 0x0040 /* NOT defined by POSIX; maps to PCRE_UTF8 */
+#define REG_STARTEND 0x0080 /* BSD feature: pass subject string by so,eo */
+#define REG_NOTEMPTY 0x0100 /* NOT defined by POSIX; maps to PCRE_NOTEMPTY */
+#define REG_UNGREEDY 0x0200 /* NOT defined by POSIX; maps to PCRE_UNGREEDY */
+#define REG_UCP 0x0400 /* NOT defined by POSIX; maps to PCRE_UCP */
+
+/* This is not used by PCRE, but by defining it we make it easier
+to slot PCRE into existing programs that make POSIX calls. */
+
+#define REG_EXTENDED 0
+
+/* Error values. Not all these are relevant or used by the wrapper. */
+
+enum {
+ REG_ASSERT = 1, /* internal error ? */
+ REG_BADBR, /* invalid repeat counts in {} */
+ REG_BADPAT, /* pattern error */
+ REG_BADRPT, /* ? * + invalid */
+ REG_EBRACE, /* unbalanced {} */
+ REG_EBRACK, /* unbalanced [] */
+ REG_ECOLLATE, /* collation error - not relevant */
+ REG_ECTYPE, /* bad class */
+ REG_EESCAPE, /* bad escape sequence */
+ REG_EMPTY, /* empty expression */
+ REG_EPAREN, /* unbalanced () */
+ REG_ERANGE, /* bad range inside [] */
+ REG_ESIZE, /* expression too big */
+ REG_ESPACE, /* failed to get memory */
+ REG_ESUBREG, /* bad back reference */
+ REG_INVARG, /* bad argument */
+ REG_NOMATCH /* match failed */
+};
+
+
+/* The structure representing a compiled regular expression. */
+
+typedef struct {
+ void *re_pcre;
+ size_t re_nsub;
+ size_t re_erroffset;
+} regex_t;
+
+/* The structure in which a captured offset is returned. */
+
+typedef int regoff_t;
+
+typedef struct {
+ regoff_t rm_so;
+ regoff_t rm_eo;
+} regmatch_t;
+
+/* When an application links to a PCRE DLL in Windows, the symbols that are
+imported have to be identified as such. When building PCRE, the appropriate
+export settings are needed, and are set in pcreposix.c before including this
+file. */
+
+#if defined(_WIN32) && !defined(PCRE_STATIC) && !defined(PCREPOSIX_EXP_DECL)
+# define PCREPOSIX_EXP_DECL extern __declspec(dllimport)
+# define PCREPOSIX_EXP_DEFN __declspec(dllimport)
+#endif
+
+/* By default, we use the standard "extern" declarations. */
+
+#ifndef PCREPOSIX_EXP_DECL
+# ifdef __cplusplus
+# define PCREPOSIX_EXP_DECL extern "C"
+# define PCREPOSIX_EXP_DEFN extern "C"
+# else
+# define PCREPOSIX_EXP_DECL extern
+# define PCREPOSIX_EXP_DEFN extern
+# endif
+#endif
+
+/* The functions */
+
+PCREPOSIX_EXP_DECL int regcomp(regex_t *, const char *, int);
+PCREPOSIX_EXP_DECL int regexec(const regex_t *, const char *, size_t,
+ regmatch_t *, int);
+PCREPOSIX_EXP_DECL size_t regerror(int, const regex_t *, char *, size_t);
+PCREPOSIX_EXP_DECL void regfree(regex_t *);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* End of pcreposix.h */
diff --git a/plugins/Variables/src/pcre/lib/pcre.lib b/plugins/Variables/src/pcre/lib/pcre.lib
new file mode 100644
index 0000000000..c0dce0ce08
--- /dev/null
+++ b/plugins/Variables/src/pcre/lib/pcre.lib
Binary files differ
diff --git a/plugins/Variables/src/pcre/lib/pcred.lib b/plugins/Variables/src/pcre/lib/pcred.lib
new file mode 100644
index 0000000000..103517b44b
--- /dev/null
+++ b/plugins/Variables/src/pcre/lib/pcred.lib
Binary files differ
diff --git a/plugins/Variables/src/pcre/lib64/pcre.lib b/plugins/Variables/src/pcre/lib64/pcre.lib
new file mode 100644
index 0000000000..57bd4b65c3
--- /dev/null
+++ b/plugins/Variables/src/pcre/lib64/pcre.lib
Binary files differ
diff --git a/plugins/Variables/src/pcre/lib64/pcred.lib b/plugins/Variables/src/pcre/lib64/pcred.lib
new file mode 100644
index 0000000000..8350667bf7
--- /dev/null
+++ b/plugins/Variables/src/pcre/lib64/pcred.lib
Binary files differ
diff --git a/plugins/Variables/src/pcre/pcre_license.txt b/plugins/Variables/src/pcre/pcre_license.txt
new file mode 100644
index 0000000000..0fbd6f3e6b
--- /dev/null
+++ b/plugins/Variables/src/pcre/pcre_license.txt
@@ -0,0 +1,45 @@
+PCRE LICENCE
+------------
+
+PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+Release 5 of PCRE is distributed under the terms of the "BSD" licence, as
+specified below. The documentation for PCRE, supplied in the "doc"
+directory, is distributed under the same terms as the software itself.
+
+Written by: Philip Hazel <ph10@cam.ac.uk>
+
+University of Cambridge Computing Service,
+Cambridge, England. Phone: +44 1223 334714.
+
+Copyright (c) 1997-2004 University of Cambridge
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+End \ No newline at end of file
diff --git a/plugins/Variables/src/resource.h b/plugins/Variables/src/resource.h
new file mode 100644
index 0000000000..3217663618
--- /dev/null
+++ b/plugins/Variables/src/resource.h
@@ -0,0 +1,56 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by Variables.rc
+//
+#define IDD_OPTS_DIALOG 101
+#define IDD_TRG_STRINGCHANGE 102
+#define IDD_INPUT_DIALOG 103
+#define IDD_CLIST_DIALOG 104
+#define IDD_EXTRATEXT_DIALOG 105
+#define IDD_HELPDIALOG 106
+#define IDD_HELP_DIALOG 106
+#define IDD_TOKENS_DIALOG 107
+#define IDD_HELPINFO_DIALOG 108
+#define IDD_ACT_PARSESTRING 109
+#define IDD_CND_PARSESTRING 110
+#define IDI_V 113
+#define IDC_FORMATTEXT 1000
+#define IDC_PARSE 1001
+#define IDC_AUTOPARSE 1002
+#define IDC_RESULT 1003
+#define IDC_PARSEATSTARTUP 1005
+#define IDC_STRIPCRLF 1006
+#define IDC_SHOWHELP 1008
+#define IDC_TOKENLIST 1013
+#define IDC_TESTSTRING 1014
+#define IDC_OK 1016
+#define IDC_CANCEL 1017
+#define IDC_SUBJECT 1018
+#define IDC_CLIST 1019
+#define IDC_APPLY 1020
+#define IDC_EXTRATEXT 1021
+#define IDC_NULL 1023
+#define IDC_CONTACT 1024
+#define IDC_RICHEDIT1 1025
+#define IDC_HELPDESC 1026
+#define IDC_SPLITTER 1028
+#define IDC_TABS 1030
+#define IDC_ABOUT 1035
+#define IDC_ABOUTFRAME 1036
+#define IDC_SETTINGFRAME 1037
+#define IDC_PARSESTRING 1038
+#define IDC_STRIPWS 1039
+#define IDC_STRIPALL 1041
+#define IDC_PARSEASYNC 1047
+#define IDC_STATIC -1
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 114
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1048
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins/Variables/src/tokenregister.cpp b/plugins/Variables/src/tokenregister.cpp
new file mode 100644
index 0000000000..0418c3024f
--- /dev/null
+++ b/plugins/Variables/src/tokenregister.cpp
@@ -0,0 +1,319 @@
+/*
+ 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"
+
+typedef struct {
+ TOKENREGISTEREX tr;
+ DWORD nameHash;
+}
+ TokenRegisterEntry;
+
+struct
+{
+ TokenRegisterEntry** items;
+ int count, limit, increment;
+ FSortFunc sortFunc;
+}
+static tokens;
+
+static CRITICAL_SECTION csRegister;
+
+unsigned long int hashlittle(void *key, size_t length, unsigned long int initval);
+
+static DWORD NameHashFunction(TCHAR *tszStr)
+{
+ return (DWORD)hashlittle(tszStr, _tcslen(tszStr)*sizeof(TCHAR), 0);
+}
+
+static TokenRegisterEntry* FindTokenRegisterByName(TCHAR *name)
+{
+ int idx;
+ TokenRegisterEntry temp;
+ temp.nameHash = NameHashFunction( name );
+ if (List_GetIndex(( SortedList* )&tokens, &temp, &idx ))
+ return tokens.items[ idx ];
+
+ return NULL;
+}
+
+int registerIntToken(TCHAR *szToken, TCHAR *(*parseFunction)(ARGUMENTSINFO *ai), int extraFlags, char* szHelpText)
+{
+ TOKENREGISTEREX tr = { 0 };
+ tr.cbSize = sizeof(tr);
+ tr.flags = TRF_FREEMEM|TRF_TCHAR|TRF_PARSEFUNC|extraFlags;
+ //tr.memType = TR_MEM_VARIABLES;
+ tr.memType = TR_MEM_MIRANDA;
+ tr.szHelpText = szHelpText;
+ tr.tszTokenString = szToken;
+ tr.parseFunctionT = parseFunction;
+
+ return registerToken(0, (LPARAM)&tr);
+}
+
+int deRegisterToken(TCHAR *token)
+{
+ TokenRegisterEntry *tre;
+
+ if (token == NULL)
+ return -1;
+
+ EnterCriticalSection(&csRegister);
+ tre = FindTokenRegisterByName( token );
+ if (tre == NULL) {
+ LeaveCriticalSection(&csRegister);
+ return -1;
+ }
+
+ List_RemovePtr(( SortedList* )&tokens, tre );
+ LeaveCriticalSection(&csRegister);
+
+ if (!( tre->tr.flags & TRF_PARSEFUNC ) && tre->tr.szService != NULL)
+ mir_free( tre->tr.szService );
+
+ if (tre->tr.tszTokenString != NULL)
+ mir_free( tre->tr.tszTokenString );
+
+ if (tre->tr.szHelpText != NULL)
+ mir_free( tre->tr.szHelpText );
+
+ if ((tre->tr.flags & TRF_CLEANUP ) && !( tre->tr.flags & TRF_CLEANUPFUNC ) && tre->tr.szCleanupService != NULL)
+ mir_free( tre->tr.szCleanupService );
+
+ mir_free( tre );
+ return 0;
+}
+
+INT_PTR registerToken(WPARAM wParam, LPARAM lParam)
+{
+ DWORD hash;
+ int idx;
+ TokenRegisterEntry *tre;
+
+ TOKENREGISTEREX *newVr = ( TOKENREGISTEREX* )lParam;
+ if (newVr == NULL || newVr->szTokenString == NULL || newVr->cbSize <= 0 )
+ return -1;
+
+ if (newVr->flags & TRF_TCHAR ) {
+ deRegisterToken( newVr->tszTokenString );
+ hash = NameHashFunction( newVr->tszTokenString );
+ }
+ else {
+
+ WCHAR *wtoken;
+
+ wtoken = mir_a2t( newVr->szTokenString );
+ deRegisterToken( wtoken );
+ hash = NameHashFunction( wtoken );
+ mir_free( wtoken );
+
+ }
+
+ tre = ( TokenRegisterEntry* )mir_alloc( sizeof( TokenRegisterEntry ));
+ if (tre == NULL)
+ return -1;
+
+ memcpy( &tre->tr, newVr, newVr->cbSize );
+ tre->nameHash = hash;
+ if (!_tcscmp( newVr->tszTokenString, _T("alias")))
+ log_debugA("alias");
+
+ if (!( newVr->flags & TRF_PARSEFUNC ) && newVr->szService != NULL)
+ tre->tr.szService = mir_strdup( newVr->szService );
+
+ if (newVr->flags & TRF_TCHAR )
+ tre->tr.tszTokenString = mir_tstrdup( newVr->tszTokenString );
+ else
+
+ tre->tr.tszTokenString = mir_a2t( newVr->szTokenString );
+
+
+ if (newVr->szHelpText != NULL)
+ tre->tr.szHelpText = mir_strdup( newVr->szHelpText );
+
+ if (( newVr->flags & TRF_CLEANUP ) && !( newVr->flags & TRF_CLEANUPFUNC ) && newVr->szCleanupService != NULL)
+ tre->tr.szCleanupService = mir_strdup( newVr->szCleanupService );
+
+ EnterCriticalSection(&csRegister);
+ List_GetIndex(( SortedList* )&tokens, tre, &idx );
+ List_Insert(( SortedList* )&tokens, tre, idx );
+ LeaveCriticalSection(&csRegister);
+
+ return 0;
+}
+
+TOKENREGISTEREX *searchRegister(TCHAR *tvar, int type)
+{
+ TokenRegisterEntry *tre;
+ TOKENREGISTEREX *retVr;
+
+ if (tvar == NULL)
+ return 0;
+
+ EnterCriticalSection( &csRegister );
+ tre = FindTokenRegisterByName( tvar );
+ if (tre == NULL || ( type != 0 && (tre->tr.flags & ( TRF_FIELD | TRF_FUNCTION )) != 0 && !( tre->tr.flags & type )))
+ retVr = NULL;
+ else
+ retVr = &tre->tr;
+
+ LeaveCriticalSection(&csRegister);
+ return retVr;
+}
+
+TCHAR *parseFromRegister(ARGUMENTSINFO *ai)
+{
+ if (ai == NULL || ai->argc == 0 || ai->targv[0] == NULL)
+ return NULL;
+
+ INT_PTR callRes = 0;
+ TCHAR *temp = NULL, *res = NULL;
+
+ EnterCriticalSection(&csRegister);
+
+ /* note the following limitation: you cannot add/remove tokens during a call from a different thread */
+ TOKENREGISTEREX *thisVr = searchRegister( ai->targv[0], 0 );
+ if (thisVr == NULL) {
+ LeaveCriticalSection(&csRegister);
+ return NULL;
+ }
+
+ TOKENREGISTEREX trCopy = *thisVr;
+
+ // ai contains WCHARs, convert to chars because the tr doesn't support WCHARs
+ if (!( thisVr->flags & TRF_TCHAR )) {
+ // unicode variables calls a non-unicode plugin
+ unsigned int j;
+ ARGUMENTSINFO cAi;
+
+ memcpy(&cAi, ai, sizeof(ARGUMENTSINFO));
+ cAi.argv = ( char** )mir_alloc(ai->argc*sizeof(char *));
+ for ( j=0; j < ai->argc; j++ )
+ cAi.argv[j] = mir_t2a( ai->targv[j] );
+
+ if (thisVr->flags & TRF_PARSEFUNC )
+ callRes = (INT_PTR)thisVr->parseFunction( &cAi );
+ else if (thisVr->szService != NULL)
+ callRes = CallService( thisVr->szService, (WPARAM)0, (LPARAM)&cAi );
+
+ for ( j=0; j < cAi.argc; j++ )
+ if (cAi.argv[j] != NULL)
+ mir_free( cAi.argv[j] );
+
+ if ((char *)callRes != NULL)
+ res = mir_a2t(( char* )callRes );
+ }
+ else {
+ // unicode variables calls unicode plugin
+ if (thisVr->flags & TRF_PARSEFUNC )
+ callRes = (INT_PTR)thisVr->parseFunctionT( ai );
+ else if (thisVr->szService != NULL)
+ callRes = CallService( thisVr->szService, (WPARAM)0, (LPARAM)ai );
+
+ if ((TCHAR*)callRes != NULL)
+ res = mir_tstrdup((TCHAR*)callRes );
+ }
+
+
+ if (( void* )callRes != NULL) {
+ if (trCopy.flags & TRF_CLEANUP ) {
+ if (trCopy.flags & TRF_CLEANUPFUNC )
+ trCopy.cleanupFunctionT((TCHAR*)callRes );
+ else if (trCopy.szCleanupService != NULL)
+ CallService( trCopy.szCleanupService, 0, (LPARAM)callRes );
+ }
+ if (trCopy.flags & TRF_FREEMEM ) {
+ if (trCopy.memType == TR_MEM_MIRANDA )
+ mir_free(( void* )callRes );
+// else if (trCopy.memType == TR_MEM_VARIABLES )
+// mir_free((void *)callRes);
+ }
+ }
+ LeaveCriticalSection(&csRegister);
+ return res;
+}
+
+TOKENREGISTEREX* getTokenRegister( int i )
+{
+ TOKENREGISTEREX *retVr;
+
+ EnterCriticalSection(&csRegister);
+ retVr = ( i >= tokens.count || i < 0 ) ? NULL : &tokens.items[i]->tr;
+ LeaveCriticalSection( &csRegister );
+ // beware! a pointer is returned here, no copy
+ return retVr;
+}
+
+int getTokenRegisterCount()
+{
+ int retVal;
+
+ EnterCriticalSection(&csRegister);
+ retVal = tokens.count;
+ LeaveCriticalSection(&csRegister);
+
+ return retVal;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static int CompareTokens( const TokenRegisterEntry* p1, const TokenRegisterEntry* p2 )
+{
+ if (p1->nameHash == p2->nameHash )
+ return 0;
+
+ return ( p1->nameHash < p2->nameHash ) ? -1 : 1;
+}
+
+int initTokenRegister()
+{
+ InitializeCriticalSection(&csRegister);
+
+ tokens.sortFunc = ( FSortFunc )CompareTokens;
+ tokens.increment = 100;
+ return 0;
+}
+
+int deinitTokenRegister()
+{
+ int i;
+ EnterCriticalSection(&csRegister);
+
+ for ( i=0; i < tokens.count; i++ ) {
+ TokenRegisterEntry *tre = tokens.items[ i ];
+ if (!( tre->tr.flags & TRF_PARSEFUNC ) && tre->tr.szService != NULL)
+ mir_free( tre->tr.szService );
+
+ if (tre->tr.tszTokenString != NULL)
+ mir_free( tre->tr.tszTokenString );
+
+ if (tre->tr.szHelpText != NULL)
+ mir_free( tre->tr.szHelpText );
+
+ if (( tre->tr.flags & TRF_CLEANUP ) && !( tre->tr.flags & TRF_CLEANUPFUNC ) && tre->tr.szCleanupService != NULL)
+ mir_free( tre->tr.szCleanupService );
+
+ mir_free( tre );
+ }
+ List_Destroy(( SortedList* )&tokens );
+
+ LeaveCriticalSection(&csRegister);
+ DeleteCriticalSection(&csRegister);
+
+ return 0;
+}
diff --git a/plugins/Variables/src/trigger_variables.cpp b/plugins/Variables/src/trigger_variables.cpp
new file mode 100644
index 0000000000..6b90088c4f
--- /dev/null
+++ b/plugins/Variables/src/trigger_variables.cpp
@@ -0,0 +1,232 @@
+/*
+ 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 "m_trigger.h"
+#include "trigger_variables.h"
+#include "resource.h"
+
+extern HINSTANCE hInst;
+
+static TRG_VAR_CACHE *tvc = NULL;
+static int tvcCount = 0;
+static unsigned int stringChangeTimerID = 0;
+
+static int addToCache(DWORD triggerID)
+{
+ /* triggerID must be in the DB */
+ DBVARIANT dbv;
+
+ for (int i=0; i < tvcCount; i++) {
+ if (tvc[i].triggerID == triggerID) {
+ mir_free(tvc[i].parsedText);
+ MoveMemory(&tvc[i], &tvc[tvcCount-1], sizeof(TRG_VAR_CACHE));
+ tvcCount -= 1;
+ }
+ }
+ if ( DBGetTriggerSettingTString(triggerID, NULL, MODULENAME, SETTING_TRIGGERTEXT, &dbv))
+ return -1;
+
+ tvc = ( TRG_VAR_CACHE* )mir_realloc(tvc, (tvcCount+1)*sizeof(TRG_VAR_CACHE));
+ if (tvc == NULL)
+ return -1;
+
+ tvc[tvcCount].triggerID = triggerID;
+ tvc[tvcCount].parsedText = variables_parsedup(dbv.ptszVal, NULL, NULL);
+ // it stays in our own mem space!
+ if (tvc[tvcCount].parsedText == NULL)
+ return -1;
+
+ tvcCount += 1;
+ DBFreeVariant(&dbv);
+ return 0;
+}
+
+static int removeFromCache(DWORD triggerID) {
+
+ int i;
+
+ for (i=0;i<tvcCount;i++) {
+ if (tvc[i].triggerID == triggerID) {
+ mir_free(tvc[i].parsedText);
+ MoveMemory(&tvc[i], &tvc[tvcCount-1], sizeof(TRG_VAR_CACHE));
+ tvcCount -= 1;
+ }
+ }
+
+ return 0;
+}
+
+static VOID CALLBACK checkStringsTimer(HWND hwnd,UINT message,UINT_PTR idEvent,DWORD dwTime)
+{
+ DWORD triggerID = 0;
+ do {
+ triggerID = (DWORD)CallService(MS_TRIGGER_FINDNEXTTRIGGERID, triggerID, (LPARAM)TRIGGERNAME);
+ if (triggerID == 0) {
+ continue;
+ }
+ for (int i=0; i < tvcCount; i++) {
+ if (triggerID != tvc[i].triggerID)
+ continue;
+
+ DBVARIANT dbv;
+ if (!DBGetTriggerSettingTString(tvc[i].triggerID, NULL, MODULENAME, SETTING_TRIGGERTEXT, &dbv)) {
+ TCHAR *parsedText = variables_parsedup(dbv.ptszVal, NULL, NULL);
+ if (parsedText == NULL)
+ continue;
+
+ if (!_tcscmp(tvc[i].parsedText, parsedText)) {
+ mir_free(parsedText);
+ continue;
+ }
+
+ TRIGGERDATA td = { 0 };
+ td.cbSize = sizeof(td);
+ td.dFlags = DF_TEXT;
+ td.tszText = parsedText;
+
+ REPORTINFO ri = { 0 };
+ ri.cbSize = sizeof(REPORTINFO);
+ ri.triggerID = tvc[i].triggerID;
+ ri.pszName = TRIGGERNAME;
+ ri.flags = TRG_PERFORM;
+ ri.td = &td;
+
+ CallService(MS_TRIGGER_REPORTEVENT, 0, (LPARAM)&ri);
+ mir_free(tvc[i].parsedText);
+ tvc[i].parsedText = parsedText;
+ DBFreeVariant(&dbv);
+ }
+ }
+ }
+ while (triggerID != 0);
+}
+
+INT_PTR CALLBACK DlgProcOptsStringChange(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
+
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ {
+ DBVARIANT dbv;
+ DWORD triggerID;
+
+ triggerID = (DWORD)lParam;
+ if (!DBGetTriggerSetting(triggerID, NULL, MODULENAME, SETTING_TRIGGERTEXT, &dbv)) {
+ SetDlgItemTextA(hwndDlg, IDC_FORMATTEXT, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ variables_skin_helpbutton(hwndDlg, IDC_SHOWHELP);
+ }
+ break;
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_SHOWHELP:
+ variables_showhelp(hwndDlg, IDC_FORMATTEXT, VHF_FULLDLG|VHF_SETLASTSUBJECT, NULL, NULL);
+ break;
+ }
+ break;
+
+ case TM_ADDTRIGGER:
+ // wParam = trigger ID
+ // lParam = (TRIGGERREGISTER *)
+ {
+ DWORD triggerID = (DWORD)wParam;
+ TCHAR *tszFormatText = Hlp_GetDlgItemText(hwndDlg, IDC_FORMATTEXT);
+ if (tszFormatText != NULL) {
+ DBWriteTriggerSettingTString(triggerID, NULL, MODULENAME, SETTING_TRIGGERTEXT, tszFormatText);
+ mir_free(tszFormatText);
+ }
+ addToCache(triggerID);
+ }
+ break;
+
+ case TM_DELTRIGGER:
+ // wParam = triggerID
+ // lParam = (TRIGGEREGISTER *) may be 0
+ {
+ REMOVETRIGGERSETTINGS rts;
+
+ DWORD triggerID = (DWORD)wParam;
+ removeFromCache(triggerID);
+ rts.cbSize = sizeof(REMOVETRIGGERSETTINGS);
+ rts.prefix = PREFIX_TRIGGERID;
+ rts.id = triggerID;
+ rts.hContact = NULL;
+ rts.szModule = MODULENAME;
+ CallService(MS_TRIGGER_REMOVESETTINGS, 0, (LPARAM)&rts);
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+int initTriggerModule()
+{
+ log_debugA("Variables: initTriggerModule");
+ if (!ServiceExists(MS_TRIGGER_REGISTERTRIGGER)) {
+ log_debugA("Variables: %s does not exist", MS_TRIGGER_REGISTERTRIGGER);
+ return -1;
+ }
+
+ TRIGGERREGISTER tr = { 0 };
+ tr.cbSize = sizeof(tr);
+ tr.pszName = TRIGGERNAME;
+ tr.hInstance = hInst;
+ tr.pfnDlgProc = DlgProcOptsStringChange;
+ tr.pszTemplate = MAKEINTRESOURCEA(IDD_TRG_STRINGCHANGE);
+ tr.dFlags = DF_TEXT|DF_TCHAR;
+ int res = CallService(MS_TRIGGER_REGISTERTRIGGER, 0, (LPARAM)&tr);
+ log_debugA("Variables: %s registered (%d)", TRIGGERNAME, res);
+
+ ACTIONREGISTER ar = { 0 };
+ ar.cbSize = sizeof(ACTIONREGISTER);
+ ar.pszName = "Variables: Parse string";
+ ar.hInstance = hInst;
+ ar.pfnDlgProc = DlgProcOptsParseString;
+ ar.pszTemplate = MAKEINTRESOURCEA(IDD_ACT_PARSESTRING);
+ ar.actionFunction = ParseStringAction;
+ ar.flags = ARF_FUNCTION|ARF_TCHAR;
+ CallService(MS_TRIGGER_REGISTERACTION, 0, (LPARAM)&ar);
+
+ CONDITIONREGISTER cr = { 0 };
+ cr.cbSize = sizeof(CONDITIONREGISTER);
+ cr.pszName = "Variables: Condition";
+ cr.hInstance = hInst;
+ cr.pfnDlgProc = DlgProcOptsCondition;
+ cr.pszTemplate = MAKEINTRESOURCEA(IDD_CND_PARSESTRING);
+ cr.conditionFunction = ParseStringCondition;
+ cr.flags = CRF_FUNCTION|CRF_TCHAR;
+ CallService(MS_TRIGGER_REGISTERCONDITION, 0, (LPARAM)&cr);
+
+ // fill cache
+ DWORD triggerID = 0;
+ do {
+ triggerID = (DWORD)CallService(MS_TRIGGER_FINDNEXTTRIGGERID, triggerID, (LPARAM)TRIGGERNAME);
+ if (triggerID == 0) {
+ continue;
+ }
+ addToCache(triggerID);
+ }
+ while (triggerID != 0);
+
+ stringChangeTimerID = SetTimer(NULL, 0, CHECKSTRINGDELAY, checkStringsTimer);
+ return res;
+}
diff --git a/plugins/Variables/src/trigger_variables.h b/plugins/Variables/src/trigger_variables.h
new file mode 100644
index 0000000000..6b80087e2d
--- /dev/null
+++ b/plugins/Variables/src/trigger_variables.h
@@ -0,0 +1,36 @@
+/*
+ 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
+*/
+#define TRIGGERNAME "Variables: String changed"
+#define SETTING_TRIGGERTEXT "trigger_TriggerText"
+#define CHECKSTRINGDELAY 5000
+
+typedef struct {
+ DWORD triggerID;
+ TCHAR *parsedText;
+} TRG_VAR_CACHE;
+
+
+#define SETTING_PARSESTRING "action_ParseString"
+#define SETTING_PARSEASYNC "action_ParseAsync"
+
+int ParseStringAction(DWORD actionID, REPORTINFO *ri);
+INT_PTR CALLBACK DlgProcOptsParseString(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+int ParseStringCondition(DWORD actionID, REPORTINFO *ri);
+INT_PTR CALLBACK DlgProcOptsCondition(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); \ No newline at end of file
diff --git a/plugins/Variables/src/variables.cpp b/plugins/Variables/src/variables.cpp
new file mode 100644
index 0000000000..258725055f
--- /dev/null
+++ b/plugins/Variables/src/variables.cpp
@@ -0,0 +1,642 @@
+/*
+ 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"
+
+BOOL (WINAPI *pfnEnableThemeDialogTexture)(HANDLE, DWORD) = 0;
+static BOOL bWarningShown = FALSE; // unicode on ansi warning
+
+/* some handles */
+static HANDLE
+ hFormatStringService,
+ hFreeMemoryService,
+ hRegisterVariableService,
+ hGetMMIService,
+ hShowHelpService,
+ hShowHelpExService,
+ hGetIconService;
+
+static HANDLE
+ hOptionsHook = NULL,
+ hIconsChangedHook = NULL;
+
+HCURSOR hCurSplitNS;
+
+struct ParseOptions gParseOpts;
+
+extern HINSTANCE hInst;
+
+TCHAR *getArguments(TCHAR *string, TCHAR ***aargv, int *aargc) {
+
+ BOOL bDontParse, bNewArg, bDone;
+ TCHAR *cur, *scur, **argv;
+ int i, argc, brackets;
+
+ *aargv = NULL;
+ *aargc = 0;
+ argc = brackets = 0;
+ argv = NULL;
+ cur = string;
+ while (*cur == _T(' ')) {
+ cur++;
+ }
+ if (*cur != _T('(')) {
+ return NULL;
+ }
+ cur++;
+ scur = cur-1;
+ bDontParse = bNewArg = bDone = FALSE;
+ while ( (!bDone) && (*cur != _T('\0'))) {
+ switch (*cur) {
+ case _T(DONTPARSE_CHAR):
+ if (bDontParse) {
+ bDontParse = FALSE;
+ }
+ else {
+ bDontParse = TRUE;
+ }
+ break;
+
+ case _T(','):
+ if ((!bDontParse) && (brackets == 0)) {
+ bNewArg = TRUE;
+ }
+ break;
+
+ case _T('('):
+ if (!bDontParse) {
+ brackets += 1;
+ }
+ break;
+
+ case _T(')'):
+ if ((brackets == 0) && (!bDontParse)) {
+ bDone = bNewArg = TRUE;
+ }
+ else if ((brackets > 0) && (!bDontParse)) {
+ brackets -= 1;
+ }
+ break;
+ }
+ if (bNewArg) {
+ argv = ( TCHAR** )mir_realloc(argv, (argc+1)*sizeof(TCHAR*));
+ if (argv == NULL) {
+ return NULL;
+ }
+ if (cur > scur) {
+ argv[argc] = (TCHAR*)mir_alloc((cur-scur+2)*sizeof(TCHAR));
+ if (argv[argc] == NULL) {
+ return NULL;
+ }
+ memset(argv[argc], '\0', (cur-(scur+1)+1)*sizeof(TCHAR));
+ _tcsncpy(argv[argc], scur+1, cur-(scur+1));
+ }
+ else {
+ argv[argc] = mir_tstrdup(_T(""));
+ }
+ argc += 1;
+ bNewArg = FALSE;
+ scur = cur;
+ }
+ cur++;
+ }
+ // set args
+ if (*(cur-1) == _T(')')) {
+ *aargv = argv;
+ *aargc = argc;
+ }
+ else {
+ for (i=0;i<argc;i++) {
+ if (argv[i] != NULL) {
+ mir_free(argv[i]);
+ }
+ }
+ mir_free(argv);
+ *aargv = NULL;
+ *aargc = 0;
+ cur = NULL;
+ }
+
+ return cur;
+}
+
+int isValidTokenChar(TCHAR tc) {
+
+ return (
+ (tc != _T('(')) &&
+ (tc != _T(',')) &&
+ (tc != _T(')')) &&
+ (tc != _T(FIELD_CHAR)) &&
+ (tc != _T(FUNC_CHAR)) &&
+ (tc != _T(FUNC_ONCE_CHAR)) &&
+ (tc != _T('/')) &&
+ (tc != _T('\0'))
+ );
+}
+
+/* pretty much the main loop */
+static TCHAR* replaceDynVars(TCHAR* szTemplate, FORMATINFO* fi)
+{
+ TCHAR
+ *string,
+ *cur, // current position (pnt only)
+ *tcur, // temp cur (pnt only)
+ *scur, // start of variable(pnt only)
+ *parsedToken, // parsed result (dyn alloc)
+ **argv, // arguments (dyn alloc)
+ **pargv, // dyn alloc
+ *token; // variable name (pnt only)
+ int argc, i, parsedTokenLen, initStrLen, tokenLen, scurPos, curPos, tmpVarPos;
+ unsigned int pos;
+ FORMATINFO afi;
+ TOKENREGISTEREX *tr;
+ ARGUMENTSINFO ai = { 0 };
+
+ string = mir_tstrdup(szTemplate);
+ if (string == NULL)
+ return NULL;
+
+ argc = parsedTokenLen = initStrLen = tokenLen = 0;
+ cur = tcur = scur = token = parsedToken = NULL;
+ pargv = argv = NULL;
+ //fi->pCount = 0;
+ memcpy(&afi, fi, sizeof(afi));
+ for (pos = 0;pos < _tcslen(string);pos++) {
+ // string may move in memory, iterate by remembering the position in the string
+ cur = string+pos;
+ // mir_free memory from last iteration, this way we can bail out at any time in the loop
+ if (parsedToken != NULL)
+ mir_free(parsedToken);
+
+ for (i=0;i<argc;i++)
+ if (argv[i] != NULL)
+ mir_free(argv[i]);
+
+ if (argv != NULL)
+ mir_free(argv);
+
+ argc = parsedTokenLen = initStrLen = tokenLen = 0;
+ tcur = scur = token = parsedToken = NULL;
+ pargv = argv = NULL;
+ // new round
+ if (*cur == _T(DONTPARSE_CHAR)) {
+ MoveMemory(cur, cur+1, (_tcslen(cur+1)+1)*sizeof(TCHAR));
+ if (*cur == _T(DONTPARSE_CHAR))
+ continue;
+
+ while ( (*cur != _T(DONTPARSE_CHAR)) && (*cur != _T('\0')))
+ cur++;
+
+ MoveMemory(cur, cur+1, (_tcslen(cur+1)+1)*sizeof(TCHAR));
+ pos = cur-string-1;
+ continue;
+ }
+ // remove end of lines
+ else if ((!_tcsncmp(cur, _T("\r\n"), 2)) && (gParseOpts.bStripEOL)) {
+ MoveMemory(cur, cur+2, (_tcslen(cur+2)+1)*sizeof(TCHAR));
+ pos = cur-string-1;
+ continue;
+ }
+ else if (((*cur == _T('\n')) && (gParseOpts.bStripEOL)) || ((*cur == _T(' ')) && (gParseOpts.bStripWS))) {
+ MoveMemory(cur, cur+1, (_tcslen(cur+1)+1)*sizeof(TCHAR));
+ pos = cur - string - 1;
+ continue;
+ }
+ // remove comments
+ else if (!_tcsncmp(cur, _T(COMMENT_STRING), _tcslen(_T(COMMENT_STRING)))) {
+ scur = cur;
+ while ( (_tcsncmp(cur, _T("\r\n"), 2)) && (*cur != _T('\n')) && (*cur != _T('\0')))
+ cur++;
+
+ if (*cur == _T('\0')) {
+ *scur = _T('\0');
+ string = (TCHAR*)mir_realloc(string, (_tcslen(string)+1)*sizeof(TCHAR));
+ continue;
+ }
+ MoveMemory(scur, cur, (_tcslen(cur)+1)*sizeof(TCHAR));
+ pos = scur-string-1;
+ continue;
+ }
+ else if ((*cur != _T(FIELD_CHAR)) && (*cur != _T(FUNC_CHAR)) && (*cur != _T(FUNC_ONCE_CHAR))) {
+ if (gParseOpts.bStripAll) {
+ MoveMemory(cur, cur+1, (_tcslen(cur+1)+1)*sizeof(TCHAR));
+ pos = cur - string - 1;
+ }
+ continue;
+ }
+ scur = tcur = cur+1;
+ while (isValidTokenChar(*tcur))
+ tcur++;
+
+ if (tcur == cur) {
+ fi->eCount += 1;
+ continue;
+ }
+ token = (TCHAR*)mir_alloc((tcur-scur+1)*sizeof(TCHAR));
+ if (token == NULL) {
+ fi->eCount += 1;
+ return NULL;
+ }
+ memset(token, '\0', (tcur-scur+1)*sizeof(TCHAR));
+ _tcsncpy(token, cur+1, tcur-scur);
+ // cur points to FIELD_CHAR or FUNC_CHAR
+ tmpVarPos = -1;
+ tr = NULL;
+ if (*cur==_T(FIELD_CHAR)) {
+ for(i = 0; i < fi->cbTemporaryVarsSize; i += 2) {
+ if (lstrcmp(fi->tszaTemporaryVars[i], token) == 0) {
+ tmpVarPos = i;
+ break;
+ }
+ }
+ }
+ if (tmpVarPos < 0)
+ tr = searchRegister(token, (*cur==_T(FIELD_CHAR))?TRF_FIELD:TRF_FUNCTION);
+ mir_free(token);
+ if (tmpVarPos < 0 && tr == NULL) {
+ fi->eCount += 1;
+ // token not found, continue
+ continue;
+ }
+ scur = cur; // store this pointer for later use
+ if (*cur == _T(FIELD_CHAR)) {
+ size_t len = _tcslen(tr != NULL ? tr->tszTokenString : fi->tszaTemporaryVars[tmpVarPos]);
+ cur++;
+ if (*(cur + len) != _T(FIELD_CHAR)) { // the next char after the token should be %
+ fi->eCount += 1;
+ continue;
+ }
+ cur += len+1;
+ }
+ else if ((*cur == _T(FUNC_CHAR)) || (*cur == _T(FUNC_ONCE_CHAR))) {
+ TCHAR *argcur;
+
+ cur += _tcslen(tr->tszTokenString)+1;
+ argcur = getArguments(cur, &argv, &argc);
+ if ((argcur == cur) || (argcur == NULL)) {
+ fi->eCount += 1;
+ // error getting arguments
+ continue;
+ }
+ cur = argcur;
+ // arguments
+ for (i=0;i<argc;i++) {
+ if (argv[i] != NULL) {
+ if (!(tr->flags&TRF_UNPARSEDARGS)) {
+ afi.tszFormat = argv[i];
+ afi.eCount = afi.pCount = 0;
+ argv[i] = formatString(&afi);
+ fi->eCount += afi.eCount;
+ fi->pCount += afi.pCount;
+ mir_free(afi.szFormat);
+ }
+ }
+ if (argv[i] == NULL)
+ argv[i] = mir_tstrdup(_T(""));
+ }
+ }
+ // cur should now point at the character after FIELD_CHAR or after the last ')'
+ if (tr != NULL) {
+ pargv = ( TCHAR** )mir_alloc((argc+1)*sizeof(TCHAR*));
+ if (pargv == NULL) {
+ fi->eCount += 1;
+ return NULL;
+ }
+ for (i=0;i<argc;i++)
+ pargv[i+1] = argv[i];
+
+ pargv[0] = tr->tszTokenString;
+ ZeroMemory(&ai, sizeof(ai));
+ ai.cbSize = sizeof(ai);
+ ai.argc = argc+1;
+ ai.targv = pargv;
+ ai.fi = fi;
+ if ((*scur == _T(FUNC_ONCE_CHAR)) || (*scur == _T(FIELD_CHAR)))
+ ai.flags |= AIF_DONTPARSE;
+
+ parsedToken = parseFromRegister(&ai);
+ mir_free(pargv);
+ }
+ else parsedToken = fi->tszaTemporaryVars[tmpVarPos + 1];
+
+ if (parsedToken == NULL) {
+ fi->eCount += 1;
+ continue;
+ }
+
+ //replaced a var
+ if (ai.flags & AIF_FALSE )
+ fi->eCount++;
+ else
+ fi->pCount++;
+
+ // 'special' chars need to be taken care of (DONTPARSE, TRYPARSE, \r\n)
+ // if the var contains the escape character, this character must be doubled, we don't want it to act as an esacpe char
+ /*for (tcur=parsedToken;*tcur != '\0';tcur++) {
+ if (*tcur == DONTPARSE_CHAR) {//|| (*(var+pos) == ')')) {
+ parsedToken = mir_realloc(parsedToken, strlen(parsedToken) + 2);
+ if (parsedToken == NULL) {
+ fi->err = EMEM;
+ return NULL;
+ }
+ CopyMemory(tcur+1, tcur, strlen(tcur)+1);
+ tcur++;
+ }
+ }*/
+
+ parsedTokenLen = _tcslen(parsedToken);
+ initStrLen = _tcslen(string);
+ tokenLen = cur-scur;
+ scurPos = scur-string;
+ curPos = cur-string;
+ if (tokenLen < parsedTokenLen) {
+ // string needs more memory
+ string = (TCHAR*)mir_realloc(string, (initStrLen-tokenLen+parsedTokenLen+1)*sizeof(TCHAR));
+ if (string == NULL) {
+ fi->eCount += 1;
+ return NULL;
+ }
+ }
+ scur = string+scurPos;
+ cur = string+curPos;
+ MoveMemory(scur + parsedTokenLen, cur, (_tcslen(cur)+1)*sizeof(TCHAR));
+ CopyMemory(scur, parsedToken, parsedTokenLen*sizeof(TCHAR));
+ {
+ size_t len = _tcslen(string);
+ string = (TCHAR*)mir_realloc(string, (len+1)*sizeof(TCHAR));
+ }
+ if (( ai.flags & AIF_DONTPARSE ) || tmpVarPos >= 0)
+ pos += parsedTokenLen;
+
+ pos--; // parse the same pos again, it changed
+
+ if (tr == NULL)
+ parsedToken = NULL; // To avoid mir_free
+ }
+ if (parsedToken != NULL)
+ mir_free(parsedToken);
+
+ for ( i=0; i < argc; i++ )
+ if (argv[i] != NULL)
+ mir_free( argv[i] );
+
+ if (argv != NULL)
+ mir_free(argv);
+
+ return (TCHAR*)mir_realloc(string, (_tcslen(string)+1)*sizeof(TCHAR));
+}
+
+/*
+ MS_VARS_FORMATSTRING
+*/
+static INT_PTR formatStringService(WPARAM wParam, LPARAM lParam) {
+
+ INT_PTR res;
+ int i;
+ BOOL copied;
+ FORMATINFO *fi, tempFi;
+ FORMATINFOV1 *fiv1;
+ TCHAR *tszFormat, *orgFormat, *tszSource, *orgSource, *tRes;
+
+ if (((FORMATINFO *)wParam)->cbSize >= sizeof(FORMATINFO)) {
+ ZeroMemory(&tempFi, sizeof(FORMATINFO));
+ CopyMemory(&tempFi, (FORMATINFO *)wParam, sizeof(FORMATINFO));
+ fi = &tempFi;
+ }
+ else if (((FORMATINFO *)wParam)->cbSize == FORMATINFOV2_SIZE) {
+ ZeroMemory(&tempFi, sizeof(FORMATINFO));
+ CopyMemory(&tempFi, (FORMATINFO *)wParam, FORMATINFOV2_SIZE);
+ fi = &tempFi;
+ }
+ else {
+ // old struct, must be ANSI
+ fiv1 = (FORMATINFOV1 *)wParam;
+ ZeroMemory(&tempFi, sizeof(FORMATINFO));
+ tempFi.cbSize = sizeof(FORMATINFO);
+ tempFi.hContact = fiv1->hContact;
+ tempFi.szFormat = fiv1->szFormat;
+ tempFi.szExtraText = fiv1->szSource;
+ fi = &tempFi;
+ }
+ orgFormat = fi->tszFormat;
+ orgSource = fi->tszExtraText;
+
+ if (!(fi->flags&FIF_TCHAR)) {
+ copied = TRUE;
+ log_debugA("mir_a2t (%s)", fi->szExtraText);
+ tszFormat = fi->szFormat!=NULL?mir_a2t(fi->szFormat):NULL;
+ tszSource = fi->szExtraText!=NULL?mir_a2t(fi->szExtraText):NULL;
+ for(i = 0; i < fi->cbTemporaryVarsSize; i++) {
+ fi->tszaTemporaryVars[i] = fi->szaTemporaryVars[i]!=NULL?mir_a2t(fi->szaTemporaryVars[i]):NULL;
+ }
+ }
+ else {
+ copied = FALSE;
+ tszFormat = fi->tszFormat;
+ tszSource = fi->tszExtraText;
+ }
+
+ fi->tszFormat = tszFormat;
+ fi->tszExtraText = tszSource;
+
+ tRes = formatString(fi);
+
+ if (!(fi->flags&FIF_TCHAR)) {
+ res = (INT_PTR)mir_u2a(tRes);
+ mir_free(tRes);
+ }
+ else {
+ res = (INT_PTR)tRes;
+ }
+
+ if (copied) {
+ if (tszFormat != NULL) {
+ mir_free(tszFormat);
+ }
+ if (tszSource != NULL) {
+ mir_free(tszSource);
+ }
+ for(i = 0; i < fi->cbTemporaryVarsSize; i++) {
+ if (fi->tszaTemporaryVars != NULL) {
+ mir_free(fi->tszaTemporaryVars);
+ }
+ }
+ }
+ //fi->tszFormat = orgFormat;
+ //fi->tszExtraText = orgSource;
+
+ if (((FORMATINFO *)wParam)->cbSize == sizeof(FORMATINFOV1)) {
+ ((FORMATINFOV1 *)wParam)->eCount = fi->eCount;
+ ((FORMATINFOV1 *)wParam)->pCount = fi->pCount;
+ }
+ else {
+ ((FORMATINFO *)wParam)->eCount = fi->eCount;
+ ((FORMATINFO *)wParam)->pCount = fi->pCount;
+ }
+// clearVariableRegister();?
+
+ return res;
+}
+
+TCHAR *formatString(FORMATINFO *fi) {
+
+ /* the service to format a given string */
+ TCHAR *string, *formattedString;
+
+ if (fi->eCount + fi->pCount > 5000) {
+ fi->eCount += 1;
+ fi->pCount += 1;
+ log_debugA("Variables: Overflow protection; %d parses", fi->eCount + fi->pCount);
+ return NULL;
+ }
+ if ((fi == NULL) || (fi->tszFormat == NULL)) {
+ return NULL;
+ }
+ string = mir_tstrdup(fi->tszFormat);
+ if (string == NULL) {
+ return NULL;
+ }
+ formattedString = replaceDynVars(string, fi);
+ mir_free(string);
+ if (formattedString == NULL) {
+ return NULL;
+ }
+
+ return formattedString;
+}
+
+/*
+ MS_VARS_FREEMEMORY
+*/
+static INT_PTR freeMemory(WPARAM wParam, LPARAM lParam) {
+
+ if ((void*)wParam == NULL) {
+ return -1;
+ }
+ mir_free((void*)wParam);
+
+ return 0;
+}
+
+int setParseOptions(struct ParseOptions *po) {
+
+ if (po == NULL) {
+ po = &gParseOpts;
+ }
+ ZeroMemory(po, sizeof(struct ParseOptions));
+ if (!db_get_b(NULL, MODULENAME, SETTING_STRIPALL, 0)) {
+ po->bStripEOL = db_get_b(NULL, MODULENAME, SETTING_STRIPCRLF, 0);
+ po->bStripWS = db_get_b(NULL, MODULENAME, SETTING_STRIPWS, 0);
+ }
+ else {
+ po->bStripAll = TRUE;
+ }
+
+ return 0;
+}
+
+int LoadVarModule()
+{
+ if (initTokenRegister() != 0 || initContactModule() != 0)
+ return -1;
+
+ setParseOptions(NULL);
+ hFormatStringService = CreateServiceFunction(MS_VARS_FORMATSTRING, formatStringService);
+ hFreeMemoryService = CreateServiceFunction(MS_VARS_FREEMEMORY, freeMemory);
+ hRegisterVariableService = CreateServiceFunction(MS_VARS_REGISTERTOKEN, registerToken);
+ // help dialog
+ hCurSplitNS = LoadCursor(NULL, IDC_SIZENS);
+
+ if(IsWinVerXPPlus()) {
+ HMODULE hUxTheme = GetModuleHandle(_T("uxtheme.dll"));
+ if (hUxTheme)
+ pfnEnableThemeDialogTexture = (BOOL (WINAPI *)(HANDLE, DWORD))GetProcAddress(hUxTheme, "EnableThemeDialogTexture");
+ }
+ hShowHelpService = CreateServiceFunction(MS_VARS_SHOWHELP, showHelpService);
+ hShowHelpExService = CreateServiceFunction(MS_VARS_SHOWHELPEX, showHelpExService);
+
+ TCHAR szFile[MAX_PATH];
+ GetModuleFileName(hInst, szFile, MAX_PATH);
+
+ SKINICONDESC sid = { 0 };
+ sid.cbSize = sizeof(SKINICONDESC);
+ sid.ptszSection = TranslateT("Variables");
+ sid.ptszDescription = TranslateT("Help");
+ sid.pszName = "vars_help";
+ sid.ptszDefaultFile = szFile;
+ sid.iDefaultIndex = -IDI_V;
+ sid.cx = sid.cy = 16;
+ sid.flags = SIDF_ALL_TCHAR;
+ Skin_AddIcon(&sid);
+
+ hIconsChangedHook = HookEvent(ME_SKIN2_ICONSCHANGED, iconsChanged);
+
+ hGetIconService = CreateServiceFunction(MS_VARS_GETSKINITEM, getSkinItemService);
+ hOptionsHook = HookEvent(ME_OPT_INITIALISE, OptionsInit);
+
+ // register internal tokens
+ registerExternalTokens();
+ registerLogicTokens();
+ registerMathTokens();
+ registerMirandaTokens();
+ registerStrTokens();
+ registerSystemTokens();
+ registerVariablesTokens();
+ registerRegExpTokens();
+ registerInetTokens();
+ registerXsltTokens();
+ registerAliasTokens();
+ registerMetaContactsTokens();
+
+ log_debugA("Variables: Internal tokens registered");
+
+ if (db_get_b(NULL, MODULENAME, SETTING_PARSEATSTARTUP, 0)) {
+ FORMATINFO fi = { 0 };
+ fi.cbSize = sizeof(fi);
+ fi.tszFormat = db_get_tsa(NULL, MODULENAME, SETTING_STARTUPTEXT);
+ if (fi.tszFormat != NULL) {
+ freeMemory((WPARAM)formatString(&fi), 0);
+ mir_free(fi.tszFormat);
+ }
+ }
+ log_debugA("Variables: Init done");
+
+ return 0;
+}
+
+int UnloadVarModule() {
+
+ UnhookEvent(hOptionsHook);
+ if (hIconsChangedHook != NULL)
+ UnhookEvent(hIconsChangedHook);
+
+ DestroyServiceFunction(hRegisterVariableService);
+ DestroyServiceFunction(hFreeMemoryService);
+ DestroyServiceFunction(hFormatStringService);
+ DestroyServiceFunction(hGetMMIService);
+ DestroyServiceFunction(hShowHelpService);
+ DestroyServiceFunction(hShowHelpExService);
+ DestroyServiceFunction(hGetIconService);
+ DestroyCursor(hCurSplitNS);
+ deinitContactModule();
+ deInitExternal();
+ deinitTokenRegister();
+ unregisterAliasTokens();
+ unregisterVariablesTokens();
+ return 0;
+}
diff --git a/plugins/Variables/src/variables.h b/plugins/Variables/src/variables.h
new file mode 100644
index 0000000000..24b2d17737
--- /dev/null
+++ b/plugins/Variables/src/variables.h
@@ -0,0 +1,175 @@
+/*
+ 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
+*/
+
+
+#define MIRANDA_VER 0x0A00
+
+#define _CRT_NON_CONFORMING_SWPRINTFS
+
+#include <tchar.h>
+#include <malloc.h>
+
+#include <windows.h>
+#include <commctrl.h>
+#include "uxtheme.h"
+#include <stdio.h>
+#include <time.h>
+#include "resource.h"
+#ifndef WINE
+#include <win2k.h>
+#endif
+#include <newpluginapi.h>
+#include <m_system.h>
+#include <m_langpack.h>
+#include <m_database.h>
+#include <m_protosvc.h>
+#include <m_clist.h>
+#include <m_contacts.h>
+#include <m_awaymsg.h>
+#include <m_options.h>
+#include <m_utils.h>
+#include <m_icolib.h>
+#include "m_variables.h"
+
+#define MODULENAME "Variables"
+
+#include "../helpers/gen_helpers.h"
+
+#define SETTING_STARTUPTEXT "StartupText"
+#define SETTING_STRIPCRLF "StripCRLF"
+#define SETTING_STRIPWS "StripWS"
+#define SETTING_STRIPALL "StripAll"
+#define SETTING_PARSEATSTARTUP "ParseAtStartup"
+#define SETTING_SPLITTERPOS "SplitterPos"
+#define SETTING_SUBJECT "LastSubject"
+
+#define FIELD_CHAR '%'
+#define FUNC_CHAR '?'
+#define FUNC_ONCE_CHAR '!'
+#define DONTPARSE_CHAR '`'
+#define TRYPARSE_CHAR_OPEN '['
+#define TRYPARSE_CHAR_CLOSE ']'
+#define COMMENT_STRING "#"
+
+// special tokens
+#define SUBJECT "subject"
+#define EXTRATEXT "extratext"
+
+// options
+#define IDT_PARSE 1
+#define DM_SPLITTERMOVED (WM_USER+15)
+
+// Messages you can send to the help window:
+#define VARM_PARSE (WM_APP+11) // wParam=lParam=0
+#define VARM_SETINPUTTEXT (WM_APP+12)
+#define VARM_GETINPUTTEXT (WM_APP+13)
+#define VARM_GETINPUTTEXTLENGTH (WM_APP+14)
+#define VARM_SETSUBJECT (WM_APP+15)
+#define VARM_GETSUBJECT (WM_APP+16) // wParam=HANDLE hContact
+#define VARM_SETEXTRATEXT (WM_APP+17)
+#define VARM_GETEXTRATEXT (WM_APP+18)
+#define VARM_GETEXTRATEXTLENGTH (WM_APP+19)
+#define VARM_GETDIALOG (WM_APP+20)
+
+// if a different struct internally is used, we can use TOKENREGISTEREX
+#define TOKENREGISTEREX TOKENREGISTER
+
+// old struct
+typedef struct {
+ int cbSize;
+ char *szFormat;
+ char *szSource;
+ HANDLE hContact;
+ int pCount; // number of succesful parses
+ int eCount; // number of failures
+} FORMATINFOV1;
+
+struct ParseOptions {
+ BOOL bStripEOL;
+ BOOL bStripWS;
+ BOOL bStripAll;
+};
+
+// variables.c
+//TCHAR *getArguments(char *string, char ***aargv, int *aargc);
+//int isValidTokenChar(char c);
+TCHAR *formatString(FORMATINFO *fi);
+int setParseOptions(struct ParseOptions *po);
+int LoadVarModule();
+int UnloadVarModule();
+// tokenregister.c
+int registerIntToken(TCHAR *szToken, TCHAR *(*parseFunction)(ARGUMENTSINFO *ai), int extraFlags, char* szHelpText);
+INT_PTR registerToken(WPARAM wParam, LPARAM lParam);
+int deRegisterToken(TCHAR *var);
+TOKENREGISTEREX *searchRegister(TCHAR *var, int type);
+TCHAR *parseFromRegister(ARGUMENTSINFO *ai);
+TOKENREGISTEREX *getTokenRegister(int i);
+int getTokenRegisterCount();
+TOKENREGISTER *getTokenRegisterByIndex(int i);
+void deRegisterTemporaryVariables();
+int initTokenRegister();
+int deinitTokenRegister();
+// contact.c
+BYTE getContactInfoType(TCHAR* type);
+TCHAR* getContactInfoT(BYTE type, HANDLE hContact);
+int getContactFromString( CONTACTSINFO* );
+int initContactModule();
+int deinitContactModule();
+// alias
+int registerAliasTokens();
+void unregisterAliasTokens();
+// system
+int registerSystemTokens();
+// external
+int registerExternalTokens();
+int deInitExternal();
+// miranda
+int registerMirandaTokens();
+// str
+int registerStrTokens();
+// variables
+int registerVariablesTokens();
+void unregisterVariablesTokens();
+int clearVariableRegister();
+// logic
+int registerLogicTokens();
+// math
+int registerMathTokens();
+// metacontacts
+int registerMetaContactsTokens();
+// options
+int OptionsInit(WPARAM wParam, LPARAM lParam);
+// reg exp
+int registerRegExpTokens();
+// inet
+int registerInetTokens();
+// xml
+int registerXsltTokens();
+// trigger
+int initTriggerModule();
+// help
+INT_PTR showHelpService(WPARAM wParam, LPARAM lParam);
+INT_PTR showHelpExService(WPARAM wParam, LPARAM lParam);
+INT_PTR getSkinItemService(WPARAM wParam, LPARAM lParam);
+int iconsChanged(WPARAM wParam, LPARAM lParam);
+
+int ttoi(TCHAR *string);
+TCHAR *itot(int num);
+
+extern DWORD g_mirandaVersion;