Complete transition to rtypecheck typemaps from hard coded logic

See 973590ff91.

The rtypecheck typemaps implement typechecking in R for each function
parameter using functions such as is.numeric, is.character, is.logical,
is.null etc.

Closes #2605
This commit is contained in:
William S Fulton 2023-09-11 08:16:02 +01:00
parent a28b8cfed4
commit 64c9720a7a
4 changed files with 13 additions and 50 deletions

View File

@ -7,6 +7,12 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.2.0 (in progress)
===========================
2023-09-11: wsfulton
[R] #2605 Complete transition to rtypecheck typemaps from hard coded
logic. Also see entry dated 2022-10-28 for swig-4.1.1. The rtypecheck
typemaps implement typechecking in R for each function parameter using
functions such as is.numeric, is.character, is.logical, is.null etc.
2023-09-09: wsfulton
https://sourceforge.net/p/swig/bugs/919/

View File

@ -60,8 +60,6 @@
%typemap("rtypecheck") enum SWIGTYPE *
%{ is.character($arg) %}
#if 0
// Replacement rtypecheck typemaps (for swig-4.2, see r.cxx)
%typemap("rtypecheck") SWIGTYPE *
%{ extends($argtype, '$R_class') || is.null($arg) %}
@ -73,7 +71,6 @@
%typemap("rtypecheck") SWIGTYPE
%{ extends($argtype, '$&R_class') && length($arg) == 1 %}
#endif
/*
Set up type checks to insure overloading precedence.

View File

@ -264,7 +264,8 @@
/* please leave 740-749 free for Python */
#define WARN_R_MISSING_RTYPECHECK_TYPEMAP 750
/* Unused since 4.2.0: #define WARN_R_MISSING_RTYPECHECK_TYPEMAP 750 */
#define WARN_R_TYPEMAP_RTYPECHECK_UNDEF 751
/* please leave 750-759 free for R */

View File

@ -1596,27 +1596,24 @@ void R::dispatchFunction(Node *n) {
}
Printv(f->code, "if (", NIL);
for (p = pi, j = 0 ; j < num_arguments ; j++) {
SwigType *pt = Getattr(p, "type");
if (debugMode) {
Swig_print_node(p);
}
String *tm = Swig_typemap_lookup("rtype", p, "", 0);
if (tm) {
replaceRClass(tm, Getattr(p, "type"));
replaceRClass(tm, pt);
}
/* Check if type have a %typemap(rtypecheck) */
String *tmcheck = Getattr(p,"tmap:rtypecheck");
if (tmcheck) {
tmcheck = Copy(tmcheck);
} else {
tmcheck = Swig_typemap_lookup("rtypecheck", p, "", 0);
}
if (tmcheck) {
String *tmp_argtype = NewStringf("argtypes[%d]", j+1);
Replaceall(tmcheck, "$argtype", tmp_argtype);
String *tmp_arg = NewStringf("argv[[%d]]", j+1);
Replaceall(tmcheck, "$arg", tmp_arg);
replaceRClass(tmcheck, Getattr(p, "type"));
replaceRClass(tmcheck, pt);
if (debugMode) {
Printf(stdout, "<rtypecheck>%s\n", tmcheck);
}
@ -1625,49 +1622,11 @@ void R::dispatchFunction(Node *n) {
} else {
Printf(f->code, "%s(%s)", j == 0 ? "" : " && ", tmcheck);
}
p = Getattr(p, "tmap:in:next");
Delete(tmcheck);
Delete(tmp_arg);
Delete(tmp_argtype);
continue;
}
// Below should be migrated into rtypecheck typemaps
// Preparation for this has started by warning in swig-4.1.1 for "numeric", "integer", "character" typemaps
// For swig-4.2: remove the code block below and uncomment typemaps marked 'Replacement rtypecheck typemaps' in rtype.swg.
// There is a slight difference in output as the typemap approach fixes some bugs due to a missing type resolution below
if (tm) {
String *tmcode = NULL;
Printf(f->code, "%s", j == 0 ? "" : " && ");
if (num_arguments != 1)
Printf(f->code, "(");
Printf(f->code, " ");
if (Strcmp(tm, "numeric") == 0) {
tmcode = NewString("is.numeric($arg)");
} else if (Strcmp(tm, "integer") == 0) {
tmcode = NewString("(is.integer($arg) || is.numeric($arg))");
} else if (Strcmp(tm, "character") == 0) {
tmcode = NewString("is.character($arg)");
} else {
if (SwigType_ispointer(Getattr(p, "type")))
Printf(f->code, "extends(argtypes[%d], '%s') || is.null(argv[[%d]])", j+1, tm, j+1);
else
Printf(f->code, "extends(argtypes[%d], '%s') && length(argv[[%d]]) == 1", j+1, tm, j+1);
}
if (tmcode) {
if (!SwigType_ispointer(Getattr(p, "type")))
Printf(tmcode, " && length($arg) == 1");
Swig_warning(WARN_R_MISSING_RTYPECHECK_TYPEMAP, input_file, line_number,
"Optional rtypecheck code is deprecated. Add the following typemap to fix as the next version of SWIG will not work without it: %%typemap(\"rtypecheck\") %s %%{ %s %%}\n",
SwigType_str(Getattr(p, "type"), 0), tmcode);
String *tmp_arg = NewStringf("argv[[%d]]", j+1);
Replaceall(tmcode, "$arg", tmp_arg);
Printv(f->code, tmcode, NIL);
Delete(tmp_arg);
}
Printf(f->code, " ");
if (num_arguments != 1)
Printf(f->code, ")");
Delete(tmcode);
} else {
Swig_warning(WARN_R_TYPEMAP_RTYPECHECK_UNDEF, input_file, line_number, "No rtypecheck typemap defined for %s\n", SwigType_str(pt, 0));
}
p = Getattr(p, "tmap:in:next");
}