Add support for regex encoder for %rename.

This allows to write %rename("%(regex:/pattern/subst/)s") to apply a
regex-based replacement to a declaration name.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12170 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Vadim Zeitlin 2010-07-22 17:00:37 +00:00
commit c4e9043288
3 changed files with 130 additions and 0 deletions

View file

@ -9,6 +9,18 @@ Version 2.0.1 (in progress)
Fix wrapping of function pointers and member function pointers when the function
returns by reference.
2010-07-13: vadz
Add the new "regex" encoder that can be used in %rename, e.g.
%rename("regex:/(\\w+)_(.*)/\\2/") "";
to remove any alphabetical prefix from all identifiers. The syntax
of the regular expressions is Perl-like and PCRE library
(http://www.pcre.org/) is used to implement this feature but notice
that backslashes need to be escaped as usual inside C strings.
Original patch from Torsten Landschoff.
2010-07-08: wsfulton
Fix #3024875 - shared_ptr of classes with non-public destructors. This also fixes
the "unref" feature when used on classes with non-public destructors.

View file

@ -1871,6 +1871,18 @@ and a more descriptive one, but the two functions are otherwise equivalent):
literally, e.g. <tt>%rename("strip:[wx]")</tt></td>
<td><tt>wxPrint</tt></td><td><tt>Print</tt></td>
</tr>
<tr>
<td><span style="white-space: nowrap;"><tt>regex:/pattern/subst/</tt></span</td>
<td>String after (Perl-like) regex substitution operation. This function
allows to apply arbitrary regular expressions to the identifier names. The
<i>pattern</i> part is a regular expression in Perl syntax (as supported
by <a href="http://www.pcre.org/">PCRE</a>) and the <i>subst</i> string
can contain back-references introduced by <tt>'\'</tt> or, as backslashes need
to be escaped in C strings, rather by <tt>"\\"</tt>. For example, to remove
any alphabetic prefix before an underscore you could use the following directive:
<tt>%rename("regex:/(\\w+)_(.*)/\\2/")</tt></td>
<td><tt>Prefix_Print</tt></td><td><tt>Print</tt></td>
</tr>
<tr>
<td><tt>command:cmd</tt></td>
<td>Output of an external command <tt>cmd</tt> with the string passed to

View file

@ -1214,6 +1214,111 @@ String *Swig_string_rxspencer(String *s) {
}
#endif
#ifdef HAVE_PCRE
#include <pcre.h>
static int split_regex_pattern_subst(String *s, String **pattern, String **subst, const char **input)
{
const char *pats, *pate;
const char *subs, *sube;
/* Locate the search pattern */
const char *p = Char(s);
if (*p++ != '/') goto err_out;
pats = p;
p = strchr(p, '/');
if (!p) goto err_out;
pate = p;
/* Locate the substitution string */
subs = ++p;
p = strchr(p, '/');
if (!p) goto err_out;
sube = p;
*pattern = NewStringWithSize(pats, pate - pats);
*subst = NewStringWithSize(subs, sube - subs);
*input = p + 1;
return 1;
err_out:
Swig_error("SWIG", Getline(s), "Invalid regex substitution: '%s'.\n", s);
exit(1);
}
String *replace_captures(const char *input, String *subst, int captures[])
{
String *result = NewStringEmpty();
const char *p = Char(subst);
while (*p) {
/* Copy part without substitutions */
const char *q = strchr(p, '\\');
if (!q) {
Write(result, p, strlen(p));
break;
}
Write(result, p, q - p);
p = q + 1;
/* Handle substitution */
if (*p == '\0') {
Putc('\\', result);
} else if (isdigit(*p)) {
int group = *p++ - '0';
int l = captures[group*2], r = captures[group*2 + 1];
if (l != -1) {
Write(result, input + l, r - l);
}
}
}
return result;
}
/* -----------------------------------------------------------------------------
* Swig_string_regex()
*
* Executes a regexp substitution. For example:
*
* Printf(stderr,"gsl%(regex:/GSL_.*_/\\1/)s","GSL_Hello_") -> gslHello
* ----------------------------------------------------------------------------- */
String *Swig_string_regex(String *s) {
const int pcre_options = 0;
String *res = 0;
pcre *compiled_pat = 0;
const char *pcre_error, *input;
int pcre_errorpos;
String *pattern = 0, *subst = 0;
int captures[30];
if (split_regex_pattern_subst(s, &pattern, &subst, &input)) {
compiled_pat = pcre_compile(
Char(pattern), pcre_options, &pcre_error, &pcre_errorpos, NULL);
if (!compiled_pat) {
Swig_error("SWIG", Getline(s), "PCRE compilation failed: '%s' in '%s':%i.\n",
pcre_error, Char(pattern), pcre_errorpos);
exit(1);
}
pcre_exec(compiled_pat, NULL, input, strlen(input), 0, 0, captures, 30);
res = replace_captures(input, subst, captures);
}
DohDelete(pattern);
DohDelete(subst);
pcre_free(compiled_pat);
return res ? res : NewStringEmpty();
}
#else
String *Swig_string_regex(String *s) {
Swig_error("SWIG", Getline(s), "PCRE regex support not enabled in this SWIG build.\n");
exit(1);
}
#endif
/* -----------------------------------------------------------------------------
* Swig_init()
@ -1236,6 +1341,7 @@ void Swig_init() {
DohEncoding("rxspencer", Swig_string_rxspencer);
DohEncoding("schemify", Swig_string_schemify);
DohEncoding("strip", Swig_string_strip);
DohEncoding("regex", Swig_string_regex);
/* aliases for the case encoders */
DohEncoding("uppercase", Swig_string_upper);