The R Project SVN R

Rev

Rev 75597 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 75597 Rev 75629
Line 29... Line 29...
29
#include <Rconnections.h>
29
#include <Rconnections.h>
30
#include <Rinterface.h>
30
#include <Rinterface.h>
31
#include <R_ext/GraphicsEngine.h> /* for GEonExit */
31
#include <R_ext/GraphicsEngine.h> /* for GEonExit */
32
#include <Rmath.h> /* for imax2 */
32
#include <Rmath.h> /* for imax2 */
33
#include <R_ext/Print.h>
33
#include <R_ext/Print.h>
-
 
34
#include <stdarg.h>
34
 
35
 
35
#ifndef min
36
#ifndef min
36
#define min(a, b) (a<b?a:b)
37
#define min(a, b) (a<b?a:b)
37
#endif
38
#endif
38
 
39
 
Line 244... Line 245...
244
{
245
{
245
    R_Warnings = allocVector(VECSXP, R_nwarnings);
246
    R_Warnings = allocVector(VECSXP, R_nwarnings);
246
    setAttrib(R_Warnings, R_NamesSymbol, allocVector(STRSXP, R_nwarnings));
247
    setAttrib(R_Warnings, R_NamesSymbol, allocVector(STRSXP, R_nwarnings));
247
}
248
}
248
 
249
 
249
/* Rvsnprintf: like vsnprintf, but guaranteed to null-terminate. */
250
/* Rvsnprintf: like vsnprintf, but guaranteed to null-terminate and not to
-
 
251
   split multi-byte characters */
250
#ifdef Win32
252
#ifdef Win32
251
int trio_vsnprintf(char *buffer, size_t bufferSize, const char *format,
253
int trio_vsnprintf(char *buffer, size_t bufferSize, const char *format,
252
		   va_list args);
254
		   va_list args);
253
 
255
 
254
static int Rvsnprintf(char *buf, size_t size, const char  *format, va_list ap)
256
static int Rvsnprintf(char *buf, size_t size, const char  *format, va_list ap)
255
{
257
{
256
    int val;
258
    int val;
257
    val = trio_vsnprintf(buf, size, format, ap);
259
    val = trio_vsnprintf(buf, size, format, ap);
258
    buf[size-1] = '\0';
260
    buf[size-1] = '\0';
-
 
261
    if (val >= size)
-
 
262
	mbcsTruncateToValid(buf);
259
    return val;
263
    return val;
260
}
264
}
261
#else
265
#else
262
static int Rvsnprintf(char *buf, size_t size, const char  *format, va_list ap)
266
static int Rvsnprintf(char *buf, size_t size, const char  *format, va_list ap)
263
{
267
{
264
    int val;
268
    int val;
265
    val = vsnprintf(buf, size, format, ap);
269
    val = vsnprintf(buf, size, format, ap);
266
    buf[size-1] = '\0';
270
    buf[size-1] = '\0';
-
 
271
    if (val >= size)
-
 
272
	mbcsTruncateToValid(buf);
267
    return val;
273
    return val;
268
}
274
}
269
#endif
275
#endif
270
 
276
 
-
 
277
/* Rsnprintf: like snprintf, but guaranteed to null-terminate and not to
-
 
278
   split multi-byte characters */
-
 
279
static int Rsnprintf(char *str, size_t size, const char *format, ...)
-
 
280
{
-
 
281
    int val;
-
 
282
    va_list ap;
-
 
283
 
-
 
284
    va_start(ap, format);
-
 
285
    val = Rvsnprintf(str, size, format, ap);
-
 
286
    va_end(ap);
-
 
287
 
-
 
288
    return val;
-
 
289
}
-
 
290
 
-
 
291
/* Rstrncat: like strncat, but guaranteed not to split multi-byte characters */
-
 
292
static char *Rstrncat(char *dest, const char *src, size_t n)
-
 
293
{
-
 
294
    size_t after;
-
 
295
    size_t before = strlen(dest);
-
 
296
 
-
 
297
    strncat(dest, src, n);
-
 
298
    
-
 
299
    after = strlen(dest);
-
 
300
    if (after - before == n)
-
 
301
	/* the string may have been truncated, but we cannot know for sure
-
 
302
	   because str may not be null terminated */
-
 
303
	mbcsTruncateToValid(dest + before);
-
 
304
 
-
 
305
    return dest;
-
 
306
}
-
 
307
 
-
 
308
/* Rstrncat: like strncpy, but guaranteed to null-terminate and not to
-
 
309
   split multi-byte characters */
-
 
310
static char *Rstrncpy(char *dest, const char *src, size_t n)
-
 
311
{
-
 
312
    strncpy(dest, src, n);
-
 
313
    if (dest[n-1] != '\0') {
-
 
314
	dest[n-1] = '\0';
-
 
315
	mbcsTruncateToValid(dest);
-
 
316
    }
-
 
317
    return dest;
-
 
318
}
-
 
319
 
271
#define BUFSIZE 8192
320
#define BUFSIZE 8192
272
static R_INLINE void RprintTrunc(char *buf)
321
static R_INLINE void RprintTrunc(char *buf, int truncated)
273
{
322
{
-
 
323
    if(R_WarnLength < BUFSIZE - 20 &&
274
    if(R_WarnLength < BUFSIZE - 20 && strlen(buf) == R_WarnLength) {
324
      (truncated || strlen(buf) == R_WarnLength)) {
-
 
325
 
275
	strcat(buf, " ");
326
	strcat(buf, " ");
276
	strcat(buf, _("[... truncated]"));
327
	strcat(buf, _("[... truncated]"));
277
    }
328
    }
278
}
329
}
279
 
330
 
Line 295... Line 346...
295
{
346
{
296
    char buf[BUFSIZE], *p;
347
    char buf[BUFSIZE], *p;
297
 
348
 
298
    va_list(ap);
349
    va_list(ap);
299
    va_start(ap, format);
350
    va_start(ap, format);
-
 
351
    size_t psize;
-
 
352
    int pval;
-
 
353
    
300
    Rvsnprintf(buf, min(BUFSIZE, R_WarnLength+1), format, ap);
354
    psize = min(BUFSIZE, R_WarnLength+1);
-
 
355
    pval = Rvsnprintf(buf, psize, format, ap);
301
    va_end(ap);
356
    va_end(ap);
302
    p = buf + strlen(buf) - 1;
357
    p = buf + strlen(buf) - 1;
303
    if(strlen(buf) > 0 && *p == '\n') *p = '\0';
358
    if(strlen(buf) > 0 && *p == '\n') *p = '\0';
304
    RprintTrunc(buf);
359
    RprintTrunc(buf, pval >= psize);
305
    warningcall(getCurrentCall(), "%s", buf);
360
    warningcall(getCurrentCall(), "%s", buf);
306
}
361
}
307
 
362
 
308
/* declarations for internal condition handling */
363
/* declarations for internal condition handling */
309
 
364
 
Line 336... Line 391...
336
    SEXP names, s;
391
    SEXP names, s;
337
    const char *dcall;
392
    const char *dcall;
338
    char buf[BUFSIZE];
393
    char buf[BUFSIZE];
339
    RCNTXT *cptr;
394
    RCNTXT *cptr;
340
    RCNTXT cntxt;
395
    RCNTXT cntxt;
-
 
396
    size_t psize;
-
 
397
    int pval;
341
 
398
 
342
    if (inWarning)
399
    if (inWarning)
343
	return;
400
	return;
344
 
401
 
345
    s = GetOption1(install("warning.expression"));
402
    s = GetOption1(install("warning.expression"));
Line 369... Line 426...
369
    cntxt.cend = &reset_inWarning;
426
    cntxt.cend = &reset_inWarning;
370
 
427
 
371
    inWarning = 1;
428
    inWarning = 1;
372
 
429
 
373
    if(w >= 2) { /* make it an error */
430
    if(w >= 2) { /* make it an error */
374
	Rvsnprintf(buf, min(BUFSIZE, R_WarnLength), format, ap);
431
	psize = min(BUFSIZE, R_WarnLength+1);
-
 
432
	pval = Rvsnprintf(buf, psize, format, ap);
375
	RprintTrunc(buf);
433
	RprintTrunc(buf, pval >= psize);
376
	inWarning = 0; /* PR#1570 */
434
	inWarning = 0; /* PR#1570 */
377
	errorcall(call, _("(converted from warning) %s"), buf);
435
	errorcall(call, _("(converted from warning) %s"), buf);
378
    }
436
    }
379
    else if(w == 1) {	/* print as they happen */
437
    else if(w == 1) {	/* print as they happen */
380
	char *tr;
438
	char *tr;
381
	if( call != R_NilValue ) {
439
	if( call != R_NilValue ) {
382
	    dcall = CHAR(STRING_ELT(deparse1s(call), 0));
440
	    dcall = CHAR(STRING_ELT(deparse1s(call), 0));
383
	} else dcall = "";
441
	} else dcall = "";
384
	Rvsnprintf(buf, min(BUFSIZE, R_WarnLength+1), format, ap);
442
	psize = min(BUFSIZE, R_WarnLength+1);
-
 
443
	pval = Rvsnprintf(buf, psize, format, ap);
385
	RprintTrunc(buf);
444
	RprintTrunc(buf, pval >= psize);
386
 
445
 
387
	if(dcall[0] == '\0') REprintf(_("Warning:"));
446
	if(dcall[0] == '\0') REprintf(_("Warning:"));
388
	else {
447
	else {
389
	    REprintf(_("Warning in %s :"), dcall);
448
	    REprintf(_("Warning in %s :"), dcall);
390
	    if(!(noBreakWarning ||
449
	    if(!(noBreakWarning ||
Line 400... Line 459...
400
    }
459
    }
401
    else if(w == 0) {	/* collect them */
460
    else if(w == 0) {	/* collect them */
402
	if(!R_CollectWarnings) setupwarnings();
461
	if(!R_CollectWarnings) setupwarnings();
403
	if(R_CollectWarnings < R_nwarnings) {
462
	if(R_CollectWarnings < R_nwarnings) {
404
	    SET_VECTOR_ELT(R_Warnings, R_CollectWarnings, call);
463
	    SET_VECTOR_ELT(R_Warnings, R_CollectWarnings, call);
405
	    Rvsnprintf(buf, min(BUFSIZE, R_WarnLength+1), format, ap);
464
	    psize = min(BUFSIZE, R_WarnLength+1);
-
 
465
	    pval = Rvsnprintf(buf, psize, format, ap);
406
	    RprintTrunc(buf);
466
	    RprintTrunc(buf, pval >= psize);
407
	    if(R_ShowWarnCalls && call != R_NilValue) {
467
	    if(R_ShowWarnCalls && call != R_NilValue) {
408
		char *tr =  R_ConciseTraceback(call, 0);
468
		char *tr =  R_ConciseTraceback(call, 0);
409
		size_t nc = strlen(tr);
469
		size_t nc = strlen(tr);
410
		if (nc && nc + (int)strlen(buf) + 8 < BUFSIZE) {
470
		if (nc && nc + (int)strlen(buf) + 8 < BUFSIZE) {
411
		    strcat(buf, "\n");
471
		    strcat(buf, "\n");
Line 601... Line 661...
601
    return result;
661
    return result;
602
}
662
}
603
 
663
 
604
static char errbuf[BUFSIZE];
664
static char errbuf[BUFSIZE];
605
 
665
 
606
#define ERRBUFCAT(txt) strncat(errbuf, txt, BUFSIZE - strlen(errbuf))
666
#define ERRBUFCAT(txt) Rstrncat(errbuf, txt, BUFSIZE - strlen(errbuf))
607
 
667
 
608
const char *R_curErrorBuf() {
668
const char *R_curErrorBuf() {
609
    return (const char *)errbuf;
669
    return (const char *)errbuf;
610
}
670
}
611
 
671
 
Line 680... Line 740...
680
	    else
740
	    else
681
		skip = asInteger(opt);
741
		skip = asInteger(opt);
682
	}
742
	}
683
 
743
 
684
	const char *dcall = CHAR(STRING_ELT(deparse1s(call), 0));
744
	const char *dcall = CHAR(STRING_ELT(deparse1s(call), 0));
685
	snprintf(tmp2, BUFSIZE,  "%s", head);
745
	Rsnprintf(tmp2, BUFSIZE,  "%s", head);
686
	if (skip != NA_INTEGER) {
746
	if (skip != NA_INTEGER) {
687
	    PROTECT(srcloc = GetSrcLoc(R_GetCurrentSrcref(skip)));
747
	    PROTECT(srcloc = GetSrcLoc(R_GetCurrentSrcref(skip)));
688
	    protected++;
748
	    protected++;
689
	    len = strlen(CHAR(STRING_ELT(srcloc, 0)));
749
	    len = strlen(CHAR(STRING_ELT(srcloc, 0)));
690
	    if (len)
750
	    if (len)
691
		snprintf(tmp2, BUFSIZE,  _("Error in %s (from %s) : "),
751
		Rsnprintf(tmp2, BUFSIZE,  _("Error in %s (from %s) : "),
692
			 dcall, CHAR(STRING_ELT(srcloc, 0)));
752
			 dcall, CHAR(STRING_ELT(srcloc, 0)));
693
	}
753
	}
694
 
754
 
695
	Rvsnprintf(tmp, min(BUFSIZE, R_WarnLength) - strlen(head), format, ap);
755
	Rvsnprintf(tmp, min(BUFSIZE, R_WarnLength) - strlen(head), format, ap);
696
	if (strlen(tmp2) + strlen(tail) + strlen(tmp) < BUFSIZE) {
756
	if (strlen(tmp2) + strlen(tail) + strlen(tmp) < BUFSIZE) {
697
	    if(len) snprintf(errbuf, BUFSIZE,
757
	    if(len) Rsnprintf(errbuf, BUFSIZE,
698
			     _("Error in %s (from %s) : "),
758
			     _("Error in %s (from %s) : "),
699
			     dcall, CHAR(STRING_ELT(srcloc, 0)));
759
			     dcall, CHAR(STRING_ELT(srcloc, 0)));
700
	    else snprintf(errbuf, BUFSIZE,  _("Error in %s : "), dcall);
760
	    else Rsnprintf(errbuf, BUFSIZE,  _("Error in %s : "), dcall);
701
	    if (mbcslocale) {
761
	    if (mbcslocale) {
702
		int msgline1;
762
		int msgline1;
703
		char *p = strchr(tmp, '\n');
763
		char *p = strchr(tmp, '\n');
704
		if (p) {
764
		if (p) {
705
		    *p = '\0';
765
		    *p = '\0';
Line 718... Line 778...
718
		if (14 + strlen(dcall) + msgline1 > LONGWARN)
778
		if (14 + strlen(dcall) + msgline1 > LONGWARN)
719
		    ERRBUFCAT(tail);
779
		    ERRBUFCAT(tail);
720
	    }
780
	    }
721
	    ERRBUFCAT(tmp);
781
	    ERRBUFCAT(tmp);
722
	} else {
782
	} else {
723
	    snprintf(errbuf, BUFSIZE, _("Error: "));
783
	    Rsnprintf(errbuf, BUFSIZE, _("Error: "));
724
	    ERRBUFCAT(tmp); // FIXME
784
	    ERRBUFCAT(tmp); // FIXME
725
	}
785
	}
726
	UNPROTECT(protected);
786
	UNPROTECT(protected);
727
    }
787
    }
728
    else {
788
    else {
729
	snprintf(errbuf, BUFSIZE, _("Error: "));
789
	Rsnprintf(errbuf, BUFSIZE, _("Error: "));
730
	p = errbuf + strlen(errbuf);
790
	p = errbuf + strlen(errbuf);
731
	Rvsnprintf(p, min(BUFSIZE, R_WarnLength) - strlen(errbuf), format, ap);
791
	Rvsnprintf(p, min(BUFSIZE, R_WarnLength) - strlen(errbuf), format, ap);
732
    }
792
    }
733
 
793
 
734
    size_t nc = strlen(errbuf);
794
    size_t nc = strlen(errbuf);
Line 1009... Line 1069...
1009
	}
1069
	}
1010
	if(strlen(domain)) {
1070
	if(strlen(domain)) {
1011
	    size_t len = strlen(domain)+3;
1071
	    size_t len = strlen(domain)+3;
1012
	    R_CheckStack2(len);
1072
	    R_CheckStack2(len);
1013
	    buf = (char *) alloca(len);
1073
	    buf = (char *) alloca(len);
1014
	    snprintf(buf, len, "R-%s", domain);
1074
	    Rsnprintf(buf, len, "R-%s", domain);
1015
	    domain = buf;
1075
	    domain = buf;
1016
	}
1076
	}
1017
    } else if(isString(CAR(args)))
1077
    } else if(isString(CAR(args)))
1018
	domain = translateChar(STRING_ELT(CAR(args),0));
1078
	domain = translateChar(STRING_ELT(CAR(args),0));
1019
    else if(isLogical(CAR(args)) && LENGTH(CAR(args)) == 1 && LOGICAL(CAR(args))[0] == NA_LOGICAL) ;
1079
    else if(isLogical(CAR(args)) && LENGTH(CAR(args)) == 1 && LOGICAL(CAR(args))[0] == NA_LOGICAL) ;
Line 1034... Line 1094...
1034
		*p && (*p == ' ' || *p == '\t' || *p == '\n');
1094
		*p && (*p == ' ' || *p == '\t' || *p == '\n');
1035
		p++, ihead++) ;
1095
		p++, ihead++) ;
1036
	    if(ihead > 0) {
1096
	    if(ihead > 0) {
1037
		R_CheckStack2(ihead + 1);
1097
		R_CheckStack2(ihead + 1);
1038
		head = (char *) alloca(ihead + 1);
1098
		head = (char *) alloca(ihead + 1);
1039
		strncpy(head, tmp, ihead);
1099
		Rstrncpy(head, tmp, ihead + 1);
1040
		head[ihead] = '\0';
-
 
1041
		tmp += ihead;
1100
		tmp += ihead;
1042
		}
1101
		}
1043
	    if(strlen(tmp))
1102
	    if(strlen(tmp))
1044
		for(p = tmp+strlen(tmp)-1;
1103
		for(p = tmp+strlen(tmp)-1;
1045
		    p >= tmp && (*p == ' ' || *p == '\t' || *p == '\n');
1104
		    p >= tmp && (*p == ' ' || *p == '\t' || *p == '\n');
Line 1115... Line 1174...
1115
	}
1174
	}
1116
	if(strlen(domain)) {
1175
	if(strlen(domain)) {
1117
	    size_t len = strlen(domain)+3;
1176
	    size_t len = strlen(domain)+3;
1118
	    R_CheckStack2(len);
1177
	    R_CheckStack2(len);
1119
	    buf = (char *) alloca(len);
1178
	    buf = (char *) alloca(len);
1120
	    snprintf(buf, len, "R-%s", domain);
1179
	    Rsnprintf(buf, len, "R-%s", domain);
1121
	    domain = buf;
1180
	    domain = buf;
1122
	}
1181
	}
1123
    } else if(isString(sdom))
1182
    } else if(isString(sdom))
1124
	domain = CHAR(STRING_ELT(sdom,0));
1183
	domain = CHAR(STRING_ELT(sdom,0));
1125
    else if(isLogical(sdom) && LENGTH(sdom) == 1 && LOGICAL(sdom)[0] == NA_LOGICAL) ;
1184
    else if(isLogical(sdom) && LENGTH(sdom) == 1 && LOGICAL(sdom)[0] == NA_LOGICAL) ;
Line 1369... Line 1428...
1369
}
1428
}
1370
#endif
1429
#endif
1371
 
1430
 
1372
static void R_SetErrmessage(const char *s)
1431
static void R_SetErrmessage(const char *s)
1373
{
1432
{
1374
    strncpy(errbuf, s, sizeof(errbuf));
1433
    Rstrncpy(errbuf, s, sizeof(errbuf));
1375
    errbuf[sizeof(errbuf) - 1] = 0;
-
 
1376
}
1434
}
1377
 
1435
 
1378
static void R_PrintDeferredWarnings(void)
1436
static void R_PrintDeferredWarnings(void)
1379
{
1437
{
1380
    if( R_ShowErrorMessages && R_CollectWarnings ) {
1438
    if( R_ShowErrorMessages && R_CollectWarnings ) {
Line 1654... Line 1712...
1654
    Rvsnprintf(localbuf, BUFSIZE - 1, format, ap);
1712
    Rvsnprintf(localbuf, BUFSIZE - 1, format, ap);
1655
    while ((list = findSimpleErrorHandler()) != R_NilValue) {
1713
    while ((list = findSimpleErrorHandler()) != R_NilValue) {
1656
	char *buf = errbuf;
1714
	char *buf = errbuf;
1657
	SEXP entry = CAR(list);
1715
	SEXP entry = CAR(list);
1658
	R_HandlerStack = CDR(list);
1716
	R_HandlerStack = CDR(list);
1659
	strncpy(buf, localbuf, BUFSIZE);
1717
	Rstrncpy(buf, localbuf, BUFSIZE);
1660
	/*	Rvsnprintf(buf, BUFSIZE - 1, format, ap);*/
1718
	/*	Rvsnprintf(buf, BUFSIZE - 1, format, ap);*/
1661
	buf[BUFSIZE - 1] = 0;
-
 
1662
	if (IS_CALLING_ENTRY(entry)) {
1719
	if (IS_CALLING_ENTRY(entry)) {
1663
	    if (ENTRY_HANDLER(entry) == R_RestartToken)
1720
	    if (ENTRY_HANDLER(entry) == R_RestartToken)
1664
		return; /* go to default error handling; do not reset stack */
1721
		return; /* go to default error handling; do not reset stack */
1665
	    else {
1722
	    else {
1666
		/* if we are in the process of handling a C stack
1723
		/* if we are in the process of handling a C stack
Line 1982... Line 2039...
1982
                  const char *errmsg, const char *warnmsg,
2039
                  const char *errmsg, const char *warnmsg,
1983
                  const char *varname, Rboolean warnByDefault)
2040
                  const char *varname, Rboolean warnByDefault)
1984
{
2041
{
1985
    /* disable GC so that use of this temporary checking code does not
2042
    /* disable GC so that use of this temporary checking code does not
1986
       introduce new PROTECT errors e.g. in asLogical() use */
2043
       introduce new PROTECT errors e.g. in asLogical() use */
-
 
2044
    R_CHECK_THREAD;
1987
    int enabled = R_GCEnabled;
2045
    int enabled = R_GCEnabled;
1988
    R_GCEnabled = FALSE;
2046
    R_GCEnabled = FALSE;
1989
    int nprotect = 0;
2047
    int nprotect = 0;
1990
    char *check = getenv(varname);
2048
    char *check = getenv(varname);
1991
    const void *vmax = vmaxget();
2049
    const void *vmax = vmaxget();