diff options
| -rw-r--r-- | benchmarks/misc/prng_bench.cpp | 271 | ||||
| -rw-r--r-- | docs/cregex_api.md | 66 | ||||
| -rw-r--r-- | include/stc/cregex.h | 11 | ||||
| -rw-r--r-- | src/cregex.c | 20 |
4 files changed, 193 insertions, 175 deletions
diff --git a/benchmarks/misc/prng_bench.cpp b/benchmarks/misc/prng_bench.cpp index ca6a1f10..6f4e0e47 100644 --- a/benchmarks/misc/prng_bench.cpp +++ b/benchmarks/misc/prng_bench.cpp @@ -10,10 +10,10 @@ static inline uint64_t rotl64(const uint64_t x, const int k) static uint64_t splitmix64_x = 87213627321ull; /* The state can be seeded with any value. */ uint64_t splitmix64(void) { - uint64_t z = (splitmix64_x += 0x9e3779b97f4a7c15); - z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9; - z = (z ^ (z >> 27)) * 0x94d049bb133111eb; - return z ^ (z >> 31); + uint64_t z = (splitmix64_x += 0x9e3779b97f4a7c15); + z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9; + z = (z ^ (z >> 27)) * 0x94d049bb133111eb; + return z ^ (z >> 31); } static void init_state(uint64_t *rng, uint64_t seed) { @@ -24,21 +24,21 @@ static void init_state(uint64_t *rng, uint64_t seed) { /* romu_trio */ uint64_t romu_trio(uint64_t s[3]) { - uint64_t xp = s[0], yp = s[1], zp = s[2]; - s[0] = 15241094284759029579u * zp; - s[1] = yp - xp; s[1] = rotl64(s[1], 12); - s[2] = zp - yp; s[2] = rotl64(s[2], 44); - return xp; + uint64_t xp = s[0], yp = s[1], zp = s[2]; + s[0] = 15241094284759029579u * zp; + s[1] = yp - xp; s[1] = rotl64(s[1], 12); + s[2] = zp - yp; s[2] = rotl64(s[2], 44); + return xp; } /* sfc64 */ static inline uint64_t sfc64(uint64_t s[4]) { - uint64_t result = s[0] + s[1] + s[3]++; - s[0] = s[1] ^ (s[1] >> 11); - s[1] = s[2] + (s[2] << 3); - s[2] = rotl64(s[2], 24) + result; - return result; + uint64_t result = s[0] + s[1] + s[3]++; + s[0] = s[1] ^ (s[1] >> 11); + s[1] = s[2] + (s[2] << 3); + s[2] = rotl64(s[2], 24) + result; + return result; } uint32_t sfc32(uint32_t s[4]) { @@ -57,55 +57,64 @@ uint32_t stc32(uint32_t s[5]) { return t; } +uint32_t pcg32(uint32_t s[2]) { + uint64_t oldstate = s[0]; + s[0] = oldstate * 6364136223846793005ULL + (s[1]|1); + uint32_t xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u; + uint32_t rot = oldstate >> 59u; + return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)); +} + + /* xoshiro128+ */ uint64_t xoroshiro128plus(uint64_t s[2]) { - const uint64_t s0 = s[0]; - uint64_t s1 = s[1]; - const uint64_t result = s0 + s1; + const uint64_t s0 = s[0]; + uint64_t s1 = s[1]; + const uint64_t result = s0 + s1; - s1 ^= s0; - s[0] = rotl64(s0, 24) ^ s1 ^ (s1 << 16); // a, b - s[1] = rotl64(s1, 37); // c + s1 ^= s0; + s[0] = rotl64(s0, 24) ^ s1 ^ (s1 << 16); // a, b + s[1] = rotl64(s1, 37); // c - return result; + return result; } /* xoshiro256** */ static inline uint64_t xoshiro256starstar(uint64_t s[4]) { - const uint64_t result = rotl64(s[1] * 5, 7) * 9; - const uint64_t t = s[1] << 17; - s[2] ^= s[0]; - s[3] ^= s[1]; - s[1] ^= s[2]; - s[0] ^= s[3]; - s[2] ^= t; - s[3] = rotl64(s[3], 45); - return result; + const uint64_t result = rotl64(s[1] * 5, 7) * 9; + const uint64_t t = s[1] << 17; + s[2] ^= s[0]; + s[3] ^= s[1]; + s[1] ^= s[2]; + s[0] ^= s[3]; + s[2] ^= t; + s[3] = rotl64(s[3], 45); + return result; } // wyrand - 2020-12-07 static inline void _wymum(uint64_t *A, uint64_t *B){ #if defined(__SIZEOF_INT128__) - __uint128_t r = *A; r *= *B; - *A = (uint64_t) r; *B = (uint64_t ) (r >> 64); + __uint128_t r = *A; r *= *B; + *A = (uint64_t) r; *B = (uint64_t ) (r >> 64); #elif defined(_MSC_VER) && defined(_M_X64) - *A = _umul128(*A, *B, B); + *A = _umul128(*A, *B, B); #else - uint64_t ha=*A>>32, hb=*B>>32, la=(uint32_t)*A, lb=(uint32_t)*B, hi, lo; - uint64_t rh=ha*hb, rm0=ha*lb, rm1=hb*la, rl=la*lb, t=rl+(rm0<<32), c=t<rl; - lo=t+(rm1<<32); c+=lo<t; hi=rh+(rm0>>32)+(rm1>>32)+c; - *A=lo; *B=hi; + uint64_t ha=*A>>32, hb=*B>>32, la=(uint32_t)*A, lb=(uint32_t)*B, hi, lo; + uint64_t rh=ha*hb, rm0=ha*lb, rm1=hb*la, rl=la*lb, t=rl+(rm0<<32), c=t<rl; + lo=t+(rm1<<32); c+=lo<t; hi=rh+(rm0>>32)+(rm1>>32)+c; + *A=lo; *B=hi; #endif } static inline uint64_t _wymix(uint64_t A, uint64_t B){ - _wymum(&A,&B); return A^B; + _wymum(&A,&B); return A^B; } static inline uint64_t wyrand64(uint64_t *seed){ - static const uint64_t _wyp[] = {0xa0761d6478bd642full, 0xe7037ed1a0b428dbull}; - *seed+=_wyp[0]; return _wymix(*seed,*seed^_wyp[1]); + static const uint64_t _wyp[] = {0xa0761d6478bd642full, 0xe7037ed1a0b428dbull}; + *seed+=_wyp[0]; return _wymix(*seed,*seed^_wyp[1]); } @@ -113,94 +122,102 @@ using namespace std; int main(void) { - enum {N = 2000000000}; - uint16_t* recipient = new uint16_t[N]; - static stc64_t rng; - init_state(rng.state, 12345123); - std::mt19937 mt(12345123); - - cout << "WARMUP" << endl; - for (size_t i = 0; i < N; i++) - recipient[i] = wyrand64(rng.state); - - clock_t beg, end; - for (size_t ti = 0; ti < 2; ti++) { + enum {N = 2000000000}; + uint16_t* recipient = new uint16_t[N]; + static stc64_t rng; init_state(rng.state, 12345123); - cout << endl << "ROUND " << ti+1 << " ---------" << endl; - - beg = clock(); - for (size_t i = 0; i < N; i++) - recipient[i] = romu_trio(rng.state); - end = clock(); - cout << "romu_trio:\t" - << (float(end - beg) / CLOCKS_PER_SEC) - << "s: " << recipient[312] << endl; - - beg = clock(); - for (size_t i = 0; i < N; i++) - recipient[i] = wyrand64(rng.state); - end = clock(); - cout << "wyrand64:\t" - << (float(end - beg) / CLOCKS_PER_SEC) - << "s: " << recipient[312] << endl; - - beg = clock(); - for (size_t i = 0; i < N; i++) - recipient[i] = sfc32((uint32_t *)rng.state); - end = clock(); - cout << "sfc32:\t\t" - << (float(end - beg) / CLOCKS_PER_SEC) - << "s: " << recipient[312] << endl; - - beg = clock(); - for (size_t i = 0; i < N; i++) - recipient[i] = stc32((uint32_t *)rng.state); - end = clock(); - cout << "stc32:\t\t" - << (float(end - beg) / CLOCKS_PER_SEC) - << "s: " << recipient[312] << endl; - - beg = clock(); - for (size_t i = 0; i < N; i++) - recipient[i] = sfc64(rng.state); - end = clock(); - cout << "sfc64:\t\t" - << (float(end - beg) / CLOCKS_PER_SEC) - << "s: " << recipient[312] << endl; - - beg = clock(); - for (size_t i = 0; i < N; i++) - recipient[i] = stc64_rand(&rng); - end = clock(); - cout << "stc64:\t\t" - << (float(end - beg) / CLOCKS_PER_SEC) - << "s: " << recipient[312] << endl; - - - beg = clock(); - for (size_t i = 0; i < N; i++) - recipient[i] = xoroshiro128plus(rng.state); - end = clock(); - cout << "xoroshiro128+:\t" - << (float(end - beg) / CLOCKS_PER_SEC) - << "s: " << recipient[312] << endl; - - beg = clock(); - for (size_t i = 0; i < N; i++) - recipient[i] = xoshiro256starstar(rng.state); - end = clock(); - cout << "xoshiro256**:\t" - << (float(end - beg) / CLOCKS_PER_SEC) - << "s: " << recipient[312] << endl; + std::mt19937 mt(12345123); - beg = clock(); + cout << "WARMUP" << endl; for (size_t i = 0; i < N; i++) - recipient[i] = mt(); - end = clock(); - cout << "std::mt19937:\t" - << (float(end - beg) / CLOCKS_PER_SEC) - << "s: " << recipient[312] << endl; - } - delete[] recipient; - return 0; + recipient[i] = wyrand64(rng.state); + + clock_t beg, end; + for (size_t ti = 0; ti < 2; ti++) { + init_state(rng.state, 12345123); + cout << endl << "ROUND " << ti+1 << " ---------" << endl; + + beg = clock(); + for (size_t i = 0; i < N; i++) + recipient[i] = romu_trio(rng.state); + end = clock(); + cout << "romu_trio:\t" + << (float(end - beg) / CLOCKS_PER_SEC) + << "s: " << recipient[312] << endl; + + beg = clock(); + for (size_t i = 0; i < N; i++) + recipient[i] = wyrand64(rng.state); + end = clock(); + cout << "wyrand64:\t" + << (float(end - beg) / CLOCKS_PER_SEC) + << "s: " << recipient[312] << endl; + + beg = clock(); + for (size_t i = 0; i < N; i++) + recipient[i] = sfc32((uint32_t *)rng.state); + end = clock(); + cout << "sfc32:\t\t" + << (float(end - beg) / CLOCKS_PER_SEC) + << "s: " << recipient[312] << endl; + + beg = clock(); + for (size_t i = 0; i < N; i++) + recipient[i] = stc32((uint32_t *)rng.state); + end = clock(); + cout << "stc32:\t\t" + << (float(end - beg) / CLOCKS_PER_SEC) + << "s: " << recipient[312] << endl; + + beg = clock(); + for (size_t i = 0; i < N; i++) + recipient[i] = pcg32((uint32_t *)rng.state); + end = clock(); + cout << "pcg32:\t\t" + << (float(end - beg) / CLOCKS_PER_SEC) + << "s: " << recipient[312] << endl; + + beg = clock(); + for (size_t i = 0; i < N; i++) + recipient[i] = sfc64(rng.state); + end = clock(); + cout << "sfc64:\t\t" + << (float(end - beg) / CLOCKS_PER_SEC) + << "s: " << recipient[312] << endl; + + beg = clock(); + for (size_t i = 0; i < N; i++) + recipient[i] = stc64_rand(&rng); + end = clock(); + cout << "stc64:\t\t" + << (float(end - beg) / CLOCKS_PER_SEC) + << "s: " << recipient[312] << endl; + + + beg = clock(); + for (size_t i = 0; i < N; i++) + recipient[i] = xoroshiro128plus(rng.state); + end = clock(); + cout << "xoroshiro128+:\t" + << (float(end - beg) / CLOCKS_PER_SEC) + << "s: " << recipient[312] << endl; + + beg = clock(); + for (size_t i = 0; i < N; i++) + recipient[i] = xoshiro256starstar(rng.state); + end = clock(); + cout << "xoshiro256**:\t" + << (float(end - beg) / CLOCKS_PER_SEC) + << "s: " << recipient[312] << endl; + + beg = clock(); + for (size_t i = 0; i < N; i++) + recipient[i] = mt(); + end = clock(); + cout << "std::mt19937:\t" + << (float(end - beg) / CLOCKS_PER_SEC) + << "s: " << recipient[312] << endl; + } + delete[] recipient; + return 0; } diff --git a/docs/cregex_api.md b/docs/cregex_api.md index 1c0f346a..9bed66fa 100644 --- a/docs/cregex_api.md +++ b/docs/cregex_api.md @@ -11,46 +11,51 @@ The API is simple and includes powerful string pattern matches and replace funct ```c enum { - // compile-flags - CREG_C_DOTALL = 1<<0, // dot matches newline too - CREG_C_ICASE = 1<<1, // ignore case - // match-flags - CREG_M_FULLMATCH = 1<<2, // like start-, end-of-line anchors were in pattern: "^ ... $" - CREG_M_NEXT = 1<<3, // use end of previous match[0] as start of input - CREG_M_STARTEND = 1<<4, // use match[0] as start+end of input - // replace-flags - CREG_R_STRIP = 1<<5, // only keep the replaced matches, strip the rest + /* compile-flags */ + CREG_C_DOTALL = 1<<0, /* dot matches newline too: can be set/overridden by (?s) and (?-s) in RE */ + CREG_C_ICASE = 1<<1, /* ignore case mode: can be set/overridden by (?i) and (?-i) in RE */ + /* match-flags */ + CREG_M_FULLMATCH = 1<<2, /* like start-, end-of-line anchors were in pattern: "^ ... $" */ + CREG_M_NEXT = 1<<3, /* use end of previous match[0] as start of input */ + CREG_M_STARTEND = 1<<4, /* use match[0] as start+end of input */ + /* replace-flags */ + CREG_R_STRIP = 1<<5, /* only keep the replaced matches, strip the rest */ }; cregex cregex_init(void); - cregex cregex_from(const char* pattern, int cflags); - // return CREG_SUCCESS, or negative error code on failure. + /* return CREG_OK, or negative error code on failure */ int cregex_compile(cregex *self, const char* pattern, int cflags); - // num. of capture groups in regex. 0 if RE is invalid. First group is the full match. + /* num. of capture groups in regex. 0 if RE is invalid. First group is the full match */ int cregex_captures(const cregex* self); - // return CREG_SUCCESS, CREG_NOMATCH, or CREG_MATCHERROR. + /* return CREG_OK, CREG_NOMATCH, or CREG_MATCHERROR */ int cregex_find(const cregex* re, const char* input, csview match[], int mflags); + /* Search inside input string-view only */ int cregex_find_sv(const cregex* re, csview input, csview match[]); + /* All-in-one search (compile + find + drop) */ int cregex_find_pattern(const char* pattern, const char* input, csview match[], int cmflags); + /* Check if there are matches in input */ bool cregex_is_match(const cregex* re, const char* input); + /* Replace all matches in input */ cstr cregex_replace(const cregex* re, const char* input, const char* replace); + /* Replace count matches in input string-view. Optionally transform replacement with mfun. */ cstr cregex_replace_sv(const cregex* re, csview input, const char* replace, unsigned count, bool(*mfun)(int capgrp, csview match, cstr* mstr), int rflags); + /* All-in-one replacement (compile + find/replace + drop) */ cstr cregex_replace_pattern(const char* pattern, const char* input, const char* replace); cstr cregex_replace_pattern_n(const char* pattern, const char* input, const char* replace, unsigned count, bool(*mfun)(int capgrp, csview match, cstr* mstr), int rflags); -void cregex_drop(cregex* self); // destroy +void cregex_drop(cregex* self); /* destroy */ ``` ### Error codes -- CREG_SUCCESS = 0 +- CREG_OK = 0 - CREG_NOMATCH = -1 - CREG_MATCHERROR = -2 - CREG_OUTOFMEMORY = -3 @@ -79,14 +84,15 @@ if (result < 0) return result; const char* url = "(https?://|ftp://|www\\.)([0-9A-Za-z@:%_+~#=-]+\\.)+([a-z][a-z][a-z]?)(/[/0-9A-Za-z\\.@:%_+~#=\\?&-]*)?"; cregex re2 = cregex_from(url, CREG_DEFAULT); -if (re2.error) return re2.error; +if (re2.error != CREG_OK) + return re2.error; ... cregex_drop(&re2); cregex_drop(&re1); ``` -If an error occurs ```cregex_compile``` returns a negative value, see error codes. +If an error occurs ```cregex_compile``` returns a negative error code stored in re2.error. -### Getting the first match +### Getting the first match and making text replacements ```c #define i_extern // include external utf8 and cregex functions implementation. #include <stc/cregex.h> @@ -100,7 +106,7 @@ int main() { // Lets find the first date in the string: csview match[4]; // full-match, year, month, date. - if (cregex_find(&re, input, match, CREG_DEFAULT) == CREG_SUCCESS) + if (cregex_find(&re, input, match, CREG_DEFAULT) == CREG_OK) printf("Found date: %.*s\n", c_ARGsv(match[0])); else printf("Could not find any date\n"); @@ -128,7 +134,7 @@ In order to use a callback function in the replace call, see `examples/regex_rep To iterate multiple matches in an input string, you may use ```c csview match[5] = {0}; -while (cregex_find(&re, input, match, CREG_M_NEXT) == CREG_SUCCESS) +while (cregex_find(&re, input, match, CREG_M_NEXT) == CREG_OK) c_forrange (k, cregex_captures(&re)) printf("submatch %lld: %.*s\n", k, c_ARGsv(match[k])); ``` @@ -141,7 +147,9 @@ c_formatch (it, &re, input) ## Using cregex in a project -**cregex** uses the following files: +The easiest is to `#define i_extern` before `#include <stc/cregex.h>`. Make sure to do that in one translation unit only. + +For reference, **cregex** uses the following files: - `stc/cregex.h`, `stc/utf8.h`, `stc/csview.h`, `stc/cstr.h`, `stc/ccommon.h`, `stc/forward.h` - `src/cregex.c`, `src/utf8code.c`. @@ -156,7 +164,7 @@ c_formatch (it, &re, input) | * | Match the preceding token as often as possible | | | + | Match the preceding token at least once and as often as possible | | | \| | Match either the expression before the \| or the expression after it | | -| (***expr***) | Match the expression inside the parentheses. This adds a capture group | | +| (***expr***) | Match the expression inside the parentheses. ***This adds a capture group*** | | | [***chars***] | Match any character inside the brackets. Ranges like a-z may also be used | | | \[^***chars***\] | Match any character not inside the bracket. | | | \x{***hex***} | Match UTF8 character/codepoint given as a hex number | * | @@ -182,14 +190,14 @@ c_formatch (it, &re, input) | \p{Upper} or \p{Lu} | Match UTF8 upper case | * | | \p{Space} or \p{Sz} | Match UTF8 whitespace | * | | \P{***Class***} | Do not match the classes described above | * | -| [[:alnum:]] [[:alpha:]] [[:ascii:]] | Match ASCII character class | * | -| [[:blank:]] [[:cntrl:]] [[:digit:]] | Match ASCII character class | * | -| [[:graph:]] [[:lower:]] [[:print:]] | Match ASCII character class | * | -| [[:punct:]] [[:space:]] [[:upper:]] | Match ASCII character class | * | -| [[:xdigit:]] [[:word:]] | Match ASCII character class | * | -| [[:^***class***:]] | Match character not in the ASCII class | * | +| [:alnum:] [:alpha:] [:ascii:] | Match ASCII character class. NB: only to be used inside [] brackets | * | +| [:blank:] [:cntrl:] [:digit:] | " | * | +| [:graph:] [:lower:] [:print:] | " | * | +| [:punct:] [:space:] [:upper:] | " | * | +| [:xdigit:] [:word:] | " | * | +| [:^***class***:] | Match character not in the ASCII class | * | | $***n*** | *n*-th substitution backreference to capture group. ***n*** in 0-9. $0 is the entire match. | * | -| $***nn***; | As above, but can handle ***nn*** < CREG_MAX_CAPTURES. | * | +| $***nn;*** | As above, but can handle ***nn*** < CREG_MAX_CAPTURES. | * | ## Limitations diff --git a/include/stc/cregex.h b/include/stc/cregex.h index 7798b5a7..b6e33879 100644 --- a/include/stc/cregex.h +++ b/include/stc/cregex.h @@ -51,7 +51,8 @@ enum { }; typedef enum { - CREG_SUCCESS = 0, + CREG_OK = 0, + CREG_SUCCESS = 0, /* [deprecated] */ CREG_NOMATCH = -1, CREG_MATCHERROR = -2, CREG_OUTOFMEMORY = -3, @@ -80,7 +81,7 @@ typedef struct { #define c_formatch(it, Re, Input) \ for (cregex_iter it = {Re, Input}; \ - cregex_find(it.re, it.input, it.match, CREG_M_NEXT) == CREG_SUCCESS;) + cregex_find(it.re, it.input, it.match, CREG_M_NEXT) == CREG_OK; ) static inline cregex cregex_init(void) { @@ -88,7 +89,7 @@ cregex cregex_init(void) { return re; } -/* return CREG_SUCCESS, or negative error code on failure. */ +/* return CREG_OK, or negative error code on failure. */ int cregex_compile(cregex *self, const char* pattern, int cflags); static inline @@ -101,7 +102,7 @@ cregex cregex_from(const char* pattern, int cflags) { /* number of capture groups in a regex pattern, 0 if regex is invalid */ unsigned cregex_captures(const cregex* self); -/* return CREG_SUCCESS, CREG_NOMATCH or CREG_MATCHERROR. */ +/* return CREG_OK, CREG_NOMATCH or CREG_MATCHERROR. */ int cregex_find(const cregex* re, const char* input, csview match[], int mflags); static inline @@ -117,7 +118,7 @@ int cregex_find_pattern(const char* pattern, const char* input, static inline bool cregex_is_match(const cregex* re, const char* input) - { return cregex_find(re, input, NULL, CREG_DEFAULT) == CREG_SUCCESS; } + { return cregex_find(re, input, NULL, CREG_DEFAULT) == CREG_OK; } /* replace regular expression */ cstr cregex_replace_sv(const cregex* re, csview input, const char* replace, unsigned count, diff --git a/src/cregex.c b/src/cregex.c index 213663e0..acbf53fa 100644 --- a/src/cregex.c +++ b/src/cregex.c @@ -861,22 +861,14 @@ _regcomp1(_Reprog *progp, _Parser *par, const char *s, int cflags) /* Force TOK_END */ _operand(par, TOK_END); _evaluntil(par, TOK_START); -#ifdef DEBUG - dumpstack(par); -#endif + if (par->nbra) _rcerror(par, CREG_UNMATCHEDLEFTPARENTHESIS); --par->andp; /* points to first and only _operand */ pp->startinst = par->andp->first; -#ifdef DEBUG - dump(pp); -#endif + pp = _optimize(par, pp); pp->nsubids = (unsigned)par->cursubid; -#ifdef DEBUG - print("start: %d\n", par->andp->first-pp->firstinst); - dump(pp); -#endif out: if (par->error) { c_free(pp); @@ -1236,7 +1228,7 @@ cregex_find(const cregex* re, const char* input, csview match[], int mflags) { int res = _regexec(re->prog, input, cregex_captures(re), match, mflags); switch (res) { - case 1: return CREG_SUCCESS; + case 1: return CREG_OK; case 0: return CREG_NOMATCH; default: return CREG_MATCHERROR; } @@ -1247,7 +1239,7 @@ cregex_find_pattern(const char* pattern, const char* input, csview match[], int cmflags) { cregex re = cregex_init(); int res = cregex_compile(&re, pattern, cmflags); - if (res != CREG_SUCCESS) return res; + if (res != CREG_OK) return res; res = cregex_find(&re, input, match, cmflags); cregex_drop(&re); return res; @@ -1263,7 +1255,7 @@ cregex_replace_sv(const cregex* re, csview input, const char* replace, unsigned if (!count) count = ~0U; bool copy = !(rflags & CREG_R_STRIP); - while (count-- && cregex_find_sv(re, input, match) == CREG_SUCCESS) { + while (count-- && cregex_find_sv(re, input, match) == CREG_OK) { _build_subst(replace, nmatch, match, mfun, &subst); const size_t mpos = (size_t)(match[0].str - input.str); if (copy & (mpos > 0)) cstr_append_n(&out, input.str, mpos); @@ -1280,7 +1272,7 @@ cstr cregex_replace_pattern_n(const char* pattern, const char* input, const char* replace, unsigned count, bool (*mfun)(int, csview, cstr*), int crflags) { cregex re = cregex_init(); - if (cregex_compile(&re, pattern, crflags) != CREG_SUCCESS) + if (cregex_compile(&re, pattern, crflags) != CREG_OK) assert(0); csview sv = {input, strlen(input)}; cstr out = cregex_replace_sv(&re, sv, replace, count, mfun, crflags); |
