From 73b15ba391b3a533786e2a2f4f80274b80866822 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Fri, 13 Dec 2002 23:18:03 +0000 Subject: [PATCH] System fnmatch wasn't going to be UTF-8 clean, neither was our version. Fri Dec 13 17:45:40 2002 Owen Taylor * 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 | 18 +++ ChangeLog.pre-2-10 | 18 +++ ChangeLog.pre-2-2 | 18 +++ ChangeLog.pre-2-4 | 18 +++ ChangeLog.pre-2-6 | 18 +++ ChangeLog.pre-2-8 | 18 +++ gtk/fnmatch.c | 393 ++++++++++++++++++++++++++++++--------------- gtk/fnmatch.h | 81 ---------- gtk/gtkclist.c | 8 +- gtk/gtkfilesel.c | 21 +-- gtk/gtkprivate.h | 3 + 11 files changed, 385 insertions(+), 229 deletions(-) delete mode 100644 gtk/fnmatch.h diff --git a/ChangeLog b/ChangeLog index f2fa7fb01..6cf2be7b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +Fri Dec 13 17:45:40 2002 Owen Taylor + + * 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 + + * 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 * gtk/gtkfilesel.c (cmpl_completion_fullname): Const diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index f2fa7fb01..6cf2be7b6 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,21 @@ +Fri Dec 13 17:45:40 2002 Owen Taylor + + * 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 + + * 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 * gtk/gtkfilesel.c (cmpl_completion_fullname): Const diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index f2fa7fb01..6cf2be7b6 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,21 @@ +Fri Dec 13 17:45:40 2002 Owen Taylor + + * 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 + + * 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 * gtk/gtkfilesel.c (cmpl_completion_fullname): Const diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index f2fa7fb01..6cf2be7b6 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,21 @@ +Fri Dec 13 17:45:40 2002 Owen Taylor + + * 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 + + * 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 * gtk/gtkfilesel.c (cmpl_completion_fullname): Const diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index f2fa7fb01..6cf2be7b6 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,21 @@ +Fri Dec 13 17:45:40 2002 Owen Taylor + + * 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 + + * 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 * gtk/gtkfilesel.c (cmpl_completion_fullname): Const diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index f2fa7fb01..6cf2be7b6 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,21 @@ +Fri Dec 13 17:45:40 2002 Owen Taylor + + * 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 + + * 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 * gtk/gtkfilesel.c (cmpl_completion_fullname): Const diff --git a/gtk/fnmatch.c b/gtk/fnmatch.c index 198363fc8..e6ccb4073 100644 --- a/gtk/fnmatch.c +++ b/gtk/fnmatch.c @@ -23,206 +23,341 @@ * 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 -#include /* tolower */ +#include -/* Added for GTK. We need to make sure that all constants are defined - * to properly compile this file */ +#include + +/* 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 +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 index f2131f8f5..000000000 --- a/gtk/fnmatch.h +++ /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 /* 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 . */ -#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 */ diff --git a/gtk/gtkclist.c b/gtk/gtkclist.c index 86e895dff..40b0ea5d1 100644 --- a/gtk/gtkclist.c +++ b/gtk/gtkclist.c @@ -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; } diff --git a/gtk/gtkfilesel.c b/gtk/gtkfilesel.c index 2a11d0fed..061a0f476 100644 --- a/gtk/gtkfilesel.c +++ b/gtk/gtkfilesel.c @@ -55,8 +55,6 @@ #include /* 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) diff --git a/gtk/gtkprivate.h b/gtk/gtkprivate.h index 86935ee1b..c42c26f05 100644 --- a/gtk/gtkprivate.h +++ b/gtk/gtkprivate.h @@ -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 */ -- 2.43.2