mirror of https://github.com/djcb/mu.git
* mu-threader, mu-util: cleanups
This commit is contained in:
parent
6a13866235
commit
846d2da27f
|
@ -41,11 +41,11 @@
|
|||
* Msg4 (child of Msg2) => 00001:00001
|
||||
* Msg5 (child of Msg4) => 00001:00001:00000
|
||||
* Msg6 => 00002
|
||||
*
|
||||
*
|
||||
* the padding-0's are added to make them easy to sort using strcmp;
|
||||
* the number hexadecimal numbers, and the length of the 'segments'
|
||||
* (the parts separated by the ':') is equal to ceil(log_16(matchnum))
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
@ -67,10 +67,10 @@ mu_threader_calculate (MuMsgIter *iter, size_t matchnum, MuMsgFieldId sortfield)
|
|||
g_return_val_if_fail (mu_msg_field_id_is_valid (sortfield) ||
|
||||
sortfield == MU_MSG_FIELD_ID_NONE,
|
||||
FALSE);
|
||||
|
||||
|
||||
/* step 1 */
|
||||
id_table = create_containers (iter);
|
||||
|
||||
|
||||
/* step 2 -- the root_set is the list of children without parent */
|
||||
root_set = find_root_set (id_table);
|
||||
|
||||
|
@ -78,22 +78,22 @@ mu_threader_calculate (MuMsgIter *iter, size_t matchnum, MuMsgFieldId sortfield)
|
|||
|
||||
/* step 4: prune empty containers */
|
||||
root_set = prune_empty_containers (root_set);
|
||||
|
||||
|
||||
/* sort root set */
|
||||
if (sortfield != MU_MSG_FIELD_ID_NONE)
|
||||
root_set = mu_container_sort (root_set, sortfield,
|
||||
NULL, FALSE);
|
||||
|
||||
|
||||
/* step 5: group root set by subject */
|
||||
//group_root_set_by_subject (root_set);
|
||||
|
||||
/* sort */
|
||||
mu_msg_iter_reset (iter); /* go all the way back */
|
||||
|
||||
|
||||
/* finally, deliver the docid => thread-path hash */
|
||||
thread_ids = mu_container_thread_info_hash_new (root_set,
|
||||
matchnum);
|
||||
|
||||
|
||||
g_hash_table_destroy (id_table); /* step 3*/
|
||||
|
||||
return thread_ids;
|
||||
|
@ -119,11 +119,11 @@ assert_no_duplicates (GHashTable *ids)
|
|||
GHashTable *hash;
|
||||
|
||||
hash = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
|
||||
|
||||
g_hash_table_foreach (ids,
|
||||
(GHFunc)check_dup,
|
||||
hash);
|
||||
|
||||
|
||||
g_hash_table_destroy (hash);
|
||||
}
|
||||
|
||||
|
@ -140,7 +140,7 @@ find_or_create_referred (GHashTable *id_table, const char *msgid,
|
|||
|
||||
g_return_val_if_fail (msgid, NULL);
|
||||
|
||||
c = g_hash_table_lookup (id_table, msgid);
|
||||
c = g_hash_table_lookup (id_table, msgid);
|
||||
*created = !c;
|
||||
if (!c) {
|
||||
c = mu_container_new (NULL, 0, msgid);
|
||||
|
@ -148,7 +148,7 @@ find_or_create_referred (GHashTable *id_table, const char *msgid,
|
|||
/* assert_no_duplicates (id_table); */
|
||||
}
|
||||
|
||||
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -162,13 +162,13 @@ find_or_create (GHashTable *id_table, MuMsg *msg, guint docid)
|
|||
|
||||
g_return_val_if_fail (msg, NULL);
|
||||
g_return_val_if_fail (docid != 0, NULL);
|
||||
|
||||
|
||||
msgid = mu_msg_get_msgid (msg);
|
||||
if (!msgid)
|
||||
msgid = mu_msg_get_path (msg); /* fake it */
|
||||
|
||||
c = g_hash_table_lookup (id_table, msgid);
|
||||
|
||||
|
||||
c = g_hash_table_lookup (id_table, msgid);
|
||||
|
||||
/* If id_table contains an empty MuContainer for this ID: * *
|
||||
* Store this message in the MuContainer's message slot. */
|
||||
if (c) {
|
||||
|
@ -200,14 +200,14 @@ find_or_create (GHashTable *id_table, MuMsg *msg, guint docid)
|
|||
c = mu_container_new (msg, docid, msgid);
|
||||
g_hash_table_insert (id_table, (gpointer)msgid, c);
|
||||
/* assert_no_duplicates (id_table); */
|
||||
|
||||
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
child_elligible (MuContainer *parent, MuContainer *child, gboolean created)
|
||||
{
|
||||
{
|
||||
if (!parent || !child)
|
||||
return FALSE;
|
||||
if (child->parent)
|
||||
|
@ -230,25 +230,25 @@ handle_references (GHashTable *id_table, MuContainer *c)
|
|||
const GSList *refs, *cur;
|
||||
MuContainer *parent;
|
||||
gboolean created;
|
||||
|
||||
|
||||
refs = mu_msg_get_references (c->msg);
|
||||
if (!refs)
|
||||
if (!refs)
|
||||
return; /* nothing to do */
|
||||
|
||||
|
||||
/* For each element in the message's References field:
|
||||
|
||||
Find a MuContainer object for the given Message-ID: If
|
||||
there's one in id_table use that; Otherwise, make (and
|
||||
index) one with a null Message. */
|
||||
|
||||
/* go over over our list of refs, until 1 before the last... */
|
||||
|
||||
/* go over over our list of refs, until 1 before the last... */
|
||||
created = FALSE;
|
||||
for (parent = NULL, cur = refs; cur; cur = g_slist_next (cur)) {
|
||||
|
||||
MuContainer *child;
|
||||
child = find_or_create_referred (id_table, (gchar*)cur->data,
|
||||
&created);
|
||||
|
||||
|
||||
/*Link the References field's MuContainers together in
|
||||
* the order implied by the References header.
|
||||
|
||||
|
@ -261,13 +261,13 @@ handle_references (GHashTable *id_table, MuContainer *c)
|
|||
as a child of the other, don't add the link. */
|
||||
|
||||
if (child_elligible (parent, child, created))
|
||||
parent = mu_container_append_children (parent, child);
|
||||
parent = mu_container_append_children (parent, child);
|
||||
|
||||
parent = child;
|
||||
}
|
||||
|
||||
/* 'parent' points to the last ref: our direct parent;
|
||||
|
||||
/* 'parent' points to the last ref: our direct parent;
|
||||
|
||||
Set the parent of this message to be the last element in
|
||||
References. Note that this message may have a parent
|
||||
already: this can happen because we saw this ID in a
|
||||
|
@ -276,12 +276,12 @@ handle_references (GHashTable *id_table, MuContainer *c)
|
|||
we can be more definitive, so throw away the old parent and
|
||||
use this new one. Find this MuContainer in the parent's
|
||||
children list, and unlink it.
|
||||
|
||||
|
||||
Note that this could cause this message to now have no
|
||||
parent, if it has no references field, but some message
|
||||
referred to it as the non-first element of its
|
||||
references. (Which would have been some kind of lie...)
|
||||
|
||||
|
||||
Note that at all times, the various ``parent'' and ``child'' fields
|
||||
must be kept inter-consistent. */
|
||||
|
||||
|
@ -302,24 +302,24 @@ create_containers (MuMsgIter *iter)
|
|||
g_str_equal,
|
||||
NULL,
|
||||
(GDestroyNotify)mu_container_destroy);
|
||||
|
||||
|
||||
for (mu_msg_iter_reset (iter); !mu_msg_iter_is_done (iter);
|
||||
mu_msg_iter_next (iter)) {
|
||||
|
||||
|
||||
MuContainer *c;
|
||||
MuMsg *msg;
|
||||
unsigned docid;
|
||||
|
||||
|
||||
/* 1.A */
|
||||
msg = mu_msg_iter_get_msg (iter, NULL);
|
||||
msg = mu_msg_iter_get_msg_floating (iter); /* don't unref */
|
||||
docid = mu_msg_iter_get_docid (iter);
|
||||
|
||||
|
||||
c = find_or_create (id_table, msg, docid);
|
||||
|
||||
/* 1.B and C */
|
||||
if (c)
|
||||
handle_references (id_table, c);
|
||||
}
|
||||
handle_references (id_table, c);
|
||||
}
|
||||
|
||||
return id_table;
|
||||
}
|
||||
|
@ -330,7 +330,7 @@ static void
|
|||
filter_root_set (const gchar *msgid, MuContainer *c, MuContainer **root_set)
|
||||
{
|
||||
if (c->parent)
|
||||
return;
|
||||
return;
|
||||
|
||||
if (*root_set == NULL) {
|
||||
*root_set = c;
|
||||
|
@ -358,25 +358,25 @@ static gboolean
|
|||
prune_maybe (MuContainer *c)
|
||||
{
|
||||
MuContainer *cur;
|
||||
|
||||
|
||||
for (cur = c->child; cur; cur = cur->next) {
|
||||
if (cur->flags & MU_CONTAINER_FLAG_DELETE)
|
||||
if (cur->flags & MU_CONTAINER_FLAG_DELETE)
|
||||
c = mu_container_remove_child (c, cur);
|
||||
else if (cur->flags & MU_CONTAINER_FLAG_SPLICE)
|
||||
else if (cur->flags & MU_CONTAINER_FLAG_SPLICE)
|
||||
c = mu_container_splice_children (c, cur);
|
||||
}
|
||||
|
||||
|
||||
/* don't touch containers with messages */
|
||||
if (c->msg)
|
||||
if (c->msg)
|
||||
return TRUE;
|
||||
|
||||
|
||||
/* A. If it is an msg-less container with no children, mark it
|
||||
* for deletion. */
|
||||
if (!c->child) {
|
||||
c->flags |= MU_CONTAINER_FLAG_DELETE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* B. If the MuContainer has no Message, but does have
|
||||
* children, remove this container but promote its
|
||||
* children to this level (that is, splice them in to
|
||||
|
@ -388,9 +388,9 @@ prune_maybe (MuContainer *c)
|
|||
*/
|
||||
if (c->child->next) /* ie., > 1 child */
|
||||
return TRUE;
|
||||
|
||||
|
||||
c->flags |= MU_CONTAINER_FLAG_SPLICE;
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -401,11 +401,11 @@ prune_empty_containers (MuContainer *root_set)
|
|||
MuContainer *cur;
|
||||
|
||||
mu_container_foreach (root_set, (MuContainerForeachFunc)prune_maybe, NULL);
|
||||
|
||||
|
||||
/* and prune the root_set itself... */
|
||||
for (cur = root_set; cur; cur = cur->next) {
|
||||
|
||||
if (cur->flags & MU_CONTAINER_FLAG_DELETE)
|
||||
|
||||
if (cur->flags & MU_CONTAINER_FLAG_DELETE)
|
||||
root_set = mu_container_remove_sibling (root_set, cur);
|
||||
|
||||
else if (cur->flags & MU_CONTAINER_FLAG_SPLICE) {
|
||||
|
|
102
src/mu-util.c
102
src/mu-util.c
|
@ -1,6 +1,6 @@
|
|||
/* -*-mode: c; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-*/
|
||||
/*
|
||||
**
|
||||
**
|
||||
** Copyright (C) 2008-2011 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
|
@ -63,12 +63,12 @@ do_wordexp (const char *path)
|
|||
/* g_debug ("%s: path is empty", __FUNCTION__); */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (wordexp (path, &wexp, 0) != 0) {
|
||||
/* g_debug ("%s: expansion failed for %s", __FUNCTION__, path); */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* we just pick the first one */
|
||||
dir = g_strdup (wexp.we_wordv[0]);
|
||||
|
||||
|
@ -76,7 +76,7 @@ do_wordexp (const char *path)
|
|||
so we have to allow for a tiny leak here on that
|
||||
platform... maybe instead of __APPLE__ it should be
|
||||
__BSD__?*/
|
||||
#ifndef __APPLE__
|
||||
#ifndef __APPLE__
|
||||
wordfree (&wexp);
|
||||
#endif /*__APPLE__*/
|
||||
|
||||
|
@ -102,16 +102,16 @@ mu_util_dir_expand (const char *path)
|
|||
/* don't try realpath if the dir does not exist */
|
||||
if (access (dir, F_OK) != 0)
|
||||
return dir;
|
||||
|
||||
|
||||
/* now resolve any symlinks, .. etc. */
|
||||
if (realpath (dir, resolved) == NULL) {
|
||||
g_debug ("%s: could not get realpath for '%s': %s",
|
||||
__FUNCTION__, dir, strerror(errno));
|
||||
g_free (dir);
|
||||
return NULL;
|
||||
} else
|
||||
} else
|
||||
g_free (dir);
|
||||
|
||||
|
||||
return g_strdup (resolved);
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ char*
|
|||
mu_util_create_tmpdir (void)
|
||||
{
|
||||
gchar *dirname;
|
||||
|
||||
|
||||
dirname = g_strdup_printf ("%s%cmu-%d%c%x",
|
||||
g_get_tmp_dir(),
|
||||
G_DIR_SEPARATOR,
|
||||
|
@ -141,7 +141,7 @@ const char*
|
|||
mu_util_cache_dir (void)
|
||||
{
|
||||
static char cachedir [PATH_MAX];
|
||||
|
||||
|
||||
snprintf (cachedir, sizeof(cachedir), "%s%cmu-%u",
|
||||
g_get_tmp_dir(), G_DIR_SEPARATOR,
|
||||
getuid());
|
||||
|
@ -170,9 +170,9 @@ mu_util_init_system (void)
|
|||
}
|
||||
/* g_debug ("setting G_SLICE to always-malloc"); */
|
||||
#endif /*!__linux__*/
|
||||
|
||||
|
||||
g_type_init ();
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -182,10 +182,10 @@ mu_util_check_dir (const gchar* path, gboolean readable, gboolean writeable)
|
|||
{
|
||||
int mode;
|
||||
struct stat statbuf;
|
||||
|
||||
if (!path)
|
||||
|
||||
if (!path)
|
||||
return FALSE;
|
||||
|
||||
|
||||
mode = F_OK | (readable ? R_OK : 0) | (writeable ? W_OK : 0);
|
||||
|
||||
if (access (path, mode) != 0) {
|
||||
|
@ -197,7 +197,7 @@ mu_util_check_dir (const gchar* path, gboolean readable, gboolean writeable)
|
|||
g_debug ("Cannot stat %s: %s", path, strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
return S_ISDIR(statbuf.st_mode) ? TRUE: FALSE;
|
||||
}
|
||||
|
||||
|
@ -207,18 +207,18 @@ mu_util_guess_maildir (void)
|
|||
{
|
||||
const gchar *mdir1;
|
||||
gchar *mdir2;
|
||||
|
||||
|
||||
/* first, try MAILDIR */
|
||||
mdir1 = g_getenv ("MAILDIR");
|
||||
|
||||
if (mdir1 && mu_util_check_dir (mdir1, TRUE, FALSE))
|
||||
return g_strdup (mdir1);
|
||||
|
||||
|
||||
/* then, try ~/Maildir */
|
||||
mdir2 = mu_util_dir_expand ("~/Maildir");
|
||||
if (mu_util_check_dir (mdir2, TRUE, FALSE))
|
||||
return mdir2;
|
||||
|
||||
|
||||
/* nope; nothing found */
|
||||
return NULL;
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ mu_util_guess_mu_homedir (void)
|
|||
|
||||
if (!home)
|
||||
MU_WRITE_LOG ("failed to determine homedir");
|
||||
|
||||
|
||||
return g_strdup_printf ("%s%c%s", home ? home : ".", G_DIR_SEPARATOR,
|
||||
".mu");
|
||||
}
|
||||
|
@ -244,10 +244,10 @@ gboolean
|
|||
mu_util_create_dir_maybe (const gchar *path, mode_t mode, gboolean nowarn)
|
||||
{
|
||||
struct stat statbuf;
|
||||
|
||||
|
||||
g_return_val_if_fail (path, FALSE);
|
||||
|
||||
/* if it exists, it must be a readable dir */
|
||||
/* if it exists, it must be a readable dir */
|
||||
if (stat (path, &statbuf) == 0) {
|
||||
if ((!S_ISDIR(statbuf.st_mode)) ||
|
||||
(access (path, W_OK|R_OK) != 0)) {
|
||||
|
@ -256,8 +256,8 @@ mu_util_create_dir_maybe (const gchar *path, mode_t mode, gboolean nowarn)
|
|||
"directory: %s", path);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (g_mkdir_with_parents (path, mode) != 0) {
|
||||
if (!nowarn)
|
||||
g_warning ("failed to create %s: %s",
|
||||
|
@ -274,22 +274,22 @@ mu_util_str_from_strv (const gchar **params)
|
|||
{
|
||||
GString *str;
|
||||
int i;
|
||||
|
||||
|
||||
g_return_val_if_fail (params, NULL);
|
||||
|
||||
|
||||
if (!params[0])
|
||||
return g_strdup ("");
|
||||
|
||||
|
||||
str = g_string_sized_new (64); /* just a guess */
|
||||
|
||||
|
||||
for (i = 0; params[i]; ++i) {
|
||||
|
||||
if (i>0)
|
||||
g_string_append_c (str, ' ');
|
||||
|
||||
g_string_append (str, params[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
|
@ -299,7 +299,7 @@ mu_util_create_writeable_fd (const char* path, mode_t mode,
|
|||
{
|
||||
errno = 0; /* clear! */
|
||||
g_return_val_if_fail (path, -1);
|
||||
|
||||
|
||||
if (overwrite)
|
||||
return open (path, O_WRONLY|O_CREAT|O_TRUNC, mode);
|
||||
else
|
||||
|
@ -315,11 +315,11 @@ mu_util_is_local_file (const char* path)
|
|||
* still considered local) */
|
||||
if (g_ascii_strncasecmp ("file://", path, strlen("file://")) == 0)
|
||||
return TRUE;
|
||||
|
||||
|
||||
if (access (path, R_OK) == 0)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -329,11 +329,11 @@ mu_util_play (const char *path, gboolean allow_local, gboolean allow_remote)
|
|||
#ifndef XDGOPEN
|
||||
g_warning ("opening files not supported (xdg-open missing)");
|
||||
return FALSE;
|
||||
#else
|
||||
#else
|
||||
gboolean rv;
|
||||
GError *err;
|
||||
const gchar *argv[3];
|
||||
|
||||
|
||||
g_return_val_if_fail (path, FALSE);
|
||||
g_return_val_if_fail (mu_util_is_local_file (path) || allow_remote,
|
||||
FALSE);
|
||||
|
@ -342,11 +342,11 @@ mu_util_play (const char *path, gboolean allow_local, gboolean allow_remote)
|
|||
argv[0] = XDGOPEN;
|
||||
argv[1] = path;
|
||||
argv[2] = NULL;
|
||||
|
||||
|
||||
err = NULL;
|
||||
rv = g_spawn_async (NULL, (gchar**)&argv, NULL, 0,
|
||||
NULL, NULL, NULL, &err);
|
||||
|
||||
|
||||
if (!rv) {
|
||||
g_warning ("failed to spawn xdg-open: %s",
|
||||
err->message ? err->message : "error");
|
||||
|
@ -362,14 +362,14 @@ unsigned char
|
|||
mu_util_get_dtype_with_lstat (const char *path)
|
||||
{
|
||||
struct stat statbuf;
|
||||
|
||||
|
||||
g_return_val_if_fail (path, DT_UNKNOWN);
|
||||
|
||||
|
||||
if (lstat (path, &statbuf) != 0) {
|
||||
g_warning ("stat failed on %s: %s", path, strerror(errno));
|
||||
return DT_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
/* we only care about dirs, regular files and links */
|
||||
if (S_ISREG (statbuf.st_mode))
|
||||
return DT_REG;
|
||||
|
@ -387,10 +387,10 @@ mu_util_locale_is_utf8 (void)
|
|||
{
|
||||
const gchar *dummy;
|
||||
static int is_utf8 = -1;
|
||||
|
||||
if (G_UNLIKELY(is_utf8 == -1))
|
||||
|
||||
if (G_UNLIKELY(is_utf8 == -1))
|
||||
is_utf8 = g_get_charset(&dummy) ? 1 : 0;
|
||||
|
||||
|
||||
return is_utf8 ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
|
@ -399,19 +399,19 @@ mu_util_fputs_encoded (const char *str, FILE *stream)
|
|||
{
|
||||
char *conv;
|
||||
int rv;
|
||||
|
||||
|
||||
g_return_val_if_fail (str, FALSE);
|
||||
g_return_val_if_fail (stream, FALSE);
|
||||
|
||||
|
||||
/* g_get_charset return TRUE when the locale is UTF8 */
|
||||
if (mu_util_locale_is_utf8())
|
||||
if (mu_util_locale_is_utf8())
|
||||
rv = fputs (str, stream);
|
||||
else { /* charset is _not_ utf8, so we actually have to
|
||||
* convert it..*/
|
||||
GError *err;
|
||||
unsigned bytes;
|
||||
err = NULL;
|
||||
|
||||
|
||||
conv = g_locale_from_utf8 (str, -1, &bytes, NULL, &err);
|
||||
if (err) {
|
||||
/* conversion failed; this happens because is
|
||||
|
@ -427,7 +427,7 @@ mu_util_fputs_encoded (const char *str, FILE *stream)
|
|||
rv = fputs (conv, stream);
|
||||
g_free (conv);
|
||||
}
|
||||
|
||||
|
||||
if (rv == EOF) { /* note, apparently, does not set errno */
|
||||
g_printerr ("fputs failed");
|
||||
return FALSE;
|
||||
|
@ -442,7 +442,7 @@ print_args (FILE *stream, const char *frm, va_list args)
|
|||
{
|
||||
gchar *str;
|
||||
gboolean rv;
|
||||
|
||||
|
||||
str = g_strdup_vprintf (frm, args);
|
||||
|
||||
rv = mu_util_fputs_encoded (str, stream);
|
||||
|
@ -460,7 +460,7 @@ mu_util_print_encoded (const char *frm, ...)
|
|||
gboolean rv;
|
||||
|
||||
g_return_val_if_fail (frm, FALSE);
|
||||
|
||||
|
||||
va_start (args, frm);
|
||||
rv = print_args (stdout, frm, args);
|
||||
va_end (args);
|
||||
|
@ -475,10 +475,12 @@ mu_util_printerr_encoded (const char *frm, ...)
|
|||
gboolean rv;
|
||||
|
||||
g_return_val_if_fail (frm, FALSE);
|
||||
|
||||
|
||||
va_start (args, frm);
|
||||
rv = print_args (stderr, frm, args);
|
||||
va_end (args);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -255,6 +255,18 @@ typedef gpointer XapianDocument;
|
|||
typedef gpointer XapianEnquire;
|
||||
|
||||
|
||||
/* print a warning for a GError, and free it */
|
||||
#define MU_HANDLE_G_ERROR(GE) \
|
||||
do { \
|
||||
if (!(GE)) \
|
||||
g_warning ("%s:%u: an error occured in %s", \
|
||||
__FILE__, __LINE__, __FUNCTION__); \
|
||||
else { \
|
||||
g_warning ("error %u: %s", (GE)->code, (GE)->message); \
|
||||
g_error_free ((GE)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue