aboutsummaryrefslogtreecommitdiff
path: root/lib/lib.c
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2016-07-26 13:35:56 -0500
committerRob Landley <rob@landley.net>2016-07-26 13:35:56 -0500
commitf20b10ee7b0568ff800588579c7f74ca74f0c23f (patch)
tree334d2d7faed346ff2829e640fec2ee76b9ea89d7 /lib/lib.c
parent7918d9ff8c39b1acdfaffb93de7d337dd4faa9a8 (diff)
downloadtoybox-f20b10ee7b0568ff800588579c7f74ca74f0c23f.tar.gz
Move regexec0 into lib (regexec that takes length and matches after NUL).
Diffstat (limited to 'lib/lib.c')
-rw-r--r--lib/lib.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/lib/lib.c b/lib/lib.c
index 09264c95..5c7696d0 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -1149,3 +1149,38 @@ int readlink0(char *path, char *buf, int len)
{
return readlinkat0(AT_FDCWD, path, buf, len);
}
+
+// Do regex matching handling embedded NUL bytes in string (hence extra len
+// argument). Note that neither the pattern nor the match can currently include
+// NUL bytes (even with wildcards) and string must be null terminated at
+// string[len]. But this can find a match after the first NUL.
+int regexec0(regex_t *preg, char *string, long len, int nmatch,
+ regmatch_t pmatch[], int eflags)
+{
+ char *s = string;
+
+ for (;;) {
+ long ll = 0;
+ int rc;
+
+ while (len && !*s) {
+ s++;
+ len--;
+ }
+ while (s[ll] && ll<len) ll++;
+
+ rc = regexec(preg, s, nmatch, pmatch, eflags);
+ if (!rc) {
+ for (rc = 0; rc<nmatch && pmatch[rc].rm_so!=-1; rc++) {
+ pmatch[rc].rm_so += s-string;
+ pmatch[rc].rm_eo += s-string;
+ }
+
+ return 0;
+ }
+ if (ll==len) return rc;
+
+ s += ll;
+ len -= ll;
+ }
+}