summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2022-07-22 15:05:25 +0200
committerTyge Løvset <[email protected]>2022-07-22 15:05:25 +0200
commit29d9d1d96d8a37f6d7e24dc170aa08a40f0f1559 (patch)
treeb239018af9c0dfa1b07edaf835663757dd4759ed
parent28ee78e128c14fe309cb5f7cfc3f2172bf675ea7 (diff)
downloadSTC-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.c27
-rw-r--r--include/stc/cregex.h6
-rw-r--r--include/stc/cstr.h8
-rw-r--r--src/cregex.c14
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)