[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[SCM] GNU Mailutils branch, master, updated. release-3.0-28-gcab2fd5
From: |
Sergey Poznyakoff |
Subject: |
[SCM] GNU Mailutils branch, master, updated. release-3.0-28-gcab2fd5 |
Date: |
Tue, 6 Dec 2016 13:52:19 +0000 (UTC) |
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Mailutils".
http://git.savannah.gnu.org/cgit/mailutils.git/commit/?id=cab2fd5c0479d16a3dcd746c98de8be771a8963d
The branch, master has been updated
via cab2fd5c0479d16a3dcd746c98de8be771a8963d (commit)
via df608ed0cfb5f0db57d1ff97eb208ceb46f06e17 (commit)
from f8a0fd0fdb20fdb607343d932f19e650dfd8f1d2 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit cab2fd5c0479d16a3dcd746c98de8be771a8963d
Author: Sergey Poznyakoff <address@hidden>
Date: Tue Dec 6 15:48:39 2016 +0200
Use glob API in sieve
* libmu_sieve/comparator.c: Use mu_glob_compile instead of fnmatch.
commit df608ed0cfb5f0db57d1ff97eb208ceb46f06e17
Author: Sergey Poznyakoff <address@hidden>
Date: Tue Dec 6 15:32:20 2016 +0200
New API for converting globbing patterns to extended POSIX regex
* include/mailutils/opool.h (mu_nonlocal_jmp_t): New type.
(mu_opool_setjmp,mu_opool_clrjmp): New functions.
(mu_opool_setup_nonlocal_jump): New macro.
* libmailutils/base/opool.c (_mu_opool)<jmp>: New field.
(alloc_bucket): Do a non-local jump on out of memory condition,
if jmp is not NULL.
(mu_opool_setjmp,mu_opool_clrjmp): New functions.
* libmailutils/base/glob.c: New file.
* libmailutils/base/Makefile.am: Add glob.c
* include/mailutils/glob.h: New file.
* include/mailutils/mailutils.h: Include glob.h
* libmailutils/tests/globtest.c: New file.
* libmailutils/tests/globtest.at: New test.
* libmailutils/tests/Makefile.am: Add new files.
* libmailutils/tests/testsuite.at: Include new test.
-----------------------------------------------------------------------
Summary of changes:
gint | 2 +-
gnulib.modules | 2 +-
include/mailutils/mailutils.h | 1 +
include/mailutils/opool.h | 22 ++++
libmailutils/base/Makefile.am | 1 +
libmailutils/base/glob.c | 264 +++++++++++++++++++++++++++++++++++++++
libmailutils/base/opool.c | 23 ++++
libmailutils/tests/Makefile.am | 2 +
libmailutils/tests/globtest.at | 46 +++++++
libmailutils/tests/globtest.c | 95 ++++++++++++++
libmailutils/tests/testsuite.at | 2 +
libmu_sieve/comparator.c | 26 +++-
12 files changed, 481 insertions(+), 5 deletions(-)
create mode 100644 libmailutils/base/glob.c
create mode 100644 libmailutils/tests/globtest.at
create mode 100644 libmailutils/tests/globtest.c
diff --git a/gint b/gint
index 42f4712..fd86bf7 160000
--- a/gint
+++ b/gint
@@ -1 +1 @@
-Subproject commit 42f4712085b40173eaea58e14b1a579291a6fe3a
+Subproject commit fd86bf7d44b0c970771830692ae7491447ebe8b1
diff --git a/gnulib.modules b/gnulib.modules
index b672acc..4e7fcd2 100644
--- a/gnulib.modules
+++ b/gnulib.modules
@@ -1,7 +1,7 @@
# List of gnulib modules needed for GNU mailutils.
# A module name per line. Empty lines and comments are ignored.
-# FIXME: fnmatch, regex and glob are used by libmailutils...
+# FIXME: regex and glob are used by libmailutils...
autobuild
crypto/des
diff --git a/include/mailutils/mailutils.h b/include/mailutils/mailutils.h
index cc14889..dfcb357 100644
--- a/include/mailutils/mailutils.h
+++ b/include/mailutils/mailutils.h
@@ -32,6 +32,7 @@
#include <mailutils/error.h>
#include <mailutils/filter.h>
#include <mailutils/folder.h>
+#include <mailutils/glob.h>
#include <mailutils/header.h>
#include <mailutils/iterator.h>
#include <mailutils/kwd.h>
diff --git a/include/mailutils/opool.h b/include/mailutils/opool.h
index 45fe64f..9f474cf 100644
--- a/include/mailutils/opool.h
+++ b/include/mailutils/opool.h
@@ -19,6 +19,7 @@
#define _MAILUTILS_OPOOL_H
#include <mailutils/types.h>
+#include <setjmp.h>
#ifndef MU_OPOOL_BUCKET_SIZE
# define MU_OPOOL_BUCKET_SIZE 1024
@@ -33,6 +34,27 @@ int mu_opool_create (mu_opool_t *pret, int flags);
int mu_opool_set_bucket_size (mu_opool_t opool, size_t size);
int mu_opool_get_bucket_size (mu_opool_t opool, size_t *psize);
+struct mu_nonlocal_jmp
+{
+ jmp_buf buf;
+ struct mu_nonlocal_jmp *next;
+};
+
+typedef struct mu_nonlocal_jmp mu_nonlocal_jmp_t;
+
+void mu_opool_setjmp (mu_opool_t opool, mu_nonlocal_jmp_t *err);
+void mu_opool_clrjmp (mu_opool_t opool);
+
+#define mu_opool_setup_nonlocal_jump(p,jb) \
+ do \
+ { \
+ int __rc = setjmp (jb.buf); \
+ if (__rc) \
+ return __rc; \
+ mu_opool_setjmp (p, &jb); \
+ } \
+ while (0)
+
/* Merge all data from *SRC into *DST. If the latter is NULL, create
it. On success, free *SRC and initialize it with NULL. */
int mu_opool_union (mu_opool_t *dst, mu_opool_t *src);
diff --git a/libmailutils/base/Makefile.am b/libmailutils/base/Makefile.am
index 8679eb0..79a8ef4 100644
--- a/libmailutils/base/Makefile.am
+++ b/libmailutils/base/Makefile.am
@@ -34,6 +34,7 @@ libbase_la_SOURCES = \
getcwd.c\
getmaxfd.c\
getpass.c\
+ glob.c\
hostname.c\
iterator.c\
kwd.c\
diff --git a/libmailutils/base/glob.c b/libmailutils/base/glob.c
new file mode 100644
index 0000000..2d88990
--- /dev/null
+++ b/libmailutils/base/glob.c
@@ -0,0 +1,264 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2007, 2009-2012, 2014-2016 Free Software Foundation,
+ Inc.
+
+ GNU Mailutils 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.
+
+ GNU Mailutils 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 GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <mailutils/opool.h>
+#include <mailutils/error.h>
+#include <mailutils/errno.h>
+#include <mailutils/glob.h>
+#include <regex.h>
+#include <string.h>
+#include <stdlib.h>
+
+static void
+parse_character_class (unsigned char const *str, mu_opool_t pool,
+ unsigned char const **endp)
+{
+ unsigned char const *cur;
+
+ cur = str + 1;
+ if (*cur == '!')
+ cur++;
+ if (*cur == ']')
+ cur++;
+
+ while (*cur && *cur != ']')
+ {
+ int c = *cur++;
+ if (c == '\\')
+ cur++;
+ else if (c >= 0xc2)
+ {
+ size_t len;
+
+ if (c < 0xe0)
+ len = 1;
+ else if (c < 0xf0)
+ len = 2;
+ else if (c < 0xf8)
+ len = 3;
+ else
+ /* Invalid UTF-8 sequence; skip. */
+ continue;
+
+ while (len-- && *cur)
+ cur++;
+ }
+ }
+
+ if (*cur == ']')
+ {
+ /* Valid character class */
+ mu_opool_append_char (pool, *str);
+ str++;
+ if (*str == '!')
+ {
+ mu_opool_append_char (pool, '^');
+ str++;
+ }
+ while (str < cur)
+ {
+ if (*str == '[')
+ mu_opool_append_char (pool, '\\');
+
+ mu_opool_append_char (pool, *str);
+ str++;
+ }
+ mu_opool_append_char (pool, ']');
+ *endp = cur + 1;
+ }
+ else
+ {
+ mu_opool_append_char (pool, '\\');
+ mu_opool_append_char (pool, *str);
+ str++;
+ *endp = str;
+ }
+}
+
+int
+mu_glob_to_regex_opool (char const *pattern, mu_opool_t pool, int flags)
+{
+ unsigned char const *str = (unsigned char const *) pattern;
+ mu_nonlocal_jmp_t jmp;
+
+ if (!(flags & MU_GLOBF_SUB))
+ flags |= MU_GLOBF_COLLAPSE;
+
+ mu_opool_setup_nonlocal_jump (pool, jmp);
+
+ while (*str)
+ {
+ int c = *str++;
+
+ if (c < 0x80)
+ {
+ switch (c)
+ {
+ case '\\':
+ mu_opool_append_char (pool, '\\');
+ if (*str && strchr ("?*[", *str))
+ {
+ mu_opool_append_char (pool, *str);
+ str++;
+ }
+ else
+ mu_opool_append_char (pool, '\\');
+ break;
+
+ case '?':
+ if (flags & MU_GLOBF_SUB)
+ mu_opool_append_char (pool, '(');
+ mu_opool_append_char (pool, '.');
+ if (flags & MU_GLOBF_SUB)
+ mu_opool_append_char (pool, ')');
+ break;
+
+ case '*':
+ if (flags & MU_GLOBF_COLLAPSE)
+ {
+ while (*str == '*')
+ str++;
+ }
+
+ if (flags & MU_GLOBF_SUB)
+ {
+ while (*str == '*')
+ {
+ mu_opool_append (pool, "()", 2);
+ str++;
+ }
+ mu_opool_append_char (pool, '(');
+ mu_opool_append (pool, ".*", 2);
+ mu_opool_append_char (pool, ')');
+ }
+ else
+ mu_opool_append (pool, ".*", 2);
+ break;
+
+ case '[':
+ parse_character_class (str - 1, pool, &str);
+ break;
+
+ case '(':
+ case ')':
+ case '{':
+ case '}':
+ case '^':
+ case '$':
+ case ']':
+ case '|':
+ case '.':
+ mu_opool_append_char (pool, '\\');
+ mu_opool_append_char (pool, c);
+ break;
+
+ default:
+ mu_opool_append_char (pool, c);
+ }
+ }
+ else
+ {
+ mu_opool_append_char (pool, c);
+ if (c >= 0xc2)
+ {
+ size_t len;
+
+ if (c < 0xe0)
+ len = 1;
+ else if (c < 0xf0)
+ len = 2;
+ else if (c < 0xf8)
+ len = 3;
+ else
+ /* Invalid UTF-8 sequence; skip. */
+ continue;
+
+ for (; len-- && *str; str++)
+ mu_opool_append_char (pool, *str);
+ }
+ }
+ }
+ mu_opool_clrjmp (pool);
+ return 0;
+}
+
+int
+mu_glob_to_regex (char **rxstr, char const *pattern, int flags)
+{
+ mu_opool_t pool;
+ int rc;
+ mu_nonlocal_jmp_t jmp;
+
+ rc = mu_opool_create (&pool, MU_OPOOL_DEFAULT);
+ if (rc)
+ return rc;
+ mu_opool_setup_nonlocal_jump (pool, jmp);
+ mu_opool_append_char (pool, '^');
+ rc = mu_glob_to_regex_opool (pattern, pool, flags);
+ if (rc == 0)
+ {
+ mu_opool_append_char (pool, '$');
+ mu_opool_append_char (pool, 0);
+ *rxstr = mu_opool_detach (pool, NULL);
+ }
+ mu_opool_clrjmp (pool);
+ mu_opool_destroy (&pool);
+ return rc;
+}
+
+int
+mu_glob_compile (regex_t *rx, char const *pattern, int flags)
+{
+ char *str;
+ int rc;
+ int rxflags;
+
+ rc = mu_glob_to_regex (&str, pattern, flags);
+ if (rc)
+ return rc;
+
+ rxflags = REG_EXTENDED;
+ if (flags & MU_GLOBF_ICASE)
+ rxflags |= REG_ICASE;
+ if (!(flags & MU_GLOBF_SUB))
+ rxflags |= REG_NOSUB;
+
+ rc = regcomp (rx, str, rxflags);
+ if (rc)
+ {
+ size_t size = regerror (rc, rx, NULL, 0);
+ char *errbuf = malloc (size + 1);
+ if (errbuf)
+ {
+ regerror (rc, rx, errbuf, size);
+ mu_error ("INTERNAL ERROR: can't compile regular expression \"%s\":
%s",
+ str, mu_strerror (rc));
+ }
+ else
+ mu_error ("INTERNAL ERROR: can't compile regular expression \"%s\"",
+ str);
+ mu_error ("INTERNAL ERROR: expression compiled from globbing pattern:
%s",
+ pattern);
+ free (errbuf);
+ }
+ free (str);
+
+ return rc;
+}
diff --git a/libmailutils/base/opool.c b/libmailutils/base/opool.c
index d6628dd..4dedd7c 100644
--- a/libmailutils/base/opool.c
+++ b/libmailutils/base/opool.c
@@ -53,6 +53,7 @@ struct _mu_opool
int flags; /* Flag bits */
size_t bucket_size; /* Default bucket size */
size_t itr_count; /* Number of iterators created for this pool */
+ mu_nonlocal_jmp_t *jmp; /* Buffer for non-local exit */
union mu_opool_bucket *bkt_head, *bkt_tail;
union mu_opool_bucket *bkt_fini; /* List of finished objects */
};
@@ -65,6 +66,8 @@ alloc_bucket (struct _mu_opool *opool, size_t size)
{
if (opool->flags & MU_OPOOL_ENOMEMABRT)
mu_alloc_die ();
+ if (opool->jmp)
+ longjmp (opool->jmp->buf, ENOMEM);
}
else
{
@@ -122,10 +125,30 @@ mu_opool_create (mu_opool_t *pret, int flags)
x->bucket_size = MU_OPOOL_BUCKET_SIZE;
x->itr_count = 0;
x->bkt_head = x->bkt_tail = x->bkt_fini = NULL;
+ x->jmp = NULL;
*pret = x;
return 0;
}
+void
+mu_opool_setjmp (mu_opool_t opool, mu_nonlocal_jmp_t *jmp)
+{
+ if (jmp)
+ {
+ jmp->next = opool->jmp;
+ opool->jmp = jmp;
+ }
+ else
+ mu_opool_clrjmp (opool);
+}
+
+void
+mu_opool_clrjmp (mu_opool_t opool)
+{
+ if (opool->jmp)
+ opool->jmp = opool->jmp->next;
+}
+
int
mu_opool_set_bucket_size (mu_opool_t opool, size_t size)
{
diff --git a/libmailutils/tests/Makefile.am b/libmailutils/tests/Makefile.am
index 72850f2..36f19eb 100644
--- a/libmailutils/tests/Makefile.am
+++ b/libmailutils/tests/Makefile.am
@@ -49,6 +49,7 @@ noinst_PROGRAMS = \
fsaf\
fsaftomod\
fsfolder\
+ globtest\
imapio\
listop\
mailcap\
@@ -94,6 +95,7 @@ TESTSUITE_AT = \
fsfolder02.at\
hdrflt.at\
htmlent.at\
+ globtest.at\
imapio.at\
inline-comment.at\
linecon.at\
diff --git a/libmailutils/tests/globtest.at b/libmailutils/tests/globtest.at
new file mode 100644
index 0000000..6c5f079
--- /dev/null
+++ b/libmailutils/tests/globtest.at
@@ -0,0 +1,46 @@
+# This file is part of GNU Mailutils. -*- Autotest -*-
+# Copyright (C) 2016 Free Software Foundation, Inc.
+#
+# GNU Mailutils 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.
+#
+# GNU Mailutils 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 GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
+
+AT_BANNER([Globbing patterns])
+
+dnl ------------------------------------------------------------------
+dnl GLOBCOMP (pattern, regex, [FLAGS])
+m4_pushdef([GLOBCOMP],
+[AT_SETUP([[$1][]m4_foreach([flag],[m4_shift(m4_shift($@))],[ flag])])
+AT_KEYWORDS([glob])
+AT_CHECK([globtest m4_foreach([flag],[m4_shift(m4_shift($@))],[dnl
+m4_if(flag,[sub],[ -s],[icase],[ -i],[collapse],[ -c])]) '[$1]'],[0],[[^$2$]
+])
+AT_CLEANUP
+])
+dnl ------------------------------------------------------------------
+
+GLOBCOMP(abab, abab)
+GLOBCOMP(a*c, a.*c)
+GLOBCOMP(a*c?d, a(.*)c(.)d, sub)
+GLOBCOMP(a***c, a.*c)
+GLOBCOMP(a***c, a()()(.*)c, sub)
+GLOBCOMP(a***c, a(.*)c, sub, collapse)
+GLOBCOMP([{$|a$$], [\{\$\|a\$\$])
+GLOBCOMP([a[0-9A-Z]c], [a[0-9A-Z]c])
+GLOBCOMP([a[!a-z]c], [a[^a-z]c])
+GLOBCOMP([a[!]z@:>@], [a[^]z@:>@])
+GLOBCOMP([a@<:@cde], [a\@<:@cde])
+GLOBCOMP([a[@<:@ba]], [a[\@<:@ba]])
+GLOBCOMP([*.c], [.*\.c])
+GLOBCOMP([a\],[a\\])
+
+m4_popdef([GLOBCOMP])
\ No newline at end of file
diff --git a/libmailutils/tests/globtest.c b/libmailutils/tests/globtest.c
new file mode 100644
index 0000000..d281f28
--- /dev/null
+++ b/libmailutils/tests/globtest.c
@@ -0,0 +1,95 @@
+#include <config.h>
+#include <mailutils/mailutils.h>
+
+/* globtest PATTERN [WORD...]
+ */
+int
+main (int argc, char **argv)
+{
+ char *pattern = NULL;
+ int flags = 0;
+ int rc;
+ int i;
+
+ mu_set_program_name (argv[0]);
+ for (i = 1; i < argc; i++)
+ {
+ char *a = argv[i];
+ if (strcmp (a, "-i") == 0)
+ flags |= MU_GLOBF_ICASE;
+ else if (strcmp (a, "-s") == 0)
+ flags |= MU_GLOBF_SUB;
+ else if (strcmp (a, "-c") == 0)
+ flags |= MU_GLOBF_COLLAPSE;
+ else if (strcmp (a, "--") == 0)
+ {
+ i++;
+ break;
+ }
+ else if (*a != '-')
+ break;
+ else
+ {
+ mu_error ("unknown option %s", a);
+ return 1;
+ }
+ }
+
+ if (i == argc)
+ {
+ mu_printf ("usage: %s [-ics] PATTERN [WORD...]\n", mu_program_name);
+ return 1;
+ }
+
+ pattern = argv[i++];
+
+ if (i == argc)
+ {
+ char *regstr;
+
+ rc = mu_glob_to_regex (®str, pattern, flags);
+ if (rc)
+ {
+ mu_error ("convert: %s", mu_strerror (rc));
+ return 1;
+ }
+ mu_printf ("%s\n", regstr);
+ free (regstr);
+ }
+ else
+ {
+ regex_t regex;
+ size_t nmatch = 0;
+ regmatch_t *matches = NULL;
+
+ rc = mu_glob_compile (®ex, pattern, flags);
+ if (rc)
+ {
+ mu_error ("compile: %s", mu_strerror (rc));
+ return 1;
+ }
+
+ if (flags & MU_GLOBF_SUB)
+ {
+ nmatch = regex.re_nsub + 1;
+ matches = mu_calloc (nmatch, sizeof matches[0]);
+ }
+
+ for (; i < argc; i++)
+ {
+ char *a = argv[i];
+ rc = regexec (®ex, a, nmatch, matches, 0);
+ mu_printf ("%s: %s\n", a, rc == 0 ? "OK" : "NO");
+ if (flags & MU_GLOBF_SUB)
+ {
+ size_t j;
+
+ for (j = 0; j < nmatch; j++)
+ printf ("%02d: %.*s\n", j,
+ matches[j].rm_eo - matches[j].rm_so,
+ a + matches[j].rm_so);
+ }
+ }
+ }
+ return 0;
+}
diff --git a/libmailutils/tests/testsuite.at b/libmailutils/tests/testsuite.at
index 67f5c3b..0a51790 100644
--- a/libmailutils/tests/testsuite.at
+++ b/libmailutils/tests/testsuite.at
@@ -180,3 +180,5 @@ m4_include([modtofsaf.at])
m4_include([mimehdr.at])
m4_include([msgset.at])
+
+m4_include([globtest.at])
diff --git a/libmu_sieve/comparator.c b/libmu_sieve/comparator.c
index 591b4d4..5e10c83 100644
--- a/libmu_sieve/comparator.c
+++ b/libmu_sieve/comparator.c
@@ -25,7 +25,6 @@
#include <unistd.h>
#include <string.h>
#include <sieve-priv.h>
-#include <fnmatch.h>
#include <regex.h>
#include <mailutils/cctype.h>
#include <mailutils/cstr.h>
@@ -102,6 +101,25 @@ compile_pattern (mu_sieve_machine_t mach,
mu_sieve_string_t *pattern, int flags)
pattern->rx = preg;
}
+static void
+compile_wildcard (mu_sieve_machine_t mach, mu_sieve_string_t *pattern,
+ int flags)
+{
+ int rc;
+ regex_t *preg;
+
+ if (pattern->rx)
+ return;
+ preg = mu_sieve_malloc (mach, sizeof (*preg));
+ rc = mu_glob_compile (preg, pattern->orig, flags);
+ if (rc)
+ {
+ mu_sieve_error (mach, _("can't compile pattern"));
+ mu_sieve_abort (mach);
+ }
+ pattern->rx = preg;
+}
+
static int
comp_false (mu_sieve_machine_t mach, mu_sieve_string_t *pattern,
const char *text)
@@ -263,7 +281,8 @@ static int
i_octet_matches (mu_sieve_machine_t mach, mu_sieve_string_t *pattern,
const char *text)
{
- return fnmatch (pattern->orig, text, 0) == 0;
+ compile_wildcard (mach, pattern, 0);
+ return regexec ((regex_t *)pattern->rx, text, 0, NULL, 0) == 0;
}
static int
@@ -300,7 +319,8 @@ static int
i_ascii_casemap_matches (mu_sieve_machine_t mach,
mu_sieve_string_t *pattern, const char *text)
{
- return fnmatch (pattern->orig, text, FNM_CASEFOLD) == 0;
+ compile_wildcard (mach, pattern, MU_GLOBF_ICASE);
+ return regexec ((regex_t *)pattern->rx, text, 0, NULL, 0) == 0;
}
static int
hooks/post-receive
--
GNU Mailutils
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [SCM] GNU Mailutils branch, master, updated. release-3.0-28-gcab2fd5,
Sergey Poznyakoff <=