summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMole Shang <[email protected]>2023-08-08 23:17:38 +0800
committerMole Shang <[email protected]>2023-08-08 23:17:38 +0800
commit02c045e6e7217c590acba5f8acc63e25f3b542b9 (patch)
treeb5862ddbaf47988d48dcbf828bdfd343cfd865e8
parent66e17a6855dfa723b017ccd3685950c2de51f5da (diff)
downloadhinata-02c045e6e7217c590acba5f8acc63e25f3b542b9.tar.gz
hinata-02c045e6e7217c590acba5f8acc63e25f3b542b9.tar.bz2
hinata-02c045e6e7217c590acba5f8acc63e25f3b542b9.zip
utils: add a method to substitute string using PCRE
-rw-r--r--src/utils/utils.c59
-rw-r--r--src/utils/utils.h3
2 files changed, 61 insertions, 1 deletions
diff --git a/src/utils/utils.c b/src/utils/utils.c
index f3ebbb4..ea0b424 100644
--- a/src/utils/utils.c
+++ b/src/utils/utils.c
@@ -7,6 +7,13 @@
#include "../logger.h"
#include "utils.h"
+static void print_error(int code) {
+ PCRE2_UCHAR message[256];
+ if (pcre2_get_error_message(code, message,
+ sizeof(message) / sizeof(PCRE2_UCHAR)))
+ LOG("PCRE2", "Error: %s\n", (const char *)message);
+}
+
int regex_match(const char *subject, str_array_t patterns,
str_array_t *results) {
pcre2_code *re;
@@ -75,7 +82,7 @@ int regex_match(const char *subject, str_array_t patterns,
"ovector was not big enough for all the captured substrings\n");
break;
default:
- LOG("PCRE2", "Matching error %d\n", rc);
+ print_error(rc);
return 1;
}
}
@@ -83,6 +90,56 @@ int regex_match(const char *subject, str_array_t patterns,
return 0;
}
+int substitute_str(const char *subject, const char *pattern,
+ const char *replacement, char **presult) {
+ pcre2_code *re;
+ pcre2_match_context *match_context;
+ int rc, error;
+ PCRE2_SIZE erroffset, outlength;
+ PCRE2_UCHAR *outbuf;
+
+ re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED,
+ PCRE2_MULTILINE, &error, &erroffset, 0);
+ if (!re) {
+ print_error(error);
+ return 1;
+ }
+
+ match_context = pcre2_match_context_create(0);
+
+ outlength = 0;
+ rc = pcre2_substitute(re, (PCRE2_SPTR)subject, PCRE2_ZERO_TERMINATED, 0,
+ PCRE2_SUBSTITUTE_GLOBAL |
+ PCRE2_SUBSTITUTE_OVERFLOW_LENGTH |
+ PCRE2_SUBSTITUTE_EXTENDED,
+ 0, match_context, (PCRE2_SPTR)replacement,
+ PCRE2_ZERO_TERMINATED, 0, &outlength);
+
+ if (rc != PCRE2_ERROR_NOMEMORY) {
+ print_error(rc);
+ return 1;
+ }
+
+ outbuf = malloc(outlength * sizeof(PCRE2_UCHAR));
+
+ rc = pcre2_substitute(re, (PCRE2_SPTR)subject, PCRE2_ZERO_TERMINATED, 0,
+ PCRE2_SUBSTITUTE_GLOBAL | PCRE2_SUBSTITUTE_EXTENDED,
+ 0, match_context, (PCRE2_SPTR)replacement,
+ PCRE2_ZERO_TERMINATED, outbuf, &outlength);
+
+ if (rc < 0) {
+ print_error(rc);
+ return 1;
+ }
+
+ *presult = (char *)outbuf;
+
+ pcre2_match_context_free(match_context);
+ pcre2_code_free(re);
+
+ return 0;
+}
+
int repchr(char *str, char t, char r) {
int c = 0;
for (size_t i = 0; str[i] != '\0'; i++) {
diff --git a/src/utils/utils.h b/src/utils/utils.h
index d7e45dc..f5bf8fc 100644
--- a/src/utils/utils.h
+++ b/src/utils/utils.h
@@ -6,6 +6,9 @@
int regex_match(const char *, str_array_t, str_array_t *);
+int substitute_str(const char *subject, const char *pattern,
+ const char *replacement, char **presult);
+
int repchr(char *str, char t, char r);
void free_and_nullify(void *p);