summaryrefslogtreecommitdiff
path: root/usr.bin/make/str.c
diff options
context:
space:
mode:
authorMarc Espie <espie@cvs.openbsd.org>2007-09-16 15:17:45 +0000
committerMarc Espie <espie@cvs.openbsd.org>2007-09-16 15:17:45 +0000
commit54a9a48236e00d6f6bf0d016ae4ae95e01df83db (patch)
tree6598b33774a68d2a3af9131b0571b88b905871f0 /usr.bin/make/str.c
parent3a1c1a317a3309066efc5fb5a624f61cdc76eeaf (diff)
remove some of the complexity of Str_Matchi by separating code into
range_match and star_match to handle special characters. reindent.
Diffstat (limited to 'usr.bin/make/str.c')
-rw-r--r--usr.bin/make/str.c148
1 files changed, 75 insertions, 73 deletions
diff --git a/usr.bin/make/str.c b/usr.bin/make/str.c
index ee1ab5f76bf..998bda38bd9 100644
--- a/usr.bin/make/str.c
+++ b/usr.bin/make/str.c
@@ -1,5 +1,5 @@
/* $OpenPackages$ */
-/* $OpenBSD: str.c,v 1.21 2004/04/07 13:11:36 espie Exp $ */
+/* $OpenBSD: str.c,v 1.22 2007/09/16 15:17:44 espie Exp $ */
/* $NetBSD: str.c,v 1.13 1996/11/06 17:59:23 christos Exp $ */
/*-
@@ -44,6 +44,10 @@
#include "memory.h"
#include "buf.h"
+/* helpers for Str_Matchi */
+static bool range_match(char, const char **, const char *);
+static bool star_match(const char *, const char *, const char *, const char *);
+
char *
Str_concati(const char *s1, const char *e1, const char *s2, const char *e2,
int sep)
@@ -147,7 +151,8 @@ brk_string(const char *str, int *store_argc, char **buffer)
*t++ = '\0';
if (argc == argmax) {
argmax *= 2; /* ramp up fast */
- argv = erealloc(argv, (argmax + 1) * sizeof(char *));
+ argv = erealloc(argv,
+ (argmax + 1) * sizeof(char *));
}
argv[argc++] = start;
start = NULL;
@@ -184,7 +189,7 @@ brk_string(const char *str, int *store_argc, char **buffer)
start = t;
*t++ = ch;
}
-done:
+ done:
argv[argc] = NULL;
*store_argc = argc;
return argv;
@@ -229,19 +234,16 @@ iterate_words(const char **end)
}
}
-bool
-Str_Matchi(const char *string, const char *estring,
+static bool
+star_match(const char *string, const char *estring,
const char *pattern, const char *epattern)
{
- while (pattern != epattern) {
- /* Check for a "*" as the next pattern character. It matches
- * any substring. We handle this by calling ourselves
- * recursively for each postfix of string, until either we
- * match or we reach the end of the string. */
- if (*pattern == '*') {
+ /* '*' matches any substring. We handle this by calling ourselves
+ * recursively for each postfix of string, until either we match or
+ * we reach the end of the string. */
pattern++;
- /* Skip over contiguous sequences of `?*', so that recursive
- * calls only occur on `real' characters. */
+ /* Skip over contiguous sequences of `?*', so that
+ * recursive calls only occur on `real' characters. */
while (pattern != epattern &&
(*pattern == '?' || *pattern == '*')) {
if (*pattern == '?') {
@@ -255,85 +257,86 @@ Str_Matchi(const char *string, const char *estring,
if (pattern == epattern)
return true;
for (; string != estring; string++)
- if (Str_Matchi(string, estring, pattern, epattern))
+ if (Str_Matchi(string, estring, pattern,
+ epattern))
return true;
return false;
- } else if (string == estring)
- return false;
- /* Check for a "[" as the next pattern character. It is
- * followed by a list of characters that are acceptable, or
- * by a range (two characters separated by "-"). */
- else if (*pattern == '[') {
- pattern++;
- if (pattern == epattern)
- return false;
- if (*pattern == '!' || *pattern == '^') {
- pattern++;
- if (pattern == epattern)
- return false;
- /* Negative match */
- for (;;) {
- if (*pattern == '\\') {
- if (++pattern == epattern)
+}
+
+static bool
+range_match(char c, const char **ppat, const char *epattern)
+{
+ if (*ppat == epattern) {
+ if (c == '[')
+ return true;
+ else
return false;
}
- if (*pattern == *string)
- return false;
- if (pattern[1] == '-') {
- if (pattern + 2 == epattern)
- return false;
- if (*pattern < *string && *string <= pattern[2])
- return false;
- if (pattern[2] <= *string && *string < *pattern)
- return false;
- pattern += 3;
- } else
- pattern++;
- if (pattern == epattern)
- return false;
- /* The test for ']' is done at the end so that ']'
- * can be used at the start of the range without '\' */
- if (*pattern == ']')
- break;
+ if (**ppat == '!' || **ppat == '^') {
+ (*ppat)++;
+ return !range_match(c, ppat, epattern);
}
- } else {
for (;;) {
- if (*pattern == '\\') {
- if (++pattern == epattern)
+ if (**ppat == '\\') {
+ if (++(*ppat) == epattern)
return false;
}
- if (*pattern == *string)
+ if (**ppat == c)
break;
- if (pattern[1] == '-') {
- if (pattern + 2 == epattern)
+ if ((*ppat)[1] == '-') {
+ if (*ppat + 2 == epattern)
return false;
- if (*pattern < *string && *string <= pattern[2])
+ if (**ppat < c && c <= (*ppat)[2])
break;
- if (pattern[2] <= *string && *string < *pattern)
+ if ((*ppat)[2] <= c && c < **ppat)
break;
- pattern += 3;
+ *ppat += 3;
} else
- pattern++;
- /* The test for ']' is done at the end so that ']'
- * can be used at the start of the range without '\' */
- if (pattern == epattern || *pattern == ']')
+ (*ppat)++;
+ /* The test for ']' is done at the end
+ * so that ']' can be used at the
+ * start of the range without '\' */
+ if (*ppat == epattern || **ppat == ']')
return false;
}
- /* Found matching character, skip over rest of class. */
- while (*pattern != ']') {
- if (*pattern == '\\')
- pattern++;
- /* A non-terminated character class is ok. */
- if (pattern == epattern)
+ /* Found matching character, skip over rest
+ * of class. */
+ while (**ppat != ']') {
+ if (**ppat == '\\')
+ (*ppat)++;
+ /* A non-terminated character class
+ * is ok. */
+ if (*ppat == epattern)
break;
- pattern++;
- }
+ (*ppat)++;
}
+ return true;
+}
+
+bool
+Str_Matchi(const char *string, const char *estring,
+ const char *pattern, const char *epattern)
+{
+ while (pattern != epattern) {
+ /* Check for a "*" as the next pattern character. */
+ if (*pattern == '*')
+ return star_match(string, estring, pattern, epattern);
+ else if (string == estring)
+ return false;
+ /* Check for a "[" as the next pattern character. It is
+ * followed by a list of characters that are acceptable, or
+ * by a range (two characters separated by "-"). */
+ else if (*pattern == '[') {
+ pattern++;
+ if (!range_match(*string, &pattern, epattern))
+ return false;
+
}
/* '?' matches any single character, so shunt test. */
else if (*pattern != '?') {
- /* If the next pattern character is '\', just strip off the
- * '\' so we do exact matching on the character that follows. */
+ /* If the next pattern character is '\', just strip
+ * off the '\' so we do exact matching on the
+ * character that follows. */
if (*pattern == '\\') {
if (++pattern == epattern)
return false;
@@ -401,7 +404,6 @@ Str_SYSVMatch(const char *word, const char *pattern, size_t *len)
}
} while (*w++ != '\0');
-
return NULL;
}