+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.
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
+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.
@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}
+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.
# 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.
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
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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 */
+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>,
# 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
--- /dev/null
+#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
+])
+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'.
# include <unistd.h>
#endif
+#include <fnmatch.h>
+
#include "dir-list.h"
#include "error.h"
#include "progname.h"
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
}
+/* 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().
/* 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. */