dovecot-2.0: Added wildcard_match*() for matching strings with '...
dovecot at dovecot.org
dovecot at dovecot.org
Thu Mar 18 04:12:27 EET 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/f7d14405de09
changeset: 10941:f7d14405de09
user: Timo Sirainen <tss at iki.fi>
date: Thu Mar 18 04:11:55 2010 +0200
description:
Added wildcard_match*() for matching strings with '*' and '?' wildcards.
diffstat:
src/lib/Makefile.am | 2 +
src/lib/wildcard-match.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/lib/wildcard-match.h | 9 ++++
3 files changed, 114 insertions(+), 0 deletions(-)
diffs (139 lines):
diff -r 480bf5fefcce -r f7d14405de09 src/lib/Makefile.am
--- a/src/lib/Makefile.am Thu Mar 18 04:00:17 2010 +0200
+++ b/src/lib/Makefile.am Thu Mar 18 04:11:55 2010 +0200
@@ -111,6 +111,7 @@
utc-offset.c \
utc-mktime.c \
var-expand.c \
+ wildcard-match.c \
write-full.c
headers = \
@@ -203,6 +204,7 @@
utc-offset.h \
utc-mktime.h \
var-expand.h \
+ wildcard-match.h \
write-full.h
test_programs = test-lib
diff -r 480bf5fefcce -r f7d14405de09 src/lib/wildcard-match.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/wildcard-match.c Thu Mar 18 04:11:55 2010 +0200
@@ -0,0 +1,103 @@
+/*
+ * This code would not have been possible without the prior work and
+ * suggestions of various sourced. Special thanks to Robey for
+ * all his time/help tracking down bugs and his ever-helpful advice.
+ *
+ * 04/09: Fixed the "*\*" against "*a" bug (caused an endless loop)
+ *
+ * Chris Fuller (aka Fred1 at IRC & Fwitz at IRC)
+ * crf at cfox.bchs.uh.edu
+ *
+ * I hereby release this code into the public domain
+ *
+ */
+
+#include "lib.h"
+#include "wildcard-match.h"
+
+#include <ctype.h>
+
+#define WILDS '*' /* matches 0 or more characters (including spaces) */
+#define WILDQ '?' /* matches ecactly one character */
+
+#define NOMATCH 0
+#define MATCH (match+sofar)
+
+static int wildcard_match_int(const char *data, const char *mask, int icase)
+{
+ const char *ma = mask, *na = data, *lsm = 0, *lsn = 0;
+ int match = 1;
+ int sofar = 0;
+
+ /* null strings should never match */
+ if ((ma == 0) || (na == 0) || (!*ma) || (!*na))
+ return NOMATCH;
+ /* find the end of each string */
+ while (*(++mask));
+ mask--;
+ while (*(++data));
+ data--;
+
+ while (data >= na) {
+ /* If the mask runs out of chars before the string, fall back on
+ * a wildcard or fail. */
+ if (mask < ma) {
+ if (lsm) {
+ data = --lsn;
+ mask = lsm;
+ if (data < na)
+ lsm = 0;
+ sofar = 0;
+ }
+ else
+ return NOMATCH;
+ }
+
+ switch (*mask) {
+ case WILDS: /* Matches anything */
+ do
+ mask--; /* Zap redundant wilds */
+ while ((mask >= ma) && (*mask == WILDS));
+ lsm = mask;
+ lsn = data;
+ match += sofar;
+ sofar = 0; /* Update fallback pos */
+ if (mask < ma)
+ return MATCH;
+ continue; /* Next char, please */
+ case WILDQ:
+ mask--;
+ data--;
+ continue; /* '?' always matches */
+ }
+ if (icase ? (i_toupper(*mask) == i_toupper(*data)) :
+ (*mask == *data)) { /* If matching char */
+ mask--;
+ data--;
+ sofar++; /* Tally the match */
+ continue; /* Next char, please */
+ }
+ if (lsm) { /* To to fallback on '*' */
+ data = --lsn;
+ mask = lsm;
+ if (data < na)
+ lsm = 0; /* Rewind to saved pos */
+ sofar = 0;
+ continue; /* Next char, please */
+ }
+ return NOMATCH; /* No fallback=No match */
+ }
+ while ((mask >= ma) && (*mask == WILDS))
+ mask--; /* Zap leftover %s & *s */
+ return (mask >= ma) ? NOMATCH : MATCH; /* Start of both = match */
+}
+
+bool wildcard_match(const char *data, const char *mask)
+{
+ return wildcard_match_int(data, mask, FALSE) != 0;
+}
+
+bool wildcard_match_icase(const char *data, const char *mask)
+{
+ return wildcard_match_int(data, mask, TRUE) != 0;
+}
diff -r 480bf5fefcce -r f7d14405de09 src/lib/wildcard-match.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/wildcard-match.h Thu Mar 18 04:11:55 2010 +0200
@@ -0,0 +1,9 @@
+#ifndef WILDCARD_MATCH_H
+#define WILDCARD_MATCH_H
+
+/* Returns TRUE if mask matches data. mask can contain '*' and '?' wildcards. */
+bool wildcard_match(const char *data, const char *mask);
+/* Like wildcard_match(), but match ASCII characters case-insensitively. */
+bool wildcard_match_icase(const char *data, const char *mask);
+
+#endif
More information about the dovecot-cvs
mailing list