Revision: 16272
Author: roast
Date: 2006-06-16 19:11:13 -0700 (Fri, 16 Jun 2006)
ViewCVS: http://svn.sourceforge.net/gaim/?rev=16272&view=rev
Log Message:
-----------
merged with svn trunk, r16271
Modified Paths:
--------------
branches/soc-2006-file-loggers/Makefile.mingw
branches/soc-2006-file-loggers/config.h.mingw
branches/soc-2006-file-loggers/configure.ac
branches/soc-2006-file-loggers/gaim-installer.nsi
branches/soc-2006-file-loggers/pixmaps/smileys/THEMES-HOWTO
branches/soc-2006-file-loggers/plugins/tcl/Makefile.am
branches/soc-2006-file-loggers/plugins/tcl/Makefile.mingw
branches/soc-2006-file-loggers/plugins/tcl/tcl.c
branches/soc-2006-file-loggers/plugins/tcl/tcl_cmds.c
branches/soc-2006-file-loggers/plugins/tcl/tcl_gaim.h
branches/soc-2006-file-loggers/plugins/tcl/tcl_glib.c
branches/soc-2006-file-loggers/plugins/tcl/tcl_signals.c
branches/soc-2006-file-loggers/src/Makefile.am
branches/soc-2006-file-loggers/src/Makefile.mingw
branches/soc-2006-file-loggers/src/gtkblist.c
branches/soc-2006-file-loggers/src/gtkdialogs.c
branches/soc-2006-file-loggers/src/gtkutils.h
branches/soc-2006-file-loggers/src/protocols/jabber/Makefile.am
branches/soc-2006-file-loggers/src/protocols/jabber/Makefile.mingw
branches/soc-2006-file-loggers/src/protocols/jabber/auth.c
branches/soc-2006-file-loggers/src/protocols/jabber/buddy.c
branches/soc-2006-file-loggers/src/protocols/jabber/chat.c
branches/soc-2006-file-loggers/src/protocols/jabber/disco.c
branches/soc-2006-file-loggers/src/protocols/jabber/iq.c
branches/soc-2006-file-loggers/src/protocols/jabber/jabber.c
branches/soc-2006-file-loggers/src/protocols/jabber/jabber.h
branches/soc-2006-file-loggers/src/protocols/jabber/message.c
branches/soc-2006-file-loggers/src/protocols/jabber/oob.c
branches/soc-2006-file-loggers/src/protocols/jabber/parser.c
branches/soc-2006-file-loggers/src/protocols/jabber/presence.c
branches/soc-2006-file-loggers/src/protocols/jabber/roster.c
branches/soc-2006-file-loggers/src/protocols/jabber/si.c
branches/soc-2006-file-loggers/src/protocols/jabber/xdata.c
branches/soc-2006-file-loggers/src/protocols/msn/userlist.c
branches/soc-2006-file-loggers/src/protocols/oscar/oscar.c
branches/soc-2006-file-loggers/src/protocols/yahoo/yahoo_packet.c
branches/soc-2006-file-loggers/src/xmlnode.c
branches/soc-2006-file-loggers/src/xmlnode.h
Modified: branches/soc-2006-file-loggers/Makefile.mingw
===================================================================
--- branches/soc-2006-file-loggers/Makefile.mingw 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/Makefile.mingw 2006-06-17 02:11:13 UTC (rev 16272)
@@ -12,6 +12,7 @@
GAIM_SOUNDS = ./sounds
GAIM_INSTALL_DIR = ./win32-install-dir
GTKSPELL_TOP = ../win32-dev/gtkspell-2.0.6/gtkspell
+LIBXML2_DIR = ../win32-dev/libxml2
IDLETRACK_TOP = $(GAIM_SRC)/win32/IdleTracker
GTKRC_TOP = ../win32-dev/gtkrc
OSCAR = $(GAIM_PROTOS)/oscar
@@ -33,7 +34,8 @@
VERSION := $(shell cat ./VERSION)
NEEDED_DLLS = $(GTKSPELL_TOP)/libgtkspell.dll \
- $(IDLETRACK_TOP)/idletrack.dll
+ $(IDLETRACK_TOP)/idletrack.dll \
+ $(LIBXML2_DIR)/bin/libxml2.dll
SOUNDS = $(GAIM_SOUNDS)/alert.wav \
$(GAIM_SOUNDS)/login.wav \
Modified: branches/soc-2006-file-loggers/config.h.mingw
===================================================================
--- branches/soc-2006-file-loggers/config.h.mingw 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/config.h.mingw 2006-06-17 02:11:13 UTC (rev 16272)
@@ -635,6 +635,8 @@
<inttypes.h> don't define. */
/* #undef uintmax_t */
+#define HAVE_LIBXML 1
+
/*
* Following are added for Win32 version of Gaim
*/
Modified: branches/soc-2006-file-loggers/configure.ac
===================================================================
--- branches/soc-2006-file-loggers/configure.ac 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/configure.ac 2006-06-17 02:11:13 UTC (rev 16272)
@@ -171,6 +171,18 @@
AC_DEFINE(USE_GSTREAMER, 1, [Use GStreamer for making sounds])
fi
+dnl #################
+dnl # LibXML2
+dnl #################
+enable_libxml2=yes
+PKG_CHECK_MODULES(LIBXML, libxml-2.0, ,enable_libxml2=no)
+AC_SUBST(LIBXML_CFLAGS)
+AC_SUBST(LIBXML_LIBS)
+AC_ARG_ENABLE(libxml,[ --disable-libxml compile without libxml2 support],enable_libxml2=no)
+if test "x$enable_libxml2" = "xyes"; then
+ AC_DEFINE(HAVE_LIBXML, 1, [Use libxml2 for xml parsing])
+fi
+
dnl #######################################################################
dnl # Check for Meanwhile headers (for Sametime)
dnl #######################################################################
@@ -306,8 +318,8 @@
dnl #######################################################################
dnl # Check for Gadu-Gadu client includes and libraries
dnl #######################################################################
-AC_ARG_WITH(gadu-includes, [AC_HELP_STRING([--with-gadu-includes=DIR], [compile the GaduGadu plugin against includes in DIR])], [ac_gadu_includes="$withval"], [ac_gadu_includes="no"])
-AC_ARG_WITH(gadu-libs, [AC_HELP_STRING([--with-gadu-libs=DIR], [compile the GaduGadu plugin against the libs in DIR])], [ac_gadu_libs="$withval"], [ac_gadu_libs="no"])
+AC_ARG_WITH(gadu-includes, [AC_HELP_STRING([--with-gadu-includes=DIR], [compile the Gadu-Gadu plugin against includes in DIR])], [ac_gadu_includes="$withval"], [ac_gadu_includes="no"])
+AC_ARG_WITH(gadu-libs, [AC_HELP_STRING([--with-gadu-libs=DIR], [compile the Gadu-Gadu plugin against the libs in DIR])], [ac_gadu_libs="$withval"], [ac_gadu_libs="no"])
GADU_CFLAGS=""
GADU_LIBS=""
if test -n "$with_gadu_includes" || test -n "$with_gadu_libs"; then
@@ -1060,7 +1072,7 @@
dnl These two are inverses of each other <-- stolen from evolution!
AC_ARG_ENABLE(gnutls,
- [ --enable-gnutls=[yes,no] attempt to use GNUTLS for SSL support (preferred) [default=yes]],
+ [ --enable-gnutls=[yes,no] attempt to use GnuTLS for SSL support (preferred) [default=yes]],
[enable_gnutls="$enableval"],
[enable_gnutls="yes"])
@@ -1072,14 +1084,14 @@
msg_ssl="None (MSN will not work without SSL!)"
dnl #
-dnl # Check for GNUTLS if it's specified.
+dnl # Check for GnuTLS if it's specified.
dnl #
if test "x$enable_gnutls" != "xno"; then
enable_gnutls="no"
prefix=`eval echo $prefix`
AC_ARG_WITH(gnutls-includes,
- [ --with-gnutls-includes=PREFIX location of GNUTLS includes.],
+ [ --with-gnutls-includes=PREFIX location of GnuTLS includes.],
[ with_gnutls_includes="$withval" ],
[ with_gnutls_includes="$prefix/include" ])
@@ -1088,7 +1100,7 @@
if test "x$with_gnutls_includes" != "xno"; then
CPPFLAGS_save="$CPPFLAGS"
- AC_MSG_CHECKING(for GNUTLS includes)
+ AC_MSG_CHECKING(for GnuTLS includes)
AC_MSG_RESULT("")
CPPFLAGS="$CPPFLAGS -I$with_gnutls_includes"
@@ -1104,12 +1116,12 @@
GNUTLS_CFLAGS=""
fi
else
- AC_MSG_CHECKING(for GNUTLS includes)
+ AC_MSG_CHECKING(for GnuTLS includes)
AC_MSG_RESULT(no)
fi
AC_ARG_WITH(gnutls-libs,
- [ --with-gnutls-libs=PREFIX location of GNUTLS libraries.],
+ [ --with-gnutls-libs=PREFIX location of GnuTLS libraries.],
[ with_gnutls_libs="$withval" ])
if test "x$with_gnutls_libs" != "xno" -a \
@@ -1122,7 +1134,7 @@
*) with_gnutls_libs="-L$with_gnutls_libs" ;;
esac
- AC_CACHE_CHECK([for GNUTLS libraries], gnutls_libs,
+ AC_CACHE_CHECK([for GnuTLS libraries], gnutls_libs,
[
LDFLAGS="$LDFLAGS $with_gnutls_libs -lgnutls -lgcrypt"
AC_TRY_LINK_FUNC(gnutls_init, gnutls_libs="yes", gnutls_libs="no")
@@ -1130,9 +1142,9 @@
])
if test "x$gnutls_libs" != "xno"; then
- AC_DEFINE(HAVE_GNUTLS, 1, [Define if you have GNUTLS])
+ AC_DEFINE(HAVE_GNUTLS, 1, [Define if you have GnuTLS])
AC_DEFINE(HAVE_SSL)
- msg_gnutls="GNUTLS"
+ msg_gnutls="GnuTLS"
GNUTLS_LIBS="$with_gnutls_libs -lgnutls -lgcrypt"
enable_gnutls="yes"
@@ -1141,7 +1153,7 @@
GNUTLS_LIBS=""
fi
else
- AC_MSG_CHECKING(for GNUTLS libraries)
+ AC_MSG_CHECKING(for GnuTLS libraries)
AC_MSG_RESULT(no)
fi
else
@@ -1156,7 +1168,7 @@
dnl #
-dnl # Check for NSS if it's specified, or if GNUTLS checks failed.
+dnl # Check for NSS if it's specified, or if GnuTLS checks failed.
dnl #
if test "x$enable_nss" != "xno"; then
@@ -1785,6 +1797,7 @@
eval echo DBUS servies directory........ : $DBUS_SERVICES_DIR
fi
echo Build with Cyrus SASL support. : $enable_cyrus_sasl
+echo Build with libxml2 support.... : $enable_libxml2
echo Has you....................... : yes
echo
echo
Modified: branches/soc-2006-file-loggers/gaim-installer.nsi
===================================================================
--- branches/soc-2006-file-loggers/gaim-installer.nsi 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/gaim-installer.nsi 2006-06-17 02:11:13 UTC (rev 16272)
@@ -744,6 +744,7 @@
Delete "$INSTDIR\idletrack.dll"
Delete "$INSTDIR\libgtkspell.dll"
Delete "$INSTDIR\libmeanwhile-1.dll"
+ Delete "$INSTDIR\libxml2.dll"
Delete "$INSTDIR\nspr4.dll"
Delete "$INSTDIR\nss3.dll"
Delete "$INSTDIR\nssckbi.dll"
Modified: branches/soc-2006-file-loggers/pixmaps/smileys/THEMES-HOWTO
===================================================================
--- branches/soc-2006-file-loggers/pixmaps/smileys/THEMES-HOWTO 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/pixmaps/smileys/THEMES-HOWTO 2006-06-17 02:11:13 UTC (rev 16272)
@@ -4,10 +4,8 @@
Version 0.60 of Gaim brings up all themable smileys. In the preferences dialog, a user can choose from a selection of looks his smileys will take. This guide is to serve as a reference to those interested in creating third-party smiley themes.
-(SME: I'm doing this at 6:30AM; I'm tired, but I can't sleep. Someone make sure I fix this up to make sure it all makes sense when I'm not tired anymore. Right now it's mostly just unassembled thoughts)
+Your theme should be contained in a single directory. This directory will be installed in the Gaim smiley theme directory ($HOME/.gaim/smileys/). This directory will contain a file called `theme' that specifies the theme metadata and image files that are used by the theme. The format of the `theme' file is as follows.
-Your theme should be contained in a single directory. This directory will be installed in the Gaim smiley theme directory (SME: There should probably be a $HOME/.gaim/smileys/ that the theme could go in too.). This directory will contain a file called `theme' that specifies the theme and image (SME: And possibly sound) files that are used by the theme. The format of the `theme' file is as follows.
-
The beginning of the file contains some metainformation about the theme in the format
Key=Value
@@ -19,10 +17,16 @@
Author - The author's name
Following this meta-information are "sml" groups. A "sml" group is a group of smileys that will be shown together. For example, each protocol has its own "sml" group (MSN, Yahoo, Gadu-Gadu, etc.). The name of the group is surrounded in square brackets, and each line beneath it (until the next sml group or the end of the file) defines a smiley.
-Each line of the group starts with a filename of the icon (SME: Or sound?) followed by a space-delimited list of the characters that represent it.
+Each line of the group starts with a filename of the icon followed by a space-delimited list of the characters that represent it.
Example:
[AIM/ICQ]
smiley.png :) :-)
In the smiley selector UI, each icon will only be shown once, and the first string representing it will be used. To keep a smiley out of the selector altogether, make the first two characters of the line "! " followed by the filename and emoticons.
+
+As of 2.0.0beta2, spaces and backslashes in the "list of characters" (see above) must be escaped by prepending them with a backslash. For example, to define a smiley that is represented by ":-/" and ":-\", use:
+
+[AIM/ICQ]
+think.png :-/ :-\\
+
Modified: branches/soc-2006-file-loggers/plugins/tcl/Makefile.am
===================================================================
--- branches/soc-2006-file-loggers/plugins/tcl/Makefile.am 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/plugins/tcl/Makefile.am 2006-06-17 02:11:13 UTC (rev 16272)
@@ -4,7 +4,8 @@
plugin_LTLIBRARIES = tcl.la
-tcl_la_SOURCES = tcl.c tcl_glib.c tcl_glib.h tcl_cmds.c tcl_signals.c tcl_gaim.h
+tcl_la_SOURCES = tcl.c tcl_glib.c tcl_glib.h tcl_cmds.c tcl_signals.c tcl_gaim.h \
+ tcl_ref.c
EXTRA_DIST = signal-test.tcl Makefile.mingw
Modified: branches/soc-2006-file-loggers/plugins/tcl/Makefile.mingw
===================================================================
--- branches/soc-2006-file-loggers/plugins/tcl/Makefile.mingw 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/plugins/tcl/Makefile.mingw 2006-06-17 02:11:13 UTC (rev 16272)
@@ -63,6 +63,7 @@
C_SRC = tcl.c \
tcl_cmds.c \
tcl_glib.c \
+ tcl_ref.c \
tcl_signals.c
Modified: branches/soc-2006-file-loggers/plugins/tcl/tcl.c
===================================================================
--- branches/soc-2006-file-loggers/plugins/tcl/tcl.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/plugins/tcl/tcl.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -50,6 +50,15 @@
Tcl_Interp *interp;
};
+GaimStringref *GaimTclRefAccount;
+GaimStringref *GaimTclRefConnection;
+GaimStringref *GaimTclRefConversation;
+GaimStringref *GaimTclRefPointer;
+GaimStringref *GaimTclRefPresence;
+GaimStringref *GaimTclRefStatus;
+GaimStringref *GaimTclRefStatusAttr;
+GaimStringref *GaimTclRefStatusType;
+
static GHashTable *tcl_plugins = NULL;
GaimPlugin *_tcl_plugin;
@@ -123,8 +132,12 @@
Tcl_CreateObjCommand(interp, "::gaim::debug", tcl_cmd_debug, (ClientData)NULL, NULL);
Tcl_CreateObjCommand(interp, "::gaim::notify", tcl_cmd_notify, (ClientData)NULL, NULL);
Tcl_CreateObjCommand(interp, "::gaim::prefs", tcl_cmd_prefs, (ClientData)NULL, NULL);
+ Tcl_CreateObjCommand(interp, "::gaim::presence", tcl_cmd_presence, (ClientData)NULL, NULL);
Tcl_CreateObjCommand(interp, "::gaim::send_im", tcl_cmd_send_im, (ClientData)NULL, NULL);
Tcl_CreateObjCommand(interp, "::gaim::signal", tcl_cmd_signal, (ClientData)NULL, NULL);
+ Tcl_CreateObjCommand(interp, "::gaim::status", tcl_cmd_status, (ClientData)NULL, NULL);
+ Tcl_CreateObjCommand(interp, "::gaim::status_attr", tcl_cmd_status_attr, (ClientData)NULL, NULL);
+ Tcl_CreateObjCommand(interp, "::gaim::status_type", tcl_cmd_status_type, (ClientData)NULL, NULL);
Tcl_CreateObjCommand(interp, "::gaim::unload", tcl_cmd_unload, (ClientData)NULL, NULL);
return 0;
@@ -329,6 +342,17 @@
return FALSE;
tcl_glib_init();
tcl_signal_init();
+ gaim_tcl_ref_init();
+
+ GaimTclRefAccount = gaim_stringref_new("Account");
+ GaimTclRefConnection = gaim_stringref_new("Connection");
+ GaimTclRefConversation = gaim_stringref_new("Conversation");
+ GaimTclRefPointer = gaim_stringref_new("Pointer");
+ GaimTclRefPresence = gaim_stringref_new("Presence");
+ GaimTclRefStatus = gaim_stringref_new("Status");
+ GaimTclRefStatusAttr = gaim_stringref_new("StatusAttr");
+ GaimTclRefStatusType = gaim_stringref_new("StatusType");
+
tcl_plugins = g_hash_table_new(g_direct_hash, g_direct_equal);
#ifdef HAVE_TK
@@ -343,6 +367,15 @@
g_hash_table_destroy(tcl_plugins);
tcl_plugins = NULL;
+ gaim_stringref_unref(GaimTclRefAccount);
+ gaim_stringref_unref(GaimTclRefConnection);
+ gaim_stringref_unref(GaimTclRefConversation);
+ gaim_stringref_unref(GaimTclRefPointer);
+ gaim_stringref_unref(GaimTclRefPresence);
+ gaim_stringref_unref(GaimTclRefStatus);
+ gaim_stringref_unref(GaimTclRefStatusAttr);
+ gaim_stringref_unref(GaimTclRefStatusType);
+
return TRUE;
}
Modified: branches/soc-2006-file-loggers/plugins/tcl/tcl_cmds.c
===================================================================
--- branches/soc-2006-file-loggers/plugins/tcl/tcl_cmds.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/plugins/tcl/tcl_cmds.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -35,61 +35,91 @@
#include "tcl_gaim.h"
-static gboolean tcl_validate_account(GaimAccount *account, Tcl_Interp *interp);
-static gboolean tcl_validate_conversation(GaimConversation *convo, Tcl_Interp *interp);
-static gboolean tcl_validate_gc(GaimConnection *gc);
+static GaimAccount *tcl_validate_account(Tcl_Obj *obj, Tcl_Interp *interp);
+static GaimConversation *tcl_validate_conversation(Tcl_Obj *obj, Tcl_Interp *interp);
+static GaimConnection *tcl_validate_gc(Tcl_Obj *obj, Tcl_Interp *interp);
-static gboolean tcl_validate_account(GaimAccount *account, Tcl_Interp *interp)
+static GaimAccount *tcl_validate_account(Tcl_Obj *obj, Tcl_Interp *interp)
{
+ GaimAccount *account;
GList *cur;
+
+ account = gaim_tcl_ref_get(interp, obj, GaimTclRefAccount);
+
+ if (account == NULL)
+ return NULL;
+
for (cur = gaim_accounts_get_all(); cur != NULL; cur = g_list_next(cur)) {
if (account == cur->data)
- return TRUE;
+ return account;
}
if (interp != NULL)
Tcl_SetStringObj(Tcl_GetObjResult(interp), "invalid account", -1);
- return FALSE;
+ return NULL;
}
-static gboolean tcl_validate_conversation(GaimConversation *convo, Tcl_Interp *interp)
+static GaimConversation *tcl_validate_conversation(Tcl_Obj *obj, Tcl_Interp *interp)
{
+ GaimConversation *convo;
GList *cur;
+ convo = gaim_tcl_ref_get(interp, obj, GaimTclRefConversation);
+
+ if (convo == NULL)
+ return NULL;
+
for (cur = gaim_get_conversations(); cur != NULL; cur = g_list_next(cur)) {
if (convo == cur->data)
- return TRUE;
+ return convo;
}
if (interp != NULL)
Tcl_SetStringObj(Tcl_GetObjResult(interp), "invalid account", -1);
- return FALSE;
+ return NULL;
}
-static gboolean tcl_validate_gc(GaimConnection *gc)
+static GaimConnection *tcl_validate_gc(Tcl_Obj *obj, Tcl_Interp *interp)
{
+ GaimConnection *gc;
GList *cur;
+
+ gc = gaim_tcl_ref_get(interp, obj, GaimTclRefConnection);
+
+ if (gc == NULL)
+ return NULL;
+
for (cur = gaim_connections_get_all(); cur != NULL; cur = g_list_next(cur)) {
if (gc == cur->data)
- return TRUE;
+ return gc;
}
- return FALSE;
+ return NULL;
}
int tcl_cmd_account(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
Tcl_Obj *result = Tcl_GetObjResult(interp), *list, *elem;
- const char *cmds[] = { "alias", "connect", "connection", "disconnect", "find",
- "handle", "isconnected", "list",
- "protocol", "username", NULL };
- enum { CMD_ACCOUNT_ALIAS, CMD_ACCOUNT_CONNECT, CMD_ACCOUNT_CONNECTION,
- CMD_ACCOUNT_DISCONNECT, CMD_ACCOUNT_FIND, CMD_ACCOUNT_HANDLE,
- CMD_ACCOUNT_ISCONNECTED, CMD_ACCOUNT_LIST,
- CMD_ACCOUNT_PROTOCOL, CMD_ACCOUNT_USERNAME } cmd;
+ const char *cmds[] = { "alias", "connect", "connection", "disconnect",
+ "enabled", "find", "handle", "isconnected",
+ "list", "presence", "protocol", "status",
+ "status_type", "status_types", "username",
+ NULL };
+ enum { CMD_ACCOUNT_ALIAS,
+ CMD_ACCOUNT_CONNECT, CMD_ACCOUNT_CONNECTION,
+ CMD_ACCOUNT_DISCONNECT, CMD_ACCOUNT_ENABLED, CMD_ACCOUNT_FIND,
+ CMD_ACCOUNT_HANDLE, CMD_ACCOUNT_ISCONNECTED, CMD_ACCOUNT_LIST,
+ CMD_ACCOUNT_PRESENCE, CMD_ACCOUNT_PROTOCOL, CMD_ACCOUNT_STATUS,
+ CMD_ACCOUNT_STATUS_TYPE, CMD_ACCOUNT_STATUS_TYPES,
+ CMD_ACCOUNT_USERNAME } cmd;
const char *listopts[] = { "-all", "-online", NULL };
enum { CMD_ACCOUNTLIST_ALL, CMD_ACCOUNTLIST_ONLINE } listopt;
const char *alias;
- GList *cur;
+ const GList *cur;
GaimAccount *account;
+ GaimStatus *status;
+ GaimStatusType *status_type;
+ GaimValue *value;
+ char *attr_id;
int error;
+ int b, i;
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?");
@@ -105,8 +135,7 @@
Tcl_WrongNumArgs(interp, 2, objv, "account");
return TCL_ERROR;
}
- error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account);
- if (error || !tcl_validate_account(account, interp))
+ if ((account = tcl_validate_account(objv[2], interp)) == NULL)
return TCL_ERROR;
alias = gaim_account_get_alias(account);
Tcl_SetStringObj(result, alias ? (char *)alias : "", -1);
@@ -116,40 +145,61 @@
Tcl_WrongNumArgs(interp, 2, objv, "account");
return TCL_ERROR;
}
- error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account);
- if (error || !tcl_validate_account(account, interp))
+ if ((account = tcl_validate_account(objv[2], interp)) == NULL)
return TCL_ERROR;
if (!gaim_account_is_connected(account))
gaim_account_connect(account);
- Tcl_SetIntObj(result, (int)gaim_account_get_connection(account));
+ Tcl_SetObjResult(interp,
+ gaim_tcl_ref_new(GaimTclRefConnection,
+ gaim_account_get_connection(account)));
break;
case CMD_ACCOUNT_CONNECTION:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "account");
return TCL_ERROR;
}
- error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account);
- if (error || !tcl_validate_account(account, interp))
+
+ if ((account = tcl_validate_account(objv[2], interp)) == NULL)
return TCL_ERROR;
- Tcl_SetIntObj(result, (int)gaim_account_get_connection(account));
+ Tcl_SetObjResult(interp,
+ gaim_tcl_ref_new(GaimTclRefConnection,
+ gaim_account_get_connection(account)));
break;
case CMD_ACCOUNT_DISCONNECT:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "account");
return TCL_ERROR;
}
- error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account);
- if (error || !tcl_validate_account(account, interp))
+ if ((account = tcl_validate_account(objv[2], interp)) == NULL)
return TCL_ERROR;
gaim_account_disconnect(account);
break;
+ case CMD_ACCOUNT_ENABLED:
+ if (objc != 3 && objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "account ?enabled?");
+ return TCL_ERROR;
+ }
+ if ((account = tcl_validate_account(objv[2], interp)) == NULL)
+ return TCL_ERROR;
+ if (objc == 3) {
+ Tcl_SetBooleanObj(result,
+ gaim_account_get_enabled(account,
+ gaim_core_get_ui()));
+ } else {
+ if ((error = Tcl_GetBooleanFromObj(interp, objv[3], &b)) != TCL_OK)
+ return TCL_ERROR;
+ gaim_account_set_enabled(account, gaim_core_get_ui(), b);
+ }
+ break;
case CMD_ACCOUNT_FIND:
if (objc != 4) {
Tcl_WrongNumArgs(interp, 2, objv, "username protocol");
return TCL_ERROR;
}
- Tcl_SetIntObj(result, (int)gaim_accounts_find(Tcl_GetString(objv[2]),
- Tcl_GetString(objv[3])));
+ account = gaim_accounts_find(Tcl_GetString(objv[2]),
+ Tcl_GetString(objv[3]));
+ Tcl_SetObjResult(interp,
+ gaim_tcl_ref_new(GaimTclRefAccount, account));
break;
case CMD_ACCOUNT_HANDLE:
if (objc != 2) {
@@ -163,8 +213,7 @@
Tcl_WrongNumArgs(interp, 2, objv, "account");
return TCL_ERROR;
}
- error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account);
- if (error || !tcl_validate_account(account, interp))
+ if ((account = tcl_validate_account(objv[2], interp)) == NULL)
return TCL_ERROR;
Tcl_SetBooleanObj(result, gaim_account_is_connected(account));
break;
@@ -183,28 +232,140 @@
account = cur->data;
if (listopt == CMD_ACCOUNTLIST_ONLINE && !gaim_account_is_connected(account))
continue;
- elem = Tcl_NewIntObj((int)account);
+ elem = gaim_tcl_ref_new(GaimTclRefAccount, account);
Tcl_ListObjAppendElement(interp, list, elem);
}
Tcl_SetObjResult(interp, list);
break;
+ case CMD_ACCOUNT_PRESENCE:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "account");
+ return TCL_ERROR;
+ }
+ if ((account = tcl_validate_account(objv[2], interp)) == NULL)
+ return TCL_ERROR;
+ Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefPresence,
+ gaim_account_get_presence(account)));
+ break;
case CMD_ACCOUNT_PROTOCOL:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "account");
return TCL_ERROR;
}
- error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account);
- if (error || !tcl_validate_account(account, interp))
+ if ((account = tcl_validate_account(objv[2], interp)) == NULL)
return TCL_ERROR;
Tcl_SetStringObj(result, (char *)gaim_account_get_protocol_id(account), -1);
break;
+ case CMD_ACCOUNT_STATUS:
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "account ?status_id name value ...?");
+ return TCL_ERROR;
+ }
+ if ((account = tcl_validate_account(objv[2], interp)) == NULL)
+ return TCL_ERROR;
+ if (objc == 3) {
+ Tcl_SetObjResult(interp,
+ gaim_tcl_ref_new(GaimTclRefStatus,
+ gaim_account_get_active_status(account)));
+ } else {
+ GList *l = NULL;
+ if (objc % 2) {
+ Tcl_SetStringObj(result, "name without value setting status", -1);
+ return TCL_ERROR;
+ }
+ status = gaim_account_get_status(account, Tcl_GetString(objv[3]));
+ if (status == NULL) {
+ Tcl_SetStringObj(result, "invalid status for account", -1);
+ return TCL_ERROR;
+ }
+ for (i = 4; i < objc; i += 2) {
+ attr_id = Tcl_GetString(objv[i]);
+ value = gaim_status_get_attr_value(status, attr_id);
+ if (value == NULL) {
+ Tcl_SetStringObj(result, "invalid attribute for account", -1);
+ return TCL_ERROR;
+ }
+ switch (gaim_value_get_type(value)) {
+ case GAIM_TYPE_BOOLEAN:
+ error = Tcl_GetBooleanFromObj(interp, objv[i + 1], &b);
+ if (error != TCL_OK)
+ return error;
+ l = g_list_append(l, attr_id);
+ l = g_list_append(l, GINT_TO_POINTER(b));
+ break;
+ case GAIM_TYPE_INT:
+ error = Tcl_GetIntFromObj(interp, objv[i + 1], &b);
+ if (error != TCL_OK)
+ return error;
+ l = g_list_append(l, attr_id);
+ l = g_list_append(l, GINT_TO_POINTER(b));
+ break;
+ case GAIM_TYPE_STRING:
+ l = g_list_append(l, attr_id);
+ l = g_list_append(l, Tcl_GetString(objv[i + 1]));
+ break;
+ default:
+ Tcl_SetStringObj(result, "unknown GaimValue type", -1);
+ return TCL_ERROR;
+ }
+ }
+ gaim_account_set_status_list(account, Tcl_GetString(objv[3]), TRUE, l);
+ g_list_free(l);
+ }
+ break;
+ case CMD_ACCOUNT_STATUS_TYPE:
+ if (objc != 4 && objc != 5) {
+ Tcl_WrongNumArgs(interp, 2, objv, "account ?statustype? ?-primitive primitive?");
+ return TCL_ERROR;
+ }
+ if ((account = tcl_validate_account(objv[2], interp)) == NULL)
+ return TCL_ERROR;
+ if (objc == 4) {
+ status_type = gaim_account_get_status_type(account,
+ Tcl_GetString(objv[3]));
+ } else {
+ GaimStatusPrimitive primitive;
+ if (strcmp(Tcl_GetString(objv[3]), "-primitive")) {
+ Tcl_SetStringObj(result, "bad option \"", -1);
+ Tcl_AppendObjToObj(result, objv[3]);
+ Tcl_AppendToObj(result,
+ "\": should be -primitive", -1);
+ return TCL_ERROR;
+ }
+ primitive = gaim_primitive_get_type_from_id(Tcl_GetString(objv[4]));
+ status_type = gaim_account_get_status_type_with_primitive(account,
+ primitive);
+ }
+ if (status_type == NULL) {
+ Tcl_SetStringObj(result, "status type not found", -1);
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp,
+ gaim_tcl_ref_new(GaimTclRefStatusType,
+ status_type));
+ break;
+ case CMD_ACCOUNT_STATUS_TYPES:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "account");
+ return TCL_ERROR;
+ }
+ if ((account = tcl_validate_account(objv[2], interp)) == NULL)
+ return TCL_ERROR;
+ list = Tcl_NewListObj(0, NULL);
+ for (cur = gaim_account_get_status_types(account); cur != NULL;
+ cur = g_list_next(cur)) {
+ Tcl_ListObjAppendElement(interp, list,
+ gaim_tcl_ref_new(GaimTclRefStatusType,
+ cur->data));
+ }
+ Tcl_SetObjResult(interp, list);
+ break;
case CMD_ACCOUNT_USERNAME:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "account");
return TCL_ERROR;
}
- error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account);
- if (error || !tcl_validate_account(account, interp))
+ if ((account = tcl_validate_account(objv[2], interp)) == NULL)
return TCL_ERROR;
Tcl_SetStringObj(result, (char *)gaim_account_get_username(account), -1);
break;
@@ -227,10 +388,8 @@
type = Tcl_GetString(elems[0]);
name = Tcl_GetString(elems[1]);
- if (Tcl_GetIntFromObj(interp, elems[2], (int *)&account) != TCL_OK)
+ if ((account = tcl_validate_account(elems[2], interp)) == NULL)
return NULL;
- if (!tcl_validate_account(account, interp))
- return NULL;
if (!strcmp(type, "buddy")) {
node = (GaimBlistNode *)gaim_find_buddy(account, name);
@@ -301,15 +460,11 @@
Tcl_SetStringObj(result, "invalid buddy", -1);
return TCL_ERROR;
}
- if ((error = Tcl_GetIntFromObj(interp, elems[2], (int *)&account)) != TCL_OK)
+ if ((account = tcl_validate_account(elems[2], interp)) == NULL)
return TCL_ERROR;
- if (!tcl_validate_account(account, interp))
- return TCL_ERROR;
serv_get_info(gaim_account_get_connection(account), Tcl_GetString(elems[1]));
} else {
- if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account)) != TCL_OK)
- return error;
- if (!tcl_validate_account(account, interp))
+ if ((account = tcl_validate_account(objv[2], interp)) == NULL)
return TCL_ERROR;
serv_get_info(gaim_account_get_connection(account), Tcl_GetString(objv[3]));
}
@@ -351,7 +506,7 @@
tclbud = Tcl_NewListObj(0, NULL);
Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj("buddy", -1));
Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj(bud->name, -1));
- Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewIntObj((int)bud->account));
+ Tcl_ListObjAppendElement(interp, tclbud, gaim_tcl_ref_new(GaimTclRefAccount, bud->account));
Tcl_ListObjAppendElement(interp, tclcontactlist, tclbud);
}
if (count) {
@@ -368,7 +523,7 @@
tclbud = Tcl_NewListObj(0, NULL);
Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj("chat", -1));
Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj(cnode->alias, -1));
- Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewIntObj((int)cnode->account));
+ Tcl_ListObjAppendElement(interp, tclbud, gaim_tcl_ref_new(GaimTclRefAccount, cnode->account));
Tcl_ListObjAppendElement(interp, tclgrouplist, tclbud);
break;
default:
@@ -409,23 +564,19 @@
Tcl_WrongNumArgs(interp, 2, objv, "gc");
return TCL_ERROR;
}
- error = Tcl_GetIntFromObj(interp, objv[2], (int *)&gc);
- if (error || !tcl_validate_gc(gc)) {
- Tcl_SetStringObj(result, "invalid gc", -1);
+ if ((gc = tcl_validate_gc(objv[2], interp)) == NULL)
return TCL_ERROR;
- }
- Tcl_SetIntObj(result, (int)gaim_connection_get_account(gc));
+ Tcl_SetObjResult(interp,
+ gaim_tcl_ref_new(GaimTclRefAccount,
+ gaim_connection_get_account(gc)));
break;
case CMD_CONN_DISPLAYNAME:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "gc");
return TCL_ERROR;
}
- error = Tcl_GetIntFromObj(interp, objv[2], (int *)&gc);
- if (error || !tcl_validate_gc(gc)) {
- Tcl_SetStringObj(result, "invalid gc", -1);
+ if ((gc = tcl_validate_gc(objv[2], interp)) == NULL)
return TCL_ERROR;
- }
Tcl_SetStringObj(result, (char *)gaim_connection_get_display_name(gc), -1);
break;
case CMD_CONN_HANDLE:
@@ -442,7 +593,7 @@
}
list = Tcl_NewListObj(0, NULL);
for (cur = gaim_connections_get_all(); cur != NULL; cur = g_list_next(cur)) {
- elem = Tcl_NewIntObj((int)cur->data);
+ elem = gaim_tcl_ref_new(GaimTclRefConnection, cur->data);
Tcl_ListObjAppendElement(interp, list, elem);
}
Tcl_SetObjResult(interp, list);
@@ -483,15 +634,12 @@
return TCL_ERROR;
}
account = NULL;
- if ((error = Tcl_GetIntFromObj(interp, objv[2],
- (int *)&account)) != TCL_OK)
- return error;
- if (!tcl_validate_account(account, interp))
+ if ((account = tcl_validate_account(objv[2], interp)) == NULL)
return TCL_ERROR;
convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_ANY,
Tcl_GetString(objv[3]),
account);
- Tcl_SetIntObj(result, (int)convo);
+ Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefConversation, convo));
break;
case CMD_CONV_HANDLE:
if (objc != 2) {
@@ -503,7 +651,7 @@
case CMD_CONV_LIST:
list = Tcl_NewListObj(0, NULL);
for (cur = gaim_get_conversations(); cur != NULL; cur = g_list_next(cur)) {
- elem = Tcl_NewIntObj((int)cur->data);
+ elem = gaim_tcl_ref_new(GaimTclRefConversation, cur->data);
Tcl_ListObjAppendElement(interp, list, elem);
}
Tcl_SetObjResult(interp, list);
@@ -538,24 +686,20 @@
Tcl_WrongNumArgs(interp, 2, objv, "?options? account name");
return TCL_ERROR;
}
- if ((error = Tcl_GetIntFromObj(interp, objv[argsused++], (int *)&account)) != TCL_OK)
- return error;
- if (!tcl_validate_account(account, interp))
+ if ((account = tcl_validate_account(objv[argsused++], interp)) == NULL)
return TCL_ERROR;
convo = gaim_conversation_new(type, account, Tcl_GetString(objv[argsused]));
- Tcl_SetIntObj(result, (int)convo);
+ Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefConversation, convo));
break;
case CMD_CONV_WRITE:
if (objc != 6) {
Tcl_WrongNumArgs(interp, 2, objv, "conversation style from what");
return TCL_ERROR;
}
- if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&convo)) != TCL_OK)
- return error;
+ if ((convo = tcl_validate_conversation(objv[2], interp)) == NULL)
+ return TCL_ERROR;
if ((error = Tcl_GetIndexFromObj(interp, objv[3], styles, "style", 0, (int *)&style)) != TCL_OK)
return error;
- if (!tcl_validate_conversation(convo, interp))
- return TCL_ERROR;
from = Tcl_GetString(objv[4]);
what = Tcl_GetString(objv[5]);
@@ -799,25 +943,224 @@
return TCL_OK;
}
+int tcl_cmd_presence(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
+{
+ const char *cmds[] = { "account", "active_status", "available",
+ "chat_user", "context", "conversation", "idle",
+ "login", "online", "status", "statuses", NULL };
+ enum { CMD_PRESENCE_ACCOUNT, CMD_PRESENCE_ACTIVE_STATUS,
+ CMD_PRESENCE_AVAILABLE, CMD_PRESENCE_CHAT_USER,
+ CMD_PRESENCE_CONTEXT, CMD_PRESENCE_CONVERSATION,
+ CMD_PRESENCE_IDLE, CMD_PRESENCE_LOGIN, CMD_PRESENCE_ONLINE,
+ CMD_PRESENCE_STATUS, CMD_PRESENCE_STATUSES } cmd;
+ Tcl_Obj *result = Tcl_GetObjResult(interp);
+ Tcl_Obj *list, *elem;
+ GaimPresence *presence;
+ const GList *cur;
+ int error, idle, idle_time, login_time;
+
+ if (objc < 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?");
+ return TCL_ERROR;
+ }
+
+ if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK)
+ return error;
+
+ switch (cmd) {
+ case CMD_PRESENCE_ACCOUNT:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "presence");
+ return TCL_ERROR;
+ }
+ if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL)
+ return TCL_ERROR;
+ Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefAccount,
+ gaim_presence_get_account(presence)));
+ break;
+ case CMD_PRESENCE_ACTIVE_STATUS:
+ if (objc != 3 && objc != 4 && objc != 5) {
+ Tcl_WrongNumArgs(interp, 2, objv, "presence [?status_id? | ?-primitive primitive?]");
+ return TCL_ERROR;
+ }
+ if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL)
+ return TCL_ERROR;
+ if (objc == 3) {
+ Tcl_SetObjResult(interp,
+ gaim_tcl_ref_new(GaimTclRefStatus,
+ gaim_presence_get_active_status(presence)));
+ } else if (objc == 4) {
+ Tcl_SetBooleanObj(result,
+ gaim_presence_is_status_active(presence,
+ Tcl_GetString(objv[3])));
+ } else {
+ GaimStatusPrimitive primitive;
+ if (strcmp(Tcl_GetString(objv[3]), "-primitive")) {
+ Tcl_SetStringObj(result, "bad option \"", -1);
+ Tcl_AppendObjToObj(result, objv[3]);
+ Tcl_AppendToObj(result,
+ "\": should be -primitive", -1);
+ return TCL_ERROR;
+ }
+ primitive = gaim_primitive_get_type_from_id(Tcl_GetString(objv[4]));
+ if (primitive == GAIM_STATUS_UNSET) {
+ Tcl_SetStringObj(result, "invalid primitive ", -1);
+ Tcl_AppendObjToObj(result, objv[4]);
+ return TCL_ERROR;
+ }
+ Tcl_SetBooleanObj(result, gaim_presence_is_status_primitive_active(presence, primitive));
+ break;
+ }
+ break;
+ case CMD_PRESENCE_AVAILABLE:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "presence");
+ return TCL_ERROR;
+ }
+ if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL)
+ return TCL_ERROR;
+ Tcl_SetBooleanObj(result, gaim_presence_is_available(presence));
+ break;
+ case CMD_PRESENCE_CHAT_USER:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "presence");
+ return TCL_ERROR;
+ }
+ if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL)
+ return TCL_ERROR;
+ Tcl_SetStringObj(result, gaim_presence_get_chat_user(presence), -1);
+ break;
+ case CMD_PRESENCE_CONTEXT:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "presence");
+ return TCL_ERROR;
+ }
+ if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL)
+ return TCL_ERROR;
+ switch (gaim_presence_get_context(presence)) {
+ case GAIM_PRESENCE_CONTEXT_UNSET:
+ Tcl_SetStringObj(result, "unset", -1);
+ break;
+ case GAIM_PRESENCE_CONTEXT_ACCOUNT:
+ Tcl_SetStringObj(result, "account", -1);
+ break;
+ case GAIM_PRESENCE_CONTEXT_CONV:
+ Tcl_SetStringObj(result, "conversation", -1);
+ break;
+ case GAIM_PRESENCE_CONTEXT_BUDDY:
+ Tcl_SetStringObj(result, "buddy", -1);
+ break;
+ }
+ break;
+ case CMD_PRESENCE_CONVERSATION:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "presence");
+ return TCL_ERROR;
+ }
+ if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL)
+ return TCL_ERROR;
+ Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefConversation,
+ gaim_presence_get_conversation(presence)));
+ break;
+ case CMD_PRESENCE_IDLE:
+ if (objc < 3 || objc > 5) {
+ Tcl_WrongNumArgs(interp, 2, objv, "presence ?idle? ?time?");
+ return TCL_ERROR;
+ }
+ if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL)
+ return TCL_ERROR;
+ if (objc == 3) {
+ if (gaim_presence_is_idle(presence)) {
+ idle_time = gaim_presence_get_idle_time (presence);
+ Tcl_SetIntObj(result, idle_time);
+ } else {
+ result = Tcl_NewListObj(0, NULL);
+ Tcl_SetObjResult(interp, result);
+ }
+ break;
+ }
+ if ((error = Tcl_GetBooleanFromObj(interp, objv[3], &idle)) != TCL_OK)
+ return TCL_ERROR;
+ if (objc == 4) {
+ gaim_presence_set_idle(presence, idle, time(NULL));
+ } else if (objc == 5) {
+ if ((error = Tcl_GetIntFromObj(interp,
+ objv[4],
+ &idle_time)) != TCL_OK)
+ return TCL_ERROR;
+ gaim_presence_set_idle(presence, idle, idle_time);
+ }
+ break;
+ case CMD_PRESENCE_LOGIN:
+ if (objc != 3 && objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "presence ?time?");
+ return TCL_ERROR;
+ }
+ if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL)
+ return TCL_ERROR;
+ if (objc == 3) {
+ Tcl_SetIntObj(result, gaim_presence_get_login_time(presence));
+ } else {
+ if ((error == Tcl_GetIntFromObj(interp,
+ objv[3],
+ &login_time)) != TCL_OK)
+ return TCL_ERROR;
+ gaim_presence_set_login_time(presence, login_time);
+ }
+ break;
+ case CMD_PRESENCE_ONLINE:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "presence");
+ return TCL_ERROR;
+ }
+ if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL)
+ return TCL_ERROR;
+ Tcl_SetBooleanObj(result, gaim_presence_is_online(presence));
+ break;
+ case CMD_PRESENCE_STATUS:
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "presence status_id");
+ return TCL_ERROR;
+ }
+ if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL)
+ return TCL_ERROR;
+ Tcl_SetObjResult(interp,
+ gaim_tcl_ref_new(GaimTclRefStatus,
+ gaim_presence_get_status(presence,
+ Tcl_GetString(objv[3]))));
+ break;
+ case CMD_PRESENCE_STATUSES:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "presence");
+ return TCL_ERROR;
+ }
+ if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL)
+ return TCL_ERROR;
+ list = Tcl_NewListObj(0, NULL);
+ for (cur = gaim_presence_get_statuses(presence); cur != NULL;
+ cur = g_list_next(cur)) {
+ elem = gaim_tcl_ref_new(GaimTclRefStatus, cur->data);
+ Tcl_ListObjAppendElement(interp, list, elem);
+ }
+ Tcl_SetObjResult(interp, list);
+ break;
+ }
+
+ return TCL_OK;
+}
+
int tcl_cmd_send_im(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
GaimConnection *gc;
char *who, *text;
- int error;
- Tcl_Obj *result;
if (objc != 4) {
Tcl_WrongNumArgs(interp, 1, objv, "gc who text");
return TCL_ERROR;
}
- if ((error = Tcl_GetIntFromObj(interp, objv[1], (int *)&gc)) != TCL_OK)
- return error;
- if (!tcl_validate_gc(gc)) {
- result = Tcl_GetObjResult(interp);
- Tcl_SetStringObj(result, "invalid gc", -1);
+ if ((gc = tcl_validate_gc(objv[1], interp)) == NULL)
return TCL_ERROR;
- }
who = Tcl_GetString(objv[2]);
text = Tcl_GetString(objv[3]);
@@ -856,6 +1199,7 @@
return error;
}
handler->signal = objv[3];
+ Tcl_IncrRefCount(handler->signal);
handler->args = objv[4];
handler->proc = objv[5];
handler->interp = interp;
@@ -868,7 +1212,7 @@
break;
case CMD_SIGNAL_DISCONNECT:
if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "signal");
+ Tcl_WrongNumArgs(interp, 2, objv, "instance signal");
return TCL_ERROR;
}
if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&instance)) != TCL_OK)
@@ -880,6 +1224,265 @@
return TCL_OK;
}
+int tcl_cmd_status(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
+{
+ const char *cmds[] = { "attr", "type", NULL };
+ enum { CMD_STATUS_ATTR, CMD_STATUS_TYPE } cmd;
+ Tcl_Obj *result = Tcl_GetObjResult(interp);
+ GaimStatus *status;
+ GaimStatusType *status_type;
+ GaimValue *value;
+ const char *attr;
+ int error, v;
+
+ if (objc < 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?");
+ return TCL_ERROR;
+ }
+
+ if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK)
+ return error;
+
+ switch (cmd) {
+ case CMD_STATUS_ATTR:
+ if (objc != 4 && objc != 5) {
+ Tcl_WrongNumArgs(interp, 2, objv, "status attr_id ?value?");
+ return TCL_ERROR;
+ }
+ if ((status = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatus)) == NULL)
+ return TCL_ERROR;
+ attr = Tcl_GetString(objv[3]);
+ value = gaim_status_get_attr_value(status, attr);
+ if (value == NULL) {
+ Tcl_SetStringObj(result, "no such attribute", -1);
+ return TCL_ERROR;
+ }
+ switch (gaim_value_get_type(value)) {
+ case GAIM_TYPE_BOOLEAN:
+ if (objc == 4) {
+ Tcl_SetBooleanObj(result, gaim_value_get_boolean(value));
+ } else {
+ if ((error = Tcl_GetBooleanFromObj(interp, objv[4], &v)) != TCL_OK)
+ return error;
+ gaim_status_set_attr_boolean(status, attr, v);
+ }
+ break;
+ case GAIM_TYPE_INT:
+ if (objc == 4) {
+ Tcl_SetIntObj(result, gaim_value_get_int(value));
+ } else {
+ if ((error = Tcl_GetIntFromObj(interp, objv[4], &v)) != TCL_OK)
+ return error;
+ gaim_status_set_attr_int(status, attr, v );
+ }
+ break;
+ case GAIM_TYPE_STRING:
+ if (objc == 4)
+ Tcl_SetStringObj(result, gaim_value_get_string(value), -1);
+ else
+ gaim_status_set_attr_string(status, attr, Tcl_GetString(objv[4]));
+ break;
+ default:
+ Tcl_SetStringObj(result, "attribute has unknown type", -1);
+ return TCL_ERROR;
+ }
+ break;
+ case CMD_STATUS_TYPE:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "status");
+ return TCL_ERROR;
+ }
+ if ((status = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatus)) == NULL)
+ return TCL_ERROR;
+ status_type = gaim_status_get_type(status);
+ Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefStatusType,
+ status_type));
+ break;
+ }
+
+ return TCL_OK;
+}
+
+int tcl_cmd_status_attr(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
+{
+ const char *cmds[] = { "id", "name", NULL };
+ enum { CMD_STATUS_ATTR_ID, CMD_STATUS_ATTR_NAME } cmd;
+ Tcl_Obj *result = Tcl_GetObjResult(interp);
+ GaimStatusAttr *attr;
+ int error;
+
+ if (objc < 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?");
+ return TCL_ERROR;
+ }
+
+ if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK)
+ return error;
+
+ switch (cmd) {
+ case CMD_STATUS_ATTR_ID:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "attr");
+ return TCL_ERROR;
+ }
+ if ((attr = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusAttr)) == NULL)
+ return TCL_ERROR;
+ Tcl_SetStringObj(result, gaim_status_attr_get_id(attr), -1);
+ break;
+ case CMD_STATUS_ATTR_NAME:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "attr");
+ return TCL_ERROR;
+ }
+ if ((attr = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusAttr)) == NULL)
+ return TCL_ERROR;
+ Tcl_SetStringObj(result, gaim_status_attr_get_name(attr), -1);
+ break;
+ }
+
+ return TCL_OK;
+}
+
+int tcl_cmd_status_type(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
+{
+ const char *cmds[] = { "attr", "attrs", "available", "exclusive", "id",
+ "independent", "name", "primary_attr",
+ "primitive", "saveable", "user_settable",
+ NULL };
+ enum { CMD_STATUS_TYPE_ATTR, CMD_STATUS_TYPE_ATTRS,
+ CMD_STATUS_TYPE_AVAILABLE, CMD_STATUS_TYPE_EXCLUSIVE,
+ CMD_STATUS_TYPE_ID, CMD_STATUS_TYPE_INDEPENDENT,
+ CMD_STATUS_TYPE_NAME, CMD_STATUS_TYPE_PRIMARY_ATTR,
+ CMD_STATUS_TYPE_PRIMITIVE, CMD_STATUS_TYPE_SAVEABLE,
+ CMD_STATUS_TYPE_USER_SETTABLE } cmd;
+ Tcl_Obj *result = Tcl_GetObjResult(interp);
+ GaimStatusType *status_type;
+ Tcl_Obj *list, *elem;
+ const GList *cur;
+ int error;
+
+ if (objc < 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?");
+ return TCL_ERROR;
+ }
+
+ if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK)
+ return error;
+
+ switch (cmd) {
+ case CMD_STATUS_TYPE_AVAILABLE:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "statustype");
+ return TCL_ERROR;
+ }
+ if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL)
+ return TCL_ERROR;
+ Tcl_SetBooleanObj(result, gaim_status_type_is_available(status_type));
+ break;
+ case CMD_STATUS_TYPE_ATTR:
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "statustype attr");
+ return TCL_ERROR;
+ }
+ if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL)
+ return TCL_ERROR;
+ Tcl_SetObjResult(interp,
+ gaim_tcl_ref_new(GaimTclRefStatusAttr,
+ gaim_status_type_get_attr(status_type,
+ Tcl_GetStringFromObj(objv[3], NULL))));
+ break;
+ case CMD_STATUS_TYPE_ATTRS:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "statustype");
+ return TCL_ERROR;
+ }
+ if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL)
+ return TCL_ERROR;
+ list = Tcl_NewListObj(0, NULL);
+ for (cur = gaim_status_type_get_attrs(status_type);
+ cur != NULL; cur = g_list_next(cur)) {
+ elem = gaim_tcl_ref_new(GaimTclRefStatusAttr, cur->data);
+ Tcl_ListObjAppendElement(interp, list, elem);
+ }
+ Tcl_SetObjResult(interp, list);
+ break;
+ case CMD_STATUS_TYPE_EXCLUSIVE:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "statustype");
+ return TCL_ERROR;
+ }
+ if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL)
+ return TCL_ERROR;
+ Tcl_SetBooleanObj(result, gaim_status_type_is_exclusive(status_type));
+ break;
+ case CMD_STATUS_TYPE_ID:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "statustype");
+ return TCL_ERROR;
+ }
+ if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL)
+ return TCL_ERROR;
+ Tcl_SetStringObj(result, gaim_status_type_get_id(status_type), -1);
+ break;
+ case CMD_STATUS_TYPE_INDEPENDENT:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "statustype");
+ return TCL_ERROR;
+ }
+ if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL)
+ return TCL_ERROR;
+ Tcl_SetBooleanObj(result, gaim_status_type_is_independent(status_type));
+ break;
+ case CMD_STATUS_TYPE_NAME:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "statustype");
+ return TCL_ERROR;
+ }
+ if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL)
+ return TCL_ERROR;
+ Tcl_SetStringObj(result, gaim_status_type_get_name(status_type), -1);
+ break;
+ case CMD_STATUS_TYPE_PRIMITIVE:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "statustype");
+ return TCL_ERROR;
+ }
+ if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL)
+ return TCL_ERROR;
+ Tcl_SetStringObj(result, gaim_primitive_get_id_from_type(gaim_status_type_get_primitive(status_type)), -1);
+ break;
+ case CMD_STATUS_TYPE_PRIMARY_ATTR:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "statustype");
+ return TCL_ERROR;
+ }
+ if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL)
+ return TCL_ERROR;
+ Tcl_SetStringObj(result, gaim_status_type_get_primary_attr(status_type), -1);
+ break;
+ case CMD_STATUS_TYPE_SAVEABLE:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "statustype");
+ return TCL_ERROR;
+ }
+ if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL)
+ return TCL_ERROR;
+ Tcl_SetBooleanObj(result, gaim_status_type_is_saveable(status_type));
+ break;
+ case CMD_STATUS_TYPE_USER_SETTABLE:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "statustype");
+ return TCL_ERROR;
+ }
+ if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL)
+ return TCL_ERROR;
+ Tcl_SetBooleanObj(result, gaim_status_type_is_user_settable(status_type));
+ break;
+ }
+
+ return TCL_OK;
+}
+
static gboolean unload_self(gpointer data)
{
GaimPlugin *plugin = data;
Modified: branches/soc-2006-file-loggers/plugins/tcl/tcl_gaim.h
===================================================================
--- branches/soc-2006-file-loggers/plugins/tcl/tcl_gaim.h 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/plugins/tcl/tcl_gaim.h 2006-06-17 02:11:13 UTC (rev 16272)
@@ -28,6 +28,7 @@
#include "internal.h"
#include "plugin.h"
#include "value.h"
+#include "stringref.h"
struct tcl_signal_handler {
Tcl_Obj *signal;
@@ -46,6 +47,16 @@
extern GaimPlugin *_tcl_plugin;
+/* Capitalized this way because these are "types" */
+extern GaimStringref *GaimTclRefAccount;
+extern GaimStringref *GaimTclRefConnection;
+extern GaimStringref *GaimTclRefConversation;
+extern GaimStringref *GaimTclRefPointer;
+extern GaimStringref *GaimTclRefPresence;
+extern GaimStringref *GaimTclRefStatus;
+extern GaimStringref *GaimTclRefStatusAttr;
+extern GaimStringref *GaimTclRefStatusType;
+
GaimPlugin *tcl_interp_get_plugin(Tcl_Interp *interp);
void tcl_signal_init(void);
@@ -54,6 +65,10 @@
gboolean tcl_signal_connect(struct tcl_signal_handler *handler);
void tcl_signal_disconnect(void *instance, const char *signal, Tcl_Interp *interp);
+void gaim_tcl_ref_init(void);
+void *gaim_tcl_ref_get(Tcl_Interp *interp, Tcl_Obj *obj, GaimStringref *type);
+Tcl_Obj *gaim_tcl_ref_new(GaimStringref *type, void *value);
+
Tcl_ObjCmdProc tcl_cmd_account;
Tcl_ObjCmdProc tcl_cmd_signal_connect;
Tcl_ObjCmdProc tcl_cmd_buddy;
@@ -63,8 +78,12 @@
Tcl_ObjCmdProc tcl_cmd_debug;
Tcl_ObjCmdProc tcl_cmd_notify;
Tcl_ObjCmdProc tcl_cmd_prefs;
+Tcl_ObjCmdProc tcl_cmd_presence;
Tcl_ObjCmdProc tcl_cmd_send_im;
Tcl_ObjCmdProc tcl_cmd_signal;
+Tcl_ObjCmdProc tcl_cmd_status;
+Tcl_ObjCmdProc tcl_cmd_status_attr;
+Tcl_ObjCmdProc tcl_cmd_status_type;
Tcl_ObjCmdProc tcl_cmd_unload;
#endif /* _GAIM_TCL_GAIM_H_ */
Modified: branches/soc-2006-file-loggers/plugins/tcl/tcl_glib.c
===================================================================
--- branches/soc-2006-file-loggers/plugins/tcl/tcl_glib.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/plugins/tcl/tcl_glib.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -1,7 +1,7 @@
/*
* Tcl/Glib glue
*
- * Copyright (C) 2003, 2004 Ethan Blanton <eblanton@...>
+ * Copyright (C) 2003, 2004, 2006 Ethan Blanton <eblanton@...>
*
* This file is dual-licensed under the two sets of terms below. You may
* use, redistribute, or modify it pursuant to either the set of conditions
@@ -157,8 +157,8 @@
GIOChannel *channel;
GIOCondition cond = 0;
- if (g_hash_table_lookup(tcl_file_handlers, (gpointer)fd))
- tcl_delete_file_handler(fd);
+ if (g_hash_table_lookup(tcl_file_handlers, GINT_TO_POINTER(fd)))
+ tcl_delete_file_handler(fd);
if (mask & TCL_READABLE)
cond |= G_IO_IN;
@@ -176,7 +176,7 @@
tfh->source = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond, tcl_file_callback, tfh, g_free);
g_io_channel_unref(channel);
- g_hash_table_insert(tcl_file_handlers, (gpointer)fd, tfh);
+ g_hash_table_insert(tcl_file_handlers, GINT_TO_POINTER(fd), tfh);
Tcl_ServiceAll();
}
@@ -189,7 +189,7 @@
return;
g_source_remove(tfh->source);
- g_hash_table_remove(tcl_file_handlers, (gpointer)fd);
+ g_hash_table_remove(tcl_file_handlers, GINT_TO_POINTER(fd));
Tcl_ServiceAll();
}
@@ -241,7 +241,7 @@
return 0;
}
- tfh = g_hash_table_lookup(tcl_file_handlers, (gpointer)fev->fd);
+ tfh = g_hash_table_lookup(tcl_file_handlers, GINT_TO_POINTER(fev->fd));
if (tfh == NULL)
return 1;
Modified: branches/soc-2006-file-loggers/plugins/tcl/tcl_signals.c
===================================================================
--- branches/soc-2006-file-loggers/plugins/tcl/tcl_signals.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/plugins/tcl/tcl_signals.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -48,7 +48,8 @@
return;
Tcl_DecrRefCount(handler->signal);
- Tcl_DecrRefCount(handler->namespace);
+ if (handler->namespace)
+ Tcl_DecrRefCount(handler->namespace);
g_free(handler);
}
@@ -86,7 +87,6 @@
(void *)handler))
return FALSE;
- Tcl_IncrRefCount(handler->signal);
handler->namespace = new_cb_namespace ();
Tcl_IncrRefCount(handler->namespace);
proc = g_string_new("");
@@ -134,6 +134,22 @@
tcl_callbacks = g_list_remove_all(tcl_callbacks, NULL);
}
+static GaimStringref *ref_type(GaimSubType type)
+{
+ switch (type) {
+ case GAIM_SUBTYPE_ACCOUNT:
+ return GaimTclRefAccount;
+ case GAIM_SUBTYPE_CONNECTION:
+ return GaimTclRefConnection;
+ case GAIM_SUBTYPE_CONVERSATION:
+ return GaimTclRefConversation;
+ case GAIM_SUBTYPE_STATUS:
+ return GaimTclRefStatus;
+ default:
+ return NULL;
+ }
+}
+
static void *tcl_signal_callback(va_list args, struct tcl_signal_handler *handler)
{
GString *name, *val;
@@ -170,14 +186,9 @@
case GAIM_TYPE_OBJECT:
case GAIM_TYPE_BOXED:
/* These are all "pointer" types to us */
- if (gaim_value_is_outgoing(handler->argtypes[i])) {
- vals[i] = va_arg(args, void **);
- Tcl_LinkVar(handler->interp, name->str,
- vals[i], TCL_LINK_INT);
- arg = Tcl_NewStringObj(name->str, -1);
- } else {
- arg = Tcl_NewIntObj((int)va_arg(args, void *));
- }
+ if (gaim_value_is_outgoing(handler->argtypes[i]))
+ gaim_debug_error("tcl", "pointer types do not currently support outgoing arguments\n");
+ arg = gaim_tcl_ref_new(GaimTclRefPointer, va_arg(args, void *));
break;
case GAIM_TYPE_BOOLEAN:
if (gaim_value_is_outgoing(handler->argtypes[i])) {
@@ -258,6 +269,11 @@
case GAIM_SUBTYPE_ACCOUNT:
case GAIM_SUBTYPE_CONNECTION:
case GAIM_SUBTYPE_CONVERSATION:
+ case GAIM_SUBTYPE_STATUS:
+ if (gaim_value_is_outgoing(handler->argtypes[i]))
+ gaim_debug_error("tcl", "pointer subtypes do not currently support outgoing arguments\n");
+ arg = gaim_tcl_ref_new(ref_type(gaim_value_get_subtype(handler->argtypes[i])), va_arg(args, void *));
+ break;
case GAIM_SUBTYPE_PLUGIN:
case GAIM_SUBTYPE_XFER:
/* pointers again */
@@ -281,24 +297,40 @@
node = va_arg(args, GaimBlistNode *);
switch (node->type) {
case GAIM_BLIST_GROUP_NODE:
- g_string_printf(val, "group {%s}", ((GaimGroup *)node)->name);
+ arg = Tcl_NewListObj(0, NULL);
+ Tcl_ListObjAppendElement(handler->interp, arg,
+ Tcl_NewStringObj("group", -1));
+ Tcl_ListObjAppendElement(handler->interp, arg,
+ Tcl_NewStringObj(((GaimGroup *)node)->name, -1));
break;
case GAIM_BLIST_CONTACT_NODE:
/* g_string_printf(val, "contact {%s}", Contact Name? ); */
+ arg = Tcl_NewStringObj("contact", -1);
break;
case GAIM_BLIST_BUDDY_NODE:
- g_string_printf(val, "buddy {%s} %lu", ((GaimBuddy *)node)->name,
- (unsigned long)((GaimBuddy *)node)->account);
+ arg = Tcl_NewListObj(0, NULL);
+ Tcl_ListObjAppendElement(handler->interp, arg,
+ Tcl_NewStringObj("buddy", -1));
+ Tcl_ListObjAppendElement(handler->interp, arg,
+ Tcl_NewStringObj(((GaimBuddy *)node)->name, -1));
+ Tcl_ListObjAppendElement(handler->interp, arg,
+ gaim_tcl_ref_new(GaimTclRefAccount,
+ ((GaimBuddy *)node)->account));
break;
case GAIM_BLIST_CHAT_NODE:
- g_string_printf(val, "chat {%s} %lu", ((GaimChat *)node)->alias,
- (unsigned long)((GaimChat *)node)->account);
+ arg = Tcl_NewListObj(0, NULL);
+ Tcl_ListObjAppendElement(handler->interp, arg,
+ Tcl_NewStringObj("chat", -1));
+ Tcl_ListObjAppendElement(handler->interp, arg,
+ Tcl_NewStringObj(((GaimChat *)node)->alias, -1));
+ Tcl_ListObjAppendElement(handler->interp, arg,
+ gaim_tcl_ref_new(GaimTclRefAccount,
+ ((GaimChat *)node)->account));
break;
case GAIM_BLIST_OTHER_NODE:
- g_string_printf(val, "other");
+ arg = Tcl_NewStringObj("other", -1);
break;
}
- arg = Tcl_NewStringObj(val->str, -1);
break;
}
}
@@ -329,8 +361,10 @@
for (i = 0; i < handler->nargs; i++) {
g_string_printf(name, "%s::arg%d",
Tcl_GetString(handler->namespace), i);
- if (gaim_value_is_outgoing(handler->argtypes[i]))
+ if (gaim_value_is_outgoing(handler->argtypes[i])
+ && gaim_value_get_type(handler->argtypes[i]) != GAIM_TYPE_SUBTYPE)
Tcl_UnlinkVar(handler->interp, name->str);
+
/* We basically only have to deal with strings on the
* way out */
switch (gaim_value_get_type(handler->argtypes[i])) {
Modified: branches/soc-2006-file-loggers/src/Makefile.am
===================================================================
--- branches/soc-2006-file-loggers/src/Makefile.am 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/Makefile.am 2006-06-17 02:11:13 UTC (rev 16272)
@@ -347,7 +347,8 @@
$(SM_LIBS) \
$(INTLLIBS) \
$(GTKSPELL_LIBS) \
- $(STARTUP_NOTIFICATION_LIBS)
+ $(STARTUP_NOTIFICATION_LIBS) \
+ $(LIBXML_LIBS)
AM_CPPFLAGS = \
-DBR_PTHREADS=0 \
@@ -361,4 +362,5 @@
$(GTK_CFLAGS) \
$(DBUS_CFLAGS) \
$(GTKSPELL_CFLAGS) \
- $(STARTUP_NOTIFICATION_CFLAGS)
+ $(STARTUP_NOTIFICATION_CFLAGS) \
+ $(LIBXML_CFLAGS)
Modified: branches/soc-2006-file-loggers/src/Makefile.mingw
===================================================================
--- branches/soc-2006-file-loggers/src/Makefile.mingw 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/Makefile.mingw 2006-06-17 02:11:13 UTC (rev 16272)
@@ -18,6 +18,7 @@
GAIM_INSTALL_DIR := $(GAIM_TOP)/win32-install-dir
NSS_DIR := ../../win32-dev/nss-3.9
NSPR_DIR := ../../win32-dev/nspr-4.4.1
+LIBXML2_DIR := ../../win32-dev/libxml2
##
## VARIABLE DEFINITIONS
@@ -66,7 +67,8 @@
-I$(ASPELL_TOP)/include \
-I$(GTKSPELL_TOP) \
-I$(NSS_DIR)/include \
- -I$(NSPR_DIR)/include
+ -I$(NSPR_DIR)/include \
+ -I$(LIBXML2_DIR)/include
LIB_PATHS = -L$(GTK_TOP)/lib \
@@ -74,7 +76,8 @@
-L$(IDLETRACK_TOP) \
-L$(ASPELL_TOP)/lib \
-L$(NSS_DIR)/lib \
- -L$(NSPR_DIR)/lib
+ -L$(NSPR_DIR)/lib \
+ -L$(LIBXML2_DIR)/lib
##
## SOURCES, OBJECTS
@@ -191,8 +194,8 @@
-lidletrack \
-lnss3 \
-lnspr4 \
- -lssl3
-
+ -lssl3 \
+ -lxml2
EXE_LIBS =
Modified: branches/soc-2006-file-loggers/src/gtkblist.c
===================================================================
--- branches/soc-2006-file-loggers/src/gtkblist.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/gtkblist.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -4162,10 +4162,7 @@
ihrs = (t - idle_secs) / 3600;
imin = ((t - idle_secs) / 60) % 60;
- if (ihrs > 0)
- idle = g_strdup_printf("%d:%02d", ihrs, imin);
- else
- idle = g_strdup_printf("%d", imin);
+ idle = g_strdup_printf("%d:%02d", ihrs, imin);
}
}
Modified: branches/soc-2006-file-loggers/src/gtkdialogs.c
===================================================================
--- branches/soc-2006-file-loggers/src/gtkdialogs.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/gtkdialogs.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -506,6 +506,12 @@
g_string_append(str, " <b>Tk:</b> Disabled<br/>");
#endif
+#ifdef HAVE_LIBXML
+ g_string_append(str, " <b>XML Parser:</b> libxml2<br/>");
+#else
+ g_string_append(str, " <b>XML Parser:</b> GMarkup<br/>");
+#endif
+
#ifndef _WIN32
#ifdef USE_SM
g_string_append(str, " <b>X Session Management:</b> Enabled<br/>");
@@ -729,6 +735,16 @@
gaim_request_field_group_add_field(group, field);
field = gaim_request_field_account_new("account", _("_Account"), NULL);
+
+ /* gaim_request_field_account_new() only sets a default value if you're
+ * connected, and it sets it from the list of connected accounts. Since
+ * we're going to set show_all here, it makes sense to use the first
+ * account, not the first connected account. */
+ if (gaim_accounts_get_all() != NULL) {
+ gaim_request_field_account_set_default_value(field, gaim_accounts_get_all()->data);
+ gaim_request_field_account_set_value(field, gaim_accounts_get_all()->data);
+ }
+
gaim_request_field_set_type_hint(field, "account");
gaim_request_field_set_visible(field,
(gaim_connections_get_all() != NULL &&
Modified: branches/soc-2006-file-loggers/src/gtkutils.h
===================================================================
--- branches/soc-2006-file-loggers/src/gtkutils.h 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/gtkutils.h 2006-06-17 02:11:13 UTC (rev 16272)
@@ -432,8 +432,6 @@
* @param menu The menu to append to.
* @param act The GaimMenuAction to append.
* @param gobject The object to be passed to the action callback.
- *
- * @return The menu.
*/
void gaim_gtk_append_menu_action(GtkWidget *menu, GaimMenuAction *act,
gpointer gobject);
Modified: branches/soc-2006-file-loggers/src/protocols/jabber/Makefile.am
===================================================================
--- branches/soc-2006-file-loggers/src/protocols/jabber/Makefile.am 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/protocols/jabber/Makefile.am 2006-06-17 02:11:13 UTC (rev 16272)
@@ -60,4 +60,5 @@
AM_CPPFLAGS = \
-I$(top_srcdir)/src \
$(DEBUG_CFLAGS) \
- $(GLIB_CFLAGS)
+ $(GLIB_CFLAGS) \
+ $(LIBXML_CFLAGS)
Modified: branches/soc-2006-file-loggers/src/protocols/jabber/Makefile.mingw
===================================================================
--- branches/soc-2006-file-loggers/src/protocols/jabber/Makefile.mingw 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/protocols/jabber/Makefile.mingw 2006-06-17 02:11:13 UTC (rev 16272)
@@ -10,6 +10,7 @@
INCLUDE_DIR := .
GTK_TOP := ../../../../win32-dev/gtk_2_0
+LIBXML2_DIR:= ../../../../win32-dev/libxml2
GAIM_TOP := ../../..
JABBER_ROOT := .
GAIM_INSTALL_DIR := $(GAIM_TOP)/win32-install-dir
@@ -50,18 +51,16 @@
INCLUDE_PATHS += -I$(JABBER_ROOT) \
-I$(JABBER_ROOT)/win32 \
-I$(GTK_TOP)/include \
- -I$(GTK_TOP)/include/gtk-2.0 \
-I$(GTK_TOP)/include/glib-2.0 \
- -I$(GTK_TOP)/include/pango-1.0 \
- -I$(GTK_TOP)/include/atk-1.0 \
-I$(GTK_TOP)/lib/glib-2.0/include \
- -I$(GTK_TOP)/lib/gtk-2.0/include \
+ -I$(LIBXML2_DIR)/include \
-I$(GAIM_TOP)/src \
-I$(GAIM_TOP)/src/win32 \
-I$(GAIM_TOP)
LIB_PATHS = -L$(GTK_TOP)/lib \
+ -L$(LIBXML2_DIR)/lib \
-L$(GAIM_TOP)/src
@@ -93,11 +92,9 @@
## LIBRARIES
##
-LIBS = -lgtk-win32-2.0 \
+LIBS = \
-lglib-2.0 \
- -lgdk-win32-2.0 \
- -lgmodule-2.0 \
- -lgobject-2.0 \
+ -lxml2 \
-lws2_32 \
-lintl \
-lgaim
Modified: branches/soc-2006-file-loggers/src/protocols/jabber/auth.c
===================================================================
--- branches/soc-2006-file-loggers/src/protocols/jabber/auth.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/protocols/jabber/auth.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -67,7 +67,7 @@
gchar *enc_out;
auth = xmlnode_new("auth");
- xmlnode_set_attrib(auth, "xmlns", "urn:ietf:params:xml:ns:xmpp-sasl");
+ xmlnode_set_namespace(auth, "urn:ietf:params:xml:ns:xmpp-sasl");
response = g_string_new("");
response = g_string_append_len(response, "\0", 1);
@@ -269,7 +269,7 @@
if (js->sasl_state == SASL_CONTINUE || js->sasl_state == SASL_OK) {
auth = xmlnode_new("auth");
- xmlnode_set_attrib(auth, "xmlns", "urn:ietf:params:xml:ns:xmpp-sasl");
+ xmlnode_set_namespace(auth, "urn:ietf:params:xml:ns:xmpp-sasl");
xmlnode_set_attrib(auth,"mechanism", mech);
if (clientout) {
if (coutlen == 0) {
@@ -386,7 +386,7 @@
js->auth_type = JABBER_AUTH_DIGEST_MD5;
auth = xmlnode_new("auth");
- xmlnode_set_attrib(auth, "xmlns", "urn:ietf:params:xml:ns:xmpp-sasl");
+ xmlnode_set_namespace(auth, "urn:ietf:params:xml:ns:xmpp-sasl");
xmlnode_set_attrib(auth, "mechanism", "DIGEST-MD5");
jabber_send(js, auth);
@@ -720,7 +720,7 @@
return;
} else {
response = xmlnode_new("response");
- xmlnode_set_attrib(response, "xmlns", "urn:ietf:params:xml:ns:xmpp-sasl");
+ xmlnode_set_namespace(response, "urn:ietf:params:xml:ns:xmpp-sasl");
if (c_out) {
enc_out = gaim_base64_encode((unsigned char*)c_out, clen);
xmlnode_insert_data(response, enc_out, -1);
@@ -735,7 +735,7 @@
void jabber_auth_handle_success(JabberStream *js, xmlnode *packet)
{
- const char *ns = xmlnode_get_attrib(packet, "xmlns");
+ const char *ns = xmlnode_get_namespace(packet);
#ifdef HAVE_CYRUS_SASL
int *x;
#endif
Modified: branches/soc-2006-file-loggers/src/protocols/jabber/buddy.c
===================================================================
--- branches/soc-2006-file-loggers/src/protocols/jabber/buddy.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/protocols/jabber/buddy.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -1108,7 +1108,7 @@
xmlnode_set_attrib(iq->node, "to", jid);
vcard = xmlnode_new_child(iq->node, "vCard");
- xmlnode_set_attrib(vcard, "xmlns", "vcard-temp");
+ xmlnode_set_namespace(vcard, "vcard-temp");
jabber_iq_set_callback(iq, jabber_vcard_parse, jbi);
jbi->ids = g_slist_prepend(jbi->ids, g_strdup(iq->id));
Modified: branches/soc-2006-file-loggers/src/protocols/jabber/chat.c
===================================================================
--- branches/soc-2006-file-loggers/src/protocols/jabber/chat.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/protocols/jabber/chat.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -162,7 +162,7 @@
if(chat->muc) {
xmlnode_set_attrib(message, "to", room_jid);
x = xmlnode_new_child(message, "x");
- xmlnode_set_attrib(x, "xmlns", "http://jabber.org/protocol/muc#user");
+ xmlnode_set_namespace(x, "http://jabber.org/protocol/muc#user");
invite = xmlnode_new_child(x, "invite");
xmlnode_set_attrib(invite, "to", name);
body = xmlnode_new_child(invite, "reason");
@@ -173,7 +173,7 @@
xmlnode_insert_data(body, msg, -1);
x = xmlnode_new_child(message, "x");
xmlnode_set_attrib(x, "jid", room_jid);
- xmlnode_set_attrib(x, "xmlns", "jabber:x:conference");
+ xmlnode_set_namespace(x, "jabber:x:conference");
}
jabber_send(js, message);
@@ -267,7 +267,7 @@
g_free(full_jid);
x = xmlnode_new_child(presence, "x");
- xmlnode_set_attrib(x, "xmlns", "http://jabber.org/protocol/muc");
+ xmlnode_set_namespace(x, "http://jabber.org/protocol/muc");
if(passwd && *passwd) {
xmlnode *password = xmlnode_new_child(x, "password");
@@ -380,7 +380,7 @@
for(x = xmlnode_get_child(query, "x"); x; x = xmlnode_get_next_twin(x)) {
const char *xmlns;
- if(!(xmlns = xmlnode_get_attrib(x, "xmlns")))
+ if(!(xmlns = xmlnode_get_namespace(x)))
continue;
if(!strcmp(xmlns, "jabber:x:data")) {
@@ -451,7 +451,7 @@
room_jid = g_strdup_printf("%s@...", chat->room, chat->server);
xmlnode_set_attrib(iq->node, "to", room_jid);
- xmlnode_set_attrib(x, "xmlns", "jabber:x:data");
+ xmlnode_set_namespace(x, "jabber:x:data");
xmlnode_set_attrib(x, "type", "submit");
jabber_iq_send(iq);
@@ -524,7 +524,7 @@
for(x = xmlnode_get_child(query, "x"); x; x = xmlnode_get_next_twin(x)) {
const char *xmlns;
- if(!(xmlns = xmlnode_get_attrib(x, "xmlns")))
+ if(!(xmlns = xmlnode_get_namespace(x)))
continue;
if(!strcmp(xmlns, "jabber:x:data")) {
Modified: branches/soc-2006-file-loggers/src/protocols/jabber/disco.c
===================================================================
--- branches/soc-2006-file-loggers/src/protocols/jabber/disco.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/protocols/jabber/disco.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -104,7 +104,7 @@
xmlnode_set_attrib(error, "code", "404");
xmlnode_set_attrib(error, "type", "cancel");
inf = xmlnode_new_child(error, "item-not-found");
- xmlnode_set_attrib(inf, "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas");
+ xmlnode_set_namespace(inf, "urn:ietf:params:xml:ns:xmpp-stanzas");
}
jabber_iq_send(iq);
Modified: branches/soc-2006-file-loggers/src/protocols/jabber/iq.c
===================================================================
--- branches/soc-2006-file-loggers/src/protocols/jabber/iq.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/protocols/jabber/iq.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -78,7 +78,7 @@
xmlnode *query;
query = xmlnode_new_child(iq->node, "query");
- xmlnode_set_attrib(query, "xmlns", xmlns);
+ xmlnode_set_namespace(query, xmlns);
return iq;
}
@@ -268,7 +268,7 @@
/* Apparently not, so lets see if we have a pre-defined handler */
- if(type && query && (xmlns = xmlnode_get_attrib(query, "xmlns"))) {
+ if(type && query && (xmlns = xmlnode_get_namespace(query))) {
if(!strcmp(type, "set")) {
if(!strcmp(xmlns, "jabber:iq:roster")) {
jabber_roster_parse(js, packet);
@@ -329,7 +329,7 @@
xmlnode_set_attrib(error, "type", "cancel");
xmlnode_set_attrib(error, "code", "501");
x = xmlnode_new_child(error, "feature-not-implemented");
- xmlnode_set_attrib(x, "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas");
+ xmlnode_set_namespace(x, "urn:ietf:params:xml:ns:xmpp-stanzas");
jabber_iq_send(iq);
}
Modified: branches/soc-2006-file-loggers/src/protocols/jabber/jabber.c
===================================================================
--- branches/soc-2006-file-loggers/src/protocols/jabber/jabber.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/protocols/jabber/jabber.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -63,9 +63,9 @@
"xmlns:stream='http://etherx.jabber.org/streams' "
"version='1.0'>",
js->user->domain);
-
+ /* setup the parser fresh for each stream */
+ jabber_parser_setup(js);
jabber_send_raw(js, open_stream, -1);
-
g_free(open_stream);
}
@@ -88,7 +88,7 @@
jabber_iq_set_callback(iq, jabber_session_initialized_cb, NULL);
session = xmlnode_new_child(iq->node, "session");
- xmlnode_set_attrib(session, "xmlns", "urn:ietf:params:xml:ns:xmpp-session");
+ xmlnode_set_namespace(session, "urn:ietf:params:xml:ns:xmpp-session");
jabber_iq_send(iq);
}
@@ -137,7 +137,7 @@
xmlnode *bind, *resource;
JabberIq *iq = jabber_iq_new(js, JABBER_IQ_SET);
bind = xmlnode_new_child(iq->node, "bind");
- xmlnode_set_attrib(bind, "xmlns", "urn:ietf:params:xml:ns:xmpp-bind");
+ xmlnode_set_namespace(bind, "urn:ietf:params:xml:ns:xmpp-bind");
resource = xmlnode_new_child(bind, "resource");
xmlnode_insert_data(resource, js->user->resource, -1);
@@ -174,8 +174,14 @@
jabber_message_parse(js, packet);
} else if(!strcmp(packet->name, "stream:features")) {
jabber_stream_features_parse(js, packet);
+ } else if (!strcmp(packet->name, "features") &&
+ !strcmp(xmlnode_get_namespace(packet), "http://etherx.jabber.org/streams")) {
+ jabber_stream_features_parse(js, packet);
} else if(!strcmp(packet->name, "stream:error")) {
jabber_stream_handle_error(js, packet);
+ } else if (!strcmp(packet->name, "error") &&
+ !strcmp(xmlnode_get_namespace(packet), "http://etherx.jabber.org/streams")) {
+ jabber_stream_handle_error(js, packet);
} else if(!strcmp(packet->name, "challenge")) {
if(js->state == JABBER_STREAM_AUTHENTICATING)
jabber_auth_handle_challenge(js, packet);
@@ -405,7 +411,6 @@
if(js->state == JABBER_STREAM_CONNECTING)
jabber_send_raw(js, "<?xml version='1.0' ?>", -1);
-
jabber_stream_set_state(js, JABBER_STREAM_INITIALIZING);
gaim_ssl_input_add(gsc, jabber_recv_cb_ssl, gc);
}
@@ -923,9 +928,10 @@
gaim_input_remove(js->gc->inpa);
close(js->fd);
}
-
+#ifndef HAVE_LIBXML
if(js->context)
g_markup_parse_context_free(js->context);
+#endif
if(js->iq_callbacks)
g_hash_table_destroy(js->iq_callbacks);
if(js->disco_callbacks)
@@ -981,7 +987,6 @@
gaim_connection_update_progress(js->gc, _("Initializing Stream"),
js->gsc ? 5 : 2, JABBER_CONNECT_STEPS);
jabber_stream_init(js);
- jabber_parser_setup(js);
break;
case JABBER_STREAM_AUTHENTICATING:
gaim_connection_update_progress(js->gc, _("Authenticating"),
@@ -1400,7 +1405,7 @@
{
xmlnode *error;
const char *code = NULL, *text = NULL;
- const char *xmlns = xmlnode_get_attrib(packet, "xmlns");
+ const char *xmlns = xmlnode_get_namespace(packet);
char *cdata = NULL;
if((error = xmlnode_get_child(packet, "error"))) {
Modified: branches/soc-2006-file-loggers/src/protocols/jabber/jabber.h
===================================================================
--- branches/soc-2006-file-loggers/src/protocols/jabber/jabber.h 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/protocols/jabber/jabber.h 2006-06-17 02:11:13 UTC (rev 16272)
@@ -22,6 +22,9 @@
#ifndef _GAIM_JABBER_H_
#define _GAIM_JABBER_H_
+#ifdef HAVE_LIBXML
+#include <libxml/parser.h>
+#endif
#include <glib.h>
#include "connection.h"
#include "roomlist.h"
@@ -64,7 +67,11 @@
{
int fd;
+#ifdef HAVE_LIBXML
+ xmlParserCtxt *context;
+#else
GMarkupParseContext *context;
+#endif
xmlnode *current;
enum {
Modified: branches/soc-2006-file-loggers/src/protocols/jabber/message.c
===================================================================
--- branches/soc-2006-file-loggers/src/protocols/jabber/message.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/protocols/jabber/message.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -123,7 +123,7 @@
for(etc = jm->etc; etc; etc = etc->next) {
xmlnode *x = etc->data;
- const char *xmlns = xmlnode_get_attrib(x, "xmlns");
+ const char *xmlns = xmlnode_get_namespace(x);
if(xmlns && !strcmp(xmlns, "jabber:x:oob")) {
xmlnode *url, *desc;
char *urltxt, *desctxt;
@@ -325,7 +325,7 @@
g_free(code_txt);
g_free(text);
} else if(!strcmp(child->name, "x")) {
- const char *xmlns = xmlnode_get_attrib(child, "xmlns");
+ const char *xmlns = xmlnode_get_namespace(child);
if(xmlns && !strcmp(xmlns, "jabber:x:event")) {
if(xmlnode_get_child(child, "composing")) {
if(jm->chat_state == JM_STATE_ACTIVE)
@@ -440,7 +440,7 @@
if(JM_TS_JEP_0022 == (jm->typing_style & JM_TS_JEP_0022)) {
child = xmlnode_new_child(message, "x");
- xmlnode_set_attrib(child, "xmlns", "jabber:x:event");
+ xmlnode_set_namespace(child, "jabber:x:event");
if(jm->chat_state == JM_STATE_COMPOSING || jm->body)
xmlnode_new_child(child, "composing");
}
@@ -466,7 +466,7 @@
break;
}
if(child)
- xmlnode_set_attrib(child, "xmlns", "http://jabber.org/protocol/chatstates");
+ xmlnode_set_namespace(child, "http://jabber.org/protocol/chatstates");
}
if(jm->subject) {
Modified: branches/soc-2006-file-loggers/src/protocols/jabber/oob.c
===================================================================
--- branches/soc-2006-file-loggers/src/protocols/jabber/oob.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/protocols/jabber/oob.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -168,11 +168,11 @@
if(!strcmp(code, "406")) {
z = xmlnode_new_child(y, "not-acceptable");
xmlnode_set_attrib(y, "type", "modify");
- xmlnode_set_attrib(z, "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas");
+ xmlnode_set_namespace(z, "urn:ietf:params:xml:ns:xmpp-stanzas");
} else if(!strcmp(code, "404")) {
z = xmlnode_new_child(y, "not-found");
xmlnode_set_attrib(y, "type", "cancel");
- xmlnode_set_attrib(z, "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas");
+ xmlnode_set_namespace(z, "urn:ietf:params:xml:ns:xmpp-stanzas");
}
jabber_iq_send(iq);
Modified: branches/soc-2006-file-loggers/src/protocols/jabber/parser.c
===================================================================
--- branches/soc-2006-file-loggers/src/protocols/jabber/parser.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/protocols/jabber/parser.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -20,12 +20,17 @@
*/
#include "internal.h"
+#ifdef HAVE_LIBXML
+#include <libxml/parser.h>
+#endif
+
#include "connection.h"
-
+#include "debug.h"
#include "jabber.h"
#include "parser.h"
#include "xmlnode.h"
+#ifndef HAVE_LIBXML
static void
jabber_parser_element_start(GMarkupParseContext *context,
const char *element_name, const char **attrib_names,
@@ -104,6 +109,136 @@
xmlnode_insert_data(js->current, text, text_len);
}
+#else /* HAVE_LIBXML */
+
+static void
+jabber_parser_element_start_libxml(void *user_data,
+ const xmlChar *element_name, const xmlChar *prefix, const xmlChar *namespace,
+ int nb_namespaces, const xmlChar **namespaces,
+ int nb_attributes, int nb_defaulted, const xmlChar **attributes)
+{
+ JabberStream *js = user_data;
+ xmlnode *node;
+ int i;
+
+ if(!element_name) {
+ return;
+ } else if(!strcmp(element_name, "stream")) {
+ js->protocol_version = JABBER_PROTO_0_9;
+ for(i=0; i < nb_attributes * 5; i += 5) {
+ int attrib_len = attributes[i+4] - attributes[i+3];
+ char *attrib = g_malloc(attrib_len + 1);
+ memcpy(attrib, attributes[i+3], attrib_len);
+ attrib[attrib_len] = '\0';
+
+ if(!strcmp(attributes[i], "version")
+ && !strcmp(attrib, "1.0")) {
+ js->protocol_version = JABBER_PROTO_1_0;
+ } else if(!strcmp(attributes[i], "id")) {
+ if(js->stream_id)
+ g_free(js->stream_id);
+ js->stream_id = g_strdup(attrib);
+ }
+ g_free(attrib);
+ }
+ if(js->protocol_version == JABBER_PROTO_0_9)
+ js->auth_type = JABBER_AUTH_IQ_AUTH;
+
+ if(js->state == JABBER_STREAM_INITIALIZING)
+ jabber_stream_set_state(js, JABBER_STREAM_AUTHENTICATING);
+ } else {
+
+ if(js->current)
+ node = xmlnode_new_child(js->current, element_name);
+ else
+ node = xmlnode_new(element_name);
+ xmlnode_set_namespace(node, namespace);
+
+ for(i=0; i < nb_attributes * 5; i+=5) {
+ int attrib_len = attributes[i+4] - attributes[i+3];
+ char *attrib = g_malloc(attrib_len + 1);
+ memcpy(attrib, attributes[i+3], attrib_len);
+ attrib[attrib_len] = '\0';
+ xmlnode_set_attrib(node, attributes[i], attrib);
+ g_free(attrib);
+ }
+
+ js->current = node;
+ }
+}
+
+static void
+jabber_parser_element_end_libxml(void *user_data, const xmlChar *element_name,
+ const xmlChar *prefix, const xmlChar *namespace)
+{
+ JabberStream *js = user_data;
+
+ if(!js->current)
+ return;
+
+ if(js->current->parent) {
+ if(!strcmp(js->current->name, element_name))
+ js->current = js->current->parent;
+ } else {
+ xmlnode *packet = js->current;
+ js->current = NULL;
+ jabber_process_packet(js, packet);
+ xmlnode_free(packet);
+ }
+}
+
+static void
+jabber_parser_element_text_libxml(void *user_data, const xmlChar *text, int text_len)
+{
+ JabberStream *js = user_data;
+
+ if(!js->current)
+ return;
+
+ if(!text || !text_len)
+ return;
+
+ xmlnode_insert_data(js->current, text, text_len);
+}
+#endif /* HAVE_LIBXML */
+
+
+#ifdef HAVE_LIBXML
+static xmlSAXHandler jabber_parser_libxml = {
+ .internalSubset = NULL,
+ .isStandalone = NULL,
+ .hasInternalSubset = NULL,
+ .hasExternalSubset = NULL,
+ .resolveEntity = NULL,
+ .getEntity = NULL,
+ .entityDecl = NULL,
+ .notationDecl = NULL,
+ .attributeDecl = NULL,
+ .elementDecl = NULL,
+ .unparsedEntityDecl = NULL,
+ .setDocumentLocator = NULL,
+ .startDocument = NULL,
+ .endDocument = NULL,
+ .startElement = NULL,
+ .endElement = NULL,
+ .reference = NULL,
+ .characters = jabber_parser_element_text_libxml,
+ .ignorableWhitespace = NULL,
+ .processingInstruction = NULL,
+ .comment = NULL,
+ .warning = NULL,
+ .error = NULL,
+ .fatalError = NULL,
+ .getParameterEntity = NULL,
+ .cdataBlock = NULL,
+ .externalSubset = NULL,
+ .initialized = XML_SAX2_MAGIC,
+ ._private = NULL,
+ .startElementNs = jabber_parser_element_start_libxml,
+ .endElementNs = jabber_parser_element_end_libxml,
+ .serror = NULL
+};
+#else
static GMarkupParser jabber_parser = {
jabber_parser_element_start,
jabber_parser_element_end,
@@ -111,24 +246,47 @@
NULL,
NULL
};
+#endif
void
jabber_parser_setup(JabberStream *js)
{
+#ifdef HAVE_LIBXML
+ /* This seems backwards, but it makes sense. The libxml code creates the parser
+ * context when you try to use it (this way, it can figure out the encoding at
+ * creation time. So, setting up the parser is just a matter of destroying any
+ * current parser. */
+ if (js->context) {
+ xmlParseChunk(js->context, NULL,0,1);
+ xmlFreeParserCtxt(js->context);
+ js->context = NULL;
+ }
+#else
if(!js->context)
js->context = g_markup_parse_context_new(&jabber_parser, 0, js, NULL);
+#endif
}
void jabber_parser_process(JabberStream *js, const char *buf, int len)
{
+#ifndef HAVE_LIBXML
/* May need to check for other encodings and do the conversion here */
-
if(!g_markup_parse_context_parse(js->context, buf, len, NULL)) {
g_markup_parse_context_free(js->context);
js->context = NULL;
gaim_connection_error(js->gc, _("XML Parse error"));
}
+#else
+ if (js->context == NULL) {
+ /* libxml inconsistently starts parsing on creating the parser, so so a ParseChunk
+ * right afterwards to force it. */
+ js->context = xmlCreatePushParserCtxt(&jabber_parser_libxml, js, buf, len, NULL);
+ xmlParseChunk(js->context, NULL, 0, 0);
+ } else if (xmlParseChunk(js->context, buf, len, 0) < 0) {
+ gaim_connection_error(js->gc, _("XML Parse error"));
+ }
+#endif
}
Modified: branches/soc-2006-file-loggers/src/protocols/jabber/presence.c
===================================================================
--- branches/soc-2006-file-loggers/src/protocols/jabber/presence.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/protocols/jabber/presence.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -121,7 +121,7 @@
if(js->avatar_hash) {
x = xmlnode_new_child(presence, "x");
- xmlnode_set_attrib(x, "xmlns", "vcard-temp:x:update");
+ xmlnode_set_namespace(x, "vcard-temp:x:update");
photo = xmlnode_new_child(x, "photo");
xmlnode_insert_data(photo, js->avatar_hash, -1);
}
@@ -167,7 +167,7 @@
/* JEP-0115 */
c = xmlnode_new_child(presence, "c");
- xmlnode_set_attrib(c, "xmlns", "http://jabber.org/protocol/caps");
+ xmlnode_set_namespace(c, "http://jabber.org/protocol/caps");
xmlnode_set_attrib(c, "node", CAPS0115_NODE);
xmlnode_set_attrib(c, "ver", VERSION);
@@ -290,7 +290,6 @@
gboolean muc = FALSE;
char *avatar_hash = NULL;
-
if(!(jb = jabber_buddy_find(js, from, TRUE)))
return;
@@ -363,7 +362,7 @@
g_free(p);
}
} else if(!strcmp(y->name, "x")) {
- const char *xmlns = xmlnode_get_attrib(y, "xmlns");
+ const char *xmlns = xmlnode_get_namespace(y);
if(xmlns && !strcmp(xmlns, "jabber:x:delay")) {
/* XXX: compare the time. jabber:x:delay can happen on presence packets that aren't really and truly delayed */
delayed = TRUE;
@@ -464,7 +463,7 @@
for(x = xmlnode_get_child(packet, "x"); x; x = xmlnode_get_next_twin(x)) {
const char *xmlns, *nick, *code;
xmlnode *stat, *item;
- if(!(xmlns = xmlnode_get_attrib(x, "xmlns")) ||
+ if(!(xmlns = xmlnode_get_namespace(x)) ||
strcmp(xmlns, "http://jabber.org/protocol/muc#user"))
continue;
if(!(stat = xmlnode_get_child(x, "status")))
@@ -560,7 +559,7 @@
iq = jabber_iq_new(js, JABBER_IQ_GET);
xmlnode_set_attrib(iq->node, "to", buddy_name);
vcard = xmlnode_new_child(iq->node, "vCard");
- xmlnode_set_attrib(vcard, "xmlns", "vcard-temp");
+ xmlnode_set_namespace(vcard, "vcard-temp");
jabber_iq_set_callback(iq, jabber_vcard_parse_avatar, NULL);
jabber_iq_send(iq);
Modified: branches/soc-2006-file-loggers/src/protocols/jabber/roster.c
===================================================================
--- branches/soc-2006-file-loggers/src/protocols/jabber/roster.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/protocols/jabber/roster.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -21,6 +21,7 @@
#include "internal.h"
#include "debug.h"
#include "server.h"
+#include "util.h"
#include "buddy.h"
#include "presence.h"
@@ -202,7 +203,9 @@
if(!(group_name = xmlnode_get_data(group)))
group_name = g_strdup("");
- groups = g_slist_append(groups, group_name);
+
+ if (g_slist_find_custom(groups, group_name, (GCompareFunc)gaim_utf8_strcasecmp) == NULL)
+ groups = g_slist_append(groups, group_name);
}
add_gaim_buddies_in_groups(js, jid, name, groups);
}
Modified: branches/soc-2006-file-loggers/src/protocols/jabber/si.c
===================================================================
--- branches/soc-2006-file-loggers/src/protocols/jabber/si.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/protocols/jabber/si.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -139,7 +139,7 @@
xmlnode_set_attrib(error, "code", "404");
xmlnode_set_attrib(error, "type", "cancel");
condition = xmlnode_new_child(error, "condition");
- xmlnode_set_attrib(condition, "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas");
+ xmlnode_set_namespace(condition, "urn:ietf:params:xml:ns:xmpp-stanzas");
xmlnode_new_child(condition, "item-not-found");
jabber_iq_send(iq);
@@ -637,14 +637,14 @@
iq = jabber_iq_new(jsx->js, JABBER_IQ_SET);
xmlnode_set_attrib(iq->node, "to", xfer->who);
si = xmlnode_new_child(iq->node, "si");
- xmlnode_set_attrib(si, "xmlns", "http://jabber.org/protocol/si");
+ xmlnode_set_namespace(si, "http://jabber.org/protocol/si");
jsx->stream_id = jabber_get_next_id(jsx->js);
xmlnode_set_attrib(si, "id", jsx->stream_id);
xmlnode_set_attrib(si, "profile",
"http://jabber.org/protocol/si/profile/file-transfer");
file = xmlnode_new_child(si, "file");
- xmlnode_set_attrib(file, "xmlns",
+ xmlnode_set_namespace(file,
"http://jabber.org/protocol/si/profile/file-transfer");
xmlnode_set_attrib(file, "name", xfer->filename);
g_snprintf(buf, sizeof(buf), "%" G_GSIZE_FORMAT, xfer->size);
@@ -652,10 +652,10 @@
/* maybe later we'll do hash and date attribs */
feature = xmlnode_new_child(si, "feature");
- xmlnode_set_attrib(feature, "xmlns",
+ xmlnode_set_namespace(feature,
"http://jabber.org/protocol/feature-neg");
x = xmlnode_new_child(feature, "x");
- xmlnode_set_attrib(x, "xmlns", "jabber:x:data");
+ xmlnode_set_namespace(x, "jabber:x:data");
xmlnode_set_attrib(x, "type", "form");
field = xmlnode_new_child(x, "field");
xmlnode_set_attrib(field, "var", "stream-method");
@@ -771,13 +771,13 @@
jsx->accepted = TRUE;
si = xmlnode_new_child(iq->node, "si");
- xmlnode_set_attrib(si, "xmlns", "http://jabber.org/protocol/si");
+ xmlnode_set_namespace(si, "http://jabber.org/protocol/si");
feature = xmlnode_new_child(si, "feature");
- xmlnode_set_attrib(feature, "xmlns", "http://jabber.org/protocol/feature-neg");
+ xmlnode_set_namespace(feature, "http://jabber.org/protocol/feature-neg");
x = xmlnode_new_child(feature, "x");
- xmlnode_set_attrib(x, "xmlns", "jabber:x:data");
+ xmlnode_set_namespace(x, "jabber:x:data");
xmlnode_set_attrib(x, "type", "submit");
field = xmlnode_new_child(x, "field");
Modified: branches/soc-2006-file-loggers/src/protocols/jabber/xdata.c
===================================================================
--- branches/soc-2006-file-loggers/src/protocols/jabber/xdata.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/protocols/jabber/xdata.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -49,7 +49,7 @@
JabberStream *js = data->js;
GList *groups, *flds;
- xmlnode_set_attrib(result, "xmlns", "jabber:x:data");
+ xmlnode_set_namespace(result, "jabber:x:data");
xmlnode_set_attrib(result, "type", "submit");
for(groups = gaim_request_fields_get_groups(fields); groups; groups = groups->next) {
@@ -140,7 +140,7 @@
}
g_free(data);
- xmlnode_set_attrib(result, "xmlns", "jabber:x:data");
+ xmlnode_set_namespace(result, "jabber:x:data");
xmlnode_set_attrib(result, "type", "cancel");
cb(js, result, user_data);
Modified: branches/soc-2006-file-loggers/src/protocols/msn/userlist.c
===================================================================
--- branches/soc-2006-file-loggers/src/protocols/msn/userlist.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/protocols/msn/userlist.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -292,6 +292,11 @@
if (!(user->list_op & (MSN_LIST_AL_OP | MSN_LIST_BL_OP)))
{
+ /*
+ * TODO: The friendly name was NULL for me when I
+ * looked at this. Maybe we should use the store
+ * name instead? --KingAnt
+ */
got_new_entry(gc, passport, friendly);
}
}
@@ -413,7 +418,12 @@
if (list_op & MSN_LIST_RL_OP)
{
/* These are users who have us on their buddy list. */
- /* TODO: what does store name is when this happens? */
+ /*
+ * TODO: What is store name set to when this happens?
+ * For one of my accounts "something@..."
+ * the store name was "something." Maybe we
+ * should use the friendly name, instead? --KingAnt
+ */
if (!(list_op & (MSN_LIST_AL_OP | MSN_LIST_BL_OP)))
{
Modified: branches/soc-2006-file-loggers/src/protocols/oscar/oscar.c
===================================================================
--- branches/soc-2006-file-loggers/src/protocols/oscar/oscar.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/protocols/oscar/oscar.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -1903,6 +1903,7 @@
file = g_fopen(iconfile, "rb");
if (file) {
/* XXX - Use g_file_get_contents() */
+ /* g_file_get_contents(iconfile, &data, &len, NULL); */
int len = fread(buf, 1, st.st_size, file);
gaim_debug_info("oscar",
"Sending buddy icon to %s (%d bytes, "
Modified: branches/soc-2006-file-loggers/src/protocols/yahoo/yahoo_packet.c
===================================================================
--- branches/soc-2006-file-loggers/src/protocols/yahoo/yahoo_packet.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/protocols/yahoo/yahoo_packet.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -116,7 +116,7 @@
struct yahoo_pair *pair = g_new0(struct yahoo_pair, 1);
- /* this is weird, and in one of the chat packets, and causes us
+ /* this is weird, and in one of the chat packets, and causes us to
* think all the values are keys and all the keys are values after
* this point if we don't handle it */
if (data[pos] == '\0') {
Modified: branches/soc-2006-file-loggers/src/xmlnode.c
===================================================================
--- branches/soc-2006-file-loggers/src/xmlnode.c 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/xmlnode.c 2006-06-17 02:11:13 UTC (rev 16272)
@@ -29,6 +29,9 @@
#include "internal.h"
+#ifdef HAVE_LIBXML
+#include <libxml/parser.h>
+#endif
#include <string.h>
#include <glib.h>
@@ -172,6 +175,32 @@
return NULL;
}
+
+void xmlnode_set_namespace(xmlnode *node, const char *xmlns)
+{
+#ifdef HAVE_LIBXML
+ g_return_if_fail(node != NULL);
+
+ if (node->namespace)
+ g_free(node->namespace);
+
+ node->namespace = g_strdup(xmlns);
+#else
+ return xmlnode_set_attrib(node, "xmlns", xmlns);
+#endif
+}
+
+const char *xmlnode_get_namespace(xmlnode *node)
+{
+#ifdef HAVE_LIBXML
+ g_return_val_if_fail(node != NULL, NULL);
+
+ return node->namespace;
+#else
+ return xmlnode_get_attrib(node, "xmlns");
+#endif
+}
+
void
xmlnode_free(xmlnode *node)
{
@@ -190,6 +219,10 @@
g_free(node->name);
if(node->data)
g_free(node->data);
+#ifdef HAVE_LIBXML
+ if(node->namespace)
+ g_free(node->namespace);
+#endif
g_free(node);
}
@@ -216,7 +249,7 @@
for(x = parent->child; x; x = x->next) {
const char *xmlns = NULL;
if(ns)
- xmlns = xmlnode_get_attrib(x, "xmlns");
+ xmlns = xmlnode_get_namespace(x);
if(x->type == XMLNODE_TYPE_TAG && name && !strcmp(parent_name, x->name)
&& (!ns || (xmlns && !strcmp(ns, xmlns)))) {
@@ -272,6 +305,13 @@
node_name = g_markup_escape_text(node->name, -1);
g_string_append_printf(text, "<%s", node_name);
+#ifdef HAVE_LIBXML
+ if (node->namespace) {
+ char *namespace = g_markup_escape_text(node->namespace, -1);
+ g_string_append_printf(text, " xmlns='%s'", namespace);
+ g_free(namespace);
+ }
+#endif
for(c = node->child; c; c = c->next)
{
if(c->type == XMLNODE_TYPE_ATTRIB) {
@@ -347,7 +387,72 @@
xmlnode *current;
};
+#ifdef HAVE_LIBXML
static void
+xmlnode_parser_element_start_libxml(void *user_data,
+ const xmlChar *element_name, const xmlChar *prefix, const xmlChar *namespace,
+ int nb_namespaces, const xmlChar **namespaces,
+ int nb_attributes, int nb_defaulted, const xmlChar **attributes)
+{
+ struct _xmlnode_parser_data *xpd = user_data;
+ xmlnode *node;
+ int i;
+
+ if(!element_name) {
+ return;
+ } else {
+ if(xpd->current)
+ node = xmlnode_new_child(xpd->current, element_name);
+ else
+ node = xmlnode_new(element_name);
+
+ xmlnode_set_namespace(node, namespace);
+
+ for(i=0; i < nb_attributes * 5; i+=5) {
+ int attrib_len = attributes[i+4] - attributes[i+3];
+ char *attrib = g_malloc(attrib_len + 1);
+ memcpy(attrib, attributes[i+3], attrib_len);
+ attrib[attrib_len] = '\0';
+ xmlnode_set_attrib(node, attributes[i], attrib);
+ g_free(attrib);
+ }
+
+ xpd->current = node;
+ }
+}
+
+static void
+xmlnode_parser_element_end_libxml(void *user_data, const xmlChar *element_name,
+ const xmlChar *prefix, const xmlChar *namespace)
+{
+ struct _xmlnode_parser_data *xpd = user_data;
+
+ if(!element_name || !xpd->current)
+ return;
+
+ if(xpd->current->parent) {
+ if(!strcmp(xpd->current->name, element_name))
+ xpd->current = xpd->current->parent;
+ }
+}
+
+static void
+xmlnode_parser_element_text_libxml(void *user_data, const xmlChar *text, int text_len)
+{
+ struct _xmlnode_parser_data *xpd = user_data;
+
+ if(!xpd->current)
+ return;
+
+ if(!text || !text_len)
+ return;
+
+ xmlnode_insert_data(xpd->current, text, text_len);
+}
+
+#else
+
+static void
xmlnode_parser_element_start(GMarkupParseContext *context,
const char *element_name, const char **attrib_names,
const char **attrib_values, gpointer user_data, GError **error)
@@ -400,7 +505,44 @@
xmlnode_insert_data(xpd->current, text, text_len);
}
+#endif
+#ifdef HAVE_LIBXML
+static xmlSAXHandler xmlnode_parser_libxml = {
+ .internalSubset = NULL,
+ .isStandalone = NULL,
+ .hasInternalSubset = NULL,
+ .hasExternalSubset = NULL,
+ .resolveEntity = NULL,
+ .getEntity = NULL,
+ .entityDecl = NULL,
+ .notationDecl = NULL,
+ .attributeDecl = NULL,
+ .elementDecl = NULL,
+ .unparsedEntityDecl = NULL,
+ .setDocumentLocator = NULL,
+ .startDocument = NULL,
+ .endDocument = NULL,
+ .startElement = NULL,
+ .endElement = NULL,
+ .reference = NULL,
+ .characters = xmlnode_parser_element_text_libxml,
+ .ignorableWhitespace = NULL,
+ .processingInstruction = NULL,
+ .comment = NULL,
+ .warning = NULL,
+ .error = NULL,
+ .fatalError = NULL,
+ .getParameterEntity = NULL,
+ .cdataBlock = NULL,
+ .externalSubset = NULL,
+ .initialized = XML_SAX2_MAGIC,
+ ._private = NULL,
+ .startElementNs = xmlnode_parser_element_start_libxml,
+ .endElementNs = xmlnode_parser_element_end_libxml,
+ .serror = NULL
+};
+#else
static GMarkupParser xmlnode_parser = {
xmlnode_parser_element_start,
xmlnode_parser_element_end,
@@ -408,8 +550,8 @@
NULL,
NULL
};
+#endif
-
xmlnode *
xmlnode_from_str(const char *str, gssize size)
{
@@ -422,6 +564,16 @@
real_size = size < 0 ? strlen(str) : size;
xpd = g_new0(struct _xmlnode_parser_data, 1);
+
+#ifdef HAVE_LIBXML
+ if (xmlSAXUserParseMemory(&xmlnode_parser_libxml, xpd, str, size) < 0) {
+ while(xpd->current && xpd->current->parent)
+ xpd->current = xpd->current->parent;
+ if(xpd->current)
+ xmlnode_free(xpd->current);
+ xpd->current = NULL;
+ }
+#else
context = g_markup_parse_context_new(&xmlnode_parser, 0, xpd, NULL);
if(!g_markup_parse_context_parse(context, str, real_size, NULL)) {
@@ -432,7 +584,7 @@
xpd->current = NULL;
}
g_markup_parse_context_free(context);
-
+#endif
ret = xpd->current;
g_free(xpd);
return ret;
@@ -477,7 +629,7 @@
xmlnode_get_next_twin(xmlnode *node)
{
xmlnode *sibling;
- const char *ns = xmlnode_get_attrib(node, "xmlns");
+ const char *ns = xmlnode_get_namespace(node);
g_return_val_if_fail(node != NULL, NULL);
g_return_val_if_fail(node->type == XMLNODE_TYPE_TAG, NULL);
@@ -485,7 +637,7 @@
for(sibling = node->next; sibling; sibling = sibling->next) {
const char *xmlns = NULL;
if(ns)
- xmlns = xmlnode_get_attrib(sibling, "xmlns");
+ xmlns = xmlnode_get_namespace(sibling);
if(sibling->type == XMLNODE_TYPE_TAG && !strcmp(node->name, sibling->name) &&
(!ns || (xmlns && !strcmp(ns, xmlns))))
Modified: branches/soc-2006-file-loggers/src/xmlnode.h
===================================================================
--- branches/soc-2006-file-loggers/src/xmlnode.h 2006-06-17 01:33:09 UTC (rev 16271)
+++ branches/soc-2006-file-loggers/src/xmlnode.h 2006-06-17 02:11:13 UTC (rev 16272)
@@ -41,6 +41,9 @@
typedef struct _xmlnode
{
char *name; /**< The name of the node. */
+#ifdef HAVE_LIBXML
+ char *namespace; /**< The namespace of the node */
+#endif
XMLNodeType type; /**< The type of the node. */
char *data; /**< The data for the node. */
size_t data_sz; /**< The size of the data. */
@@ -154,6 +157,22 @@
void xmlnode_remove_attrib(xmlnode *node, const char *attr);
/**
+ * Sets the namespace of a node
+ *
+ * @param node The node to qualify
+ * @param xmlns The namespace of the node
+ */
+void xmlnode_set_namespace(xmlnode *node, const char *xmlns);
+
+/**
+ * Returns the namespace of a node
+ *
+ * @param node The node to get the namepsace from
+ * @return The namespace of this node
+ */
+const char *xmlnode_get_namespace(xmlnode *node);
+
+/**
* Returns the node in a string of xml.
*
* @param node The starting node to output.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|