diff options
Diffstat (limited to 'src/gmutil.c')
-rw-r--r-- | src/gmutil.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/gmutil.c b/src/gmutil.c index 98e4d4d6..e59e6649 100644 --- a/src/gmutil.c +++ b/src/gmutil.c | |||
@@ -131,6 +131,16 @@ static iRangecc prevPathSeg_(const char *end, const char *start) { | |||
131 | return seg; | 131 | return seg; |
132 | } | 132 | } |
133 | 133 | ||
134 | void stripUrlPort_String(iString *d) { | ||
135 | iUrl parts; | ||
136 | init_Url(&parts, d); | ||
137 | if (!isEmpty_Range(&parts.port)) { | ||
138 | /* Always preceded by a colon. */ | ||
139 | remove_Block(&d->chars, parts.port.start - 1 - constBegin_String(d), | ||
140 | size_Range(&parts.port) + 1); | ||
141 | } | ||
142 | } | ||
143 | |||
134 | void stripDefaultUrlPort_String(iString *d) { | 144 | void stripDefaultUrlPort_String(iString *d) { |
135 | iUrl parts; | 145 | iUrl parts; |
136 | init_Url(&parts, d); | 146 | init_Url(&parts, d); |
@@ -248,6 +258,9 @@ iRangecc urlRoot_String(const iString *d) { | |||
248 | else { | 258 | else { |
249 | iUrl parts; | 259 | iUrl parts; |
250 | init_Url(&parts, d); | 260 | init_Url(&parts, d); |
261 | if (equalCase_Rangecc(parts.scheme, "about")) { | ||
262 | return (iRangecc){ constBegin_String(d), parts.path.start }; | ||
263 | } | ||
251 | rootEnd = parts.path.start; | 264 | rootEnd = parts.path.start; |
252 | } | 265 | } |
253 | return (iRangecc){ constBegin_String(d), rootEnd }; | 266 | return (iRangecc){ constBegin_String(d), rootEnd }; |
@@ -681,6 +694,17 @@ const iString *withSpacesEncoded_String(const iString *d) { | |||
681 | return d; | 694 | return d; |
682 | } | 695 | } |
683 | 696 | ||
697 | const iString *withScheme_String(const iString *d, const char *scheme) { | ||
698 | iUrl parts; | ||
699 | init_Url(&parts, d); | ||
700 | if (!equalCase_Rangecc(parts.scheme, scheme)) { | ||
701 | iString *repl = collectNewCStr_String(scheme); | ||
702 | appendRange_String(repl, (iRangecc){ parts.scheme.end, constEnd_String(d) }); | ||
703 | return repl; | ||
704 | } | ||
705 | return d; | ||
706 | } | ||
707 | |||
684 | const iString *canonicalUrl_String(const iString *d) { | 708 | const iString *canonicalUrl_String(const iString *d) { |
685 | /* The "canonical" form, used for internal storage and comparisons, is: | 709 | /* The "canonical" form, used for internal storage and comparisons, is: |
686 | - all non-reserved characters decoded (i.e., it's an IRI) | 710 | - all non-reserved characters decoded (i.e., it's an IRI) |
@@ -880,3 +904,41 @@ const iGmError *get_GmError(enum iGmStatusCode code) { | |||
880 | iAssert(errors_[0].code == unknownStatusCode_GmStatusCode); | 904 | iAssert(errors_[0].code == unknownStatusCode_GmStatusCode); |
881 | return &errors_[0].err; /* unknown */ | 905 | return &errors_[0].err; /* unknown */ |
882 | } | 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 | } | ||