The R Project SVN R

Rev

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

Rev 14156 Rev 14571
Line 43... Line 43...
43
static SEXP PkgSymbol = NULL;
43
static SEXP PkgSymbol = NULL;
44
 
44
 
45
static char DLLname[PATH_MAX];
45
static char DLLname[PATH_MAX];
46
 
46
 
47
/* This looks up entry points in DLLs in a platform specific way. */
47
/* This looks up entry points in DLLs in a platform specific way. */
48
DL_FUNC R_FindSymbol(char const *, char const *);
48
#include "R_ext/Rdynpriv.h"
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.
Line 298... Line 298...
298
#endif
298
#endif
299
 
299
 
300
/* find NAOK and DUP, find and remove PACKAGE */
300
/* find NAOK and DUP, find and remove PACKAGE */
301
static SEXP naokfind(SEXP args, int * len, int *naok, int *dup)
301
static SEXP naokfind(SEXP args, int * len, int *naok, int *dup)
302
{
302
{
303
    SEXP s, ss;
303
    SEXP s, prev;
304
    int nargs=0, naokused=0, dupused=0, pkgused=0;
304
    int nargs=0, naokused=0, dupused=0, pkgused=0;
305
 
305
 
306
    *naok = 0;
306
    *naok = 0;
307
    *dup = 1;
307
    *dup = 1;
308
    *len = 0;
308
    *len = 0;
309
    for(s = args; s != R_NilValue; ) {
309
    for(s = args, prev=args; s != R_NilValue;) {
310
	if(TAG(s) == NaokSymbol) {
310
	if(TAG(s) == NaokSymbol) {
311
	    *naok = asLogical(CAR(s));
311
	    *naok = asLogical(CAR(s));
-
 
312
	    /* SETCDR(prev, s = CDR(s)); */
312
	    if(naokused++ == 1) warning("NAOK used more than once");
313
	    if(naokused++ == 1) warning("NAOK used more than once");
313
	} else if(TAG(s) == DupSymbol) {
314
	} else if(TAG(s) == DupSymbol) {
314
	    *dup = asLogical(CAR(s));
315
	    *dup = asLogical(CAR(s));
-
 
316
	    /* SETCDR(prev, s = CDR(s)); */
315
	    if(dupused++ == 1) warning("DUP used more than once");
317
	    if(dupused++ == 1) warning("DUP used more than once");
316
	}
-
 
317
	/* Now look for PACKAGE=. We look at the next arg, unless
-
 
318
	   this is the last one (which will only happen for one arg),
-
 
319
	   and remove it */
-
 
320
	ss = CDR(s);
-
 
321
	if(ss == R_NilValue && TAG(s) == PkgSymbol) {
318
	} else if(TAG(s) == PkgSymbol) {
322
	    if(pkgused++ == 1) warning("PACKAGE used more than once");
319
	    if(pkgused++ == 1) warning("PACKAGE used more than once");
323
	    strcpy(DLLname, CHAR(STRING_ELT(CAR(s), 0)));
320
	    strcpy(DLLname, CHAR(STRING_ELT(CAR(s), 0)));
324
	    return R_NilValue;
321
            if(s == args)
325
	}
-
 
326
	if(TAG(ss) == PkgSymbol) {
322
		args = CDR(s);
327
	    if(pkgused++ == 1) warning("PACKAGE used more than once");
323
            else
328
	    strcpy(DLLname, CHAR(STRING_ELT(CAR(ss), 0)));
-
 
329
	    SETCDR(s, CDR(ss)); /* delete this arg, which is the next one */
324
	        SETCDR(prev, s = CDR(s)); /* delete this arg, which is the next one */
-
 
325
            continue;
-
 
326
	} else {
330
	}
327
	}
331
	nargs++;
328
        nargs++;
-
 
329
	prev = s;
332
	s = CDR(s);
330
	s = CDR(s);
333
    }
331
    }
334
    *len = nargs;
332
    *len = nargs;
335
    return args;
333
    return args;
336
}
334
}
Line 395... Line 393...
395
}
393
}
396
 
394
 
397
SEXP do_isloaded(SEXP call, SEXP op, SEXP args, SEXP env)
395
SEXP do_isloaded(SEXP call, SEXP op, SEXP args, SEXP env)
398
{
396
{
399
    SEXP ans;
397
    SEXP ans;
400
    char *sym;
398
    char *sym, *pkg;
401
    int val;
399
    int val;
402
    checkArity(op, args);
400
    checkArity(op, args);
403
    if(!isValidString(CAR(args)))
401
    if(!isValidString(CAR(args)))
404
	errorcall(call, R_MSG_IA);
402
	errorcall(call, R_MSG_IA);
405
    sym = CHAR(STRING_ELT(CAR(args), 0));
403
    sym = CHAR(STRING_ELT(CAR(args), 0));
-
 
404
    if(!isValidString(CADR(args)))
-
 
405
	errorcall(call, R_MSG_IA);
-
 
406
    pkg = CHAR(STRING_ELT(CADR(args), 0));
406
    val = 1;
407
    val = 1;
407
    if (!(R_FindSymbol(sym, "")))
408
    if (!(R_FindSymbol(sym, pkg, NULL)))
408
	val = 0;
409
	val = 0;
409
    ans = allocVector(LGLSXP, 1);
410
    ans = allocVector(LGLSXP, 1);
410
    LOGICAL(ans)[0] = val;
411
    LOGICAL(ans)[0] = val;
411
    return ans;
412
    return ans;
412
}
413
}
Line 416... Line 417...
416
 
417
 
417
SEXP do_External(SEXP call, SEXP op, SEXP args, SEXP env)
418
SEXP do_External(SEXP call, SEXP op, SEXP args, SEXP env)
418
{
419
{
419
    DL_FUNC fun;
420
    DL_FUNC fun;
420
    SEXP retval;
421
    SEXP retval;
-
 
422
    R_RegisteredNativeSymbol symbol = {R_EXTERNAL_SYM, NULL};
421
    /* I don't like this messing with vmax <TSL> */
423
    /* I don't like this messing with vmax <TSL> */
422
    /* But it is needed for clearing R_alloc and to be like .Call <BDR>*/
424
    /* But it is needed for clearing R_alloc and to be like .Call <BDR>*/
423
    char *vmax = vmaxget();
425
    char *vmax = vmaxget();
424
 
426
 
425
    op = CAR(args);
427
    op = CAR(args);
Line 427... Line 429...
427
	errorcall(call, "function name must be a string (of length 1)");
429
	errorcall(call, "function name must be a string (of length 1)");
428
    if (PkgSymbol == NULL) PkgSymbol = install("PACKAGE");
430
    if (PkgSymbol == NULL) PkgSymbol = install("PACKAGE");
429
    strcpy(DLLname, "");
431
    strcpy(DLLname, "");
430
    args = pkgtrim(args);
432
    args = pkgtrim(args);
431
 
433
 
432
    if (!(fun=R_FindSymbol(CHAR(STRING_ELT(op, 0)), DLLname)))
434
    if (!(fun=R_FindSymbol(CHAR(STRING_ELT(op, 0)), DLLname, NULL)))
433
	errorcall(call, "C function name not in load table");
435
	errorcall(call, "C function name not in load table");
434
 
436
 
-
 
437
    if(symbol.symbol.external && symbol.symbol.external->numArgs > -1) {
-
 
438
	if(symbol.symbol.external->numArgs != length(args))
-
 
439
	    error("Incorrect number of arguments (%d), expecting %d for %s", 
-
 
440
		  length(args), symbol.symbol.external->numArgs, CHAR(STRING_ELT(op, 0)));
-
 
441
    }
435
    retval = (SEXP)fun(args);
442
    retval = (SEXP)fun(args);
436
    vmaxset(vmax);
443
    vmaxset(vmax);
437
    return retval;
444
    return retval;
438
}
445
}
439
 
446
 
Line 441... Line 448...
441
/* .Call(name, <args>) */
448
/* .Call(name, <args>) */
442
SEXP do_dotcall(SEXP call, SEXP op, SEXP args, SEXP env)
449
SEXP do_dotcall(SEXP call, SEXP op, SEXP args, SEXP env)
443
{
450
{
444
    DL_FUNC fun;
451
    DL_FUNC fun;
445
    SEXP retval, cargs[MAX_ARGS], pargs;
452
    SEXP retval, cargs[MAX_ARGS], pargs;
-
 
453
    R_RegisteredNativeSymbol symbol = {R_CALL_SYM, NULL};
446
    int nargs;
454
    int nargs;
447
    char *vmax = vmaxget();
455
    char *vmax = vmaxget();
448
    op = CAR(args);
456
    op = CAR(args);
449
    if (!isValidString(op))
457
    if (!isValidString(op))
450
	errorcall(call, "function name must be a string (of length 1)");
458
	errorcall(call, "function name must be a string (of length 1)");
451
 
459
 
452
    if (PkgSymbol == NULL) PkgSymbol = install("PACKAGE");
460
    if (PkgSymbol == NULL) PkgSymbol = install("PACKAGE");
453
    strcpy(DLLname, "");
461
    strcpy(DLLname, "");
454
    args = pkgtrim(args);
462
    args = pkgtrim(args);
455
 
463
 
456
    if (!(fun=R_FindSymbol(CHAR(STRING_ELT(op, 0)), DLLname)))
464
    if (!(fun=R_FindSymbol(CHAR(STRING_ELT(op, 0)), DLLname, &symbol)))
457
        errorcall(call, "C function name not in load table");
465
        errorcall(call, ".Call function name not in load table");
458
    args = CDR(args);
466
    args = CDR(args);
459
 
467
 
460
    for(nargs = 0, pargs = args ; pargs != R_NilValue; pargs = CDR(pargs)) {
468
    for(nargs = 0, pargs = args ; pargs != R_NilValue; pargs = CDR(pargs)) {
461
        if (nargs == MAX_ARGS)
469
        if (nargs == MAX_ARGS)
462
            errorcall(call, "too many arguments in foreign function call");
470
            errorcall(call, "too many arguments in foreign function call");
463
	cargs[nargs] = CAR(pargs);
471
	cargs[nargs] = CAR(pargs);
464
	nargs++;
472
	nargs++;
465
    }
473
    }
-
 
474
    if(symbol.symbol.call && symbol.symbol.call->numArgs > -1) {
-
 
475
	if(symbol.symbol.call->numArgs != nargs)
-
 
476
	    error("Incorrect number of arguments (%d), expecting %d for %s", 
-
 
477
		  nargs, symbol.symbol.call->numArgs, CHAR(STRING_ELT(op, 0)));
-
 
478
    }
466
 
479
 
467
    retval = R_NilValue;	/* -Wall */
480
    retval = R_NilValue;	/* -Wall */
468
    switch (nargs) {
481
    switch (nargs) {
469
    case 0:
482
    case 0:
470
	retval = (SEXP)fun();
483
	retval = (SEXP)fun();
Line 1154... Line 1167...
1154
    void **cargs;
1167
    void **cargs;
1155
    int dup, havenames, naok, nargs, which;
1168
    int dup, havenames, naok, nargs, which;
1156
    DL_FUNC fun;
1169
    DL_FUNC fun;
1157
    SEXP ans, pargs, s;
1170
    SEXP ans, pargs, s;
1158
    R_toCConverter  *argConverters[65];
1171
    R_toCConverter  *argConverters[65];
-
 
1172
    R_RegisteredNativeSymbol symbol = {R_C_SYM, NULL};
-
 
1173
 
1159
    char buf[128], *p, *q, *vmax;
1174
    char buf[128], *p, *q, *vmax;
1160
    if (NaokSymbol == NULL || DupSymbol == NULL || PkgSymbol == NULL) {
1175
    if (NaokSymbol == NULL || DupSymbol == NULL || PkgSymbol == NULL) {
1161
	NaokSymbol = install("NAOK");
1176
	NaokSymbol = install("NAOK");
1162
	DupSymbol = install("DUP");
1177
	DupSymbol = install("DUP");
1163
	PkgSymbol = install("PACKAGE");
1178
	PkgSymbol = install("PACKAGE");
1164
    }
1179
    }
1165
    vmax = vmaxget();
1180
    vmax = vmaxget();
1166
    which = PRIMVAL(op);
1181
    which = PRIMVAL(op);
-
 
1182
    if(which)
-
 
1183
	symbol.type = R_FORTRAN_SYM;
1167
    op = CAR(args);
1184
    op = CAR(args);
1168
    if (!isValidString(op))
1185
    if (!isValidString(op))
1169
	errorcall(call, "function name must be a string (of length 1)");
1186
	errorcall(call, "function name must be a string (of length 1)");
1170
 
1187
 
1171
    /* The following code modifies the argument list */
1188
    /* The following code modifies the argument list */
Line 1176... Line 1193...
1176
    args = naokfind(CDR(args), &nargs, &naok, &dup);
1193
    args = naokfind(CDR(args), &nargs, &naok, &dup);
1177
    if(naok == NA_LOGICAL)
1194
    if(naok == NA_LOGICAL)
1178
	errorcall(call, "invalid naok value");
1195
	errorcall(call, "invalid naok value");
1179
    if(nargs > MAX_ARGS)
1196
    if(nargs > MAX_ARGS)
1180
	errorcall(call, "too many arguments in foreign function call");
1197
	errorcall(call, "too many arguments in foreign function call");
1181
    cargs = (void**)R_alloc(nargs, sizeof(void*));
-
 
1182
 
-
 
1183
 
1198
 
1184
    /* Make up the load symbol and look it up. */
1199
    /* Make up the load symbol and look it up. */
1185
 
1200
 
1186
    p = CHAR(STRING_ELT(op, 0));
1201
    p = CHAR(STRING_ELT(op, 0));
1187
    q = buf;
1202
    q = buf;
Line 1193... Line 1208...
1193
    if (which)
1208
    if (which)
1194
	*q++ = '_';
1209
	*q++ = '_';
1195
    *q = '\0';
1210
    *q = '\0';
1196
#endif
1211
#endif
1197
#ifdef Macintosh
1212
#ifdef Macintosh
1198
    if (!(fun = R_FindSymbol(buf, "")))
1213
    if (!(fun = R_FindSymbol(buf, "", &symbol)))
1199
#else
1214
#else
1200
    if (!(fun = R_FindSymbol(buf, DLLname)))
1215
    if (!(fun = R_FindSymbol(buf, DLLname, &symbol)))
1201
#endif /* Macintosh */
1216
#endif /* Macintosh */
1202
	errorcall(call, "C/Fortran function name not in load table");
1217
	errorcall(call, "C/Fortran function name not in load table");
1203
 
1218
 
-
 
1219
    if(symbol.symbol.c && symbol.symbol.c->numArgs > -1) {
-
 
1220
	if(symbol.symbol.c->numArgs != nargs)
-
 
1221
	    error("Incorrect number of arguments (%d), expecting %d for %s", 
-
 
1222
		  nargs, symbol.symbol.c->numArgs, buf);
-
 
1223
    }
1204
 
1224
 
1205
    /* Convert the arguments for use in foreign */
1225
    /* Convert the arguments for use in foreign */
1206
    /* function calls.  Note that we copy twice */
1226
    /* function calls.  Note that we copy twice */
1207
    /* once here, on the way into the call, and */
1227
    /* once here, on the way into the call, and */
1208
    /* once below on the way out. */
1228
    /* once below on the way out. */
1209
 
1229
 
-
 
1230
    cargs = (void**)R_alloc(nargs, sizeof(void*));
1210
    nargs = 0;
1231
    nargs = 0;
1211
    for(pargs = args ; pargs != R_NilValue; pargs = CDR(pargs)) {
1232
    for(pargs = args ; pargs != R_NilValue; pargs = CDR(pargs)) {
1212
	cargs[nargs] = RObjToCPtr(CAR(pargs), naok, dup, nargs + 1, which, buf, argConverters + nargs);
1233
	cargs[nargs] = RObjToCPtr(CAR(pargs), naok, dup, nargs + 1, which, buf, argConverters + nargs);
1213
	nargs++;
1234
	nargs++;
1214
    }
1235
    }