diff options
author | Rob Landley <rob@landley.net> | 2016-07-26 13:35:56 -0500 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2016-07-26 13:35:56 -0500 |
commit | f20b10ee7b0568ff800588579c7f74ca74f0c23f (patch) | |
tree | 334d2d7faed346ff2829e640fec2ee76b9ea89d7 /lib | |
parent | 7918d9ff8c39b1acdfaffb93de7d337dd4faa9a8 (diff) | |
download | toybox-f20b10ee7b0568ff800588579c7f74ca74f0c23f.tar.gz |
Move regexec0 into lib (regexec that takes length and matches after NUL).
Diffstat (limited to 'lib')
-rw-r--r-- | lib/lib.c | 35 | ||||
-rw-r--r-- | lib/lib.h | 2 |
2 files changed, 37 insertions, 0 deletions
@@ -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; + } +} @@ -218,6 +218,8 @@ struct passwd *bufgetpwuid(uid_t uid); struct group *bufgetgrgid(gid_t gid); int readlinkat0(int dirfd, char *path, char *buf, int len); int readlink0(char *path, char *buf, int len); +int regexec0(regex_t *preg, char *string, long len, int nmatch, + regmatch_t pmatch[], int eflags); #define HR_SPACE 1 // Space between number and units #define HR_B 2 // Use "B" for single byte units |