The R Project SVN R

Rev

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

Rev 66547 Rev 66552
Line 1... Line 1...
1
/*
1
/*
2
 *  R : A Computer Language for Statistical Data Analysis
2
 *  R : A Computer Language for Statistical Data Analysis
3
 *  Copyright (C) 1995  Robert Gentleman and Ross Ihaka
3
 *  Copyright (C) 1995  Robert Gentleman and Ross Ihaka
4
 *  Copyright (C) 1997--2013  The R Core Team
4
 *  Copyright (C) 1997--2014  The R Core Team
5
 *  Copyright (C) 2003	      The R Foundation
5
 *  Copyright (C) 2003	      The R Foundation
6
 *
6
 *
7
 *  This program is free software; you can redistribute it and/or modify
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  the Free Software Foundation; either version 2 of the License, or
Line 74... Line 74...
74
/* This looks up entry points in DLLs in a platform specific way. */
74
/* This looks up entry points in DLLs in a platform specific way. */
75
static DL_FUNC
75
static DL_FUNC
76
R_FindNativeSymbolFromDLL(char *name, DllReference *dll,
76
R_FindNativeSymbolFromDLL(char *name, DllReference *dll,
77
			  R_RegisteredNativeSymbol *symbol, SEXP env);
77
			  R_RegisteredNativeSymbol *symbol, SEXP env);
78
 
78
 
79
static SEXP naokfind(SEXP args, int * len, int *naok, int *dup,
79
static SEXP naokfind(SEXP args, int * len, int *naok, DllReference *dll);
80
		     DllReference *dll);
-
 
81
static SEXP pkgtrim(SEXP args, DllReference *dll);
80
static SEXP pkgtrim(SEXP args, DllReference *dll);
82
 
81
 
83
static R_INLINE Rboolean isNativeSymbolInfo(SEXP op)
82
static R_INLINE Rboolean isNativeSymbolInfo(SEXP op)
84
{
83
{
85
    /* was: inherits(op, "NativeSymbolInfo")
84
    /* was: inherits(op, "NativeSymbolInfo")
Line 188... Line 187...
188
*/
187
*/
189
 
188
 
190
static SEXP
189
static SEXP
191
resolveNativeRoutine(SEXP args, DL_FUNC *fun,
190
resolveNativeRoutine(SEXP args, DL_FUNC *fun,
192
		     R_RegisteredNativeSymbol *symbol, char *buf,
191
		     R_RegisteredNativeSymbol *symbol, char *buf,
193
		     int *nargs, int *naok, int *dup, SEXP call, SEXP env)
192
		     int *nargs, int *naok, SEXP call, SEXP env)
194
{
193
{
195
    SEXP op;
194
    SEXP op;
196
    const char *p; char *q;
195
    const char *p; char *q;
197
    DllReference dll;
196
    DllReference dll;
198
    /* This is used as shorthand for 'all' in R_FindSymbol, but
197
    /* This is used as shorthand for 'all' in R_FindSymbol, but
Line 208... Line 207...
208
    /* We know this is ok because do_dotCode is entered */
207
    /* We know this is ok because do_dotCode is entered */
209
    /* with its arguments evaluated. */
208
    /* with its arguments evaluated. */
210
 
209
 
211
    if(symbol->type == R_C_SYM || symbol->type == R_FORTRAN_SYM) {
210
    if(symbol->type == R_C_SYM || symbol->type == R_FORTRAN_SYM) {
212
	/* And that also looks for PACKAGE = */
211
	/* And that also looks for PACKAGE = */
213
	args = naokfind(CDR(args), nargs, naok, dup, &dll);
212
	args = naokfind(CDR(args), nargs, naok, &dll);
214
	if(*naok == NA_LOGICAL)
213
	if(*naok == NA_LOGICAL)
215
	    errorcall(call, _("invalid '%s' value"), "naok");
214
	    errorcall(call, _("invalid '%s' value"), "naok");
216
	if(*nargs > MAX_ARGS)
215
	if(*nargs > MAX_ARGS)
217
	    errorcall(call, _("too many arguments in foreign function call"));
216
	    errorcall(call, _("too many arguments in foreign function call"));
218
    } else {
217
    } else {
Line 327... Line 326...
327
    return(TRUE);
326
    return(TRUE);
328
}
327
}
329
 
328
 
330
 
329
 
331
static Rboolean
330
static Rboolean
332
comparePrimitiveTypes(R_NativePrimitiveArgType type, SEXP s, Rboolean dup)
331
comparePrimitiveTypes(R_NativePrimitiveArgType type, SEXP s)
333
{
332
{
334
   if(type == ANYSXP || TYPEOF(s) == type)
333
   if(type == ANYSXP || TYPEOF(s) == type)
335
      return(TRUE);
334
      return(TRUE);
336
 
335
 
337
   if(dup && type == SINGLESXP)
336
   if(type == SINGLESXP)
338
      return(asLogical(getAttrib(s, install("Csingle"))) == TRUE);
337
      return(asLogical(getAttrib(s, install("Csingle"))) == TRUE);
339
 
338
 
340
   return(FALSE);
339
   return(FALSE);
341
}
340
}
342
 
341
 
Line 345... Line 344...
345
/* or Fortran code which is either statically or dynamically linked. */
344
/* or Fortran code which is either statically or dynamically linked. */
346
 
345
 
347
/* NB: this leaves NAOK and DUP arguments on the list */
346
/* NB: this leaves NAOK and DUP arguments on the list */
348
 
347
 
349
/* find NAOK and DUP, find and remove PACKAGE */
348
/* find NAOK and DUP, find and remove PACKAGE */
350
static SEXP naokfind(SEXP args, int * len, int *naok, int *dup,
349
static SEXP naokfind(SEXP args, int * len, int *naok, DllReference *dll)
351
		     DllReference *dll)
-
 
352
{
350
{
353
    SEXP s, prev;
351
    SEXP s, prev;
354
    int nargs=0, naokused=0, dupused=0, pkgused=0;
352
    int nargs=0, naokused=0, dupused=0, pkgused=0;
355
    const char *p;
353
    const char *p;
356
 
354
 
357
    *naok = 0;
355
    *naok = 0;
358
    *dup = 1;
-
 
359
    *len = 0;
356
    *len = 0;
360
    for(s = args, prev=args; s != R_NilValue;) {
357
    for(s = args, prev=args; s != R_NilValue;) {
361
	if(TAG(s) == NaokSymbol) {
358
	if(TAG(s) == NaokSymbol) {
362
	    *naok = asLogical(CAR(s));
359
	    *naok = asLogical(CAR(s));
363
	    /* SETCDR(prev, s = CDR(s)); */
-
 
364
	    if(naokused++ == 1) warning(_("'%s' used more than once"), "NAOK");
360
	    if(naokused++ == 1) warning(_("'%s' used more than once"), "NAOK");
365
	} else if(TAG(s) == DupSymbol) {
361
	} else if(TAG(s) == DupSymbol) {
366
	    *dup = asLogical(CAR(s));
-
 
367
	    /* SETCDR(prev, s = CDR(s)); */
-
 
368
	    if(dupused++ == 1) warning(_("'%s' used more than once"), "DUP");
362
	    if(dupused++ == 1) warning(_("'%s' used more than once"), "DUP");
369
	} else if(TAG(s) == PkgSymbol) {
363
	} else if(TAG(s) == PkgSymbol) {
370
	    dll->obj = CAR(s);  // really?
364
	    dll->obj = CAR(s);  // really?
371
	    if(TYPEOF(CAR(s)) == STRSXP) {
365
	    if(TYPEOF(CAR(s)) == STRSXP) {
372
		p = translateChar(STRING_ELT(CAR(s), 0));
366
		p = translateChar(STRING_ELT(CAR(s), 0));
Line 526... Line 520...
526
    char buf[MaxSymbolBytes];
520
    char buf[MaxSymbolBytes];
527
 
521
 
528
    if (length(args) < 1) errorcall(call, _("'.NAME' is missing"));
522
    if (length(args) < 1) errorcall(call, _("'.NAME' is missing"));
529
    check1arg2(args, call, ".NAME");
523
    check1arg2(args, call, ".NAME");
530
    args = resolveNativeRoutine(args, &ofun, &symbol, buf, NULL, NULL,
524
    args = resolveNativeRoutine(args, &ofun, &symbol, buf, NULL, NULL,
531
				NULL, call, env);
525
				call, env);
532
 
526
 
533
    if(symbol.symbol.external && symbol.symbol.external->numArgs > -1) {
527
    if(symbol.symbol.external && symbol.symbol.external->numArgs > -1) {
534
	int nargs = length(args) - 1;
528
	int nargs = length(args) - 1;
535
	if(symbol.symbol.external->numArgs != nargs)
529
	if(symbol.symbol.external->numArgs != nargs)
536
	    errorcall(call,
530
	    errorcall(call,
Line 568... Line 562...
568
    char buf[MaxSymbolBytes];
562
    char buf[MaxSymbolBytes];
569
 
563
 
570
    if (length(args) < 1) errorcall(call, _("'.NAME' is missing"));
564
    if (length(args) < 1) errorcall(call, _("'.NAME' is missing"));
571
    check1arg2(args, call, ".NAME");
565
    check1arg2(args, call, ".NAME");
572
 
566
 
573
    args = resolveNativeRoutine(args, &ofun, &symbol, buf, NULL, NULL,
567
    args = resolveNativeRoutine(args, &ofun, &symbol, buf, NULL, NULL, call, env);
574
				NULL, call, env);
-
 
575
    args = CDR(args);
568
    args = CDR(args);
576
 
569
 
577
    for(nargs = 0, pargs = args ; pargs != R_NilValue; pargs = CDR(pargs)) {
570
    for(nargs = 0, pargs = args ; pargs != R_NilValue; pargs = CDR(pargs)) {
578
	if (nargs == MAX_ARGS)
571
	if (nargs == MAX_ARGS)
579
	    errorcall(call, _("too many arguments in foreign function call"));
572
	    errorcall(call, _("too many arguments in foreign function call"));
Line 1397... Line 1390...
1397
#define NG 64
1390
#define NG 64
1398
 
1391
 
1399
SEXP attribute_hidden do_dotCode(SEXP call, SEXP op, SEXP args, SEXP env)
1392
SEXP attribute_hidden do_dotCode(SEXP call, SEXP op, SEXP args, SEXP env)
1400
{
1393
{
1401
    void **cargs, **cargs0 = NULL /* -Wall */;
1394
    void **cargs, **cargs0 = NULL /* -Wall */;
1402
    int dup, naok, na, nargs, Fort;
1395
    int naok, na, nargs, Fort;
1403
    Rboolean havenames, copy = R_CBoundsCheck; /* options(CboundsCheck) */
1396
    Rboolean havenames, copy = R_CBoundsCheck; /* options(CboundsCheck) */
1404
    DL_FUNC ofun = NULL;
1397
    DL_FUNC ofun = NULL;
1405
    VarFun fun = NULL;
1398
    VarFun fun = NULL;
1406
    SEXP ans, pa, s;
1399
    SEXP ans, pa, s;
1407
    R_RegisteredNativeSymbol symbol = {R_C_SYM, {NULL}, NULL};
1400
    R_RegisteredNativeSymbol symbol = {R_C_SYM, {NULL}, NULL};
Line 1423... Line 1416...
1423
    Fort = PRIMVAL(op);
1416
    Fort = PRIMVAL(op);
1424
    if(Fort) symbol.type = R_FORTRAN_SYM;
1417
    if(Fort) symbol.type = R_FORTRAN_SYM;
1425
 
1418
 
1426
    args = enctrim(args);
1419
    args = enctrim(args);
1427
    args = resolveNativeRoutine(args, &ofun, &symbol, symName, &nargs,
1420
    args = resolveNativeRoutine(args, &ofun, &symbol, symName, &nargs,
1428
				&naok, &dup, call, env);
1421
				&naok, call, env);
1429
    dup = 1; // for now: clean up later
-
 
1430
    fun = (VarFun) ofun;
1422
    fun = (VarFun) ofun;
1431
 
1423
 
1432
    if(symbol.symbol.c && symbol.symbol.c->numArgs > -1) {
1424
    if(symbol.symbol.c && symbol.symbol.c->numArgs > -1) {
1433
	if(symbol.symbol.c->numArgs != nargs)
1425
	if(symbol.symbol.c->numArgs != nargs)
1434
	    errorcall(call,
1426
	    errorcall(call,
Line 1464... Line 1456...
1464
    /* Convert the arguments for use in foreign function calls. */
1456
    /* Convert the arguments for use in foreign function calls. */
1465
    cargs = (void**) R_alloc(nargs, sizeof(void*));
1457
    cargs = (void**) R_alloc(nargs, sizeof(void*));
1466
    if (copy) cargs0 = (void**) R_alloc(nargs, sizeof(void*));
1458
    if (copy) cargs0 = (void**) R_alloc(nargs, sizeof(void*));
1467
    for(na = 0, pa = args ; pa != R_NilValue; pa = CDR(pa), na++) {
1459
    for(na = 0, pa = args ; pa != R_NilValue; pa = CDR(pa), na++) {
1468
	if(checkTypes &&
1460
	if(checkTypes &&
1469
	   !comparePrimitiveTypes(checkTypes[na], CAR(pa), dup)) {
1461
	   !comparePrimitiveTypes(checkTypes[na], CAR(pa))) {
1470
	    /* We can loop over all the arguments and report all the
1462
	    /* We can loop over all the arguments and report all the
1471
	       erroneous ones, but then we would also want to avoid
1463
	       erroneous ones, but then we would also want to avoid
1472
	       the conversions.  Also, in the future, we may just
1464
	       the conversions.  Also, in the future, we may just
1473
	       attempt to coerce the value to the appropriate
1465
	       attempt to coerce the value to the appropriate
1474
	       type. */
1466
	       type. */
Line 1477... Line 1469...
1477
	}
1469
	}
1478
	int nprotect = 0, targetType =  checkTypes ? checkTypes[na] : 0;
1470
	int nprotect = 0, targetType =  checkTypes ? checkTypes[na] : 0;
1479
	R_xlen_t n;
1471
	R_xlen_t n;
1480
	s = CAR(pa);
1472
	s = CAR(pa);
1481
	/* start with return value a copy of the inputs, as that is
1473
	/* start with return value a copy of the inputs, as that is
1482
	   what is needed for DUP = FALSE and for non-atomic-vector inputs */
1474
	   what is needed for non-atomic-vector inputs */
1483
	SET_VECTOR_ELT(ans, na, s);
1475
	SET_VECTOR_ELT(ans, na, s);
1484
 
1476
 
1485
	if(checkNativeType(targetType, TYPEOF(s)) == FALSE) {
1477
	if(checkNativeType(targetType, TYPEOF(s)) == FALSE &&
1486
	    if(!dup) {
-
 
1487
		error(_("explicit request not to duplicate arguments in call to '%s', but argument %d is of the wrong type (%d != %d)"),
-
 
1488
		      symName, na + 1, targetType, TYPEOF(s));
-
 
1489
	    }
-
 
1490
 
-
 
1491
	    if(targetType != SINGLESXP) {
1478
	   targetType != SINGLESXP) {
1492
		/* Cannot be called if DUP = FALSE, so only needs to live
1479
	    /* Cannot be called if DUP = FALSE, so only needs to live
1493
		   until copied in the switch.
1480
	       until copied in the switch.
1494
		   But R_alloc allocates, so missed protection < R 2.15.0.
1481
	       But R_alloc allocates, so missed protection < R 2.15.0.
1495
		*/
1482
	    */
1496
		PROTECT(s = coerceVector(s, targetType));
1483
	    PROTECT(s = coerceVector(s, targetType));
1497
		nprotect++;
1484
	    nprotect++;
1498
	    }
-
 
1499
	}
1485
	}
1500
 
1486
 
1501
	/* We create any copies needed for the return value here,
1487
	/* We create any copies needed for the return value here,
1502
	   except for character vectors.  The compiled code works on
1488
	   except for character vectors.  The compiled code works on
1503
	   the data pointer of the return value for the other atomic
1489
	   the data pointer of the return value for the other atomic
Line 1511... Line 1497...
1511
		  na + 1, Fort ? ".C" : ".Fortran");
1497
		  na + 1, Fort ? ".C" : ".Fortran");
1512
#endif
1498
#endif
1513
	SEXPTYPE t = TYPEOF(s);
1499
	SEXPTYPE t = TYPEOF(s);
1514
	switch(t) {
1500
	switch(t) {
1515
	case RAWSXP:
1501
	case RAWSXP:
1516
	    if (copy && dup) {
1502
	    if (copy) {
1517
		n = XLENGTH(s);
1503
		n = XLENGTH(s);
1518
		char *ptr = R_alloc(n * sizeof(Rbyte) + 2 * NG, 1);
1504
		char *ptr = R_alloc(n * sizeof(Rbyte) + 2 * NG, 1);
1519
		memset(ptr, FILL, n * sizeof(Rbyte) + 2 * NG);
1505
		memset(ptr, FILL, n * sizeof(Rbyte) + 2 * NG);
1520
		ptr += NG;
1506
		ptr += NG;
1521
		memcpy(ptr, RAW(s), n);
1507
		memcpy(ptr, RAW(s), n);
1522
		cargs[na] = (void *) ptr;
1508
		cargs[na] = (void *) ptr;
1523
	    } else if (dup && MAYBE_REFERENCED(s)) {
1509
	    } else if (MAYBE_REFERENCED(s)) {
1524
		n = XLENGTH(s);
1510
		n = XLENGTH(s);
1525
		SEXP ss = allocVector(t, n);
1511
		SEXP ss = allocVector(t, n);
1526
		memcpy(RAW(ss), RAW(s), n * sizeof(Rbyte));
1512
		memcpy(RAW(ss), RAW(s), n * sizeof(Rbyte));
1527
		SET_VECTOR_ELT(ans, na, ss);
1513
		SET_VECTOR_ELT(ans, na, ss);
1528
		cargs[na] = (void*) RAW(ss);
1514
		cargs[na] = (void*) RAW(ss);
Line 1537... Line 1523...
1537
	    int *iptr = INTEGER(s);
1523
	    int *iptr = INTEGER(s);
1538
	    if (!naok)
1524
	    if (!naok)
1539
		for (R_xlen_t i = 0 ; i < n ; i++)
1525
		for (R_xlen_t i = 0 ; i < n ; i++)
1540
		    if(iptr[i] == NA_INTEGER)
1526
		    if(iptr[i] == NA_INTEGER)
1541
			error(_("NAs in foreign function call (arg %d)"), na + 1);
1527
			error(_("NAs in foreign function call (arg %d)"), na + 1);
1542
	    if (copy && dup) {
1528
	    if (copy) {
1543
		char *ptr = R_alloc(n * sizeof(int) + 2 * NG, 1);
1529
		char *ptr = R_alloc(n * sizeof(int) + 2 * NG, 1);
1544
		memset(ptr, FILL, n * sizeof(int) + 2 * NG);
1530
		memset(ptr, FILL, n * sizeof(int) + 2 * NG);
1545
		ptr += NG;
1531
		ptr += NG;
1546
		memcpy(ptr, INTEGER(s), n * sizeof(int));
1532
		memcpy(ptr, INTEGER(s), n * sizeof(int));
1547
		cargs[na] = (void*) ptr;
1533
		cargs[na] = (void*) ptr;
1548
	    } else if (dup && MAYBE_REFERENCED(s)) {
1534
	    } else if (MAYBE_REFERENCED(s)) {
1549
		SEXP ss = allocVector(t, n);
1535
		SEXP ss = allocVector(t, n);
1550
		memcpy(INTEGER(ss), INTEGER(s), n * sizeof(int));
1536
		memcpy(INTEGER(ss), INTEGER(s), n * sizeof(int));
1551
		SET_VECTOR_ELT(ans, na, ss);
1537
		SET_VECTOR_ELT(ans, na, ss);
1552
		cargs[na] = (void*) INTEGER(ss);
1538
		cargs[na] = (void*) INTEGER(ss);
1553
#ifdef R_MEMORY_PROFILING
1539
#ifdef R_MEMORY_PROFILING
Line 1564... Line 1550...
1564
			error(_("NA/NaN/Inf in foreign function call (arg %d)"), na + 1);
1550
			error(_("NA/NaN/Inf in foreign function call (arg %d)"), na + 1);
1565
	    if (asLogical(getAttrib(s, CSingSymbol)) == 1) {
1551
	    if (asLogical(getAttrib(s, CSingSymbol)) == 1) {
1566
		float *sptr = (float*) R_alloc(n, sizeof(float));
1552
		float *sptr = (float*) R_alloc(n, sizeof(float));
1567
		for (R_xlen_t i = 0 ; i < n ; i++) sptr[i] = (float) REAL(s)[i];
1553
		for (R_xlen_t i = 0 ; i < n ; i++) sptr[i] = (float) REAL(s)[i];
1568
		cargs[na] = (void*) sptr;
1554
		cargs[na] = (void*) sptr;
1569
		if (!dup) warning(_("single values not returned if not duplicated"));
-
 
1570
#ifdef R_MEMORY_PROFILING
1555
#ifdef R_MEMORY_PROFILING
1571
		if (RTRACE(s)) memtrace_report(s, sptr);
1556
		if (RTRACE(s)) memtrace_report(s, sptr);
1572
#endif
1557
#endif
1573
	    } else if (copy && dup) {
1558
	    } else if (copy) {
1574
		char *ptr = R_alloc(n * sizeof(double) + 2 * NG, 1);
1559
		char *ptr = R_alloc(n * sizeof(double) + 2 * NG, 1);
1575
		memset(ptr, FILL, n * sizeof(double) + 2 * NG);
1560
		memset(ptr, FILL, n * sizeof(double) + 2 * NG);
1576
		ptr += NG;
1561
		ptr += NG;
1577
		memcpy(ptr, REAL(s), n * sizeof(double));
1562
		memcpy(ptr, REAL(s), n * sizeof(double));
1578
		cargs[na] = (void*) ptr;
1563
		cargs[na] = (void*) ptr;
1579
	    } else if (dup && MAYBE_REFERENCED(s)) {
1564
	    } else if (MAYBE_REFERENCED(s)) {
1580
		SEXP ss  = allocVector(t, n);
1565
		SEXP ss  = allocVector(t, n);
1581
		memcpy(REAL(ss), REAL(s), n * sizeof(double));
1566
		memcpy(REAL(ss), REAL(s), n * sizeof(double));
1582
		SET_VECTOR_ELT(ans, na, ss);
1567
		SET_VECTOR_ELT(ans, na, ss);
1583
		cargs[na] = (void*) REAL(ss);
1568
		cargs[na] = (void*) REAL(ss);
1584
#ifdef R_MEMORY_PROFILING
1569
#ifdef R_MEMORY_PROFILING
Line 1591... Line 1576...
1591
	    Rcomplex *zptr = COMPLEX(s);
1576
	    Rcomplex *zptr = COMPLEX(s);
1592
	    if (!naok)
1577
	    if (!naok)
1593
		for (R_xlen_t i = 0 ; i < n ; i++)
1578
		for (R_xlen_t i = 0 ; i < n ; i++)
1594
		    if(!R_FINITE(zptr[i].r) || !R_FINITE(zptr[i].i))
1579
		    if(!R_FINITE(zptr[i].r) || !R_FINITE(zptr[i].i))
1595
			error(_("complex NA/NaN/Inf in foreign function call (arg %d)"), na + 1);
1580
			error(_("complex NA/NaN/Inf in foreign function call (arg %d)"), na + 1);
1596
	    if (copy && dup) {
1581
	    if (copy) {
1597
		char *ptr = R_alloc(n * sizeof(Rcomplex) + 2 * NG, 1);
1582
		char *ptr = R_alloc(n * sizeof(Rcomplex) + 2 * NG, 1);
1598
		memset(ptr, FILL, n * sizeof(Rcomplex) + 2 * NG);
1583
		memset(ptr, FILL, n * sizeof(Rcomplex) + 2 * NG);
1599
		ptr += NG;
1584
		ptr += NG;
1600
		memcpy(ptr, COMPLEX(s), n * sizeof(Rcomplex));
1585
		memcpy(ptr, COMPLEX(s), n * sizeof(Rcomplex));
1601
		cargs[na] = (void*) ptr;
1586
		cargs[na] = (void*) ptr;
1602
	    } else if (dup && MAYBE_REFERENCED(s)) {
1587
	    } else if (MAYBE_REFERENCED(s)) {
1603
		SEXP ss = allocVector(t, n);
1588
		SEXP ss = allocVector(t, n);
1604
		memcpy(COMPLEX(ss), COMPLEX(s), n * sizeof(Rcomplex));
1589
		memcpy(COMPLEX(ss), COMPLEX(s), n * sizeof(Rcomplex));
1605
		SET_VECTOR_ELT(ans, na, ss);
1590
		SET_VECTOR_ELT(ans, na, ss);
1606
		cargs[na] = (void*) COMPLEX(ss);
1591
		cargs[na] = (void*) COMPLEX(ss);
1607
#ifdef R_MEMORY_PROFILING
1592
#ifdef R_MEMORY_PROFILING
1608
		if (RTRACE(s)) memtrace_report(s, ss);
1593
		if (RTRACE(s)) memtrace_report(s, ss);
1609
#endif
1594
#endif
1610
	    } else cargs[na] = (void *) zptr;
1595
	    } else cargs[na] = (void *) zptr;
1611
	    break;
1596
	    break;
1612
	case STRSXP:
1597
	case STRSXP:
1613
	    if (!dup)
-
 
1614
		error(_("character variables must be duplicated in .C/.Fortran"));
-
 
1615
	    n = XLENGTH(s);
1598
	    n = XLENGTH(s);
1616
	    if (Fort) {
1599
	    if (Fort) {
1617
		const char *ss = translateChar(STRING_ELT(s, 0));
1600
		const char *ss = translateChar(STRING_ELT(s, 0));
1618
		if (n > 1)
1601
		if (n > 1)
1619
		    warning(_("only first string in char vector used in .Fortran"));
1602
		    warning(_("only first string in char vector used in .Fortran"));
Line 2291... Line 2274...
2291
	break;
2274
	break;
2292
    default:
2275
    default:
2293
	errorcall(call, _("too many arguments, sorry"));
2276
	errorcall(call, _("too many arguments, sorry"));
2294
    }
2277
    }
2295
 
2278
 
2296
    if (dup) {
-
 
2297
 
-
 
2298
	for (na = 0, pa = args ; pa != R_NilValue ; pa = CDR(pa), na++) {
2279
    for (na = 0, pa = args ; pa != R_NilValue ; pa = CDR(pa), na++) {
2299
	    if(argStyles && argStyles[na] == R_ARG_IN) {
2280
	if(argStyles && argStyles[na] == R_ARG_IN) {
2300
		SET_VECTOR_ELT(ans, na, R_NilValue);
2281
	    SET_VECTOR_ELT(ans, na, R_NilValue);
2301
		continue;
2282
	    continue;
2302
	    } else {
2283
	} else {
2303
		void *p = cargs[na];
2284
	    void *p = cargs[na];
2304
		SEXP arg = CAR(pa);
2285
	    SEXP arg = CAR(pa);
2305
		s = VECTOR_ELT(ans, na);
2286
	    s = VECTOR_ELT(ans, na);
2306
		R_NativePrimitiveArgType type =
2287
	    R_NativePrimitiveArgType type =
2307
		    checkTypes ? checkTypes[na] : TYPEOF(arg);
2288
		checkTypes ? checkTypes[na] : TYPEOF(arg);
2308
	        R_xlen_t n = xlength(arg);
2289
	    R_xlen_t n = xlength(arg);
2309
 
2290
 
2310
		switch(type) {
2291
	    switch(type) {
2311
		case RAWSXP:
2292
	    case RAWSXP:
2312
		    if (copy) {
2293
		if (copy) {
2313
			s = allocVector(type, n);
2294
		    s = allocVector(type, n);
2314
			unsigned char *ptr = (unsigned char *) p;
2295
		    unsigned char *ptr = (unsigned char *) p;
2315
			memcpy(RAW(s), ptr, n * sizeof(Rbyte));
2296
		    memcpy(RAW(s), ptr, n * sizeof(Rbyte));
2316
			ptr += n * sizeof(Rbyte);
2297
		    ptr += n * sizeof(Rbyte);
-
 
2298
		    for (int i = 0; i < NG; i++)
-
 
2299
			if(*ptr++ != FILL)
-
 
2300
			    error("array over-run in %s(\"%s\") in %s argument %d\n",
-
 
2301
				  Fort ? ".Fortran" : ".C",
-
 
2302
				  symName, type2char(type), na+1);
-
 
2303
		    ptr = (unsigned char *) p;
-
 
2304
		    for (int i = 0; i < NG; i++)
-
 
2305
			if(*--ptr != FILL)
-
 
2306
			    error("array under-run in %s(\"%s\") in %s argument %d\n",
-
 
2307
				  Fort ? ".Fortran" : ".C",
-
 
2308
				  symName, type2char(type), na+1);
-
 
2309
		}
-
 
2310
		break;
-
 
2311
	    case INTSXP:
-
 
2312
		if (copy) {
-
 
2313
		    s = allocVector(type, n);
-
 
2314
		    unsigned char *ptr = (unsigned char *) p;
-
 
2315
		    memcpy(INTEGER(s), ptr, n * sizeof(int));
-
 
2316
		    ptr += n * sizeof(int);
2317
			for (int i = 0; i < NG; i++)
2317
		    for (int i = 0; i < NG; i++)
2318
			    if(*ptr++ != FILL)
2318
			if(*ptr++ != FILL)
2319
				error("array over-run in %s(\"%s\") in %s argument %d\n",
2319
			    error("array over-run in %s(\"%s\") in %s argument %d\n",
2320
				      Fort ? ".Fortran" : ".C",
2320
				  Fort ? ".Fortran" : ".C",
2321
				      symName, type2char(type), na+1);
2321
				  symName, type2char(type), na+1);
2322
			ptr = (unsigned char *) p;
2322
		    ptr = (unsigned char *) p;
2323
			for (int i = 0; i < NG; i++)
2323
		    for (int i = 0; i < NG; i++)
2324
			    if(*--ptr != FILL)
2324
			if(*--ptr != FILL)
2325
				error("array under-run in %s(\"%s\") in %s argument %d\n",
2325
			    error("array under-run in %s(\"%s\") in %s argument %d\n",
2326
				      Fort ? ".Fortran" : ".C",
2326
				  Fort ? ".Fortran" : ".C",
2327
				      symName, type2char(type), na+1);
2327
				  symName, type2char(type), na+1);
-
 
2328
		}
-
 
2329
		break;
-
 
2330
	    case LGLSXP:
-
 
2331
		if (copy) {
-
 
2332
		    s = allocVector(type, n);
-
 
2333
		    unsigned char *ptr = (unsigned char *) p;
-
 
2334
		    int *iptr = (int*) ptr, tmp;
-
 
2335
		    for (R_xlen_t i = 0 ; i < n ; i++) {
-
 
2336
			tmp =  iptr[i];
-
 
2337
			LOGICAL(s)[i] = (tmp == NA_INTEGER || tmp == 0) ? tmp : 1;
2328
		    }
2338
		    }
2329
		    break;
-
 
2330
		case INTSXP:
-
 
2331
		    if (copy) {
-
 
2332
			s = allocVector(type, n);
-
 
2333
			unsigned char *ptr = (unsigned char *) p;
-
 
2334
			memcpy(INTEGER(s), ptr, n * sizeof(int));
-
 
2335
			ptr += n * sizeof(int);
2339
		    ptr += n * sizeof(int);
2336
			for (int i = 0; i < NG; i++)
2340
		    for (int i = 0; i < NG;  i++)
2337
			    if(*ptr++ != FILL)
2341
			if(*ptr++ != FILL)
2338
				error("array over-run in %s(\"%s\") in %s argument %d\n",
2342
			    error("array over-run in %s(\"%s\") in %s argument %d\n",
2339
				      Fort ? ".Fortran" : ".C",
2343
				  Fort ? ".Fortran" : ".C",
2340
				      symName, type2char(type), na+1);
2344
				  symName, type2char(type), na+1);
2341
			ptr = (unsigned char *) p;
2345
		    ptr = (unsigned char *) p;
2342
			for (int i = 0; i < NG; i++)
2346
		    for (int i = 0; i < NG; i++)
2343
			    if(*--ptr != FILL)
2347
			if(*--ptr != FILL)
2344
				error("array under-run in %s(\"%s\") in %s argument %d\n",
2348
			    error("array under-run in %s(\"%s\") in %s argument %d\n",
2345
				      Fort ? ".Fortran" : ".C",
2349
				  Fort ? ".Fortran" : ".C",
2346
				      symName, type2char(type), na+1);
2350
				  symName, type2char(type), na+1);
-
 
2351
		} else {
-
 
2352
		    int *iptr = INTEGER(arg), tmp;
-
 
2353
		    for (R_xlen_t i = 0 ; i < n ; i++) {
-
 
2354
			tmp =  iptr[i];
-
 
2355
			iptr[i] = (tmp == NA_INTEGER || tmp == 0) ? tmp : 1;
2347
		    }
2356
		    }
-
 
2357
		}
2348
		    break;
2358
		break;
2349
		case LGLSXP:
2359
	    case REALSXP:
-
 
2360
	    case SINGLESXP:
2350
		    if (copy) {
2361
		if (copy) {
2351
			s = allocVector(type, n);
2362
		    s = allocVector(REALSXP, n);
-
 
2363
		    if (type == SINGLESXP || asLogical(getAttrib(arg, CSingSymbol)) == 1) {
-
 
2364
			float *sptr = (float*) p;
-
 
2365
			for(R_xlen_t i = 0 ; i < n ; i++)
-
 
2366
			    REAL(s)[i] = (double) sptr[i];
-
 
2367
		    } else {
2352
			unsigned char *ptr = (unsigned char *) p;
2368
			unsigned char *ptr = (unsigned char *) p;
2353
			int *iptr = (int*) ptr, tmp;
-
 
2354
			for (R_xlen_t i = 0 ; i < n ; i++) {
2369
			memcpy(REAL(s), ptr, n * sizeof(double));
2355
			    tmp =  iptr[i];
-
 
2356
			    LOGICAL(s)[i] = (tmp == NA_INTEGER || tmp == 0) ? tmp : 1;
-
 
2357
			}
-
 
2358
			ptr += n * sizeof(int);
2370
			ptr += n * sizeof(double);
2359
			for (int i = 0; i < NG;  i++)
2371
			for (int i = 0; i < NG; i++)
2360
			    if(*ptr++ != FILL)
2372
			    if(*ptr++ != FILL)
2361
				error("array over-run in %s(\"%s\") in %s argument %d\n",
2373
				error("array over-run in %s(\"%s\") in %s argument %d\n",
2362
				      Fort ? ".Fortran" : ".C",
2374
				      Fort ? ".Fortran" : ".C",
2363
				      symName, type2char(type), na+1);
2375
				      symName, type2char(type), na+1);
2364
			ptr = (unsigned char *) p;
2376
			ptr = (unsigned char *) p;
2365
			for (int i = 0; i < NG; i++)
2377
			for (int i = 0; i < NG; i++)
2366
			    if(*--ptr != FILL)
2378
			    if(*--ptr != FILL)
2367
				error("array under-run in %s(\"%s\") in %s argument %d\n",
2379
				error("array under-run in %s(\"%s\") in %s argument %d\n",
2368
				      Fort ? ".Fortran" : ".C",
2380
				      Fort ? ".Fortran" : ".C",
2369
				      symName, type2char(type), na+1);
2381
				      symName, type2char(type), na+1);
2370
		    } else {
-
 
2371
			int *iptr = INTEGER(arg), tmp;
-
 
2372
			for (R_xlen_t i = 0 ; i < n ; i++) {
-
 
2373
			    tmp =  iptr[i];
-
 
2374
			    iptr[i] = (tmp == NA_INTEGER || tmp == 0) ? tmp : 1;
-
 
2375
			}
-
 
2376
		    }
2382
		    }
2377
		    break;
2383
		} else {
2378
		case REALSXP:
-
 
2379
		case SINGLESXP:
-
 
2380
		    if (copy) {
2384
		    if (type == SINGLESXP || asLogical(getAttrib(arg, CSingSymbol)) == 1) {
2381
			s = allocVector(REALSXP, n);
2385
			s = allocVector(REALSXP, n);
2382
			if (type == SINGLESXP || asLogical(getAttrib(arg, CSingSymbol)) == 1) {
-
 
2383
			    float *sptr = (float*) p;
2386
			float *sptr = (float*) p;
2384
			    for(R_xlen_t i = 0 ; i < n ; i++)
-
 
2385
				REAL(s)[i] = (double) sptr[i];
-
 
2386
			} else {
-
 
2387
			    unsigned char *ptr = (unsigned char *) p;
-
 
2388
			    memcpy(REAL(s), ptr, n * sizeof(double));
-
 
2389
			    ptr += n * sizeof(double);
-
 
2390
			    for (int i = 0; i < NG; i++)
-
 
2391
				if(*ptr++ != FILL)
-
 
2392
				    error("array over-run in %s(\"%s\") in %s argument %d\n",
-
 
2393
					  Fort ? ".Fortran" : ".C",
-
 
2394
					  symName, type2char(type), na+1);
-
 
2395
			    ptr = (unsigned char *) p;
-
 
2396
			    for (int i = 0; i < NG; i++)
-
 
2397
				if(*--ptr != FILL)
-
 
2398
				    error("array under-run in %s(\"%s\") in %s argument %d\n",
-
 
2399
					  Fort ? ".Fortran" : ".C",
-
 
2400
					  symName, type2char(type), na+1);
-
 
2401
			}
-
 
2402
		    } else {
-
 
2403
			if (type == SINGLESXP || asLogical(getAttrib(arg, CSingSymbol)) == 1) {
-
 
2404
			    s = allocVector(REALSXP, n);
-
 
2405
			    float *sptr = (float*) p;
-
 
2406
			    for(int i = 0 ; i < n ; i++)
2387
			for(int i = 0 ; i < n ; i++)
2407
				REAL(s)[i] = (double) sptr[i];
2388
			    REAL(s)[i] = (double) sptr[i];
2408
			}
-
 
2409
		    }
2389
		    }
-
 
2390
		}
2410
		    break;
2391
		break;
2411
		case CPLXSXP:
2392
	    case CPLXSXP:
2412
		    if (copy) {
2393
		if (copy) {
2413
			s = allocVector(type, n);
2394
		    s = allocVector(type, n);
2414
			unsigned char *ptr = (unsigned char *) p;
2395
		    unsigned char *ptr = (unsigned char *) p;
2415
			memcpy(COMPLEX(s), p, n * sizeof(Rcomplex));
2396
		    memcpy(COMPLEX(s), p, n * sizeof(Rcomplex));
2416
			ptr += n * sizeof(Rcomplex);
2397
		    ptr += n * sizeof(Rcomplex);
2417
			for (int i = 0; i < NG;  i++)
2398
		    for (int i = 0; i < NG;  i++)
2418
			    if(*ptr++ != FILL)
2399
			if(*ptr++ != FILL)
2419
				error("array over-run in %s(\"%s\") in %s argument %d\n",
2400
			    error("array over-run in %s(\"%s\") in %s argument %d\n",
2420
				      Fort ? ".Fortran" : ".C",
2401
				  Fort ? ".Fortran" : ".C",
2421
				      symName, type2char(type), na+1);
2402
				  symName, type2char(type), na+1);
2422
			ptr = (unsigned char *) p;
2403
		    ptr = (unsigned char *) p;
2423
			for (int i = 0; i < NG; i++)
2404
		    for (int i = 0; i < NG; i++)
2424
			    if(*--ptr != FILL)
2405
			if(*--ptr != FILL)
2425
				error("array under-run in %s(\"%s\") in %s argument %d\n",
2406
			    error("array under-run in %s(\"%s\") in %s argument %d\n",
2426
				      Fort ? ".Fortran" : ".C",
2407
				  Fort ? ".Fortran" : ".C",
2427
				      symName, type2char(type), na+1);
2408
				  symName, type2char(type), na+1);
2428
		    }
2409
		}
2429
		    break;
2410
		break;
2430
		case STRSXP:
2411
	    case STRSXP:
2431
		    if(Fort) {
2412
		if(Fort) {
2432
			char buf[256];
2413
		    char buf[256];
2433
			/* only return one string: warned on the R -> Fortran step */
2414
		    /* only return one string: warned on the R -> Fortran step */
2434
			strncpy(buf, (char*)p, 255);
2415
		    strncpy(buf, (char*)p, 255);
2435
			buf[255] = '\0';
2416
		    buf[255] = '\0';
2436
			PROTECT(s = allocVector(type, 1));
2417
		    PROTECT(s = allocVector(type, 1));
2437
			SET_STRING_ELT(s, 0, mkChar(buf));
2418
		    SET_STRING_ELT(s, 0, mkChar(buf));
2438
			UNPROTECT(1);
2419
		    UNPROTECT(1);
2439
		    } else if (copy) {
2420
		} else if (copy) {
2440
			SEXP ss = arg;
2421
		    SEXP ss = arg;
2441
			PROTECT(s = allocVector(type, n));
2422
		    PROTECT(s = allocVector(type, n));
2442
			char **cptr = (char**) p, **cptr0 = (char**) cargs0[na];
2423
		    char **cptr = (char**) p, **cptr0 = (char**) cargs0[na];
2443
			for (R_xlen_t i = 0 ; i < n ; i++) {
2424
		    for (R_xlen_t i = 0 ; i < n ; i++) {
2444
			    unsigned char *ptr = (unsigned char *) cptr[i];
2425
			unsigned char *ptr = (unsigned char *) cptr[i];
2445
			    SET_STRING_ELT(s, i, mkChar(cptr[i]));
2426
			SET_STRING_ELT(s, i, mkChar(cptr[i]));
2446
			    if (cptr[i] == cptr0[i]) {
2427
			if (cptr[i] == cptr0[i]) {
2447
				    const char *z = translateChar(STRING_ELT(ss, i));
2428
			    const char *z = translateChar(STRING_ELT(ss, i));
2448
				for (int j = 0; j < NG; j++)
2429
			    for (int j = 0; j < NG; j++)
2449
				    if(*--ptr != FILL)
2430
				if(*--ptr != FILL)
2450
					error("array under-run in .C(\"%s\") in character argument %d, element %d",
2431
				    error("array under-run in .C(\"%s\") in character argument %d, element %d",
2451
					      symName, na+1, (int)(i+1));
2432
					  symName, na+1, (int)(i+1));
2452
				ptr = (unsigned char *) cptr[i];
2433
			    ptr = (unsigned char *) cptr[i];
2453
				ptr += strlen(z) + 1;
2434
			    ptr += strlen(z) + 1;
2454
				for (int j = 0; j < NG;  j++)
2435
			    for (int j = 0; j < NG;  j++)
2455
				    if(*ptr++ != FILL) {
2436
				if(*ptr++ != FILL) {
2456
					 // force termination
2437
				    // force termination
2457
					unsigned char *p = ptr;
2438
				    unsigned char *p = ptr;
2458
					for (int k = 1; k < NG - j; k++, p++)
2439
				    for (int k = 1; k < NG - j; k++, p++)
2459
					    if (*p == FILL) *p = '\0';
2440
					if (*p == FILL) *p = '\0';
2460
					error("array over-run in .C(\"%s\") in character argument %d, element %d\n'%s'->'%s'\n",
2441
				    error("array over-run in .C(\"%s\") in character argument %d, element %d\n'%s'->'%s'\n",
2461
					      symName, na+1, (int)(i+1),
2442
					  symName, na+1, (int)(i+1),
2462
					      z, cptr[i]);
2443
					  z, cptr[i]);
2463
				    }
2444
				}
2464
			    }
-
 
2465
			}
2445
			}
2466
			UNPROTECT(1);
-
 
2467
		    } else {
-
 
2468
			PROTECT(s = allocVector(type, n));
-
 
2469
			char **cptr = (char**) p;
-
 
2470
			for (R_xlen_t i = 0 ; i < n ; i++)
-
 
2471
			    SET_STRING_ELT(s, i, mkChar(cptr[i]));
-
 
2472
			UNPROTECT(1);
-
 
2473
		    }
2446
		    }
2474
		    break;
2447
		    UNPROTECT(1);
2475
		default:
-
 
2476
		    break;
2448
		} else {
2477
		}
-
 
2478
		if (s != arg) {
2449
		    PROTECT(s = allocVector(type, n));
2479
		    PROTECT(s);
2450
		    char **cptr = (char**) p;
2480
		    DUPLICATE_ATTRIB(s, arg);
2451
		    for (R_xlen_t i = 0 ; i < n ; i++)
2481
		    SET_VECTOR_ELT(ans, na, s);
2452
			SET_STRING_ELT(s, i, mkChar(cptr[i]));
2482
		    UNPROTECT(1);
2453
		    UNPROTECT(1);
2483
		}
2454
		}
-
 
2455
		break;
-
 
2456
	    default:
-
 
2457
		break;
-
 
2458
	    }
-
 
2459
	    if (s != arg) {
-
 
2460
		PROTECT(s);
-
 
2461
		DUPLICATE_ATTRIB(s, arg);
-
 
2462
		SET_VECTOR_ELT(ans, na, s);
-
 
2463
		UNPROTECT(1);
2484
	    }
2464
	    }
2485
	}
2465
	}
2486
    }
2466
    }
2487
    UNPROTECT(1);
2467
    UNPROTECT(1);
2488
    vmaxset(vmax);
2468
    vmaxset(vmax);