Add support for case conversion characters in regex substitutions.
Allow using Perl-like \l, \L, \u, \U and \E escape sequences in the
substitution string used with %rename("%(regex:/pattern/subst/)s").
This is useful for e.g. title casing all string after removing some prefix.
Closes #82
This commit is contained in:
parent
669a27bb7b
commit
72afb74f47
7 changed files with 108 additions and 21 deletions
|
|
@ -1180,8 +1180,38 @@ err_out:
|
|||
exit(1);
|
||||
}
|
||||
|
||||
/* This function copies len characters from src to dst, possibly applying case conversions to them: if convertCase is 1, to upper case and if it is -1, to lower
|
||||
* case. If convertNextOnly is 1, only a single character is converted (and convertCase is reset), otherwise all of them are. */
|
||||
static void copy_with_maybe_case_conversion(String *dst, const char *src, int len, int *convertCase, int convertNextOnly)
|
||||
{
|
||||
/* Deal with the trivial cases first. */
|
||||
if (!len)
|
||||
return;
|
||||
|
||||
if (!*convertCase) {
|
||||
Write(dst, src, len);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we must convert only the first character, do it and write the rest at once. */
|
||||
if (convertNextOnly) {
|
||||
Putc(*convertCase == 1 ? toupper(*src) : tolower(*src), dst);
|
||||
*convertCase = 0;
|
||||
if (len > 1) {
|
||||
Write(dst, src + 1, len - 1);
|
||||
}
|
||||
} else {
|
||||
/* We need to convert all characters. */
|
||||
int i;
|
||||
for (i = 0; i < len; i++, src++) {
|
||||
Putc(*convertCase == 1 ? toupper(*src) : tolower(*src), dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String *replace_captures(int num_captures, const char *input, String *subst, int captures[], String *pattern, String *s)
|
||||
{
|
||||
int convertCase = 0, convertNextOnly = 0;
|
||||
String *result = NewStringEmpty();
|
||||
const char *p = Char(subst);
|
||||
|
||||
|
|
@ -1189,10 +1219,10 @@ String *replace_captures(int num_captures, const char *input, String *subst, int
|
|||
/* Copy part without substitutions */
|
||||
const char *q = strchr(p, '\\');
|
||||
if (!q) {
|
||||
Write(result, p, strlen(p));
|
||||
copy_with_maybe_case_conversion(result, p, strlen(p), &convertCase, convertNextOnly);
|
||||
break;
|
||||
}
|
||||
Write(result, p, q - p);
|
||||
copy_with_maybe_case_conversion(result, p, q - p, &convertCase, convertNextOnly);
|
||||
p = q + 1;
|
||||
|
||||
/* Handle substitution */
|
||||
|
|
@ -1203,12 +1233,39 @@ String *replace_captures(int num_captures, const char *input, String *subst, int
|
|||
if (group < num_captures) {
|
||||
int l = captures[group*2], r = captures[group*2 + 1];
|
||||
if (l != -1) {
|
||||
Write(result, input + l, r - l);
|
||||
copy_with_maybe_case_conversion(result, input + l, r - l, &convertCase, convertNextOnly);
|
||||
}
|
||||
} else {
|
||||
Swig_error("SWIG", Getline(s), "PCRE capture replacement failed while matching \"%s\" using \"%s\" - request for group %d is greater than the number of captures %d.\n",
|
||||
Char(pattern), input, group, num_captures-1);
|
||||
}
|
||||
} else {
|
||||
/* Handle Perl-like case conversion escapes. */
|
||||
switch (*p) {
|
||||
case 'u':
|
||||
convertCase = 1;
|
||||
convertNextOnly = 1;
|
||||
break;
|
||||
case 'U':
|
||||
convertCase = 1;
|
||||
convertNextOnly = 0;
|
||||
break;
|
||||
case 'l':
|
||||
convertCase = -1;
|
||||
convertNextOnly = 1;
|
||||
break;
|
||||
case 'L':
|
||||
convertCase = -1;
|
||||
convertNextOnly = 0;
|
||||
break;
|
||||
case 'E':
|
||||
convertCase = 0;
|
||||
break;
|
||||
default:
|
||||
Swig_error("SWIG", Getline(s), "Unrecognized escape character '%c' in the replacement string \"%s\".\n",
|
||||
*p, Char(subst));
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue