(root)/
glib-2.79.0/
glib/
tests/
pattern.c
       1  /* GLIB - Library of useful routines for C programming
       2   * Copyright (C) 2001 Matthias Clasen <matthiasc@poet.de>
       3   *
       4   * SPDX-License-Identifier: LGPL-2.1-or-later
       5   *
       6   * This library is free software; you can redistribute it and/or
       7   * modify it under the terms of the GNU Lesser General Public
       8   * License as published by the Free Software Foundation; either
       9   * version 2.1 of the License, or (at your option) any later version.
      10   *
      11   * This library is distributed in the hope that it will be useful,
      12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14   * Lesser General Public License for more details.
      15   *
      16   * You should have received a copy of the GNU Lesser General Public
      17   * License along with this library; if not, see <http://www.gnu.org/licenses/>.
      18   */
      19  
      20  #undef G_DISABLE_ASSERT
      21  #undef G_LOG_DOMAIN
      22  
      23  #include <string.h>
      24  #include <glib.h>
      25  
      26  /* keep enum and structure of gpattern.c and patterntest.c in sync */
      27  typedef enum
      28  {
      29    G_MATCH_ALL,       /* "*A?A*" */
      30    G_MATCH_ALL_TAIL,  /* "*A?AA" */
      31    G_MATCH_HEAD,      /* "AAAA*" */
      32    G_MATCH_TAIL,      /* "*AAAA" */
      33    G_MATCH_EXACT,     /* "AAAAA" */
      34    G_MATCH_LAST
      35  } GMatchType;
      36  
      37  struct _GPatternSpec
      38  {
      39    GMatchType match_type;
      40    guint      pattern_length;
      41    guint      min_length;
      42    guint      max_length;
      43    gchar     *pattern;
      44  };
      45  
      46  typedef struct _CompileTest CompileTest;
      47  
      48  struct _CompileTest
      49  {
      50    const gchar *src;
      51    GMatchType match_type;
      52    gchar *pattern;
      53    guint min;
      54  };
      55  
      56  static CompileTest compile_tests[] = {
      57    { "*A?B*", G_MATCH_ALL, "*A?B*", 3 },
      58    { "ABC*DEFGH", G_MATCH_ALL_TAIL, "HGFED*CBA", 8 },
      59    { "ABCDEF*GH", G_MATCH_ALL, "ABCDEF*GH", 8 },
      60    { "ABC**?***??**DEF*GH", G_MATCH_ALL, "ABC*???DEF*GH", 11 },
      61    { "**ABC***?🤌DEF**", G_MATCH_ALL, "*ABC*?🤌DEF*", 11 },
      62    { "*A?AA", G_MATCH_ALL_TAIL, "AA?A*", 4 },
      63    { "ABCD*", G_MATCH_HEAD, "ABCD", 4 },
      64    { "*ABCD", G_MATCH_TAIL, "ABCD", 4 },
      65    { "ABCDE", G_MATCH_EXACT, "ABCDE", 5 },
      66    { "A?C?E", G_MATCH_ALL, "A?C?E", 5 },
      67    { "*?x", G_MATCH_ALL_TAIL, "x?*", 2 },
      68    { "?*x", G_MATCH_ALL_TAIL, "x?*", 2 },
      69    { "*?*x", G_MATCH_ALL_TAIL, "x?*", 2 },
      70    { "x*??", G_MATCH_ALL_TAIL, "??*x", 3 }
      71  };
      72  
      73  static void
      74  test_compilation (gconstpointer d)
      75  {
      76    const CompileTest *test = d;
      77    GPatternSpec *spec;
      78  
      79    spec = g_pattern_spec_new (test->src);
      80  
      81    g_assert_cmpint (spec->match_type, ==, test->match_type);
      82    g_assert_cmpstr (spec->pattern, ==, test->pattern);
      83    g_assert_cmpint (spec->pattern_length, ==, strlen (spec->pattern));
      84    g_assert_cmpint (spec->min_length, ==, test->min);
      85  
      86    g_pattern_spec_free (spec);
      87  }
      88  
      89  static void
      90  test_copy (gconstpointer d)
      91  {
      92    const CompileTest *test = d;
      93    GPatternSpec *p1, *p2;
      94  
      95    p1 = g_pattern_spec_new (test->src);
      96    p2 = g_pattern_spec_copy (p1);
      97  
      98    g_assert_cmpint (p2->match_type, ==, test->match_type);
      99    g_assert_cmpstr (p2->pattern, ==, test->pattern);
     100    g_assert_cmpint (p2->pattern_length, ==, strlen (p1->pattern));
     101    g_assert_cmpint (p2->min_length, ==, test->min);
     102  
     103    g_pattern_spec_free (p1);
     104    g_pattern_spec_free (p2);
     105  }
     106  
     107  typedef struct _MatchTest MatchTest;
     108  
     109  struct _MatchTest
     110  {
     111    const gchar *pattern;
     112    const gchar *string;
     113    gboolean match;
     114  };
     115  
     116  static MatchTest match_tests[] =
     117  {
     118    { "*x", "x", TRUE },
     119    { "*x", "xx", TRUE },
     120    { "*x", "yyyx", TRUE },
     121    { "*x", "yyxy", FALSE },
     122    { "?x", "x", FALSE },
     123    { "?x", "xx", TRUE },
     124    { "?x", "yyyx", FALSE },
     125    { "?x", "yyxy", FALSE },
     126    { "*?x", "xx", TRUE },
     127    { "?*x", "xx", TRUE },
     128    { "*?x", "x", FALSE },
     129    { "?*x", "x", FALSE },
     130    { "*?*x", "yx", TRUE },
     131    { "*?*x", "xxxx", TRUE },
     132    { "x*??", "xyzw", TRUE },
     133    { "*x", "\xc3\x84x", TRUE },
     134    { "?x", "\xc3\x84x", TRUE },
     135    { "??x", "\xc3\x84x", FALSE },
     136    { "ab\xc3\xa4\xc3\xb6", "ab\xc3\xa4\xc3\xb6", TRUE },
     137    { "ab\xc3\xa4\xc3\xb6", "abao", FALSE },
     138    { "ab?\xc3\xb6", "ab\xc3\xa4\xc3\xb6", TRUE },
     139    { "ab?\xc3\xb6", "abao", FALSE },
     140    { "ab\xc3\xa4?", "ab\xc3\xa4\xc3\xb6", TRUE },
     141    { "ab\xc3\xa4?", "abao", FALSE },
     142    { "ab??", "ab\xc3\xa4\xc3\xb6", TRUE },
     143    { "ab*", "ab\xc3\xa4\xc3\xb6", TRUE },
     144    { "ab*\xc3\xb6", "ab\xc3\xa4\xc3\xb6", TRUE },
     145    { "ab*\xc3\xb6", "aba\xc3\xb6x\xc3\xb6", TRUE },
     146    { "", "abc", FALSE },
     147    { "", "", TRUE },
     148    { "abc", "abc", TRUE },
     149    { "*fo1*bar", "yyyfoxfo1bar", TRUE },
     150    { "12*fo1g*bar", "12yyyfoxfo1gbar", TRUE },
     151    { "__________:*fo1g*bar", "__________:yyyfoxfo1gbar", TRUE },
     152    { "*abc*cde", "abcde", FALSE },
     153    { "*abc*cde", "abccde", TRUE },
     154    { "*abc*cde", "abcxcde", TRUE },
     155    { "*abc*?cde", "abccde", FALSE },
     156    { "*abc*?cde", "abcxcde", TRUE },
     157    { "*abc*def", "abababcdededef", TRUE },
     158    { "*abc*def", "abcbcbcdededef", TRUE },
     159    { "*acbc*def", "acbcbcbcdededef", TRUE },
     160    { "*a?bc*def", "acbcbcbcdededef", TRUE },
     161    { "*abc*def", "bcbcbcdefdef", FALSE },
     162    { "*abc*def*ghi", "abcbcbcbcbcbcdefefdefdefghi", TRUE },
     163    { "*abc*def*ghi", "bcbcbcbcbcbcdefdefdefdefghi", FALSE },
     164    { "_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_*abc*def*ghi", "_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_abcbcbcbcbcbcdefefdefdefghi", TRUE },
     165    { "fooooooo*a*bc", "fooooooo_a_bd_a_bc", TRUE },
     166    { "x*?", "x", FALSE },
     167    { "abc*", "abc", TRUE },
     168    { "*", "abc", TRUE }
     169  };
     170  
     171  static void
     172  test_match (gconstpointer d)
     173  {
     174    const MatchTest *test = d;
     175    GPatternSpec *p;
     176    gchar *r;
     177  
     178    g_assert_cmpint (g_pattern_match_simple (test->pattern, test->string), ==, test->match);
     179  
     180    p = g_pattern_spec_new (test->pattern);
     181    g_assert_cmpint (g_pattern_spec_match_string (p, test->string), ==, test->match);
     182    G_GNUC_BEGIN_IGNORE_DEPRECATIONS
     183    g_assert_cmpint (g_pattern_match_string (p, test->string), ==, test->match);
     184    G_GNUC_END_IGNORE_DEPRECATIONS
     185  
     186    r = g_utf8_strreverse (test->string, -1);
     187    g_assert_cmpint (g_pattern_spec_match (p, strlen (test->string), test->string, r), ==, test->match);
     188    G_GNUC_BEGIN_IGNORE_DEPRECATIONS
     189    g_assert_cmpint (g_pattern_match (p, strlen (test->string), test->string, r), ==, test->match);
     190    G_GNUC_END_IGNORE_DEPRECATIONS
     191    g_free (r);
     192  
     193    g_pattern_spec_free (p);
     194  }
     195  
     196  typedef struct _EqualTest EqualTest;
     197  
     198  struct _EqualTest
     199  {
     200    const gchar *pattern1;
     201    const gchar *pattern2;
     202    gboolean expected;
     203  };
     204  
     205  static EqualTest equal_tests[] =
     206  {
     207    { "*A?B*", "*A?B*", TRUE },
     208    { "A*BCD", "A*BCD", TRUE },
     209    { "ABCD*", "ABCD****", TRUE },
     210    { "A1*", "A1*", TRUE },
     211    { "*YZ", "*YZ", TRUE },
     212    { "A1x", "A1x", TRUE },
     213    { "AB*CD", "AB**CD", TRUE },
     214    { "AB*?*CD", "AB*?CD", TRUE },
     215    { "AB*?CD", "AB?*CD", TRUE },
     216    { "AB*CD", "AB*?*CD", FALSE },
     217    { "ABC*", "ABC?", FALSE },
     218  };
     219  
     220  static void
     221  test_equal (gconstpointer d)
     222  {
     223    const EqualTest *test = d;
     224    GPatternSpec *p1, *p2;
     225  
     226    p1 = g_pattern_spec_new (test->pattern1);
     227    p2 = g_pattern_spec_new (test->pattern2);
     228  
     229    g_assert_cmpint (g_pattern_spec_equal (p1, p2), ==, test->expected);
     230  
     231    g_pattern_spec_free (p1);
     232    g_pattern_spec_free (p2);
     233  }
     234  
     235  
     236  int
     237  main (int argc, char** argv)
     238  {
     239    gsize i;
     240    gchar *path;
     241  
     242    g_test_init (&argc, &argv, NULL);
     243  
     244    for (i = 0; i < G_N_ELEMENTS (compile_tests); i++)
     245      {
     246        path = g_strdup_printf ("/pattern/compile/%" G_GSIZE_FORMAT, i);
     247        g_test_add_data_func (path, &compile_tests[i], test_compilation);
     248        g_free (path);
     249      }
     250  
     251    for (i = 0; i < G_N_ELEMENTS (compile_tests); i++)
     252      {
     253        path = g_strdup_printf ("/pattern/copy/%" G_GSIZE_FORMAT, i);
     254        g_test_add_data_func (path, &compile_tests[i], test_copy);
     255        g_free (path);
     256      }
     257  
     258    for (i = 0; i < G_N_ELEMENTS (match_tests); i++)
     259      {
     260        path = g_strdup_printf ("/pattern/match/%" G_GSIZE_FORMAT, i);
     261        g_test_add_data_func (path, &match_tests[i], test_match);
     262        g_free (path);
     263      }
     264  
     265    for (i = 0; i < G_N_ELEMENTS (equal_tests); i++)
     266      {
     267        path = g_strdup_printf ("/pattern/equal/%" G_GSIZE_FORMAT, i);
     268        g_test_add_data_func (path, &equal_tests[i], test_equal);
     269        g_free (path);
     270      }
     271  
     272    return g_test_run ();
     273  }