diff options
| author | Tyge Løvset <[email protected]> | 2022-07-22 15:05:25 +0200 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2022-07-22 15:05:25 +0200 |
| commit | 29d9d1d96d8a37f6d7e24dc170aa08a40f0f1559 (patch) | |
| tree | b239018af9c0dfa1b07edaf835663757dd4759ed | |
| parent | 28ee78e128c14fe309cb5f7cfc3f2172bf675ea7 (diff) | |
| download | STC-modified-29d9d1d96d8a37f6d7e24dc170aa08a40f0f1559.tar.gz STC-modified-29d9d1d96d8a37f6d7e24dc170aa08a40f0f1559.zip | |
FINAL cregex update for now: optimize/change callback mfun API. Also, cstr_printf() cannot take self as print argument.
| -rw-r--r-- | examples/regex_replace.c | 27 | ||||
| -rw-r--r-- | include/stc/cregex.h | 6 | ||||
| -rw-r--r-- | include/stc/cstr.h | 8 | ||||
| -rw-r--r-- | src/cregex.c | 14 |
4 files changed, 26 insertions, 29 deletions
diff --git a/examples/regex_replace.c b/examples/regex_replace.c index 0b6c9a1e..2bb9517f 100644 --- a/examples/regex_replace.c +++ b/examples/regex_replace.c @@ -2,13 +2,14 @@ #include <stc/cstr.h> #include <stc/cregex.h> -cstr sub_20y(int i, csview m) { - if (i == 1) { // year +bool add_10_years(int i, csview m, cstr* mstr) { + if (i == 1) { // group 1 matches year int year; sscanf(m.str, "%4d", &year); - return cstr_from_fmt("%04d", year - 20); + cstr_printf(mstr, "%04d", year + 10); + return true; } - return cstr_from_sv(m); + return false; } int main() @@ -18,31 +19,31 @@ int main() c_auto (cstr, str) { - printf("input: %s\n\n", input); + printf("INPUT: %s\n", input); /* replace with a fixed string, extended all-in-one call: */ cstr_take(&str, cregex_replace_p(input, pattern, "YYYY-MM-DD")); printf("fixed: %s\n", cstr_str(&str)); - /* US date format, and subtract 20 years: */ - cstr_take(&str, cregex_replace_pe(input, pattern, "\\1/\\3/\\2", sub_20y, 0, 0)); - printf("us-20: %s\n", cstr_str(&str)); + /* US date format, and add 10 years to dates: */ + cstr_take(&str, cregex_replace_pe(input, pattern, "\\1/\\3/\\2", add_10_years, 0, 0)); + printf("us+10: %s\n", cstr_str(&str)); /* Wrap first date inside []: */ cstr_take(&str, cregex_replace_pe(input, pattern, "[\\0]", NULL, 1, 0)); printf("brack: %s\n", cstr_str(&str)); - /* Wrap all words in {} */ - cstr_take(&str, cregex_replace_p("[52] apples and [31] mangoes", "[a-z]+", "{\\0}")); - printf("curly: %s\n", cstr_str(&str)); - - /* European date format, compile RE separately */ + /* European date format. Show how to compile RE separately */ cregex re = cregex_from(pattern, 0); if (cregex_captures(&re) == 0) continue; cstr_take(&str, cregex_replace(input, &re, "\\3.\\2.\\1", NULL, 0)); cregex_drop(&re); printf("euros: %s\n", cstr_str(&str)); + + /* Wrap all words in {} */ + cstr_take(&str, cregex_replace_p("[52] apples and [31] mangoes", "[a-z]+", "{\\0}")); + printf("curly: %s\n", cstr_str(&str)); } } diff --git a/include/stc/cregex.h b/include/stc/cregex.h index f93a0c03..fff8ccb1 100644 --- a/include/stc/cregex.h +++ b/include/stc/cregex.h @@ -98,11 +98,11 @@ int cregex_match_p(const char* input, const char* pattern, /* replace regular expression */ cstr cregex_replace(const char* input, const cregex* re, const char* replace, - cstr (*mfun)(int i, csview match), unsigned count); + bool (*mfun)(int i, csview match, cstr* mstr), unsigned count); -/* replace + compile RE pattern and extra arguments */ +/* replace + compile RE pattern, and extra arguments */ cstr cregex_replace_pe(const char* input, const char* pattern, const char* replace, - cstr (*mfun)(int i, csview match), unsigned count, int cflags); + bool (*mfun)(int i, csview match, cstr* mstr), unsigned count, int cflags); static inline cstr cregex_replace_p(const char* input, const char* pattern, const char* replace) { return cregex_replace_pe(input, pattern, replace, NULL, 0, 0); } diff --git a/include/stc/cstr.h b/include/stc/cstr.h index 8395f127..6db5ef49 100644 --- a/include/stc/cstr.h +++ b/include/stc/cstr.h @@ -511,8 +511,7 @@ STC_DEF int cstr_vfmt(cstr* self, const char* fmt, va_list args) { va_list args2; va_copy(args2, args); const int n = vsnprintf(NULL, (size_t)0, fmt, args); - cstr_reserve(self, n); - vsprintf(cstr_data(self), fmt, args2); + vsprintf(cstr_reserve(self, n), fmt, args2); va_end(args2); _cstr_set_size(self, n); return n; @@ -532,13 +531,12 @@ STC_DEF cstr cstr_from_fmt(const char* fmt, ...) { return s; } +/* NB! self-data in args is UB */ STC_DEF int cstr_printf(cstr* self, const char* fmt, ...) { - cstr s = cstr_null; va_list args; va_start(args, fmt); - const int n = cstr_vfmt(&s, fmt, args); + const int n = cstr_vfmt(self, fmt, args); va_end(args); - cstr_drop(self); *self = s; return n; } diff --git a/src/cregex.c b/src/cregex.c index 8705b335..02e3c3d8 100644 --- a/src/cregex.c +++ b/src/cregex.c @@ -1157,10 +1157,11 @@ regexec(const Reprog *progp, /* program to run */ static void build_subst_string(const char* replace, unsigned nmatch, const csview match[], - cstr (*mfun)(int i, csview match), cstr* subst) { + bool (*mfun)(int i, csview match, cstr* mstr), cstr* subst) { cstr_clear(subst); unsigned len = 0, cap = cstr_capacity(*subst); char* dst = cstr_data(subst); + cstr mstr = cstr_null; while (*replace != '\0') { if (*replace == '\\') { @@ -1171,15 +1172,11 @@ build_subst_string(const char* replace, unsigned nmatch, const csview match[], case '5': case '6': case '7': case '8': case '9': i = num - '0'; if (i < nmatch) { - csview m; - cstr mstr = cstr_null; - if (mfun) { mstr = mfun(i, match[i]); m = cstr_sv(&mstr); } - else m = match[i]; + csview m = mfun && mfun(i, match[i], &mstr) ? cstr_sv(&mstr) : match[i]; if (len + m.size >= cap) dst = cstr_reserve(subst, cap = cap*3/2 + m.size); for (const char* rp = m.str; rp != (m.str + m.size); ++rp) dst[len++] = *rp; - cstr_drop(&mstr); } ++replace; case '\0': @@ -1190,6 +1187,7 @@ build_subst_string(const char* replace, unsigned nmatch, const csview match[], dst = cstr_reserve(subst, cap = cap*3/2 + 4); dst[len++] = *replace++; } + cstr_drop(&mstr); _cstr_set_size(subst, len); } @@ -1233,7 +1231,7 @@ int cregex_match_p(const char* input, const char* pattern, cstr cregex_replace(const char* input, const cregex* re, const char* replace, - cstr (*mfun)(int i, csview match), unsigned count) { + bool (*mfun)(int i, csview match, cstr* mstr), unsigned count) { cstr out = cstr_null; cstr subst = cstr_null; size_t from = 0; @@ -1255,7 +1253,7 @@ cregex_replace(const char* input, const cregex* re, const char* replace, cstr cregex_replace_pe(const char* input, const char* pattern, const char* replace, - cstr (*mfun)(int i, csview match), unsigned count, int cflags) { + bool (*mfun)(int i, csview match, cstr* mstr), unsigned count, int cflags) { cregex re = cregex_init(); int res = cregex_compile(&re, pattern, cflags); if (res < 0) |
