The R Project SVN R

Rev

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

Rev 5769 Rev 6098
Line 36... Line 36...
36
 
36
 
37
/* These are set during each call to do_dotCode() below. */
37
/* These are set during each call to do_dotCode() below. */
38
 
38
 
39
static SEXP NaokSymbol = NULL;
39
static SEXP NaokSymbol = NULL;
40
static SEXP DupSymbol = NULL;
40
static SEXP DupSymbol = NULL;
-
 
41
static SEXP PkgSymbol = NULL;
-
 
42
 
-
 
43
static char DLLname[PATH_MAX];
41
 
44
 
42
/* This is a per-platform function which looks up */
45
/* This is a per-platform function which looks up */
43
/* entry points in DLLs in a platform specific way. */
46
/* entry points in DLLs in a platform specific way. */
44
 
47
 
45
DL_FUNC R_FindSymbol(char *);
48
DL_FUNC R_FindSymbol(char const *, char const *);
46
 
49
 
47
 
50
 
48
/* 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
49
   a pointer to it.  This leaves pointers for anything other
52
   a pointer to it.  This leaves pointers for anything other
50
   than vectors and lists unaltered. 
53
   than vectors and lists unaltered.
51
*/
54
*/
52
 
55
 
53
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)
54
{
57
{
55
    int *iptr;
58
    int *iptr;
Line 57... Line 60...
57
    double *rptr;
60
    double *rptr;
58
    char **cptr, *fptr;
61
    char **cptr, *fptr;
59
    complex *zptr;
62
    complex *zptr;
60
    SEXP *lptr, CSingSymbol=install("Csingle");
63
    SEXP *lptr, CSingSymbol=install("Csingle");
61
    int i, l, n;
64
    int i, l, n;
62
    
65
 
63
    switch(TYPEOF(s)) {
66
    switch(TYPEOF(s)) {
64
    case LGLSXP:
67
    case LGLSXP:
65
    case INTSXP:
68
    case INTSXP:
66
	n = LENGTH(s);
69
	n = LENGTH(s);
67
	iptr = INTEGER(s);
70
	iptr = INTEGER(s);
Line 168... Line 171...
168
    complex *zptr;
171
    complex *zptr;
169
    SEXP *lptr, CSingSymbol = install("Csingle");
172
    SEXP *lptr, CSingSymbol = install("Csingle");
170
    int i;
173
    int i;
171
    SEXP s, t;
174
    SEXP s, t;
172
    SEXPTYPE type =TYPEOF(arg);
175
    SEXPTYPE type =TYPEOF(arg);
173
    
176
 
174
    switch(type) {
177
    switch(type) {
175
    case LGLSXP:
178
    case LGLSXP:
176
    case INTSXP:
179
    case INTSXP:
177
	s = allocVector(type, n);
180
	s = allocVector(type, n);
178
	iptr = (int*)p;
181
	iptr = (int*)p;
Line 238... Line 241...
238
 
241
 
239
 
242
 
240
/* Foreign Function Interface.  This code allows a user to call C */
243
/* Foreign Function Interface.  This code allows a user to call C */
241
/* or Fortran code which is either statically or dynamically linked. */
244
/* or Fortran code which is either statically or dynamically linked. */
242
 
245
 
-
 
246
/* NB: despite its name, this leaves NAOK and DUP arguments on the list */
-
 
247
#ifdef OLD
243
static SEXP naoktrim(SEXP s, int * len, int *naok, int *dup)
248
static SEXP naoktrim(SEXP s, int * len, int *naok, int *dup)
244
{
249
{
245
    SEXP value;
250
    SEXP value;
246
    if(s == R_NilValue) {
251
    if(s == R_NilValue) {
247
	value = R_NilValue;
252
	value = R_NilValue;
Line 250... Line 255...
250
	*len = 0;
255
	*len = 0;
251
    }
256
    }
252
    else if(TAG(s) == NaokSymbol) {
257
    else if(TAG(s) == NaokSymbol) {
253
	value = naoktrim(CDR(s), len, naok, dup);
258
	value = naoktrim(CDR(s), len, naok, dup);
254
	*naok = asLogical(CAR(s));
259
	*naok = asLogical(CAR(s));
-
 
260
	(*len)++;
255
    }
261
    }
256
    else if(TAG(s) == DupSymbol) {
262
    else if(TAG(s) == DupSymbol) {
257
	value = naoktrim(CDR(s), len, naok, dup);
263
	value = naoktrim(CDR(s), len, naok, dup);
258
	*dup = asLogical(CAR(s));
264
	*dup = asLogical(CAR(s));
-
 
265
	(*len)++;
-
 
266
    }
-
 
267
    else if(TAG(s) == PkgSymbol) {
-
 
268
	value = naoktrim(CDR(s), len, naok, dup);
-
 
269
	strcpy(DLLname, CHAR(STRING(CAR(s))[0]));
-
 
270
	return value;
259
    }
271
    }
260
    else {
272
    else {
261
	CDR(s) = naoktrim(CDR(s), len, naok, dup);
273
	CDR(s) = naoktrim(CDR(s), len, naok, dup);
262
	*len = *len + 1;
274
	(*len)++;
263
    }
275
    }
264
    return s;
276
    return s;
265
}
277
}
-
 
278
#endif
-
 
279
 
-
 
280
/* find NAOK and DUP, find and remove PACKAGE */
-
 
281
static SEXP naokfind(SEXP args, int * len, int *naok, int *dup)
-
 
282
{
-
 
283
    SEXP s, ss;
-
 
284
    int nargs=0, naokused=0, dupused=0, pkgused=0;
-
 
285
 
-
 
286
    *naok = 0;
-
 
287
    *dup = 1;
-
 
288
    *len = 0;
-
 
289
    for(s = args; s != R_NilValue; ) {
-
 
290
	if(TAG(s) == NaokSymbol) {
-
 
291
	    *naok = asLogical(CAR(s));
-
 
292
	    if(naokused++ == 1) warning("NAOK used more than once");
-
 
293
	} else if(TAG(s) == DupSymbol) {
-
 
294
	    *dup = asLogical(CAR(s));
-
 
295
	    if(dupused++ == 1) warning("DUP used more than once");
-
 
296
	}
-
 
297
	/* Now look for PACKAGE=. We look at the next arg, unless
-
 
298
	   this is the last one (which will only happen for one arg),
-
 
299
	   and remove it */
-
 
300
	ss = CDR(s);
-
 
301
	if(ss == R_NilValue && TAG(s) == PkgSymbol) {
-
 
302
	    if(pkgused++ == 1) warning("PACKAGE used more than once");
-
 
303
	    strcpy(DLLname, CHAR(STRING(CAR(s))[0]));
-
 
304
	    return R_NilValue;
-
 
305
	}
-
 
306
	if(TAG(ss) == PkgSymbol) {
-
 
307
	    if(pkgused++ == 1) warning("PACKAGE used more than once");
-
 
308
	    strcpy(DLLname, CHAR(STRING(CAR(ss))[0]));
-
 
309
	    CDR(s) = CDR(ss); /* delete this arg, which is the next one */
-
 
310
	}
-
 
311
	nargs++;
-
 
312
	s = CDR(s);
-
 
313
    }
-
 
314
    *len = nargs;
-
 
315
    return args;
-
 
316
}
-
 
317
 
-
 
318
static SEXP pkgtrim(SEXP args)
-
 
319
{
-
 
320
    SEXP s, ss;
-
 
321
    int pkgused=0;
-
 
322
 
-
 
323
    for(s = args ; s != R_NilValue;) {
-
 
324
	ss = CDR(s);
-
 
325
	/* Look for PACKAGE=. We look at the next arg, unless
-
 
326
	   this is the last one (which will only happen for one arg),
-
 
327
	   and remove it */
-
 
328
	if(ss == R_NilValue && TAG(s) == PkgSymbol) {
-
 
329
	    if(pkgused++ == 1) warning("PACKAGE used more than once");
-
 
330
	    strcpy(DLLname, CHAR(STRING(CAR(s))[0]));
-
 
331
	    return R_NilValue;
-
 
332
	}
-
 
333
	if(TAG(ss) == PkgSymbol) {
-
 
334
	    if(pkgused++ == 1) warning("PACKAGE used more than once");
-
 
335
	    strcpy(DLLname, CHAR(STRING(CAR(ss))[0]));
-
 
336
	    CDR(s) = CDR(ss);
-
 
337
	}
-
 
338
	s = CDR(s);
-
 
339
    }
-
 
340
    return args;
-
 
341
}
266
 
342
 
267
#define MAX_ARGS 65
343
#define MAX_ARGS 65
268
 
344
 
269
SEXP do_symbol(SEXP call, SEXP op, SEXP args, SEXP env)
345
SEXP do_symbol(SEXP call, SEXP op, SEXP args, SEXP env)
270
{
346
{
271
    char buf[128], *p, *q;
347
    char buf[128], *p, *q;
272
    checkArity(op, args);
348
    checkArity(op, args);
273
    if(!isString(CAR(args)) || length(CAR(args)) < 1)
349
    if(!isValidString(CAR(args)))
274
	errorcall(call, "invalid argument");
350
	errorcall(call, "invalid argument");
275
    p = CHAR(STRING(CAR(args))[0]);
351
    p = CHAR(STRING(CAR(args))[0]);
276
    q = buf;
352
    q = buf;
277
    while ((*q = *p) != '\0') {
353
    while ((*q = *p) != '\0') {
278
	p++;
354
	p++;
Line 292... Line 368...
292
    SEXP ans;
368
    SEXP ans;
293
    DL_FUNC fun;
369
    DL_FUNC fun;
294
    char *sym;
370
    char *sym;
295
    int val;
371
    int val;
296
    checkArity(op, args);
372
    checkArity(op, args);
297
    if(!isString(CAR(args)) || length(CAR(args)) < 1)
373
    if(!isValidString(CAR(args)))
298
	errorcall(call, "invalid argument");
374
	errorcall(call, "invalid argument");
299
    sym = CHAR(STRING(CAR(args))[0]);
375
    sym = CHAR(STRING(CAR(args))[0]);
300
    val = 1;
376
    val = 1;
301
    if (!(fun = R_FindSymbol(sym)))
377
    if (!(fun = R_FindSymbol(sym, "")))
302
	val = 0;
378
	val = 0;
303
    ans = allocVector(LGLSXP, 1);
379
    ans = allocVector(LGLSXP, 1);
304
    LOGICAL(ans)[0] = val;
380
    LOGICAL(ans)[0] = val;
305
    return ans;
381
    return ans;
306
}
382
}
Line 308... Line 384...
308
/*   Call dynamically loaded "internal" functions */
384
/*   Call dynamically loaded "internal" functions */
309
/*   code by Jean Meloche <jean@stat.ubc.ca> */
385
/*   code by Jean Meloche <jean@stat.ubc.ca> */
310
 
386
 
311
SEXP do_External(SEXP call, SEXP op, SEXP args, SEXP env)
387
SEXP do_External(SEXP call, SEXP op, SEXP args, SEXP env)
312
{
388
{
313
      DL_FUNC fun;
389
    DL_FUNC fun;
314
      SEXP retval;
390
    SEXP retval;
315
      /* I don't like this messing with vmax <TSL> */
391
    /* I don't like this messing with vmax <TSL> */
316
      /* But it is needed for clearing R_alloc and to be like .Call <BDR>*/
392
    /* But it is needed for clearing R_alloc and to be like .Call <BDR>*/
317
      char *vmax = vmaxget();
393
    char *vmax = vmaxget();
318
 
394
 
319
      op = CAR(args);
395
    op = CAR(args);
320
      if (!isString(op))
396
    if (!isValidString(op))
321
	  errorcall(call,"function name must be a string");
397
	errorcall(call, "function name must be a string (of length 1)\n");
-
 
398
    if (PkgSymbol == NULL) PkgSymbol = install("PACKAGE");
-
 
399
    strcpy(DLLname, "");
-
 
400
    args = pkgtrim(args);
-
 
401
 
322
      if (!(fun=R_FindSymbol(CHAR(STRING(op)[0]))))
402
    if (!(fun=R_FindSymbol(CHAR(STRING(op)[0]), DLLname)))
323
	  errorcall(call, "C-R function not in load table");
403
	errorcall(call, "C function name not in load table\n");
324
 
404
 
325
      retval = (SEXP)fun(args);
405
    retval = (SEXP)fun(args);
326
      vmaxset(vmax);
406
    vmaxset(vmax);
327
      return retval;
407
    return retval;
328
}
408
}
329
 
409
 
-
 
410
/* .Call(name, <args>) */
330
SEXP do_dotcall(SEXP call, SEXP op, SEXP args, SEXP env)
411
SEXP do_dotcall(SEXP call, SEXP op, SEXP args, SEXP env)
331
{
412
{
332
    DL_FUNC fun;
413
    DL_FUNC fun;
333
    SEXP retval, cargs[MAX_ARGS], pargs;
414
    SEXP retval, cargs[MAX_ARGS], pargs;
334
    int nargs;
415
    int nargs;
335
    char *vmax = vmaxget();
416
    char *vmax = vmaxget();
336
    op = CAR(args);
417
    op = CAR(args);
337
    if (!isString(op))
418
    if (!isValidString(op))
338
        errorcall(call,"function name must be a string");
419
	errorcall(call, "function name must be a string (of length 1)\n");
-
 
420
 
-
 
421
    if (PkgSymbol == NULL) PkgSymbol = install("PACKAGE");
-
 
422
    strcpy(DLLname, "");
-
 
423
    args = pkgtrim(args);
-
 
424
 
339
    if (!(fun=R_FindSymbol(CHAR(STRING(op)[0]))))
425
    if (!(fun=R_FindSymbol(CHAR(STRING(op)[0]), DLLname)))
340
        errorcall(call, "C-R function not in load table");
426
        errorcall(call, "C function name not in load table\n");
341
    args = CDR(args);
427
    args = CDR(args);
342
 
428
 
343
    for(nargs = 0, pargs = args ; pargs != R_NilValue; pargs = CDR(pargs)) {
429
    for(nargs = 0, pargs = args ; pargs != R_NilValue; pargs = CDR(pargs)) {
344
        if (nargs == MAX_ARGS)
430
        if (nargs == MAX_ARGS)
345
            errorcall(call, "too many arguments in foreign function call");
431
            errorcall(call, "too many arguments in foreign function call");
Line 1003... Line 1089...
1003
    }
1089
    }
1004
    vmaxset(vmax);
1090
    vmaxset(vmax);
1005
    return retval;
1091
    return retval;
1006
}
1092
}
1007
 
1093
 
-
 
1094
/* .C() {op=0}  or  .Fortran() {op=1} */
1008
SEXP do_dotCode(SEXP call, SEXP op, SEXP args, SEXP env)
1095
SEXP do_dotCode(SEXP call, SEXP op, SEXP args, SEXP env)
1009
{
1096
{
1010
    void **cargs;
1097
    void **cargs;
1011
    int dup, havenames, naok, nargs, which;
1098
    int dup, havenames, naok, nargs, which;
1012
    DL_FUNC fun;
1099
    DL_FUNC fun;
1013
    SEXP ans, pargs, s;
1100
    SEXP ans, pargs, s;
1014
    char buf[128], *p, *q, *vmax;
1101
    char buf[128], *p, *q, *vmax;
1015
    if (NaokSymbol == NULL || DupSymbol == NULL) {
1102
    if (NaokSymbol == NULL || DupSymbol == NULL || PkgSymbol == NULL) {
1016
	NaokSymbol = install("NAOK");
1103
	NaokSymbol = install("NAOK");
1017
	DupSymbol = install("DUP");
1104
	DupSymbol = install("DUP");
-
 
1105
	PkgSymbol = install("PACKAGE");
1018
    }
1106
    }
1019
    vmax = vmaxget();
1107
    vmax = vmaxget();
1020
    which = PRIMVAL(op);
1108
    which = PRIMVAL(op);
1021
    op = CAR(args);
1109
    op = CAR(args);
1022
    if (!isString(op))
1110
    if (!isValidString(op))
1023
	errorcall(call, "function name must be a string");
1111
	errorcall(call, "function name must be a string (of length 1)");
1024
 
1112
 
1025
    /* The following code modifies the argument list */
1113
    /* The following code modifies the argument list */
1026
    /* We know this is ok because do_dotCode is entered */
1114
    /* We know this is ok because do_dotCode is entered */
1027
    /* with its arguments evaluated. */
1115
    /* with its arguments evaluated. */
1028
 
1116
 
-
 
1117
    strcpy(DLLname, "");
1029
    args = naoktrim(CDR(args), &nargs, &naok, &dup);
1118
    args = naokfind(CDR(args), &nargs, &naok, &dup);
1030
    if(naok == NA_LOGICAL)
1119
    if(naok == NA_LOGICAL)
1031
	errorcall(call, "invalid naok value");
1120
	errorcall(call, "invalid naok value");
1032
    if(nargs > MAX_ARGS)
1121
    if(nargs > MAX_ARGS)
1033
	errorcall(call, "too many arguments in foreign function call");
1122
	errorcall(call, "too many arguments in foreign function call");
1034
    cargs = (void**)R_alloc(nargs, sizeof(void*));
1123
    cargs = (void**)R_alloc(nargs, sizeof(void*));
Line 1055... Line 1144...
1055
#ifdef HAVE_F77_UNDERSCORE
1144
#ifdef HAVE_F77_UNDERSCORE
1056
    if (which)
1145
    if (which)
1057
	*q++ = '_';
1146
	*q++ = '_';
1058
    *q = '\0';
1147
    *q = '\0';
1059
#endif
1148
#endif
1060
    if (!(fun = R_FindSymbol(buf)))
1149
    if (!(fun = R_FindSymbol(buf, DLLname)))
1061
	errorcall(call, "C/Fortran function not in load table");
1150
	errorcall(call, "C/Fortran function name not in load table");
1062
 
1151
 
1063
    switch (nargs) {
1152
    switch (nargs) {
1064
    case 0:
1153
    case 0:
1065
	/* Silicon graphics C chokes here */
1154
	/* Silicon graphics C chokes here */
1066
	/* if there is no argument to fun. */
1155
	/* if there is no argument to fun. */