diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2014-07-29 09:03:50 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2014-07-29 09:03:50 +0300 |
commit | 8397a2858f103397d4ae82156b43f7048e788c3b (patch) | |
tree | 834a72cf1ab40701175349000bb5fbbaf06daa59 | |
parent | 2e9dee9f4ac310b688281dd840e5c132f26e108f (diff) | |
download | direvent-8397a2858f103397d4ae82156b43f7048e788c3b.tar.gz direvent-8397a2858f103397d4ae82156b43f7048e788c3b.tar.bz2 |
Introduce pattern negation.
* doc/dircond.conf.5: Document negated patterns.
* doc/dircond.texi: Likewise.
* src/config.c (file_name_pattern): A ! in front of a pattern
indicates negation.
* src/dircond.h (filename_pattern)<neg>: New member.
* src/fnpat.c: Honor neg member.
* tests/envdump.c (main): don't depend on the order of command
line options.
* tests/glob02.at: New test case.
* tests/re05.at: Likewise.
* tests/Makefile.am: Add new files.
* tests/testsuite.at: Include new testcases.
-rw-r--r-- | doc/dircond.conf.5 | 5 | ||||
-rw-r--r-- | doc/dircond.texi | 6 | ||||
m--------- | grecs | 0 | ||||
-rw-r--r-- | src/config.c | 6 | ||||
-rw-r--r-- | src/dircond.h | 1 | ||||
-rw-r--r-- | src/fnpat.c | 14 | ||||
-rw-r--r-- | tests/Makefile.am | 4 | ||||
-rw-r--r-- | tests/envdump.c | 17 | ||||
-rw-r--r-- | tests/glob02.at | 67 | ||||
-rw-r--r-- | tests/re05.at | 67 | ||||
-rw-r--r-- | tests/testsuite.at | 4 |
11 files changed, 173 insertions, 18 deletions
diff --git a/doc/dircond.conf.5 b/doc/dircond.conf.5 index c257402..199045d 100644 --- a/doc/dircond.conf.5 +++ b/doc/dircond.conf.5 @@ -13,7 +13,7 @@ .\" .\" You should have received a copy of the GNU General Public License along .\" with dircond. If not, see <http://www.gnu.org/licenses/>. -.TH DIRCOND.CONF 5 "December 27, 2013" "DIRCOND" "Dircond User Reference" +.TH DIRCOND.CONF 5 "July 29, 2014" "DIRCOND" "Dircond User Reference" dircond.conf \- configuration file for .BR dircond (8). .SH DESCRIPTION @@ -430,6 +430,9 @@ Use basic regular expressions. .TP .B i Enable case-insensitive matching. + +A pattern or regular expression prefixed with \fB!\fR matches +file names that don't match the pattern without \fB!\fR. .RE .TP \fBevent\fR \fISTRING\-LIST\fR; diff --git a/doc/dircond.texi b/doc/dircond.texi index 760a8a9..4cf0600 100644 --- a/doc/dircond.texi +++ b/doc/dircond.texi @@ -794,8 +794,10 @@ list of globbing patterns (in the sense of @pxref{fnmatch, fnmatch, fnmatch, fnmatch manual,fnmatch(3)}) or extended regular expressions (@pxref{Extended regexps, Extended regular expressions, Extended regular expressions, -sed, GNU sed}) one of which the file name must match in -order for the watcher to act on it. Regular expressions must +sed, GNU sed}) one of which must match the file name in +order for the watcher to act on it. A @samp{!} in front of a pattern +or regular expression indicates negation. Such construct matches +if the file name doesn't match the pattern. Regular expressions must be surrounded by a pair of slashes, optionally followed by the following flags: diff --git a/grecs b/grecs -Subproject 9c964ec8a4fe23fef993a1cf7f4563d0c32b68b +Subproject 57a00b140954a2c22ba2fdebc93e8e6eda41b2a diff --git a/src/config.c b/src/config.c index 84d7b54..3e35b24 100644 --- a/src/config.c +++ b/src/config.c @@ -595,7 +595,11 @@ file_name_pattern(struct grecs_list *lp, grecs_value_t *val) arg = val->v.string; pat = emalloc(sizeof(*pat)); - + if (*arg == '!') { + pat->neg = 1; + ++arg; + } else + pat->neg = 0; if (arg[0] == '/') { char *q, *p; diff --git a/src/dircond.h b/src/dircond.h index 30f520b..7a1ae65 100644 --- a/src/dircond.h +++ b/src/dircond.h @@ -56,6 +56,7 @@ struct transtab { struct filename_pattern { int type; + int neg; union { regex_t re; char *glob; diff --git a/src/fnpat.c b/src/fnpat.c index 8191705..60edea7 100644 --- a/src/fnpat.c +++ b/src/fnpat.c @@ -41,16 +41,20 @@ filename_pattern_match(struct grecs_list *lp, const char *name) return 0; for (ep = lp->head; ep; ep = ep->next) { struct filename_pattern *pat = ep->data; - + int rc; + switch (pat->type) { case PAT_GLOB: - if (fnmatch(pat->v.glob, name, FNM_PATHNAME) == 0) - return 0; + rc = fnmatch(pat->v.glob, name, FNM_PATHNAME); break; case PAT_REGEX: - if (regexec(&pat->v.re, name, 0, NULL, 0) == 0) - return 0; + rc = regexec(&pat->v.re, name, 0, NULL, 0); + break; } + if (pat->neg) + rc = !rc; + if (rc == 0) + return 0; } return 1; } diff --git a/tests/Makefile.am b/tests/Makefile.am index 4d209de..6f7f1df 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,5 +1,5 @@ # This file is part of Dircond -# Copyright (C) 2012, 2013 Sergey Poznyakoff +# Copyright (C) 2012-2014 Sergey Poznyakoff # # Dircond is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -49,10 +49,12 @@ TESTSUITE_AT = \ env02.at\ env03.at\ glob01.at\ + glob02.at\ re01.at\ re02.at\ re03.at\ re04.at\ + re05.at\ testsuite.at\ write.at diff --git a/tests/envdump.c b/tests/envdump.c index c803cdb..8a0a0b2 100644 --- a/tests/envdump.c +++ b/tests/envdump.c @@ -175,6 +175,7 @@ main(int argc, char **argv) int i; char *p; FILE *fp = NULL; + char *file; char *mode = "w"; int sortenv = 0; char *include = NULL; @@ -193,12 +194,7 @@ main(int argc, char **argv) mode = "a"; break; case 'f': - fp = fopen(optarg, mode); - if (!fp) { - fprintf(stderr, "%s: ", progname); - perror(optarg); - return 1; - } + file = optarg; break; case 'h': printf("usage: %s [-ahsx] [-f FILE] [-i INCLUDELIST] [-k [@]PID[:SIG]] [ARGS...]\n", @@ -217,7 +213,14 @@ main(int argc, char **argv) return 1; } - if (!fp) + if (file) { + fp = fopen(file, mode); + if (!fp) { + fprintf(stderr, "%s: ", progname); + perror(file); + return 1; + } + } else fp = stderr; fprintf(fp, "# Dump of execution environment\n"); diff --git a/tests/glob02.at b/tests/glob02.at new file mode 100644 index 0000000..3c43145 --- /dev/null +++ b/tests/glob02.at @@ -0,0 +1,67 @@ +# This file is part of Dircond testsuite. -*- Autotest -*- +# Copyright (C) 2013, 2014 Sergey Poznyakoff +# +# Dircond 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 3, or (at your option) +# any later version. +# +# Dircond 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 Dircond. If not, see <http://www.gnu.org/licenses/>. + +AT_SETUP([Globbing pattern negation]) +AT_KEYWORDS([create fname glob glob02 neg]) + +AT_CHECK([ +cwd=`pwd -P` +pidfile=$cwd/dircond.pid +outfile=$cwd/dump +mkdir dir +cat > test.conf <<EOT +pidfile $pidfile; +debug 10; +syslog { + facility ${TESTSUITE_FACILITY:-local0}; + tag dircond-test:create; +} +watcher { + path $cwd/dir; + event create; + file "!*.tmp"; + command "$TESTDIR/envdump -s -i DIRCOND_FILE=:DIRCOND_GENEV_ -f $outfile -a"; + option (stdout,stderr); +} +EOT + +dircond -lnotice test.conf || exit 1 +waitfile $pidfile 2 +> dir/tempfile +> dir/file.tmp +waitfile $outfile 6 +kill `cat $pidfile` +sed "s^$cwd^(CWD)^;s^$TESTDIR^(TESTDIR)^" $outfile +], +[0], +[# Dump of execution environment +cwd is (CWD)/dir +# Arguments +argv[[0]]=(TESTDIR)/envdump +argv[[1]]=-s +argv[[2]]=-i +argv[[3]]=DIRCOND_FILE=:DIRCOND_GENEV_ +argv[[4]]=-f +argv[[5]]=(CWD)/dump +argv[[6]]=-a +# Environment +DIRCOND_FILE=tempfile +DIRCOND_GENEV_CODE=1 +DIRCOND_GENEV_NAME=create +# End +]) + +AT_CLEANUP diff --git a/tests/re05.at b/tests/re05.at new file mode 100644 index 0000000..9127960 --- /dev/null +++ b/tests/re05.at @@ -0,0 +1,67 @@ +# This file is part of Dircond testsuite. -*- Autotest -*- +# Copyright (C) 2014 Sergey Poznyakoff +# +# Dircond 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 3, or (at your option) +# any later version. +# +# Dircond 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 Dircond. If not, see <http://www.gnu.org/licenses/>. + +AT_SETUP([Regexp negation]) +AT_KEYWORDS([create fname regexp re re05 neg]) + +AT_CHECK([ +cwd=`pwd -P` +pidfile=$cwd/dircond.pid +outfile=$cwd/dump +mkdir dir +cat > test.conf <<EOT +pidfile $pidfile; +debug 10; +syslog { + facility ${TESTSUITE_FACILITY:-local0}; + tag dircond-test:create; +} +watcher { + path $cwd/dir; + event create; + file "!/\.[[0-9]]+$/"; + command "$TESTDIR/envdump -s -i DIRCOND_FILE=:DIRCOND_GENEV_ -f $outfile -a"; + option (stdout,stderr); +} +EOT + +dircond -lnotice test.conf || exit 1 +waitfile $pidfile 2 +> dir/file +> dir/file.1234 +waitfile $outfile 6 +kill `cat $pidfile` +sed "s^$cwd^(CWD)^;s^$TESTDIR^(TESTDIR)^" $outfile +], +[0], +[# Dump of execution environment +cwd is (CWD)/dir +# Arguments +argv[[0]]=(TESTDIR)/envdump +argv[[1]]=-s +argv[[2]]=-i +argv[[3]]=DIRCOND_FILE=:DIRCOND_GENEV_ +argv[[4]]=-f +argv[[5]]=(CWD)/dump +argv[[6]]=-a +# Environment +DIRCOND_FILE=file +DIRCOND_GENEV_CODE=1 +DIRCOND_GENEV_NAME=create +# End +]) + +AT_CLEANUP diff --git a/tests/testsuite.at b/tests/testsuite.at index dbbd147..730a558 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -1,5 +1,5 @@ # This file is part of Dircond testsuite. -*- Autotest -*- -# Copyright (C) 2013 Sergey Poznyakoff +# Copyright (C) 2013, 2014 Sergey Poznyakoff # # Dircond is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -36,8 +36,10 @@ m4_include([env03.at]) AT_BANNER([Filename selection]) m4_include([glob01.at]) +m4_include([glob02.at]) m4_include([re01.at]) m4_include([re02.at]) m4_include([re03.at]) m4_include([re04.at]) +m4_include([re05.at]) |