summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/libsm/match.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/libsm/match.c')
-rw-r--r--contrib/sendmail/libsm/match.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/contrib/sendmail/libsm/match.c b/contrib/sendmail/libsm/match.c
new file mode 100644
index 0000000..e42b865a3
--- /dev/null
+++ b/contrib/sendmail/libsm/match.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers.
+ * All rights reserved.
+ *
+ * By using this file, you agree to the terms and conditions set
+ * forth in the LICENSE file which can be found at the top level of
+ * the sendmail distribution.
+ *
+ */
+
+#include <sm/gen.h>
+SM_RCSID("@(#)$Id: match.c,v 1.10 2001/09/11 04:04:48 gshapiro Exp $")
+
+#include <sm/string.h>
+
+/*
+** SM_MATCH -- Match a character string against a glob pattern.
+**
+** Parameters:
+** str -- string.
+** par -- pattern to find in str.
+**
+** Returns:
+** true on match, false on non-match.
+**
+** A pattern consists of normal characters, which match themselves,
+** and meta-sequences. A * matches any sequence of characters.
+** A ? matches any single character. A [ introduces a character class.
+** A ] marks the end of a character class; if the ] is missing then
+** the [ matches itself rather than introducing a character class.
+** A character class matches any of the characters between the brackets.
+** The range of characters from X to Y inclusive is written X-Y.
+** If the first character after the [ is ! then the character class is
+** complemented.
+**
+** To include a ] in a character class, make it the first character
+** listed (after the !, if any). To include a -, make it the first
+** character listed (after the !, if any) or the last character.
+** It is impossible for a ] to be the final character in a range.
+** For glob patterns that literally match "*", "?" or "[",
+** use [*], [?] or [[].
+*/
+
+bool
+sm_match(str, pat)
+ const char *str;
+ const char *pat;
+{
+ bool ccnot, ccmatch, ccfirst;
+ const char *ccstart;
+ char c, c2;
+
+ for (;;)
+ {
+ switch (*pat)
+ {
+ case '\0':
+ return *str == '\0';
+ case '?':
+ if (*str == '\0')
+ return false;
+ ++pat;
+ ++str;
+ continue;
+ case '*':
+ ++pat;
+ if (*pat == '\0')
+ {
+ /* optimize case of trailing '*' */
+ return true;
+ }
+ for (;;)
+ {
+ if (sm_match(pat, str))
+ return true;
+ if (*str == '\0')
+ return false;
+ ++str;
+ }
+ /* NOTREACHED */
+ case '[':
+ ccstart = pat++;
+ ccnot = false;
+ if (*pat == '!')
+ {
+ ccnot = true;
+ ++pat;
+ }
+ ccmatch = false;
+ ccfirst = true;
+ for (;;)
+ {
+ if (*pat == '\0')
+ {
+ pat = ccstart;
+ goto defl;
+ }
+ if (*pat == ']' && !ccfirst)
+ break;
+ c = *pat++;
+ ccfirst = false;
+ if (*pat == '-' && pat[1] != ']')
+ {
+ ++pat;
+ if (*pat == '\0')
+ {
+ pat = ccstart;
+ goto defl;
+ }
+ c2 = *pat++;
+ if (*str >= c && *str <= c2)
+ ccmatch = true;
+ }
+ else
+ {
+ if (*str == c)
+ ccmatch = true;
+ }
+ }
+ if (ccmatch ^ ccnot)
+ {
+ ++pat;
+ ++str;
+ }
+ else
+ return false;
+ continue;
+ default:
+ defl:
+ if (*pat != *str)
+ return false;
+ ++pat;
+ ++str;
+ continue;
+ }
+ }
+}
OpenPOWER on IntegriCloud