+Tue Apr 3 13:46:22 2001 Tim Janik <timj@gtk.org>
+
+ * glist.[hc]: added g_list_nth_prev() which walks ->prev instead
+ of ->next.
+
+ * gpattern.[hc]: added shell-style pattern matching code from beast,
+ derived from the gtk_pattern_*() code, but with a couple of bug fixes
+ and a number of optimizations.
+
2001-04-03 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthreadpool.c: Added documentation.
+Tue Apr 3 13:46:22 2001 Tim Janik <timj@gtk.org>
+
+ * glist.[hc]: added g_list_nth_prev() which walks ->prev instead
+ of ->next.
+
+ * gpattern.[hc]: added shell-style pattern matching code from beast,
+ derived from the gtk_pattern_*() code, but with a couple of bug fixes
+ and a number of optimizations.
+
2001-04-03 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthreadpool.c: Added documentation.
+Tue Apr 3 13:46:22 2001 Tim Janik <timj@gtk.org>
+
+ * glist.[hc]: added g_list_nth_prev() which walks ->prev instead
+ of ->next.
+
+ * gpattern.[hc]: added shell-style pattern matching code from beast,
+ derived from the gtk_pattern_*() code, but with a couple of bug fixes
+ and a number of optimizations.
+
2001-04-03 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthreadpool.c: Added documentation.
+Tue Apr 3 13:46:22 2001 Tim Janik <timj@gtk.org>
+
+ * glist.[hc]: added g_list_nth_prev() which walks ->prev instead
+ of ->next.
+
+ * gpattern.[hc]: added shell-style pattern matching code from beast,
+ derived from the gtk_pattern_*() code, but with a couple of bug fixes
+ and a number of optimizations.
+
2001-04-03 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthreadpool.c: Added documentation.
+Tue Apr 3 13:46:22 2001 Tim Janik <timj@gtk.org>
+
+ * glist.[hc]: added g_list_nth_prev() which walks ->prev instead
+ of ->next.
+
+ * gpattern.[hc]: added shell-style pattern matching code from beast,
+ derived from the gtk_pattern_*() code, but with a couple of bug fixes
+ and a number of optimizations.
+
2001-04-03 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthreadpool.c: Added documentation.
+Tue Apr 3 13:46:22 2001 Tim Janik <timj@gtk.org>
+
+ * glist.[hc]: added g_list_nth_prev() which walks ->prev instead
+ of ->next.
+
+ * gpattern.[hc]: added shell-style pattern matching code from beast,
+ derived from the gtk_pattern_*() code, but with a couple of bug fixes
+ and a number of optimizations.
+
2001-04-03 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthreadpool.c: Added documentation.
+Tue Apr 3 13:46:22 2001 Tim Janik <timj@gtk.org>
+
+ * glist.[hc]: added g_list_nth_prev() which walks ->prev instead
+ of ->next.
+
+ * gpattern.[hc]: added shell-style pattern matching code from beast,
+ derived from the gtk_pattern_*() code, but with a couple of bug fixes
+ and a number of optimizations.
+
2001-04-03 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthreadpool.c: Added documentation.
+Tue Apr 3 13:46:22 2001 Tim Janik <timj@gtk.org>
+
+ * glist.[hc]: added g_list_nth_prev() which walks ->prev instead
+ of ->next.
+
+ * gpattern.[hc]: added shell-style pattern matching code from beast,
+ derived from the gtk_pattern_*() code, but with a couple of bug fixes
+ and a number of optimizations.
+
2001-04-03 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthreadpool.c: Added documentation.
gmem.c \
gmessages.c \
gnode.c \
+ gpattern.c \
gprimes.c \
gqsort.c \
gqueue.c \
gmem.h \
gmessages.h \
gnode.h \
+ gpattern.h \
gprimes.h \
gqsort.h \
gquark.h \
type of source.
@Returns: TRUE if an event source was found and removed.
+<!-- ##### FUNCTION g_static_private_get_for_thread ##### -->
+<para>
+
+</para>
+
+@private_key:
+@thread:
+@Returns:
+
+<!-- ##### FUNCTION g_static_private_set_for_thread ##### -->
+<para>
+
+</para>
+
+@private_key:
+@thread:
+@data:
+@notify:
+
<!-- ##### MACRO g_string ##### -->
<para>
Turns the argument into a string literal by using the '#' stringizing operator.
@f:
-<!-- ##### TYPEDEF GCallback ##### -->
+<!-- ##### USER_FUNCTION GCallback ##### -->
<para>
</para>
+
<!-- ##### STRUCT GClosure ##### -->
<para>
#include <gmem.h>
#include <gmessages.h>
#include <gnode.h>
+#include <gpattern.h>
#include <gprimes.h>
#include <gqsort.h>
#include <gquark.h>
gmem.c \
gmessages.c \
gnode.c \
+ gpattern.c \
gprimes.c \
gqsort.c \
gqueue.c \
gmem.h \
gmessages.h \
gnode.h \
+ gpattern.h \
gprimes.h \
gqsort.h \
gquark.h \
#include <gmem.h>
#include <gmessages.h>
#include <gnode.h>
+#include <gpattern.h>
#include <gprimes.h>
#include <gqsort.h>
#include <gquark.h>
return list;
}
+GList*
+g_list_nth_prev (GList *list,
+ guint n)
+{
+ while ((n-- > 0) && list)
+ list = list->prev;
+
+ return list;
+}
+
gpointer
g_list_nth_data (GList *list,
guint n)
GList* g_list_copy (GList *list);
GList* g_list_nth (GList *list,
guint n);
+GList* g_list_nth_prev (GList *list,
+ guint n);
GList* g_list_find (GList *list,
gconstpointer data);
GList* g_list_find_custom (GList *list,
--- /dev/null
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997, 1999 Peter Mattis, Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "gpattern.h"
+
+#include "gmacros.h"
+#include "gmessages.h"
+#include "gmem.h"
+#include <string.h>
+
+
+/* --- functions --- */
+static inline gboolean
+g_pattern_ph_match (const gchar *match_pattern,
+ const gchar *match_string)
+{
+ register const gchar *pattern, *string;
+ register gchar ch;
+
+ pattern = match_pattern;
+ string = match_string;
+
+ ch = *pattern;
+ pattern++;
+ while (ch)
+ {
+ switch (ch)
+ {
+ case '?':
+ if (!*string)
+ return FALSE;
+ string++;
+ break;
+
+ case '*':
+ do
+ {
+ ch = *pattern;
+ pattern++;
+ if (ch == '?')
+ {
+ if (!*string)
+ return FALSE;
+ string++;
+ }
+ }
+ while (ch == '*' || ch == '?');
+ if (!ch)
+ return TRUE;
+ do
+ {
+ while (ch != *string)
+ {
+ if (!*string)
+ return FALSE;
+ string++;
+ }
+ string++;
+ if (g_pattern_ph_match (pattern, string))
+ return TRUE;
+ }
+ while (*string);
+ break;
+
+ default:
+ if (ch == *string)
+ string++;
+ else
+ return FALSE;
+ break;
+ }
+
+ ch = *pattern;
+ pattern++;
+ }
+
+ return *string == 0;
+}
+
+gboolean
+g_pattern_match (GPatternSpec *pspec,
+ guint string_length,
+ const gchar *string,
+ const gchar *string_reversed)
+{
+ g_return_val_if_fail (pspec != NULL, FALSE);
+ g_return_val_if_fail (string != NULL, FALSE);
+ g_return_val_if_fail (string_reversed != NULL, FALSE);
+
+ switch (pspec->match_type)
+ {
+ case G_MATCH_ALL:
+ return g_pattern_ph_match (pspec->pattern, string);
+
+ case G_MATCH_ALL_TAIL:
+ return g_pattern_ph_match (pspec->pattern_reversed, string_reversed);
+
+ case G_MATCH_HEAD:
+ if (pspec->pattern_length > string_length)
+ return FALSE;
+ else if (pspec->pattern_length == string_length)
+ return strcmp (pspec->pattern, string) == 0;
+ else if (pspec->pattern_length)
+ return strncmp (pspec->pattern, string, pspec->pattern_length) == 0;
+ else
+ return TRUE;
+
+ case G_MATCH_TAIL:
+ if (pspec->pattern_length > string_length)
+ return FALSE;
+ else if (pspec->pattern_length == string_length)
+ return strcmp (pspec->pattern_reversed, string_reversed) == 0;
+ else if (pspec->pattern_length)
+ return strncmp (pspec->pattern_reversed,
+ string_reversed,
+ pspec->pattern_length) == 0;
+ else
+ return TRUE;
+
+ case G_MATCH_EXACT:
+ if (pspec->pattern_length != string_length)
+ return FALSE;
+ else
+ return strcmp (pspec->pattern_reversed, string_reversed) == 0;
+
+ default:
+ g_return_val_if_fail (pspec->match_type < G_MATCH_LAST, FALSE);
+ return FALSE;
+ }
+}
+
+GPatternSpec*
+g_pattern_spec_new (const gchar *pattern)
+{
+ GPatternSpec *pspec;
+ gchar *p, *t;
+ const gchar *h;
+ guint hw = 0, tw = 0, hj = 0, tj = 0;
+
+ g_return_val_if_fail (pattern != NULL, NULL);
+
+ pspec = g_new (GPatternSpec, 1);
+ pspec->pattern_length = strlen (pattern);
+ pspec->pattern = strcpy (g_new (gchar, pspec->pattern_length + 1), pattern);
+ pspec->pattern_reversed = g_new (gchar, pspec->pattern_length + 1);
+ t = pspec->pattern_reversed + pspec->pattern_length;
+ *(t--) = 0;
+ h = pattern;
+ while (t >= pspec->pattern_reversed)
+ {
+ register gchar c = *(h++);
+
+ if (c == '*')
+ {
+ if (t < h)
+ hw++;
+ else
+ tw++;
+ }
+ else if (c == '?')
+ {
+ if (t < h)
+ hj++;
+ else
+ tj++;
+ }
+
+ *(t--) = c;
+ }
+ pspec->match_type = hw > tw || (hw == tw && hj > tj) ? G_MATCH_ALL_TAIL : G_MATCH_ALL;
+
+ if (hj || tj)
+ return pspec;
+
+ if (hw == 0 && tw == 0)
+ {
+ pspec->match_type = G_MATCH_EXACT;
+ return pspec;
+ }
+
+ if (hw)
+ {
+ p = pspec->pattern;
+ while (*p == '*')
+ p++;
+ if (p > pspec->pattern && !strchr (p, '*'))
+ {
+ gchar *tmp;
+
+ pspec->match_type = G_MATCH_TAIL;
+ pspec->pattern_length = strlen (p);
+ tmp = pspec->pattern;
+ pspec->pattern = strcpy (g_new (gchar, pspec->pattern_length + 1), p);
+ g_free (tmp);
+ g_free (pspec->pattern_reversed);
+ pspec->pattern_reversed = g_new (gchar, pspec->pattern_length + 1);
+ t = pspec->pattern_reversed + pspec->pattern_length;
+ *(t--) = 0;
+ h = pspec->pattern;
+ while (t >= pspec->pattern_reversed)
+ *(t--) = *(h++);
+ return pspec;
+ }
+ }
+
+ if (tw)
+ {
+ p = pspec->pattern_reversed;
+ while (*p == '*')
+ p++;
+ if (p > pspec->pattern_reversed && !strchr (p, '*'))
+ {
+ gchar *tmp;
+
+ pspec->match_type = G_MATCH_HEAD;
+ pspec->pattern_length = strlen (p);
+ tmp = pspec->pattern_reversed;
+ pspec->pattern_reversed = strcpy (g_new (gchar, pspec->pattern_length + 1), p);
+ g_free (tmp);
+ g_free (pspec->pattern);
+ pspec->pattern = g_new (gchar, pspec->pattern_length + 1);
+ t = pspec->pattern + pspec->pattern_length;
+ *(t--) = 0;
+ h = pspec->pattern_reversed;
+ while (t >= pspec->pattern)
+ *(t--) = *(h++);
+ }
+ }
+
+ return pspec;
+}
+
+gboolean
+g_pattern_match_string (GPatternSpec *pspec,
+ const gchar *string)
+{
+ gchar *string_reversed, *t;
+ const gchar *h;
+ guint length;
+ gboolean ergo;
+
+ g_return_val_if_fail (pspec != NULL, FALSE);
+ g_return_val_if_fail (string != NULL, FALSE);
+
+ length = strlen (string);
+ string_reversed = g_new (gchar, length + 1);
+ t = string_reversed + length;
+ *(t--) = 0;
+ h = string;
+ while (t >= string_reversed)
+ *(t--) = *(h++);
+
+ ergo = g_pattern_match (pspec, length, string, string_reversed);
+ g_free (string_reversed);
+
+ return ergo;
+}
+
+gboolean
+g_pattern_match_simple (const gchar *pattern,
+ const gchar *string)
+{
+ GPatternSpec *pspec;
+ gboolean ergo;
+
+ g_return_val_if_fail (pattern != NULL, FALSE);
+ g_return_val_if_fail (string != NULL, FALSE);
+
+ pspec = g_pattern_spec_new (pattern);
+ ergo = g_pattern_match_string (pspec, string);
+ g_pattern_spec_free (pspec);
+
+ return ergo;
+}
+
+void
+g_pattern_spec_free (GPatternSpec *pspec)
+{
+ g_return_if_fail (pspec != NULL);
+
+ g_free (pspec->pattern);
+ g_free (pspec->pattern_reversed);
+ g_free (pspec);
+}
--- /dev/null
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997, 1999 Peter Mattis, Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __G_PATTERN_H__
+#define __G_PATTERN_H__
+
+#include <gtypes.h>
+
+G_BEGIN_DECLS
+
+typedef enum
+{
+ G_MATCH_ALL, /* "*A?A*" */
+ G_MATCH_ALL_TAIL, /* "*A?AA" */
+ G_MATCH_HEAD, /* "AAAA*" */
+ G_MATCH_TAIL, /* "*AAAA" */
+ G_MATCH_EXACT, /* "AAAAA" */
+ G_MATCH_LAST
+} GMatchType;
+
+typedef struct _GPatternSpec GPatternSpec;
+struct _GPatternSpec
+{
+ GMatchType match_type;
+ guint pattern_length;
+ gchar *pattern;
+ gchar *pattern_reversed;
+};
+
+GPatternSpec* g_pattern_spec_new (const gchar *pattern);
+void g_pattern_spec_free (GPatternSpec *pspec);
+gboolean g_pattern_match (GPatternSpec *pspec,
+ guint string_length,
+ const gchar *string,
+ const gchar *string_reversed);
+gboolean g_pattern_match_string (GPatternSpec *pspec,
+ const gchar *string);
+gboolean g_pattern_match_simple (const gchar *pattern,
+ const gchar *string);
+
+G_END_DECLS
+
+#endif /* __G_PATTERN_H__ */
return list;
}
+GList*
+g_list_nth_prev (GList *list,
+ guint n)
+{
+ while ((n-- > 0) && list)
+ list = list->prev;
+
+ return list;
+}
+
gpointer
g_list_nth_data (GList *list,
guint n)
GList* g_list_copy (GList *list);
GList* g_list_nth (GList *list,
guint n);
+GList* g_list_nth_prev (GList *list,
+ guint n);
GList* g_list_find (GList *list,
gconstpointer data);
GList* g_list_find_custom (GList *list,
+Tue Apr 3 14:06:00 2001 Tim Janik <timj@gtk.org>
+
+ * gparam.[hc]: added g_param_spec_pool_list() to list pspecs per
+ owner_type. the pspecs are not referenced, so the caller is
+ supposed to have some idea about owner_type not randomly
+ nuking his pspec's. if this is going to provide problems in
+ the future, we can either auto-ref the pspecs, or add a
+ _foreach variant, though the latter would have to invoke
+ the callback while pspec's mutex is acquired, so i just
+ went for the _list variant for now.
+
+ * gclosure.h (G_CALLBACK): made GCallback a void (*) (void) fucntion.
+
Sat Mar 31 23:55:58 2001 Tim Janik <timj@gtk.org>
* gtype.h:
/* -- typedefs --- */
typedef struct _GClosure GClosure;
typedef struct _GClosureNotifyData GClosureNotifyData;
-typedef gpointer GCallback;
+typedef void (*GCallback) (void);
typedef void (*GClosureNotify) (gpointer data,
GClosure *closure);
typedef void (*GClosureMarshal) (GClosure *closure,
return NULL;
}
+static void
+pool_list (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ GParamSpec *pspec = value;
+ gpointer *data = user_data;
+ GType owner_type = GPOINTER_TO_UINT (data[1]);
+
+ if (owner_type == pspec->owner_type)
+ data[0] = g_list_prepend (data[0], pspec);
+}
+
+GList*
+g_param_spec_pool_list (GParamSpecPool *pool,
+ GType owner_type)
+{
+ gpointer data[2];
+
+ g_return_val_if_fail (pool != NULL, NULL);
+ g_return_val_if_fail (owner_type > 0, NULL);
+
+ G_SLOCK (&pool->smutex);
+ data[0] = NULL;
+ data[1] = GUINT_TO_POINTER (owner_type);
+ g_hash_table_foreach (pool->hash_table, pool_list, &data);
+ G_SUNLOCK (&pool->smutex);
+
+ return data[0];
+}
+
/* --- auxillary functions --- */
typedef struct
const gchar *param_name,
GType owner_type,
gboolean walk_ancestors);
+GList* g_param_spec_pool_list (GParamSpecPool *pool,
+ GType owner_type);
+
/* contracts:
--- /dev/null
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997, 1999 Peter Mattis, Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "gpattern.h"
+
+#include "gmacros.h"
+#include "gmessages.h"
+#include "gmem.h"
+#include <string.h>
+
+
+/* --- functions --- */
+static inline gboolean
+g_pattern_ph_match (const gchar *match_pattern,
+ const gchar *match_string)
+{
+ register const gchar *pattern, *string;
+ register gchar ch;
+
+ pattern = match_pattern;
+ string = match_string;
+
+ ch = *pattern;
+ pattern++;
+ while (ch)
+ {
+ switch (ch)
+ {
+ case '?':
+ if (!*string)
+ return FALSE;
+ string++;
+ break;
+
+ case '*':
+ do
+ {
+ ch = *pattern;
+ pattern++;
+ if (ch == '?')
+ {
+ if (!*string)
+ return FALSE;
+ string++;
+ }
+ }
+ while (ch == '*' || ch == '?');
+ if (!ch)
+ return TRUE;
+ do
+ {
+ while (ch != *string)
+ {
+ if (!*string)
+ return FALSE;
+ string++;
+ }
+ string++;
+ if (g_pattern_ph_match (pattern, string))
+ return TRUE;
+ }
+ while (*string);
+ break;
+
+ default:
+ if (ch == *string)
+ string++;
+ else
+ return FALSE;
+ break;
+ }
+
+ ch = *pattern;
+ pattern++;
+ }
+
+ return *string == 0;
+}
+
+gboolean
+g_pattern_match (GPatternSpec *pspec,
+ guint string_length,
+ const gchar *string,
+ const gchar *string_reversed)
+{
+ g_return_val_if_fail (pspec != NULL, FALSE);
+ g_return_val_if_fail (string != NULL, FALSE);
+ g_return_val_if_fail (string_reversed != NULL, FALSE);
+
+ switch (pspec->match_type)
+ {
+ case G_MATCH_ALL:
+ return g_pattern_ph_match (pspec->pattern, string);
+
+ case G_MATCH_ALL_TAIL:
+ return g_pattern_ph_match (pspec->pattern_reversed, string_reversed);
+
+ case G_MATCH_HEAD:
+ if (pspec->pattern_length > string_length)
+ return FALSE;
+ else if (pspec->pattern_length == string_length)
+ return strcmp (pspec->pattern, string) == 0;
+ else if (pspec->pattern_length)
+ return strncmp (pspec->pattern, string, pspec->pattern_length) == 0;
+ else
+ return TRUE;
+
+ case G_MATCH_TAIL:
+ if (pspec->pattern_length > string_length)
+ return FALSE;
+ else if (pspec->pattern_length == string_length)
+ return strcmp (pspec->pattern_reversed, string_reversed) == 0;
+ else if (pspec->pattern_length)
+ return strncmp (pspec->pattern_reversed,
+ string_reversed,
+ pspec->pattern_length) == 0;
+ else
+ return TRUE;
+
+ case G_MATCH_EXACT:
+ if (pspec->pattern_length != string_length)
+ return FALSE;
+ else
+ return strcmp (pspec->pattern_reversed, string_reversed) == 0;
+
+ default:
+ g_return_val_if_fail (pspec->match_type < G_MATCH_LAST, FALSE);
+ return FALSE;
+ }
+}
+
+GPatternSpec*
+g_pattern_spec_new (const gchar *pattern)
+{
+ GPatternSpec *pspec;
+ gchar *p, *t;
+ const gchar *h;
+ guint hw = 0, tw = 0, hj = 0, tj = 0;
+
+ g_return_val_if_fail (pattern != NULL, NULL);
+
+ pspec = g_new (GPatternSpec, 1);
+ pspec->pattern_length = strlen (pattern);
+ pspec->pattern = strcpy (g_new (gchar, pspec->pattern_length + 1), pattern);
+ pspec->pattern_reversed = g_new (gchar, pspec->pattern_length + 1);
+ t = pspec->pattern_reversed + pspec->pattern_length;
+ *(t--) = 0;
+ h = pattern;
+ while (t >= pspec->pattern_reversed)
+ {
+ register gchar c = *(h++);
+
+ if (c == '*')
+ {
+ if (t < h)
+ hw++;
+ else
+ tw++;
+ }
+ else if (c == '?')
+ {
+ if (t < h)
+ hj++;
+ else
+ tj++;
+ }
+
+ *(t--) = c;
+ }
+ pspec->match_type = hw > tw || (hw == tw && hj > tj) ? G_MATCH_ALL_TAIL : G_MATCH_ALL;
+
+ if (hj || tj)
+ return pspec;
+
+ if (hw == 0 && tw == 0)
+ {
+ pspec->match_type = G_MATCH_EXACT;
+ return pspec;
+ }
+
+ if (hw)
+ {
+ p = pspec->pattern;
+ while (*p == '*')
+ p++;
+ if (p > pspec->pattern && !strchr (p, '*'))
+ {
+ gchar *tmp;
+
+ pspec->match_type = G_MATCH_TAIL;
+ pspec->pattern_length = strlen (p);
+ tmp = pspec->pattern;
+ pspec->pattern = strcpy (g_new (gchar, pspec->pattern_length + 1), p);
+ g_free (tmp);
+ g_free (pspec->pattern_reversed);
+ pspec->pattern_reversed = g_new (gchar, pspec->pattern_length + 1);
+ t = pspec->pattern_reversed + pspec->pattern_length;
+ *(t--) = 0;
+ h = pspec->pattern;
+ while (t >= pspec->pattern_reversed)
+ *(t--) = *(h++);
+ return pspec;
+ }
+ }
+
+ if (tw)
+ {
+ p = pspec->pattern_reversed;
+ while (*p == '*')
+ p++;
+ if (p > pspec->pattern_reversed && !strchr (p, '*'))
+ {
+ gchar *tmp;
+
+ pspec->match_type = G_MATCH_HEAD;
+ pspec->pattern_length = strlen (p);
+ tmp = pspec->pattern_reversed;
+ pspec->pattern_reversed = strcpy (g_new (gchar, pspec->pattern_length + 1), p);
+ g_free (tmp);
+ g_free (pspec->pattern);
+ pspec->pattern = g_new (gchar, pspec->pattern_length + 1);
+ t = pspec->pattern + pspec->pattern_length;
+ *(t--) = 0;
+ h = pspec->pattern_reversed;
+ while (t >= pspec->pattern)
+ *(t--) = *(h++);
+ }
+ }
+
+ return pspec;
+}
+
+gboolean
+g_pattern_match_string (GPatternSpec *pspec,
+ const gchar *string)
+{
+ gchar *string_reversed, *t;
+ const gchar *h;
+ guint length;
+ gboolean ergo;
+
+ g_return_val_if_fail (pspec != NULL, FALSE);
+ g_return_val_if_fail (string != NULL, FALSE);
+
+ length = strlen (string);
+ string_reversed = g_new (gchar, length + 1);
+ t = string_reversed + length;
+ *(t--) = 0;
+ h = string;
+ while (t >= string_reversed)
+ *(t--) = *(h++);
+
+ ergo = g_pattern_match (pspec, length, string, string_reversed);
+ g_free (string_reversed);
+
+ return ergo;
+}
+
+gboolean
+g_pattern_match_simple (const gchar *pattern,
+ const gchar *string)
+{
+ GPatternSpec *pspec;
+ gboolean ergo;
+
+ g_return_val_if_fail (pattern != NULL, FALSE);
+ g_return_val_if_fail (string != NULL, FALSE);
+
+ pspec = g_pattern_spec_new (pattern);
+ ergo = g_pattern_match_string (pspec, string);
+ g_pattern_spec_free (pspec);
+
+ return ergo;
+}
+
+void
+g_pattern_spec_free (GPatternSpec *pspec)
+{
+ g_return_if_fail (pspec != NULL);
+
+ g_free (pspec->pattern);
+ g_free (pspec->pattern_reversed);
+ g_free (pspec);
+}
--- /dev/null
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997, 1999 Peter Mattis, Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __G_PATTERN_H__
+#define __G_PATTERN_H__
+
+#include <gtypes.h>
+
+G_BEGIN_DECLS
+
+typedef enum
+{
+ G_MATCH_ALL, /* "*A?A*" */
+ G_MATCH_ALL_TAIL, /* "*A?AA" */
+ G_MATCH_HEAD, /* "AAAA*" */
+ G_MATCH_TAIL, /* "*AAAA" */
+ G_MATCH_EXACT, /* "AAAAA" */
+ G_MATCH_LAST
+} GMatchType;
+
+typedef struct _GPatternSpec GPatternSpec;
+struct _GPatternSpec
+{
+ GMatchType match_type;
+ guint pattern_length;
+ gchar *pattern;
+ gchar *pattern_reversed;
+};
+
+GPatternSpec* g_pattern_spec_new (const gchar *pattern);
+void g_pattern_spec_free (GPatternSpec *pspec);
+gboolean g_pattern_match (GPatternSpec *pspec,
+ guint string_length,
+ const gchar *string,
+ const gchar *string_reversed);
+gboolean g_pattern_match_string (GPatternSpec *pspec,
+ const gchar *string);
+gboolean g_pattern_match_simple (const gchar *pattern,
+ const gchar *string);
+
+G_END_DECLS
+
+#endif /* __G_PATTERN_H__ */