Re: [PATCH] exclude: new function, excluded_file_name_ext
Paul Eggert <[email protected]>
| Newsgroups | gmane.comp.lib.gnulib.bugs |
|---|---|
| Organization | UCLA Computer Science Department |
| Message-ID | <[email protected]> |
On 2026-08-17 01:48, Sergey Poznyakoff wrote: > I'm OK with it either way, the > most important thing is being able to tell how excluded_file_name > took the decision: using a matching entry or because nothing matched > the file name. OK, thanks, I installed the attached into Gnulib; if this won't do please let us know.
0001-exclude-new-function-excluded_file_name_status.patch
(text/x-patch, 8.9 KB)
From a50726598270147223685f91ac9761ce8a052a0e Mon Sep 17 00:00:00 2001 From: Paul Eggert <[email protected]> Date: Tue, 18 Aug 2026 01:20:04 -0700 Subject: [PATCH] exclude: new function excluded_file_name_status From a suggestion by Sergey Poznyakoff in: https://lists.gnu.org/r/bug-gnulib/2026-08/msg00217.html * lib/exclude.c (EXCLUDE_INLINE): New macro. (excluded_file_name_status): New function, extending excluded_file_name which is now in exclude.h. * lib/exclude.h (EXCLUDE_INLINE, EXCLUDED_EXCLUDED, EXCLUDED_MATCHED): New macros. (excluded_file_name): New function. * tests/test-exclude.c (main): Test new function too. All test scripts changed. --- ChangeLog | 14 ++++++++++++++ lib/exclude.c | 24 +++++++++++++----------- lib/exclude.h | 22 +++++++++++++++++++++- tests/test-exclude.c | 6 ++++-- tests/test-exclude1.sh | 12 ++++++------ tests/test-exclude2.sh | 12 ++++++------ tests/test-exclude3.sh | 12 ++++++------ tests/test-exclude4.sh | 2 +- tests/test-exclude5.sh | 8 ++++---- tests/test-exclude6.sh | 4 ++-- tests/test-exclude7.sh | 4 ++-- tests/test-exclude8.sh | 6 +++--- 12 files changed, 82 insertions(+), 44 deletions(-) diff --git a/ChangeLog b/ChangeLog index 752464e397..30ad4d78e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2026-08-18 Paul Eggert <[email protected]> + + exclude: new function excluded_file_name_status + From a suggestion by Sergey Poznyakoff in: + https://lists.gnu.org/r/bug-gnulib/2026-08/msg00217.html + * lib/exclude.c (EXCLUDE_INLINE): New macro. + (excluded_file_name_status): New function, extending + excluded_file_name which is now in exclude.h. + * lib/exclude.h (EXCLUDE_INLINE, EXCLUDED_EXCLUDED, EXCLUDED_MATCHED): + New macros. + (excluded_file_name): New function. + * tests/test-exclude.c (main): Test new function too. + All test scripts changed. + 2026-08-17 Bruno Haible <[email protected]> Depend on 'bool' for use of 'false' or 'true'. diff --git a/lib/exclude.c b/lib/exclude.c index 6a8604ec1b..0519ffec8e 100644 --- a/lib/exclude.c +++ b/lib/exclude.c @@ -21,6 +21,7 @@ Thanks to Phil Proudman <[email protected]> for improvement suggestions. */ +#define EXCLUDE_INLINE _GL_EXTERN_INLINE #include <config.h> #include <ctype.h> @@ -455,17 +456,18 @@ file_name_matches (struct exclude_segment const *seg, char const *f, return false; } -/* Return true if EX excludes F. */ +/* Return the status of whether EX excludes F. */ -bool -excluded_file_name (struct exclude const *ex, char const *f) +int +excluded_file_name_status (struct exclude const *ex, char const *f) { /* If no patterns are given, the default is to include. */ if (!ex->head) - return false; + return 0; bool invert = false; char *filename = nullptr; + bool found = false; /* Scan through the segments, reporting the status of the first match. The segments are in reverse order, so this reports the status of @@ -477,14 +479,13 @@ excluded_file_name (struct exclude const *ex, char const *f) { if (!filename) filename = xmalloc (strlen (f) + 1); - if (file_name_matches (seg, f, filename)) - break; + found = file_name_matches (seg, f, filename); } else - { - if (file_pattern_matches (seg, f)) - break; - } + found = file_pattern_matches (seg, f); + + if (found) + break; if (! seg->next) { @@ -500,7 +501,8 @@ excluded_file_name (struct exclude const *ex, char const *f) } free (filename); - return invert ^ ! (seg->options & EXCLUDE_INCLUDE); + return ((invert ^ ! (seg->options & EXCLUDE_INCLUDE) ? EXCLUDED_EXCLUDED : 0) + | (found ? EXCLUDED_MATCHED : 0)); } /* Append to EX the exclusion PATTERN with OPTIONS. */ diff --git a/lib/exclude.h b/lib/exclude.h index c217a1e4e6..3c77493f75 100644 --- a/lib/exclude.h +++ b/lib/exclude.h @@ -30,6 +30,11 @@ #include <stdio.h> +_GL_INLINE_HEADER_BEGIN +#ifndef EXCLUDE_INLINE +# define EXCLUDE_INLINE _GL_INLINE +#endif + #ifdef __cplusplus extern "C" { #endif @@ -54,6 +59,12 @@ extern "C" { /* Allocate storage for the pattern */ #define EXCLUDE_ALLOC (1 << 26) + +/* Return status flags for excluded_file_name_status. */ +#define EXCLUDED_EXCLUDED (1 << 0) /* The file name was excluded. */ +#define EXCLUDED_MATCHED (1 << 1) /* The file name was matched. */ + + struct exclude; bool fnmatch_pattern_has_wildcards (const char *, int) _GL_ATTRIBUTE_PURE; @@ -68,13 +79,22 @@ int add_exclude_file (void (*) (struct exclude *, char const *, int), struct exclude *, char const *, int, char); int add_exclude_fp (void (*) (struct exclude *, char const *, int, void *), struct exclude *, FILE *, int, char, void *); -bool excluded_file_name (struct exclude const *, char const *); +int excluded_file_name_status (struct exclude const *, char const *); void exclude_add_pattern_buffer (struct exclude *ex, char *buf); bool exclude_fnmatch (char const *, char const *, int); +/* Return true if EX excludes F. */ +EXCLUDE_INLINE bool +excluded_file_name (struct exclude const *ex, char const *f) +{ + return excluded_file_name_status (ex, f) & EXCLUDED_EXCLUDED; +} + #ifdef __cplusplus } #endif +_GL_INLINE_HEADER_END + #endif /* _GL_EXCLUDE_H */ diff --git a/tests/test-exclude.c b/tests/test-exclude.c index 17c631c02a..e57b34d232 100644 --- a/tests/test-exclude.c +++ b/tests/test-exclude.c @@ -118,8 +118,10 @@ main (int argc, char **argv) for (; argc; --argc) { char *word = *++argv; - - printf ("%s: %d\n", word, excluded_file_name (exclude, word)); + bool excluded = excluded_file_name (exclude, word); + int status = excluded_file_name_status (exclude, word); + printf ("%s: %d %d%s\n", word, excluded, !!(status & EXCLUDED_MATCHED), + excluded != !!(status & EXCLUDED_EXCLUDED) ? " !" : ""); } free_exclude (exclude); diff --git a/tests/test-exclude1.sh b/tests/test-exclude1.sh index 0e2058915c..890da3ba43 100755 --- a/tests/test-exclude1.sh +++ b/tests/test-exclude1.sh @@ -28,12 +28,12 @@ Baz EOT cat > expected <<EOT -foo: 0 -foo*: 1 -bar: 1 -foobar: 0 -baz: 0 -bar/qux: 0 +foo: 0 0 +foo*: 1 1 +bar: 1 1 +foobar: 0 0 +baz: 0 0 +bar/qux: 0 0 EOT ${CHECKER} test-exclude in -- foo 'foo*' bar foobar baz bar/qux > out || exit $? diff --git a/tests/test-exclude2.sh b/tests/test-exclude2.sh index 25b69f4b90..c67a5d7473 100755 --- a/tests/test-exclude2.sh +++ b/tests/test-exclude2.sh @@ -28,12 +28,12 @@ EOT # Test case-insensitive literal matches cat > expected <<EOT -foo: 0 -foo*: 1 -bar: 1 -foobar: 0 -baz: 1 -bar/qux: 0 +foo: 0 0 +foo*: 1 1 +bar: 1 1 +foobar: 0 0 +baz: 1 1 +bar/qux: 0 0 EOT ${CHECKER} test-exclude -casefold in -- foo 'foo*' bar foobar baz bar/qux > out || exit $? diff --git a/tests/test-exclude3.sh b/tests/test-exclude3.sh index bfd168c21b..e3f35d8ce2 100755 --- a/tests/test-exclude3.sh +++ b/tests/test-exclude3.sh @@ -28,12 +28,12 @@ Baz EOT cat > expected <<EOT -foo: 1 -foo*: 0 -bar: 0 -foobar: 1 -baz: 1 -bar/qux: 1 +foo: 1 0 +foo*: 0 1 +bar: 0 1 +foobar: 1 0 +baz: 1 0 +bar/qux: 1 0 EOT ${CHECKER} test-exclude -include in -- foo 'foo*' bar foobar baz bar/qux > out || exit $? diff --git a/tests/test-exclude4.sh b/tests/test-exclude4.sh index 55ce8cfb86..4f250db3a8 100755 --- a/tests/test-exclude4.sh +++ b/tests/test-exclude4.sh @@ -28,7 +28,7 @@ Baz EOT cat > expected <<EOT -foobar: 1 +foobar: 1 1 EOT ${CHECKER} test-exclude -wildcards in -- foobar > out || exit $? diff --git a/tests/test-exclude5.sh b/tests/test-exclude5.sh index 6978ba4cd6..8372d9463b 100755 --- a/tests/test-exclude5.sh +++ b/tests/test-exclude5.sh @@ -28,10 +28,10 @@ Baz EOT cat > expected <<EOT -bar: 1 -bar/qux: 1 -barz: 0 -foo/bar: 1 +bar: 1 1 +bar/qux: 1 1 +barz: 0 0 +foo/bar: 1 1 EOT ${CHECKER} test-exclude -leading_dir in -- bar bar/qux barz foo/bar > out || exit $? diff --git a/tests/test-exclude6.sh b/tests/test-exclude6.sh index 240115a4f6..8b882f4e53 100755 --- a/tests/test-exclude6.sh +++ b/tests/test-exclude6.sh @@ -28,8 +28,8 @@ Baz EOT cat > expected <<EOT -bar: 1 -foo/bar: 0 +bar: 1 1 +foo/bar: 0 0 EOT ${CHECKER} test-exclude -anchored in -- bar foo/bar > out || exit $? diff --git a/tests/test-exclude7.sh b/tests/test-exclude7.sh index cb701d2c86..a8953c9d7b 100755 --- a/tests/test-exclude7.sh +++ b/tests/test-exclude7.sh @@ -28,8 +28,8 @@ Baz EOT cat > expected <<EOT -bar: 0 -bar: 1 +bar: 0 1 +bar: 1 1 EOT ${CHECKER} test-exclude in -include in -- bar > out || exit $? diff --git a/tests/test-exclude8.sh b/tests/test-exclude8.sh index 02524d6e89..e7a304ab65 100755 --- a/tests/test-exclude8.sh +++ b/tests/test-exclude8.sh @@ -27,9 +27,9 @@ b[a\*]r EOT cat > expected <<'EOT' -f*e: 1 -file: 0 -bar: 1 +f*e: 1 1 +file: 0 0 +bar: 1 1 EOT ${CHECKER} test-exclude -wildcards in -- 'f*e' 'file' 'bar' > out || exit $? -- 2.55.0