The R Project SVN R

Rev

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

Rev 27298 Rev 30599
Line 42... Line 42...
42
 
42
 
43
static SEXP NaokSymbol = NULL;
43
static SEXP NaokSymbol = NULL;
44
static SEXP DupSymbol = NULL;
44
static SEXP DupSymbol = NULL;
45
static SEXP PkgSymbol = NULL;
45
static SEXP PkgSymbol = NULL;
46
 
46
 
-
 
47
/* Global variable that should go. Should actually be doing this in a much more straightforward manner. */
-
 
48
#include <Rdynpriv.h>
-
 
49
enum {FILENAME, DLL_HANDLE, R_OBJECT, NOT_DEFINED};
-
 
50
typedef struct {
47
static char DLLname[PATH_MAX];
51
    char DLLname[PATH_MAX];
-
 
52
    HINSTANCE dll;
-
 
53
    SEXP  obj;
-
 
54
    int type;
-
 
55
} DllReference;
-
 
56
 
48
 
57
 
49
/* This looks up entry points in DLLs in a platform specific way. */
58
/* This looks up entry points in DLLs in a platform specific way. */
50
#include <Rdynpriv.h>
59
#include <Rdynpriv.h>
51
 
60
 
-
 
61
#define MAX_ARGS 65
-
 
62
 
-
 
63
static DL_FUNC R_FindNativeSymbolFromDLL(char *name, DllReference *dll, R_RegisteredNativeSymbol *symbol);
-
 
64
 
-
 
65
static SEXP naokfind(SEXP args, int * len, int *naok, int *dup, DllReference *dll);
-
 
66
static SEXP pkgtrim(SEXP args, DllReference *dll);
-
 
67
 
-
 
68
/*
-
 
69
  Checks whether the specified object correctly identifies a native routine.
-
 
70
  This can be  
-
 
71
   a) a string,
-
 
72
   b) an external pointer giving the address of the routine (e.g. getNativeSymbolInfo("foo")$address)
-
 
73
   c) or a NativeSymbolInfo itself  (e.g. getNativeSymbolInfo("foo"))
-
 
74
 */
-
 
75
static int
-
 
76
checkValidSymbolId(SEXP op, SEXP call, DL_FUNC *fun)
-
 
77
{
-
 
78
    if (isValidString(op))
-
 
79
	return(0);
-
 
80
 
-
 
81
    else if((TYPEOF(op) == EXTPTRSXP && R_ExternalPtrTag(op) == Rf_install("native symbol"))) {
-
 
82
 
-
 
83
	if((*fun = R_ExternalPtrAddr(op)) == NULL) 
-
 
84
	    errorcall(call, "NULL value passed as symbol address.");
-
 
85
	return(0);
-
 
86
 
-
 
87
    } else if(inherits(op, "NativeSymbolInfo")) {
-
 
88
 
-
 
89
	return(checkValidSymbolId(VECTOR_ELT(op, 1), call, fun));
-
 
90
 
-
 
91
    }
-
 
92
 
-
 
93
    errorcall(call, "function name must be a string (of length 1) or native symbol reference.");
-
 
94
    return(0);
-
 
95
}
-
 
96
 
-
 
97
 
-
 
98
/*
-
 
99
  This is the routine that is called by do_dotCode, do_dotcall and do_External
-
 
100
  to find the DL_FUNC to invoke. It handles processing the arguments for the
-
 
101
  PACKAGE argument, if present, and also takes care of the cases where we are given
-
 
102
  a NativeSymbolInfo object, an address directly, and if the DLL is specified.
-
 
103
  If no PACKAGE is provided, we check whether the calling function is in a namespace
-
 
104
  and look there.
-
 
105
*/
-
 
106
SEXP
-
 
107
resolveNativeRoutine(SEXP args, DL_FUNC *fun, R_RegisteredNativeSymbol *symbol, char *buf, 
-
 
108
		     int *nargs, int *naok, int *dup, SEXP call)
-
 
109
{
-
 
110
    SEXP op;
-
 
111
    char *p, *q;
-
 
112
    DllReference dll = {"", NULL, NULL, NOT_DEFINED}; 
-
 
113
 
-
 
114
    op = CAR(args);
-
 
115
    checkValidSymbolId(op, call, fun);
-
 
116
 
-
 
117
    /* The following code modifies the argument list */
-
 
118
    /* We know this is ok because do_dotCode is entered */
-
 
119
    /* with its arguments evaluated. */
-
 
120
 
-
 
121
    strcpy(dll.DLLname, "");
-
 
122
    if(symbol->type == R_C_SYM || symbol->type == R_FORTRAN_SYM) {
-
 
123
	args = naokfind(CDR(args), nargs, naok, dup, &dll);
-
 
124
	
-
 
125
	if(*naok == NA_LOGICAL)
-
 
126
	    errorcall(call, "invalid naok value");
-
 
127
	if(*nargs > MAX_ARGS)
-
 
128
	    errorcall(call, "too many arguments in foreign function call");
-
 
129
    } else {
-
 
130
	if (PkgSymbol == NULL) PkgSymbol = install("PACKAGE");
-
 
131
	args = pkgtrim(args, &dll);
-
 
132
    }
-
 
133
 
-
 
134
    /* Make up the load symbol and look it up. */
-
 
135
 
-
 
136
    if(TYPEOF(op) == STRSXP) {
-
 
137
	p = CHAR(STRING_ELT(op, 0));
-
 
138
	q = buf;
-
 
139
	while ((*q = *p) != '\0') {
-
 
140
	    p++;
-
 
141
	    q++;
-
 
142
	}
-
 
143
    } 
-
 
144
 
-
 
145
    if(!*fun) {
-
 
146
	if(dll.type != FILENAME) {
-
 
147
	    *fun = R_FindNativeSymbolFromDLL(buf, &dll, symbol);
-
 
148
	    if(!fun) {
-
 
149
		errorcall(call, "cannot resolve native routine");
-
 
150
	    }
-
 
151
	} else if (!(*fun = R_FindSymbol(buf, dll.DLLname, symbol))) {
-
 
152
	    if(strlen(dll.DLLname))
-
 
153
		errorcall(call, "%s function name not in DLL for package %s",
-
 
154
			   symbol->type == R_FORTRAN_SYM ? "Fortran" : "C", 
-
 
155
			   dll.DLLname);
-
 
156
	    else
-
 
157
		errorcall(call, "%s function name not in load table",
-
 
158
			  symbol->type == R_FORTRAN_SYM ? "Fortran" : "C"); 
-
 
159
	}
-
 
160
    }
-
 
161
 
-
 
162
    return(args);
-
 
163
}
-
 
164
 
-
 
165
 
-
 
166
 
52
/* Convert an R object to a non-moveable C/Fortran object and return
167
/* Convert an R object to a non-moveable C/Fortran object and return
53
   a pointer to it.  This leaves pointers for anything other
168
   a pointer to it.  This leaves pointers for anything other
54
   than vectors and lists unaltered.
169
   than vectors and lists unaltered.
55
*/
170
*/
56
 
171
 
Line 306... Line 421...
306
/* or Fortran code which is either statically or dynamically linked. */
421
/* or Fortran code which is either statically or dynamically linked. */
307
 
422
 
308
/* NB: despite its name, this leaves NAOK and DUP arguments on the list */
423
/* NB: despite its name, this leaves NAOK and DUP arguments on the list */
309
 
424
 
310
/* find NAOK and DUP, find and remove PACKAGE */
425
/* find NAOK and DUP, find and remove PACKAGE */
311
static SEXP naokfind(SEXP args, int * len, int *naok, int *dup)
426
static SEXP naokfind(SEXP args, int * len, int *naok, int *dup, DllReference *dll)
312
{
427
{
313
    SEXP s, prev;
428
    SEXP s, prev;
314
    int nargs=0, naokused=0, dupused=0, pkgused=0;
429
    int nargs=0, naokused=0, dupused=0, pkgused=0;
315
    char *p;
430
    char *p;
316
 
431
 
Line 325... Line 440...
325
	} else if(TAG(s) == DupSymbol) {
440
	} else if(TAG(s) == DupSymbol) {
326
	    *dup = asLogical(CAR(s));
441
	    *dup = asLogical(CAR(s));
327
	    /* SETCDR(prev, s = CDR(s)); */
442
	    /* SETCDR(prev, s = CDR(s)); */
328
	    if(dupused++ == 1) warning("DUP used more than once");
443
	    if(dupused++ == 1) warning("DUP used more than once");
329
	} else if(TAG(s) == PkgSymbol) {
444
	} else if(TAG(s) == PkgSymbol) {
-
 
445
	    dll->obj = CAR(s);
-
 
446
	    if(TYPEOF(CAR(s)) == STRSXP) {
330
	    p = CHAR(STRING_ELT(CAR(s), 0));
447
		p = CHAR(STRING_ELT(CAR(s), 0));
331
	    if(strlen(p) > PATH_MAX - 1)
448
		if(strlen(p) > PATH_MAX - 1)
332
		error("DLL name is too long");
449
		    error("DLL name is too long");
-
 
450
		dll->type = FILENAME;
333
	    strcpy(DLLname, p);
451
		strcpy(dll->DLLname, p);
334
	    if(pkgused++ > 1) warning("PACKAGE used more than once");
452
		if(pkgused++ > 1) warning("PACKAGE used more than once");
335
	    /* More generally, this should allow us to process
453
		/* More generally, this should allow us to process
336
               any additional arguments and not insist that PACKAGE
454
		   any additional arguments and not insist that PACKAGE
337
               be the last argument.
455
		   be the last argument.
-
 
456
		*/
338
             */
457
	    } else {
-
 
458
		    /* Have a DLL object*/
-
 
459
	        if(TYPEOF(CAR(s)) == EXTPTRSXP) {
-
 
460
		    dll->dll = (HINSTANCE) R_ExternalPtrAddr(CAR(s));
-
 
461
		    dll->type = DLL_HANDLE;
-
 
462
		} else if(TYPEOF(CAR(s)) == VECSXP) {
-
 
463
		    dll->type = R_OBJECT;
-
 
464
		    dll->obj = s;
-
 
465
		    strcpy(dll->DLLname, CHAR(STRING_ELT(VECTOR_ELT(CAR(s), 1), 0)));
-
 
466
		    dll->dll = (HINSTANCE) R_ExternalPtrAddr(VECTOR_ELT(s, 4));
-
 
467
		}
-
 
468
	    }
339
	} else {
469
	} else {
340
	    nargs++;
470
	    nargs++;
341
	    prev = s;
471
	    prev = s;
342
	    s = CDR(s);
472
	    s = CDR(s);
343
	    continue;
473
	    continue;
Line 349... Line 479...
349
    }
479
    }
350
    *len = nargs;
480
    *len = nargs;
351
    return args;
481
    return args;
352
}
482
}
353
 
483
 
354
static void setDLLname(SEXP s, char *DLLName)
484
static void setDLLname(SEXP s, char *DLLname)
355
{
485
{
356
    SEXP ss = CAR(s); char *name;
486
    SEXP ss = CAR(s); char *name;
357
    if(TYPEOF(ss) != STRSXP || length(ss) != 1)
487
    if(TYPEOF(ss) != STRSXP || length(ss) != 1)
358
	error("PACKAGE argument must be a single character string");
488
	error("PACKAGE argument must be a single character string");
359
    name = CHAR(STRING_ELT(ss, 0));
489
    name = CHAR(STRING_ELT(ss, 0));
Line 363... Line 493...
363
    if(strlen(name) > PATH_MAX - 1)
493
    if(strlen(name) > PATH_MAX - 1)
364
	error("PACKAGE argument is too long");
494
	error("PACKAGE argument is too long");
365
    strcpy(DLLname, name);
495
    strcpy(DLLname, name);
366
}
496
}
367
 
497
 
368
static SEXP pkgtrim(SEXP args)
498
static SEXP pkgtrim(SEXP args, DllReference *dll)
369
{
499
{
370
    SEXP s, ss;
500
    SEXP s, ss;
371
    int pkgused=0;
501
    int pkgused=0;
372
 
502
 
373
    for(s = args ; s != R_NilValue;) {
503
    for(s = args ; s != R_NilValue;) {
Line 375... Line 505...
375
	/* Look for PACKAGE=. We look at the next arg, unless
505
	/* Look for PACKAGE=. We look at the next arg, unless
376
	   this is the last one (which will only happen for one arg),
506
	   this is the last one (which will only happen for one arg),
377
	   and remove it */
507
	   and remove it */
378
	if(ss == R_NilValue && TAG(s) == PkgSymbol) {
508
	if(ss == R_NilValue && TAG(s) == PkgSymbol) {
379
	    if(pkgused++ == 1) warning("PACKAGE used more than once");
509
	    if(pkgused++ == 1) warning("PACKAGE used more than once");
380
	    setDLLname(s, DLLname);
510
	    setDLLname(s, dll->DLLname);
-
 
511
	    dll->type = FILENAME;
381
	    return R_NilValue;
512
	    return R_NilValue;
382
	}
513
	}
383
	if(TAG(ss) == PkgSymbol) {
514
	if(TAG(ss) == PkgSymbol) {
384
	    if(pkgused++ == 1) warning("PACKAGE used more than once");
515
	    if(pkgused++ == 1) warning("PACKAGE used more than once");
385
	    setDLLname(ss, DLLname);
516
	    setDLLname(ss, dll->DLLname);
-
 
517
	    dll->type = FILENAME;
386
	    SETCDR(s, CDR(ss));
518
	    SETCDR(s, CDR(ss));
387
	}
519
	}
388
	s = CDR(s);
520
	s = CDR(s);
389
    }
521
    }
390
    return args;
522
    return args;
391
}
523
}
392
 
524
 
393
#define MAX_ARGS 65
-
 
-
 
525
 
394
 
526
 
395
SEXP do_symbol(SEXP call, SEXP op, SEXP args, SEXP env)
527
SEXP do_symbol(SEXP call, SEXP op, SEXP args, SEXP env)
396
{
528
{
397
    char buf[128], *p, *q;
529
    char buf[128], *p, *q;
398
    checkArity(op, args);
530
    checkArity(op, args);
Line 439... Line 571...
439
/*   Call dynamically loaded "internal" functions */
571
/*   Call dynamically loaded "internal" functions */
440
/*   code by Jean Meloche <jean@stat.ubc.ca> */
572
/*   code by Jean Meloche <jean@stat.ubc.ca> */
441
 
573
 
442
SEXP do_External(SEXP call, SEXP op, SEXP args, SEXP env)
574
SEXP do_External(SEXP call, SEXP op, SEXP args, SEXP env)
443
{
575
{
444
    DL_FUNC fun;
576
    DL_FUNC fun = NULL;
445
    SEXP retval;
577
    SEXP retval;
446
    R_RegisteredNativeSymbol symbol = {R_EXTERNAL_SYM, {NULL}, NULL};
578
    R_RegisteredNativeSymbol symbol = {R_EXTERNAL_SYM, {NULL}, NULL};
447
    /* I don't like this messing with vmax <TSL> */
579
    /* I don't like this messing with vmax <TSL> */
448
    /* But it is needed for clearing R_alloc and to be like .Call <BDR>*/
580
    /* But it is needed for clearing R_alloc and to be like .Call <BDR>*/
449
    char *vmax = vmaxget();
581
    char *vmax = vmaxget(), buf[128];
450
 
582
 
451
    op = CAR(args);
-
 
452
    if (!isValidString(op))
-
 
453
	errorcall(call, "function name must be a string (of length 1)");
-
 
454
    if (PkgSymbol == NULL) PkgSymbol = install("PACKAGE");
-
 
455
    strcpy(DLLname, "");
-
 
456
    args = pkgtrim(args);
-
 
457
 
-
 
458
    if (!(fun=R_FindSymbol(CHAR(STRING_ELT(op, 0)), DLLname, NULL))) {
583
    args = resolveNativeRoutine(args, &fun, &symbol, buf, NULL, NULL, NULL, call);
459
	if(strlen(DLLname))
-
 
460
	    errorcall(call,
-
 
461
		      ".External function name not in DLL for package %s", 
-
 
462
		      DLLname);
-
 
463
	else
-
 
464
	    errorcall(call, ".External function name not in load table");
-
 
465
    }
-
 
466
 
584
 
-
 
585
    /* Some external symbols that are registered may have 0 as the expected number of arguments.
-
 
586
       We may want a warning here. However, the number of values may vary across calls
-
 
587
       and that is why people use the .External() mechanism.  So perhaps we should just kill this 
-
 
588
       check. */
-
 
589
#ifdef CHECK_EXTERNAL_ARG_COUNT         /* Off by default. */
467
    if(symbol.symbol.external && symbol.symbol.external->numArgs > -1) {
590
    if(symbol.symbol.external && symbol.symbol.external->numArgs > -1) {
468
	if(symbol.symbol.external->numArgs != length(args))
591
	if(symbol.symbol.external->numArgs != length(args))
469
	    error("Incorrect number of arguments (%d), expecting %d for %s",
592
	    error("Incorrect number of arguments (%d), expecting %d for %s",
470
		  length(args), symbol.symbol.external->numArgs, CHAR(STRING_ELT(op, 0)));
593
		  length(args), symbol.symbol.external->numArgs, CHAR(STRING_ELT(op, 0)));
471
    }
594
    }
-
 
595
#endif
-
 
596
 
472
    retval = (SEXP)fun(args);
597
    retval = (SEXP)fun(args);
473
    vmaxset(vmax);
598
    vmaxset(vmax);
474
    return retval;
599
    return retval;
475
}
600
}
476
 
601
 
477
 
602
 
478
/* .Call(name, <args>) */
603
/* .Call(name, <args>) */
479
SEXP do_dotcall(SEXP call, SEXP op, SEXP args, SEXP env)
604
SEXP do_dotcall(SEXP call, SEXP op, SEXP args, SEXP env)
480
{
605
{
481
    DL_FUNC fun;
606
    DL_FUNC fun = NULL;
482
    SEXP retval, cargs[MAX_ARGS], pargs;
607
    SEXP retval, cargs[MAX_ARGS], pargs;
483
    R_RegisteredNativeSymbol symbol = {R_CALL_SYM, {NULL}, NULL};
608
    R_RegisteredNativeSymbol symbol = {R_CALL_SYM, {NULL}, NULL};
484
    int nargs;
609
    int nargs;
485
    char *vmax = vmaxget();
610
    char *vmax = vmaxget();
486
    op = CAR(args);
611
    char buf[128];
487
    if (!isValidString(op))
-
 
488
	errorcall(call, "function name must be a string (of length 1)");
-
 
489
 
612
 
490
    if (PkgSymbol == NULL) PkgSymbol = install("PACKAGE");
-
 
491
    strcpy(DLLname, "");
-
 
492
    args = pkgtrim(args);
-
 
493
 
-
 
494
    if (!(fun=R_FindSymbol(CHAR(STRING_ELT(op, 0)), DLLname, &symbol))) {
613
    args = resolveNativeRoutine(args, &fun, &symbol, buf, NULL, NULL, NULL, call);
495
	if(strlen(DLLname))
-
 
496
	    errorcall(call, ".Call function name not in DLL for package %s", 
-
 
497
		      DLLname);
-
 
498
	else
-
 
499
	    errorcall(call, ".Call function name not in load table");
-
 
500
    }
-
 
501
    args = CDR(args);
614
    args = CDR(args);
502
 
615
 
503
    for(nargs = 0, pargs = args ; pargs != R_NilValue; pargs = CDR(pargs)) {
616
    for(nargs = 0, pargs = args ; pargs != R_NilValue; pargs = CDR(pargs)) {
504
        if (nargs == MAX_ARGS)
617
        if (nargs == MAX_ARGS)
505
            errorcall(call, "too many arguments in foreign function call");
618
            errorcall(call, "too many arguments in foreign function call");
Line 1194... Line 1307...
1194
    }
1307
    }
1195
    return retval;
1308
    return retval;
1196
}
1309
}
1197
 
1310
 
1198
 
1311
 
-
 
1312
 
-
 
1313
static SEXP
-
 
1314
Rf_getCallingDLL()
-
 
1315
{
-
 
1316
    SEXP e, ans;
-
 
1317
    PROTECT(e = allocVector(LANGSXP, 1));
-
 
1318
    SETCAR(e, Rf_install("getCallingDLL"));
-
 
1319
    ans = eval(e,  R_GlobalEnv);
-
 
1320
 
-
 
1321
    UNPROTECT(1);
-
 
1322
    return(ans);
-
 
1323
}
-
 
1324
 
-
 
1325
 
-
 
1326
/*
-
 
1327
  We are given the PACKAGE argument in dll.obj
-
 
1328
  and we can try to figure out how to resolve this.
-
 
1329
  0) dll.obj is NULL.  Then find the environment of the 
-
 
1330
   calling function and if it is a namespace, get the 
-
 
1331
   
-
 
1332
  1) dll.obj is a DLLInfo object
-
 
1333
*/
-
 
1334
static DL_FUNC
-
 
1335
R_FindNativeSymbolFromDLL(char *name, DllReference *dll, R_RegisteredNativeSymbol *symbol)
-
 
1336
{
-
 
1337
    int numProtects = 0;
-
 
1338
    DllInfo *info;
-
 
1339
    DL_FUNC fun = NULL;
-
 
1340
 
-
 
1341
    if(dll->obj == NULL) {
-
 
1342
	dll->obj = Rf_getCallingDLL();
-
 
1343
	PROTECT(dll->obj); numProtects++;
-
 
1344
    }
-
 
1345
 
-
 
1346
    if(inherits(dll->obj, "DLLInfo")) {
-
 
1347
	SEXP tmp;
-
 
1348
/*XXX*/
-
 
1349
DL_FUNC R_dlsym(DllInfo *info, char const *name, R_RegisteredNativeSymbol *symbol);
-
 
1350
	tmp = VECTOR_ELT(dll->obj, 4);
-
 
1351
	info = (DllInfo *) R_ExternalPtrAddr(tmp);
-
 
1352
	if(!info) 
-
 
1353
	    error("NULL value for DLLInfoReference when looking for DLL");
-
 
1354
	fun = R_dlsym(info, name, symbol);
-
 
1355
    }
-
 
1356
 
-
 
1357
    if(numProtects)
-
 
1358
	UNPROTECT(numProtects);
-
 
1359
 
-
 
1360
    return(fun);
-
 
1361
}
-
 
1362
 
-
 
1363
 
-
 
1364
 
1199
/* .C() {op=0}  or  .Fortran() {op=1} */
1365
/* .C() {op=0}  or  .Fortran() {op=1} */
1200
SEXP do_dotCode(SEXP call, SEXP op, SEXP args, SEXP env)
1366
SEXP do_dotCode(SEXP call, SEXP op, SEXP args, SEXP env)
1201
{
1367
{
1202
    void **cargs;
1368
    void **cargs;
1203
    int dup, havenames, naok, nargs, which;
1369
    int dup, havenames, naok, nargs, which;
1204
    DL_FUNC fun;
1370
    DL_FUNC fun = NULL;
1205
    SEXP ans, pargs, s;
1371
    SEXP ans, pargs, s;
1206
    R_toCConverter  *argConverters[65]; /* the post-call converters back to R objects. */
1372
    R_toCConverter  *argConverters[65]; /* the post-call converters back to R objects. */
1207
    R_RegisteredNativeSymbol symbol = {R_C_SYM, {NULL}, NULL};
1373
    R_RegisteredNativeSymbol symbol = {R_C_SYM, {NULL}, NULL};
1208
    R_NativePrimitiveArgType *checkTypes = NULL;
1374
    R_NativePrimitiveArgType *checkTypes = NULL;
1209
    R_NativeArgStyle *argStyles = NULL;
1375
    R_NativeArgStyle *argStyles = NULL;
-
 
1376
    char *vmax, symName[128];
1210
 
1377
 
1211
    char buf[128], *p, *q, *vmax;
-
 
1212
    if (NaokSymbol == NULL || DupSymbol == NULL || PkgSymbol == NULL) {
1378
    if (NaokSymbol == NULL || DupSymbol == NULL || PkgSymbol == NULL) {
1213
	NaokSymbol = install("NAOK");
1379
	NaokSymbol = install("NAOK");
1214
	DupSymbol = install("DUP");
1380
	DupSymbol = install("DUP");
1215
	PkgSymbol = install("PACKAGE");
1381
	PkgSymbol = install("PACKAGE");
1216
    }
1382
    }
1217
    vmax = vmaxget();
1383
    vmax = vmaxget();
1218
    which = PRIMVAL(op);
1384
    which = PRIMVAL(op);
1219
    if(which)
1385
    if(which)
1220
	symbol.type = R_FORTRAN_SYM;
1386
	symbol.type = R_FORTRAN_SYM;
1221
    op = CAR(args);
-
 
1222
    if (!isValidString(op))
-
 
1223
	errorcall(call, "function name must be a string (of length 1)");
-
 
1224
 
1387
 
1225
    /* The following code modifies the argument list */
-
 
1226
    /* We know this is ok because do_dotCode is entered */
-
 
1227
    /* with its arguments evaluated. */
-
 
1228
 
-
 
1229
    strcpy(DLLname, "");
-
 
1230
    args = naokfind(CDR(args), &nargs, &naok, &dup);
1388
    args = resolveNativeRoutine(args, &fun, &symbol, symName, &nargs, &naok, &dup, call);
1231
    if(naok == NA_LOGICAL)
-
 
1232
	errorcall(call, "invalid naok value");
-
 
1233
    if(nargs > MAX_ARGS)
-
 
1234
	errorcall(call, "too many arguments in foreign function call");
-
 
1235
 
-
 
1236
    /* Make up the load symbol and look it up. */
-
 
1237
 
-
 
1238
    p = CHAR(STRING_ELT(op, 0));
-
 
1239
    q = buf;
-
 
1240
    while ((*q = *p) != '\0') {
-
 
1241
	p++;
-
 
1242
	q++;
-
 
1243
    }
-
 
1244
 
-
 
1245
    if (!(fun = R_FindSymbol(buf, DLLname, &symbol))) {
-
 
1246
	if(strlen(DLLname))
-
 
1247
	    errorcall(call, "%s function name not in DLL for package %s",
-
 
1248
		      which ? "Fortran" : "C", DLLname);
-
 
1249
	else
-
 
1250
	    errorcall(call, "%s function name not in load table",
-
 
1251
		      which ? "Fortran" : "C");
-
 
1252
    }
-
 
1253
 
1389
 
1254
    if(symbol.symbol.c && symbol.symbol.c->numArgs > -1) {
1390
    if(symbol.symbol.c && symbol.symbol.c->numArgs > -1) {
1255
	if(symbol.symbol.c->numArgs != nargs)
1391
	if(symbol.symbol.c->numArgs != nargs)
1256
	    error("Incorrect number of arguments (%d), expecting %d for %s",
1392
	    error("Incorrect number of arguments (%d), expecting %d for %s",
1257
		  nargs, symbol.symbol.c->numArgs, buf);
1393
		  nargs, symbol.symbol.c->numArgs, symName);
1258
 
1394
 
1259
        checkTypes = symbol.symbol.c->types;
1395
	checkTypes = symbol.symbol.c->types;
1260
        argStyles = symbol.symbol.c->styles;
1396
	argStyles = symbol.symbol.c->styles;
1261
    }
1397
    }
1262
 
1398
 
-
 
1399
 
1263
    /* Convert the arguments for use in foreign */
1400
    /* Convert the arguments for use in foreign */
1264
    /* function calls.  Note that we copy twice */
1401
    /* function calls.  Note that we copy twice */
1265
    /* once here, on the way into the call, and */
1402
    /* once here, on the way into the call, and */
1266
    /* once below on the way out. */
1403
    /* once below on the way out. */
1267
    cargs = (void**)R_alloc(nargs, sizeof(void*));
1404
    cargs = (void**)R_alloc(nargs, sizeof(void*));
Line 1273... Line 1410...
1273
               but then we would also want to avoid the conversions.
1410
               but then we would also want to avoid the conversions.
1274
               Also, in the future, we may just attempt to coerce the value
1411
               Also, in the future, we may just attempt to coerce the value
1275
               to the appropriate type. This is why we pass the checkTypes[nargs]
1412
               to the appropriate type. This is why we pass the checkTypes[nargs]
1276
               value to RObjToCPtr(). We just have to sort out the ability to
1413
               value to RObjToCPtr(). We just have to sort out the ability to
1277
               return the correct value which is complicated by dup, etc. */
1414
               return the correct value which is complicated by dup, etc. */
1278
  	   error("Wrong type for argument %d in call to %s", nargs+1, buf);
1415
	    error("Wrong type for argument %d in call to %s", nargs+1, symName);
1279
	}
1416
	}
1280
#endif
1417
#endif
1281
	cargs[nargs] = RObjToCPtr(CAR(pargs), naok, dup, nargs + 1,
1418
	cargs[nargs] = RObjToCPtr(CAR(pargs), naok, dup, nargs + 1,
1282
				  which, buf, argConverters + nargs,
1419
				  which, symName, argConverters + nargs,
1283
				  checkTypes ? checkTypes[nargs] : 0);
1420
				  checkTypes ? checkTypes[nargs] : 0);
1284
	nargs++;
1421
	nargs++;
1285
    }
1422
    }
1286
 
1423
 
1287
 
1424
 
Line 1884... Line 2021...
1884
    if (dup) {
2021
    if (dup) {
1885
	R_FromCConvertInfo info;
2022
	R_FromCConvertInfo info;
1886
	info.cargs = cargs;
2023
	info.cargs = cargs;
1887
	info.allArgs = args;
2024
	info.allArgs = args;
1888
	info.nargs = nargs;
2025
	info.nargs = nargs;
1889
	info.functionName = buf;
2026
	info.functionName = symName;
1890
	nargs = 0;
2027
	nargs = 0;
1891
	for (pargs = args ; pargs != R_NilValue ; pargs = CDR(pargs)) {
2028
	for (pargs = args ; pargs != R_NilValue ; pargs = CDR(pargs)) {
1892
	    if(argStyles && argStyles[nargs] == R_ARG_IN) {
2029
	    if(argStyles && argStyles[nargs] == R_ARG_IN) {
1893
	        PROTECT(s = R_NilValue);
2030
	        PROTECT(s = R_NilValue);
1894
	    } else if(argConverters[nargs]) {
2031
	    } else if(argConverters[nargs]) {