The R Project SVN R

Rev

Rev 14107 | Rev 14571 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 14107 Rev 14156
Line 27... Line 27...
27
 
27
 
28
#include <Defn.h>
28
#include <Defn.h>
29
#include <Rmath.h>
29
#include <Rmath.h>
30
#include <Rdevices.h>
30
#include <Rdevices.h>
31
 
31
 
-
 
32
#include <R_ext/RConverters.h>
-
 
33
 
32
#ifndef max
34
#ifndef max
33
#define max(a, b) ((a > b)?(a):(b))
35
#define max(a, b) ((a > b)?(a):(b))
34
#endif
36
#endif
35
 
37
 
36
 
38
 
Line 40... Line 42...
40
static SEXP DupSymbol = NULL;
42
static SEXP DupSymbol = NULL;
41
static SEXP PkgSymbol = NULL;
43
static SEXP PkgSymbol = NULL;
42
 
44
 
43
static char DLLname[PATH_MAX];
45
static char DLLname[PATH_MAX];
44
 
46
 
45
/* This is a per-platform function which looks up */
-
 
46
/* entry points in DLLs in a platform specific way. */
47
/* This looks up entry points in DLLs in a platform specific way. */
47
 
-
 
48
DL_FUNC R_FindSymbol(char const *, char const *);
48
DL_FUNC R_FindSymbol(char const *, char const *);
49
 
49
 
50
 
50
 
51
/* Convert an R object to a non-moveable C/Fortran object and return
51
/* Convert an R object to a non-moveable C/Fortran object and return
52
   a pointer to it.  This leaves pointers for anything other
52
   a pointer to it.  This leaves pointers for anything other
53
   than vectors and lists unaltered.
53
   than vectors and lists unaltered.
54
*/
54
*/
55
 
55
 
56
static void *RObjToCPtr(SEXP s, int naok, int dup, int narg, int Fort)
56
static void *RObjToCPtr(SEXP s, int naok, int dup, int narg, int Fort, const char *name, R_toCConverter **converter)
57
{
57
{
58
    int *iptr;
58
    int *iptr;
59
    float *sptr;
59
    float *sptr;
60
    double *rptr;
60
    double *rptr;
61
    char **cptr, *fptr;
61
    char **cptr, *fptr;
62
    Rcomplex *zptr;
62
    Rcomplex *zptr;
63
    SEXP *lptr, CSingSymbol=install("Csingle");
63
    SEXP *lptr, CSingSymbol=install("Csingle");
64
    int i, l, n;
64
    int i, l, n;
65
 
65
 
-
 
66
    if(converter)
-
 
67
	*converter = NULL;
-
 
68
 
-
 
69
    if(length(getAttrib(s, R_ClassSymbol))) {
-
 
70
	R_CConvertInfo info;
-
 
71
	int success;
-
 
72
        void *ans;
-
 
73
 
-
 
74
	info.naok = naok;
-
 
75
	info.dup = dup;
-
 
76
	info.narg = narg;
-
 
77
	info.Fort = Fort;
-
 
78
        info.name = name;
-
 
79
 
-
 
80
	ans = Rf_convertToC(s, &info, &success, converter);
-
 
81
	if(success)
-
 
82
	    return(ans);
-
 
83
    }
-
 
84
 
66
    switch(TYPEOF(s)) {
85
    switch(TYPEOF(s)) {
67
    case LGLSXP:
86
    case LGLSXP:
68
    case INTSXP:
87
    case INTSXP:
69
	n = LENGTH(s);
88
	n = LENGTH(s);
70
	iptr = INTEGER(s);
89
	iptr = INTEGER(s);
Line 135... Line 154...
135
	    return (void*)cptr;
154
	    return (void*)cptr;
136
	}
155
	}
137
	break;
156
	break;
138
    case VECSXP:
157
    case VECSXP:
139
	if (!dup) return (void*)VECTOR_PTR(s); /***** Dangerous to GC!!! */
158
	if (!dup) return (void*)VECTOR_PTR(s); /***** Dangerous to GC!!! */
140
	n = length(s);
159
  	n = length(s);
141
	lptr = (SEXP*)R_alloc(n, sizeof(SEXP));
160
	lptr = (SEXP*)R_alloc(n, sizeof(SEXP));
142
	for (i = 0 ; i < n ; i++) {
161
	for (i = 0 ; i < n ; i++) {
143
	    lptr[i] = VECTOR_ELT(s, i);
162
	    lptr[i] = VECTOR_ELT(s, i);
144
	}
163
	}
145
	return (void*)lptr;
164
 	return (void*)lptr;
146
	break;
165
	break;
147
    case LISTSXP:
166
    case LISTSXP:
148
	if(Fort) error("invalid mode to pass to Fortran (arg %d)", narg);
167
	if(Fort) error("invalid mode to pass to Fortran (arg %d)", narg);
149
	/* Warning : The following looks like it could bite ... */
168
	/* Warning : The following looks like it could bite ... */
150
	if(!dup) return (void*)s;
169
	if(!dup) return (void*)s;
Line 160... Line 179...
160
	if(Fort) error("invalid mode to pass to Fortran (arg %d)", narg);
179
	if(Fort) error("invalid mode to pass to Fortran (arg %d)", narg);
161
	return (void*)s;
180
	return (void*)s;
162
    }
181
    }
163
}
182
}
164
 
183
 
-
 
184
 
165
static SEXP CPtrToRObj(void *p, SEXP arg, int Fort)
185
static SEXP CPtrToRObj(void *p, SEXP arg, int Fort)
166
{
186
{
167
    int *iptr, n=length(arg);
187
    int *iptr, n=length(arg);
168
    float *sptr;
188
    float *sptr;
169
    double *rptr;
189
    double *rptr;
Line 313... Line 333...
313
    }
333
    }
314
    *len = nargs;
334
    *len = nargs;
315
    return args;
335
    return args;
316
}
336
}
317
 
337
 
318
static void setDLLname(SEXP s) {
338
static void setDLLname(SEXP s, char *DLLName) {
319
  SEXP ss = CAR(s); char *name;
339
  SEXP ss = CAR(s); char *name;
320
  if(TYPEOF(ss) != STRSXP || length(ss) != 1)
340
  if(TYPEOF(ss) != STRSXP || length(ss) != 1)
321
    error("PACKAGE argument must be a single character string");
341
    error("PACKAGE argument must be a single character string");
322
  name = CHAR(STRING_ELT(ss, 0));
342
  name = CHAR(STRING_ELT(ss, 0));
323
  /* allow the package: form of the name, as returned by find */
343
  /* allow the package: form of the name, as returned by find */
Line 336... Line 356...
336
	/* Look for PACKAGE=. We look at the next arg, unless
356
	/* Look for PACKAGE=. We look at the next arg, unless
337
	   this is the last one (which will only happen for one arg),
357
	   this is the last one (which will only happen for one arg),
338
	   and remove it */
358
	   and remove it */
339
	if(ss == R_NilValue && TAG(s) == PkgSymbol) {
359
	if(ss == R_NilValue && TAG(s) == PkgSymbol) {
340
	    if(pkgused++ == 1) warning("PACKAGE used more than once");
360
	    if(pkgused++ == 1) warning("PACKAGE used more than once");
341
	    setDLLname(s);
361
	    setDLLname(s, DLLname);
342
	    return R_NilValue;
362
	    return R_NilValue;
343
	}
363
	}
344
	if(TAG(ss) == PkgSymbol) {
364
	if(TAG(ss) == PkgSymbol) {
345
	    if(pkgused++ == 1) warning("PACKAGE used more than once");
365
	    if(pkgused++ == 1) warning("PACKAGE used more than once");
346
	    setDLLname(ss);
366
	    setDLLname(ss, DLLname);
347
	    SETCDR(s, CDR(ss));
367
	    SETCDR(s, CDR(ss));
348
	}
368
	}
349
	s = CDR(s);
369
	s = CDR(s);
350
    }
370
    }
351
    return args;
371
    return args;
Line 1133... Line 1153...
1133
{
1153
{
1134
    void **cargs;
1154
    void **cargs;
1135
    int dup, havenames, naok, nargs, which;
1155
    int dup, havenames, naok, nargs, which;
1136
    DL_FUNC fun;
1156
    DL_FUNC fun;
1137
    SEXP ans, pargs, s;
1157
    SEXP ans, pargs, s;
-
 
1158
    R_toCConverter  *argConverters[65];
1138
    char buf[128], *p, *q, *vmax;
1159
    char buf[128], *p, *q, *vmax;
1139
    if (NaokSymbol == NULL || DupSymbol == NULL || PkgSymbol == NULL) {
1160
    if (NaokSymbol == NULL || DupSymbol == NULL || PkgSymbol == NULL) {
1140
	NaokSymbol = install("NAOK");
1161
	NaokSymbol = install("NAOK");
1141
	DupSymbol = install("DUP");
1162
	DupSymbol = install("DUP");
1142
	PkgSymbol = install("PACKAGE");
1163
	PkgSymbol = install("PACKAGE");
Line 1157... Line 1178...
1157
	errorcall(call, "invalid naok value");
1178
	errorcall(call, "invalid naok value");
1158
    if(nargs > MAX_ARGS)
1179
    if(nargs > MAX_ARGS)
1159
	errorcall(call, "too many arguments in foreign function call");
1180
	errorcall(call, "too many arguments in foreign function call");
1160
    cargs = (void**)R_alloc(nargs, sizeof(void*));
1181
    cargs = (void**)R_alloc(nargs, sizeof(void*));
1161
 
1182
 
1162
    /* Convert the arguments for use in foreign */
-
 
1163
    /* function calls.  Note that we copy twice */
-
 
1164
    /* once here, on the way into the call, and */
-
 
1165
    /* once below on the way out. */
-
 
1166
 
-
 
1167
    nargs = 0;
-
 
1168
    for(pargs = args ; pargs != R_NilValue; pargs = CDR(pargs)) {
-
 
1169
	cargs[nargs] = RObjToCPtr(CAR(pargs), naok, dup, nargs + 1, which);
-
 
1170
	nargs++;
-
 
1171
    }
-
 
1172
 
1183
 
1173
    /* Make up the load symbol and look it up. */
1184
    /* Make up the load symbol and look it up. */
1174
 
1185
 
1175
    p = CHAR(STRING_ELT(op, 0));
1186
    p = CHAR(STRING_ELT(op, 0));
1176
    q = buf;
1187
    q = buf;
Line 1188... Line 1199...
1188
#else
1199
#else
1189
    if (!(fun = R_FindSymbol(buf, DLLname)))
1200
    if (!(fun = R_FindSymbol(buf, DLLname)))
1190
#endif /* Macintosh */
1201
#endif /* Macintosh */
1191
	errorcall(call, "C/Fortran function name not in load table");
1202
	errorcall(call, "C/Fortran function name not in load table");
1192
 
1203
 
-
 
1204
 
-
 
1205
    /* Convert the arguments for use in foreign */
-
 
1206
    /* function calls.  Note that we copy twice */
-
 
1207
    /* once here, on the way into the call, and */
-
 
1208
    /* once below on the way out. */
-
 
1209
 
-
 
1210
    nargs = 0;
-
 
1211
    for(pargs = args ; pargs != R_NilValue; pargs = CDR(pargs)) {
-
 
1212
	cargs[nargs] = RObjToCPtr(CAR(pargs), naok, dup, nargs + 1, which, buf, argConverters + nargs);
-
 
1213
	nargs++;
-
 
1214
    }
-
 
1215
 
-
 
1216
 
1193
    switch (nargs) {
1217
    switch (nargs) {
1194
    case 0:
1218
    case 0:
1195
	/* Silicon graphics C chokes here */
1219
	/* Silicon graphics C chokes here */
1196
	/* if there is no argument to fun. */
1220
	/* if there is no argument to fun. */
1197
	fun(0);
1221
	fun(0);
Line 1785... Line 1809...
1785
	errorcall(call, "too many arguments, sorry");
1809
	errorcall(call, "too many arguments, sorry");
1786
    }
1810
    }
1787
    PROTECT(ans = allocVector(VECSXP, nargs));
1811
    PROTECT(ans = allocVector(VECSXP, nargs));
1788
    havenames = 0;
1812
    havenames = 0;
1789
    if (dup) {
1813
    if (dup) {
-
 
1814
	R_FromCConvertInfo info;
-
 
1815
	info.cargs = cargs;
-
 
1816
	info.allArgs = args;
-
 
1817
	info.nargs = nargs;
-
 
1818
	info.functionName = buf;
1790
	nargs = 0;
1819
	nargs = 0;
1791
	for (pargs = args ; pargs != R_NilValue ; pargs = CDR(pargs)) {
1820
	for (pargs = args ; pargs != R_NilValue ; pargs = CDR(pargs)) {
-
 
1821
            if(argConverters[nargs]) {
-
 
1822
                if(argConverters[nargs]->reverse) {
-
 
1823
		    info.argIndex = nargs;
-
 
1824
		    s = argConverters[nargs]->reverse(cargs[nargs], CAR(pargs), 
-
 
1825
                                                       &info, argConverters[nargs]);
-
 
1826
		} else
-
 
1827
		    s = R_NilValue;
-
 
1828
		PROTECT(s);
-
 
1829
	    } else {
1792
	    PROTECT(s = CPtrToRObj(cargs[nargs], CAR(pargs), which));
1830
		PROTECT(s = CPtrToRObj(cargs[nargs], CAR(pargs), which));
1793
	    SET_ATTRIB(s, duplicate(ATTRIB(CAR(pargs))));
1831
		SET_ATTRIB(s, duplicate(ATTRIB(CAR(pargs))));
1794
	    SET_OBJECT(s, OBJECT(CAR(pargs)));
1832
		SET_OBJECT(s, OBJECT(CAR(pargs)));
-
 
1833
	    }
1795
	    if (TAG(pargs) != R_NilValue)
1834
	    if (TAG(pargs) != R_NilValue)
1796
		havenames = 1;
1835
		havenames = 1;
1797
	    SET_VECTOR_ELT(ans, nargs, s);
1836
	    SET_VECTOR_ELT(ans, nargs, s);
1798
	    nargs++;
1837
	    nargs++;
1799
	    UNPROTECT(1);
1838
	    UNPROTECT(1);
Line 1924... Line 1963...
1924
    case INTSXP:
1963
    case INTSXP:
1925
    case REALSXP:
1964
    case REALSXP:
1926
    case CPLXSXP:
1965
    case CPLXSXP:
1927
    case STRSXP:
1966
    case STRSXP:
1928
	if(nres > 0)
1967
	if(nres > 0)
1929
	    results[0] = RObjToCPtr(s, 1, 1, 0, 0);
1968
	    results[0] = RObjToCPtr(s, 1, 1, 0, 0, (const char *)NULL, NULL);
1930
	break;
1969
	break;
1931
    case VECSXP:
1970
    case VECSXP:
1932
	n = length(s);
1971
	n = length(s);
1933
	if (nres < n) n = nres;
1972
	if (nres < n) n = nres;
1934
	for (i = 0 ; i < n ; i++) {
1973
	for (i = 0 ; i < n ; i++) {
1935
	    results[i] = RObjToCPtr(VECTOR_ELT(s, i), 1, 1, 0, 0);
1974
	    results[i] = RObjToCPtr(VECTOR_ELT(s, i), 1, 1, 0, 0, (const char *)NULL, NULL);
1936
	}
1975
	}
1937
	break;
1976
	break;
1938
    case LISTSXP:
1977
    case LISTSXP:
1939
	n = length(s);
1978
	n = length(s);
1940
	if(nres < n) n = nres;
1979
	if(nres < n) n = nres;
1941
	for(i=0 ; i<n ; i++) {
1980
	for(i=0 ; i<n ; i++) {
1942
	    results[i] = RObjToCPtr(s, 1, 1, 0, 0);
1981
	    results[i] = RObjToCPtr(s, 1, 1, 0, 0, (const char *)NULL, NULL);
1943
	    s = CDR(s);
1982
	    s = CDR(s);
1944
	}
1983
	}
1945
	break;
1984
	break;
1946
    }
1985
    }
1947
    UNPROTECT(2);
1986
    UNPROTECT(2);