From: Bruno Haible Date: Tue, 18 Dec 2001 13:42:35 +0000 (+0000) Subject: msggrep --location now accepts wildcards. X-Git-Tag: v0.11~163 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2470ca28e843e6bca8ba474fc01976adee802aa2;p=thirdparty%2Fgettext.git msggrep --location now accepts wildcards. --- diff --git a/ChangeLog b/ChangeLog index c732fd882..2e11e845d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2001-12-17 Bruno Haible + + * configure.in: Call gt_FUNC_FNMATCH. + 2001-12-17 Bruno Haible * configure.in: Change version number to 0.11-pre4. diff --git a/configure.in b/configure.in index 5a5eccac7..4a9b47e0c 100644 --- a/configure.in +++ b/configure.in @@ -74,6 +74,7 @@ AM_FUNC_GETLINE if test $am_cv_func_working_getline != yes; then AC_CHECK_FUNCS(getdelim) fi +gt_FUNC_FNMATCH jm_PREREQ_MBSWIDTH gt_PREREQ_BACKUPFILE AC_FUNC_VFORK diff --git a/doc/ChangeLog b/doc/ChangeLog index 29fd0fd2b..bcb119f97 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,7 @@ +2001-12-17 Bruno Haible + + * msggrep.texi: Document that --location arguments may be wildcards. + 2001-12-16 Bruno Haible * gettext.texi (librep): Update. diff --git a/doc/msggrep.texi b/doc/msggrep.texi index a9c48b288..5f8e912e6 100644 --- a/doc/msggrep.texi +++ b/doc/msggrep.texi @@ -62,7 +62,8 @@ expressions if -E is given, or fixed strings if -F is given. @table @samp @item -N @var{sourcefile} @itemx --location=@var{sourcefile} -Select messages extracted from @var{sourcefile}. +Select messages extracted from @var{sourcefile}. @var{sourcefile} can be +either a literal file name or a wildcard pattern. @item -M @var{domainname} @itemx --domain=@var{domainname} diff --git a/lib/ChangeLog b/lib/ChangeLog index 8c44fc31c..3a568db05 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,13 @@ +2001-12-17 Bruno Haible + + * pfnmatch.h: New file, from fileutils-4.1/lib/fnmatch.h with + modifications. + * pfnmatch.c: New file, from fileutils-4.1/lib/fnmatch.c with + modifications. + * Makefile.am (LIBADD_SOURCE): Add pfnmatch.c. + (LIBADD_HEADER): Add pfnmatch.h. + (DISTCLEANFILES): New variable. + 2001-12-18 Bruno Haible * getline.h: Include , for size_t. diff --git a/lib/Makefile.am b/lib/Makefile.am index 027ada83c..40141d3fe 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -38,11 +38,12 @@ utf16-ucs4.h wait-process.h xerror.h xmalloc.h # Sources that are compiled only on platforms that lack the functions. -LIBADD_SOURCE = alloca.c error.c getline.c memset.c mkdtemp.c setenv.c \ -stpcpy.c stpncpy.c strcasecmp.c strcspn.c strncasecmp.c strpbrk.c strstr.c \ -strtol.c strtoul.c vasprintf.c +LIBADD_SOURCE = alloca.c error.c getline.c memset.c mkdtemp.c pfnmatch.c \ +setenv.c stpcpy.c stpncpy.c strcasecmp.c strcspn.c strncasecmp.c strpbrk.c \ +strstr.c strtol.c strtoul.c vasprintf.c -LIBADD_HEADER = error.h getline.h mkdtemp.h setenv.h strpbrk.h strstr.h +LIBADD_HEADER = error.h getline.h mkdtemp.h pfnmatch.h setenv.h strpbrk.h \ +strstr.h # Unused sources. @@ -73,6 +74,9 @@ DEFS = -DLIBDIR=\"$(libdir)\" @DEFS@ INCLUDES = -I. -I$(srcdir) -I.. -I../intl -I$(top_srcdir)/intl +DISTCLEANFILES = fnmatch.h + + all-local execute.lo javacomp.lo javaexec.lo pipe-bidi.lo pipe-in.lo pipe-out.lo progname.lo wait-process.lo xerror.lo: @STDBOOL_H@ stdbool.h: stdbool.h.in cp $(srcdir)/stdbool.h.in stdbool.h diff --git a/lib/pfnmatch.c b/lib/pfnmatch.c new file mode 100644 index 000000000..e2c897aa4 --- /dev/null +++ b/lib/pfnmatch.c @@ -0,0 +1,211 @@ +/* POSIX fnmatch(). + Copyright 1991-1993, 1996, 1997, 2000, 2001 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* Enable GNU extensions in fnmatch.h. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#if HAVE_CONFIG_H +# include +#endif + +/* Specification. */ +#include "fnmatch.h" + +#include + + +/* 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; + + while ((c = *p++) != '\0') + { + switch (c) + { + case '?': + if (*n == '\0') + return FNM_NOMATCH; + else if ((flags & FNM_FILE_NAME) && *n == '/') + return FNM_NOMATCH; + else if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) + return FNM_NOMATCH; + break; + + case '\\': + if (!(flags & FNM_NOESCAPE)) + { + c = *p++; + if (c == '\0') + /* Trailing \ loses. */ + return FNM_NOMATCH; + } + if (*n != c) + return FNM_NOMATCH; + break; + + case '*': + if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) + return FNM_NOMATCH; + + for (c = *p++; c == '?' || c == '*'; c = *p++) + { + if (c == '?') + { + /* A ? needs to match one character. */ + if (*n == '\0' || (*n == '/' && (flags & FNM_FILE_NAME))) + /* There isn't another character; no match. */ + return FNM_NOMATCH; + else + /* One character of the string is consumed in matching + this ? wildcard, so *??? won't match if there are + less than three characters. */ + ++n; + } + } + + if (c == '\0') + { + if ((flags & (FNM_FILE_NAME | FNM_LEADING_DIR)) == FNM_FILE_NAME) + for (; *n != '\0'; n++) + if (*n == '/') + return FNM_NOMATCH; + return 0; + } + + { + char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c; + for (--p; *n != '\0'; ++n) + if ((c == '[' || *n == c1) && + fnmatch (p, n, flags & ~FNM_PERIOD) == 0) + return 0; + else if (*n == '/' && (flags & FNM_FILE_NAME)) + break; + return FNM_NOMATCH; + } + + case '[': + { + /* Nonzero if the sense of the character class is inverted. */ + register int not; + + if (*n == '\0') + return FNM_NOMATCH; + + if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) + return FNM_NOMATCH; + + not = (*p == '!' || *p == '^'); + if (not) + ++p; + + c = *p++; + for (;;) + { + register char cstart = c, cend = c; + + if (!(flags & FNM_NOESCAPE) && c == '\\') + { + if (*p == '\0') + return FNM_NOMATCH; + cstart = cend = *p++; + } + + cend = cstart; + + if (c == '\0') + /* [ (unterminated) loses. */ + return FNM_NOMATCH; + + c = *p++; + + if ((flags & FNM_FILE_NAME) && c == '/') + /* [/] can never match. */ + return FNM_NOMATCH; + + if (c == '-' && *p != ']') + { + cend = *p++; + if (!(flags & FNM_NOESCAPE) && cend == '\\') + cend = *p++; + if (cend == '\0') + return FNM_NOMATCH; + + c = *p++; + } + + if ((unsigned char) *n >= (unsigned char) cstart + && (unsigned char) *n <= (unsigned char) cend) + goto matched; + + if (c == ']') + break; + } + if (!not) + return FNM_NOMATCH; + break; + + matched:; + /* Skip the rest of the [...] that already matched. */ + while (c != ']') + { + if (c == '\0') + /* [... (unterminated) loses. */ + return FNM_NOMATCH; + + c = *p++; + if (!(flags & FNM_NOESCAPE) && c == '\\') + { + if (*p == '\0') + return FNM_NOMATCH; + /* XXX 1003.2d11 is unclear if this is right. */ + ++p; + } + } + if (not) + return FNM_NOMATCH; + } + break; + + default: + if (c != *n) + return FNM_NOMATCH; + } + + ++n; + } + + if (*n == '\0') + return 0; + + if ((flags & FNM_LEADING_DIR) && *n == '/') + /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ + return 0; + + return FNM_NOMATCH; +} diff --git a/lib/pfnmatch.h b/lib/pfnmatch.h new file mode 100644 index 000000000..420024e20 --- /dev/null +++ b/lib/pfnmatch.h @@ -0,0 +1,62 @@ +/* POSIX . + Copyright (C) 1991-1993, 2001 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef _FNMATCH_H +#define _FNMATCH_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef PARAMS +# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES +# define PARAMS(Args) Args +# else +# define PARAMS(Args) () +# endif +#endif + + +/* 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. */ +#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 PARAMS ((const char *__pattern, const char *__string, + int __flags)); + +#ifdef __cplusplus +} +#endif + +#endif /* fnmatch.h */ diff --git a/m4/ChangeLog b/m4/ChangeLog index 90853af06..320cc00a4 100644 --- a/m4/ChangeLog +++ b/m4/ChangeLog @@ -1,3 +1,8 @@ +2001-12-17 Bruno Haible + + * fnmatch.m4: New file, inspired by autoconf-2.13 and autoconf-2.52. + * Makefile.am (EXTRA_DIST): Add it. + 2001-12-17 Bruno Haible * getline.m4 (AM_FUNC_GETLINE): Include , not , diff --git a/m4/Makefile.am b/m4/Makefile.am index 23054aa1c..38303e99b 100644 --- a/m4/Makefile.am +++ b/m4/Makefile.am @@ -7,9 +7,9 @@ aclocal_DATA = codeset.m4 gettext.m4 glibc21.m4 iconv.m4 isc-posix.m4 lib-ld.m4 # find . -type f -name '*.m4' -printf '%f\n'|sort |fmt |tr '\012' @ \ # |sed 's/@$/%/;s/@/ \\@/g' |tr @% '\012\012' EXTRA_DIST = README \ -backupfile.m4 c-bs-a.m4 codeset.m4 flex.m4 getline.m4 gettext.m4 \ -glibc21.m4 hostname.m4 iconv.m4 inttypes_h.m4 isc-posix.m4 javacomp.m4 \ -javaexec.m4 lcmessage.m4 lib-ld.m4 lib-link.m4 lib-prefix.m4 libtool.m4 \ -mbrtowc.m4 mbstate_t.m4 mbswidth.m4 mkdtemp.m4 progtest.m4 setenv.m4 \ -setlocale.m4 siginfo.m4 signalblocking.m4 signed.m4 ssize_t.m4 stdbool.m4 \ -stdint_h.m4 tmpdir.m4 uintmax_t.m4 ulonglong.m4 unionwait.m4 +backupfile.m4 c-bs-a.m4 codeset.m4 flex.m4 fnmatch.m4 getline.m4 \ +gettext.m4 glibc21.m4 hostname.m4 iconv.m4 inttypes_h.m4 isc-posix.m4 \ +javacomp.m4 javaexec.m4 lcmessage.m4 lib-ld.m4 lib-link.m4 lib-prefix.m4 \ +libtool.m4 mbrtowc.m4 mbstate_t.m4 mbswidth.m4 mkdtemp.m4 progtest.m4 \ +setenv.m4 setlocale.m4 siginfo.m4 signalblocking.m4 signed.m4 ssize_t.m4 \ +stdbool.m4 stdint_h.m4 tmpdir.m4 uintmax_t.m4 ulonglong.m4 unionwait.m4 diff --git a/m4/fnmatch.m4 b/m4/fnmatch.m4 new file mode 100644 index 000000000..b20bcec61 --- /dev/null +++ b/m4/fnmatch.m4 @@ -0,0 +1,43 @@ +#serial 1 + +dnl Determine whether the system has a working fnmatch() function. +AC_DEFUN([gt_FUNC_FNMATCH], +[ + dnl Don't use AC_FUNC_FNMATCH. In autoconf-2.52 the test is buggy and + dnl excludes all non-GNU implementations. + dnl Some versions of Solaris or SCO have a broken fnmatch function. + dnl So we run a test program. If we are cross-compiling, take no chance. + dnl Thanks to John Oleynick and Franc,ois Pinard for this test. + AC_CACHE_CHECK([for working fnmatch function], gt_cv_func_fnmatch_works, [ + AC_TRY_RUN([ +# include +# include + int main () + { + exit (fnmatch ("a*", "abc", 0) != 0 + || fnmatch ("d*/*1", "d/s/1", FNM_PATHNAME) != FNM_NOMATCH); + } + ], + gt_cv_func_fnmatch_works=yes, gt_cv_func_fnmatch_works=no, + gt_cv_func_fnmatch_works=no dnl cross-compiling + ) + ]) + if test $gt_cv_func_fnmatch_works = yes; then + AC_DEFINE([HAVE_FNMATCH], 1, + [Define if you have and a working fnmatch() function.]) + fi + + dnl Now some other actions, not part of AC_FUNC_FNMATCH. + if test $gt_cv_func_fnmatch_works = yes; then + rm -f lib/fnmatch.h + else + echo '#include "pfnmatch.h"' > lib/fnmatch.h + dnl We must choose a different name for our function, since on ELF systems + dnl a broken fnmatch() in libc.so would override our fnmatch() in + dnl libgettextlib.so. + AC_DEFINE([fnmatch], [posix_fnmatch], + [Define to a replacement function name for fnmatch().]) + LIBOBJS="$LIBOBJS pfnmatch.${ac_objext}" + AC_SUBST(LIBOBJS) + fi +]) diff --git a/src/ChangeLog b/src/ChangeLog index 07a4b9520..dff025afb 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2001-12-17 Bruno Haible + + * msggrep.c: Include . + (filename_list_match): New function. + (is_message_selected): Use it instead of string_list_member. + 2001-12-16 Bruno Haible * message.h (format_type): New enum value 'format_librep'. diff --git a/src/msggrep.c b/src/msggrep.c index d973630eb..bd061c20b 100644 --- a/src/msggrep.c +++ b/src/msggrep.c @@ -34,6 +34,8 @@ # include #endif +#include + #include "dir-list.h" #include "error.h" #include "progname.h" @@ -105,6 +107,8 @@ static const struct option long_options[] = function argument counts despite of K&R C function definition syntax. */ static void no_pass PARAMS ((int opt)); static void usage PARAMS ((int status)); +static bool filename_list_match PARAMS ((const string_list_ty *slp, + const char *filename)); #ifdef EINTR static inline int nonintr_close PARAMS ((int fd)); #endif @@ -462,6 +466,22 @@ Informative output:\n\ } +/* Return 1 if FILENAME is contained in a list of filename patterns, + 0 otherwise. */ +static bool +filename_list_match (slp, filename) + const string_list_ty *slp; + const char *filename; +{ + size_t j; + + for (j = 0; j < slp->nitems; ++j) + if (fnmatch (slp->item[j], filename, FNM_PATHNAME) == 0) + return true; + return false; +} + + #ifdef EINTR /* EINTR handling for close(). @@ -536,7 +556,7 @@ is_message_selected (mp) /* Test whether one of mp->filepos[] is selected. */ for (i = 0; i < mp->filepos_count; i++) - if (string_list_member (location_files, mp->filepos[i].file_name)) + if (filename_list_match (location_files, mp->filepos[i].file_name)) return true; /* Test msgid and msgid_plural using the --msgid arguments. */