]> Pileus Git - ~andy/gtk/commitdiff
System fnmatch wasn't going to be UTF-8 clean, neither was our version.
authorOwen Taylor <otaylor@redhat.com>
Fri, 13 Dec 2002 23:18:03 +0000 (23:18 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Fri, 13 Dec 2002 23:18:03 +0000 (23:18 +0000)
Fri Dec 13 17:45:40 2002  Owen Taylor  <otaylor@redhat.com>

        * gtk/fnmatch.c gtk/gtkprivate.h gtk/gtkfilesel.c:
        System fnmatch wasn't going to be UTF-8 clean, neither
        was our version. Redo our fnmatch.c to be UTF-8, add
        test cases, fix all sorts of bugs inherited
        from the antique GNU fnmatch code. Change interface
        to get rid of fnmatch.h constants. Fixes basic
        non-workingness of filesel with non-ASCII filenames.

        * gtk/fnmatch.h: No longer needed.

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/fnmatch.c
gtk/fnmatch.h [deleted file]
gtk/gtkclist.c
gtk/gtkfilesel.c
gtk/gtkprivate.h

index f2fa7fb01460e02a0d9d23410371d584d422cd75..6cf2be7b6b95a6c034933c30afbb813a1a642301 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+Fri Dec 13 17:45:40 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/fnmatch.c gtk/gtkprivate.h gtk/gtkfilesel.c: 
+       System fnmatch wasn't going to be UTF-8 clean, neither 
+       was our version. Redo our fnmatch.c to be UTF-8, add 
+       test cases, fix all sorts of bugs inherited
+       from the antique GNU fnmatch code. Change interface
+       to get rid of fnmatch.h constants. Fixes basic
+       non-workingness of filesel with non-ASCII filenames.
+
+       * gtk/fnmatch.h: No longer needed.
+
+Fri Dec 13 12:15:09 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkfilesel.c (find_parent_dir_fullname): If
+       getting the parent of the directory name, make
+       an attempt to change back to the original directory.
+
 Thu Dec 12 20:07:25 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkfilesel.c (cmpl_completion_fullname): Const
index f2fa7fb01460e02a0d9d23410371d584d422cd75..6cf2be7b6b95a6c034933c30afbb813a1a642301 100644 (file)
@@ -1,3 +1,21 @@
+Fri Dec 13 17:45:40 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/fnmatch.c gtk/gtkprivate.h gtk/gtkfilesel.c: 
+       System fnmatch wasn't going to be UTF-8 clean, neither 
+       was our version. Redo our fnmatch.c to be UTF-8, add 
+       test cases, fix all sorts of bugs inherited
+       from the antique GNU fnmatch code. Change interface
+       to get rid of fnmatch.h constants. Fixes basic
+       non-workingness of filesel with non-ASCII filenames.
+
+       * gtk/fnmatch.h: No longer needed.
+
+Fri Dec 13 12:15:09 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkfilesel.c (find_parent_dir_fullname): If
+       getting the parent of the directory name, make
+       an attempt to change back to the original directory.
+
 Thu Dec 12 20:07:25 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkfilesel.c (cmpl_completion_fullname): Const
index f2fa7fb01460e02a0d9d23410371d584d422cd75..6cf2be7b6b95a6c034933c30afbb813a1a642301 100644 (file)
@@ -1,3 +1,21 @@
+Fri Dec 13 17:45:40 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/fnmatch.c gtk/gtkprivate.h gtk/gtkfilesel.c: 
+       System fnmatch wasn't going to be UTF-8 clean, neither 
+       was our version. Redo our fnmatch.c to be UTF-8, add 
+       test cases, fix all sorts of bugs inherited
+       from the antique GNU fnmatch code. Change interface
+       to get rid of fnmatch.h constants. Fixes basic
+       non-workingness of filesel with non-ASCII filenames.
+
+       * gtk/fnmatch.h: No longer needed.
+
+Fri Dec 13 12:15:09 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkfilesel.c (find_parent_dir_fullname): If
+       getting the parent of the directory name, make
+       an attempt to change back to the original directory.
+
 Thu Dec 12 20:07:25 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkfilesel.c (cmpl_completion_fullname): Const
index f2fa7fb01460e02a0d9d23410371d584d422cd75..6cf2be7b6b95a6c034933c30afbb813a1a642301 100644 (file)
@@ -1,3 +1,21 @@
+Fri Dec 13 17:45:40 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/fnmatch.c gtk/gtkprivate.h gtk/gtkfilesel.c: 
+       System fnmatch wasn't going to be UTF-8 clean, neither 
+       was our version. Redo our fnmatch.c to be UTF-8, add 
+       test cases, fix all sorts of bugs inherited
+       from the antique GNU fnmatch code. Change interface
+       to get rid of fnmatch.h constants. Fixes basic
+       non-workingness of filesel with non-ASCII filenames.
+
+       * gtk/fnmatch.h: No longer needed.
+
+Fri Dec 13 12:15:09 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkfilesel.c (find_parent_dir_fullname): If
+       getting the parent of the directory name, make
+       an attempt to change back to the original directory.
+
 Thu Dec 12 20:07:25 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkfilesel.c (cmpl_completion_fullname): Const
index f2fa7fb01460e02a0d9d23410371d584d422cd75..6cf2be7b6b95a6c034933c30afbb813a1a642301 100644 (file)
@@ -1,3 +1,21 @@
+Fri Dec 13 17:45:40 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/fnmatch.c gtk/gtkprivate.h gtk/gtkfilesel.c: 
+       System fnmatch wasn't going to be UTF-8 clean, neither 
+       was our version. Redo our fnmatch.c to be UTF-8, add 
+       test cases, fix all sorts of bugs inherited
+       from the antique GNU fnmatch code. Change interface
+       to get rid of fnmatch.h constants. Fixes basic
+       non-workingness of filesel with non-ASCII filenames.
+
+       * gtk/fnmatch.h: No longer needed.
+
+Fri Dec 13 12:15:09 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkfilesel.c (find_parent_dir_fullname): If
+       getting the parent of the directory name, make
+       an attempt to change back to the original directory.
+
 Thu Dec 12 20:07:25 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkfilesel.c (cmpl_completion_fullname): Const
index f2fa7fb01460e02a0d9d23410371d584d422cd75..6cf2be7b6b95a6c034933c30afbb813a1a642301 100644 (file)
@@ -1,3 +1,21 @@
+Fri Dec 13 17:45:40 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/fnmatch.c gtk/gtkprivate.h gtk/gtkfilesel.c: 
+       System fnmatch wasn't going to be UTF-8 clean, neither 
+       was our version. Redo our fnmatch.c to be UTF-8, add 
+       test cases, fix all sorts of bugs inherited
+       from the antique GNU fnmatch code. Change interface
+       to get rid of fnmatch.h constants. Fixes basic
+       non-workingness of filesel with non-ASCII filenames.
+
+       * gtk/fnmatch.h: No longer needed.
+
+Fri Dec 13 12:15:09 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkfilesel.c (find_parent_dir_fullname): If
+       getting the parent of the directory name, make
+       an attempt to change back to the original directory.
+
 Thu Dec 12 20:07:25 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkfilesel.c (cmpl_completion_fullname): Const
index 198363fc84963923ce6bbd9887fc7b6aeef7987c..e6ccb4073d2e4afff52afea8188594125ab4bff7 100644 (file)
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+/*
+ * Stripped down, converted to UTF-8 and test cases added
+ *
+ *                    Owen Taylor, 13 December 2002;
+ */
 
-#include <errno.h>
-#include <ctype.h> /* tolower */
+#include <string.h>
 
-/* Added for GTK. We need to make sure that all constants are defined
- * to properly compile this file */
+#include <glib.h>
+
+/* We need to make sure that all constants are defined
+ * to properly compile this file
+ */
 #ifndef _GNU_SOURCE
 #define _GNU_SOURCE
 #endif
-#include "fnmatch.h"
 
-/* We need glib.h for G_DIR_SEPARATOR and G_OS_WIN32 */
-#include <glib.h>
+static gunichar
+get_char (const char **str)
+{
+  gunichar c = g_utf8_get_char (*str);
+  *str = g_utf8_next_char (*str);
 
+#if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN)
+  if (c <= 0xff)
+      c = g_ascii_tolower (c);
+#endif
 
-/* Comment out all this code if we are using the GNU C Library, and are not
-   actually compiling the library itself.  This code is part of the GNU C
-   Library, but also included in many other GNU distributions.  Compiling
-   and linking in this code is a waste when using the GNU C library
-   (especially if it is a shared library).  Rather than having every GNU
-   program understand `configure --with-gnu-libc' and omit the object files,
-   it is simpler to just do this in the source for each such file.  */
+  return c;
+}
 
-#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
+#if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN)
+#define DO_ESCAPE 0
+#else  
+#define DO_ESCAPE 1
+#endif  
 
-#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
-extern int errno;
-#endif
+static gunichar
+get_unescaped_char (const char **str,
+                   gboolean    *was_escaped)
+{
+  gunichar c = get_char (str);
+
+  *was_escaped = DO_ESCAPE && c == '\\';
+  if (*was_escaped)
+    c = get_char (str);
+  
+  return c;
+}
 
 /* Match STRING against the filename pattern PATTERN, returning zero if
    it matches, nonzero if not.  */
-int
-fnmatch (pattern, string, flags)
-     const char *pattern;
-     const char *string;
-     int flags;
-{
-  register const char *p = pattern, *n = string;
-  register char c;
-
-/* Note that this evalutes C many times.  */
-#if !defined(G_OS_WIN32) && !defined(G_WITH_CYGWIN)
-#define FOLD(c)        ((flags & FNM_CASEFOLD) && isupper ((unsigned char )(c)) ? tolower ((unsigned char)(c)) : (c))
-#else
-#define FOLD(c)        (tolower ((unsigned char)(c)))
-#endif
 
-  while ((c = *p++) != '\0')
+static gboolean
+gtk_fnmatch_intern (const char *pattern,
+                   const char *string,
+                   gboolean   component_start)
+{
+  const char *p = pattern, *n = string;
+  
+  while (*p)
     {
-      c = FOLD (c);
-
+      const char *last_n = n;
+      
+      gunichar c = get_char (&p);
+      gunichar nc = get_char (&n);
+      
       switch (c)
        {
-       case '?':
-         if (*n == '\0')
-           return FNM_NOMATCH;
-         else if ((flags & FNM_FILE_NAME) && *n == G_DIR_SEPARATOR)
-           return FNM_NOMATCH;
-         else if ((flags & FNM_PERIOD) && *n == '.' &&
-                  (n == string || ((flags & FNM_FILE_NAME) && n[-1] == G_DIR_SEPARATOR)))
-           return FNM_NOMATCH;
+       case '?':
+         if (nc == '\0')
+           return FALSE;
+         else if (nc == G_DIR_SEPARATOR)
+           return FALSE;
+         else if (nc == '.' && component_start)
+           return FALSE;
          break;
-#ifndef G_OS_WIN32
        case '\\':
-         if (!(flags & FNM_NOESCAPE))
-           {
-             c = *p++;
-             c = FOLD (c);
-           }
-         if (FOLD (*n) != c)
-           return FNM_NOMATCH;
+         if (DO_ESCAPE)
+           c = get_char (&p);
+         if (nc != c)
+           return FALSE;
          break;
-#endif
        case '*':
-         if ((flags & FNM_PERIOD) && *n == '.' &&
-             (n == string || ((flags & FNM_FILE_NAME) && n[-1] == G_DIR_SEPARATOR)))
-           return FNM_NOMATCH;
+         if (nc == '.' && component_start)
+           return FALSE;
+
+         {
+           const char *last_p = p;
+
+           for (last_p = p, c = get_char (&p);
+                c == '?' || c == '*';
+                last_p = p, c = get_char (&p))
+             {
+               if (c == '?')
+                 {
+                   if (nc == '\0')
+                     return FALSE;
+                   else if (nc == G_DIR_SEPARATOR)
+                     return FALSE;
+                   else
+                     {
+                       last_n = n; nc = get_char (&n);
+                     }
+                 }
+             }
 
-         for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
-           if (((flags & FNM_FILE_NAME) && *n == G_DIR_SEPARATOR) ||
-               (c == '?' && *n == '\0'))
-             return FNM_NOMATCH;
+           /* If the pattern ends with wildcards, we have a
+            * guaranteed match unless there is a dir separator
+            * in the remainder of the string.
+            */
+           if (c == '\0')
+             {
+               if (strchr (last_n, G_DIR_SEPARATOR) != NULL)
+                 return FALSE;
+               else
+                 return TRUE;
+             }
 
-         if (c == '\0')
-           return 0;
+           if (DO_ESCAPE && c == '\\')
+             c = get_char (&p);
 
-         {
-#ifndef G_OS_WIN32
-           char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
-#else
-           char c1 = c;
-#endif
-           c1 = FOLD (c1);
-           for (--p; *n != '\0'; ++n)
-             if ((c == '[' || FOLD (*n) == c1) &&
-                 fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
-               return 0;
-           return FNM_NOMATCH;
+           for (p = last_p; nc != '\0';)
+             {
+               if ((c == '[' || nc == c) &&
+                   gtk_fnmatch_intern (p, last_n, component_start))
+                 return TRUE;
+               
+               component_start = (nc == G_DIR_SEPARATOR);
+               last_n = n;
+               nc = get_char (&n);
+             }
+                 
+           return FALSE;
          }
 
        case '[':
          {
            /* Nonzero if the sense of the character class is inverted.  */
-           register int not;
+           gboolean not;
+           gboolean was_escaped;
 
-           if (*n == '\0')
-             return FNM_NOMATCH;
+           if (nc == '\0' || nc == G_DIR_SEPARATOR)
+             return FALSE;
 
-           if ((flags & FNM_PERIOD) && *n == '.' &&
-               (n == string || ((flags & FNM_FILE_NAME) && n[-1] == G_DIR_SEPARATOR)))
-             return FNM_NOMATCH;
+           if (nc == '.' && component_start)
+             return FALSE;
 
            not = (*p == '!' || *p == '^');
            if (not)
              ++p;
 
-           c = *p++;
+           c = get_unescaped_char (&p, &was_escaped);
            for (;;)
              {
-               register char cstart = c, cend = c;
-#ifndef G_OS_WIN32
-               if (!(flags & FNM_NOESCAPE) && c == '\\')
-                 cstart = cend = *p++;
-#endif
-               cstart = cend = FOLD (cstart);
-
+               register gunichar cstart = c, cend = c;
                if (c == '\0')
                  /* [ (unterminated) loses.  */
-                 return FNM_NOMATCH;
+                 return FALSE;
 
-               c = *p++;
-               c = FOLD (c);
-
-               if ((flags & FNM_FILE_NAME) && c == G_DIR_SEPARATOR)
-                 /* [/] can never match.  */
-                 return FNM_NOMATCH;
-
-               if (c == '-' && *p != ']')
+               c = get_unescaped_char (&p, &was_escaped);
+               
+               if (!was_escaped && c == '-' && *p != ']')
                  {
-                   cend = *p++;
-#ifndef G_OS_WIN32
-                   if (!(flags & FNM_NOESCAPE) && cend == '\\')
-                     cend = *p++;
-#endif
+                   cend = get_unescaped_char (&p, &was_escaped);
                    if (cend == '\0')
-                     return FNM_NOMATCH;
-                   cend = FOLD (cend);
+                     return FALSE;
 
-                   c = *p++;
+                   c = get_char (&p);
                  }
 
-               if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
+               if (nc >= cstart && nc <= cend)
                  goto matched;
 
-               if (c == ']')
+               if (!was_escaped && c == ']')
                  break;
              }
            if (!not)
-             return FNM_NOMATCH;
+             return FALSE;
            break;
 
          matched:;
            /* Skip the rest of the [...] that already matched.  */
-           while (c != ']')
+           /* XXX 1003.2d11 is unclear if was_escaped is right.  */
+           while (was_escaped || c != ']')
              {
                if (c == '\0')
                  /* [... (unterminated) loses.  */
-                 return FNM_NOMATCH;
+                 return FALSE;
 
-               c = *p++;
-#ifndef G_OS_WIN32
-               if (!(flags & FNM_NOESCAPE) && c == '\\')
-                 /* XXX 1003.2d11 is unclear if this is right.  */
-                 ++p;
-#endif
+               c = get_unescaped_char (&p, &was_escaped);
              }
            if (not)
-             return FNM_NOMATCH;
+             return FALSE;
          }
          break;
 
        default:
-         if (c != FOLD (*n))
-           return FNM_NOMATCH;
+         if (c != nc)
+           return FALSE;
        }
 
-      ++n;
+      component_start = (nc == G_DIR_SEPARATOR);
     }
 
   if (*n == '\0')
-    return 0;
+    return TRUE;
+
+  return FALSE;
+}
+
+/* Match STRING against the filename pattern PATTERN, returning zero if
+ *  it matches, nonzero if not.
+ *
+ * GTK+ used to use a old version of GNU fnmatch() that was buggy
+ * in various ways and didn't handle UTF-8. The following is
+ * converted to UTF-8. To simplify the process of making it
+ * correct, this is special-cased to the combinations of flags
+ * that gtkfilesel.c uses.
+ *
+ *   FNM_FILE_NAME   - always set
+ *   FNM_LEADING_DIR - never set
+ *   FNM_PERIOD      - always set
+ *   FNM_NOESCAPE    - set only on windows
+ *   FNM_CASEFOLD    - set only on windows
+ */
+gboolean
+_gtk_fnmatch (const char *pattern,
+             const char *string)
+{
+  return gtk_fnmatch_intern (pattern, string, TRUE);
+}
+
+#define FNMATCH_TEST_CASES
+#ifdef FNMATCH_TEST_CASES
 
-  if ((flags & FNM_LEADING_DIR) && *n == G_DIR_SEPARATOR)
-    /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  */
-    return 0;
+#define TEST(pat, str, result) \
+  g_assert (_gtk_fnmatch ((pat), (str)) == result)
 
-  return FNM_NOMATCH;
+int main (int argc, char **argv)
+{
+  TEST ("[a-]", "-", TRUE);
+  
+  TEST ("a", "a", TRUE);
+  TEST ("a", "b", FALSE);
+
+  /* Test what ? matches */
+  TEST ("?", "a", TRUE);
+  TEST ("?", ".", FALSE);
+  TEST ("a?", "a.", TRUE);
+  TEST ("a/?", "a/b", TRUE);
+  TEST ("a/?", "a/.", FALSE);
+  TEST ("?", "/", FALSE);
+
+  /* Test what * matches */
+  TEST ("*", "a", TRUE);
+  TEST ("*", ".", FALSE);
+  TEST ("a*", "a.", TRUE);
+  TEST ("a/*", "a/b", TRUE);
+  TEST ("a/*", "a/.", FALSE);
+  TEST ("*", "/", FALSE);
+
+  /* Range tests */
+  TEST ("[ab]", "a", TRUE);
+  TEST ("[ab]", "c", FALSE);
+  TEST ("[^ab]", "a", FALSE);
+  TEST ("[!ab]", "a", FALSE);
+  TEST ("[^ab]", "c", TRUE);
+  TEST ("[!ab]", "c", TRUE);
+  TEST ("[a-c]", "b", TRUE);
+  TEST ("[a-c]", "d", FALSE);
+  TEST ("[a-]", "-", TRUE);
+  TEST ("[]]", "]", TRUE);
+  TEST ("[^]]", "a", TRUE);
+  TEST ("[!]]", "a", TRUE);
+
+  /* Various unclosed ranges */
+  TEST ("[ab", "a", FALSE);
+  TEST ("[a-", "a", FALSE);
+  TEST ("[ab", "c", FALSE);
+  TEST ("[a-", "c", FALSE);
+  TEST ("[^]", "a", FALSE);
+
+  /* Ranges and special no-wildcard matches */
+  TEST ("[.]", ".", FALSE);
+  TEST ("a[.]", "a.", TRUE);
+  TEST ("a/[.]", "a/.", FALSE);
+  TEST ("[/]", "/", FALSE);
+  TEST ("[^/]", "a", TRUE);
+  
+  /* Basic tests of * (and combinations of * and ?) */
+  TEST ("a*b", "ab", TRUE);
+  TEST ("a*b", "axb", TRUE);
+  TEST ("a*b", "axxb", TRUE);
+  TEST ("a**b", "ab", TRUE);
+  TEST ("a**b", "axb", TRUE);
+  TEST ("a**b", "axxb", TRUE);
+  TEST ("a*?*b", "ab", FALSE);
+  TEST ("a*?*b", "axb", TRUE);
+  TEST ("a*?*b", "axxb", TRUE);
+
+  /* Test of  *[range] */
+  TEST ("a*[cd]", "ac", TRUE);
+  TEST ("a*[cd]", "axc", TRUE);
+  TEST ("a*[cd]", "axx", FALSE);
+
+  TEST ("a/[.]", "a/.", FALSE);
+  TEST ("a*[.]", "a/.", FALSE);
+
+  /* Test of UTF-8 */
+
+  TEST ("ä", "ä", TRUE);      /* TEST ("ä", "ä", TRUE); */
+  TEST ("?", "ä", TRUE);       /* TEST ("?", "ä", TRUE); */
+  TEST ("*ö", "äö", TRUE);   /* TEST ("*ö", "äö", TRUE); */
+  TEST ("*ö", "ääö", TRUE); /* TEST ("*ö", "ääö", TRUE); */
+  TEST ("[ä]", "ä", TRUE);    /* TEST ("[ä]", "ä", TRUE); */
+  TEST ("[ä-ö]", "é", TRUE); /* TEST ("[ä-ö]", "é", TRUE); */
+  TEST ("[ä-ö]", "a", FALSE); /* TEST ("[ä-ö]", "a", FALSE); */
+
+#ifdef DO_ESCAPE
+  /* Tests of escaping */
+  TEST ("\\\\", "\\", TRUE);
+  TEST ("\\?", "?", TRUE);
+  TEST ("\\?", "a", FALSE);
+  TEST ("\\*", "*", TRUE);
+  TEST ("\\*", "a", FALSE);
+  TEST ("\\[a-b]", "[a-b]", TRUE);
+  TEST ("[\\\\]", "\\", TRUE);
+  TEST ("[\\^a]", "a", TRUE);
+  TEST ("[a\\-c]", "b", FALSE);
+  TEST ("[a\\-c]", "-", TRUE);
+  TEST ("[a\\]", "a", FALSE);
+#endif /* DO_ESCAPE */
+  
+  return 0;
 }
 
-#endif /* _LIBC or not __GNU_LIBRARY__.  */
+#endif /* FNMATCH_TEST_CASES */
diff --git a/gtk/fnmatch.h b/gtk/fnmatch.h
deleted file mode 100644 (file)
index f2131f8..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, 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.
- */
-
-/*
- * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
- * file for a list of people on the GTK+ Team.  See the ChangeLog
- * files for a list of changes.  These files are distributed with
- * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
- */
-
-#ifndef        _FNMATCH_H
-
-#define        _FNMATCH_H      1
-
-#include <stdlib.h>            /* Something to pull in features.h */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if !defined (__GNU_LIBRARY__)
-#define fnmatch _gtk_fnmatch
-#endif
-
-#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
-#undef __P
-#define        __P(protos)     protos
-#else /* Not C++ or ANSI C.  */
-#undef __P
-#define        __P(protos)     ()
-/* We can get away without defining `const' here only because in this file
-   it is used only inside the prototype for `fnmatch', which is elided in
-   non-ANSI C where `const' is problematical.  */
-#endif /* C++ or ANSI C.  */
-
-
-/* We #undef these before defining them because some losing systems
-   (HP-UX A.08.07 for example) define these in <unistd.h>.  */
-#undef FNM_PATHNAME
-#undef FNM_NOESCAPE
-#undef FNM_PERIOD
-
-/* Bits set in the FLAGS argument to `fnmatch'.  */
-#define        FNM_PATHNAME    (1 << 0) /* No wildcard can ever match `/'.  */
-#define        FNM_NOESCAPE    (1 << 1) /* Backslashes don't quote special chars.  */
-#define        FNM_PERIOD      (1 << 2) /* Leading `.' is matched only explicitly.  */
-
-#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE)
-#define        FNM_FILE_NAME   FNM_PATHNAME /* Preferred GNU name.  */
-#define        FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match.  */
-#define        FNM_CASEFOLD    (1 << 4) /* Compare without regard to case.  */
-#endif
-
-/* Value returned by `fnmatch' if STRING does not match PATTERN.  */
-#define        FNM_NOMATCH     1
-
-/* Match STRING against the filename pattern PATTERN,
-   returning zero if it matches, FNM_NOMATCH if not.  */
-extern int fnmatch __P ((const char *__pattern, const char *__string,
-                        int __flags));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* fnmatch.h */
index 86e895dff1f1d115ad63a929174116bb88ec01c3..40b0ea5d1fc94e4b5d177b97c087453fc5cff7d5 100644 (file)
@@ -2844,10 +2844,6 @@ real_remove_row (GtkCList *clist,
     clist->row_list_end = g_list_previous (list);
   g_list_remove (list, clist_row);
 
-  /*if (clist->focus_row >=0 &&
-      (row <= clist->focus_row || clist->focus_row >= clist->rows))
-      clist->focus_row--;*/
-
   if (row < ROW_FROM_YPIXEL (clist, 0))
     clist->voffset += clist->row_height + CELL_SPACING;
 
@@ -4346,7 +4342,9 @@ sync_selection (GtkCList *clist,
        clist->focus_row += d;
       if (clist->focus_row == -1 && clist->rows >= 1)
        clist->focus_row = 0;
-      else if (clist->focus_row >= clist->rows)
+      else if (d < 0 && clist->focus_row >= clist->rows - 1)
+       clist->focus_row = clist->rows - 2;
+      else if (clist->focus_row >= clist->rows)        /* Paranoia */
        clist->focus_row = clist->rows - 1;
     }
 
index 2a11d0fedf17c504bf9058911dfe319fbc0480d7..061a0f476ada8b85dec6236e23f3c1f2def42cc1 100644 (file)
@@ -55,8 +55,6 @@
 #include <winsock.h>           /* For gethostname */
 #endif
 
-#include "fnmatch.h"
-
 #include "gdk/gdkkeysyms.h"
 #include "gtkbutton.h"
 #include "gtkcellrenderertext.h"
@@ -67,6 +65,7 @@
 #include "gtklabel.h"
 #include "gtkliststore.h"
 #include "gtkmain.h"
+#include "gtkprivate.h"
 #include "gtkscrolledwindow.h"
 #include "gtkstock.h"
 #include "gtktreeselection.h"
@@ -142,10 +141,6 @@ typedef struct _PossibleCompletion PossibleCompletion;
  * match by first_diff_index()
  */
 #define PATTERN_MATCH -1
-/* The arguments used by all fnmatch() calls below
- */
-#define FNMATCH_FLAGS (FNM_PATHNAME | FNM_PERIOD)
-
 #define CMPL_ERRNO_TOO_LONG ((1<<16)-1)
 #define CMPL_ERRNO_DID_NOT_CONVERT ((1<<16)-2)
 
@@ -3447,9 +3442,10 @@ find_parent_dir_fullname (gchar* dirname)
   
   if (chdir (sys_dirname) != 0 || chdir ("..") != 0)
     {
+      cmpl_errno = errno;
+      chdir (sys_orig_dir);
       g_free (sys_dirname);
       g_free (sys_orig_dir);
-      cmpl_errno = errno;
       return NULL;
     }
   g_free (sys_dirname);
@@ -3621,8 +3617,7 @@ find_completion_dir (gchar          *text_to_complete,
       for (i = 0; i < dir->sent->entry_count; i += 1)
        {
          if (dir->sent->entries[i].is_dir &&
-            fnmatch (pat_buf, dir->sent->entries[i].entry_name,
-                     FNMATCH_FLAGS)!= FNM_NOMATCH)
+             _gtk_fnmatch (pat_buf, dir->sent->entries[i].entry_name))
            {
              if (found)
                {
@@ -3649,7 +3644,7 @@ find_completion_dir (gchar          *text_to_complete,
        {
          g_free (pat_buf);
          return NULL;
-       }
+}
       
       next->cmpl_parent = dir;
       
@@ -3772,8 +3767,7 @@ attempt_file_completion (CompletionState *cmpl_state)
     {
       if (dir->sent->entries[dir->cmpl_index].is_dir)
        {
-         if (fnmatch (pat_buf, dir->sent->entries[dir->cmpl_index].entry_name,
-                      FNMATCH_FLAGS) != FNM_NOMATCH)
+         if (_gtk_fnmatch (pat_buf, dir->sent->entries[dir->cmpl_index].entry_name))
            {
              CompletionDir* new_dir;
 
@@ -3821,8 +3815,7 @@ attempt_file_completion (CompletionState *cmpl_state)
       append_completion_text (dir->sent->entries[dir->cmpl_index].entry_name, cmpl_state);
 
       cmpl_state->the_completion.is_a_completion =
-       fnmatch (pat_buf, dir->sent->entries[dir->cmpl_index].entry_name,
-                FNMATCH_FLAGS) != FNM_NOMATCH;
+       _gtk_fnmatch (pat_buf, dir->sent->entries[dir->cmpl_index].entry_name);
 
       cmpl_state->the_completion.is_directory = dir->sent->entries[dir->cmpl_index].is_dir;
       if (dir->sent->entries[dir->cmpl_index].is_dir)
index 86935ee1bb18fcb36a9ed1766122d42bc985d3d1..c42c26f05c58ebf45d683a7ce5d8a8611797cd2e 100644 (file)
@@ -96,6 +96,9 @@ const gchar *_gtk_get_data_prefix ();
 
 #endif /* G_OS_WIN32 */
 
+gboolean _gtk_fnmatch (const char *pattern,
+                      const char *string);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */