diff --git a/include/the_Foundation/string.h b/include/the_Foundation/string.h

index e158fe2..a09cf1c 100644

--- a/include/the_Foundation/string.h

+++ b/include/the_Foundation/string.h

@@ -85,6 +85,10 @@ iDeclareType(StringList)

iDeclareType(StringComparison)

iDeclareType(MultibyteChar)

iDeclareType(Stream)

+#if defined (iHaveRegExp)

+ iDeclareType(RegExp)

+ iDeclareType(RegExpMatch)

+#endif



struct Impl_StringComparison {

 int     (*cmp)      (const char *, const char *);

@@ -264,6 +268,28 @@ iString * trimmed_String (const iString *);

void replace_String (iString *, const char *src, const char *dst);

void normalize_String (iString ); / NFC */



+#if defined (iHaveRegExp)

+/**

+ * Replace all matches of a regular expression in the string.

+ *

+ * @param regexp Regular expression to search for.

+ * @param replacement String to substitute at each match. Use the \1 syntax to refer

+ * to a capture group. \0 refers to the entire match.

+ * Backslashes must be escaped: \\. Must not be NULL.

+ * @param matchHandler In addition to replacing with @a replacement, call this callback

+ * for each match. Do not modify the String in the callback.

+ * Can be NULL.

+ * @param context User-provided pointer to pass as the first argument of

+ * @a matchHandler

+ *

+ * @return Number of replaced matches.

+ */

+int replaceRegExp_String (iString *, const iRegExp *regexp,

+ const char *replacement,

+ void (*matchHandler)(void *, const iRegExpMatch *),

+ void *context);

+#endif

+

int toInt_String (const iString *);

float toFloat_String (const iString *);

double toDouble_String (const iString *);

diff --git a/src/string.c b/src/string.c

index fc7a377..7db513e 100644

--- a/src/string.c

+++ b/src/string.c

@@ -30,6 +30,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "the_Foundation/range.h"

#include "the_Foundation/stdthreads.h"



+#if defined (iHaveRegExp)

+# include "the_Foundation/regexp.h"

+#endif

+

#include <stdlib.h>

#include <stdarg.h>

#include <strings.h>

@@ -374,6 +378,46 @@ void replace_String(iString *d, const char *src, const char *dst) {

 }

}



+#if defined (iHaveRegExp)

+int replaceRegExp_String(iString *d, const iRegExp *regexp, const char *replacement,

+ void (*matchHandler)(void *, const iRegExpMatch *),

+ void *context) {

+ iRegExpMatch m;

+ iString result;

+ int numMatches = 0;

+ const char *pos = constBegin_String(d);

+ init_RegExpMatch(&m);

+ init_String(&result);

+ while (matchString_RegExp(regexp, d, &m)) {

+ appendRange_String(&result, (iRangecc){ pos, begin_RegExpMatch(&m) });

+ /* Replace any capture group back-references. */

+ for (const char *ch = replacement; *ch; ch++) {

+ if (*ch == '\') {

+ ch++;

+ if (*ch == '\') {

+ appendCStr_String(&result, "\");

+ }

+ else if (*ch >= '0' && *ch <= '9') {

+ appendRange_String(&result, capturedRange_RegExpMatch(&m, *ch - '0'));

+ }

+ }

+ else {

+ appendData_Block(&result.chars, ch, 1);

+ }

+ }

+ if (matchHandler) {

+ matchHandler(context, &m);

+ }

+ pos = end_RegExpMatch(&m);

+ numMatches++;

+ }

+ appendRange_String(&result, (iRangecc){ pos, constEnd_String(d) });

+ set_String(d, &result);

+ deinit_String(&result);

+ return numMatches;

+}

+#endif

+

void normalize_String(iString *d) {

 size_t len = 0;

 uint8_t *nfc =

@@ -498,7 +542,7 @@ iString *urlEncode_String(const iString *d) {

}



iString *maybeUrlEncodeExclude_String(const iString *d, const char *excluded) {

- /* TODO: Return NULL if nothing to encode. */ 

+ /* TODO: Return NULL if nothing to encode. */

 iString *encoded = new_String();

 /* Note: Any UTF-8 code points are encoded as multiple %NN sequences. */

 for (const char *i = constBegin_String(d), *end = constEnd_String(d); i != end; ++i) {

@@ -514,7 +558,7 @@ iString *maybeUrlEncodeExclude_String(const iString *d, const char *excluded) {

         appendCStrN_String(encoded, escaped, 3);

     }

 }

- return encoded; 

+ return encoded;

}



static int fromHex_(char ch) {

@@ -547,7 +591,7 @@ iString *maybeUrlDecodeExclude_String(const iString *d, const char *excluded) {

     }

     appendData_Block(&decoded->chars, i, 1);

 }

- return decoded; 

+ return decoded;

}



iString *urlDecodeExclude_String(const iString *d, const char *excluded) {

Proxy Information
Original URL
gemini://git.skyjake.fi/the_Foundation/master/pcdiff/11e7a3bdbb4b40ea4417518dac9eba7ad55748d3
Status Code
Success (20)
Meta
text/plain
Capsule Response Time
31.644316 milliseconds
Gemini-to-HTML Time
2.877591 milliseconds

This content has been proxied by September (3851b).