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 Fix wrapping of function pointers and member function pointers when the function
returns by reference. 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 2010-07-08: wsfulton
Fix #3024875 - shared_ptr of classes with non-public destructors. This also fixes Fix #3024875 - shared_ptr of classes with non-public destructors. This also fixes
the "unref" feature when used on classes with non-public destructors. 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> literally, e.g. <tt>%rename("strip:[wx]")</tt></td>
<td><tt>wxPrint</tt></td><td><tt>Print</tt></td> <td><tt>wxPrint</tt></td><td><tt>Print</tt></td>
</tr> </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> <tr>
<td><tt>command:cmd</tt></td> <td><tt>command:cmd</tt></td>
<td>Output of an external command <tt>cmd</tt> with the string passed to <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 #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() * Swig_init()
@ -1236,6 +1341,7 @@ void Swig_init() {
DohEncoding("rxspencer", Swig_string_rxspencer); DohEncoding("rxspencer", Swig_string_rxspencer);
DohEncoding("schemify", Swig_string_schemify); DohEncoding("schemify", Swig_string_schemify);
DohEncoding("strip", Swig_string_strip); DohEncoding("strip", Swig_string_strip);
DohEncoding("regex", Swig_string_regex);
/* aliases for the case encoders */ /* aliases for the case encoders */
DohEncoding("uppercase", Swig_string_upper); DohEncoding("uppercase", Swig_string_upper);