summaryrefslogtreecommitdiff
path: root/plugins/Variables
diff options
context:
space:
mode:
authorKirill Volinsky <mataes2007@gmail.com>2012-05-18 22:02:50 +0000
committerKirill Volinsky <mataes2007@gmail.com>2012-05-18 22:02:50 +0000
commitf920ef497f3299ae24fe783ce03bdd93b419f764 (patch)
treebdaa9197c08d29ab141a6adfdd6cc0a68ddd3996 /plugins/Variables
parent6c3b0571f0678da0512069869afaa284c054377e (diff)
plugins folders renaming
git-svn-id: http://svn.miranda-ng.org/main/trunk@60 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/Variables')
-rw-r--r--plugins/Variables/Makefile47
-rw-r--r--plugins/Variables/V.icobin0 -> 2550 bytes
-rw-r--r--plugins/Variables/Variables.rc315
-rw-r--r--plugins/Variables/Variables.txt403
-rw-r--r--plugins/Variables/Variables_10.sln26
-rw-r--r--plugins/Variables/Variables_10.vcxproj417
-rw-r--r--plugins/Variables/Variables_10.vcxproj.filters170
-rw-r--r--plugins/Variables/ac/ac.h183
-rw-r--r--plugins/Variables/action_variables.cpp160
-rw-r--r--plugins/Variables/buildnumber.h6
-rw-r--r--plugins/Variables/condition_variables.cpp129
-rw-r--r--plugins/Variables/contact.cpp644
-rw-r--r--plugins/Variables/contact.h78
-rw-r--r--plugins/Variables/copying.txt1
-rw-r--r--plugins/Variables/dbhelpers.h119
-rw-r--r--plugins/Variables/enumprocs.cpp348
-rw-r--r--plugins/Variables/enumprocs.h21
-rw-r--r--plugins/Variables/help.cpp1374
-rw-r--r--plugins/Variables/libxml/DOCBparser.h73
-rw-r--r--plugins/Variables/libxml/HTMLparser.h159
-rw-r--r--plugins/Variables/libxml/HTMLtree.h117
-rw-r--r--plugins/Variables/libxml/SAX.h128
-rw-r--r--plugins/Variables/libxml/c14n.h91
-rw-r--r--plugins/Variables/libxml/catalog.h138
-rw-r--r--plugins/Variables/libxml/debugXML.h163
-rw-r--r--plugins/Variables/libxml/encoding.h230
-rw-r--r--plugins/Variables/libxml/entities.h110
-rw-r--r--plugins/Variables/libxml/globals.h363
-rw-r--r--plugins/Variables/libxml/hash.h166
-rw-r--r--plugins/Variables/libxml/list.h116
-rw-r--r--plugins/Variables/libxml/nanoftp.h117
-rw-r--r--plugins/Variables/libxml/nanohttp.h56
-rw-r--r--plugins/Variables/libxml/parser.h869
-rw-r--r--plugins/Variables/libxml/parserInternals.h413
-rw-r--r--plugins/Variables/libxml/schemasInternals.h354
-rw-r--r--plugins/Variables/libxml/threads.h62
-rw-r--r--plugins/Variables/libxml/tree.h905
-rw-r--r--plugins/Variables/libxml/uri.h68
-rw-r--r--plugins/Variables/libxml/valid.h330
-rw-r--r--plugins/Variables/libxml/xinclude.h26
-rw-r--r--plugins/Variables/libxml/xlink.h180
-rw-r--r--plugins/Variables/libxml/xmlIO.h287
-rw-r--r--plugins/Variables/libxml/xmlautomata.h94
-rw-r--r--plugins/Variables/libxml/xmlerror.h184
-rw-r--r--plugins/Variables/libxml/xmlmemory.h169
-rw-r--r--plugins/Variables/libxml/xmlregexp.h81
-rw-r--r--plugins/Variables/libxml/xmlschemas.h106
-rw-r--r--plugins/Variables/libxml/xmlschemastypes.h42
-rw-r--r--plugins/Variables/libxml/xmlunicode.h164
-rw-r--r--plugins/Variables/libxml/xmlversion.h272
-rw-r--r--plugins/Variables/libxml/xpath.h410
-rw-r--r--plugins/Variables/libxml/xpathInternals.h580
-rw-r--r--plugins/Variables/libxml/xpointer.h83
-rw-r--r--plugins/Variables/libxslt/numbersInternals.h69
-rw-r--r--plugins/Variables/libxslt/transform.h191
-rw-r--r--plugins/Variables/libxslt/win32config.h96
-rw-r--r--plugins/Variables/libxslt/xslt.h97
-rw-r--r--plugins/Variables/libxslt/xsltInternals.h609
-rw-r--r--plugins/Variables/libxslt/xsltexports.h106
-rw-r--r--plugins/Variables/libxslt/xsltutils.h240
-rw-r--r--plugins/Variables/libxslt/xsltwin32config.h84
-rw-r--r--plugins/Variables/lookup3.cpp640
-rw-r--r--plugins/Variables/main.cpp159
-rw-r--r--plugins/Variables/options.cpp147
-rw-r--r--plugins/Variables/pack.cmd35
-rw-r--r--plugins/Variables/parse_alias.cpp226
-rw-r--r--plugins/Variables/parse_alias.h29
-rw-r--r--plugins/Variables/parse_external.cpp266
-rw-r--r--plugins/Variables/parse_external.h25
-rw-r--r--plugins/Variables/parse_inet.cpp155
-rw-r--r--plugins/Variables/parse_inet.h22
-rw-r--r--plugins/Variables/parse_logic.cpp414
-rw-r--r--plugins/Variables/parse_logic.h34
-rw-r--r--plugins/Variables/parse_math.cpp225
-rw-r--r--plugins/Variables/parse_math.h29
-rw-r--r--plugins/Variables/parse_metacontacts.cpp218
-rw-r--r--plugins/Variables/parse_metacontacts.h22
-rw-r--r--plugins/Variables/parse_miranda.cpp997
-rw-r--r--plugins/Variables/parse_miranda.h88
-rw-r--r--plugins/Variables/parse_regexp.cpp204
-rw-r--r--plugins/Variables/parse_regexp.h20
-rw-r--r--plugins/Variables/parse_str.cpp935
-rw-r--r--plugins/Variables/parse_str.h56
-rw-r--r--plugins/Variables/parse_system.cpp1023
-rw-r--r--plugins/Variables/parse_system.h41
-rw-r--r--plugins/Variables/parse_variables.cpp173
-rw-r--r--plugins/Variables/parse_variables.h28
-rw-r--r--plugins/Variables/parse_xml.cpp293
-rw-r--r--plugins/Variables/parse_xml.h2
-rw-r--r--plugins/Variables/pcre/include/pcre.h239
-rw-r--r--plugins/Variables/pcre/include/pcreposix.h117
-rw-r--r--plugins/Variables/pcre/pcre_license.txt45
-rw-r--r--plugins/Variables/resource.h56
-rw-r--r--plugins/Variables/resource.rc2
-rw-r--r--plugins/Variables/tokenregister.cpp340
-rw-r--r--plugins/Variables/trigger_variables.cpp248
-rw-r--r--plugins/Variables/trigger_variables.h36
-rw-r--r--plugins/Variables/variables.cpp680
-rw-r--r--plugins/Variables/variables.h177
-rw-r--r--plugins/Variables/variables.spec3
-rw-r--r--plugins/Variables/version.rc44
101 files changed, 22132 insertions, 0 deletions
diff --git a/plugins/Variables/Makefile b/plugins/Variables/Makefile
new file mode 100644
index 0000000000..6e02fdc660
--- /dev/null
+++ b/plugins/Variables/Makefile
@@ -0,0 +1,47 @@
+CC = winegcc
+CPP = wineg++
+WRC = wrc
+
+CPPFLAGS = -I/usr/local/include/wine/windows \
+ -I/usr/local/include/wine/msvcrt \
+ -I./include \
+ -I./src/core
+
+LNK_COMMON = -L/usr/local/lib/wine \
+ -lwine \
+ -lmsvcrt \
+ -lgdi32 \
+ -lshell32 \
+ -lole32 \
+ -lcomctl32 \
+ -lcomdlg32
+
+LNK_MAINLIBS = -lversion \
+ -lws2_32 \
+ -lwinmm \
+ -loleaut32 \
+ -luuid
+
+VARIABLESOBJS = ./plugins/Variables/main.c ./plugins/Variables/parse_miranda.c ./plugins/Variables/options.c ./plugins/Variables/parse_alias.c ./plugins/Variables/parse_regexp.c ./plugins/Variables/tokenregister.c ./plugins/Variables/contact.c ./plugins/Variables/parse_external.c ./plugins/Variables/parse_str.c ./plugins/Variables/variables.c ./plugins/Variables/parse_inet.c ./plugins/Variables/parse_system.c ./plugins/Variables/parse_logic.c ./plugins/Variables/parse_variables.c ./plugins/Variables/help.c ./plugins/Variables/parse_math.c ./plugins/helpers/db_helpers.c ./plugins/helpers/gen_helpers.c
+
+all: plugin-variables
+
+plugin-variables: $(VARIABLESOBJS)
+ cd ./plugins/Variables && $(WRC) -I. resource.rc
+ $(CC) $(CPPFLAGS) -DWINE -shared ./plugins/Variables/variables.spec $(VARIABLESOBJS) ./plugins/Variables/resource.res $(LNK_COMMON) -o variables.dll
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) -DHAVE_CONFIG_H -o $@ $<
+
+.cpp.o:
+ $(CPP) -c $(CPPFLAGS) -o $@ $<
+
+clean:
+ rm -f Variables.so *~
+ find ./plugins/Variables -name *~ -exec rm -f {} \;
+ find ./plugins/Variables -name *.o -exec rm -f {} \;
+ find ./plugins/Variables -name *.res -exec rm -f {} \;
+ find ./plugins/Variables -name *.orig -exec rm -f {} \;
+ find ./plugins/Variables -name *.rej -exec rm -f {} \;
+
+
diff --git a/plugins/Variables/V.ico b/plugins/Variables/V.ico
new file mode 100644
index 0000000000..7f016eee31
--- /dev/null
+++ b/plugins/Variables/V.ico
Binary files differ
diff --git a/plugins/Variables/Variables.rc b/plugins/Variables/Variables.rc
new file mode 100644
index 0000000000..2907d921d9
--- /dev/null
+++ b/plugins/Variables/Variables.rc
@@ -0,0 +1,315 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include <windows.h>
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_OPTS_DIALOG DIALOGEX 0, 0, 314, 240
+STYLE DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg"
+BEGIN
+ EDITTEXT IDC_FORMATTEXT,31,101,250,52,ES_MULTILINE |
+ ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN |
+ WS_VSCROLL | WS_HSCROLL
+ PUSHBUTTON "Parse",IDC_PARSE,231,157,50,14
+ CONTROL "Auto parse",IDC_AUTOPARSE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,31,161,161,10
+ EDITTEXT IDC_RESULT,31,172,250,52,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_READONLY | ES_WANTRETURN |
+ WS_VSCROLL | WS_HSCROLL
+ CONTROL "Parse the following string at startup",
+ IDC_PARSEATSTARTUP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 31,90,161,10
+ CONTROL "Automatically strip ""end of line"" characters",
+ IDC_STRIPCRLF,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,31,
+ 20,253,10
+ CONTROL "Automatically strip white space",IDC_STRIPWS,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,31,32,253,10
+ GROUPBOX "Test area",IDC_STATIC,23,62,272,168
+ LTEXT "Click on the help button to get more information",
+ IDC_STATIC,31,73,249,8
+ GROUPBOX "Parse options",IDC_STATIC,23,7,272,51
+ CONTROL "Automatically strip all non-parsing characters",
+ IDC_STRIPALL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,31,44,
+ 253,10
+ CONTROL "",IDC_SHOWHELP,"MButtonClass",WS_TABSTOP,265,87,16,14,
+ 0x18000000L
+END
+
+IDD_TRG_STRINGCHANGE DIALOGEX 0, 0, 314, 240
+STYLE DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_FORMATTEXT,7,42,300,114,ES_MULTILINE |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ LTEXT "Trigger when the following string changes",IDC_STATIC,7,
+ 7,300,8
+END
+
+IDD_INPUT_DIALOG DIALOGEX 0, 0, 280, 240
+STYLE DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_RESULT,7,191,266,42,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_READONLY | ES_WANTRETURN |
+ WS_VSCROLL | WS_HSCROLL
+ EDITTEXT IDC_TESTSTRING,7,146,266,42,ES_MULTILINE |
+ ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN |
+ WS_VSCROLL | WS_HSCROLL
+ CONTROL "",IDC_SPLITTER,"Static",SS_ENHMETAFILE,7,188,266,2
+ LTEXT "Please enter your input below",IDC_STATIC,7,132,195,8
+ CONTROL "List1",IDC_TOKENLIST,"SysListView32",LVS_REPORT |
+ LVS_SINGLESEL | LVS_NOSORTHEADER | WS_BORDER |
+ WS_TABSTOP,7,7,266,121
+END
+
+IDD_CLIST_DIALOG DIALOGEX 0, 0, 244, 245
+STYLE DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ CONTROL "",IDC_CLIST,"ClistControl",WS_TABSTOP | 0x248,13,100,
+ 218,132,WS_EX_CLIENTEDGE
+ CONTROL "Don't set a contact",IDC_NULL,"Button",
+ BS_AUTORADIOBUTTON,13,76,144,10
+ CONTROL "Set to the following contact",IDC_CONTACT,"Button",
+ BS_AUTORADIOBUTTON,13,87,147,10
+ LTEXT "The token %subject% is translated into a special contact, which depends on the situation in which the string is parsed. Use this dialog to simulate the contact to which %subject% translates. An example for using this token is: !cinfo(%subject%,display).",
+ IDC_ABOUT,13,20,218,34
+ GROUPBOX "Description",IDC_ABOUTFRAME,7,7,230,50
+ GROUPBOX "Setting",IDC_SETTINGFRAME,7,63,230,175
+END
+
+IDD_EXTRATEXT_DIALOG DIALOGEX 0, 0, 244, 245
+STYLE DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_EXTRATEXT,13,76,218,156,ES_MULTILINE |
+ ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN |
+ WS_VSCROLL | WS_HSCROLL
+ GROUPBOX "Description",IDC_ABOUTFRAME,7,7,230,50
+ GROUPBOX "Setting",IDC_SETTINGFRAME,7,63,230,175
+ LTEXT "The token %extratext% is translated into a string which depends on the situation in which the string is parsed. Use this dialog to simulate the string to which %extratext% translates.",
+ IDC_ABOUT,13,20,218,34
+END
+
+IDD_HELP_DIALOG DIALOG DISCARDABLE 0, 0, 326, 343
+STYLE DS_3DLOOK | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION |
+ WS_THICKFRAME
+FONT 8, "MS Shell Dlg"
+BEGIN
+ CONTROL "Tab1",IDC_TABS,"SysTabControl32",0x0,7,7,312,313
+ PUSHBUTTON "Close",IDC_CANCEL,269,322,50,14
+ PUSHBUTTON "OK",IDC_OK,216,322,50,14,NOT WS_VISIBLE
+END
+
+IDD_TOKENS_DIALOG DIALOGEX 0, 0, 245, 245
+STYLE WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ CONTROL "List1",IDC_TOKENLIST,"SysListView32",LVS_REPORT |
+ LVS_SINGLESEL | LVS_NOSORTHEADER | WS_BORDER |
+ WS_TABSTOP,13,76,218,156
+ GROUPBOX "Description",IDC_ABOUTFRAME,7,7,231,50
+ GROUPBOX "Setting",IDC_SETTINGFRAME,7,63,231,175
+ LTEXT "The Variables plugin translates various tokens into a certain value. An example is: I'm running Miranda %mirandaversion%. The substring %mirandaversion% will be translated into the correct version number. The following list shows all available tokens.",
+ IDC_ABOUT,13,20,218,34
+END
+
+IDD_HELPINFO_DIALOG DIALOGEX 0, 0, 244, 244
+STYLE WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Notes",IDC_SETTINGFRAME,7,7,230,231
+ EDITTEXT IDC_HELPDESC,13,20,218,210,ES_MULTILINE | ES_READONLY |
+ ES_WANTRETURN | NOT WS_BORDER | WS_VSCROLL
+END
+
+IDD_ACT_PARSESTRING DIALOGEX 0, 0, 236, 116
+STYLE DS_3DLOOK | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_PARSESTRING,7,7,222,85,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL | WS_HSCROLL
+ PUSHBUTTON "Variables...",IDC_SHOWHELP,7,95,50,14
+END
+
+IDD_CND_PARSESTRING DIALOGEX 0, 0, 236, 116
+STYLE DS_3DLOOK | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_PARSESTRING,7,7,222,85,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL | WS_HSCROLL
+ PUSHBUTTON "Variables...",IDC_SHOWHELP,7,95,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_OPTS_DIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 307
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 233
+ END
+
+ IDD_TRG_STRINGCHANGE, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 307
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 233
+ END
+
+ IDD_INPUT_DIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 273
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 233
+ END
+
+ IDD_CLIST_DIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 237
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 238
+ END
+
+ IDD_EXTRATEXT_DIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 237
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 238
+ END
+
+ IDD_HELP_DIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 319
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 336
+ END
+
+ IDD_TOKENS_DIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 238
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 238
+ END
+
+ IDD_HELPINFO_DIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 237
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 237
+ END
+
+ IDD_ACT_PARSESTRING, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 229
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 109
+ END
+
+ IDD_CND_PARSESTRING, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 229
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 109
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE MOVEABLE PURE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE MOVEABLE PURE
+BEGIN
+ "#include <windows.h>\r\n"
+END
+
+3 TEXTINCLUDE MOVEABLE PURE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_V ICON DISCARDABLE "V.ico"
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins/Variables/Variables.txt b/plugins/Variables/Variables.txt
new file mode 100644
index 0000000000..14b37e0a48
--- /dev/null
+++ b/plugins/Variables/Variables.txt
@@ -0,0 +1,403 @@
+Variables plugin for Miranda IM v0.2.2.0
+unregistered@users.sourceforge.net
+
+--- About ---
+
+This plugin doesn't add any functionality on itself. But other plugins
+can use it to format a string which contains variables. Since this
+plugin can be quite complicated to use, please read this document
+carefully before reporting any problems.
+
+Many thanks to HeikoH and DeathDemon for their suggestions and help.
+
+--- Usage ---
+
+Variables requires Windows 2000 or higher, and the unicode version
+requires the unicode version of Miranda.
+
+The Variables plugin allows you to use special formatting of strings
+within plugins that process their strings using this plugin. Examples
+of such plugins are NewAwaySys, Tipper, SimpleAway and
+StartupStatus. Please refer to the documentation of the plugin whether
+or not Variables is supported. Usually, there is no special action
+needed to use a formatting string instead of a normal string.
+
+A formatting string consists of 'tokens', special keywords which are
+translated by the Variables plugin into some text. Popular use of
+Variables is to show the currently playing song in your away
+message. If your away message module (like NewAwaySys) supports the
+Variables plugin, you can enter a text like the following to show your
+current Winamp song in your away message: "Hi, I'm listening to
+%winampsong%.". In this example, the token '%winampsong%' will be
+translated by the Variables plugin into the current song. Please see
+the notes for more details.
+
+Such special keywords, or tokens, are there in two flavors. First,
+there are fields, the syntax for a field is %fieldname%, an example is
+the already shown %winampsong% field. A field takes no arguments. A
+but more advanced is the second flavor, functions. Functions are
+usually accessed by "?functionname(argument1,argument2,...)", a
+function can take zero or more arguments. An example of a function is
+"?add(1,1)", this function will, as you can guess, be replaced by the
+number "2".
+
+A complete list of tokens can be found by pressing "Help..." on the
+Plugins->Variables options screen.
+
+Next to the % and ? character, there are a few others which have a
+special meaning, these are:
+
+!function
+
+This will parse the function given the arguments, but the result will
+not be parsed again. Example: "Message waiting:
+!message(,first,rcvd,unread)". In case you use
+"?message(,first,rcvd,unread)" and the message would be "You should
+use the string %winampsong% to get the song.", the result could be
+"Message waiting: You should use the string DJ Mike Llama - Llama
+Whippin' Intro to get the song.".
+
+`string`
+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." It's usually a good idea to put any non-special keyword between
+` characters.
+
+#comment
+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."
+
+The Variables plugin allows you to build much more complex formatting
+strings than the one shown above. Please refer to the "Additional
+Help" and "Notes" sections at the end of this document for more
+information.
+
+There are a few settings in the options dialog:
+
+[] Automatically strip "end of line" characters
+
+This will remove any CRLF or LF characters. You can insert them using
+the crlf function.
+
+[] Automatically strip white characters
+
+This will remove any white space. You can add white spaces by placing
+` characters around them (see above).
+
+[] Automatically strip all non-parsing characters
+
+This will remove any characters that don't have a special meaning
+(all characters except those shown above). Basically this means you
+have to put all text besides tokens and comments between ` characters
+(see above).
+
+[] Parse the following string at startup
+
+The input box below this option is not just for testing, you can
+choose to parse the string at startup to set your global variables
+using the put and puts functions (which aren't different in this
+case). Also, you can created aliases using the alias function.
+
+[] Auto parse
+
+Normally the string is only parsed when you press the "Parse" button,
+check this to keep the parsed string updated every second.
+
+[Help...]
+
+Pressing this button shows up a list of available functions and
+fields.
+
+--- Additional Help ---
+
+As stated before, this plugin can be quite complicated to use, here
+follows some addition help for some of the complex functions.
+
+---
+if(x,y,z)
+---
+The Variables has several functions based on logics. The if function
+will show string y in case x evaluates to true, and z otherwise. The
+return values of the several logic functions can be found in the help
+dialog. Also, a string x is false in case an error occurs while
+parsing it.
+
+Example:
+!if(%winampsong%,`winamp is running`,`winamp is not running`)
+
+---
+cinfo(x,y)
+---
+x specifies the contact (see notes).
+
+y specifies the info you want to retrieve, the following values are
+possible:
+
+first, last, nick, cnick, email, city, state, country, phone,
+homepage, about, gender, age, firstlast, id, display, protocol,
+status, intip, extip, protoid
+
+From Miranda IM v0.4.3.0 Test Build #55, the following are also
+available:
+
+fax, cellular, timezone, mynotes, bday, bmonth, byear, street, zip,
+lang1, lang2, lang3, coname, codept, copos, costreet, cocity, costate,
+cozip, cocountry, cohomepage
+
+Example:
+!cinfo(<ICQ:12345678>,nick)
+
+---
+lsdate(x,y)
+lstime(x,y)
+lsstatus(x)
+---
+These functions require LastSeen or ContactsEx to be installed.
+
+---
+lsdate(x,y)
+cdate(x)
+---
+The format argument can be formatted using the following:
+
+d Day of month as digits with no leading zero for single-digit
+ days.
+
+dd Day of month as digits with leading zero for single-digit
+ days.
+
+ddd Day of week as a three-letter abbreviation.
+
+dddd Day of week as its full name.
+
+M Month as digits with no leading zero for single-digit months.
+
+MM Month as digits with leading zero for single-digit months.
+
+MMM Month as a three-letter abbreviation.
+
+MMMM Month as its full name.
+
+y Year as last two digits, but with no leading zero for years
+ less than 10.
+
+yy Year as last two digits, but with leading zero for years less
+ than 10.
+
+yyyy Year represented by full four digits.
+
+gg Period/era string. This element is ignored if the date to be
+ formatted does not have an associated era or period string.
+
+---
+lstime(x,y)
+ctime(x)
+---
+The format parameter can be formatted using the following:
+
+h Hours with no leading zero for single-digit hours; 12-hour
+ clock.
+
+hh Hours with leading zero for single-digit hours; 12-hour
+ clock.
+
+H Hours with no leading zero for single-digit hours; 24-hour
+ clock.
+
+HH Hours with leading zero for single-digit hours; 24-hour
+ clock.
+
+m Minutes with no leading zero for single-digit minutes.
+
+mm Minutes with leading zero for single-digit minutes.
+
+s Seconds with no leading zero for single-digit seconds.
+
+ss Seconds with leading zero for single-digit seconds.
+
+t One character time-marker string, such as A or P.
+
+tt Multicharacter time-marker string, such as AM or PM.
+
+---
+subject
+---
+This field returns a string in the format <PROTOCOL:UNQIUEID>, the
+contact associated with this token depends on the plugin which uses it.
+
+---
+extratext
+---
+This field returns a string depending on the plugin which uses it.
+
+---
+get(x)
+put(x,y)
+puts(x,y)
+---
+Put and puts will store string y under name x. Puts will return
+nothing, while put returns the string stored. Get will retrieve the
+value stored earlier with put or puts.
+
+NOTE: The stored string is first parsed, this means calling for
+example !puts(time,!ctime()) and later !get(time) will always return
+the time at which puts was called. Use !alias(x,y) to store 'unparsed
+strings'.
+
+NOTE2: Strings stored using put and puts can always be accessed (they
+are shared amongst instances). So beware you don't modify a variable
+in two places (unless you want that to happen).
+
+---
+alias(x,y)
+---
+Stores an alias named x with the value y. The alias x can be used as a
+regular token. You can also override existing tokens using the alias
+function.
+
+Example:
+!alias(song(pl,st,pa,nr),!switch(?if(!and(%winampstate%,%winampsong%),%winampstate%,`Not Running`),`Playing`,pl,`Paused`,pa,`Stopped`,st,`Not Running`,nr))
+This line above will add a token "song" which takes 4 arguments. The
+first one is the string when Winamp is playing a song, the second when
+stopped, the third when paused and the fourth argument specifies the
+string when Winamp is not running. You can use it like this:
+
+?song(%winampsong%` is playing`,`just stopped listening to `%winampsong%,%winampsong%` <- paused`,`Winamp is not running`)
+
+---
+message(x,y,z,w)
+---
+Retrieves a message for contact x according to y,z and w.
+
+y = either "first" to retrieve the first message or "last" (default)
+to get the last one.
+
+z = either "sent" to retrieve a sent message or "rcvd" to get a
+received one.
+
+w = either "read" to get a message you already read, or "unread" to
+get one from the message queue. Only used when z = "rcvd".
+
+If an argument is not given, this function will retrieve the message
+according to the rest of the arguments. Some examples:
+
+!message(,`first`,`rcvd`,`unread`)
+ This is 'normal' operation, to get the first message in the message queue.
+
+!message(%subject%,`last`,`rcvd`,`unread`)
+ Get the last message you received from the contact %subject%, which
+ is in the message queue.
+
+!message(%subject%,`last`,,)
+ Get the last message from contact %subject%. This one could be sent,
+ received, read or unread.
+
+!message(,,,)
+ Get the last message Miranda processed.
+
+---
+for(w,x,y,z)
+---
+
+Generates a for-loop; w will be initialized, x specifies the condition
+on which y will be executed and z will be shown.
+
+Example:
+!for(!puts(i,0),!not(!strcmp(!get(i),3)),!puts(i,!add(!get(i),1)),i=!get(i)!crlf())
+
+--- Notes ---
+
+1)
+Whenever a functions requires a contact as an argument, you can
+specify it in two ways:
+
+- 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>.
+
+- Using the contact function:
+---
+contact(x,y)
+---
+A contact will be searched which will have value x for its property y,
+y can be one of the following:
+
+first, last, nick, email, id, display
+
+Example:
+?contact(miranda@hotmail.com,email) or
+?contact(Miranda,nick).
+
+Contact will return either a unique contact according to the arguments
+or nothing if none or multiple contacts exists with the given
+property. If a property holds for multiple contacts, you can select
+one of those contacts by adding an extra argument z. This indicates
+which contact to use. The ?ccount function can be used to find out how
+many contacts hold for a certain property. The following formatting
+string demonstrates the use of ccount and contact with three
+arguments.
+
+Example:
+# get the number of contacts with the display name "Marley"
+!puts(count,!ccount(`Marley`,display))
+# loop through these contacts, for each of them, show the e-mail address
+!for(!puts(n,0),!not(!strcmp(!get(n),!get(count))),!puts(n,!add(!get(n),1)),!cinfo(!contact(`Marley`,`display`,!add(!get(n),1)),email))
+
+In case the z argument is used, y can be any property of the cinfo
+function. Z can be 'r' to get a random contact.
+
+2)
+The %winampsong% field will only retrieve a song for Winamp, for
+Foobar2000, I recommend using foo_text
+(http://members.lycos.co.uk/musicf/) and the txtfile function.
+
+3)
+The variables regexp_check and regexp_substr are only available if you
+have pcre.dll or pcre3.dll in your miranda directory (or system32).
+PCRE is available from the "external" folder in this package and/or
+from http://www.pcre.org/
+
+4)
+The variables amipvar and amipformat are only available if you have
+ac.dll in your miranda directory (or system32). ac.dll is available
+from the "external" folder in this package and/or from
+http://amip.tools-for.net/ (part of amip_sdk). You'll also need to
+install one of the AMIP servers from http://amip.tools-for.net/
+
+5)
+Variables v0.2.0.0 syntax is inspired by the TAGZ system used in
+Foobar2000, http://www.foobar2000.org/.
+
+
+--- Changelog ---
+
+0.2.3.4: - added ?cinfo(<>,account) -> gets the account name under 0.8.x and later
+
+0.2.3.3: - memory leak fix
+
+0.2.3.2: - adaptation for Miranda 0.8
+
+0.2.3.0: - temporary variables were added by Ricardo Pescuma Domenecci
+ - fixes for memory leaks & crashes
+
+0.2.2.0: - Added service MS_VARS_GETSKINITEM (V icon by Faith Healer)
+ - Added option to remove white spaces and other non-parsing characters
+ - Change in parsing routine: fields (%field%) are not parsed by default, use ?noop(%field%) instead
+ - Change in parsing routine: fields won't be parsed with function chars anymore and vise versa
+ - Added function strmcmp, amipvar, amipformat, noop, protoname, ls
+ - %subject% supports contacts without uniqueid (please test)
+ - txtfile now supports unicode text files
+ - Performance gain (only if you use HUGE strings or rapid parsing) by using (Bob Jenkins') hash function
+ - Lots of bug fixes
+
+0.2.1.0: - Lot of bug fixes, unicode version, extended API, much more
+
+0.2.0.0: - Build from scratch
+
+0.1.0.0: - First release
+
+--- Disclaimer ---
+
+If something terrible happens, don't blame me.
diff --git a/plugins/Variables/Variables_10.sln b/plugins/Variables/Variables_10.sln
new file mode 100644
index 0000000000..52d8970a65
--- /dev/null
+++ b/plugins/Variables/Variables_10.sln
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Variables", "Variables_10.vcxproj", "{3038EF69-85BE-4D92-9864-CD6A5EBB558A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {3038EF69-85BE-4D92-9864-CD6A5EBB558A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {3038EF69-85BE-4D92-9864-CD6A5EBB558A}.Debug|Win32.Build.0 = Debug|Win32
+ {3038EF69-85BE-4D92-9864-CD6A5EBB558A}.Debug|x64.ActiveCfg = Debug|x64
+ {3038EF69-85BE-4D92-9864-CD6A5EBB558A}.Debug|x64.Build.0 = Debug|x64
+ {3038EF69-85BE-4D92-9864-CD6A5EBB558A}.Release|Win32.ActiveCfg = Release|Win32
+ {3038EF69-85BE-4D92-9864-CD6A5EBB558A}.Release|Win32.Build.0 = Release|Win32
+ {3038EF69-85BE-4D92-9864-CD6A5EBB558A}.Release|x64.ActiveCfg = Release|x64
+ {3038EF69-85BE-4D92-9864-CD6A5EBB558A}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/plugins/Variables/Variables_10.vcxproj b/plugins/Variables/Variables_10.vcxproj
new file mode 100644
index 0000000000..028b908e84
--- /dev/null
+++ b/plugins/Variables/Variables_10.vcxproj
@@ -0,0 +1,417 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>Variables</ProjectName>
+ <ProjectGuid>{3038EF69-85BE-4D92-9864-CD6A5EBB558A}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</IgnoreImportLibrary>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</IgnoreImportLibrary>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.dll</TargetExt>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.dll</TargetExt>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)64/Plugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)64/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\Variables___Win32_Debug_Unicode/Variables.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;./pcre/include;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;VARIABLES_EXPORTS;UNICODE;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeaderFile>variables.h</PrecompiledHeaderFile>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ <AdditionalIncludeDirectories>../../include/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>Pdh.lib;Ws2_32.lib;Delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DelayLoadDLLs>pdh.dll;Ws2_32.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\Variables___Win32_Release_Unicode/Variables.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;./pcre/include;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;VARIABLES_EXPORTS;UNICODE;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderFile>variables.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4996;4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>odbc32.lib;odbccp32.lib;pdh.lib;Ws2_32.lib;Delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <DelayLoadDLLs>pdh.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;./pcre/include;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN64;NDEBUG;_WINDOWS;_USRDLL;VARIABLES_EXPORTS;UNICODE;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>Pdh.lib;Ws2_32.lib;Delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;./pcre/include;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN64;_DEBUG;_WINDOWS;_USRDLL;VARIABLES_EXPORTS;UNICODE;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>Pdh.lib;Ws2_32.lib;Delayimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="contact.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <ClCompile Include="help.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <ClCompile Include="lookup3.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ </PrecompiledHeader>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ </PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="options.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <ClCompile Include="tokenregister.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <ClCompile Include="variables.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <ClCompile Include="enumprocs.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ </PrecompiledHeader>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ </PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="parse_alias.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <ClCompile Include="parse_external.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <ClCompile Include="parse_inet.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <ClCompile Include="parse_logic.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <ClCompile Include="parse_math.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <ClCompile Include="parse_metacontacts.cpp" />
+ <ClCompile Include="parse_miranda.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <ClCompile Include="parse_regexp.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <ClCompile Include="parse_str.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <ClCompile Include="parse_system.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <ClCompile Include="parse_variables.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <ClCompile Include="parse_xml.cpp" />
+ <ClCompile Include="action_variables.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <ClCompile Include="condition_variables.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <ClCompile Include="trigger_variables.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <ClCompile Include="..\helpers\db_helpers.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ </PrecompiledHeader>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ </PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\helpers\gen_helpers.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ </PrecompiledHeader>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ </PrecompiledHeader>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="contact.h" />
+ <ClInclude Include="m_variables.h" />
+ <ClInclude Include="variables.h" />
+ <ClInclude Include="enumprocs.h" />
+ <ClInclude Include="parse_alias.h" />
+ <ClInclude Include="parse_external.h" />
+ <ClInclude Include="parse_inet.h" />
+ <ClInclude Include="parse_logic.h" />
+ <ClInclude Include="parse_math.h" />
+ <ClInclude Include="parse_metacontacts.h" />
+ <ClInclude Include="parse_miranda.h" />
+ <ClInclude Include="parse_regexp.h" />
+ <ClInclude Include="parse_str.h" />
+ <ClInclude Include="parse_system.h" />
+ <ClInclude Include="parse_variables.h" />
+ <ClInclude Include="parse_xml.h" />
+ <ClInclude Include="trigger_variables.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="V.ico" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="Variables.rc" />
+ <ResourceCompile Include="version.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/Variables/Variables_10.vcxproj.filters b/plugins/Variables/Variables_10.vcxproj.filters
new file mode 100644
index 0000000000..16981eeecb
--- /dev/null
+++ b/plugins/Variables/Variables_10.vcxproj.filters
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{bbbab72c-66ee-48bb-8146-6d77f1246b99}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{0ba7f79c-77dc-4771-ab7e-0a80d36ff344}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{58ddc992-d18e-44d2-90c4-98bf35c13102}</UniqueIdentifier>
+ <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ <Filter Include="Parse">
+ <UniqueIdentifier>{c92d28b1-a1b2-48e8-bc84-c58d24e60e7b}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="TriggerPlugin">
+ <UniqueIdentifier>{68dc4171-ed30-45bd-aaef-98c9b9bfc2f6}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="External">
+ <UniqueIdentifier>{85d92491-9930-4020-9632-66d1c5eebd74}</UniqueIdentifier>
+ <Extensions>*.cpp</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="contact.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="help.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="lookup3.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="options.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="tokenregister.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="variables.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="enumprocs.cpp">
+ <Filter>Parse</Filter>
+ </ClCompile>
+ <ClCompile Include="parse_alias.cpp">
+ <Filter>Parse</Filter>
+ </ClCompile>
+ <ClCompile Include="parse_external.cpp">
+ <Filter>Parse</Filter>
+ </ClCompile>
+ <ClCompile Include="parse_inet.cpp">
+ <Filter>Parse</Filter>
+ </ClCompile>
+ <ClCompile Include="parse_logic.cpp">
+ <Filter>Parse</Filter>
+ </ClCompile>
+ <ClCompile Include="parse_math.cpp">
+ <Filter>Parse</Filter>
+ </ClCompile>
+ <ClCompile Include="parse_metacontacts.cpp">
+ <Filter>Parse</Filter>
+ </ClCompile>
+ <ClCompile Include="parse_miranda.cpp">
+ <Filter>Parse</Filter>
+ </ClCompile>
+ <ClCompile Include="parse_regexp.cpp">
+ <Filter>Parse</Filter>
+ </ClCompile>
+ <ClCompile Include="parse_str.cpp">
+ <Filter>Parse</Filter>
+ </ClCompile>
+ <ClCompile Include="parse_system.cpp">
+ <Filter>Parse</Filter>
+ </ClCompile>
+ <ClCompile Include="parse_variables.cpp">
+ <Filter>Parse</Filter>
+ </ClCompile>
+ <ClCompile Include="parse_xml.cpp">
+ <Filter>Parse</Filter>
+ </ClCompile>
+ <ClCompile Include="action_variables.cpp">
+ <Filter>TriggerPlugin</Filter>
+ </ClCompile>
+ <ClCompile Include="condition_variables.cpp">
+ <Filter>TriggerPlugin</Filter>
+ </ClCompile>
+ <ClCompile Include="trigger_variables.cpp">
+ <Filter>TriggerPlugin</Filter>
+ </ClCompile>
+ <ClCompile Include="..\helpers\db_helpers.cpp">
+ <Filter>External</Filter>
+ </ClCompile>
+ <ClCompile Include="..\helpers\gen_helpers.cpp">
+ <Filter>External</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="contact.h">
+ <Filter>Source Files</Filter>
+ </ClInclude>
+ <ClInclude Include="m_variables.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="variables.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="enumprocs.h">
+ <Filter>Parse</Filter>
+ </ClInclude>
+ <ClInclude Include="parse_alias.h">
+ <Filter>Parse</Filter>
+ </ClInclude>
+ <ClInclude Include="parse_external.h">
+ <Filter>Parse</Filter>
+ </ClInclude>
+ <ClInclude Include="parse_inet.h">
+ <Filter>Parse</Filter>
+ </ClInclude>
+ <ClInclude Include="parse_logic.h">
+ <Filter>Parse</Filter>
+ </ClInclude>
+ <ClInclude Include="parse_math.h">
+ <Filter>Parse</Filter>
+ </ClInclude>
+ <ClInclude Include="parse_metacontacts.h">
+ <Filter>Parse</Filter>
+ </ClInclude>
+ <ClInclude Include="parse_miranda.h">
+ <Filter>Parse</Filter>
+ </ClInclude>
+ <ClInclude Include="parse_regexp.h">
+ <Filter>Parse</Filter>
+ </ClInclude>
+ <ClInclude Include="parse_str.h">
+ <Filter>Parse</Filter>
+ </ClInclude>
+ <ClInclude Include="parse_system.h">
+ <Filter>Parse</Filter>
+ </ClInclude>
+ <ClInclude Include="parse_variables.h">
+ <Filter>Parse</Filter>
+ </ClInclude>
+ <ClInclude Include="parse_xml.h">
+ <Filter>Parse</Filter>
+ </ClInclude>
+ <ClInclude Include="trigger_variables.h">
+ <Filter>TriggerPlugin</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="V.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="Variables.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ <ResourceCompile Include="version.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/Variables/ac/ac.h b/plugins/Variables/ac/ac.h
new file mode 100644
index 0000000000..7d0790f32b
--- /dev/null
+++ b/plugins/Variables/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/action_variables.cpp b/plugins/Variables/action_variables.cpp
new file mode 100644
index 0000000000..c981400410
--- /dev/null
+++ b/plugins/Variables/action_variables.cpp
@@ -0,0 +1,160 @@
+/*
+ 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
+*/
+// 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) {
+ free(tszParsed);
+ }
+ if (fi->tszFormat != NULL) {
+ free(fi->tszFormat);
+ }
+ if (fi->tszExtraText != NULL) {
+ free(fi->tszExtraText);
+ }
+ 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* )malloc(sizeof(FORMATINFO));
+ ZeroMemory(fi, sizeof(FORMATINFO));
+ fi->cbSize = sizeof(FORMATINFO);
+ fi->tszFormat = _tcsdup(dbv.ptszVal);
+ fi->tszExtraText = ((ri->td!=NULL)&&(ri->td->dFlags&DF_TEXT))?_tcsdup(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 {
+ 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;
+ TCHAR *tszText;
+
+ actionID = (DWORD)wParam;
+ tszText = Hlp_GetDlgItemText(hwndDlg, IDC_PARSESTRING);
+ if (tszText != NULL) {
+ DBWriteActionSettingTString(actionID, NULL, MODULENAME, SETTING_PARSESTRING, tszText);
+ 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/buildnumber.h b/plugins/Variables/buildnumber.h
new file mode 100644
index 0000000000..2e38a77fad
--- /dev/null
+++ b/plugins/Variables/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/condition_variables.cpp b/plugins/Variables/condition_variables.cpp
new file mode 100644
index 0000000000..6e6739f112
--- /dev/null
+++ b/plugins/Variables/condition_variables.cpp
@@ -0,0 +1,129 @@
+/*
+ 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
+*/
+// 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;
+ 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);
+ free(tszText);
+ }
+ break;
+ }
+
+ case WM_DESTROY:
+ break;
+ }
+
+ return FALSE;
+} \ No newline at end of file
diff --git a/plugins/Variables/contact.cpp b/plugins/Variables/contact.cpp
new file mode 100644
index 0000000000..862beff129
--- /dev/null
+++ b/plugins/Variables/contact.cpp
@@ -0,0 +1,644 @@
+/*
+ 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
+*/
+#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) }
+};
+
+#define NEWTSTR_ALLOCA(A) (A==NULL)?NULL:_tcscpy((TCHAR*)alloca(sizeof(TCHAR)*(_tcslen(A)+1)),A)
+
+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
+*/
+static TCHAR* getContactInfo(BYTE type, HANDLE hContact)
+{
+ /* returns dynamic allocated buffer with info, or NULL if failed */
+ CONTACTINFO ci;
+ TCHAR *res, *szStatus;
+ char *szProto, protoname[128], szVal[16];
+ int status;
+ BYTE realType;
+ DBVARIANT dbv;
+
+ res = NULL;
+ if (hContact == NULL)
+ return NULL;
+
+ realType = (type & ~CNF_UNICODE);
+ switch ( realType ) {
+ case CCNF_PROTOID:
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if (szProto == NULL)
+ return NULL;
+
+ if ( type & CNF_UNICODE )
+ return (TCHAR *)a2u(szProto);
+ return (TCHAR *)_strdup(szProto);
+
+ case CCNF_ACCOUNT:
+ if ( g_mirandaVersion < PLUGIN_MAKE_VERSION( 0,8,0,0 ))
+ return NULL;
+
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if (szProto) {
+ PROTOACCOUNT* pa = ProtoGetAccount( szProto );
+ if ( pa )
+ return _tcsdup( pa->tszAccountName );
+ }
+ return NULL;
+
+ case CCNF_PROTOCOL:
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if (szProto == NULL)
+ return NULL;
+
+ if (CallProtoService(szProto, PS_GETNAME, (WPARAM)sizeof(protoname), (LPARAM)protoname))
+ return NULL;
+
+ if ( type & CNF_UNICODE )
+ return (TCHAR *)a2u(protoname);
+
+ return (TCHAR *)_strdup(protoname);
+
+ case CCNF_STATUS:
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if (szProto == NULL)
+ return NULL;
+
+ status = DBGetContactSettingWord(hContact, szProto, "Status", 0);
+ if (status == 0)
+ return NULL;
+
+ if (type & CNF_UNICODE) {
+ szStatus = (TCHAR *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)status, (LPARAM)GSMDF_UNICODE);
+ if (szStatus == NULL)
+ return NULL;
+
+ return _tcsdup(szStatus);
+ }
+ else {
+ char *aszStatus = (char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)status, 0);
+ if (aszStatus == NULL)
+ return NULL;
+
+ return (TCHAR *)_strdup(aszStatus);
+ }
+
+ case CCNF_INTERNALIP:
+ case CCNF_EXTERNALIP:
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if (szProto == NULL)
+ return NULL;
+ else {
+ DWORD ip = DBGetContactSettingDword(hContact, szProto, (realType==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;
+
+ if ( type & CNF_UNICODE )
+ return (TCHAR *)a2u(dotted);
+ return (TCHAR *)_strdup(dotted);
+ }
+
+ case CCNF_GROUP:
+ if (!DBGetContactSetting(hContact, "CList", "Group", &dbv)) {
+ if ( type & CNF_UNICODE )
+ res = (TCHAR *)a2u(dbv.pszVal);
+ else
+ res = (TCHAR *)_strdup(dbv.pszVal);
+
+ DBFreeVariant(&dbv);
+ return res;
+ }
+ if (!DBGetContactSettingW(hContact, "CList", "Group", &dbv)) {
+ if ( type & CNF_UNICODE )
+ res = (TCHAR *)_wcsdup(dbv.pwszVal);
+ else
+ res = (TCHAR *)u2a(dbv.pwszVal);
+
+ DBFreeVariant(&dbv);
+ return res;
+ }
+ break;
+
+ case CNF_UNIQUEID:
+ //UID for ChatRoom
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if ( szProto != NULL ){
+ if ( DBGetContactSettingByte(hContact, szProto, "ChatRoom", 0) == 1) {
+ DBVARIANT dbv;
+ if ( !DBGetContactSettingTString(hContact, szProto, "ChatRoomID", &dbv )) {
+ res = _tcsdup( 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;
+ if (CallService(MS_CONTACT_GETCONTACTINFO,(WPARAM)0,(LPARAM)&ci)) {
+ if ( !( type & CNF_UNICODE ))
+ return NULL;
+
+ // retrieving the data using UNICODE failed, try without
+ ci.dwFlag &= ~CNF_UNICODE;
+ if ( CallService( MS_CONTACT_GETCONTACTINFO,(WPARAM)0,(LPARAM)&ci ))
+ return NULL;
+
+ if (ci.type == CNFT_ASCIIZ) {
+ if (type & CNF_UNICODE) {
+ TCHAR *ptszVal;
+
+ ptszVal = (TCHAR *)a2u((char *)ci.pszVal);
+ mir_free(ci.pszVal);
+ return ptszVal;
+ }
+ else {
+ res = (TCHAR *)_strdup((char *)ci.pszVal);
+ mir_free(ci.pszVal);
+ return res;
+ } } }
+
+ memset(szVal, '\0', sizeof(szVal));
+ switch(ci.type){
+ case CNFT_BYTE:
+ if (realType != CNF_GENDER)
+ return itot(ci.bVal);
+
+ szVal[0] = (char)ci.bVal;
+ if ( type & CNF_UNICODE )
+ return (TCHAR *)a2u(szVal);
+ return (TCHAR *)_strdup(szVal);
+
+ case CNFT_WORD:
+ return itot(ci.wVal);
+
+ case CNFT_DWORD:
+ return itot(ci.dVal);
+
+ case CNFT_ASCIIZ:
+ if (ci.pszVal != NULL) {
+ if (type&CNF_UNICODE)
+ res = _tcsdup(ci.pszVal);
+ else
+ res = (TCHAR *)_strdup((char *)ci.pszVal);
+
+ mir_free(ci.pszVal);
+ }
+ break;
+ }
+
+ return res;
+}
+
+TCHAR *getContactInfoT(BYTE type, HANDLE hContact, int tchar)
+{
+ if (tchar) {
+ #ifdef UNICODE
+ return getContactInfo((BYTE)(type|CNF_UNICODE), hContact);
+ #else
+ return getContactInfo(type, hContact);
+ #endif
+ }
+
+ return getContactInfo(type, hContact);
+}
+
+/*
+ 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) {
+ #ifdef UNICODE
+ tszContact = NEWTSTR_ALLOCA(ci->tszContact);
+ #else
+ char* tmp = u2a(ci->wszContact);
+ tszContact = NEWTSTR_ALLOCA(tmp);
+ free( tmp );
+ #endif
+ }
+ else {
+ #ifdef UNICODE
+ WCHAR* tmp = a2u(ci->szContact);
+ tszContact = NEWTSTR_ALLOCA(tmp);
+ free(tmp);
+ #else
+ tszContact = NEWTSTR_ALLOCA(ci->szContact);
+ #endif
+ }
+ 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* )malloc(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, ci->flags&CI_TCHAR);
+ if (cInfo == NULL) {
+ // <HANDLE:hContact>
+ cInfo = itot((int)hContact);
+ szFind = ( TCHAR* )malloc((_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;
+ }
+ free(cInfo);
+ free(szFind);
+ }
+ }
+ else {
+ szFind = ( TCHAR* )malloc((_tcslen(cInfo) + strlen(szProto) + 4)*sizeof(TCHAR));
+ if (szFind != NULL) {
+#ifdef UNICODE
+ tszProto = a2u(szProto);
+#else
+ tszProto = _strdup(szProto);
+#endif
+ if ( (tszProto != NULL) && (szFind != NULL) ) {
+ wsprintf(szFind, _T("<%s:%s>"), tszProto, cInfo);
+ free(cInfo);
+ free(tszProto);
+ if (!_tcsncmp(tszContact, szFind, _tcslen(tszContact)))
+ bMatch = TRUE;
+
+ free(szFind);
+ }
+ }
+ }
+ }
+ // id (exact)
+ if ( (ci->flags&CI_UNIQUEID) && (!bMatch) ) {
+ szFind = getContactInfoT(CNF_UNIQUEID, hContact, ci->flags&CI_TCHAR);
+ if (szFind != NULL) {
+ if (!_tcscmp(tszContact, szFind))
+ bMatch = TRUE;
+
+ free(szFind);
+ }
+ }
+ // nick (not exact)
+ if ( (ci->flags&CI_NICK) && (!bMatch) ) {
+ szFind = getContactInfoT(CNF_NICK, hContact, ci->flags&CI_TCHAR);
+ if (szFind != NULL) {
+ if (!_tcscmp(tszContact, szFind))
+ bMatch = TRUE;
+
+ free(szFind);
+ }
+ }
+ // list name (not exact)
+ if ( (ci->flags&CI_LISTNAME) && (!bMatch) ) {
+ szFind = getContactInfoT(CNF_DISPLAY, hContact, ci->flags&CI_TCHAR);
+ if (szFind != NULL) {
+ if (!_tcscmp(tszContact, szFind))
+ bMatch = TRUE;
+
+ free(szFind);
+ }
+ }
+ // firstname (exact)
+ if ( (ci->flags&CI_FIRSTNAME) && (!bMatch) ) {
+ szFind = getContactInfoT(CNF_FIRSTNAME, hContact, ci->flags&CI_TCHAR);
+ if (szFind != NULL) {
+ if (!_tcscmp(tszContact, szFind)) {
+ bMatch = TRUE;
+ }
+ free(szFind);
+ }
+ }
+ // lastname (exact)
+ if ( (ci->flags&CI_LASTNAME) && (!bMatch) ) {
+ szFind = getContactInfoT(CNF_LASTNAME, hContact, ci->flags&CI_TCHAR);
+ if (szFind != NULL) {
+ if (!_tcscmp(tszContact, szFind)) {
+ bMatch = TRUE;
+ }
+ free(szFind);
+ }
+ }
+ // email (exact)
+ if ( (ci->flags&CI_EMAIL) && (!bMatch) ) {
+ szFind = getContactInfoT(CNF_EMAIL, hContact, ci->flags&CI_TCHAR);
+ if (szFind != NULL) {
+ if (!_tcscmp(tszContact, szFind)) {
+ bMatch = TRUE;
+ }
+ free(szFind);
+ }
+ }
+ // CNF_ (exact)
+ if ( (ci->flags&CI_CNFINFO) && (!bMatch) ) {
+ szFind = getContactInfoT((BYTE)(ci->flags&~(CI_CNFINFO|CI_TCHAR)), hContact, ci->flags&CI_TCHAR);
+ if (szFind != NULL) {
+ if (!_tcscmp(tszContact, szFind)) {
+ bMatch = TRUE;
+ }
+ free(szFind);
+ }
+ }
+ if (bMatch) {
+ ci->hContacts = ( HANDLE* )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* )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 = _tcsdup(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)uid != CALLSERVICE_NOTFOUND) && (uid != NULL) ) && (!strcmp(dbw->szSetting, uid)) && (cce[i].flags & CI_UNIQUEID)))
+ {
+ /* remove from cache */
+ free(cce[i].tszContact);
+ if (cacheSize > 1) {
+ MoveMemory(&cce[i], &cce[cacheSize-1], sizeof(CONTACTCE));
+ cce = ( CONTACTCE* )realloc(cce, (cacheSize-1)*sizeof(CONTACTCE));
+ cacheSize -= 1;
+ }
+ else {
+ 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, CI_TCHAR);
+ if ( szProto == NULL || tszUniqueId == NULL )
+ return NULL;
+
+ tszResult = ( TCHAR* )calloc((_tcslen(tszUniqueId) + strlen(szProto) + 4), sizeof(TCHAR));
+ if (tszResult == NULL)
+ return NULL;
+
+ #ifdef UNICODE
+ tszProto = a2u(szProto);
+ #else
+ tszProto = _strdup(szProto);
+ #endif
+ if (tszProto == NULL)
+ return NULL;
+
+ wsprintf(tszResult, _T("<%s:%s>"), tszProto, tszUniqueId);
+ 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)
+ free(ci.hContacts);
+
+ return ( HANDLE* )hContact;
+ }
+ if (ci.hContacts != NULL) {
+ hContact = ci.hContacts[0];
+ free(ci.hContacts);
+ }
+
+ return ( HANDLE* )hContact;
+}
diff --git a/plugins/Variables/contact.h b/plugins/Variables/contact.h
new file mode 100644
index 0000000000..ecb2e32525
--- /dev/null
+++ b/plugins/Variables/contact.h
@@ -0,0 +1,78 @@
+/*
+ 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
+*/
+
+#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/copying.txt b/plugins/Variables/copying.txt
new file mode 100644
index 0000000000..bd5cace35b
--- /dev/null
+++ b/plugins/Variables/copying.txt
@@ -0,0 +1 @@
+this is not meant to be distributed in any way. WIP. \ No newline at end of file
diff --git a/plugins/Variables/dbhelpers.h b/plugins/Variables/dbhelpers.h
new file mode 100644
index 0000000000..3eb3c7e330
--- /dev/null
+++ b/plugins/Variables/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/enumprocs.cpp b/plugins/Variables/enumprocs.cpp
new file mode 100644
index 0000000000..8f0de1aa8b
--- /dev/null
+++ b/plugins/Variables/enumprocs.cpp
@@ -0,0 +1,348 @@
+/*
+ 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
+*/
+// 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/enumprocs.h b/plugins/Variables/enumprocs.h
new file mode 100644
index 0000000000..7f7f085520
--- /dev/null
+++ b/plugins/Variables/enumprocs.h
@@ -0,0 +1,21 @@
+/*
+ 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
+*/
+/*** 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/help.cpp b/plugins/Variables/help.cpp
new file mode 100644
index 0000000000..7faa156ea6
--- /dev/null
+++ b/plugins/Variables/help.cpp
@@ -0,0 +1,1374 @@
+/*
+ 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
+*/
+#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: {
+ TCHAR *tszContact;
+ LPARAM res = 0;
+ HANDLE hContact, hItem;
+
+ hContact = (HANDLE)wParam;
+ log_debugA("VARM_SETSUBJECT: %u", hContact);
+ if (hContact == INVALID_HANDLE_VALUE) {
+ tszContact = db_gets(SETTING_SUBJECT, NULL);
+ log_debugA("VARM_SETSUBJECT: %s", tszContact);
+ if (tszContact != NULL) {
+ hContact = decodeContactFromString(tszContact);
+ log_debugA("VARM_SETSUBJECT decoded: %u", hContact);
+ 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_del(SETTING_SUBJECT);
+ {
+ HANDLE hContact = (HANDLE)SendMessage(hwndDlg, VARM_GETSUBJECT, 0, 0);
+ if (hContact != NULL) {
+ TCHAR *tszContact = encodeContactToString(hContact);
+ if (tszContact != NULL) {
+ db_sets(SETTING_SUBJECT, tszContact);
+ free(tszContact);
+ } } }
+ break;
+ }
+
+ return FALSE;
+}
+
+// dialog box for the tokens
+static TCHAR *getTokenCategory(TOKENREGISTEREX *tr) {
+
+#ifdef UNICODE
+ TCHAR *res;
+#endif
+ char *cat, *cur, *helpText;
+
+ if (tr == NULL) {
+ return NULL;
+ }
+ cat = NULL;
+ helpText = _strdup(tr->szHelpText);
+ if (helpText == NULL) {
+ return NULL;
+ }
+ cur = helpText;
+ while (*cur != _T('\0')) {
+ if (*cur == _T('\t')) {
+ *cur = _T('\0');
+ helpText = ( char* )realloc(helpText, strlen(helpText)+1);
+#ifdef UNICODE
+ res = a2u(helpText);
+ free(helpText);
+ return res;
+#else
+ return helpText;
+#endif
+ }
+ cur++;
+ }
+
+#ifdef UNICODE
+ res = a2u(helpText);
+ free(helpText);
+ return res;
+#else
+ return helpText;
+#endif
+}
+
+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')) {
+#ifdef UNICODE
+ cur = _strdup(cur+1);
+ TCHAR *res = a2u(cur);
+ free(cur);
+ return res;
+#else
+ return _strdup(cur+1);
+#endif
+ }
+ cur--;
+ }
+
+#ifdef UNICODE
+ return a2u(tr->szHelpText);
+#else
+ return _strdup(tr->szHelpText);
+#endif
+}
+
+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 _tcsdup(tr->tszTokenString);
+
+ helpText = _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* )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)
+#ifdef UNICODE
+ tArgs = a2u(args);
+#else
+ tArgs = _strdup(args);
+#endif
+ mir_sntprintf(desc, len, _T("%c%s%s"), _T(FUNC_CHAR), tr->tszTokenString, (tArgs!=NULL?tArgs:_T("")));
+ }
+ if (tArgs != NULL)
+ free(tArgs);
+
+ if (helpText != NULL)
+ 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);
+ free(cat1);
+ 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)
+ free(cat1);
+
+ if (cat2 != NULL)
+ 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) {
+#ifdef UNICODE
+ tszHelpDesc = a2u(hdd->vhs->szSubjectDesc);
+#else
+ tszHelpDesc = _strdup(hdd->vhs->szSubjectDesc);
+#endif
+ }
+ }
+ if (!_tcscmp(tr->tszTokenString, _T(EXTRATEXT))) {
+ if (hdd->vhs->flags&VHF_HIDEEXTRATEXTTOKEN) {
+ continue;
+ }
+ else if (hdd->vhs->szExtraTextDesc != NULL) {
+#ifdef UNICODE
+ tszHelpDesc = a2u(hdd->vhs->szExtraTextDesc);
+#else
+ tszHelpDesc = _strdup(hdd->vhs->szExtraTextDesc);
+#endif
+ }
+ }
+ }
+ 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);
+ free(tszTokenDesc);
+
+ lvItem.mask = LVIF_TEXT;
+ if (tszHelpDesc == NULL) {
+ tszHelpDesc = getHelpDescription(tr);
+ }
+ if (tszHelpDesc == NULL) {
+ tszHelpDesc = _tcsdup(_T("unknown"));
+ }
+ lvItem.iSubItem = 1;
+ lvItem.pszText = TranslateTS(tszHelpDesc);
+ ListView_SetItem(hList, &lvItem);
+ 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 = _tcsdup(TranslateTS(cat));
+ 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) {
+ free(last);
+ lvItem.iSubItem = 0;
+ lvItem.pszText = _T("");
+ ListView_InsertItem(hList, &lvItem);
+ }
+ last = text;
+ }
+ else {
+ free(text);
+ }
+ }
+ if (last != NULL) {
+ 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* )malloc((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);
+ 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* )malloc(sizeof(INPUTDLGDATA));
+ ZeroMemory(dat, sizeof(INPUTDLGDATA));
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat);
+ // splitter things
+ dat->splitterPos = (int)db_getd(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* )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);
+
+ free(newString);
+ if (oldString != NULL)
+ free(oldString);
+ }
+ 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_setd(SETTING_SPLITTERPOS, dat->splitterPos);
+ SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_SPLITTER), GWLP_WNDPROC, (LONG_PTR) OldSplitterProc);
+ if (dat != NULL) {
+ 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 BOOL 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* )malloc(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 {
+#ifdef UNICODE
+ WCHAR *wszFormatString = a2u(dat->vhs->fi->szFormat);
+ SendMessage(hwndDlg, VARM_SETINPUTTEXT, 0, (LPARAM)wszFormatString);
+ free(wszFormatString);
+#else
+ SendMessageA(hwndDlg, VARM_SETINPUTTEXT, 0, (LPARAM)dat->vhs->fi->szFormat);
+#endif
+ }
+ }
+ else if (dat->vhs->hwndCtrl != NULL) {
+ TCHAR *tszText;
+
+ tszText = Hlp_GetWindowText(dat->vhs->hwndCtrl);
+ if ( tszText != NULL ) {
+ SendMessage(hwndDlg, VARM_SETINPUTTEXT, 0, (LPARAM)tszText);
+ 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 {
+#ifdef UNICODE
+ WCHAR *wszSource = a2u(dat->vhs->fi->szExtraText);
+ SendMessage(hwndDlg, VARM_SETEXTRATEXT, 0, (LPARAM)wszSource);
+ free(wszSource);
+#else
+ SendMessageA(hwndDlg, VARM_SETEXTRATEXT, 0, (LPARAM)dat->vhs->fi->szExtraText);
+#endif
+ }
+ }
+ 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) {
+#ifdef UNICODE
+ if ((dat->vhs->fi != NULL) && (!(dat->vhs->flags&VHF_DONTFILLSTRUCT))) {
+ if (dat->vhs->fi->flags&FIF_UNICODE) {
+ dat->vhs->fi->tszFormat = ( TCHAR* )calloc((len+1), sizeof(WCHAR));
+ SendMessage(hwndDlg, VARM_GETINPUTTEXT, (WPARAM)len+1, (LPARAM)dat->vhs->fi->tszFormat);
+ }
+ else {
+ dat->vhs->fi->szFormat = ( char* )calloc(len+1, 1);
+ SendMessageA(hwndDlg, VARM_GETINPUTTEXT, (WPARAM)len+1, (LPARAM)dat->vhs->fi->szFormat);
+ }
+ }
+#else
+ dat->vhs->fi->szFormat = (char*)calloc(len+1, 1);
+ SendMessageA(hwndDlg, VARM_GETINPUTTEXT, (WPARAM)len+1, (LPARAM)dat->vhs->fi->szFormat);
+#endif
+ }
+ }
+
+ if (dat->vhs->hwndCtrl != NULL) {
+ int len;
+
+ len = SendMessage(hwndDlg, VARM_GETINPUTTEXTLENGTH, 0, 0);
+ if (len > 0) {
+ TCHAR *tszText;
+
+ tszText = ( TCHAR* )calloc((len+1), sizeof(TCHAR));
+ if (tszText != NULL) {
+ SendMessage(hwndDlg, VARM_GETINPUTTEXT, (WPARAM)len+1, (LPARAM)tszText);
+ SetWindowText(dat->vhs->hwndCtrl, tszText);
+ 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;
+
+ len = SendMessage(hwndDlg, VARM_GETEXTRATEXTLENGTH, 0, 0);
+ if (len > 0) {
+#ifdef UNICODE
+ if (dat->vhs->fi->flags&FIF_UNICODE) {
+ dat->vhs->fi->tszExtraText = ( TCHAR* )calloc((len+1), sizeof(WCHAR));
+ SendMessage(hwndDlg, VARM_GETEXTRATEXT, (WPARAM)len+1, (LPARAM)dat->vhs->fi->tszExtraText);
+ }
+ else {
+ dat->vhs->fi->szExtraText = ( char* )calloc(len+1, 1);
+ SendMessageA(hwndDlg, VARM_GETEXTRATEXT, (WPARAM)len+1, (LPARAM)dat->vhs->fi->szExtraText);
+ }
+#else
+ dat->vhs->fi->szExtraText = (char*)calloc(len+1, 1);
+ SendMessageA(hwndDlg, VARM_GETEXTRATEXT, (WPARAM)len+1, (LPARAM)dat->vhs->fi->szExtraText);
+#endif
+ }
+ 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);
+
+ 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 = 4 * GetSystemMetrics(SM_CYSIZEFRAME);
+
+ if (wParam)
+ DialogBoxParam((HINSTANCE)hInst, (LPCTSTR)MAKEINTRESOURCE(IDD_HELP_DIALOG), (HWND)wParam, (DLGPROC)helpDlgProc, (LPARAM)lParam);
+ else
+ CreateDialogParam((HINSTANCE)hInst, (LPCTSTR)MAKEINTRESOURCE(IDD_HELP_DIALOG), (HWND)NULL, (DLGPROC)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* )malloc(sizeof(FORMATINFO));
+
+ ZeroMemory(fi, sizeof(FORMATINFO));
+ fi->cbSize = sizeof(FORMATINFO);
+ fi->szFormat = (char *)lParam;
+ if (vhs == NULL)
+ vhs = ( VARHELPINFO* )malloc(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)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)hHelpIcon;
+
+ case VSI_HELPTIPTEXT:
+ return (int)Translate("Open String Formatting Help");
+ }
+
+ return (int)NULL;
+}
+
+int iconsChanged(WPARAM wParam, LPARAM lParam)
+{
+ hHelpIcon = NULL;
+ return 0;
+}
diff --git a/plugins/Variables/libxml/DOCBparser.h b/plugins/Variables/libxml/DOCBparser.h
new file mode 100644
index 0000000000..4b7230f17d
--- /dev/null
+++ b/plugins/Variables/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/libxml/HTMLparser.h b/plugins/Variables/libxml/HTMLparser.h
new file mode 100644
index 0000000000..c6d8899c30
--- /dev/null
+++ b/plugins/Variables/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/libxml/HTMLtree.h b/plugins/Variables/libxml/HTMLtree.h
new file mode 100644
index 0000000000..3a441c4b5c
--- /dev/null
+++ b/plugins/Variables/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/libxml/SAX.h b/plugins/Variables/libxml/SAX.h
new file mode 100644
index 0000000000..d96d9e9596
--- /dev/null
+++ b/plugins/Variables/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/libxml/c14n.h b/plugins/Variables/libxml/c14n.h
new file mode 100644
index 0000000000..75ace8a4a4
--- /dev/null
+++ b/plugins/Variables/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/libxml/catalog.h b/plugins/Variables/libxml/catalog.h
new file mode 100644
index 0000000000..037e7e80e0
--- /dev/null
+++ b/plugins/Variables/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/libxml/debugXML.h b/plugins/Variables/libxml/debugXML.h
new file mode 100644
index 0000000000..cf017a4a73
--- /dev/null
+++ b/plugins/Variables/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/libxml/encoding.h b/plugins/Variables/libxml/encoding.h
new file mode 100644
index 0000000000..3c0fbb91ff
--- /dev/null
+++ b/plugins/Variables/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/libxml/entities.h b/plugins/Variables/libxml/entities.h
new file mode 100644
index 0000000000..ea7f2020c2
--- /dev/null
+++ b/plugins/Variables/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/libxml/globals.h b/plugins/Variables/libxml/globals.h
new file mode 100644
index 0000000000..6f880c0877
--- /dev/null
+++ b/plugins/Variables/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/libxml/hash.h b/plugins/Variables/libxml/hash.h
new file mode 100644
index 0000000000..ec590c91fe
--- /dev/null
+++ b/plugins/Variables/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/libxml/list.h b/plugins/Variables/libxml/list.h
new file mode 100644
index 0000000000..8c9515fe1d
--- /dev/null
+++ b/plugins/Variables/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/libxml/nanoftp.h b/plugins/Variables/libxml/nanoftp.h
new file mode 100644
index 0000000000..a0ba2ceeb3
--- /dev/null
+++ b/plugins/Variables/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/libxml/nanohttp.h b/plugins/Variables/libxml/nanohttp.h
new file mode 100644
index 0000000000..4fb4e1d256
--- /dev/null
+++ b/plugins/Variables/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/libxml/parser.h b/plugins/Variables/libxml/parser.h
new file mode 100644
index 0000000000..e6725a364d
--- /dev/null
+++ b/plugins/Variables/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/libxml/parserInternals.h b/plugins/Variables/libxml/parserInternals.h
new file mode 100644
index 0000000000..8507442be8
--- /dev/null
+++ b/plugins/Variables/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/libxml/schemasInternals.h b/plugins/Variables/libxml/schemasInternals.h
new file mode 100644
index 0000000000..fb1f7eeb39
--- /dev/null
+++ b/plugins/Variables/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/libxml/threads.h b/plugins/Variables/libxml/threads.h
new file mode 100644
index 0000000000..afca78ffe5
--- /dev/null
+++ b/plugins/Variables/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/libxml/tree.h b/plugins/Variables/libxml/tree.h
new file mode 100644
index 0000000000..8521a31997
--- /dev/null
+++ b/plugins/Variables/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/libxml/uri.h b/plugins/Variables/libxml/uri.h
new file mode 100644
index 0000000000..319c509d1b
--- /dev/null
+++ b/plugins/Variables/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/libxml/valid.h b/plugins/Variables/libxml/valid.h
new file mode 100644
index 0000000000..36373e17f0
--- /dev/null
+++ b/plugins/Variables/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/libxml/xinclude.h b/plugins/Variables/libxml/xinclude.h
new file mode 100644
index 0000000000..9c83ba0e5c
--- /dev/null
+++ b/plugins/Variables/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/libxml/xlink.h b/plugins/Variables/libxml/xlink.h
new file mode 100644
index 0000000000..c7f48c8539
--- /dev/null
+++ b/plugins/Variables/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/libxml/xmlIO.h b/plugins/Variables/libxml/xmlIO.h
new file mode 100644
index 0000000000..16cc8e507a
--- /dev/null
+++ b/plugins/Variables/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/libxml/xmlautomata.h b/plugins/Variables/libxml/xmlautomata.h
new file mode 100644
index 0000000000..96ba2245b3
--- /dev/null
+++ b/plugins/Variables/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/libxml/xmlerror.h b/plugins/Variables/libxml/xmlerror.h
new file mode 100644
index 0000000000..33e2275910
--- /dev/null
+++ b/plugins/Variables/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/libxml/xmlmemory.h b/plugins/Variables/libxml/xmlmemory.h
new file mode 100644
index 0000000000..8e8df944c1
--- /dev/null
+++ b/plugins/Variables/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/libxml/xmlregexp.h b/plugins/Variables/libxml/xmlregexp.h
new file mode 100644
index 0000000000..434b7a2bd9
--- /dev/null
+++ b/plugins/Variables/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/libxml/xmlschemas.h b/plugins/Variables/libxml/xmlschemas.h
new file mode 100644
index 0000000000..14b9230832
--- /dev/null
+++ b/plugins/Variables/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/libxml/xmlschemastypes.h b/plugins/Variables/libxml/xmlschemastypes.h
new file mode 100644
index 0000000000..a758c128e5
--- /dev/null
+++ b/plugins/Variables/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/libxml/xmlunicode.h b/plugins/Variables/libxml/xmlunicode.h
new file mode 100644
index 0000000000..f0f1fe9ce9
--- /dev/null
+++ b/plugins/Variables/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/libxml/xmlversion.h b/plugins/Variables/libxml/xmlversion.h
new file mode 100644
index 0000000000..1342eba969
--- /dev/null
+++ b/plugins/Variables/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/libxml/xpath.h b/plugins/Variables/libxml/xpath.h
new file mode 100644
index 0000000000..f36b16f938
--- /dev/null
+++ b/plugins/Variables/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/libxml/xpathInternals.h b/plugins/Variables/libxml/xpathInternals.h
new file mode 100644
index 0000000000..59a4e35d53
--- /dev/null
+++ b/plugins/Variables/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/libxml/xpointer.h b/plugins/Variables/libxml/xpointer.h
new file mode 100644
index 0000000000..80c465c70f
--- /dev/null
+++ b/plugins/Variables/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/libxslt/numbersInternals.h b/plugins/Variables/libxslt/numbersInternals.h
new file mode 100644
index 0000000000..e4938f335a
--- /dev/null
+++ b/plugins/Variables/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/libxslt/transform.h b/plugins/Variables/libxslt/transform.h
new file mode 100644
index 0000000000..9efb79c437
--- /dev/null
+++ b/plugins/Variables/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/libxslt/win32config.h b/plugins/Variables/libxslt/win32config.h
new file mode 100644
index 0000000000..c035aeb90e
--- /dev/null
+++ b/plugins/Variables/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/libxslt/xslt.h b/plugins/Variables/libxslt/xslt.h
new file mode 100644
index 0000000000..d201fccda4
--- /dev/null
+++ b/plugins/Variables/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/libxslt/xsltInternals.h b/plugins/Variables/libxslt/xsltInternals.h
new file mode 100644
index 0000000000..d574e5997b
--- /dev/null
+++ b/plugins/Variables/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/libxslt/xsltexports.h b/plugins/Variables/libxslt/xsltexports.h
new file mode 100644
index 0000000000..aab58025b8
--- /dev/null
+++ b/plugins/Variables/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/libxslt/xsltutils.h b/plugins/Variables/libxslt/xsltutils.h
new file mode 100644
index 0000000000..180ae04561
--- /dev/null
+++ b/plugins/Variables/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/libxslt/xsltwin32config.h b/plugins/Variables/libxslt/xsltwin32config.h
new file mode 100644
index 0000000000..985bfc71dc
--- /dev/null
+++ b/plugins/Variables/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/lookup3.cpp b/plugins/Variables/lookup3.cpp
new file mode 100644
index 0000000000..b2a91634cf
--- /dev/null
+++ b/plugins/Variables/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 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 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/main.cpp b/plugins/Variables/main.cpp
new file mode 100644
index 0000000000..f2718b8b03
--- /dev/null
+++ b/plugins/Variables/main.cpp
@@ -0,0 +1,159 @@
+ /*
+ 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
+*/
+#include "variables.h"
+#include "buildnumber.h"
+
+HINSTANCE hInst;
+struct MM_INTERFACE mmi;
+struct LIST_INTERFACE li;
+PLUGINLINK *pluginLink;
+DWORD g_mirandaVersion;
+int hLangpack = 0;
+
+#ifdef UNICODE
+ // {59B0036E-5403-422e-883B-C9AAF425682B}
+ #define MIID_VARIABLES { 0x59b0036e, 0x5403, 0x422e, { 0x88, 0x3b, 0xc9, 0xaa, 0xf4, 0x25, 0x68, 0x2b } }
+#else
+ // {352A6BA9-5636-4db0-B92F-7A3289F57902}
+ #define MIID_VARIABLES { 0x352a6ba9, 0x5636, 0x4db0, { 0xb9, 0x2f, 0x7a, 0x32, 0x89, 0xf5, 0x79, 0x2 } }
+#endif
+
+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;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// MirandaPluginInfo - returns an information about a plugin
+
+PLUGININFO pluginInfo = {
+ sizeof(PLUGININFO),
+#ifdef _WIN64
+ "Variables (x64, Unicode)",
+#else
+#ifdef UNICODE
+ "Variables (Unicode)",
+#else
+ "Variables",
+#endif
+#endif
+ __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://www.miranda-im.org/",
+ UNICODE_AWARE,
+ 0
+};
+
+extern "C" __declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion)
+{
+ g_mirandaVersion = mirandaVersion;
+ return &pluginInfo;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// MirandaPluginInfoEx - returns the extended information about a plugin
+
+PLUGININFOEX pluginInfoEx = {
+ sizeof(PLUGININFOEX),
+#ifdef _WIN64
+ "Variables (x64, Unicode)",
+#else
+#ifdef UNICODE
+ "Variables (Unicode)",
+#else
+ "Variables",
+#endif
+#endif
+ __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://www.miranda-im.org/",
+ UNICODE_AWARE,
+ 0,
+ MIID_VARIABLES
+};
+
+extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ g_mirandaVersion = mirandaVersion;
+ return &pluginInfoEx;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// MirandaPluginInterfaces - returns the protocol interface to the core
+
+static const MUUID interfaces[] = { MIID_VARIABLES, MIID_LAST };
+extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces( void )
+{
+ return interfaces;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Load - plugin's entry point
+
+extern "C" int __declspec(dllexport) Load(PLUGINLINK *link)
+{
+ pluginLink = link;
+ if (UnicodeCheck(pluginInfo.shortName, FALSE))
+ return 0;
+
+ mir_getMMI( &mmi );
+ mir_getLI( &li );
+ 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/options.cpp b/plugins/Variables/options.cpp
new file mode 100644
index 0000000000..03956ddea9
--- /dev/null
+++ b/plugins/Variables/options.cpp
@@ -0,0 +1,147 @@
+/*
+ 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
+*/
+#include "variables.h"
+
+extern HINSTANCE hInst;
+extern struct ParseOptions gParseOpts;
+
+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_getb(SETTING_PARSEATSTARTUP, 0));
+ CheckDlgButton(hwndDlg, IDC_STRIPCRLF, db_getb(SETTING_STRIPCRLF, 0));
+ CheckDlgButton(hwndDlg, IDC_STRIPWS, db_getb(SETTING_STRIPWS, 0));
+ CheckDlgButton(hwndDlg, IDC_STRIPALL, db_getb(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* )calloc((len+1), sizeof(TCHAR));
+ if (szFormatText == NULL)
+ break;
+
+ if (GetDlgItemText(hwndDlg, IDC_FORMATTEXT, szFormatText, len+1) != 0)
+ db_sets(SETTING_STARTUPTEXT, szFormatText);
+
+ free(szFormatText);
+ }
+ db_setb(SETTING_PARSEATSTARTUP, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_PARSEATSTARTUP)?1:0));
+ db_setb(SETTING_STRIPCRLF, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_STRIPCRLF)?1:0));
+ db_setb(SETTING_STRIPWS, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_STRIPWS)?1:0));
+ db_setb(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);
+ free(newString);
+ }
+ 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;
+ CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
+
+ return 0;
+}
diff --git a/plugins/Variables/pack.cmd b/plugins/Variables/pack.cmd
new file mode 100644
index 0000000000..9e7ddb4e71
--- /dev/null
+++ b/plugins/Variables/pack.cmd
@@ -0,0 +1,35 @@
+@echo off
+nmake -f Variables.mak CFG="Variables - Win32 Release"
+if errorlevel 1 (
+ echo "Make failed"
+ goto :eof )
+nmake -f Variables.mak CFG="Variables - Win32 Release Unicode"
+if errorlevel 1 (
+ echo "Make failed"
+ goto :eof )
+
+del "%temp%\Variables.zip" > nul
+del "%temp%\VariablesW.zip" > nul
+del "%temp%\VariablesSrc.zip" > nul
+del *.user > nul
+
+rd /S /Q Release
+rd /S /Q Release_Unicode
+
+for /F "tokens=1-6 delims=, " %%i in (buildnumber.h) do call :Translate %%i %%j %%k %%l %%m %%n
+
+"%PROGRAMFILES%\7-zip\7z.exe" a -tzip -r- -mx=9 "%temp%\Variables.zip" ../../bin/Release/Plugins/Variables.dll variables-translation.txt m_variables.h
+del ../../bin/Release/Plugins/Variables.dll >nul
+
+"%PROGRAMFILES%\7-zip\7z.exe" a -tzip -r- -mx=9 "%temp%\VariablesW.zip" "../../bin/Release Unicode/Plugins/Variables.dll" variables-translation.txt m_variables.h
+del "../../bin/Release Unicode/Plugins/Variables.dll" >nul
+
+cd ..
+"%PROGRAMFILES%\7-zip\7z.exe" a -tzip -r0 -mx=9 "%temp%\VariablesSrc.zip" -ir!helpers/*.* -ir!Variables/*.* -ir!NewTriggerPlugin/*.* -xr!.svn -x!*.cmd
+goto :eof
+
+:Translate
+if %2 == __FILEVERSION_STRING (
+ perl lpgen.pl variables version %3 %4 %5 %6 )
+
+goto :eof
diff --git a/plugins/Variables/parse_alias.cpp b/plugins/Variables/parse_alias.cpp
new file mode 100644
index 0000000000..49d7df3310
--- /dev/null
+++ b/plugins/Variables/parse_alias.cpp
@@ -0,0 +1,226 @@
+/*
+ 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
+*/
+#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* )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 = _tcsdup(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)) {
+ free(ar[i].szTranslation);
+ ar[i].szTranslation = _tcsdup(szTranslation);
+ for (j=0;j<ar[i].argc;j++) {
+ if (ar[i].argv[j] != NULL) {
+ free(ar[i].argv[j]);
+ }
+ }
+ ar[i].argc = argc;
+ ar[i].argv = ( TCHAR** )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] = _tcsdup(argv[j]);
+ else
+ ar[i].argv[j] = NULL;
+ }
+ LeaveCriticalSection(&csAliasRegister);
+ return 0;
+ }
+ }
+ ar = ( ALIASREGISTER* )realloc(ar, (arCount+1)*sizeof(ALIASREGISTER));
+ if (ar == NULL) {
+ LeaveCriticalSection(&csAliasRegister);
+ return -1;
+ }
+ ar[arCount].szAlias = _tcsdup(szAlias);
+ ar[arCount].szTranslation = _tcsdup(szTranslation);
+ ar[arCount].argc = argc;
+ ar[arCount].argv = ( TCHAR** )malloc(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] = _tcsdup(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* )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* )calloc( _tcslen(argv[i])+2, sizeof(TCHAR));
+ else
+ szArgs = ( TCHAR* )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) ) {
+#ifdef UNICODE
+ szArgsA = u2a(szArgs);
+#else
+ szArgsA = _strdup(szArgs);
+#endif
+ szHelp = ( char* )malloc(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);
+ free(szArgsA);
+ }
+ else {
+ szHelp = ( char* )malloc(32);
+ memset(szHelp, '\0', 32);
+ sprintf(szHelp, "Alias\t\tuser defined");
+ res = registerIntToken(alias, parseTranslateAlias, TRF_FIELD|TRF_UNPARSEDARGS, szHelp);
+ }
+ free(szArgs);
+ free(szHelp);
+
+ return res==0?_tcsdup(_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/parse_alias.h b/plugins/Variables/parse_alias.h
new file mode 100644
index 0000000000..3914988780
--- /dev/null
+++ b/plugins/Variables/parse_alias.h
@@ -0,0 +1,29 @@
+/*
+ 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
+*/
+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/parse_external.cpp b/plugins/Variables/parse_external.cpp
new file mode 100644
index 0000000000..76170971e7
--- /dev/null
+++ b/plugins/Variables/parse_external.cpp
@@ -0,0 +1,266 @@
+/*
+ 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
+*/
+#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* )malloc((GetWindowTextLength(hwndWinamp) + 1)*sizeof(TCHAR));
+ if (szWinText == NULL)
+ return NULL;
+
+ if (GetWindowText(hwndWinamp, szWinText, GetWindowTextLength(hwndWinamp)+1) == 0) {
+ free(szWinText);
+ return NULL;
+ }
+ szTitle = ( TCHAR* )malloc((2*_tcslen(szWinText)+1)*sizeof(TCHAR));
+ if (szTitle == NULL) {
+ free(szWinText);
+ return NULL;
+ }
+ _tcscpy(szTitle, szWinText);
+ _tcscpy(szTitle+_tcslen(szTitle), szWinText);
+ 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))) ) {
+ free(szTitle);
+ return NULL;
+ }
+ scur++;
+ scur++;
+ *cur = '\0';
+ res = _tcsdup(scur);
+ 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) ) {
+ free(szTitle);
+ return _tcsdup(TranslateT("Stopped"));
+ }
+ if ( (!_tcsncmp(cur+10, _T("[Stopped]"), 9)) ) {
+ free(szTitle);
+ return _tcsdup(TranslateT("Stopped"));
+ }
+ if ( (!_tcsncmp(cur+10, _T("[Paused]"), 8)) ) {
+ free(szTitle);
+ return _tcsdup(TranslateT("Paused"));
+ }
+ free(szTitle);
+ return _tcsdup(_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;
+ }
+#ifdef UNICODE
+ cmd = u2a(ai->targv[1]);
+#else
+ cmd = _strdup(ai->targv[1]);
+#endif
+ if (checkAMIP() != 0) {
+ log_debugA("checkAMIP failed");
+
+ return NULL;
+ }
+ ZeroMemory(&szRes, sizeof(szRes));
+ if (AC_ERR_NOERROR == acEval(cmd, szRes)) {
+#ifdef UNICODE
+ tszRes = a2u(szRes);
+#else
+ tszRes = _strdup(szRes);
+#endif
+ }
+ else {
+ lastAMIPFailure = GetTickCount();
+ }
+ 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;
+ }
+#ifdef UNICODE
+ cmd = u2a(ai->targv[1]);
+#else
+ cmd = _strdup(ai->targv[1]);
+#endif
+ if (checkAMIP() != 0) {
+
+ return NULL;
+ }
+ if (AC_ERR_NOERROR == acFormat(cmd, szRes)) {
+#ifdef UNICODE
+ tszRes = a2u(szRes);
+#else
+ tszRes = _strdup(szRes);
+#endif
+ }
+ else {
+ lastAMIPFailure = GetTickCount();
+ }
+ 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/parse_external.h b/plugins/Variables/parse_external.h
new file mode 100644
index 0000000000..ac31e429fa
--- /dev/null
+++ b/plugins/Variables/parse_external.h
@@ -0,0 +1,25 @@
+/*
+ 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
+*/
+#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/parse_inet.cpp b/plugins/Variables/parse_inet.cpp
new file mode 100644
index 0000000000..cf8f24524f
--- /dev/null
+++ b/plugins/Variables/parse_inet.cpp
@@ -0,0 +1,155 @@
+/*
+ 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
+*/
+#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;
+ }
+#ifdef UNICODE
+ res = u2a(ai->targv[1]);
+#else
+ res = _strdup(ai->argv[1]);
+#endif
+ 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* )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);
+ }
+#ifdef UNICODE
+ tres = a2u(res);
+#else
+ tres = _strdup(res);
+#endif
+ free(res);
+
+ return tres;
+}
+
+static TCHAR *parseUrlDec(ARGUMENTSINFO *ai) {
+
+ char *res, hex[8];
+ TCHAR *tres;
+ unsigned int cur;
+
+ if (ai->argc != 2) {
+ return NULL;
+ }
+#ifdef UNICODE
+ res = u2a(ai->targv[1]);
+#else
+ res = _strdup(ai->argv[1]);
+#endif
+ 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* )realloc(res, strlen(res)+1);
+#ifdef UNICODE
+ tres = a2u(res);
+#else
+ tres = _strdup(res);
+#endif
+ 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) {
+#ifdef UNICODE
+ return a2u(res);
+#else
+ return _strdup(res);
+#endif
+ }
+
+ 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) {
+#ifdef UNICODE
+ return a2u(res);
+#else
+ return _strdup(res);
+#endif
+ }
+
+ 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/parse_inet.h b/plugins/Variables/parse_inet.h
new file mode 100644
index 0000000000..d9e3f23c70
--- /dev/null
+++ b/plugins/Variables/parse_inet.h
@@ -0,0 +1,22 @@
+/*
+ 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
+*/
+#define URLENC "urlenc"
+#define URLDEC "urldec"
+#define NTOA "ntoa"
+#define HTOA "htoa"
diff --git a/plugins/Variables/parse_logic.cpp b/plugins/Variables/parse_logic.cpp
new file mode 100644
index 0000000000..36a5f664e3
--- /dev/null
+++ b/plugins/Variables/parse_logic.cpp
@@ -0,0 +1,414 @@
+/*
+ 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
+*/
+#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);
+ free(szCondition);
+ //if (fi.pCount <= 0) {
+ if (fi.eCount > 0) {
+ ai->flags |= AIF_FALSE;
+ return _tcsdup(_T(""));
+ }
+ }
+
+ return _tcsdup(_T(""));
+}
+
+static TCHAR *parseFalse(ARGUMENTSINFO *ai) {
+
+ if (ai->argc != 1) {
+ return NULL;
+ }
+ ai->flags |= AIF_FALSE;
+
+ return _tcsdup(_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);
+ free(szCondition);
+ //if (fi.pCount > 0) {
+ if (fi.eCount == 0) {
+ return _tcsdup(ai->targv[2]);
+ }
+ else {
+ return _tcsdup(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;
+ free(szCondition);
+ }
+ return _tcsdup(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) {
+ 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)
+ free(tszFirst);
+
+ if (tszSecond != NULL)
+ free(tszSecond);
+
+ return NULL;
+ }
+ if ( (ttoi(tszFirst)) == (ttoi(tszSecond)) ) {
+ free(tszFirst);
+ free(tszSecond);
+ return _tcsdup(ai->targv[3]);
+ }
+ free(tszFirst);
+ free(tszSecond);
+
+ return _tcsdup(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) {
+ free(tszFirst);
+ }
+ if (tszSecond != NULL) {
+ free(tszSecond);
+ }
+ return NULL;
+ }
+ if ( (ttoi(tszFirst)) > (ttoi(tszSecond)) ) {
+ free(tszFirst);
+ free(tszSecond);
+ return _tcsdup(ai->targv[3]);
+ }
+ free(tszFirst);
+ free(tszSecond);
+
+ return _tcsdup(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) {
+ free(tszFirst);
+ }
+ if (tszSecond != NULL) {
+ free(tszSecond);
+ }
+ return NULL;
+ }
+ if ( _tcslen(tszFirst) > _tcslen(tszSecond) ) {
+ free(tszFirst);
+ free(tszSecond);
+ return _tcsdup(ai->targv[3]);
+ }
+ free(tszFirst);
+ free(tszSecond);
+
+ return _tcsdup(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 = _tcsdup(_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];
+ free(formatString(&fi));
+ fi.tszFormat = ai->targv[2];
+ free(formatString(&fi));
+ while (fi.eCount == 0) {
+ fi.tszFormat = ai->targv[4];
+ parsed = formatString(&fi);
+ if (parsed != NULL) {
+ if (res == NULL) {
+ res = ( TCHAR* )calloc( _tcslen(parsed)+1, sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+ }
+ else res = ( TCHAR* )realloc(res, (_tcslen(res)+_tcslen(parsed)+1)*sizeof(TCHAR));
+
+ _tcscat(res, parsed);
+ }
+ fi.tszFormat = ai->targv[3];
+ free(formatString(&fi));
+ fi.eCount = 0;
+ fi.tszFormat = ai->targv[2];
+ 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 _tcsdup(_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 _tcsdup(_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 _tcsdup(_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);
+ free(szCondition);
+ //if (fi.pCount > 0) {
+ if (fi.eCount == 0) {
+ ai->flags |= AIF_FALSE;
+ }
+
+ return _tcsdup(_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);
+ free(szCondition);
+ //if (fi.pCount > 0) {
+ if (fi.eCount == 0) {
+ ai->flags &= ~AIF_FALSE;
+ }
+ }
+
+ return _tcsdup(_T(""));
+}
+
+static TCHAR *parseTrue(ARGUMENTSINFO *ai) {
+
+ if (ai->argc != 1) {
+ return NULL;
+ }
+
+ return _tcsdup(_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);
+ free(szCondition);
+ //val1 = fi.pCount > 0;
+ val1 = fi.eCount == 0;
+ fi.tszFormat = ai->targv[1];
+ szCondition = formatString(&fi);
+ free(szCondition);
+ //val2 = fi.pCount > 0;
+ val2 = fi.eCount == 0;
+ ai->flags |= ((val1&AIF_FALSE)==!(val2&AIF_FALSE))?0:AIF_FALSE;
+
+ return _tcsdup(_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/parse_logic.h b/plugins/Variables/parse_logic.h
new file mode 100644
index 0000000000..ae20cfd77f
--- /dev/null
+++ b/plugins/Variables/parse_logic.h
@@ -0,0 +1,34 @@
+/*
+ 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
+*/
+#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/parse_math.cpp b/plugins/Variables/parse_math.cpp
new file mode 100644
index 0000000000..1d4cb3c30a
--- /dev/null
+++ b/plugins/Variables/parse_math.cpp
@@ -0,0 +1,225 @@
+/*
+ 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
+*/
+#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* )malloc((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* )malloc((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);
+ 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/parse_math.h b/plugins/Variables/parse_math.h
new file mode 100644
index 0000000000..29ce847cba
--- /dev/null
+++ b/plugins/Variables/parse_math.h
@@ -0,0 +1,29 @@
+/*
+ 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
+*/
+#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/parse_metacontacts.cpp b/plugins/Variables/parse_metacontacts.cpp
new file mode 100644
index 0000000000..5940569bad
--- /dev/null
+++ b/plugins/Variables/parse_metacontacts.cpp
@@ -0,0 +1,218 @@
+/*
+ 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
+*/
+
+#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];
+ free(ci.hContacts);
+ }
+ else {
+ if (ci.hContacts != NULL)
+ 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, 1);
+
+ if ( szUniqueID == NULL ) {
+ szProto = PROTOID_HANDLE;
+ szUniqueID = itot((int)hContact);
+ if ( szProto == NULL || szUniqueID == NULL )
+ return NULL;
+ }
+
+ res = ( TCHAR* )malloc((strlen(szProto) + _tcslen(szUniqueID) + 4)*sizeof(TCHAR));
+ if (res == NULL) {
+ free(szUniqueID);
+ return NULL;
+ }
+
+ TCHAR* tszProto;
+ #ifdef UNICODE
+ tszProto = a2u(szProto);
+ #else
+ tszProto = _strdup(szProto);
+ #endif
+
+ if ( tszProto != NULL && szUniqueID != NULL ) {
+ wsprintf(res, _T("<%s:%s>"), tszProto, szUniqueID);
+ free(szUniqueID);
+ 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];
+ free(ci.hContacts);
+ }
+ else {
+ if (ci.hContacts != NULL)
+ 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, 1);
+
+ if (szUniqueID == NULL) {
+ szProto = PROTOID_HANDLE;
+ szUniqueID = itot((int)hContact);
+ if ( szProto == NULL || szUniqueID == NULL )
+ return NULL;
+ }
+
+ res = ( TCHAR* )malloc((strlen(szProto) + _tcslen(szUniqueID) + 4)*sizeof(TCHAR));
+ if (res == NULL) {
+ free(szUniqueID);
+ return NULL;
+ }
+
+ TCHAR* tszProto;
+ #ifdef UNICODE
+ tszProto = a2u(szProto);
+ #else
+ tszProto = _strdup(szProto);
+ #endif
+
+ if ( tszProto != NULL && szUniqueID != NULL ) {
+ wsprintf(res, _T("<%s:%s>"), tszProto, szUniqueID);
+ free(szUniqueID);
+ 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];
+ free( ci.hContacts );
+ }
+ else {
+ if ( ci.hContacts != NULL )
+ 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, 1);
+
+ if (szUniqueID == NULL) {
+ szProto = PROTOID_HANDLE;
+ szUniqueID = itot((int)hContact);
+ if ( szProto == NULL || szUniqueID == NULL )
+ return NULL;
+ }
+
+ res = ( TCHAR* )malloc((strlen(szProto) + _tcslen(szUniqueID) + 4)*sizeof(TCHAR));
+ if (res == NULL) {
+ free(szUniqueID);
+ return NULL;
+ }
+
+ TCHAR* tszProto;
+ #ifdef UNICODE
+ tszProto = a2u(szProto);
+ #else
+ tszProto = _strdup(szProto);
+ #endif
+
+ if ( tszProto != NULL && szUniqueID != NULL ) {
+ wsprintf(res, _T("<%s:%s>"), tszProto, szUniqueID);
+ free(szUniqueID);
+ 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/parse_metacontacts.h b/plugins/Variables/parse_metacontacts.h
new file mode 100644
index 0000000000..d808213915
--- /dev/null
+++ b/plugins/Variables/parse_metacontacts.h
@@ -0,0 +1,22 @@
+/*
+ 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
+*/
+
+#define MC_GETPARENT "mc_getparent"
+#define MC_GETDEFAULT "mc_getdefault"
+#define MC_GETMOSTONLINE "mc_getmostonline"
diff --git a/plugins/Variables/parse_miranda.cpp b/plugins/Variables/parse_miranda.cpp
new file mode 100644
index 0000000000..0b8e0a5139
--- /dev/null
+++ b/plugins/Variables/parse_miranda.cpp
@@ -0,0 +1,997 @@
+/*
+ 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
+*/
+#include "variables.h"
+#include "parse_miranda.h"
+#include "contact.h"
+
+static TCHAR *parseCodeToStatus(ARGUMENTSINFO *ai)
+{
+ TCHAR *szStatus;
+ unsigned int status;
+
+ if (ai->argc != 2)
+ return NULL;
+
+ status = ttoi(ai->targv[1]);
+ szStatus = (TCHAR *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)status, GSMDF_TCHAR);
+ if (szStatus != NULL)
+ return _tcsdup(szStatus);
+
+ return NULL;
+}
+
+static int getContactInfoFlags(TCHAR *tszDesc)
+{
+ int flags;
+ TCHAR *cur;
+
+ 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)
+{
+ CONTACTSINFO ci;
+ int count, n;
+ HANDLE hContact;
+
+ if ( ai->argc < 3 || ai->argc > 4 )
+ return NULL;
+
+ n = 0;
+ if ( ai->argc == 4 && *ai->targv[3] != _T('r'))
+ n = ttoi(ai->targv[3]) - 1;
+
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.tszContact = ai->targv[1];
+ ci.flags = getContactInfoFlags(ai->targv[2]);
+ 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 ) {
+ if ( ci.hContacts != NULL )
+ free(ci.hContacts);
+
+ return NULL;
+ }
+ hContact = ci.hContacts[n];
+ log_debugA("contact: %x", hContact);
+ free(ci.hContacts);
+
+ return encodeContactToString(hContact);
+}
+
+static TCHAR *parseContactCount(ARGUMENTSINFO *ai)
+{
+ CONTACTSINFO ci;
+ int count;
+
+ if (ai->argc != 3)
+ return NULL;
+
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.tszContact = ai->targv[1];
+ ci.flags = getContactInfoFlags(ai->targv[2]);
+ count = getContactFromString( &ci );
+ if ( count != 0 && ci.hContacts != NULL )
+ free(ci.hContacts);
+
+ return itot(count);
+}
+
+static TCHAR *parseContactInfo(ARGUMENTSINFO *ai)
+{
+ HANDLE hContact;
+ CONTACTSINFO ci;
+ int count;
+ BYTE type;
+
+ if (ai->argc != 3)
+ return NULL;
+
+ hContact = NULL;
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.tszContact = ai->targv[1];
+ ci.flags = 0xFFFFFFFF ^ (CI_TCHAR == 0 ? CI_UNICODE : 0);
+ count = getContactFromString( &ci );
+ if ( count == 1 && ci.hContacts != NULL ) {
+ hContact = ci.hContacts[0];
+ free(ci.hContacts);
+ }
+ else {
+ if (ci.hContacts != NULL)
+ free(ci.hContacts);
+ return NULL;
+ }
+ type = getContactInfoType(ai->targv[2]);
+ if (type == 0)
+ return NULL;
+
+ return getContactInfoT(type, hContact, 1);
+}
+
+static TCHAR *parseDBProfileName(ARGUMENTSINFO *ai)
+{
+ char name[MAX_PATH];
+
+ if (ai->argc != 1)
+ return NULL;
+
+ if (CallService(MS_DB_GETPROFILENAME, SIZEOF(name), (LPARAM)name))
+ return NULL;
+
+ #ifdef UNICODE
+ return a2u(name);
+ #else
+ return _strdup(name);
+ #endif
+}
+
+static TCHAR *parseDBProfilePath(ARGUMENTSINFO *ai) {
+
+ char path[MAX_PATH];
+
+ if (ai->argc != 1)
+ return NULL;
+
+ if (CallService(MS_DB_GETPROFILEPATH, SIZEOF(path), (LPARAM)path))
+ return NULL;
+
+ #ifdef UNICODE
+ return a2u(path);
+ #else
+ return _strdup(path);
+ #endif
+}
+
+static TCHAR* getDBSetting(HANDLE hContact, char* module, char* setting, TCHAR* defaultValue) {
+
+ DBVARIANT dbv;
+ TCHAR* var = NULL;
+
+ if (DBGetContactSettingW(hContact, module, setting, &dbv))
+ return defaultValue;
+
+ 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:
+ #ifdef UNICODE
+ var = a2u(dbv.pszVal);
+ #else
+ var = _strdup(dbv.pszVal);
+ #endif
+ break;
+ case DBVT_WCHAR:
+ #ifdef UNICODE
+ var = _wcsdup(dbv.pwszVal);
+ #else
+ var = u2a(dbv.pwszVal);
+ #endif
+ break;
+ case DBVT_UTF8:
+ #ifdef UNICODE
+ Utf8Decode(dbv.pszVal, &var);
+ #else
+ var = _strdup(dbv.pszVal);
+ Utf8Decode(var, NULL);
+ #endif
+ break;
+ }
+
+ DBFreeVariant(&dbv);
+ return var;
+}
+
+static TCHAR *parseDBSetting(ARGUMENTSINFO *ai)
+{
+ CONTACTSINFO ci;
+ HANDLE hContact;
+ int count;
+ char *szModule, *szSetting;
+ TCHAR *res, *szDefaultValue;
+
+ if (ai->argc < 4)
+ return NULL;
+
+ res = NULL;
+ hContact = NULL;
+ szDefaultValue = NULL;
+ if (_tcslen(ai->targv[1]) > 0) {
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.tszContact = ai->targv[1];
+ ci.flags = 0xFFFFFFFF^(CI_TCHAR==0?CI_UNICODE:0);
+ count = getContactFromString( &ci );
+ if ( count == 1 && ci.hContacts != NULL ) {
+ hContact = ci.hContacts[0];
+ free(ci.hContacts);
+ }
+ else {
+ if (ci.hContacts != NULL)
+ free(ci.hContacts);
+ return NULL;
+ }
+ }
+
+ #ifdef UNICODE
+ szModule = u2a(ai->targv[2]);
+ szSetting = u2a(ai->targv[3]);
+ #else
+ szModule = _strdup(ai->argv[2]);
+ szSetting = _strdup(ai->argv[3]);
+ #endif
+
+ if ( ai->argc > 4 && _tcslen(ai->targv[4]) > 0 )
+ szDefaultValue = _tcsdup(ai->targv[4]);
+
+ if ( szModule != NULL && szSetting != NULL ) {
+ res = getDBSetting(hContact, szModule, szSetting, szDefaultValue);
+ free(szModule);
+ free(szSetting);
+ }
+ return res;
+}
+
+static TCHAR *parseLastSeenDate(ARGUMENTSINFO *ai)
+{
+ HANDLE hContact;
+ CONTACTSINFO ci;
+ int count, len;
+ SYSTEMTIME lsTime;
+ TCHAR *szFormat, *res;
+ char *szModule;
+
+ if (ai->argc <= 1)
+ return NULL;
+
+ hContact = NULL;
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.tszContact = ai->targv[1];
+ ci.flags = 0xFFFFFFFF^(CI_TCHAR==0?CI_UNICODE:0);
+ count = getContactFromString( &ci );
+ if ( count == 1 && ci.hContacts != NULL ) {
+ hContact = ci.hContacts[0];
+ free(ci.hContacts);
+ }
+ else {
+ if (ci.hContacts != NULL)
+ free(ci.hContacts);
+ return NULL;
+ }
+ if ( ai->argc == 2 || (ai->argc > 2 && _tcslen(ai->targv[2]) == 0))
+ szFormat = NULL;
+ else
+ szFormat = ai->targv[2];
+
+ ZeroMemory(&lsTime, sizeof(lsTime));
+ 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);
+
+ len = GetDateFormat(LOCALE_USER_DEFAULT, 0, &lsTime, szFormat, NULL, 0);
+ res = ( TCHAR* )malloc((len+1)*sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &lsTime, szFormat, res, len) == 0) {
+ free(res);
+ return NULL;
+ }
+
+ return res;
+}
+
+static TCHAR *parseLastSeenTime(ARGUMENTSINFO *ai)
+{
+ HANDLE hContact;
+ CONTACTSINFO ci;
+ int count, len;
+ SYSTEMTIME lsTime;
+ TCHAR *szFormat, *res;
+ char *szModule;
+
+ if (ai->argc <= 1)
+ return NULL;
+
+ hContact = NULL;
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.tszContact = ai->targv[1];
+ ci.flags = 0xFFFFFFFF^(CI_TCHAR==0?CI_UNICODE:0);
+ count = getContactFromString( &ci );
+ if ( count == 1 && ci.hContacts != NULL ) {
+ hContact = ci.hContacts[0];
+ free(ci.hContacts);
+ }
+ else {
+ if (ci.hContacts != NULL)
+ free(ci.hContacts);
+ return NULL;
+ }
+ if ( ai->argc == 2 || (ai->argc > 2 && _tcslen(ai->targv[2]) == 0))
+ szFormat = NULL;
+ else
+ szFormat = ai->targv[2];
+
+ ZeroMemory(&lsTime, sizeof(lsTime));
+ 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);
+
+ len = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &lsTime, szFormat, NULL, 0);
+ res = ( TCHAR* )malloc((len+1)*sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ if (GetTimeFormat(LOCALE_USER_DEFAULT, 0, &lsTime, szFormat, res, len) == 0) {
+ free(res);
+ return NULL;
+ }
+
+ return res;
+}
+
+static TCHAR *parseLastSeenStatus(ARGUMENTSINFO *ai) {
+
+ HANDLE hContact;
+ CONTACTSINFO ci;
+ int count, status;
+ char *szModule;
+ TCHAR *szStatus;
+
+ if (ai->argc != 2)
+ return NULL;
+
+ hContact = NULL;
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.tszContact = ai->targv[1];
+ ci.flags = 0xFFFFFFFF^(CI_TCHAR==0?CI_UNICODE:0);
+ count = getContactFromString( &ci );
+ if ( (count == 1) && (ci.hContacts != NULL) ) {
+ hContact = ci.hContacts[0];
+ free(ci.hContacts);
+ }
+ else {
+ if (ci.hContacts != NULL)
+ free(ci.hContacts);
+ return NULL;
+ }
+ szModule = CEX_MODULE;
+ status = DBGetContactSettingWord(hContact, szModule, "Status", 0);
+ if (status == 0)
+ szModule = SEEN_MODULE;
+
+ status = DBGetContactSettingWord(hContact, szModule, "Status", 0);
+ if (status == 0)
+ return NULL;
+
+ szStatus = (TCHAR *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)status, GSMDF_UNICODE);
+ if (szStatus != NULL)
+ return _tcsdup(szStatus);
+
+ return NULL;
+}
+
+static TCHAR *parseMirandaPath(ARGUMENTSINFO *ai) {
+
+ TCHAR path[MAX_PATH];
+
+ if (ai->argc != 1)
+ return NULL;
+
+ ai->flags |= AIF_DONTPARSE;
+ if (GetModuleFileName(NULL, path, SIZEOF(path)) == 0)
+ return NULL;
+
+ return _tcsdup(path);
+}
+
+static TCHAR *parseMyStatus(ARGUMENTSINFO *ai) {
+
+ int status;
+ char *szProto;
+ TCHAR *szStatus;
+
+ if (ai->argc > 2)
+ return NULL;
+
+ if ( ai->argc == 1 || _tcslen(ai->targv[1]) == 0 )
+ status = CallService(MS_CLIST_GETSTATUSMODE, 0, 0);
+ else {
+#ifdef UNICODE
+ szProto = u2a(ai->targv[1]);
+#else
+ szProto = _strdup(ai->targv[1]);
+#endif
+ status = CallProtoService(szProto, PS_GETSTATUS, 0, 0);
+ free(szProto);
+ }
+ szStatus = (TCHAR *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)status, GSMDF_UNICODE);
+ if (szStatus != NULL)
+ return _tcsdup(szStatus);
+
+ return NULL;
+}
+
+static TCHAR *parseProtoInfo(ARGUMENTSINFO *ai)
+{
+ TCHAR *tszRes;
+ char *szProto, *szRes;
+
+ if (ai->argc != 3)
+ return NULL;
+
+ szRes = NULL;
+ tszRes = NULL;
+#ifdef UNICODE
+ szProto = u2a(ai->targv[1]);
+#else
+ szProto = _strdup(ai->targv[1]);
+#endif
+ if (!_tcscmp(ai->targv[2], _T(STR_PINAME)))
+ tszRes = Hlp_GetProtocolName(szProto);
+ else if (!_tcscmp(ai->targv[2], _T(STR_PIUIDTEXT))) {
+ char *szText;
+
+ if (!ProtoServiceExists(szProto, PS_GETCAPS))
+ return NULL;
+
+ 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))) {
+ char *szText;
+ if (!ProtoServiceExists(szProto, PS_GETCAPS))
+ return NULL;
+
+ szText = (char *)CallProtoService(szProto, PS_GETCAPS, (WPARAM)PFLAG_UNIQUEIDSETTING, 0);
+ if (szText != NULL)
+ szRes = _strdup(szText);
+ }
+ free(szProto);
+ if ( szRes == NULL && tszRes == NULL )
+ return NULL;
+
+ if ( szRes != NULL && tszRes == NULL ) {
+ #ifdef UNICODE
+ tszRes = a2u(szRes);
+ free(szRes);
+ #else
+ tszRes = szRes;
+ #endif
+ }
+ else if ( szRes != NULL && tszRes != NULL )
+ free(szRes);
+
+ return tszRes;
+}
+
+static TCHAR *parseSpecialContact(ARGUMENTSINFO *ai)
+{
+ char *szProto;
+ TCHAR *szUniqueID, *res, *tszProto;
+
+ if ( ai->argc != 1 || ai->fi->hContact == NULL )
+ return NULL;
+
+ ai->flags |= AIF_DONTPARSE;
+ res = NULL;
+ szUniqueID = NULL;
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)ai->fi->hContact, 0);
+ if (szProto != NULL)
+ szUniqueID = getContactInfoT(CNF_UNIQUEID, ai->fi->hContact, 1);
+
+ if (szUniqueID == NULL) {
+ szProto = PROTOID_HANDLE;
+ szUniqueID = itot((int)ai->fi->hContact);
+ if ( szProto == NULL || szUniqueID == NULL )
+ return NULL;
+ }
+
+ res = ( TCHAR* )malloc((strlen(szProto) + _tcslen(szUniqueID) + 4)*sizeof(TCHAR));
+ if (res == NULL) {
+ free(szUniqueID);
+ return NULL;
+ }
+
+ #ifdef UNICODE
+ tszProto = a2u(szProto);
+ #else
+ tszProto = _strdup(szProto);
+ #endif
+
+ if ( tszProto != NULL && szUniqueID != NULL ) {
+ wsprintf(res, _T("<%s:%s>"), tszProto, szUniqueID);
+ free(szUniqueID);
+ 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;
+}
+
+// modified from history.c
+static TCHAR *GetMessageDescription(DBEVENTINFO *dbei)
+{
+ TCHAR *tszRes;
+
+ if ( ServiceExists( MS_DB_EVENT_GETTEXT )) {
+ // Miranda 0.7
+ TCHAR *buf = DbGetEventTextT(dbei, CP_ACP);
+ tszRes = _tcsdup(buf);
+ mir_free(buf);
+ }
+ else {
+ char *pszSrc = ( char* )dbei->pBlob;
+ size_t len = strlen(( char* )dbei->pBlob )+1;
+ #if defined( _UNICODE )
+ if ( dbei->cbBlob > len ) {
+ int len2 = dbei->cbBlob - len;
+
+ tszRes = ( TCHAR* )calloc(len2, 1);
+ memcpy( tszRes, &dbei->pBlob[ len ], len2 );
+ }
+ else {
+ char *szRes = ( char* )calloc(len, sizeof(char));
+ strncpy( szRes, ( const char* )pszSrc, len );
+ tszRes = a2u(szRes);
+ free(szRes);
+ }
+ #else
+ tszRes = ( char* )calloc(len, sizeof(char));
+ strncpy( tszRes, ( const char* )pszSrc, len );
+ #endif
+ }
+
+ return tszRes;
+}
+// end: from history.c
+
+// ?message(%subject%,last|first,sent|recv,read|unread)
+static TCHAR *parseDbEvent(ARGUMENTSINFO *ai)
+{
+ int flags, count;
+ HANDLE hContact;
+ HANDLE hDbEvent;
+ DBEVENTINFO dbe;
+ CONTACTSINFO ci;
+ TCHAR *res;
+
+ if (ai->argc != 5)
+ return NULL;
+
+ 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;
+ }
+ hContact = NULL;
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.tszContact = ai->targv[1];
+ ci.flags = 0xFFFFFFFF^(CI_TCHAR==0?CI_UNICODE:0);
+ count = getContactFromString( &ci );
+ if ( (count == 1) && (ci.hContacts != NULL) ) {
+ hContact = ci.hContacts[0];
+ free(ci.hContacts);
+ }
+ else if (ci.hContacts != NULL)
+ free(ci.hContacts);
+
+ hDbEvent = findDbEvent(hContact, NULL, flags);
+ if (hDbEvent == NULL)
+ return NULL;
+
+ ZeroMemory(&dbe, sizeof(DBEVENTINFO));
+ dbe.cbSize = sizeof(DBEVENTINFO);
+ dbe.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0);
+ dbe.pBlob = ( PBYTE )calloc(dbe.cbBlob, 1);
+ if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbe)) {
+ free(dbe.pBlob);
+ return NULL;
+ }
+ res = GetMessageDescription(&dbe);
+ 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 : _tcsdup(res);
+}
+
+static TCHAR *parseVersionString(ARGUMENTSINFO *ai) {
+
+ char versionString[128];
+
+ if (ai->argc != 1)
+ return NULL;
+
+ ai->flags |= AIF_DONTPARSE;
+ if (CallService(MS_SYSTEM_GETVERSIONTEXT, (WPARAM)sizeof(versionString), (LPARAM)versionString))
+ return NULL;
+
+ #ifdef UNICODE
+ return a2u(versionString);
+ #else
+ return _strdup(versionString);
+ #endif
+}
+
+static TCHAR *parseContactNameString(ARGUMENTSINFO *ai)
+{
+ TCHAR *ret;
+
+ if (ai->argc != 1 || ai->fi->hContact == NULL)
+ return NULL;
+
+ ai->flags |= AIF_DONTPARSE;
+ ret = (TCHAR *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) ai->fi->hContact, GCDNF_TCHAR);
+ if (ret == NULL)
+ return NULL;
+
+ return _tcsdup(ret);
+}
+
+static TCHAR *parseMirDateString(ARGUMENTSINFO *ai)
+{
+ TCHAR ret[128];
+ DBTIMETOSTRINGT tst = {0};
+
+ if (ai->argc != 1)
+ return NULL;
+
+ ai->flags |= AIF_DONTPARSE;
+ 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 _tcsdup(ret);
+}
+
+static TCHAR *parseMirandaCoreVar(ARGUMENTSINFO *ai) {
+
+ TCHAR path[MAX_PATH], corevar[MAX_PATH];
+ TCHAR* tmpPath;
+
+ if (ai->argc != 1)
+ return NULL;
+
+ ai->flags |= AIF_DONTPARSE;
+
+ mir_sntprintf(corevar, MAX_PATH,_T("%%%s%%"), ai->targv[0]);
+ tmpPath = Utils_ReplaceVarsT(corevar);
+ mir_sntprintf(path, sizeof(path)-1, _T("%s"), tmpPath);
+ mir_free(tmpPath);
+
+ return _tcsdup(path);
+}
+
+static TCHAR *parseMirSrvExists(ARGUMENTSINFO *ai)
+{
+ if ( ai->argc != 2 )
+ return NULL;
+
+ char* serviceName;
+ #ifdef _UNICODE
+ serviceName = u2a( ai->targv[1] );
+ #else
+ serviceName = ai->targv[1];
+ #endif
+
+ if ( !ServiceExists( serviceName ))
+ ai->flags |= AIF_FALSE;
+
+ #ifdef _UNICODE
+ free( serviceName );
+ #endif
+
+ return _tcsdup(_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/parse_miranda.h b/plugins/Variables/parse_miranda.h
new file mode 100644
index 0000000000..6cf1c12278
--- /dev/null
+++ b/plugins/Variables/parse_miranda.h
@@ -0,0 +1,88 @@
+/*
+ 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
+*/
+#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/parse_regexp.cpp b/plugins/Variables/parse_regexp.cpp
new file mode 100644
index 0000000000..52eaf8430e
--- /dev/null
+++ b/plugins/Variables/parse_regexp.cpp
@@ -0,0 +1,204 @@
+/*
+ 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
+*/
+#include "variables.h"
+#include "parse_regexp.h"
+#include <pcre.h>
+
+static void (*pcreFree)(void *);
+static pcre_extra *(*pcreStudy)(const pcre *, int, const char **);
+static pcre *(*pcreCompile)(const char *, int, const char **, int *, const unsigned char *);
+static int (*pcreExec)(const pcre *, const pcre_extra *, const char *, int, int, int, int *, int);
+static void *(*pcreMalloc)(size_t);
+static void (*pcreFreeSubstring)(const char *);
+static int (*pcreGetSubstring)(const char *, int *, int, int, const char **);
+
+/*
+ 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;
+#ifdef UNICODE
+ arg1 = u2a(ai->targv[1]);
+ arg2 = u2a(ai->targv[2]);
+#else
+ arg1 = _strdup(ai->argv[1]);
+ arg2 = _strdup(ai->argv[2]);
+#endif
+ ppat = pcreCompile(arg1, 0, &err, &erroffset, NULL);
+ if (ppat == NULL) {
+ free(arg1);
+ free(arg2);
+ return NULL;
+ }
+ extra = pcreStudy(ppat, 0, &err);
+ nmat = pcreExec(ppat, extra, arg2, strlen(arg2), 0, 0, offsets, 99);
+ free(arg1);
+ free(arg2);
+ if (nmat > 0) {
+ ai->flags &= ~AIF_FALSE;
+ _ltoa(nmat, szVal, 10);
+#ifdef UNICODE
+ res = a2u(szVal);
+#else
+ res = _strdup(szVal);
+#endif
+ return res;
+ }
+
+ return _tcsdup(_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;
+ }
+#ifdef UNICODE
+ arg1 = u2a(ai->targv[1]);
+ arg2 = u2a(ai->targv[2]);
+ arg3 = u2a(ai->targv[3]);
+#else
+ arg1 = _strdup(ai->argv[1]);
+ arg2 = _strdup(ai->argv[2]);
+ arg3 = _strdup(ai->argv[3]);
+#endif
+ number = atoi(arg3);
+ if (number < 0) {
+ free(arg1);
+ free(arg2);
+ free(arg3);
+ return NULL;
+ }
+ ai->flags = AIF_FALSE;
+ ppat = pcreCompile(arg1, 0, &err, &erroffset, NULL);
+ if (ppat == NULL) {
+ free(arg1);
+ free(arg2);
+ free(arg3);
+ return NULL;
+ }
+ extra = pcreStudy(ppat, 0, &err);
+ nmat = pcreExec(ppat, extra, arg2, strlen(arg2), 0, 0, offsets, 99);
+ if (nmat >= 0) {
+ ai->flags &= ~AIF_FALSE;
+ }
+ if (pcreGetSubstring(arg2, offsets, nmat, number, &substring) < 0) {
+ ai->flags |= AIF_FALSE;
+ }
+ else {
+ res = _strdup(substring);
+ pcreFreeSubstring(substring);
+
+#ifdef UNICODE
+ tres = a2u(res);
+#else
+ tres = _strdup(res);
+#endif
+ free(res);
+ free(arg1);
+ free(arg2);
+ free(arg3);
+
+ return tres;
+ }
+ free(arg1);
+ free(arg2);
+ free(arg3);
+
+ return _tcsdup(_T(""));
+}
+
+int initPcre() {
+
+ HMODULE hModule;
+
+ hModule = LoadLibraryA("pcre.dll");
+ if (hModule == NULL) {
+ char path[MAX_PATH];
+ char *cur;
+
+ GetModuleFileNameA(NULL, path, sizeof(path));
+ cur = strrchr(path, '\\');
+ if (cur != NULL)
+ strcpy(cur+1, "pcre.dll");
+ else
+ strcpy(path, "pcre.dll");
+ hModule = LoadLibraryA(path);
+ if (hModule == NULL) {
+ if (cur != NULL)
+ strcpy(cur+1, "pcre3.dll");
+ else
+ strcpy(path, "pcre3.dll");
+ hModule = LoadLibraryA(path);
+ }
+ }
+ if (hModule == NULL) {
+ return -1;
+ }
+ pcreMalloc = (void *(__cdecl *)(size_t))GetProcAddress(hModule, "pcre_malloc");
+ pcreFree = (void (__cdecl *)(void *))GetProcAddress(hModule, "pcre_free");
+ pcreStudy = (struct pcre_extra *(__cdecl *)(const struct real_pcre *,int ,const char ** ))GetProcAddress(hModule, "pcre_study");
+ pcreCompile = (struct real_pcre *(__cdecl *)(const char *,int ,const char ** ,int *,const unsigned char *))GetProcAddress(hModule, "pcre_compile");
+ pcreExec = (int (__cdecl *)(const struct real_pcre *,const struct pcre_extra *,const char *,int ,int ,int ,int *,int ))GetProcAddress(hModule, "pcre_exec");
+ pcreFreeSubstring = (void (__cdecl *)(const char *))GetProcAddress(hModule, "pcre_free_substring");
+ pcreGetSubstring = (int (__cdecl *)(const char *,int *,int ,int ,const char ** ))GetProcAddress(hModule, "pcre_get_substring");
+
+ return 0;
+}
+
+int registerRegExpTokens() {
+
+ if (initPcre() != 0) {
+ log_infoA("Variables: pcre.dll for PCRE not found");
+ return -1;
+ }
+
+#ifdef UNICODE
+ 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");
+#else
+ registerIntToken(_T(REGEXPCHECK), parseRegExpCheck, TRF_FUNCTION, "Regular Expressions\t(x,y)\tthe number of substring matches found in y with pattern x");
+ registerIntToken(_T(REGEXPSUBSTR), parseRegExpSubstr, TRF_FUNCTION, "Regular Expressions\t(x,y,z)\tsubstring match number z found in subject y with pattern x");
+#endif
+
+ return 0;
+}
diff --git a/plugins/Variables/parse_regexp.h b/plugins/Variables/parse_regexp.h
new file mode 100644
index 0000000000..24fb13e529
--- /dev/null
+++ b/plugins/Variables/parse_regexp.h
@@ -0,0 +1,20 @@
+/*
+ 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
+*/
+#define REGEXPCHECK "regexp_check"
+#define REGEXPSUBSTR "regexp_substr"
diff --git a/plugins/Variables/parse_str.cpp b/plugins/Variables/parse_str.cpp
new file mode 100644
index 0000000000..d8edcf642d
--- /dev/null
+++ b/plugins/Variables/parse_str.cpp
@@ -0,0 +1,935 @@
+/*
+ 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
+*/
+#include "variables.h"
+#include "parse_str.h"
+
+static TCHAR *parseCaps(ARGUMENTSINFO *ai) {
+
+ TCHAR *cur, *res;
+
+ if (ai->argc != 2)
+ return NULL;
+
+ res = _tcsdup(ai->targv[1]);
+ 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) {
+
+ TCHAR *cur, *res;
+
+ if (ai->argc != 2)
+ return NULL;
+
+ res = _tcsdup(ai->targv[1]);
+ 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 _tcsdup(_T("\r\n"));
+}
+
+static TCHAR *parseEolToCrlf(ARGUMENTSINFO *ai) {
+
+ int loc;
+ TCHAR *cur, *res;
+
+ if (ai->argc != 2) {
+ return NULL;
+ }
+ res = _tcsdup(ai->targv[1]);
+ cur = res;
+ do {
+ cur = _tcschr(cur, _T('\n'));
+ if ( (cur == NULL) || ((cur > res) && (*(cur-1) == '\r')) ) {
+ continue;
+ }
+ log_debug(cur);
+ loc = cur - res;
+ res = ( TCHAR* )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 *cur, *szReplacement, *res;
+
+ if (ai->argc == 2) {
+ szReplacement = _T("(...)");
+ }
+ else if (ai->argc == 3) {
+ szReplacement = ai->targv[2];
+ }
+ else {
+ return NULL;
+ }
+ cur = ai->targv[1];
+ while ( (_tcscmp(cur, _T("\r\n"))) && (*cur != _T('\n')) && (*cur != _T('\0')) ) {
+ cur++;
+ }
+ if (*cur == '\0') {
+ return _tcsdup(ai->targv[1]);
+ }
+ cur--;
+ res = ( TCHAR* )malloc((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 *res, *cur, *szEol, *szReplacement;
+
+ unsigned int pos = 0;
+ res = _tcsdup(ai->targv[1]);
+ switch( ai->argc ) {
+ case 2: szReplacement = _T(" "); break;
+ case 3: szReplacement = ai->targv[2]; break;
+ default: return NULL;
+ }
+
+ for ( pos=0; pos < _tcslen(res); pos++ ) {
+ cur = res+pos;
+ 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* )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;
+ }
+ }
+ res = ( TCHAR* )realloc(res, (_tcslen(res)+1)*sizeof(TCHAR));
+
+ return res;
+}
+
+static TCHAR *parseInsert(ARGUMENTSINFO *ai) {
+
+ TCHAR *res;
+ unsigned int pos;
+
+ if (ai->argc != 4) {
+ return NULL;
+ }
+
+ pos = ttoi(ai->targv[3]);
+ if (pos > _tcslen(ai->targv[1])) {
+ return NULL;
+ }
+ res = ( TCHAR* )malloc((_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) {
+
+ 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* )malloc((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) {
+
+ int len;
+
+ if (ai->argc != 2) {
+ return NULL;
+ }
+ len = _tcslen(ai->targv[1]);
+
+ return itot(len);
+}
+
+static TCHAR *parseLineCount(ARGUMENTSINFO *ai) {
+
+ int count;
+ TCHAR *cur;
+
+ if (ai->argc != 2) {
+ return NULL;
+ }
+ count = 1;
+ 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 += 1;
+ }
+ cur++;
+ }
+
+ return itot(count);
+}
+
+static TCHAR *parseLower(ARGUMENTSINFO *ai) {
+
+ TCHAR *res;
+
+ if (ai->argc != 2) {
+ return NULL;
+ }
+ res = _tcsdup(ai->targv[1]);
+ if (res == NULL) {
+ return NULL;
+ }
+
+ return CharLower(res);
+}
+
+static TCHAR *parseLongest(ARGUMENTSINFO *ai) {
+
+ unsigned int i, iLong;
+
+ if (ai->argc < 2) {
+ return NULL;
+ }
+ iLong = 1;
+ for (i=2;i<ai->argc;i++) {
+ if (_tcslen(ai->targv[i]) > _tcslen(ai->targv[iLong])) {
+ iLong = i;
+ }
+ }
+ return _tcsdup(ai->targv[iLong]);
+}
+
+static TCHAR *parseNoOp(ARGUMENTSINFO *ai) {
+
+ if (ai->argc != 2) {
+ return NULL;
+ }
+
+ return _tcsdup(ai->targv[1]);
+}
+
+static TCHAR *parsePad(ARGUMENTSINFO *ai) {
+
+ unsigned int addcount, i;
+ int padding;
+ TCHAR *res, padchar, *cur;
+
+ switch( ai->argc ) {
+ case 3: padchar = _T(' '); break;
+ case 4: padchar = *ai->targv[3]; break;
+ default: return NULL;
+ }
+
+ padding = ttoi(ai->targv[2]);
+ if (padding < 0)
+ return NULL;
+
+ addcount = max(padding - (signed int)_tcslen(ai->targv[1]), 0);
+ res = ( TCHAR* )malloc((addcount + _tcslen(ai->targv[1]) + 1)*sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ ZeroMemory(res, (addcount + _tcslen(ai->targv[1]) + 1)*sizeof(TCHAR));
+ cur = res;
+ for ( i=0; i < addcount; i++ )
+ *cur++ = padchar;
+
+ _tcscat(res, ai->targv[1]);
+ return res;
+}
+
+static TCHAR *parsePadright(ARGUMENTSINFO *ai) {
+
+ unsigned int addcount, i;
+ int padding;
+ TCHAR *res, padchar, *cur;
+
+ switch (ai->argc ) {
+ case 3: padchar = _T(' '); break;
+ case 4: padchar = *ai->targv[3]; break;
+ default: return NULL;
+ }
+
+ padding = ttoi(ai->targv[2]);
+ if (padding < 0)
+ return NULL;
+
+ addcount = max(padding - (signed int)_tcslen(ai->targv[1]), 0);
+ res = ( TCHAR* )malloc((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]);
+ cur = res + _tcslen(ai->targv[1]);
+ for (i=0;i<addcount;i++)
+ *cur++ = padchar;
+
+ return res;
+}
+
+static TCHAR *parsePadcut(ARGUMENTSINFO *ai) {
+
+ int padding, addcount, i;
+ TCHAR *res, padchar, *cur;
+
+ switch( ai->argc ) {
+ case 3: padchar = _T(' '); break;
+ case 4: padchar = *ai->targv[3]; break;
+ default: return NULL;
+ }
+
+ padding = ttoi(ai->targv[2]);
+ if (padding < 0)
+ return NULL;
+
+ addcount = max(padding - (signed int)_tcslen(ai->targv[1]), 0);
+ res = ( TCHAR* )malloc((padding + 1)*sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ ZeroMemory(res, (padding + 1)*sizeof(TCHAR));
+ cur = res;
+ for (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) {
+
+ int padding, addcount, i;
+ TCHAR *res, padchar, *cur;
+
+ switch( ai->argc ) {
+ case 3: padchar = _T(' '); break;
+ case 4: padchar = *ai->targv[3]; break;
+ default: return NULL;
+ }
+
+ padding = ttoi(ai->targv[2]);
+ if (padding < 0)
+ return NULL;
+
+ addcount = max(padding - (signed int)_tcslen(ai->targv[1]), 0);
+ res = ( TCHAR* )malloc((padding + 1)*sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ ZeroMemory(res, (padding + 1)*sizeof(TCHAR));
+ cur = res + padding - addcount;
+ for (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* )malloc((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 = _tcsdup(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* )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* )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* )malloc((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 _tcsdup(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* )malloc((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* )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 _tcsdup(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 _tcsdup(_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 _tcsdup(_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 _tcsdup(_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 _tcsdup(_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 _tcsdup(_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 _tcsdup(_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 _tcsdup(_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 _tcsdup(_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* )malloc((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 _tcsdup(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 _tcsdup(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 _tcsdup(_T(""));
+ }
+ res = ( TCHAR* )malloc((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* )malloc((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 = _tcsdup(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* )malloc((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* )realloc(res, (_tcslen(res) + _tcslen(szWord) + 2)*sizeof(TCHAR));
+ if (res != NULL) {
+ _tcscat(res, _T(" "));
+ _tcscat(res, szWord);
+ }
+ }
+ else res = _tcsdup(szWord);
+
+ 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 _tcsdup(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/parse_str.h b/plugins/Variables/parse_str.h
new file mode 100644
index 0000000000..e77ff4466c
--- /dev/null
+++ b/plugins/Variables/parse_str.h
@@ -0,0 +1,56 @@
+/*
+ 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
+*/
+#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/parse_system.cpp b/plugins/Variables/parse_system.cpp
new file mode 100644
index 0000000000..5bc927bd93
--- /dev/null
+++ b/plugins/Variables/parse_system.cpp
@@ -0,0 +1,1023 @@
+/*
+ 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
+*/
+#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* )calloc((len + 1), sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ if (!GetComputerName(res, &len)) {
+ 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 = _tcsdup(_T("\\Processor(_Total)\\% Processor Time"));
+ else {
+ szCounter = ( TCHAR* )malloc((_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) {
+ free(szCounter);
+ return NULL;
+ }
+ pdhStatus = PdhOpenQuery(NULL, 0, &hQuery);
+ if (pdhStatus != ERROR_SUCCESS) {
+ free(szCounter);
+ return NULL;
+ }
+ pdhStatus = PdhAddCounter(hQuery, szCounter, 0, &hCounter);
+ if (pdhStatus != ERROR_SUCCESS) {
+ free(szCounter);
+ pdhStatus = PdhCloseQuery(hQuery);
+ return NULL;
+ }
+ pdhStatus = PdhCollectQueryData(hQuery);
+ if (pdhStatus != ERROR_SUCCESS) {
+ free(szCounter);
+ PdhRemoveCounter(hCounter);
+ pdhStatus = PdhCloseQuery(hQuery);
+ return NULL;
+ }
+ Sleep(100);
+ pdhStatus = PdhCollectQueryData(hQuery);
+ if (pdhStatus != ERROR_SUCCESS) {
+ free(szCounter);
+ PdhRemoveCounter(hCounter);
+ pdhStatus = PdhCloseQuery(hQuery);
+ return NULL;
+ }
+ pdhStatus = PdhGetFormattedCounterValue(hCounter, PDH_FMT_DOUBLE, (LPDWORD)NULL, &cValue);
+ if (pdhStatus != ERROR_SUCCESS) {
+ free(szCounter);
+ PdhRemoveCounter(hCounter);
+ pdhStatus = PdhCloseQuery(hQuery);
+ return NULL;
+ }
+ if (cValue.CStatus != ERROR_SUCCESS) {
+ free(szCounter);
+ PdhRemoveCounter(hCounter);
+ pdhStatus = PdhCloseQuery(hQuery);
+ return NULL;
+ }
+ mir_sntprintf(szVal, SIZEOF(szVal), _T("%.0f"), cValue.doubleValue);
+ //PdhRemoveCounter(*hCounter);
+ PdhCloseQuery(hQuery);
+ free(szCounter);
+
+ return _tcsdup(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* )malloc((len+1)*sizeof(TCHAR));
+ if (res == NULL) {
+ return NULL;
+ }
+ if (GetDateFormat(LOCALE_USER_DEFAULT, 0, NULL, szFormat, res, len) == 0) {
+ 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* )malloc((len+1)*sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ if (GetTimeFormat(LOCALE_USER_DEFAULT, 0, NULL, szFormat, res, len) == 0) {
+ free(res);
+ return NULL;
+ }
+
+ return res;
+}
+
+static TCHAR *parseDirectory(ARGUMENTSINFO *ai) {
+
+ int depth;
+ TCHAR *res, *ecur, *scur;
+
+ if ( ai->argc < 2 || ai->argc > 3 )
+ return NULL;
+
+ depth = 1;
+ if (ai->argc == 3)
+ depth = ttoi(ai->targv[2]);
+
+ if (depth <= 0)
+ return NULL;
+
+ 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--;
+ }
+ scur = ecur;
+ while ( (*scur != _T('\\')) && (scur > ai->targv[1]) )
+ scur--;
+
+ if (*scur == _T('\\'))
+ scur++;
+
+ res = ( TCHAR* )calloc((ecur-scur)+2, sizeof(TCHAR));
+ if (res == NULL)
+ return NULL;
+
+ _tcsncpy(res, scur, (ecur-scur)+1);
+ return res;
+}
+
+/*
+ path, depth
+ returns complete path up to "path depth - depth"
+*/
+static TCHAR *parseDirectory2(ARGUMENTSINFO *ai) {
+
+ int depth;
+ TCHAR *res, *ecur;
+
+ if ( ai->argc < 2 || ai->argc > 3 )
+ return NULL;
+
+ depth = 1;
+ if (ai->argc == 3)
+ depth = ttoi(ai->targv[2]);
+
+ if (depth <= 0)
+ return NULL;
+
+ 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--;
+ }
+ res = ( TCHAR* )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 _tcsdup(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 _tcsdup(_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* )malloc((len+1)*sizeof(TCHAR));
+ if (res == NULL) {
+ return NULL;
+ }
+ ZeroMemory(res, (len+1)*sizeof(TCHAR));
+ if (ExpandEnvironmentStrings(ai->targv[1], res, len) == 0) {
+ 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 _tcsdup(_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* )malloc((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* )malloc((_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* )realloc(tszRes, (_tcslen(tszRes) + _tcslen(ffd.cFileName) + _tcslen(tszSeperator) + 1)*sizeof(TCHAR));
+ }
+ else {
+ tszRes = ( TCHAR* )malloc((_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;
+ }
+#ifdef UNICODE
+ szProc = ref = u2a(ai->targv[1]);
+#else
+ szProc = ref = _strdup(ai->argv[1]);
+#endif
+ EnumProcs((PROCENUMPROC) MyProcessEnumerator, (LPARAM)&szProc);
+ if (szProc != NULL) {
+ ai->flags |= AIF_FALSE;
+ }
+ free(ref);
+ return _tcsdup(_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 = _tcsdup(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 {
+ free(key);
+ return NULL;
+ }
+ subKey = cur+1;
+ if (RegOpenKeyEx(hKey, subKey, 0, KEY_READ, &hKey) != ERROR_SUCCESS) {
+ free(key);
+ return NULL;
+ }
+ free(key);
+ len = MAX_REGVALUE_LENGTH+1;
+ res = ( TCHAR* )malloc(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);
+ 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* )calloc((len+1), sizeof(TCHAR));
+ if (res == NULL) {
+ return NULL;
+ }
+ if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &sysTime, szFormat, res, len) == 0) {
+ 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* )malloc((len+1)*sizeof(TCHAR));
+ if (res == NULL) {
+ return NULL;
+ }
+ if (GetTimeFormat(LOCALE_USER_DEFAULT, 0, &sysTime, szFormat, res, len) == 0) {
+ 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 {
+#ifndef UNICODE
+ return NULL;
+#else
+ csz = sizeof(TCHAR);
+#endif
+ }
+ totalReadSz = 0;
+ lineCount = 1;
+ if (*ai->targv[2] == _T('0')) {
+ // complete file
+ bufSz = fileSz + csz;
+ pBuf = ( PBYTE )calloc(1, bufSz);
+ if (pBuf == NULL)
+ return NULL;
+
+ if (ReadFile(hFile, pBuf, bufSz-csz, &readSz, NULL) == 0) {
+ CloseHandle(hFile);
+ free(pBuf);
+ return NULL;
+ }
+ CloseHandle(hFile);
+#ifdef UNICODE
+ if (tUC) {
+ res = (TCHAR *)pBuf;
+ }
+ else {
+ res = a2u((char *)pBuf);
+ free(pBuf);
+ }
+#else
+ res = (char*)pBuf;
+#endif
+
+ return res;
+ }
+ bufSz = TXTFILEBUFSZ*csz;
+ pBuf = ( PBYTE )calloc(bufSz, 1);
+ if (pBuf == NULL) {
+ return NULL;
+ }
+ // count number of lines
+ do {
+ ZeroMemory(pBuf, bufSz);
+ if (ReadFile(hFile, pBuf, bufSz-csz, &readSz, NULL) == 0) {
+ CloseHandle(hFile);
+ 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);
+ free(pBuf);
+ return NULL;
+ }
+ if (SetFilePointer(hFile, linePos, NULL, FILE_BEGIN) != linePos) {
+ CloseHandle(hFile);
+ free(pBuf);
+ return NULL;
+ }
+ ZeroMemory(pBuf, bufSz);
+ pCur = pBuf;
+ do {
+ icur = 0;
+ if (ReadFile(hFile, pBuf, bufSz-csz, &readSz, NULL) == 0) {
+ 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';
+ }
+#ifdef UNICODE
+ if (tUC) {
+ res = (TCHAR *)pBuf;
+ }
+ else {
+ res = a2u((char *)pBuf);
+ free(pBuf);
+ }
+#else
+ res = (char *)pBuf;
+#endif
+ return res;
+ }
+ }
+ if ( ((DWORD)(linePos+(pCur-pBuf)) == fileSz) ) { // eof
+ CloseHandle(hFile);
+#ifdef UNICODE
+ if (tUC) {
+ res = (TCHAR *)pBuf;
+ }
+ else {
+ res = a2u((char *)pBuf);
+ free(pBuf);
+ }
+#else
+ res = (char *)pBuf;
+#endif
+ 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 )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 _tcsdup(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* )malloc(len + 1);
+ if (res == NULL) {
+ return NULL;
+ }
+ ZeroMemory(res, len + 1);
+ if (!GetUserName(res, &len)) {
+ 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;
+#ifdef _UNICODE
+ hData = GetClipboardData(CF_UNICODETEXT);
+#else
+ hData = GetClipboardData(CF_TEXT);
+#endif
+ if (hData != NULL) {
+ tszText = (TCHAR*)GlobalLock(hData);
+ len = _tcslen(tszText);
+ res = (TCHAR*)malloc((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/parse_system.h b/plugins/Variables/parse_system.h
new file mode 100644
index 0000000000..4da3f762fe
--- /dev/null
+++ b/plugins/Variables/parse_system.h
@@ -0,0 +1,41 @@
+/*
+ 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
+*/
+#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/parse_variables.cpp b/plugins/Variables/parse_variables.cpp
new file mode 100644
index 0000000000..19f5a39c20
--- /dev/null
+++ b/plugins/Variables/parse_variables.cpp
@@ -0,0 +1,173 @@
+/*
+ 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
+*/
+#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()) ) {
+ free(vr[i].szText);
+ vr[i].szText = _tcsdup(szText);
+ LeaveCriticalSection(&csVarRegister);
+
+ return 0;
+ }
+ }
+ vr = ( VARIABLEREGISTER* )realloc(vr, (vrCount+1)*sizeof(VARIABLEREGISTER));
+ if (vr == NULL) {
+ LeaveCriticalSection(&csVarRegister);
+ return -1;
+ }
+ vr[vrCount].szName = _tcsdup(szName);
+ vr[vrCount].szText = _tcsdup(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 = _tcsdup(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()) {
+ free(vr[i].szName);
+ free(vr[i].szText);
+ if (vrCount > 1) {
+ memcpy(&vr[i], &vr[vrCount-1], sizeof(VARIABLEREGISTER));
+ vr = ( VARIABLEREGISTER* )realloc(vr, (vrCount-1)*sizeof(VARIABLEREGISTER));
+ if (vr == NULL) {
+ LeaveCriticalSection(&csVarRegister);
+ return -1;
+ }
+ vrCount -= 1;
+ }
+ else {
+ 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 _tcsdup(_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/parse_variables.h b/plugins/Variables/parse_variables.h
new file mode 100644
index 0000000000..562e20d72b
--- /dev/null
+++ b/plugins/Variables/parse_variables.h
@@ -0,0 +1,28 @@
+/*
+ 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
+*/
+typedef struct {
+ TCHAR *szName;
+ TCHAR *szText;
+ DWORD dwOwnerThread;
+} VARIABLEREGISTER;
+
+#define PUT "put"
+#define PUTS "puts"
+#define GET "get"
+
diff --git a/plugins/Variables/parse_xml.cpp b/plugins/Variables/parse_xml.cpp
new file mode 100644
index 0000000000..5d3b5778a0
--- /dev/null
+++ b/plugins/Variables/parse_xml.cpp
@@ -0,0 +1,293 @@
+/*
+ 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
+*/
+#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;
+ }
+#ifdef UNICODE
+ szStyleSheet = u2a(ai->targv[1]);
+ szDoc = u2a(ai->targv[2]);
+#else
+ szStyleSheet = _strdup(ai->argv[1]);
+ szDoc = _strdup(ai->argv[2]);
+#endif
+
+ 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 free");
+ free(szStyleSheet);
+ log_debugA("calling free");
+ free(szDoc);
+#ifdef UNICODE
+ tszRes = a2u((char *)xmlChRes);
+#else
+ tszRes = _strdup((const char *)xmlChRes);
+#endif
+ 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;
+ }
+#ifdef UNICODE
+ szStyleSheet = u2a(ai->targv[1]);
+ szDoc = u2a(ai->targv[2]);
+#else
+ szStyleSheet = _strdup(ai->argv[1]);
+ szDoc = _strdup(ai->argv[2]);
+#endif
+
+ 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();
+
+ free(szStyleSheet);
+ free(szDoc);
+#ifdef UNICODE
+ tszRes = a2u((char *)xmlChRes);
+#else
+ tszRes = _strdup((const char *)xmlChRes);
+#endif
+ 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/parse_xml.h b/plugins/Variables/parse_xml.h
new file mode 100644
index 0000000000..51df56be79
--- /dev/null
+++ b/plugins/Variables/parse_xml.h
@@ -0,0 +1,2 @@
+#define XSLTF "xsltf"
+#define XSLTS "xslts" \ No newline at end of file
diff --git a/plugins/Variables/pcre/include/pcre.h b/plugins/Variables/pcre/include/pcre.h
new file mode 100644
index 0000000000..aa373893bb
--- /dev/null
+++ b/plugins/Variables/pcre/include/pcre.h
@@ -0,0 +1,239 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* In its original form, this is the .in file that is transformed by
+"configure" into pcre.h.
+
+ Copyright (c) 1997-2004 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 file pcre.h is build by "configure". Do not edit it; instead
+make changes to pcre.in. */
+
+#define PCRE_MAJOR 5
+#define PCRE_MINOR 0
+#define PCRE_DATE 13-Sep-2004
+
+/* Win32 uses DLL by default */
+
+#ifdef _WIN32
+# ifdef PCRE_DEFINITION
+# ifdef DLL_EXPORT
+# define PCRE_DATA_SCOPE __declspec(dllexport)
+# endif
+# else
+# ifndef PCRE_STATIC
+# define PCRE_DATA_SCOPE extern __declspec(dllimport)
+# endif
+# endif
+#endif
+#ifndef PCRE_DATA_SCOPE
+# define PCRE_DATA_SCOPE extern
+#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 */
+
+#define PCRE_CASELESS 0x0001
+#define PCRE_MULTILINE 0x0002
+#define PCRE_DOTALL 0x0004
+#define PCRE_EXTENDED 0x0008
+#define PCRE_ANCHORED 0x0010
+#define PCRE_DOLLAR_ENDONLY 0x0020
+#define PCRE_EXTRA 0x0040
+#define PCRE_NOTBOL 0x0080
+#define PCRE_NOTEOL 0x0100
+#define PCRE_UNGREEDY 0x0200
+#define PCRE_NOTEMPTY 0x0400
+#define PCRE_UTF8 0x0800
+#define PCRE_NO_AUTO_CAPTURE 0x1000
+#define PCRE_NO_UTF8_CHECK 0x2000
+#define PCRE_AUTO_CALLOUT 0x4000
+#define PCRE_PARTIAL 0x8000
+
+/* 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_NODE (-5)
+#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)
+#define PCRE_ERROR_BADUTF8_OFFSET (-11)
+#define PCRE_ERROR_PARTIAL (-12)
+#define PCRE_ERROR_BADPARTIAL (-13)
+#define PCRE_ERROR_INTERNAL (-14)
+#define PCRE_ERROR_BADCOUNT (-15)
+
+/* 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
+
+/* Request types for pcre_config() */
+
+#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
+
+/* Bit flags for the pcre_extra structure */
+
+#define PCRE_EXTRA_STUDY_DATA 0x0001
+#define PCRE_EXTRA_MATCH_LIMIT 0x0002
+#define PCRE_EXTRA_CALLOUT_DATA 0x0004
+#define PCRE_EXTRA_TABLES 0x0008
+
+/* Types */
+
+struct real_pcre; /* declaration; the definition is private */
+typedef struct real_pcre pcre;
+
+/* 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 */
+} pcre_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 */
+ const char *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 */
+ /* ------------------------------------------------------------------ */
+} pcre_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. Some magic is required for Win32 DLL;
+it is null on other OS. For Virtual Pascal, these have to be different again.
+*/
+
+#ifndef VPCOMPAT
+PCRE_DATA_SCOPE void *(*pcre_malloc)(size_t);
+PCRE_DATA_SCOPE void (*pcre_free)(void *);
+PCRE_DATA_SCOPE void *(*pcre_stack_malloc)(size_t);
+PCRE_DATA_SCOPE void (*pcre_stack_free)(void *);
+PCRE_DATA_SCOPE int (*pcre_callout)(pcre_callout_block *);
+#else /* VPCOMPAT */
+extern void *pcre_malloc(size_t);
+extern void pcre_free(void *);
+extern void *pcre_stack_malloc(size_t);
+extern void pcre_stack_free(void *);
+extern int pcre_callout(pcre_callout_block *);
+#endif /* VPCOMPAT */
+
+/* Exported PCRE functions */
+
+extern pcre *pcre_compile(const char *, int, const char **,
+ int *, const unsigned char *);
+extern int pcre_config(int, void *);
+extern int pcre_copy_named_substring(const pcre *, const char *,
+ int *, int, const char *, char *, int);
+extern int pcre_copy_substring(const char *, int *, int, int,
+ char *, int);
+extern int pcre_exec(const pcre *, const pcre_extra *,
+ const char *, int, int, int, int *, int);
+extern void pcre_free_substring(const char *);
+extern void pcre_free_substring_list(const char **);
+extern int pcre_fullinfo(const pcre *, const pcre_extra *, int,
+ void *);
+extern int pcre_get_named_substring(const pcre *, const char *,
+ int *, int, const char *, const char **);
+extern int pcre_get_stringnumber(const pcre *, const char *);
+extern int pcre_get_substring(const char *, int *, int, int,
+ const char **);
+extern int pcre_get_substring_list(const char *, int *, int,
+ const char ***);
+extern int pcre_info(const pcre *, int *, int *);
+extern const unsigned char *pcre_maketables(void);
+extern pcre_extra *pcre_study(const pcre *, int, const char **);
+extern const char *pcre_version(void);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* End of pcre.h */
diff --git a/plugins/Variables/pcre/include/pcreposix.h b/plugins/Variables/pcre/include/pcreposix.h
new file mode 100644
index 0000000000..a8056bd77c
--- /dev/null
+++ b/plugins/Variables/pcre/include/pcreposix.h
@@ -0,0 +1,117 @@
+/*************************************************
+* 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-2004 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 defined by POSIX. */
+
+#define REG_ICASE 0x01
+#define REG_NEWLINE 0x02
+#define REG_NOTBOL 0x04
+#define REG_NOTEOL 0x08
+
+/* These are not used by PCRE, but by defining them we make it easier
+to slot PCRE into existing programs that make POSIX calls. */
+
+#define REG_EXTENDED 0
+#define REG_NOSUB 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;
+
+/* The functions */
+
+extern int regcomp(regex_t *, const char *, int);
+extern int regexec(const regex_t *, const char *, size_t, regmatch_t *, int);
+extern size_t regerror(int, const regex_t *, char *, size_t);
+extern void regfree(regex_t *);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* End of pcreposix.h */
diff --git a/plugins/Variables/pcre/pcre_license.txt b/plugins/Variables/pcre/pcre_license.txt
new file mode 100644
index 0000000000..0fbd6f3e6b
--- /dev/null
+++ b/plugins/Variables/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/resource.h b/plugins/Variables/resource.h
new file mode 100644
index 0000000000..3217663618
--- /dev/null
+++ b/plugins/Variables/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/resource.rc b/plugins/Variables/resource.rc
new file mode 100644
index 0000000000..a65ead411e
--- /dev/null
+++ b/plugins/Variables/resource.rc
@@ -0,0 +1,2 @@
+#include "variables.rc"
+#include "version.rc" \ No newline at end of file
diff --git a/plugins/Variables/tokenregister.cpp b/plugins/Variables/tokenregister.cpp
new file mode 100644
index 0000000000..74da8858a3
--- /dev/null
+++ b/plugins/Variables/tokenregister.cpp
@@ -0,0 +1,340 @@
+/*
+ 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
+*/
+#include "variables.h"
+
+extern struct LIST_INTERFACE li;
+
+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 ( li.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.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;
+ }
+
+ li.List_RemovePtr(( SortedList* )&tokens, tre );
+ LeaveCriticalSection(&csRegister);
+
+ if ( !( tre->tr.flags & TRF_PARSEFUNC ) && tre->tr.szService != NULL )
+ free( tre->tr.szService );
+
+ if ( tre->tr.tszTokenString != NULL )
+ free( tre->tr.tszTokenString );
+
+ if ( tre->tr.szHelpText != NULL )
+ free( tre->tr.szHelpText );
+
+ if ( (tre->tr.flags & TRF_CLEANUP ) && !( tre->tr.flags & TRF_CLEANUPFUNC ) && tre->tr.szCleanupService != NULL )
+ free( tre->tr.szCleanupService );
+
+ 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 {
+#ifdef UNICODE
+ WCHAR *wtoken;
+
+ wtoken = a2u( newVr->szTokenString );
+ deRegisterToken( wtoken );
+ hash = NameHashFunction( wtoken );
+ free( wtoken );
+#else
+ deRegisterToken( newVr->szTokenString );
+ hash = NameHashFunction( newVr->szTokenString );
+#endif
+ }
+
+ tre = ( TokenRegisterEntry* )malloc( 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 = _strdup( newVr->szService );
+
+ if ( newVr->flags & TRF_TCHAR )
+ tre->tr.tszTokenString = _tcsdup( newVr->tszTokenString );
+ else
+#ifdef UNICODE
+ tre->tr.tszTokenString = a2u( newVr->szTokenString );
+#else
+ tre->tr.szTokenString = _strdup( newVr->szTokenString );
+#endif
+
+ if ( newVr->szHelpText != NULL )
+ tre->tr.szHelpText = _strdup( newVr->szHelpText );
+
+ if (( newVr->flags & TRF_CLEANUP ) && !( newVr->flags & TRF_CLEANUPFUNC ) && newVr->szCleanupService != NULL )
+ tre->tr.szCleanupService = _strdup( newVr->szCleanupService );
+
+ EnterCriticalSection(&csRegister);
+ li.List_GetIndex(( SortedList* )&tokens, tre, &idx );
+ li.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)
+{
+ int callRes;
+ TCHAR *temp, *res;
+ TOKENREGISTEREX *thisVr, trCopy;
+
+ if ( (ai == NULL) || (ai->argc == 0) || (ai->targv[0] == NULL) ) {
+ return NULL;
+ }
+ callRes = 0;
+ temp = res = NULL;
+ thisVr = NULL;
+ EnterCriticalSection(&csRegister);
+
+ /* note the following limitation: you cannot add/remove tokens during a call from a different thread */
+ thisVr = searchRegister( ai->targv[0], 0 );
+ if ( thisVr == NULL ) {
+ LeaveCriticalSection(&csRegister);
+ return NULL;
+ }
+
+ trCopy = *thisVr;
+
+#ifdef UNICODE
+ // 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** )malloc(ai->argc*sizeof(char *));
+ for ( j=0; j < ai->argc; j++ )
+ cAi.argv[j] = u2a( ai->targv[j] );
+
+ if ( thisVr->flags & TRF_PARSEFUNC )
+ callRes = (int)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 )
+ free( cAi.argv[j] );
+
+ if ((char *)callRes != NULL )
+ res = a2u(( char* )callRes );
+ }
+ else {
+ // unicode variables calls unicode plugin
+ if ( thisVr->flags & TRF_PARSEFUNC )
+ callRes = (int)thisVr->parseFunctionT( ai );
+ else if ( thisVr->szService != NULL )
+ callRes = CallService( thisVr->szService, (WPARAM)0, (LPARAM)ai );
+
+ if (( TCHAR* )callRes != NULL )
+ res = _tcsdup(( TCHAR* )callRes );
+ }
+#else
+ // non-unicode variables, should call non-unicode plugin (assume)
+ // ai contains chars, tr shouldn't use WCHARs
+ if ( thisVr->flags & TRF_PARSEFUNC )
+ callRes = (int)thisVr->parseFunction(ai);
+ else if ( thisVr->szService != NULL )
+ callRes = CallService( thisVr->szService, (WPARAM)0, (LPARAM)ai );
+
+ if (( char* )callRes != NULL )
+ res = _strdup(( char* )callRes );
+#endif
+
+ 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 )
+ 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 )
+ free( tre->tr.szService );
+
+ if ( tre->tr.tszTokenString != NULL )
+ free( tre->tr.tszTokenString );
+
+ if ( tre->tr.szHelpText != NULL )
+ free( tre->tr.szHelpText );
+
+ if (( tre->tr.flags & TRF_CLEANUP ) && !( tre->tr.flags & TRF_CLEANUPFUNC ) && tre->tr.szCleanupService != NULL )
+ free( tre->tr.szCleanupService );
+
+ free( tre );
+ }
+ li.List_Destroy(( SortedList* )&tokens );
+
+ LeaveCriticalSection(&csRegister);
+ DeleteCriticalSection(&csRegister);
+
+ return 0;
+}
diff --git a/plugins/Variables/trigger_variables.cpp b/plugins/Variables/trigger_variables.cpp
new file mode 100644
index 0000000000..16333b29e6
--- /dev/null
+++ b/plugins/Variables/trigger_variables.cpp
@@ -0,0 +1,248 @@
+/*
+ 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
+*/
+#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;
+ int i;
+
+ for (i=0;i<tvcCount;i++) {
+ if (tvc[i].triggerID == triggerID) {
+ free(tvc[i].parsedText);
+ MoveMemory(&tvc[i], &tvc[tvcCount-1], sizeof(TRG_VAR_CACHE));
+ tvcCount -= 1;
+ }
+ }
+ if (!DBGetTriggerSettingTString(triggerID, NULL, MODULENAME, SETTING_TRIGGERTEXT, &dbv)) {
+ tvc = ( TRG_VAR_CACHE* )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);
+ }
+ else {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int removeFromCache(DWORD triggerID) {
+
+ int i;
+
+ for (i=0;i<tvcCount;i++) {
+ if (tvc[i].triggerID == triggerID) {
+ 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) {
+
+ int i;
+ TCHAR *parsedText;
+ REPORTINFO ri;
+ TRIGGERDATA td;
+ DBVARIANT dbv;
+ DWORD triggerID;
+
+ triggerID = 0;
+ do {
+ triggerID = (DWORD)CallService(MS_TRIGGER_FINDNEXTTRIGGERID, triggerID, (LPARAM)TRIGGERNAME);
+ if (triggerID == 0) {
+ continue;
+ }
+ for (i=0;i<tvcCount;i++) {
+ if (triggerID != tvc[i].triggerID) {
+ continue;
+ }
+ if (!DBGetTriggerSettingTString(tvc[i].triggerID, NULL, MODULENAME, SETTING_TRIGGERTEXT, &dbv)) {
+ parsedText = variables_parsedup(dbv.ptszVal, NULL, NULL);
+ if (parsedText == NULL) {
+ continue;
+ }
+ if (!_tcscmp(tvc[i].parsedText, parsedText)) {
+ free(parsedText);
+ continue;
+ }
+ else {
+ ZeroMemory(&td, sizeof(td));
+ td.cbSize = sizeof(td);
+ td.dFlags = DF_TEXT;
+ td.tszText = parsedText;
+
+ ZeroMemory(&ri, sizeof(REPORTINFO));
+ 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);
+ 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: {
+ DBVARIANT dbv;
+ DWORD triggerID;
+
+ TranslateDialogDefault(hwndDlg);
+ 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;
+ TCHAR *tszFormatText;
+
+ triggerID = (DWORD)wParam;
+ tszFormatText = Hlp_GetDlgItemText(hwndDlg, IDC_FORMATTEXT);
+ if (tszFormatText != NULL) {
+ DBWriteTriggerSettingTString(triggerID, NULL, MODULENAME, SETTING_TRIGGERTEXT, tszFormatText);
+ free(tszFormatText);
+ }
+ addToCache(triggerID);
+ break;
+ }
+
+ case TM_DELTRIGGER: {
+ // wParam = triggerID
+ // lParam = (TRIGGEREGISTER *) may be 0
+ DWORD triggerID;
+ REMOVETRIGGERSETTINGS rts;
+
+ 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() {
+
+ CONDITIONREGISTER cr;
+ TRIGGERREGISTER tr;
+ ACTIONREGISTER ar;
+ int res;
+ DWORD triggerID;
+
+ log_debugA("Variables: initTriggerModule");
+ if (!ServiceExists(MS_TRIGGER_REGISTERTRIGGER)) {
+ log_debugA("Variables: %s does not exist", MS_TRIGGER_REGISTERTRIGGER);
+ return -1;
+ }
+ ZeroMemory(&tr, sizeof(tr));
+ 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;
+ res = CallService(MS_TRIGGER_REGISTERTRIGGER, 0, (LPARAM)&tr);
+ log_debugA("Variables: %s registered (%d)", TRIGGERNAME, res);
+
+ ZeroMemory(&ar, sizeof(ACTIONREGISTER));
+ 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);
+
+ ZeroMemory(&cr, sizeof(CONDITIONREGISTER));
+ 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
+ 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/trigger_variables.h b/plugins/Variables/trigger_variables.h
new file mode 100644
index 0000000000..39679dfa78
--- /dev/null
+++ b/plugins/Variables/trigger_variables.h
@@ -0,0 +1,36 @@
+/*
+ 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
+*/
+#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/variables.cpp b/plugins/Variables/variables.cpp
new file mode 100644
index 0000000000..aa316b9169
--- /dev/null
+++ b/plugins/Variables/variables.cpp
@@ -0,0 +1,680 @@
+/*
+ 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
+*/
+#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** )realloc(argv, (argc+1)*sizeof(TCHAR *));
+ if (argv == NULL) {
+ return NULL;
+ }
+ if (cur > scur) {
+ argv[argc] = ( TCHAR* )malloc((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] = _tcsdup(_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) {
+ free(argv[i]);
+ }
+ }
+ 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 = _tcsdup(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;
+ // free memory from last iteration, this way we can bail out at any time in the loop
+ if (parsedToken != NULL)
+ free(parsedToken);
+
+ for (i=0;i<argc;i++)
+ if (argv[i] != NULL)
+ free(argv[i]);
+
+ if (argv != NULL)
+ 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* )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* )malloc((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);
+ 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;
+ free(afi.szFormat);
+ }
+ }
+ if (argv[i] == NULL)
+ argv[i] = _tcsdup(_T(""));
+ }
+ }
+ // cur should now point at the character after FIELD_CHAR or after the last ')'
+ if (tr != NULL) {
+ pargv = ( TCHAR** )malloc((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);
+ 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 = 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* )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));
+ {
+ int len;
+
+ len = _tcslen(string);
+ string = ( TCHAR* )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 free
+ }
+ if (parsedToken != NULL)
+ free(parsedToken);
+
+ for ( i=0; i < argc; i++ )
+ if ( argv[i] != NULL )
+ free( argv[i] );
+
+ if ( argv != NULL )
+ free(argv);
+
+ return ( TCHAR* )realloc(string, (_tcslen(string)+1)*sizeof(TCHAR));
+}
+
+/*
+ MS_VARS_FORMATSTRING
+*/
+static INT_PTR formatStringService(WPARAM wParam, LPARAM lParam) {
+
+ int res, 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;
+#ifdef UNICODE
+ if (!(fi->flags&FIF_TCHAR)) {
+ copied = TRUE;
+ log_debugA("a2u (%s)", fi->szExtraText);
+ tszFormat = fi->szFormat!=NULL?a2u(fi->szFormat):NULL;
+ tszSource = fi->szExtraText!=NULL?a2u(fi->szExtraText):NULL;
+ for(i = 0; i < fi->cbTemporaryVarsSize; i++) {
+ fi->tszaTemporaryVars[i] = fi->szaTemporaryVars[i]!=NULL?a2u(fi->szaTemporaryVars[i]):NULL;
+ }
+ }
+ else {
+ copied = FALSE;
+ tszFormat = fi->tszFormat;
+ tszSource = fi->tszExtraText;
+ }
+#else
+ if (fi->flags&FIF_UNICODE) {
+ if (!bWarningShown) {
+ MessageBoxA(NULL, "A plugin using UNICODE encoding tries to make use of the ANSI version of Variables.\r\nPlease use the UNICODE version of Variables or the ANSI version of the plugin using Variables.", "Variables", MB_OK);
+ bWarningShown = TRUE;
+ }
+ return (int)NULL;
+ }
+ copied = FALSE;
+ tszFormat = fi->szFormat;
+ tszSource = fi->szExtraText;
+#endif
+ fi->tszFormat = tszFormat;
+ fi->tszExtraText = tszSource;
+
+ tRes = formatString(fi);
+#ifdef UNICODE
+ if (!(fi->flags&FIF_TCHAR)) {
+ res = (int)u2a(tRes);
+ free(tRes);
+ }
+ else {
+ res = (int)tRes;
+ }
+#else
+ res = (int)tRes;
+#endif
+ if (copied) {
+ if (tszFormat != NULL) {
+ free(tszFormat);
+ }
+ if (tszSource != NULL) {
+ free(tszSource);
+ }
+ for(i = 0; i < fi->cbTemporaryVarsSize; i++) {
+ if (fi->tszaTemporaryVars != NULL) {
+ 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 = _tcsdup(fi->tszFormat);
+ if (string == NULL) {
+ return NULL;
+ }
+ formattedString = replaceDynVars(string, fi);
+ 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;
+ }
+ free((void*)wParam);
+
+ return 0;
+}
+
+/*
+ MS_VARS_GET_MMI
+ this code is copied from Miranda's core (miranda.c)
+*/
+INT_PTR getMemoryManagerInterface(WPARAM wParam, LPARAM lParam) {
+
+ struct MM_INTERFACE *mmi = (struct MM_INTERFACE*) lParam;
+ if (mmi || mmi->cbSize == sizeof(struct MM_INTERFACE))
+ {
+ mmi->mmi_malloc = malloc;
+ mmi->mmi_realloc = realloc;
+ mmi->mmi_free = free;
+ return 0;
+ }
+ return 1;
+}
+
+int setParseOptions(struct ParseOptions *po) {
+
+ if (po == NULL) {
+ po = &gParseOpts;
+ }
+ ZeroMemory(po, sizeof(struct ParseOptions));
+ if (!db_getb(SETTING_STRIPALL, 0)) {
+ po->bStripEOL = db_getb(SETTING_STRIPCRLF, 0);
+ po->bStripWS = db_getb(SETTING_STRIPWS, 0);
+ }
+ else {
+ po->bStripAll = TRUE;
+ }
+
+ return 0;
+}
+
+int LoadVarModule() {
+
+ HMODULE hUxTheme;
+
+ 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);
+ hGetMMIService = CreateServiceFunction(MS_VARS_GET_MMI, getMemoryManagerInterface);
+ // help dialog
+ hCurSplitNS = LoadCursor(NULL, IDC_SIZENS);
+ hUxTheme = NULL;
+ if(IsWinVerXPPlus()) {
+ 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);
+ if (ServiceExists(MS_SKIN2_ADDICON)) {
+ SKINICONDESC sid;
+ char szFile[MAX_PATH];
+
+ ZeroMemory(&sid, sizeof(SKINICONDESC));
+ sid.cbSize = sizeof(SKINICONDESC);
+ sid.ptszSection = TranslateT("Variables");
+ sid.ptszDescription = TranslateT("Help");
+ sid.pszName = "vars_help";
+ GetModuleFileNameA(hInst, szFile, MAX_PATH);
+ sid.pszDefaultFile = szFile;
+ sid.iDefaultIndex = -IDI_V;
+ sid.cx = sid.cy = 16;
+ sid.flags = SIDF_TCHAR;
+ CallService(MS_SKIN2_ADDICON, (WPARAM)0, (LPARAM)&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_getb(SETTING_PARSEATSTARTUP, 0)) {
+ FORMATINFO fi;
+
+ ZeroMemory(&fi, sizeof(fi));
+ fi.cbSize = sizeof(fi);
+ fi.tszFormat = db_gets(SETTING_STARTUPTEXT, NULL);
+ if (fi.tszFormat != NULL) {
+ freeMemory((WPARAM)formatString(&fi), 0);
+ 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/variables.h b/plugins/Variables/variables.h
new file mode 100644
index 0000000000..eca0b1acd8
--- /dev/null
+++ b/plugins/Variables/variables.h
@@ -0,0 +1,177 @@
+/*
+ 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
+*/
+#if defined( UNICODE ) && !defined( _UNICODE )
+# define _UNICODE
+#endif
+
+#define MIRANDA_VER 0x0A00
+
+#include <tchar.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"
+//#include "dbhelpers.h"
+#define MODULENAME "Variables"
+//#define LOGLEVEL __LOGLEVEL_DEBUG
+#include "../helpers/gen_helpers.h"
+#include "../helpers/db_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 tchar);
+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);
+
+char* u2a( wchar_t* src );
+wchar_t* a2u( char* src );
+int ttoi(TCHAR *string);
+TCHAR *itot(int num);
+
+extern DWORD g_mirandaVersion; \ No newline at end of file
diff --git a/plugins/Variables/variables.spec b/plugins/Variables/variables.spec
new file mode 100644
index 0000000000..ff78e224ba
--- /dev/null
+++ b/plugins/Variables/variables.spec
@@ -0,0 +1,3 @@
+@ cdecl MirandaPluginInfo(long)
+@ cdecl Load(ptr)
+@ cdecl Unload()
diff --git a/plugins/Variables/version.rc b/plugins/Variables/version.rc
new file mode 100644
index 0000000000..3c1b5d1f3b
--- /dev/null
+++ b/plugins/Variables/version.rc
@@ -0,0 +1,44 @@
+#include <windows.h>
+#include "buildnumber.h"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION __FILEVERSION_STRING
+ PRODUCTVERSION __FILEVERSION_STRING
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "\0"
+ VALUE "FileDescription", "Variables Miranda-IM plugin\0"
+ VALUE "FileVersion", __VERSION_STRING
+ VALUE "InternalName", "Variables\0"
+ VALUE "LegalCopyright", "Copyright © 2003-2006 P. Boon\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "Variables.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "Variables\0"
+ VALUE "ProductVersion", __VERSION_STRING
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END