diff options
Diffstat (limited to 'src/gmutil.c')
-rw-r--r-- | src/gmutil.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/src/gmutil.c b/src/gmutil.c index ce1b68c7..e59e6649 100644 --- a/src/gmutil.c +++ b/src/gmutil.c | |||
@@ -904,3 +904,41 @@ const iGmError *get_GmError(enum iGmStatusCode code) { | |||
904 | iAssert(errors_[0].code == unknownStatusCode_GmStatusCode); | 904 | iAssert(errors_[0].code == unknownStatusCode_GmStatusCode); |
905 | return &errors_[0].err; /* unknown */ | 905 | return &errors_[0].err; /* unknown */ |
906 | } | 906 | } |
907 | |||
908 | int replaceRegExp_String(iString *d, const iRegExp *regexp, const char *replacement, | ||
909 | void (*matchHandler)(void *, const iRegExpMatch *), | ||
910 | void *context) { | ||
911 | iRegExpMatch m; | ||
912 | iString result; | ||
913 | int numMatches = 0; | ||
914 | const char *pos = constBegin_String(d); | ||
915 | init_RegExpMatch(&m); | ||
916 | init_String(&result); | ||
917 | while (matchString_RegExp(regexp, d, &m)) { | ||
918 | appendRange_String(&result, (iRangecc){ pos, begin_RegExpMatch(&m) }); | ||
919 | /* Replace any capture group back-references. */ | ||
920 | for (const char *ch = replacement; *ch; ch++) { | ||
921 | if (*ch == '\\') { | ||
922 | ch++; | ||
923 | if (*ch == '\\') { | ||
924 | appendCStr_String(&result, "\\"); | ||
925 | } | ||
926 | else if (*ch >= '0' && *ch <= '9') { | ||
927 | appendRange_String(&result, capturedRange_RegExpMatch(&m, *ch - '0')); | ||
928 | } | ||
929 | } | ||
930 | else { | ||
931 | appendData_Block(&result.chars, ch, 1); | ||
932 | } | ||
933 | } | ||
934 | if (matchHandler) { | ||
935 | matchHandler(context, &m); | ||
936 | } | ||
937 | pos = end_RegExpMatch(&m); | ||
938 | numMatches++; | ||
939 | } | ||
940 | appendRange_String(&result, (iRangecc){ pos, constEnd_String(d) }); | ||
941 | set_String(d, &result); | ||
942 | deinit_String(&result); | ||
943 | return numMatches; | ||
944 | } | ||