Merge branch 'gpattern-introspectable' into 'master'

gpattern: Register as Boxed type and support introspection for it

See merge request GNOME/glib!2066
This commit is contained in:
Philip Withnall 2021-04-27 14:43:30 +00:00
commit 78ba6c8b07
8 changed files with 184 additions and 16 deletions

View File

@ -1425,6 +1425,9 @@ GPatternSpec
g_pattern_spec_new g_pattern_spec_new
g_pattern_spec_free g_pattern_spec_free
g_pattern_spec_equal g_pattern_spec_equal
g_pattern_spec_copy
g_pattern_spec_match
g_pattern_spec_match_string
g_pattern_match g_pattern_match
g_pattern_match_string g_pattern_match_string
g_pattern_match_simple g_pattern_match_simple

View File

@ -411,6 +411,7 @@ G_TYPE_THREAD
G_TYPE_OPTION_GROUP G_TYPE_OPTION_GROUP
G_TYPE_URI G_TYPE_URI
G_TYPE_TREE G_TYPE_TREE
G_TYPE_PATTERN_SPEC
<SUBSECTION Standard> <SUBSECTION Standard>
G_TYPE_IS_BOXED G_TYPE_IS_BOXED
@ -446,6 +447,7 @@ g_thread_get_type
g_option_group_get_type g_option_group_get_type
g_uri_get_type g_uri_get_type
g_tree_get_type g_tree_get_type
g_pattern_spec_get_type
</SECTION> </SECTION>
<SECTION> <SECTION>

View File

@ -22,8 +22,9 @@
#include "gpattern.h" #include "gpattern.h"
#include "gmacros.h" #include "gmacros.h"
#include "gmessages.h"
#include "gmem.h" #include "gmem.h"
#include "gmessages.h"
#include "gstrfuncs.h"
#include "gunicode.h" #include "gunicode.h"
#include "gutils.h" #include "gutils.h"
@ -157,7 +158,7 @@ g_pattern_ph_match (const gchar *match_pattern,
} }
/** /**
* g_pattern_match: * g_pattern_spec_match:
* @pspec: a #GPatternSpec * @pspec: a #GPatternSpec
* @string_length: the length of @string (in bytes, i.e. strlen(), * @string_length: the length of @string (in bytes, i.e. strlen(),
* not g_utf8_strlen()) * not g_utf8_strlen())
@ -183,10 +184,12 @@ g_pattern_ph_match (const gchar *match_pattern,
* g_utf8_strreverse() function to reverse UTF-8 encoded strings. * g_utf8_strreverse() function to reverse UTF-8 encoded strings.
* *
* Returns: %TRUE if @string matches @pspec * Returns: %TRUE if @string matches @pspec
*
* Since: 2.70
**/ **/
gboolean gboolean
g_pattern_match (GPatternSpec *pspec, g_pattern_spec_match (GPatternSpec *pspec,
guint string_length, gsize string_length,
const gchar *string, const gchar *string,
const gchar *string_reversed) const gchar *string_reversed)
{ {
@ -237,6 +240,44 @@ g_pattern_match (GPatternSpec *pspec,
} }
} }
/**
* g_pattern_match: (skip)
* @pspec: a #GPatternSpec
* @string_length: the length of @string (in bytes, i.e. strlen(),
* not g_utf8_strlen())
* @string: the UTF-8 encoded string to match
* @string_reversed: (nullable): the reverse of @string or %NULL
*
* Matches a string against a compiled pattern. Passing the correct
* length of the string given is mandatory. The reversed string can be
* omitted by passing %NULL, this is more efficient if the reversed
* version of the string to be matched is not at hand, as
* g_pattern_match() will only construct it if the compiled pattern
* requires reverse matches.
*
* Note that, if the user code will (possibly) match a string against a
* multitude of patterns containing wildcards, chances are high that
* some patterns will require a reversed string. In this case, it's
* more efficient to provide the reversed string to avoid multiple
* constructions thereof in the various calls to g_pattern_match().
*
* Note also that the reverse of a UTF-8 encoded string can in general
* not be obtained by g_strreverse(). This works only if the string
* does not contain any multibyte characters. GLib offers the
* g_utf8_strreverse() function to reverse UTF-8 encoded strings.
*
* Returns: %TRUE if @string matches @pspec
* Deprecated: 2.70: Use g_pattern_spec_match() instead
**/
gboolean
g_pattern_match (GPatternSpec *pspec,
guint string_length,
const gchar *string,
const gchar *string_reversed)
{
return g_pattern_spec_match (pspec, string_length, string, string_reversed);
}
/** /**
* g_pattern_spec_new: * g_pattern_spec_new:
* @pattern: a zero-terminated UTF-8 encoded string * @pattern: a zero-terminated UTF-8 encoded string
@ -353,6 +394,30 @@ g_pattern_spec_new (const gchar *pattern)
return pspec; return pspec;
} }
/**
* g_pattern_spec_copy:
* @pspec: a #GPatternSpec
*
* Copies @pspec in a new #GPatternSpec.
*
* Returns: (transfer full): a copy of @pspec.
*
* Since: 2.70
**/
GPatternSpec *
g_pattern_spec_copy (GPatternSpec *pspec)
{
GPatternSpec *pspec_copy;
g_return_val_if_fail (pspec != NULL, NULL);
pspec_copy = g_new (GPatternSpec, 1);
*pspec_copy = *pspec;
pspec_copy->pattern = g_strndup (pspec->pattern, pspec->pattern_length);
return pspec_copy;
}
/** /**
* g_pattern_spec_free: * g_pattern_spec_free:
* @pspec: a #GPatternSpec * @pspec: a #GPatternSpec
@ -391,7 +456,7 @@ g_pattern_spec_equal (GPatternSpec *pspec1,
} }
/** /**
* g_pattern_match_string: * g_pattern_spec_match_string:
* @pspec: a #GPatternSpec * @pspec: a #GPatternSpec
* @string: the UTF-8 encoded string to match * @string: the UTF-8 encoded string to match
* *
@ -400,15 +465,36 @@ g_pattern_spec_equal (GPatternSpec *pspec1,
* g_pattern_match() instead while supplying the reversed string. * g_pattern_match() instead while supplying the reversed string.
* *
* Returns: %TRUE if @string matches @pspec * Returns: %TRUE if @string matches @pspec
*
* Since: 2.70
**/ **/
gboolean gboolean
g_pattern_match_string (GPatternSpec *pspec, g_pattern_spec_match_string (GPatternSpec *pspec,
const gchar *string) const gchar *string)
{ {
g_return_val_if_fail (pspec != NULL, FALSE); g_return_val_if_fail (pspec != NULL, FALSE);
g_return_val_if_fail (string != NULL, FALSE); g_return_val_if_fail (string != NULL, FALSE);
return g_pattern_match (pspec, strlen (string), string, NULL); return g_pattern_spec_match (pspec, strlen (string), string, NULL);
}
/**
* g_pattern_match_string: (skip)
* @pspec: a #GPatternSpec
* @string: the UTF-8 encoded string to match
*
* Matches a string against a compiled pattern. If the string is to be
* matched against more than one pattern, consider using
* g_pattern_match() instead while supplying the reversed string.
*
* Returns: %TRUE if @string matches @pspec
* Deprecated: 2.70: Use g_pattern_spec_match_string() instead
**/
gboolean
g_pattern_match_string (GPatternSpec *pspec,
const gchar *string)
{
return g_pattern_spec_match_string (pspec, string);
} }
/** /**
@ -434,7 +520,7 @@ g_pattern_match_simple (const gchar *pattern,
g_return_val_if_fail (string != NULL, FALSE); g_return_val_if_fail (string != NULL, FALSE);
pspec = g_pattern_spec_new (pattern); pspec = g_pattern_spec_new (pattern);
ergo = g_pattern_match (pspec, strlen (string), string, NULL); ergo = g_pattern_spec_match (pspec, strlen (string), string, NULL);
g_pattern_spec_free (pspec); g_pattern_spec_free (pspec);
return ergo; return ergo;

View File

@ -33,15 +33,25 @@ GLIB_AVAILABLE_IN_ALL
GPatternSpec* g_pattern_spec_new (const gchar *pattern); GPatternSpec* g_pattern_spec_new (const gchar *pattern);
GLIB_AVAILABLE_IN_ALL GLIB_AVAILABLE_IN_ALL
void g_pattern_spec_free (GPatternSpec *pspec); void g_pattern_spec_free (GPatternSpec *pspec);
GLIB_AVAILABLE_IN_2_70
GPatternSpec *g_pattern_spec_copy (GPatternSpec *pspec);
GLIB_AVAILABLE_IN_ALL GLIB_AVAILABLE_IN_ALL
gboolean g_pattern_spec_equal (GPatternSpec *pspec1, gboolean g_pattern_spec_equal (GPatternSpec *pspec1,
GPatternSpec *pspec2); GPatternSpec *pspec2);
GLIB_AVAILABLE_IN_ALL GLIB_AVAILABLE_IN_2_70
gboolean g_pattern_spec_match (GPatternSpec *pspec,
gsize string_length,
const gchar *string,
const gchar *string_reversed);
GLIB_AVAILABLE_IN_2_70
gboolean g_pattern_spec_match_string (GPatternSpec *pspec,
const gchar *string);
GLIB_DEPRECATED_IN_2_70_FOR (g_pattern_spec_match)
gboolean g_pattern_match (GPatternSpec *pspec, gboolean g_pattern_match (GPatternSpec *pspec,
guint string_length, guint string_length,
const gchar *string, const gchar *string,
const gchar *string_reversed); const gchar *string_reversed);
GLIB_AVAILABLE_IN_ALL GLIB_DEPRECATED_IN_2_70_FOR (g_pattern_spec_match_string)
gboolean g_pattern_match_string (GPatternSpec *pspec, gboolean g_pattern_match_string (GPatternSpec *pspec,
const gchar *string); const gchar *string);
GLIB_AVAILABLE_IN_ALL GLIB_AVAILABLE_IN_ALL

View File

@ -51,12 +51,12 @@ struct _CompileTest
guint min; guint min;
}; };
static CompileTest compile_tests[] = static CompileTest compile_tests[] = {
{
{ "*A?B*", G_MATCH_ALL, "*A?B*", 3 }, { "*A?B*", G_MATCH_ALL, "*A?B*", 3 },
{ "ABC*DEFGH", G_MATCH_ALL_TAIL, "HGFED*CBA", 8 }, { "ABC*DEFGH", G_MATCH_ALL_TAIL, "HGFED*CBA", 8 },
{ "ABCDEF*GH", G_MATCH_ALL, "ABCDEF*GH", 8 }, { "ABCDEF*GH", G_MATCH_ALL, "ABCDEF*GH", 8 },
{ "ABC**?***??**DEF*GH", G_MATCH_ALL, "ABC*???DEF*GH", 11 }, { "ABC**?***??**DEF*GH", G_MATCH_ALL, "ABC*???DEF*GH", 11 },
{ "**ABC***?🤌DEF**", G_MATCH_ALL, "*ABC*?🤌DEF*", 11 },
{ "*A?AA", G_MATCH_ALL_TAIL, "AA?A*", 4 }, { "*A?AA", G_MATCH_ALL_TAIL, "AA?A*", 4 },
{ "ABCD*", G_MATCH_HEAD, "ABCD", 4 }, { "ABCD*", G_MATCH_HEAD, "ABCD", 4 },
{ "*ABCD", G_MATCH_TAIL, "ABCD", 4 }, { "*ABCD", G_MATCH_TAIL, "ABCD", 4 },
@ -84,6 +84,24 @@ test_compilation (gconstpointer d)
g_pattern_spec_free (spec); g_pattern_spec_free (spec);
} }
static void
test_copy (gconstpointer d)
{
const CompileTest *test = d;
GPatternSpec *p1, *p2;
p1 = g_pattern_spec_new (test->src);
p2 = g_pattern_spec_copy (p1);
g_assert_cmpint (p2->match_type, ==, test->match_type);
g_assert_cmpstr (p2->pattern, ==, test->pattern);
g_assert_cmpint (p2->pattern_length, ==, strlen (p1->pattern));
g_assert_cmpint (p2->min_length, ==, test->min);
g_pattern_spec_free (p1);
g_pattern_spec_free (p2);
}
typedef struct _MatchTest MatchTest; typedef struct _MatchTest MatchTest;
struct _MatchTest struct _MatchTest
@ -158,10 +176,16 @@ test_match (gconstpointer d)
g_assert_cmpint (g_pattern_match_simple (test->pattern, test->string), ==, test->match); g_assert_cmpint (g_pattern_match_simple (test->pattern, test->string), ==, test->match);
p = g_pattern_spec_new (test->pattern); p = g_pattern_spec_new (test->pattern);
g_assert_cmpint (g_pattern_spec_match_string (p, test->string), ==, test->match);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
g_assert_cmpint (g_pattern_match_string (p, test->string), ==, test->match); g_assert_cmpint (g_pattern_match_string (p, test->string), ==, test->match);
G_GNUC_END_IGNORE_DEPRECATIONS
r = g_utf8_strreverse (test->string, -1); r = g_utf8_strreverse (test->string, -1);
g_assert_cmpint (g_pattern_spec_match (p, strlen (test->string), test->string, r), ==, test->match);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
g_assert_cmpint (g_pattern_match (p, strlen (test->string), test->string, r), ==, test->match); g_assert_cmpint (g_pattern_match (p, strlen (test->string), test->string, r), ==, test->match);
G_GNUC_END_IGNORE_DEPRECATIONS
g_free (r); g_free (r);
g_pattern_spec_free (p); g_pattern_spec_free (p);
@ -222,6 +246,13 @@ main (int argc, char** argv)
g_free (path); g_free (path);
} }
for (i = 0; i < G_N_ELEMENTS (compile_tests); i++)
{
path = g_strdup_printf ("/pattern/copy/%" G_GSIZE_FORMAT, i);
g_test_add_data_func (path, &compile_tests[i], test_copy);
g_free (path);
}
for (i = 0; i < G_N_ELEMENTS (match_tests); i++) for (i = 0; i < G_N_ELEMENTS (match_tests); i++)
{ {
path = g_strdup_printf ("/pattern/match/%" G_GSIZE_FORMAT, i); path = g_strdup_printf ("/pattern/match/%" G_GSIZE_FORMAT, i);

View File

@ -175,6 +175,7 @@ G_DEFINE_BOXED_TYPE (GChecksum, g_checksum, g_checksum_copy, g_checksum_free)
G_DEFINE_BOXED_TYPE (GUri, g_uri, g_uri_ref, g_uri_unref) G_DEFINE_BOXED_TYPE (GUri, g_uri, g_uri_ref, g_uri_unref)
G_DEFINE_BOXED_TYPE (GOptionGroup, g_option_group, g_option_group_ref, g_option_group_unref) G_DEFINE_BOXED_TYPE (GOptionGroup, g_option_group, g_option_group_ref, g_option_group_unref)
G_DEFINE_BOXED_TYPE (GPatternSpec, g_pattern_spec, g_pattern_spec_copy, g_pattern_spec_free);
/* This one can't use G_DEFINE_BOXED_TYPE (GStrv, g_strv, g_strdupv, g_strfreev) */ /* This one can't use G_DEFINE_BOXED_TYPE (GStrv, g_strv, g_strdupv, g_strfreev) */
GType GType

View File

@ -315,6 +315,15 @@ typedef gsize GType;
*/ */
#define G_TYPE_TREE (g_tree_get_type ()) #define G_TYPE_TREE (g_tree_get_type ())
/**
* G_TYPE_PATTERN_SPEC:
*
* The #GType for #GPatternSpec.
*
* Since: 2.70
*/
#define G_TYPE_PATTERN_SPEC (g_pattern_spec_get_type ())
GLIB_AVAILABLE_IN_ALL GLIB_AVAILABLE_IN_ALL
GType g_date_get_type (void) G_GNUC_CONST; GType g_date_get_type (void) G_GNUC_CONST;
GLIB_AVAILABLE_IN_ALL GLIB_AVAILABLE_IN_ALL
@ -375,6 +384,8 @@ GLIB_AVAILABLE_IN_2_66
GType g_uri_get_type (void) G_GNUC_CONST; GType g_uri_get_type (void) G_GNUC_CONST;
GLIB_AVAILABLE_IN_2_68 GLIB_AVAILABLE_IN_2_68
GType g_tree_get_type (void) G_GNUC_CONST; GType g_tree_get_type (void) G_GNUC_CONST;
GLIB_AVAILABLE_IN_2_70
GType g_pattern_spec_get_type (void) G_GNUC_CONST;
GLIB_DEPRECATED_FOR('G_TYPE_VARIANT') GLIB_DEPRECATED_FOR('G_TYPE_VARIANT')
GType g_variant_get_gtype (void) G_GNUC_CONST; GType g_variant_get_gtype (void) G_GNUC_CONST;

View File

@ -645,6 +645,29 @@ test_boxed_tree (void)
g_value_unset (&value); g_value_unset (&value);
} }
static void
test_boxed_pattern_spec (void)
{
GPatternSpec *ps, *ps2;
GValue value = G_VALUE_INIT;
g_value_init (&value, G_TYPE_PATTERN_SPEC);
g_assert_true (G_VALUE_HOLDS_BOXED (&value));
ps = g_pattern_spec_new ("*abc*?cde");
g_value_take_boxed (&value, ps);
ps2 = g_value_get_boxed (&value);
g_assert_true (ps == ps2);
ps2 = g_value_dup_boxed (&value);
g_assert_true (ps != ps2);
g_assert_true (g_pattern_spec_equal (ps, ps2));
g_pattern_spec_free (ps2);
g_value_unset (&value);
}
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
@ -675,6 +698,7 @@ main (int argc, char *argv[])
g_test_add_func ("/boxed/thread", test_boxed_thread); g_test_add_func ("/boxed/thread", test_boxed_thread);
g_test_add_func ("/boxed/checksum", test_boxed_checksum); g_test_add_func ("/boxed/checksum", test_boxed_checksum);
g_test_add_func ("/boxed/tree", test_boxed_tree); g_test_add_func ("/boxed/tree", test_boxed_tree);
g_test_add_func ("/boxed/patternspec", test_boxed_pattern_spec);
return g_test_run (); return g_test_run ();
} }