]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
msggrep --location now accepts wildcards.
authorBruno Haible <bruno@clisp.org>
Tue, 18 Dec 2001 13:42:35 +0000 (13:42 +0000)
committerBruno Haible <bruno@clisp.org>
Sun, 21 Jun 2009 21:50:24 +0000 (23:50 +0200)
13 files changed:
ChangeLog
configure.in
doc/ChangeLog
doc/msggrep.texi
lib/ChangeLog
lib/Makefile.am
lib/pfnmatch.c [new file with mode: 0644]
lib/pfnmatch.h [new file with mode: 0644]
m4/ChangeLog
m4/Makefile.am
m4/fnmatch.m4 [new file with mode: 0644]
src/ChangeLog
src/msggrep.c

index c732fd882929f4a0e9f73d179b2d2ea7ea7a0ad3..2e11e845d4990d8b48eb43dada2dc450308d588c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2001-12-17  Bruno Haible  <bruno@clisp.org>
+
+       * configure.in: Call gt_FUNC_FNMATCH.
+
 2001-12-17  Bruno Haible  <bruno@clisp.org>
 
        * configure.in: Change version number to 0.11-pre4.
index 5a5eccac7a15668840b82be9d69d55127c68c3a3..4a9b47e0c54871af1052004276c26fdc6e788acf 100644 (file)
@@ -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
index 29fd0fd2b30ac5377457b73608f8cba3e1aba74b..bcb119f97420839c2f2772afb5207f159c5a656f 100644 (file)
@@ -1,3 +1,7 @@
+2001-12-17  Bruno Haible  <bruno@clisp.org>
+
+       * msggrep.texi: Document that --location arguments may be wildcards.
+
 2001-12-16  Bruno Haible  <bruno@clisp.org>
 
        * gettext.texi (librep): Update.
index a9c48b288149f57c9d426546388fa8bd220f8430..5f8e912e6e324862c011884bc03552cd85e1d22e 100644 (file)
@@ -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}
index 8c44fc31c302e50f1a6d3c30e1594a5e82bf9bc4..3a568db058661d4e53583b4bdea78d9f7380b653 100644 (file)
@@ -1,3 +1,13 @@
+2001-12-17  Bruno Haible  <bruno@clisp.org>
+
+       * 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  <bruno@clisp.org>
 
        * getline.h: Include <stddef.h>, for size_t.
index 027ada83c741b6b9966b90fa618b54fd699e67e1..40141d3fe7b9e52b4bd7e126c730c4be50a27795 100644 (file)
@@ -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 (file)
index 0000000..e2c897a
--- /dev/null
@@ -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 <config.h>
+#endif
+
+/* Specification.  */
+#include "fnmatch.h"
+
+#include <errno.h>
+
+
+/* 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 (file)
index 0000000..420024e
--- /dev/null
@@ -0,0 +1,62 @@
+/* POSIX <fnmatch.h>.
+   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 <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.  */
+#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 */
index 90853af06fca3caf836cfad0d753b960be12fb9d..320cc00a4b424f53a7ea71031ac1182f67d951a7 100644 (file)
@@ -1,3 +1,8 @@
+2001-12-17  Bruno Haible  <bruno@clisp.org>
+
+       * fnmatch.m4: New file, inspired by autoconf-2.13 and autoconf-2.52.
+       * Makefile.am (EXTRA_DIST): Add it.
+
 2001-12-17  Bruno Haible  <bruno@clisp.org>
 
        * getline.m4 (AM_FUNC_GETLINE): Include <stdlib.h>, not <sys/types.h>,
index 23054aa1c6be0b52415f6d4d81832d71f42b2f41..38303e99b9350dfe2428ff24366f00243aac1453 100644 (file)
@@ -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 (file)
index 0000000..b20bcec
--- /dev/null
@@ -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 <stdlib.h>
+#     include <fnmatch.h>
+      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 <fnmatch.h> 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
+])
index 07a4b952010466f63b010068ff8f068672395476..dff025afbbde98640b1723107c7dcea3f0b83209 100644 (file)
@@ -1,3 +1,9 @@
+2001-12-17  Bruno Haible  <bruno@clisp.org>
+
+       * msggrep.c: Include <fnmatch.h>.
+       (filename_list_match): New function.
+       (is_message_selected): Use it instead of string_list_member.
+
 2001-12-16  Bruno Haible  <bruno@clisp.org>
 
        * message.h (format_type): New enum value 'format_librep'.
index d973630ebc3d203958fe404e7ac853295a7442bf..bd061c20bcf2d8d0a385de8daab4408a25c140ea 100644 (file)
@@ -34,6 +34,8 @@
 # include <unistd.h>
 #endif
 
+#include <fnmatch.h>
+
 #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.  */