The R Project SVN R

Rev

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

Rev 19912 Rev 20110
Line 50... Line 50...
50
/* Convert an R object to a non-moveable C/Fortran object and return
50
/* Convert an R object to a non-moveable C/Fortran object and return
51
   a pointer to it.  This leaves pointers for anything other
51
   a pointer to it.  This leaves pointers for anything other
52
   than vectors and lists unaltered.
52
   than vectors and lists unaltered.
53
*/
53
*/
54
 
54
 
55
static void *RObjToCPtr(SEXP s, int naok, int dup, int narg, int Fort, const char *name, R_toCConverter **converter)
55
static void *RObjToCPtr(SEXP s, int naok, int dup, int narg, int Fort, const char *name, R_toCConverter **converter,
-
 
56
                          int targetType)
56
{
57
{
57
    int *iptr;
58
    int *iptr;
58
    float *sptr;
59
    float *sptr;
59
    double *rptr;
60
    double *rptr;
60
    char **cptr, *fptr;
61
    char **cptr, *fptr;
Line 79... Line 80...
79
	ans = Rf_convertToC(s, &info, &success, converter);
80
	ans = Rf_convertToC(s, &info, &success, converter);
80
	if(success)
81
	if(success)
81
	    return(ans);
82
	    return(ans);
82
    }
83
    }
83
 
84
 
-
 
85
    if(targetType > 0 && targetType != TYPEOF(s)) {
-
 
86
     if(!dup) {
-
 
87
       error("expliciti request not to duplicate arguments in call to %s, but argument %d is of the wrong type", 
-
 
88
	     name, narg + 1);
-
 
89
     } 
-
 
90
 
-
 
91
     if(targetType != SINGLESXP) 
-
 
92
        s = coerceVector(s, targetType);
-
 
93
    }
-
 
94
 
84
    switch(TYPEOF(s)) {
95
    switch(TYPEOF(s)) {
85
    case LGLSXP:
96
    case LGLSXP:
86
    case INTSXP:
97
    case INTSXP:
87
	n = LENGTH(s);
98
	n = LENGTH(s);
88
	iptr = INTEGER(s);
99
	iptr = INTEGER(s);
Line 179... Line 190...
179
	return (void*)s;
190
	return (void*)s;
180
    }
191
    }
181
}
192
}
182
 
193
 
183
 
194
 
184
static SEXP CPtrToRObj(void *p, SEXP arg, int Fort)
195
static SEXP CPtrToRObj(void *p, SEXP arg, int Fort, R_NativePrimitiveArgType type)
185
{
196
{
186
    int *iptr, n=length(arg);
197
    int *iptr, n=length(arg);
187
    float *sptr;
198
    float *sptr;
188
    double *rptr;
199
    double *rptr;
189
    char **cptr, buf[256];
200
    char **cptr, buf[256];
190
    Rcomplex *zptr;
201
    Rcomplex *zptr;
191
    SEXP *lptr, CSingSymbol = install("Csingle");
202
    SEXP *lptr, CSingSymbol = install("Csingle");
192
    int i;
203
    int i;
193
    SEXP s, t;
204
    SEXP s, t;
194
    SEXPTYPE type =TYPEOF(arg);
-
 
195
 
205
 
196
    switch(type) {
206
    switch(type) {
197
    case LGLSXP:
207
    case LGLSXP:
198
    case INTSXP:
208
    case INTSXP:
199
	s = allocVector(type, n);
209
	s = allocVector(type, n);
200
	iptr = (int*)p;
210
	iptr = (int*)p;
201
	for(i=0 ; i<n ; i++) {
211
	for(i=0 ; i<n ; i++) 
202
	    INTEGER(s)[i] = iptr[i];
212
            INTEGER(s)[i] = iptr[i];
203
	}
-
 
204
	break;
213
	break;
205
    case REALSXP:
214
    case REALSXP:
-
 
215
    case SINGLESXP:
206
	s = allocVector(type, n);
216
	s = allocVector(REALSXP, n);
207
	if(asLogical(getAttrib(arg, CSingSymbol)) == 1) {
217
	if(type == SINGLESXP || asLogical(getAttrib(arg, CSingSymbol)) == 1) {
208
	    sptr = (float*) p;
218
	    sptr = (float*) p;
209
	    for(i=0 ; i<n ; i++) REAL(s)[i] = (double) sptr[i];
219
	    for(i=0 ; i<n ; i++) REAL(s)[i] = (double) sptr[i];
210
	} else {
220
	} else {
211
	    rptr = (double*) p;
221
	    rptr = (double*) p;
212
	    for(i=0 ; i<n ; i++) REAL(s)[i] = rptr[i];
222
	    for(i=0 ; i<n ; i++) REAL(s)[i] = rptr[i];
Line 256... Line 266...
256
	s = (SEXP)p;
266
	s = (SEXP)p;
257
    }
267
    }
258
    return s;
268
    return s;
259
}
269
}
260
 
270
 
-
 
271
#ifdef THROW_REGISTRATION_TYPE_ERROR
-
 
272
static Rboolean
-
 
273
comparePrimitiveTypes(R_NativePrimitiveArgType type, SEXP s, Rboolean dup)
-
 
274
{
-
 
275
   if(TYPEOF(s) == type)
-
 
276
      return(TRUE);
-
 
277
 
-
 
278
   if(dup && type == SINGLESXP)
-
 
279
      return(asLogical(getAttrib(s, install("Csingle"))) == TRUE);
-
 
280
 
-
 
281
   return(FALSE);
-
 
282
}
-
 
283
#endif /* end of THROW_REGISTRATION_TYPE_ERROR */
-
 
284
 
261
 
285
 
262
/* Foreign Function Interface.  This code allows a user to call C */
286
/* Foreign Function Interface.  This code allows a user to call C */
263
/* or Fortran code which is either statically or dynamically linked. */
287
/* or Fortran code which is either statically or dynamically linked. */
264
 
288
 
265
/* NB: despite its name, this leaves NAOK and DUP arguments on the list */
289
/* NB: despite its name, this leaves NAOK and DUP arguments on the list */
Line 1179... Line 1203...
1179
{
1203
{
1180
    void **cargs;
1204
    void **cargs;
1181
    int dup, havenames, naok, nargs, which;
1205
    int dup, havenames, naok, nargs, which;
1182
    DL_FUNC fun;
1206
    DL_FUNC fun;
1183
    SEXP ans, pargs, s;
1207
    SEXP ans, pargs, s;
1184
    R_toCConverter  *argConverters[65];
1208
    R_toCConverter  *argConverters[65]; /* the post-call converters back to R objects. */
1185
    R_RegisteredNativeSymbol symbol = {R_C_SYM, {NULL}, NULL};
1209
    R_RegisteredNativeSymbol symbol = {R_C_SYM, {NULL}, NULL};
-
 
1210
    R_NativePrimitiveArgType *checkTypes = NULL;
-
 
1211
    R_NativeArgStyle *argStyles = NULL;
1186
 
1212
 
1187
    char buf[128], *p, *q, *vmax;
1213
    char buf[128], *p, *q, *vmax;
1188
    if (NaokSymbol == NULL || DupSymbol == NULL || PkgSymbol == NULL) {
1214
    if (NaokSymbol == NULL || DupSymbol == NULL || PkgSymbol == NULL) {
1189
	NaokSymbol = install("NAOK");
1215
	NaokSymbol = install("NAOK");
1190
	DupSymbol = install("DUP");
1216
	DupSymbol = install("DUP");
Line 1231... Line 1257...
1231
 
1257
 
1232
    if(symbol.symbol.c && symbol.symbol.c->numArgs > -1) {
1258
    if(symbol.symbol.c && symbol.symbol.c->numArgs > -1) {
1233
	if(symbol.symbol.c->numArgs != nargs)
1259
	if(symbol.symbol.c->numArgs != nargs)
1234
	    error("Incorrect number of arguments (%d), expecting %d for %s", 
1260
	    error("Incorrect number of arguments (%d), expecting %d for %s", 
1235
		  nargs, symbol.symbol.c->numArgs, buf);
1261
		  nargs, symbol.symbol.c->numArgs, buf);
-
 
1262
 
-
 
1263
        checkTypes = symbol.symbol.c->types;
-
 
1264
        argStyles = symbol.symbol.c->styles;
1236
    }
1265
    }
1237
 
1266
 
1238
    /* Convert the arguments for use in foreign */
1267
    /* Convert the arguments for use in foreign */
1239
    /* function calls.  Note that we copy twice */
1268
    /* function calls.  Note that we copy twice */
1240
    /* once here, on the way into the call, and */
1269
    /* once here, on the way into the call, and */
1241
    /* once below on the way out. */
1270
    /* once below on the way out. */
1242
    cargs = (void**)R_alloc(nargs, sizeof(void*));
1271
    cargs = (void**)R_alloc(nargs, sizeof(void*));
1243
    nargs = 0;
1272
    nargs = 0;
1244
    for(pargs = args ; pargs != R_NilValue; pargs = CDR(pargs)) {
1273
    for(pargs = args ; pargs != R_NilValue; pargs = CDR(pargs)) {
-
 
1274
#ifdef THROW_REGISTRATION_TYPE_ERROR
-
 
1275
        if(checkTypes && !comparePrimitiveTypes(checkTypes[nargs], CAR(pargs), dup)) {
-
 
1276
            /* We can loop over all the arguments and report all the erroneous ones,
-
 
1277
               but then we would also want to avoid the conversions.
-
 
1278
               Also, in the future, we may just attempt to coerce the value
-
 
1279
               to the appropriate type. This is why we pass the checkTypes[nargs]
-
 
1280
               value to RObjToCPtr(). We just have to sort out the ability to 
-
 
1281
               return the correct value which is complicated by dup, etc. */
-
 
1282
  	   error("Wrong type for argument %d in call to %s", nargs+1, buf);
-
 
1283
	}
-
 
1284
#endif
1245
	cargs[nargs] = RObjToCPtr(CAR(pargs), naok, dup, nargs + 1, 
1285
	cargs[nargs] = RObjToCPtr(CAR(pargs), naok, dup, nargs + 1, 
1246
				  which, buf, argConverters + nargs);
1286
				  which, buf, argConverters + nargs, 
-
 
1287
				  checkTypes ? checkTypes[nargs] : 0);
1247
	nargs++;
1288
	nargs++;
1248
    }
1289
    }
1249
 
1290
 
1250
 
1291
 
1251
    switch (nargs) {
1292
    switch (nargs) {
Line 1850... Line 1891...
1850
	info.allArgs = args;
1891
	info.allArgs = args;
1851
	info.nargs = nargs;
1892
	info.nargs = nargs;
1852
	info.functionName = buf;
1893
	info.functionName = buf;
1853
	nargs = 0;
1894
	nargs = 0;
1854
	for (pargs = args ; pargs != R_NilValue ; pargs = CDR(pargs)) {
1895
	for (pargs = args ; pargs != R_NilValue ; pargs = CDR(pargs)) {
-
 
1896
	    if(argStyles && argStyles[nargs] == R_ARG_IN) {
-
 
1897
	        PROTECT(s = R_NilValue);
1855
            if(argConverters[nargs]) {
1898
	    } else if(argConverters[nargs]) {
1856
                if(argConverters[nargs]->reverse) {
1899
                if(argConverters[nargs]->reverse) {
1857
		    info.argIndex = nargs;
1900
		    info.argIndex = nargs;
1858
		    s = argConverters[nargs]->reverse(cargs[nargs], CAR(pargs), 
1901
		    s = argConverters[nargs]->reverse(cargs[nargs], CAR(pargs), 
1859
                                                       &info, argConverters[nargs]);
1902
                                                       &info, argConverters[nargs]);
1860
		} else
1903
		} else
1861
		    s = R_NilValue;
1904
		    s = R_NilValue;
1862
		PROTECT(s);
1905
		PROTECT(s);
1863
	    } else {
1906
	    } else {
1864
		PROTECT(s = CPtrToRObj(cargs[nargs], CAR(pargs), which));
1907
		PROTECT(s = CPtrToRObj(cargs[nargs], CAR(pargs), which, 
-
 
1908
				       checkTypes ? checkTypes[nargs] : TYPEOF(CAR(pargs))));
1865
		SET_ATTRIB(s, duplicate(ATTRIB(CAR(pargs))));
1909
		SET_ATTRIB(s, duplicate(ATTRIB(CAR(pargs))));
1866
		SET_OBJECT(s, OBJECT(CAR(pargs)));
1910
		SET_OBJECT(s, OBJECT(CAR(pargs)));
1867
	    }
1911
	    }
1868
	    if (TAG(pargs) != R_NilValue)
1912
	    if (TAG(pargs) != R_NilValue)
1869
		havenames = 1;
1913
		havenames = 1;
Line 1997... Line 2041...
1997
    case INTSXP:
2041
    case INTSXP:
1998
    case REALSXP:
2042
    case REALSXP:
1999
    case CPLXSXP:
2043
    case CPLXSXP:
2000
    case STRSXP:
2044
    case STRSXP:
2001
	if(nres > 0)
2045
	if(nres > 0)
2002
	    results[0] = RObjToCPtr(s, 1, 1, 0, 0, (const char *)NULL, NULL);
2046
	    results[0] = RObjToCPtr(s, 1, 1, 0, 0, (const char *)NULL, NULL, 0);
2003
	break;
2047
	break;
2004
    case VECSXP:
2048
    case VECSXP:
2005
	n = length(s);
2049
	n = length(s);
2006
	if (nres < n) n = nres;
2050
	if (nres < n) n = nres;
2007
	for (i = 0 ; i < n ; i++) {
2051
	for (i = 0 ; i < n ; i++) {
2008
	    results[i] = RObjToCPtr(VECTOR_ELT(s, i), 1, 1, 0, 0, (const char *)NULL, NULL);
2052
	    results[i] = RObjToCPtr(VECTOR_ELT(s, i), 1, 1, 0, 0, (const char *)NULL, NULL, 0);
2009
	}
2053
	}
2010
	break;
2054
	break;
2011
    case LISTSXP:
2055
    case LISTSXP:
2012
	n = length(s);
2056
	n = length(s);
2013
	if(nres < n) n = nres;
2057
	if(nres < n) n = nres;
2014
	for(i=0 ; i<n ; i++) {
2058
	for(i=0 ; i<n ; i++) {
2015
	    results[i] = RObjToCPtr(s, 1, 1, 0, 0, (const char *)NULL, NULL);
2059
	    results[i] = RObjToCPtr(s, 1, 1, 0, 0, (const char *)NULL, NULL, 0);
2016
	    s = CDR(s);
2060
	    s = CDR(s);
2017
	}
2061
	}
2018
	break;
2062
	break;
2019
    }
2063
    }
2020
    UNPROTECT(2);
2064
    UNPROTECT(2);