str: New str_matchx function optionally reports possible prefix.
authorMark Wooding <mdw@distorted.org.uk>
Thu, 13 Apr 2006 20:52:59 +0000 (21:52 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Thu, 13 Apr 2006 20:52:59 +0000 (21:52 +0100)
It can be useful (trust me) to know whether a string is a possible
prefix of something which matches a glob pattern.  The function
str_matchx is like str_match (which is now a compatibility veneer) and
takes a flags word; the option STRF_PREFIX reports success if it hits
the end of the target string while trying to find a match.

man/str.3
str.c
str.h

index 24a983c..1d442ca 100644 (file)
--- a/man/str.3
+++ b/man/str.3
@@ -18,6 +18,7 @@ str \- small string utilities
 .\" @str_qsplit
 .\" @str_getword
 .\" @str_split
+.\" @str_matchx
 .\" @str_match
 .\" @str_sanitize
 .SH SYNOPSIS
@@ -29,6 +30,7 @@ str \- small string utilities
 .BI "                  char **" rest ", unsigned " f );
 .BI "char *str_getword(char **" pp );
 .BI "size_t str_split(char *" p ", char *" v "[], size_t " c ", char **" rest );
+.BI "int str_matchx(const char *" p ", const char *" s ", unsigned " f );
 .BI "int str_match(const char *" p ", const char *" s );
 .BI "void str_sanitize(char *" d ", const char *" p ", size_t " sz );
 .fi
@@ -107,7 +109,7 @@ respectively; they are equivalent to calls to the latter functions with
 flags words of zero.
 .PP
 The
-.B str_match
+.B str_matchx
 function does simple wildcard matching.  The first argument is a
 pattern, which may contain metacharacters:
 .RB ` * '
@@ -134,7 +136,17 @@ of the set.  The return value is nonzero if the pattern
 .I p
 matches the given string
 .IR s ,
-or zero if the pattern doesn't match.
+or zero if the pattern doesn't match.  If the flag
+.B STRF_PREFIX
+is passed,
+.B str_matchx
+returns true if it reaches the end of the target string before finding a
+mismatch \(en i.e., if the target string is a prefix of a string which
+might match the pattern.  The function
+.B str_match
+is a convenient wrapper for
+.B str_matchx
+with a zero flags word, which is the normal case.
 .PP
 The function
 .B str_sanitize
diff --git a/str.c b/str.c
index 36dea7a..e30682d 100644 (file)
--- a/str.c
+++ b/str.c
@@ -183,10 +183,11 @@ char *str_getword(char **pp) { return (str_qword(pp, 0)); }
 size_t str_split(char *p, char *v[], size_t c, char **rest)
   { return (str_qsplit(p, v, c, rest, 0)); }
 
-/* --- @str_match@ --- *
+/* --- @str_matchx@ --- *
  *
  * Arguments:  @const char *p@ = pointer to pattern string
  *             @const char *s@ = string to compare with
+ *             @unsigned f@ = various flags
  *
  * Returns:    Nonzero if the pattern matches the string.
  *
@@ -195,12 +196,14 @@ size_t str_split(char *p, char *v[], size_t c, char **rest)
  *             '['.
  */
 
-int str_match(const char *p, const char *s)
+int str_matchx(const char *p, const char *s, unsigned f)
 {
   for (;;) {
     char pch = *p++, pche, sch;
     int sense;
 
+    if ((f & STRF_PREFIX) && !*s)
+      return (1);
     switch (pch) {
       case '?':
        if (!*s)
@@ -208,7 +211,7 @@ int str_match(const char *p, const char *s)
        s++;
        break;
       case '*':
-       if (!*p)
+       if (!*p || (f & STRF_PREFIX))
          return (1);
        while (*s) {
          if (str_match(p, s))
@@ -277,6 +280,20 @@ int str_match(const char *p, const char *s)
   }
 }
 
+/* --- @str_match@ --- *
+ *
+ * Arguments:  @const char *p@ = pointer to pattern string
+ *             @const char *s@ = string to compare with
+ *
+ * Returns:    Nonzero if the pattern matches the string.
+ *
+ * Use:                Does simple wildcard matching.  Equivalent to @str_matchx@
+ *             with zero flags word.
+ */
+
+int str_match(const char *p, const char *s)
+  { return (str_matchx(p, s, 0)); }
+
 /* --- @str_sanitize@ --- *
  *
  * Arguments:  @char *d@ = destination buffer
diff --git a/str.h b/str.h
index c7bd87b..4f9c5c2 100644 (file)
--- a/str.h
+++ b/str.h
@@ -110,10 +110,11 @@ extern char *str_getword(char **/*pp*/);
 extern size_t str_split(char */*p*/, char */*v*/[],
                        size_t /*c*/, char **/*rest*/);
 
-/* --- @str_match@ --- *
+/* --- @str_matchx@ --- *
  *
  * Arguments:  @const char *p@ = pointer to pattern string
  *             @const char *s@ = string to compare with
+ *             @unsigned f@ = various flags
  *
  * Returns:    Nonzero if the pattern matches the string.
  *
@@ -122,6 +123,22 @@ extern size_t str_split(char */*p*/, char */*v*/[],
  *             '['.
  */
 
+#define STRF_PREFIX 1u                 /* Accept if @s@ is exhausted during
+                                        *   the attempted match */
+
+extern int str_matchx(const char */*p*/, const char */*s*/, unsigned /*f*/);
+
+/* --- @str_match@ --- *
+ *
+ * Arguments:  @const char *p@ = pointer to pattern string
+ *             @const char *s@ = string to compare with
+ *
+ * Returns:    Nonzero if the pattern matches the string.
+ *
+ * Use:                Does simple wildcard matching.  Equivalent to @str_matchx@
+ *             with zero flags word.
+ */
+
 extern int str_match(const char */*p*/, const char */*s*/);
 
 /* --- @str_sanitize@ --- *