The R Project SVN R

Rev

Rev 90294 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 r 1
/*
2440 maechler 2
 *  R : A Computer Language for Statistical Data Analysis
89935 luke 3
 *  Copyright (C) 1995--2026  The R Core Team.
2 r 4
 *
5
 *  This program is free software; you can redistribute it and/or modify
6
 *  it under the terms of the GNU General Public License as published by
7
 *  the Free Software Foundation; either version 2 of the License, or
8
 *  (at your option) any later version.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
42307 ripley 16
 *  along with this program; if not, a copy is available at
68947 ripley 17
 *  https://www.R-project.org/Licenses/
2 r 18
 */
19
 
5187 hornik 20
#ifdef HAVE_CONFIG_H
7701 hornik 21
#include <config.h>
5187 hornik 22
#endif
23
 
57538 ripley 24
#define R_USE_SIGNALS 1
13305 ripley 25
#include <Defn.h>
87097 maechler 26
/* -> Errormsg.h , R_ext/Error.h */
60667 ripley 27
#include <Internal.h>
13305 ripley 28
#include <Startup.h> /* rather cleanup ..*/
29
#include <Rconnections.h>
39866 duncan 30
#include <Rinterface.h>
31938 murrell 31
#include <R_ext/GraphicsEngine.h> /* for GEonExit */
33115 ripley 32
#include <Rmath.h> /* for imax2 */
60239 ripley 33
#include <R_ext/Print.h>
75601 kalibera 34
#include <stdarg.h>
11046 maechler 35
 
78071 luke 36
/* eval() sets R_Visible = TRUE. Thas may not be wanted when eval() is
37
   used in C code. This is a version that saves/restores R_Visible.
38
   This should probably be moved to eval.c, be make public, and used
39
   in  more places. LT */
40
static SEXP evalKeepVis(SEXP e, SEXP rho)
41
{
87815 ripley 42
    Rboolean oldvis = R_Visible;
78071 luke 43
    SEXP val = eval(e, rho);
44
    R_Visible = oldvis;
45
    return val;
46
}
47
 
20106 ripley 48
#ifndef min
49
#define min(a, b) (a<b?a:b)
50
#endif
79123 kalibera 51
#ifndef max
52
#define max(a, b) (a>b?a:b)
53
#endif
20106 ripley 54
 
41712 ripley 55
/* Total line length, in chars, before splitting in warnings/errors */
41688 ripley 56
#define LONGWARN 75
57
 
8004 maechler 58
/*
6199 rgentlem 59
Different values of inError are used to indicate different places
79123 kalibera 60
in the error handling:
61
inError = 1: In internal error handling, e.g. `verrorcall_dflt`, others.
62
inError = 2: Writing traceback
63
inError = 3: In user error handler (i.e. options(error=handler))
6199 rgentlem 64
*/
8004 maechler 65
static int inError = 0;
4230 rgentlem 66
static int inWarning = 0;
25367 luke 67
static int inPrintWarnings = 0;
31757 ripley 68
static int immediateWarning = 0;
64828 ripley 69
static int noBreakWarning = 0;
2 r 70
 
25470 luke 71
static void try_jump_to_restart(void);
62367 ripley 72
// The next is crucial to the use of NORET attributes.
83452 ripley 73
NORET static void 
62367 ripley 74
jump_to_top_ex(Rboolean, Rboolean, Rboolean, Rboolean, Rboolean);
26354 luke 75
static void signalInterrupt(void);
41712 ripley 76
static char * R_ConciseTraceback(SEXP call, int skip);
25368 luke 77
 
6098 pd 78
/* Interface / Calling Hierarchy :
79
 
62372 ripley 80
  R__stop()   -> do_error ->   errorcall --> (eventually) jump_to_top_ex
8004 maechler 81
			 /
82
		    error
6098 pd 83
 
84
  R__warning()-> do_warning   -> warningcall -> if(warn >= 2) errorcall
85
			     /
86
		    warning /
87
 
14442 luke 88
  ErrorMessage()-> errorcall   (but with message from ErrorDB[])
6098 pd 89
 
63431 ripley 90
  WarningMessage()-> warningcall (but with message from WarningDB[]).
6098 pd 91
*/
92
 
83452 ripley 93
NORET void R_SignalCStackOverflow(intptr_t usage)
35899 ripley 94
{
63426 luke 95
    /* We do need some stack space to process error recovery, so
96
       temporarily raise the limit.  We have 5% head room because we
97
       reduced R_CStackLimit to 95% of the initial value in
98
       setup_Rmainloop.
99
    */
70315 luke 100
    if (R_OldCStackLimit == 0) {
101
	R_OldCStackLimit = R_CStackLimit;
70316 ripley 102
	R_CStackLimit = (uintptr_t) (R_CStackLimit / 0.95);
70315 luke 103
    }
63426 luke 104
 
81150 luke 105
    SEXP cond = R_makeCStackOverflowError(R_NilValue, usage);
106
    PROTECT(cond);
107
    /* calling handlers at this point might produce a C stack
108
       overflow/SEGFAULT so treat them as failed and skip them */
109
    /* use R_NilValue as the call to avoid using stack in deparsing */
110
    R_signalErrorConditionEx(cond, R_NilValue, TRUE);
111
    UNPROTECT(1); /* cond; not reached */
63426 luke 112
}
113
 
83082 kalibera 114
void attribute_no_sanitizer_instrumentation (R_CheckStack)(void)
63426 luke 115
{
35899 ripley 116
    int dummy;
42252 ripley 117
    intptr_t usage = R_CStackDir * (R_CStackStart - (uintptr_t)&dummy);
6098 pd 118
 
35899 ripley 119
    /* printf("usage %ld\n", usage); */
63454 luke 120
    if(R_CStackLimit != -1 && usage > ((intptr_t) R_CStackLimit))
63481 ripley 121
	R_SignalCStackOverflow(usage);
35899 ripley 122
}
123
 
83082 kalibera 124
void attribute_no_sanitizer_instrumentation R_CheckStack2(size_t extra)
59752 ripley 125
{
126
    int dummy;
127
    intptr_t usage = R_CStackDir * (R_CStackStart - (uintptr_t)&dummy);
128
 
87078 maechler 129
    if (INTPTR_MAX - usage < extra)
130
	/* addition would overflow, this is definitely too much */
131
	R_SignalCStackOverflow(INTPTR_MAX);
132
 
70047 ripley 133
    /* do it this way, as some compilers do usage + extra
59752 ripley 134
       in unsigned arithmetic */
135
    usage += extra;
63454 luke 136
    if(R_CStackLimit != -1 && usage > ((intptr_t) R_CStackLimit))
63481 ripley 137
	R_SignalCStackOverflow(usage);
59752 ripley 138
 
139
}
140
 
25212 luke 141
void R_CheckUserInterrupt(void)
142
{
35899 ripley 143
    R_CheckStack();
46629 luke 144
 
145
    /* Don't do any processing of interrupts, timing limits, or other
146
       asynchronous events if interrupts are suspended. */
52104 ripley 147
    if (R_interrupts_suspended) return;
46629 luke 148
 
25224 luke 149
    /* This is the point where GUI systems need to do enough event
150
       processing to determine whether there is a user interrupt event
151
       pending.  Need to be careful not to do too much event
152
       processing though: if event handlers written in R are allowed
153
       to run at this point then we end up with concurrent R
154
       evaluations and that can cause problems until we have proper
155
       concurrency support. LT */
52104 ripley 156
 
157
    R_ProcessEvents(); /* Also processes timing limits */
158
    if (R_interrupts_pending) onintr();
25212 luke 159
}
160
 
82754 ripley 161
static SEXP getInterruptCondition(void);
85087 luke 162
static void addInternalRestart(RCNTXT *, const char *);
70852 luke 163
 
164
static void onintrEx(Rboolean resumeOK)
2 r 165
{
25497 luke 166
    if (R_interrupts_suspended) {
167
	R_interrupts_pending = 1;
168
	return;
169
    }
170
    else R_interrupts_pending = 0;
26354 luke 171
 
70852 luke 172
    if (resumeOK) {
173
	SEXP rho = R_GlobalContext->cloenv;
174
	int dbflag = RDEBUG(rho);
175
	RCNTXT restartcontext;
176
	begincontext(&restartcontext, CTXT_RESTART, R_NilValue, R_GlobalEnv,
177
		     R_BaseEnv, R_NilValue, R_NilValue);
178
	if (SETJMP(restartcontext.cjmpbuf)) {
179
	    SET_RDEBUG(rho, dbflag); /* in case browser() has messed with it */
180
	    R_ReturnedValue = R_NilValue;
181
	    R_Visible = FALSE;
182
	    endcontext(&restartcontext);
183
	    return;
184
	}
85087 luke 185
	addInternalRestart(&restartcontext, "resume");
70852 luke 186
	signalInterrupt();
187
	endcontext(&restartcontext);
70708 luke 188
    }
189
    else signalInterrupt();
190
 
70852 luke 191
    /* Interrupts do not inherit from error, so we should not run the
88473 kalibera 192
       user error handler. But we have been, so as a transition,
70850 luke 193
       continue to use options('error') if options('interrupt') is not
194
       set */
195
    Rboolean tryUserError = GetOption1(install("interrupt")) == R_NilValue;
196
 
1839 ihaka 197
    REprintf("\n");
70850 luke 198
    /* Attempt to save a traceback, show warnings, and reset console;
199
       also stop at restart (try/browser) frames.  Not clear this is
200
       what we really want, but this preserves current behavior */
201
    jump_to_top_ex(TRUE, tryUserError, TRUE, TRUE, FALSE);
2 r 202
}
203
 
82931 ripley 204
void onintr(void)  { onintrEx(TRUE); }
205
void onintrNoResume(void) { onintrEx(FALSE); }
70852 luke 206
 
8422 tlumley 207
/* SIGUSR1: save and quit
208
   SIGUSR2: save and quit, don't run .Last or on.exit().
36857 ripley 209
 
210
   These do far more processing than is allowed in a signal handler ....
8422 tlumley 211
*/
14478 luke 212
 
83446 ripley 213
attribute_hidden void onsigusr1(int dummy)
8422 tlumley 214
{
25221 luke 215
    if (R_interrupts_suspended) {
216
	/**** ought to save signal and handle after suspend */
32858 ripley 217
	REprintf(_("interrupts suspended; signal ignored"));
36857 ripley 218
	signal(SIGUSR1, onsigusr1);
25221 luke 219
	return;
220
    }
29340 murdoch 221
 
8422 tlumley 222
    inError = 1;
223
 
36857 ripley 224
    if(R_CollectWarnings) PrintWarnings();
8422 tlumley 225
 
226
    R_ResetConsole();
227
    R_FlushConsole();
228
    R_ClearerrConsole();
45446 ripley 229
    R_ParseError = 0;
39996 murdoch 230
    R_ParseErrorFile = NULL;
231
    R_ParseErrorMsg[0] = '\0';
14478 luke 232
 
25470 luke 233
    /* Bail out if there is a browser/try on the stack--do we really
39460 ripley 234
       want this?  No, as from R 2.4.0
235
    try_jump_to_restart(); */
14478 luke 236
 
237
    /* Run all onexit/cend code on the stack (without stopping at
238
       intervening CTXT_TOPLEVEL's.  Since intervening CTXT_TOPLEVEL's
239
       get used by what are conceptually concurrent computations, this
240
       is a bit like telling all active threads to terminate and clean
241
       up on the way out. */
242
    R_run_onexits(NULL);
243
 
14443 luke 244
    R_CleanUp(SA_SAVE, 2, 1); /* quit, save,  .Last, status=2 */
8422 tlumley 245
}
246
 
247
 
83446 ripley 248
attribute_hidden void onsigusr2(int dummy)
8422 tlumley 249
{
250
    inError = 1;
8892 maechler 251
 
25221 luke 252
    if (R_interrupts_suspended) {
253
	/**** ought to save signal and handle after suspend */
32858 ripley 254
	REprintf(_("interrupts suspended; signal ignored"));
36857 ripley 255
	signal(SIGUSR2, onsigusr2);
25221 luke 256
	return;
257
    }
29340 murdoch 258
 
36857 ripley 259
    if(R_CollectWarnings) PrintWarnings();
8892 maechler 260
 
8422 tlumley 261
    R_ResetConsole();
262
    R_FlushConsole();
263
    R_ClearerrConsole();
264
    R_ParseError = 0;
39996 murdoch 265
    R_ParseErrorFile = NULL;
45446 ripley 266
    R_ParseErrorMsg[0] = '\0';
8422 tlumley 267
    R_CleanUp(SA_SAVE, 0, 0);
268
}
269
 
270
 
4179 rgentlem 271
static void setupwarnings(void)
2 r 272
{
57675 ripley 273
    R_Warnings = allocVector(VECSXP, R_nwarnings);
274
    setAttrib(R_Warnings, R_NamesSymbol, allocVector(STRSXP, R_nwarnings));
4179 rgentlem 275
}
276
 
79248 kalibera 277
/* Rvsnprintf_mbcs: like vsnprintf, but guaranteed to null-terminate and not to
278
   split multi-byte characters, except if size is zero in which case the buffer
279
   is untouched and thus may not be null-terminated.
79123 kalibera 280
 
79248 kalibera 281
   This function may be invoked by the error handler via REvprintf.  Do not
282
   change it unless you are SURE that your changes are compatible with the
283
   error handling mechanism.
284
 
285
   REvprintf is also used in R_Suicide on Unix.
286
 
287
   Dangerous pattern: `Rvsnprintf_mbcs(buf, size - n, )` with n >= size */
58571 ripley 288
#ifdef Win32
289
int trio_vsnprintf(char *buffer, size_t bufferSize, const char *format,
290
		   va_list args);
291
 
79159 kalibera 292
attribute_hidden
293
int Rvsnprintf_mbcs(char *buf, size_t size, const char *format, va_list ap)
14439 luke 294
{
295
    int val;
58571 ripley 296
    val = trio_vsnprintf(buf, size, format, ap);
79123 kalibera 297
    if (size) {
298
	if (val < 0) buf[0] = '\0'; /* not all uses check val < 0 */
299
	else buf[size-1] = '\0';
300
	if (val >= size)
301
	    mbcsTruncateToValid(buf);
302
    }
58571 ripley 303
    return val;
304
}
305
#else
79159 kalibera 306
attribute_hidden
307
int Rvsnprintf_mbcs(char *buf, size_t size, const char *format, va_list ap)
58571 ripley 308
{
309
    int val;
14439 luke 310
    val = vsnprintf(buf, size, format, ap);
79123 kalibera 311
    if (size) {
312
	if (val < 0) buf[0] = '\0'; /* not all uses check val < 0 */
313
	else buf[size-1] = '\0';
314
	if (val >= size)
315
	    mbcsTruncateToValid(buf);
316
    }
14439 luke 317
    return val;
318
}
58571 ripley 319
#endif
14439 luke 320
 
79216 kalibera 321
/* Rsnprintf_mbcs: like snprintf, but guaranteed to null-terminate and
322
   not to split multi-byte characters, except if size is zero in which
323
   case the buffer is untouched and thus may not be null-terminated.
79123 kalibera 324
 
79216 kalibera 325
   Dangerous pattern: `Rsnprintf_mbcs(buf, size - n, )` with maybe n >= size*/
326
attribute_hidden
327
int Rsnprintf_mbcs(char *str, size_t size, const char *format, ...)
75601 kalibera 328
{
329
    int val;
330
    va_list ap;
331
 
332
    va_start(ap, format);
79159 kalibera 333
    val = Rvsnprintf_mbcs(str, size, format, ap);
75601 kalibera 334
    va_end(ap);
335
 
336
    return val;
337
}
338
 
339
/* Rstrncat: like strncat, but guaranteed not to split multi-byte characters */
340
static char *Rstrncat(char *dest, const char *src, size_t n)
341
{
342
    size_t after;
343
    size_t before = strlen(dest);
344
 
345
    strncat(dest, src, n);
76872 maechler 346
 
75601 kalibera 347
    after = strlen(dest);
348
    if (after - before == n)
349
	/* the string may have been truncated, but we cannot know for sure
350
	   because str may not be null terminated */
351
	mbcsTruncateToValid(dest + before);
352
 
353
    return dest;
354
}
355
 
79163 kalibera 356
/* Rstrncpy: like strncpy, but guaranteed to null-terminate and not to
75601 kalibera 357
   split multi-byte characters */
358
static char *Rstrncpy(char *dest, const char *src, size_t n)
359
{
360
    strncpy(dest, src, n);
79163 kalibera 361
    if (n) {
75601 kalibera 362
	dest[n-1] = '\0';
363
	mbcsTruncateToValid(dest);
364
    }
365
    return dest;
366
}
367
 
4179 rgentlem 368
#define BUFSIZE 8192
75601 kalibera 369
static R_INLINE void RprintTrunc(char *buf, int truncated)
65311 ripley 370
{
79125 kalibera 371
    if (truncated) {
372
	char *msg = _("[... truncated]");
373
	if (strlen(buf) + 1 + strlen(msg) < BUFSIZE) {
374
	    strcat(buf, " ");
375
	    strcat(buf, msg);
376
	}
65311 ripley 377
    }
378
}
379
 
82931 ripley 380
static SEXP getCurrentCall(void)
71744 luke 381
{
382
    RCNTXT *c = R_GlobalContext;
383
 
384
    /* This can be called before R_GlobalContext is defined, so... */
385
    /* If profiling is on, this can be a CTXT_BUILTIN */
386
 
387
    if (c && (c->callflag & CTXT_BUILTIN)) c = c->nextcontext;
388
    if (c == R_GlobalContext && R_BCIntActive)
389
	return R_getBCInterpreterExpression();
390
    else
391
	return c ? c->call : R_NilValue;
392
}
393
 
4179 rgentlem 394
void warning(const char *format, ...)
395
{
5502 ripley 396
    char buf[BUFSIZE], *p;
4179 rgentlem 397
 
1839 ihaka 398
    va_list(ap);
399
    va_start(ap, format);
75601 kalibera 400
    size_t psize;
401
    int pval;
76872 maechler 402
 
75601 kalibera 403
    psize = min(BUFSIZE, R_WarnLength+1);
79159 kalibera 404
    pval = Rvsnprintf_mbcs(buf, psize, format, ap);
1839 ihaka 405
    va_end(ap);
5502 ripley 406
    p = buf + strlen(buf) - 1;
407
    if(strlen(buf) > 0 && *p == '\n') *p = '\0';
75601 kalibera 408
    RprintTrunc(buf, pval >= psize);
84167 kalibera 409
    SEXP call = PROTECT(getCurrentCall());
410
    warningcall(call, "%s", buf);
411
    UNPROTECT(1);
2 r 412
}
4165 rgentlem 413
 
25523 luke 414
/* declarations for internal condition handling */
415
 
25526 luke 416
static void vsignalError(SEXP call, const char *format, va_list ap);
25523 luke 417
static void vsignalWarning(SEXP call, const char *format, va_list ap);
83452 ripley 418
NORET static void invokeRestart(SEXP, SEXP);
25523 luke 419
 
25352 luke 420
static void reset_inWarning(void *data)
421
{
422
    inWarning = 0;
423
}
424
 
60260 ripley 425
#include <rlocale.h>
41944 ripley 426
 
427
static int wd(const char * buf)
428
{
59173 ripley 429
    int nc = (int) mbstowcs(NULL, buf, 0), nw;
41966 ripley 430
    if(nc > 0 && nc < 2000) {
431
	wchar_t wc[2000];
41944 ripley 432
	mbstowcs(wc, buf, nc + 1);
79693 ripley 433
	// FIXME: width could conceivably exceed MAX_INT.
79776 ripley 434
#ifdef USE_RI18N_WIDTH
41944 ripley 435
	nw = Ri18n_wcswidth(wc, 2147483647);
79776 ripley 436
#else
437
	nw = wcswidth(wc, 2147483647);
438
#endif
81029 hornik 439
	return (nw < 0) ? nc : nw;
41944 ripley 440
    }
441
    return nc;
442
}
443
 
25523 luke 444
static void vwarningcall_dflt(SEXP call, const char *format, va_list ap)
2 r 445
{
12976 pd 446
    int w;
4165 rgentlem 447
    SEXP names, s;
41807 rgentlem 448
    const char *dcall;
449
    char buf[BUFSIZE];
4165 rgentlem 450
    RCNTXT *cptr;
25352 luke 451
    RCNTXT cntxt;
75601 kalibera 452
    size_t psize;
453
    int pval;
4165 rgentlem 454
 
25368 luke 455
    if (inWarning)
456
	return;
29340 murdoch 457
 
54049 ripley 458
    s = GetOption1(install("warning.expression"));
41680 ripley 459
    if( s != R_NilValue ) {
8004 maechler 460
	if( !isLanguage(s) &&  ! isExpression(s) )
32858 ripley 461
	    error(_("invalid option \"warning.expression\""));
8004 maechler 462
	cptr = R_GlobalContext;
463
	while ( !(cptr->callflag & CTXT_FUNCTION) && cptr->callflag )
464
	    cptr = cptr->nextcontext;
78071 luke 465
	evalKeepVis(s, cptr->cloenv);
8004 maechler 466
	return;
4247 rgentlem 467
    }
468
 
54049 ripley 469
    w = asInteger(GetOption1(install("warn")));
4230 rgentlem 470
 
4179 rgentlem 471
    if( w == NA_INTEGER ) /* set to a sensible value */
472
	w = 0;
4230 rgentlem 473
 
39091 ripley 474
    if( w <= 0 && immediateWarning ) w = 1;
475
 
41712 ripley 476
    if( w < 0 || inWarning || inError) /* ignore if w<0 or already in here*/
8004 maechler 477
	return;
25352 luke 478
 
479
    /* set up a context which will restore inWarning if there is an exit */
35450 murdoch 480
    begincontext(&cntxt, CTXT_CCODE, R_NilValue, R_BaseEnv, R_BaseEnv,
25352 luke 481
		 R_NilValue, R_NilValue);
482
    cntxt.cend = &reset_inWarning;
483
 
4230 rgentlem 484
    inWarning = 1;
485
 
12976 pd 486
    if(w >= 2) { /* make it an error */
75601 kalibera 487
	psize = min(BUFSIZE, R_WarnLength+1);
79159 kalibera 488
	pval = Rvsnprintf_mbcs(buf, psize, format, ap);
75601 kalibera 489
	RprintTrunc(buf, pval >= psize);
19761 ripley 490
	inWarning = 0; /* PR#1570 */
32858 ripley 491
	errorcall(call, _("(converted from warning) %s"), buf);
4165 rgentlem 492
    }
12976 pd 493
    else if(w == 1) {	/* print as they happen */
41712 ripley 494
	char *tr;
8004 maechler 495
	if( call != R_NilValue ) {
87909 ripley 496
	    dcall = CHAR(STRING_ELT(deparse1s(call), false));
41688 ripley 497
	} else dcall = "";
75601 kalibera 498
	psize = min(BUFSIZE, R_WarnLength+1);
79159 kalibera 499
	pval = Rvsnprintf_mbcs(buf, psize, format, ap);
75601 kalibera 500
	RprintTrunc(buf, pval >= psize);
65311 ripley 501
 
502
	if(dcall[0] == '\0') REprintf(_("Warning:"));
503
	else {
504
	    REprintf(_("Warning in %s :"), dcall);
85879 ripley 505
	    // This did not allow for buf containing line breaks
506
	    // We can put the first line on the same line as the warning
507
	    // if it fits within LONGWARN.
508
	    char buf1[BUFSIZE];
509
	    strncpy(buf1, buf, BUFSIZE);
510
	    char *p = strstr(buf1, "\n");
511
	    if(p) *p = '\0';
70047 ripley 512
	    if(!(noBreakWarning ||
85879 ripley 513
		 ( mbcslocale && (18 + wd(dcall) + wd(buf1) <= LONGWARN)) ||
86057 luke 514
		 (!mbcslocale && (18 + strlen(dcall) + strlen(buf1) <= LONGWARN))))
65311 ripley 515
		REprintf("\n ");
516
	}
517
	REprintf(" %s\n", buf);
41944 ripley 518
	if(R_ShowWarnCalls && call != R_NilValue) {
41712 ripley 519
	    tr = R_ConciseTraceback(call, 0);
65311 ripley 520
	    if (strlen(tr)) {REprintf(_("Calls:")); REprintf(" %s\n", tr);}
41712 ripley 521
	}
4165 rgentlem 522
    }
12976 pd 523
    else if(w == 0) {	/* collect them */
57666 ripley 524
	if(!R_CollectWarnings) setupwarnings();
57675 ripley 525
	if(R_CollectWarnings < R_nwarnings) {
57666 ripley 526
	    SET_VECTOR_ELT(R_Warnings, R_CollectWarnings, call);
75601 kalibera 527
	    psize = min(BUFSIZE, R_WarnLength+1);
79159 kalibera 528
	    pval = Rvsnprintf_mbcs(buf, psize, format, ap);
75601 kalibera 529
	    RprintTrunc(buf, pval >= psize);
57666 ripley 530
	    if(R_ShowWarnCalls && call != R_NilValue) {
70047 ripley 531
		char *tr =  R_ConciseTraceback(call, 0);
59173 ripley 532
		size_t nc = strlen(tr);
533
		if (nc && nc + (int)strlen(buf) + 8 < BUFSIZE) {
65311 ripley 534
		    strcat(buf, "\n");
535
		    strcat(buf, _("Calls:"));
536
		    strcat(buf, " ");
57666 ripley 537
		    strcat(buf, tr);
538
		}
41712 ripley 539
	    }
57666 ripley 540
	    names = CAR(ATTRIB(R_Warnings));
541
	    SET_STRING_ELT(names, R_CollectWarnings++, mkChar(buf));
41712 ripley 542
	}
6191 maechler 543
    }
6098 pd 544
    /* else:  w <= -1 */
25352 luke 545
    endcontext(&cntxt);
4230 rgentlem 546
    inWarning = 0;
2 r 547
}
548
 
25523 luke 549
static void warningcall_dflt(SEXP call, const char *format,...)
550
{
551
    va_list(ap);
552
 
553
    va_start(ap, format);
554
    vwarningcall_dflt(call, format, ap);
555
    va_end(ap);
556
}
557
 
558
void warningcall(SEXP call, const char *format, ...)
559
{
560
    va_list(ap);
561
    va_start(ap, format);
562
    vsignalWarning(call, format, ap);
563
    va_end(ap);
564
}
565
 
39091 ripley 566
void warningcall_immediate(SEXP call, const char *format, ...)
567
{
568
    va_list(ap);
569
 
570
    immediateWarning = 1;
571
    va_start(ap, format);
67418 luke 572
    vsignalWarning(call, format, ap);
39091 ripley 573
    va_end(ap);
574
    immediateWarning = 0;
575
}
576
 
25358 luke 577
static void cleanup_PrintWarnings(void *data)
578
{
25367 luke 579
    if (R_CollectWarnings) {
580
	R_CollectWarnings = 0;
581
	R_Warnings = R_NilValue;
32858 ripley 582
	REprintf(_("Lost warning messages\n"));
25367 luke 583
    }
584
    inPrintWarnings = 0;
25358 luke 585
}
586
 
61771 ripley 587
attribute_hidden
6191 maechler 588
void PrintWarnings(void)
4165 rgentlem 589
{
590
    int i;
33553 ripley 591
    char *header;
592
    SEXP names, s, t;
25352 luke 593
    RCNTXT cntxt;
4165 rgentlem 594
 
25367 luke 595
    if (R_CollectWarnings == 0)
596
	return;
597
    else if (inPrintWarnings) {
598
	if (R_CollectWarnings) {
599
	    R_CollectWarnings = 0;
600
	    R_Warnings = R_NilValue;
32858 ripley 601
	    REprintf(_("Lost warning messages\n"));
25367 luke 602
	}
603
	return;
604
    }
605
 
606
    /* set up a context which will restore inPrintWarnings if there is
607
       an exit */
35450 murdoch 608
    begincontext(&cntxt, CTXT_CCODE, R_NilValue, R_BaseEnv, R_BaseEnv,
25352 luke 609
		 R_NilValue, R_NilValue);
25358 luke 610
    cntxt.cend = &cleanup_PrintWarnings;
25352 luke 611
 
25367 luke 612
    inPrintWarnings = 1;
70047 ripley 613
    header = ngettext("Warning message:", "Warning messages:",
65311 ripley 614
		      R_CollectWarnings);
4165 rgentlem 615
    if( R_CollectWarnings == 1 ) {
65311 ripley 616
	REprintf("%s\n", header);
4165 rgentlem 617
	names = CAR(ATTRIB(R_Warnings));
10172 luke 618
	if( VECTOR_ELT(R_Warnings, 0) == R_NilValue )
65311 ripley 619
	    REprintf("%s \n", CHAR(STRING_ELT(names, 0)));
41680 ripley 620
	else {
90285 ripley 621
	    const char *msg = CHAR(STRING_ELT(names, 0));
622
	    const char *dcall = CHAR(STRING_ELT(deparse1s(VECTOR_ELT(R_Warnings, 0)), 0));
70047 ripley 623
	    REprintf(_("In %s :"), dcall);
41712 ripley 624
	    if (mbcslocale) {
41731 ripley 625
		int msgline1;
90285 ripley 626
		if (strchr(msg, '\n')) {
627
		    // this branch alters msg temporarily
90288 ripley 628
		    char msg1[strlen(msg) + 1];
90285 ripley 629
		    strcpy(msg1, msg);
630
		    char *p = strchr(msg1, '\n');
41731 ripley 631
		    *p = '\0';
90285 ripley 632
		    msgline1 = wd(msg1);
41944 ripley 633
		} else msgline1 = wd(msg);
65311 ripley 634
		if (6 + wd(dcall) + msgline1 > LONGWARN) REprintf("\n ");
90285 ripley 635
		REprintf(" %s\n", msg);
49591 ripley 636
	    } else {
59173 ripley 637
		size_t msgline1 = strlen(msg);
90285 ripley 638
		const char *p = strchr(msg, '\n');
41731 ripley 639
		if (p) msgline1 = (int)(p - msg);
65311 ripley 640
		if (6 + strlen(dcall) + msgline1 > LONGWARN) REprintf("\n ");
90285 ripley 641
		REprintf(" %s\n", msg);
41731 ripley 642
	    }
41680 ripley 643
	}
644
    } else if( R_CollectWarnings <= 10 ) {
65311 ripley 645
	REprintf("%s\n", header);
4165 rgentlem 646
	names = CAR(ATTRIB(R_Warnings));
38545 ripley 647
	for(i = 0; i < R_CollectWarnings; i++) {
65311 ripley 648
	    if( VECTOR_ELT(R_Warnings, i) == R_NilValue ) {
41680 ripley 649
		REprintf("%d: %s \n", i+1, CHAR(STRING_ELT(names, i)));
65311 ripley 650
	    } else {
651
		const char *dcall, *msg = CHAR(STRING_ELT(names, i));
44633 ripley 652
		dcall = CHAR(STRING_ELT(deparse1s(VECTOR_ELT(R_Warnings, i)), 0));
70047 ripley 653
		REprintf("%d: ", i + 1);
654
		REprintf(_("In %s :"), dcall);
41712 ripley 655
		if (mbcslocale) {
41731 ripley 656
		    int msgline1;
90308 ripley 657
		    if (strchr(msg, '\n')) {
658
			// this branch alters msg temporarily
659
			char msg1[strlen(msg) + 1];
660
			strcpy(msg1, msg);
661
			char *p = strchr(msg1, '\n');
41731 ripley 662
			*p = '\0';
90308 ripley 663
			msgline1 = wd(msg1);
41944 ripley 664
		    } else msgline1 = wd(msg);
65311 ripley 665
		    if (10 + wd(dcall) + msgline1 > LONGWARN) {
70047 ripley 666
			REprintf("\n ");
667
		    }
49591 ripley 668
		} else {
59173 ripley 669
		    size_t msgline1 = strlen(msg);
90308 ripley 670
		    const char *p = strchr(msg, '\n');
41731 ripley 671
		    if (p) msgline1 = (int)(p - msg);
65311 ripley 672
		    if (10 + strlen(dcall) + msgline1 > LONGWARN) {
70047 ripley 673
			REprintf("\n ");
674
		    }
41731 ripley 675
		}
65311 ripley 676
		REprintf(" %s\n", msg);
41680 ripley 677
	    }
4165 rgentlem 678
	}
41680 ripley 679
    } else {
57675 ripley 680
	if (R_CollectWarnings < R_nwarnings)
70047 ripley 681
	    REprintf(ngettext("There was %d warning (use warnings() to see it)",
682
			      "There were %d warnings (use warnings() to see them)",
683
			      R_CollectWarnings),
8315 ripley 684
		     R_CollectWarnings);
685
	else
70047 ripley 686
	    REprintf(_("There were %d or more warnings (use warnings() to see the first %d)"),
65311 ripley 687
		     R_nwarnings, R_nwarnings);
688
	REprintf("\n");
4165 rgentlem 689
    }
690
    /* now truncate and install last.warning */
691
    PROTECT(s = allocVector(VECSXP, R_CollectWarnings));
692
    PROTECT(t = allocVector(STRSXP, R_CollectWarnings));
693
    names = CAR(ATTRIB(R_Warnings));
41712 ripley 694
    for(i = 0; i < R_CollectWarnings; i++) {
10172 luke 695
	SET_VECTOR_ELT(s, i, VECTOR_ELT(R_Warnings, i));
38540 ripley 696
	SET_STRING_ELT(t, i, STRING_ELT(names, i));
4165 rgentlem 697
    }
698
    setAttrib(s, R_NamesSymbol, t);
38616 ripley 699
    SET_SYMVALUE(install("last.warning"), s);
4165 rgentlem 700
    UNPROTECT(2);
25352 luke 701
 
702
    endcontext(&cntxt);
703
 
25367 luke 704
    inPrintWarnings = 0;
7879 ripley 705
    R_CollectWarnings = 0;
706
    R_Warnings = R_NilValue;
4165 rgentlem 707
    return;
708
}
709
 
59431 murdoch 710
/* Return a constructed source location (e.g. filename#123) from a srcref.  If the srcref
711
   is not valid "" will be returned.
712
*/
713
 
714
static SEXP GetSrcLoc(SEXP srcref)
715
{
67099 luke 716
    SEXP sep, line, result, srcfile;
61827 ripley 717
    if (TYPEOF(srcref) != INTSXP || length(srcref) < 4)
59431 murdoch 718
	return ScalarString(mkChar(""));
67099 luke 719
 
720
    PROTECT(srcref);
721
    PROTECT(srcfile = R_GetSrcFilename(srcref));
61827 ripley 722
    SEXP e2 = PROTECT(lang2( install("basename"), srcfile));
723
    PROTECT(srcfile = eval(e2, R_BaseEnv ) );
59431 murdoch 724
    PROTECT(sep = ScalarString(mkChar("#")));
725
    PROTECT(line = ScalarInteger(INTEGER(srcref)[0]));
61827 ripley 726
    SEXP e = PROTECT(lang4( install("paste0"), srcfile, sep, line ));
727
    result = eval(e, R_BaseEnv );
67099 luke 728
    UNPROTECT(7);
59431 murdoch 729
    return result;
730
}
731
 
76840 luke 732
static char errbuf[BUFSIZE + 1]; /* add 1 to leave room for a null byte */
4165 rgentlem 733
 
75601 kalibera 734
#define ERRBUFCAT(txt) Rstrncat(errbuf, txt, BUFSIZE - strlen(errbuf))
73929 luke 735
 
82931 ripley 736
const char *R_curErrorBuf(void) {
54493 jmc 737
    return (const char *)errbuf;
738
}
739
 
25352 luke 740
static void restore_inError(void *data)
741
{
39866 duncan 742
    int *poldval = (int *) data;
25352 luke 743
    inError = *poldval;
37271 ripley 744
    R_Expressions = R_Expressions_keep;
25352 luke 745
}
746
 
70827 luke 747
/* Do not check constants on error more than this number of times per one
748
   R process lifetime; if so many errors are generated, the performance
749
   overhead due to the checks would be too high, and the program is doing
750
   something strange anyway (i.e. running no-segfault tests). The constant
751
   checks in GC and session exit (or .Call) do not have such limit. */
752
static int allowedConstsChecks = 1000;
753
 
79123 kalibera 754
/* Construct newline terminated error message, write it to global errbuf, and
755
   possibly display with REprintf. */
83452 ripley 756
NORET static void
62367 ripley 757
verrorcall_dflt(SEXP call, const char *format, va_list ap)
2 r 758
{
70827 luke 759
    if (allowedConstsChecks > 0) {
760
	allowedConstsChecks--;
761
	R_checkConstants(TRUE);
762
    }
8004 maechler 763
 
8892 maechler 764
    if (inError) {
25367 luke 765
	/* fail-safe handler for recursive errors */
14608 luke 766
	if(inError == 3) {
767
	     /* Can REprintf generate an error? If so we should guard for it */
32858 ripley 768
	    REprintf(_("Error during wrapup: "));
14608 luke 769
	    /* this does NOT try to print the call since that could
45446 ripley 770
	       cause a cascade of error calls */
79159 kalibera 771
	    Rvsnprintf_mbcs(errbuf, sizeof(errbuf), format, ap);
14608 luke 772
	    REprintf("%s\n", errbuf);
773
	}
25367 luke 774
	if (R_Warnings != R_NilValue) {
775
	    R_CollectWarnings = 0;
776
	    R_Warnings = R_NilValue;
32858 ripley 777
	    REprintf(_("Lost warning messages\n"));
25367 luke 778
	}
77712 luke 779
	REprintf(_("Error: no more error handlers available "
780
		   "(recursive errors?); invoking 'abort' restart\n"));
37271 ripley 781
	R_Expressions = R_Expressions_keep;
25370 luke 782
	jump_to_top_ex(FALSE, FALSE, FALSE, FALSE, FALSE);
6199 rgentlem 783
    }
784
 
25352 luke 785
    /* set up a context to restore inError value on exit */
87097 maechler 786
    RCNTXT cntxt;
35450 murdoch 787
    begincontext(&cntxt, CTXT_CCODE, R_NilValue, R_BaseEnv, R_BaseEnv,
25352 luke 788
		 R_NilValue, R_NilValue);
87097 maechler 789
    int oldInError;
25352 luke 790
    cntxt.cend = &restore_inError;
791
    cntxt.cenddata = &oldInError;
792
    oldInError = inError;
25368 luke 793
    inError = 1;
25352 luke 794
 
79123 kalibera 795
    // For use with Rv?snprintf, which truncates at size - 1, hence the + 1
796
    size_t msg_len = min(BUFSIZE, R_WarnLength) + 1;
797
 
8892 maechler 798
    if(call != R_NilValue) {
65311 ripley 799
	char tmp[BUFSIZE], tmp2[BUFSIZE];
800
	char *head = _("Error in "), *tail = "\n  ";
65321 ripley 801
	SEXP srcloc = R_NilValue; // -Wall
802
	size_t len = 0;	// indicates if srcloc has been set
87647 kalibera 803
	int protected = 0, show = 0;
59431 murdoch 804
	SEXP opt = GetOption1(install("show.error.locations"));
87647 kalibera 805
	if (length(opt) == 1 &&
806
	    (asLogical(opt) == 1 ||
807
	     (TYPEOF(opt) == STRSXP &&
808
	      pmatch(ScalarString(mkChar("top")), opt, 0))))
809
	    	show = 1;
14439 luke 810
 
65311 ripley 811
	const char *dcall = CHAR(STRING_ELT(deparse1s(call), 0));
79216 kalibera 812
	Rsnprintf_mbcs(tmp2, BUFSIZE,  "%s", head);
87647 kalibera 813
	if (show) {
814
	    PROTECT(srcloc = GetSrcLoc(R_GetCurrentSrcref(NA_INTEGER)));
59431 murdoch 815
	    protected++;
816
	    len = strlen(CHAR(STRING_ELT(srcloc, 0)));
65311 ripley 817
	    if (len)
79216 kalibera 818
		Rsnprintf_mbcs(tmp2, BUFSIZE,  _("Error in %s (from %s) : "),
819
			       dcall, CHAR(STRING_ELT(srcloc, 0)));
59431 murdoch 820
	}
65311 ripley 821
 
79159 kalibera 822
	Rvsnprintf_mbcs(tmp, max(msg_len - strlen(head), 0), format, ap);
65311 ripley 823
	if (strlen(tmp2) + strlen(tail) + strlen(tmp) < BUFSIZE) {
79216 kalibera 824
	    if(len) Rsnprintf_mbcs(errbuf, BUFSIZE,
825
				   _("Error in %s (from %s) : "),
826
				   dcall, CHAR(STRING_ELT(srcloc, 0)));
827
	    else Rsnprintf_mbcs(errbuf, BUFSIZE,  _("Error in %s : "), dcall);
41712 ripley 828
	    if (mbcslocale) {
55099 ripley 829
		int msgline1;
90308 ripley 830
		// tmp is local array, so OK to temporaily edit in place
41742 ripley 831
		char *p = strchr(tmp, '\n');
832
		if (p) {
833
		    *p = '\0';
41944 ripley 834
		    msgline1 = wd(tmp);
41742 ripley 835
		    *p = '\n';
41944 ripley 836
		} else msgline1 = wd(tmp);
74951 ripley 837
		// gcc 8 warns here
838
		// 'output may be truncated copying between 0 and 8191 bytes from a string of length 8191'
839
		// but truncation is intentional.
55099 ripley 840
		if (14 + wd(dcall) + msgline1 > LONGWARN)
73929 luke 841
		    ERRBUFCAT(tail);
49591 ripley 842
	    } else {
59173 ripley 843
		size_t msgline1 = strlen(tmp);
90308 ripley 844
		const char *p = strchr(tmp, '\n');
41742 ripley 845
		if (p) msgline1 = (int)(p - tmp);
846
		if (14 + strlen(dcall) + msgline1 > LONGWARN)
73929 luke 847
		    ERRBUFCAT(tail);
41742 ripley 848
	    }
73929 luke 849
	    ERRBUFCAT(tmp);
41712 ripley 850
	} else {
79216 kalibera 851
	    Rsnprintf_mbcs(errbuf, BUFSIZE, _("Error: "));
79123 kalibera 852
	    ERRBUFCAT(tmp);
14439 luke 853
	}
59431 murdoch 854
	UNPROTECT(protected);
4179 rgentlem 855
    }
41712 ripley 856
    else {
79216 kalibera 857
	Rsnprintf_mbcs(errbuf, BUFSIZE, _("Error: "));
87097 maechler 858
	char *p = errbuf + strlen(errbuf);
79159 kalibera 859
	Rvsnprintf_mbcs(p, max(msg_len - strlen(errbuf), 0), format, ap);
41712 ripley 860
    }
79123 kalibera 861
    /* Approximate truncation detection, may produce false positives.  Assumes
80402 kalibera 862
       R_MB_CUR_MAX > 0. Note: approximation is fine, as the string may include
79123 kalibera 863
       dots, anyway */
864
    size_t nc = strlen(errbuf); // > 0, ignoring possibility of failure
80402 kalibera 865
    if (nc > BUFSIZE - 1 - (R_MB_CUR_MAX - 1)) {
79123 kalibera 866
	size_t end = min(nc + 1, (BUFSIZE + 1) - 4); // room for "...\n\0"
867
	for(size_t i = end; i <= BUFSIZE + 1; ++i) errbuf[i - 1] = '\0';
868
	mbcsTruncateToValid(errbuf);
869
	ERRBUFCAT("...\n");
870
    } else {
87097 maechler 871
	char *p = errbuf + nc - 1;
79123 kalibera 872
	if(*p != '\n') {
873
	    ERRBUFCAT("\n");  // guaranteed to have room for this
874
	    ++nc;
41712 ripley 875
	}
79123 kalibera 876
	if(R_ShowErrorCalls && call != R_NilValue) {  /* assume we want to avoid deparse */
87097 maechler 877
	    char *tr = R_ConciseTraceback(call, 0);
79123 kalibera 878
	    size_t nc_tr = strlen(tr);
879
	    if (nc_tr) {
880
		char * call_trans = _("Calls:");
881
		if (nc_tr + nc + strlen(call_trans) + 2 < BUFSIZE + 1) {
882
		    ERRBUFCAT(call_trans);
883
		    ERRBUFCAT(" ");
884
		    ERRBUFCAT(tr);
885
		    ERRBUFCAT("\n");
886
		}
887
	    }
888
	}
41712 ripley 889
    }
8103 ripley 890
    if (R_ShowErrorMessages) REprintf("%s", errbuf);
25358 luke 891
 
892
    if( R_ShowErrorMessages && R_CollectWarnings ) {
32858 ripley 893
	REprintf(_("In addition: "));
25358 luke 894
	PrintWarnings();
895
    }
896
 
25370 luke 897
    jump_to_top_ex(TRUE, TRUE, TRUE, TRUE, FALSE);
25352 luke 898
 
899
    /* not reached */
900
    endcontext(&cntxt);
25368 luke 901
    inError = oldInError;
2 r 902
}
903
 
83452 ripley 904
NORET static void errorcall_dflt(SEXP call, const char *format,...)
25523 luke 905
{
906
    va_list(ap);
907
 
908
    va_start(ap, format);
909
    verrorcall_dflt(call, format, ap);
910
    va_end(ap);
911
}
912
 
83452 ripley 913
NORET void errorcall(SEXP call, const char *format,...)
25523 luke 914
{
915
    va_list(ap);
916
 
71744 luke 917
    if (call == R_CurrentExpression)
918
	/* behave like error( */
919
	call = getCurrentCall();
920
 
25523 luke 921
    va_start(ap, format);
25526 luke 922
    vsignalError(call, format, ap);
25523 luke 923
    va_end(ap);
924
 
925
    va_start(ap, format);
926
    verrorcall_dflt(call, format, ap);
927
    va_end(ap);
928
}
929
 
71884 kalibera 930
/* Like errorcall, but copies all data for the error message into a buffer
931
   before doing anything else. */
87740 ripley 932
NORET attribute_hidden
933
void errorcall_cpy(SEXP call, const char *format, ...)
71884 kalibera 934
{
935
    char buf[BUFSIZE];
936
 
937
    va_list(ap);
938
    va_start(ap, format);
79159 kalibera 939
    Rvsnprintf_mbcs(buf, BUFSIZE, format, ap);
71884 kalibera 940
    va_end(ap);
941
 
942
    errorcall(call, "%s", buf);
943
}
944
 
74130 maechler 945
// geterrmessage(): Return (the global) 'errbuf' as R string
83446 ripley 946
attribute_hidden SEXP do_geterrmessage(SEXP call, SEXP op, SEXP args, SEXP env)
8103 ripley 947
{
948
    checkArity(op, args);
74130 maechler 949
    SEXP res = PROTECT(allocVector(STRSXP, 1));
10172 luke 950
    SET_STRING_ELT(res, 0, mkChar(errbuf));
8892 maechler 951
    UNPROTECT(1);
8103 ripley 952
    return res;
953
}
954
 
2 r 955
void error(const char *format, ...)
956
{
14494 hornik 957
    char buf[BUFSIZE];
6199 rgentlem 958
 
1839 ihaka 959
    va_list(ap);
960
    va_start(ap, format);
79159 kalibera 961
    Rvsnprintf_mbcs(buf, min(BUFSIZE, R_WarnLength), format, ap);
1839 ihaka 962
    va_end(ap);
71744 luke 963
    errorcall(getCurrentCall(), "%s", buf);
2 r 964
}
965
 
25470 luke 966
static void try_jump_to_restart(void)
967
{
25523 luke 968
    SEXP list;
969
 
970
    for (list = R_RestartStack; list != R_NilValue; list = CDR(list)) {
971
	SEXP restart = CAR(list);
972
	if (TYPEOF(restart) == VECSXP && LENGTH(restart) > 1) {
973
	    SEXP name = VECTOR_ELT(restart, 0);
974
	    if (TYPEOF(name) == STRSXP && LENGTH(name) == 1) {
41807 rgentlem 975
		const char *cname = CHAR(STRING_ELT(name, 0));
25523 luke 976
		if (! strcmp(cname, "browser") ||
977
		    ! strcmp(cname, "tryRestart") ||
978
		    ! strcmp(cname, "abort")) /**** move abort eventually? */
979
		    invokeRestart(restart, R_NilValue);
980
	    }
981
	}
982
    }
25470 luke 983
}
984
 
2 r 985
/* Unwind the call stack in an orderly fashion */
986
/* calling the code installed by on.exit along the way */
11414 rgentlem 987
/* and finally longjmping to the innermost TOPLEVEL context */
2 r 988
 
25368 luke 989
static void jump_to_top_ex(Rboolean traceback,
990
			   Rboolean tryUserHandler,
991
			   Rboolean processWarnings,
25370 luke 992
			   Rboolean resetConsole,
993
			   Rboolean ignoreRestartContexts)
2 r 994
{
25352 luke 995
    RCNTXT cntxt;
25421 luke 996
    SEXP s;
25352 luke 997
    int haveHandler, oldInError;
6098 pd 998
 
25352 luke 999
    /* set up a context to restore inError value on exit */
35450 murdoch 1000
    begincontext(&cntxt, CTXT_CCODE, R_NilValue, R_BaseEnv, R_BaseEnv,
25352 luke 1001
		 R_NilValue, R_NilValue);
1002
    cntxt.cend = &restore_inError;
1003
    cntxt.cenddata = &oldInError;
6178 rgentlem 1004
 
25352 luke 1005
    oldInError = inError;
1006
 
25368 luke 1007
    haveHandler = FALSE;
25352 luke 1008
 
70323 luke 1009
    /* don't use options("error") when handling a C stack overflow */
1010
    if (R_OldCStackLimit == 0 && tryUserHandler && inError < 3) {
25368 luke 1011
	if (! inError)
1012
	    inError = 1;
6199 rgentlem 1013
 
54049 ripley 1014
	/* now see if options("error") is set */
1015
	s = GetOption1(install("error"));
25353 luke 1016
	haveHandler = ( s != R_NilValue );
1017
	if (haveHandler) {
1018
	    if( !isLanguage(s) &&  ! isExpression(s) )  /* shouldn't happen */
32858 ripley 1019
		REprintf(_("invalid option \"error\"\n"));
25353 luke 1020
	    else {
81150 luke 1021
		R_CheckStack();
25353 luke 1022
		inError = 3;
1023
		if (isLanguage(s))
1024
		    eval(s, R_GlobalEnv);
1025
		else /* expression */
1026
		    {
1027
			int i, n = LENGTH(s);
1028
			for (i = 0 ; i < n ; i++)
1029
			    eval(VECTOR_ELT(s, i), R_GlobalEnv);
1030
		    }
25368 luke 1031
		inError = oldInError;
25353 luke 1032
	    }
1033
	}
25368 luke 1034
	inError = oldInError;
1035
    }
25353 luke 1036
 
25368 luke 1037
    /* print warnings if there are any left to be printed */
1038
    if( processWarnings && R_CollectWarnings )
1039
	PrintWarnings();
25358 luke 1040
 
25368 luke 1041
    /* reset some stuff--not sure (all) this belongs here */
1042
    if (resetConsole) {
25353 luke 1043
	R_ResetConsole();
1044
	R_FlushConsole();
1045
	R_ClearerrConsole();
1046
	R_ParseError = 0;
39996 murdoch 1047
	R_ParseErrorFile = NULL;
45446 ripley 1048
	R_ParseErrorMsg[0] = '\0';
6199 rgentlem 1049
    }
1050
 
31938 murrell 1051
    /*
1052
     * Reset graphics state
1053
     */
1054
    GEonExit();
1055
 
25368 luke 1056
    /* WARNING: If oldInError > 0 ABSOLUTELY NO ALLOCATION can be
27000 luke 1057
       triggered after this point except whatever happens in writing
70325 luke 1058
       the traceback.  The error could be an out of memory error and
1059
       any allocation could result in an infinite-loop condition. All
1060
       you can do is reset things and exit.  */
14478 luke 1061
 
25470 luke 1062
    /* jump to a browser/try if one is on the stack */
1063
    if (! ignoreRestartContexts)
1064
	try_jump_to_restart();
1065
    /* at this point, i.e. if we have not exited in
1066
       try_jump_to_restart, we are heading for R_ToplevelContext */
1067
 
27000 luke 1068
    /* only run traceback if we are not going to bail out of a
1069
       non-interactive session */
85406 maechler 1070
 
1071
    if (R_Interactive || haveHandler || R_isTRUE(GetOption1(install("catch.script.errors")))) {
27000 luke 1072
	/* write traceback if requested, unless we're already doing it
38616 ripley 1073
	   or there is an inconsistency between inError and oldInError
27000 luke 1074
	   (which should not happen) */
1075
	if (traceback && inError < 2 && inError == oldInError) {
1076
	    inError = 2;
76872 maechler 1077
	    PROTECT(s = R_GetTracebackOnly(0));
38616 ripley 1078
	    SET_SYMVALUE(install(".Traceback"), s);
1079
	    /* should have been defineVar
1080
	       setVar(install(".Traceback"), s, R_GlobalEnv); */
27000 luke 1081
	    UNPROTECT(1);
1082
	    inError = oldInError;
1083
	}
1084
    }
1085
 
70324 luke 1086
    R_jumpctxt(R_ToplevelContext, 0, NULL);
2 r 1087
}
1088
 
83452 ripley 1089
NORET void jump_to_toplevel(void)
25368 luke 1090
{
1091
    /* no traceback, no user error option; for now, warnings are
1092
       printed here and console is reset -- eventually these should be
25370 luke 1093
       done after arriving at the jump target.  Now ignores
1094
       try/browser frames--it really is a jump to toplevel */
1095
    jump_to_top_ex(FALSE, FALSE, TRUE, TRUE, TRUE);
25368 luke 1096
}
1097
 
32933 ripley 1098
/* #define DEBUG_GETTEXT 1 */
32928 ripley 1099
 
81081 maechler 1100
#ifdef DEBUG_GETTEXT
1101
# include <Print.h>
1102
# define GETT_PRINT(...) REprintf(__VA_ARGS__)
1103
#else
1104
# define GETT_PRINT(...) do {} while(0)
1105
#endif
79942 maechler 1106
 
85616 kalibera 1107
#ifdef ENABLE_NLS
79945 maechler 1108
/* Called from do_gettext() and do_ngettext() */
81208 maechler 1109
static const char * determine_domain_gettext(SEXP domain_, Rboolean up)
32928 ripley 1110
{
79942 maechler 1111
    const char *domain = "";
1112
    char *buf; // will be returned
45446 ripley 1113
 
81082 maechler 1114
    /* If TYPEOF(cptr->callfun) == CLOSXP (not .Primitive("eval")),
80987 maechler 1115
     * ENCLOS(cptr->cloenv) is CLOENV(cptr->callfun) */
1116
    /* R_findParentContext(cptr, 1)->cloenv == cptr->sysparent */
79942 maechler 1117
    if(isNull(domain_)) {
81082 maechler 1118
	RCNTXT *cptr;
81081 maechler 1119
	GETT_PRINT(">> determine_domain_gettext(), first rho=%s\n", EncodeEnvironment(rho));
79942 maechler 1120
 
80987 maechler 1121
	/* stop() etc have internal call to .makeMessage */
1122
	/* gettextf calls gettext */
81082 maechler 1123
 
1124
	SEXP rho = R_EmptyEnv;
1125
	if(R_GlobalContext->callflag & CTXT_FUNCTION) {
1126
	    if(up) {
1127
		SEXP call = R_GlobalContext->call;
1128
		/* The call is of the form
1129
		   <symbol>(<symbol>, domain = domain [possible other argument]) */
1130
		rho =
1131
		    (isSymbol(CAR(call)) && (call = CDR(call)) != R_NilValue &&
1132
		     TAG(call) == R_NilValue && isSymbol(CAR(call)) &&
1133
		     (call = CDR(call)) != R_NilValue &&
1134
		     isSymbol(TAG(call)) && streql(CHAR(PRINTNAME(TAG(call))), "domain") &&
1135
		     isSymbol(CAR(call)) && streql(CHAR(PRINTNAME(CAR(call))), "domain") &&
1136
		     (cptr = R_findParentContext(R_GlobalContext, 1)))
1137
		    ? cptr->sysparent
1138
		    : R_GlobalContext->sysparent;
32928 ripley 1139
	    }
81082 maechler 1140
	    else
1141
		rho = R_GlobalContext->sysparent;
80987 maechler 1142
	}
81082 maechler 1143
	GETT_PRINT(" .. rho1_domain_ => rho=%s\n", EncodeEnvironment(rho));
79942 maechler 1144
 
79969 kalibera 1145
	SEXP ns = R_NilValue;
81081 maechler 1146
	int cnt = 0;
79942 maechler 1147
	    while(rho != R_EmptyEnv) {
1148
		if (rho == R_GlobalEnv) break;
1149
		else if (R_IsNamespaceEnv(rho)) {
79969 kalibera 1150
		    ns = R_NamespaceEnvSpec(rho);
79942 maechler 1151
		    break;
1152
		}
81081 maechler 1153
		if(++cnt <= 5 || cnt > 99) { // diagnose "inf." loop
1154
		    GETT_PRINT("  cnt=%4d, rho=%s\n", cnt, EncodeEnvironment(rho));
1155
		    if(cnt > 111) break;
1156
		}
1157
		if(rho == ENCLOS(rho)) break; // *did* happen; now keep for safety
79969 kalibera 1158
		rho = ENCLOS(rho);
32928 ripley 1159
	    }
79969 kalibera 1160
	if (!isNull(ns)) {
1161
	    PROTECT(ns);
1162
	    domain = translateChar(STRING_ELT(ns, 0));
1163
	    if (strlen(domain)) {
1164
		size_t len = strlen(domain)+3;
1165
		buf = R_alloc(len, sizeof(char));
1166
		Rsnprintf_mbcs(buf, len, "R-%s", domain);
1167
		UNPROTECT(1); /* ns */
81081 maechler 1168
		GETT_PRINT("Managed to determine 'domain' from environment as: '%s'\n", buf);
81208 maechler 1169
		return (const char*) buf;
79969 kalibera 1170
	    }
81081 maechler 1171
	    UNPROTECT(1); /* ns */
79969 kalibera 1172
	}
1173
	return NULL;
1174
 
1175
    } else if(isString(domain_)) {
79942 maechler 1176
	domain = translateChar(STRING_ELT(domain_, 0));
79969 kalibera 1177
	if (!strlen(domain))
1178
	    return NULL;
81208 maechler 1179
	return domain;
81081 maechler 1180
 
79969 kalibera 1181
    } else if(isLogical(domain_) && LENGTH(domain_) == 1 && LOGICAL(domain_)[0] == NA_LOGICAL)
1182
	return NULL;
70830 luke 1183
    else error(_("invalid '%s' value"), "domain");
79942 maechler 1184
}
85616 kalibera 1185
#endif
79942 maechler 1186
 
1187
 
81162 maechler 1188
/* gettext(domain, string, trim) */
83446 ripley 1189
attribute_hidden SEXP do_gettext(SEXP call, SEXP op, SEXP args, SEXP rho)
79942 maechler 1190
{
81162 maechler 1191
#ifdef _gettext_3_args_only_
79942 maechler 1192
    checkArity(op, args);
81162 maechler 1193
#else
1194
    // legacy code allowing "captured" 2-arg calls
1195
    int nargs = length(args);
1196
    if (nargs < 2 || nargs > 3)
1197
	errorcall(call, "either 2 or 3 arguments are required");
1198
#endif
79942 maechler 1199
#ifdef ENABLE_NLS
1200
    SEXP string = CADR(args);
1201
    int n = LENGTH(string);
1202
 
1203
    if(isNull(string) || !n) return string;
1204
 
1205
    if(!isString(string)) error(_("invalid '%s' value"), "string");
1206
 
81208 maechler 1207
    const char * domain = determine_domain_gettext(CAR(args), /*up*/TRUE);
79942 maechler 1208
 
1209
    if(domain && strlen(domain)) {
1210
	SEXP ans = PROTECT(allocVector(STRSXP, n));
81164 maechler 1211
	Rboolean trim;
1212
#ifdef _gettext_3_args_only_
1213
#else
1214
	if(nargs == 2)
1215
	    trim = TRUE;
1216
	else
81162 maechler 1217
#endif
87815 ripley 1218
	    trim = asRbool(CADDR(args), call);
79942 maechler 1219
	for(int i = 0; i < n; i++) {
32933 ripley 1220
	    int ihead = 0, itail = 0;
41784 ripley 1221
	    const char * This = translateChar(STRING_ELT(string, i));
81208 maechler 1222
	    char *tmp, *head = NULL, *tail = NULL, *tr;
1223
	    const char *p;
79942 maechler 1224
 
81208 maechler 1225
	    if(trim) {
1226
		R_CheckStack2(strlen(This) + 1);
1227
		tmp = (char *) alloca(strlen(This) + 1);
1228
		strcpy(tmp, This);
79942 maechler 1229
 
81162 maechler 1230
		/* strip leading and trailing white spaces and
1231
		   add back after translation */
1232
		for(p = tmp;
1233
		    *p && (*p == ' ' || *p == '\t' || *p == '\n');
1234
		    p++, ihead++) ;
79942 maechler 1235
 
81162 maechler 1236
		if(ihead > 0) {
1237
		    R_CheckStack2(ihead + 1);
1238
		    head = (char *) alloca(ihead + 1);
1239
		    Rstrncpy(head, tmp, ihead + 1);
1240
		    tmp += ihead;
1241
		}
79942 maechler 1242
 
81162 maechler 1243
		if(strlen(tmp))
1244
		    for(p = tmp+strlen(tmp)-1;
1245
			p >= tmp && (*p == ' ' || *p == '\t' || *p == '\n');
1246
			p--, itail++) ;
1247
 
1248
		if(itail > 0) {
1249
		    R_CheckStack2(itail + 1);
1250
		    tail = (char *) alloca(itail + 1);
1251
		    strcpy(tail, tmp+strlen(tmp)-itail);
1252
		    tmp[strlen(tmp)-itail] = '\0';
1253
		}
81208 maechler 1254
 
1255
		p = tmp;
1256
	    } else
1257
		p = This;
1258
	    if(strlen(p)) {
1259
		GETT_PRINT("translating '%s' in domain '%s'\n", p, domain);
1260
		tr = dgettext(domain, p);
1261
		if(ihead > 0 || itail > 0) {
79942 maechler 1262
 		R_CheckStack2(        strlen(tr) + ihead + itail + 1);
39866 duncan 1263
		tmp = (char *) alloca(strlen(tr) + ihead + itail + 1);
32938 ripley 1264
		tmp[0] ='\0';
81208 maechler 1265
		if(ihead > 0) strcat(tmp, head);
32938 ripley 1266
		strcat(tmp, tr);
81208 maechler 1267
		if(itail > 0) strcat(tmp, tail);
1268
		} else
1269
		    tmp = tr;
41883 ripley 1270
		SET_STRING_ELT(ans, i, mkChar(tmp));
45446 ripley 1271
	    } else
41883 ripley 1272
		SET_STRING_ELT(ans, i, mkChar(This));
32928 ripley 1273
	}
1274
	UNPROTECT(1);
1275
	return ans;
79942 maechler 1276
    } else
32928 ripley 1277
#endif
79942 maechler 1278
	// no NLS or no domain :
1279
	return CADR(args);
32928 ripley 1280
}
1281
 
33115 ripley 1282
/* ngettext(n, msg1, msg2, domain) */
83446 ripley 1283
attribute_hidden SEXP do_ngettext(SEXP call, SEXP op, SEXP args, SEXP rho)
33115 ripley 1284
{
36138 ripley 1285
    SEXP msg1 = CADR(args), msg2 = CADDR(args);
33115 ripley 1286
    int n = asInteger(CAR(args));
45446 ripley 1287
 
33115 ripley 1288
    checkArity(op, args);
54958 ripley 1289
    if(n == NA_INTEGER || n < 0) error(_("invalid '%s' argument"), "n");
33115 ripley 1290
    if(!isString(msg1) || LENGTH(msg1) != 1)
67542 maechler 1291
	error(_("'%s' must be a character string"), "msg1");
33115 ripley 1292
    if(!isString(msg2) || LENGTH(msg2) != 1)
67542 maechler 1293
	error(_("'%s' must be a character string"), "msg2");
33115 ripley 1294
 
1295
#ifdef ENABLE_NLS
81208 maechler 1296
    const char * domain = determine_domain_gettext(CADDDR(args), /*up*/FALSE);
79942 maechler 1297
 
1298
    if(domain && strlen(domain)) {
1299
	/* libintl seems to malfunction if given a message of "" */
1300
	if(length(STRING_ELT(msg1, 0))) {
1301
	    char *fmt = dngettext(domain,
1302
		      translateChar(STRING_ELT(msg1, 0)),
1303
		      translateChar(STRING_ELT(msg2, 0)),
1304
		      n);
1305
	    return mkString(fmt);
33115 ripley 1306
	}
79942 maechler 1307
    }
33115 ripley 1308
#endif
79942 maechler 1309
    return n == 1 ? msg1 : msg2;
33115 ripley 1310
}
1311
 
1312
 
32928 ripley 1313
/* bindtextdomain(domain, dirname) */
83446 ripley 1314
attribute_hidden SEXP do_bindtextdomain(SEXP call, SEXP op, SEXP args, SEXP rho)
32928 ripley 1315
{
1316
#ifdef ENABLE_NLS
1317
    checkArity(op, args);
81184 maechler 1318
    if(isNull(CAR(args)) && isNull(CADR(args))) {
1319
	textdomain(textdomain(NULL)); // flush the cache
1320
	return ScalarLogical(TRUE);
1321
    }
1322
    else if(!isString(CAR(args)) || LENGTH(CAR(args)) != 1)
70830 luke 1323
	error(_("invalid '%s' value"), "domain");
81184 maechler 1324
 
1325
    char *res;
32928 ripley 1326
    if(isNull(CADR(args))) {
40705 ripley 1327
	res = bindtextdomain(translateChar(STRING_ELT(CAR(args),0)), NULL);
32928 ripley 1328
    } else {
45446 ripley 1329
	if(!isString(CADR(args)) || LENGTH(CADR(args)) != 1)
70830 luke 1330
	    error(_("invalid '%s' value"), "dirname");
81081 maechler 1331
	res = bindtextdomain(translateChar(STRING_ELT(CAR (args),0)),
40705 ripley 1332
			     translateChar(STRING_ELT(CADR(args),0)));
32928 ripley 1333
    }
1334
    if(res) return mkString(res);
1335
    /* else this failed */
1336
#endif
1337
    return R_NilValue;
1338
}
1339
 
25513 luke 1340
static SEXP findCall(void)
1341
{
1342
    RCNTXT *cptr;
1343
    for (cptr = R_GlobalContext->nextcontext;
1344
	 cptr != NULL && cptr->callflag != CTXT_TOPLEVEL;
1345
	 cptr = cptr->nextcontext)
1346
	if (cptr->callflag & CTXT_FUNCTION)
1347
	    return cptr->call;
1348
    return R_NilValue;
1349
}
29340 murdoch 1350
 
87740 ripley 1351
NORET attribute_hidden SEXP do_stop(SEXP call, SEXP op, SEXP args, SEXP rho)
2 r 1352
{
10919 maechler 1353
/* error(.) : really doesn't return anything; but all do_foo() must be SEXP */
8892 maechler 1354
    SEXP c_call;
69326 luke 1355
    checkArity(op, args);
6199 rgentlem 1356
 
25513 luke 1357
    if(asLogical(CAR(args))) /* find context -> "Error in ..:" */
1358
	c_call = findCall();
8892 maechler 1359
    else
45446 ripley 1360
	c_call = R_NilValue;
1361
 
8892 maechler 1362
    args = CDR(args);
1363
 
1364
    if (CAR(args) != R_NilValue) { /* message */
10172 luke 1365
      SETCAR(args, coerceVector(CAR(args), STRSXP));
8004 maechler 1366
      if(!isValidString(CAR(args)))
32858 ripley 1367
	  errorcall(c_call, _(" [invalid string in stop(.)]"));
40705 ripley 1368
      errorcall(c_call, "%s", translateChar(STRING_ELT(CAR(args), 0)));
6199 rgentlem 1369
    }
1839 ihaka 1370
    else
85580 kalibera 1371
      errorcall(c_call, "%s", "");
67181 luke 1372
    /* never called: */
2 r 1373
}
1374
 
83446 ripley 1375
attribute_hidden SEXP do_warning(SEXP call, SEXP op, SEXP args, SEXP rho)
2 r 1376
{
18015 ripley 1377
    SEXP c_call;
69326 luke 1378
    checkArity(op, args);
4179 rgentlem 1379
 
25513 luke 1380
    if(asLogical(CAR(args))) /* find context -> "... in: ..:" */
1381
	c_call = findCall();
1382
    else
18015 ripley 1383
	c_call = R_NilValue;
1384
 
1385
    args = CDR(args);
31757 ripley 1386
    if(asLogical(CAR(args))) { /* immediate = TRUE */
1387
	immediateWarning = 1;
45446 ripley 1388
    } else
31757 ripley 1389
	immediateWarning = 0;
1390
    args = CDR(args);
64828 ripley 1391
    if(asLogical(CAR(args))) { /* noBreak = TRUE */
1392
	noBreakWarning = 1;
1393
    } else
1394
	noBreakWarning = 0;
1395
    args = CDR(args);
1839 ihaka 1396
    if (CAR(args) != R_NilValue) {
10172 luke 1397
	SETCAR(args, coerceVector(CAR(args), STRSXP));
8004 maechler 1398
	if(!isValidString(CAR(args)))
32858 ripley 1399
	    warningcall(c_call, _(" [invalid string in warning(.)]"));
8004 maechler 1400
	else
40705 ripley 1401
	    warningcall(c_call, "%s", translateChar(STRING_ELT(CAR(args), 0)));
1839 ihaka 1402
    }
1403
    else
85580 kalibera 1404
	warningcall(c_call, "%s", "");
31757 ripley 1405
    immediateWarning = 0; /* reset to internal calls */
64828 ripley 1406
    noBreakWarning = 0;
25523 luke 1407
 
1839 ihaka 1408
    return CAR(args);
2 r 1409
}
1410
 
2472 maechler 1411
/* Error recovery for incorrect argument count error. */
87740 ripley 1412
NORET attribute_hidden
1413
void WrongArgCount(const char *s)
2472 maechler 1414
{
32858 ripley 1415
    error(_("incorrect number of arguments to \"%s\""), s);
2472 maechler 1416
}
1417
 
1418
 
83452 ripley 1419
NORET void UNIMPLEMENTED(const char *s)
2 r 1420
{
33297 ripley 1421
    error(_("unimplemented feature in %s"), s);
2 r 1422
}
1423
 
11046 maechler 1424
/* ERROR_.. codes in Errormsg.h */
2 r 1425
static struct {
39866 duncan 1426
    const R_ERROR code;
13997 duncan 1427
    const char* const format;
2 r 1428
}
13997 duncan 1429
const ErrorDB[] = {
32875 ripley 1430
    { ERROR_NUMARGS,		N_("invalid number of arguments")	},
1431
    { ERROR_ARGTYPE,		N_("invalid argument type")		},
2 r 1432
 
32875 ripley 1433
    { ERROR_TSVEC_MISMATCH,	N_("time-series/vector length mismatch")},
1434
    { ERROR_INCOMPAT_ARGS,	N_("incompatible arguments")		},
2 r 1435
 
32875 ripley 1436
    { ERROR_UNIMPLEMENTED,	N_("unimplemented feature in %s")	},
1437
    { ERROR_UNKNOWN,		N_("unknown error (report this!)")	}
2 r 1438
};
1439
 
11046 maechler 1440
static struct {
1441
    R_WARNING code;
1442
    char* format;
1443
}
1444
WarningDB[] = {
32875 ripley 1445
    { WARNING_coerce_NA,	N_("NAs introduced by coercion")	},
1446
    { WARNING_coerce_INACC,	N_("inaccurate integer conversion in coercion")},
1447
    { WARNING_coerce_IMAG,	N_("imaginary parts discarded in coercion") },
11046 maechler 1448
 
32875 ripley 1449
    { WARNING_UNKNOWN,		N_("unknown warning (report this!)")	},
11046 maechler 1450
};
1451
 
1452
 
87740 ripley 1453
NORET attribute_hidden
1454
void ErrorMessage(SEXP call, int which_error, ...)
2 r 1455
{
1839 ihaka 1456
    int i;
14494 hornik 1457
    char buf[BUFSIZE];
1839 ihaka 1458
    va_list(ap);
14442 luke 1459
 
1839 ihaka 1460
    i = 0;
11046 maechler 1461
    while(ErrorDB[i].code != ERROR_UNKNOWN) {
1462
	if (ErrorDB[i].code == which_error)
1839 ihaka 1463
	    break;
1464
	i++;
1465
    }
14442 luke 1466
 
1839 ihaka 1467
    va_start(ap, which_error);
79159 kalibera 1468
    Rvsnprintf_mbcs(buf, BUFSIZE, _(ErrorDB[i].format), ap);
1839 ihaka 1469
    va_end(ap);
14442 luke 1470
    errorcall(call, "%s", buf);
2 r 1471
}
1472
 
61771 ripley 1473
attribute_hidden
11046 maechler 1474
void WarningMessage(SEXP call, R_WARNING which_warn, ...)
2 r 1475
{
1839 ihaka 1476
    int i;
14494 hornik 1477
    char buf[BUFSIZE];
1839 ihaka 1478
    va_list(ap);
14442 luke 1479
 
1839 ihaka 1480
    i = 0;
11046 maechler 1481
    while(WarningDB[i].code != WARNING_UNKNOWN) {
1482
	if (WarningDB[i].code == which_warn)
1839 ihaka 1483
	    break;
1484
	i++;
1485
    }
14442 luke 1486
 
70829 ripley 1487
/* clang pre-3.9.0 says
74589 maechler 1488
      warning: passing an object that undergoes default argument promotion to
70829 ripley 1489
      'va_start' has undefined behavior [-Wvarargs]
1490
*/
1839 ihaka 1491
    va_start(ap, which_warn);
79159 kalibera 1492
    Rvsnprintf_mbcs(buf, BUFSIZE, _(WarningDB[i].format), ap);
1839 ihaka 1493
    va_end(ap);
14442 luke 1494
    warningcall(call, "%s", buf);
2 r 1495
}
14570 luke 1496
 
61766 ripley 1497
static void R_SetErrmessage(const char *s)
14570 luke 1498
{
76844 luke 1499
    Rstrncpy(errbuf, s, sizeof(errbuf) - 1);
14570 luke 1500
}
1501
 
61766 ripley 1502
static void R_PrintDeferredWarnings(void)
14570 luke 1503
{
1504
    if( R_ShowErrorMessages && R_CollectWarnings ) {
45446 ripley 1505
	REprintf(_("In addition: "));
1506
	PrintWarnings();
14570 luke 1507
    }
29340 murdoch 1508
}
87647 kalibera 1509
 
1510
/* if srcref indicates it is in bytecode, it needs a fixup */
1511
static SEXP fixBCSrcref(SEXP srcref, RCNTXT *c)
1512
{
1513
    if (srcref == R_InBCInterpreter)
1514
	srcref = R_findBCInterpreterSrcref(c);
1515
    return srcref;
1516
}
1517
 
76872 maechler 1518
/*
1519
 * Return the traceback without deparsing the calls
1520
 */
61766 ripley 1521
attribute_hidden
76872 maechler 1522
SEXP R_GetTracebackOnly(int skip)
14570 luke 1523
{
1524
    int nback = 0, ns;
1525
    RCNTXT *c;
1526
    SEXP s, t;
1527
 
14723 luke 1528
    for (c = R_GlobalContext, ns = skip;
1529
	 c != NULL && c->callflag != CTXT_TOPLEVEL;
1530
	 c = c->nextcontext)
36975 ripley 1531
	if (c->callflag & (CTXT_FUNCTION | CTXT_BUILTIN) ) {
14570 luke 1532
	    if (ns > 0)
1533
		ns--;
1534
	    else
1535
		nback++;
14629 ripley 1536
	}
14570 luke 1537
 
1538
    PROTECT(s = allocList(nback));
1539
    t = s;
14723 luke 1540
    for (c = R_GlobalContext ;
1541
	 c != NULL && c->callflag != CTXT_TOPLEVEL;
1542
	 c = c->nextcontext)
36975 ripley 1543
	if (c->callflag & (CTXT_FUNCTION | CTXT_BUILTIN) ) {
14570 luke 1544
	    if (skip > 0)
1545
		skip--;
1546
	    else {
76872 maechler 1547
		SETCAR(t, duplicate(c->call));
71390 luke 1548
		if (c->srcref && !isNull(c->srcref)) {
1549
		    SEXP sref;
1550
		    if (c->srcref == R_InBCInterpreter)
1551
			sref = R_findBCInterpreterSrcref(c);
1552
		    else
1553
			sref = c->srcref;
1554
		    setAttrib(CAR(t), R_SrcrefSymbol, duplicate(sref));
1555
		}
14570 luke 1556
		t = CDR(t);
1557
	    }
14629 ripley 1558
	}
14570 luke 1559
    UNPROTECT(1);
1560
    return s;
1561
}
76872 maechler 1562
/*
1563
 * Return the traceback with calls deparsed
1564
 */
1565
attribute_hidden
1566
SEXP R_GetTraceback(int skip)
1567
{
1568
    int nback = 0;
1569
    SEXP s, t, u, v;
1570
    s = PROTECT(R_GetTracebackOnly(skip));
1571
    for(t = s; t != R_NilValue; t = CDR(t)) nback++;
1572
    u = v = PROTECT(allocList(nback));
44012 ripley 1573
 
76872 maechler 1574
    for(t = s; t != R_NilValue; t = CDR(t), v=CDR(v)) {
79305 maechler 1575
	SEXP sref = getAttrib(CAR(t), R_SrcrefSymbol);
1576
	SEXP dep = PROTECT(deparse1m(CAR(t), 0, DEFAULTDEPARSE));
1577
	if (!isNull(sref))
1578
	    setAttrib(dep, R_SrcrefSymbol, duplicate(sref));
1579
	SETCAR(v, dep);
1580
	UNPROTECT(1);
76872 maechler 1581
    }
1582
    UNPROTECT(2);
1583
    return u;
1584
}
1585
 
83446 ripley 1586
attribute_hidden SEXP do_traceback(SEXP call, SEXP op, SEXP args, SEXP rho)
58045 murdoch 1587
{
1588
    int skip;
70047 ripley 1589
 
58045 murdoch 1590
    checkArity(op, args);
1591
    skip = asInteger(CAR(args));
70047 ripley 1592
 
58045 murdoch 1593
    if (skip == NA_INTEGER || skip < 0 )
70047 ripley 1594
	error(_("invalid '%s' value"), "skip");
1595
 
58045 murdoch 1596
    return R_GetTraceback(skip);
1597
}
1598
 
41712 ripley 1599
static char * R_ConciseTraceback(SEXP call, int skip)
1600
{
41944 ripley 1601
    static char buf[560];
41712 ripley 1602
    RCNTXT *c;
59173 ripley 1603
    size_t nl;
1604
    int ncalls = 0;
41712 ripley 1605
    Rboolean too_many = FALSE;
41807 rgentlem 1606
    const char *top = "" /* -Wall */;
41712 ripley 1607
 
1608
    buf[0] = '\0';
1609
    for (c = R_GlobalContext;
1610
	 c != NULL && c->callflag != CTXT_TOPLEVEL;
1611
	 c = c->nextcontext)
1612
	if (c->callflag & (CTXT_FUNCTION | CTXT_BUILTIN) ) {
1613
	    if (skip > 0)
1614
		skip--;
1615
	    else {
1616
		SEXP fun = CAR(c->call);
41807 rgentlem 1617
		const char *this = (TYPEOF(fun) == SYMSXP) ?
41712 ripley 1618
		    CHAR(PRINTNAME(fun)) : "<Anonymous>";
45446 ripley 1619
		if(streql(this, "stop") ||
1620
		   streql(this, "warning") ||
1621
		   streql(this, "suppressWarnings") ||
41712 ripley 1622
		   streql(this, ".signalSimpleWarning")) {
1623
		    buf[0] =  '\0'; ncalls = 0; too_many = FALSE;
1624
		} else {
1625
		    ncalls++;
1626
		    if(too_many) {
1627
			top = this;
41944 ripley 1628
		    } else if(strlen(buf) > R_NShowCalls) {
41712 ripley 1629
			memmove(buf+4, buf, strlen(buf)+1);
1630
			memcpy(buf, "... ", 4);
1631
			too_many = TRUE;
1632
			top = this;
1633
		    } else if(strlen(buf)) {
1634
			nl = strlen(this);
1635
			memmove(buf+nl+4, buf, strlen(buf)+1);
1636
			memcpy(buf, this, strlen(this));
1637
			memcpy(buf+nl, " -> ", 4);
1638
		    } else
1639
			memcpy(buf, this, strlen(this)+1);
1640
		}
1641
	    }
1642
	}
1643
    if(too_many && (nl = strlen(top)) < 50) {
1644
	memmove(buf+nl+1, buf, strlen(buf)+1);
1645
	memcpy(buf, top, strlen(top));
1646
	memcpy(buf+nl, " ", 1);
1647
    }
1648
    /* don't add Calls if it adds no extra information */
1649
    /* However: do we want to include the call in the list if it is a
1650
       primitive? */
59477 murdoch 1651
    if (ncalls == 1 && TYPEOF(call) == LANGSXP) {
41712 ripley 1652
	SEXP fun = CAR(call);
41807 rgentlem 1653
	const char *this = (TYPEOF(fun) == SYMSXP) ?
41712 ripley 1654
	    CHAR(PRINTNAME(fun)) : "<Anonymous>";
1655
	if(streql(buf, this)) return "";
1656
    }
1657
    return buf;
1658
}
1659
 
1660
 
1661
 
39866 duncan 1662
static SEXP mkHandlerEntry(SEXP klass, SEXP parentenv, SEXP handler, SEXP rho,
25523 luke 1663
			   SEXP result, int calling)
1664
{
1665
    SEXP entry = allocVector(VECSXP, 5);
39866 duncan 1666
    SET_VECTOR_ELT(entry, 0, klass);
25523 luke 1667
    SET_VECTOR_ELT(entry, 1, parentenv);
1668
    SET_VECTOR_ELT(entry, 2, handler);
1669
    SET_VECTOR_ELT(entry, 3, rho);
1670
    SET_VECTOR_ELT(entry, 4, result);
1671
    SETLEVELS(entry, calling);
1672
    return entry;
1673
}
1674
 
1675
/**** rename these??*/
1676
#define IS_CALLING_ENTRY(e) LEVELS(e)
1677
#define ENTRY_CLASS(e) VECTOR_ELT(e, 0)
1678
#define ENTRY_CALLING_ENVIR(e) VECTOR_ELT(e, 1)
1679
#define ENTRY_HANDLER(e) VECTOR_ELT(e, 2)
1680
#define ENTRY_TARGET_ENVIR(e) VECTOR_ELT(e, 3)
1681
#define ENTRY_RETURN_RESULT(e) VECTOR_ELT(e, 4)
79542 luke 1682
#define CLEAR_ENTRY_CALLING_ENVIR(e) SET_VECTOR_ELT(e, 1, R_NilValue)
1683
#define CLEAR_ENTRY_TARGET_ENVIR(e) SET_VECTOR_ELT(e, 3, R_NilValue)
25523 luke 1684
 
83446 ripley 1685
attribute_hidden SEXP R_UnwindHandlerStack(SEXP target)
79542 luke 1686
{
79543 luke 1687
    SEXP hs;
1688
 
1689
    /* check that the target is in the current stack */
1690
    for (hs = R_HandlerStack; hs != target && hs != R_NilValue; hs = CDR(hs))
1691
	if (hs == target)
1692
	    break;
1693
    if (hs != target)
1694
	return target; /* restoring a saved stack */
1695
 
1696
    for (hs = R_HandlerStack; hs != target; hs = CDR(hs)) {
79542 luke 1697
	/* pop top handler; may not be needed */
1698
	R_HandlerStack = CDR(hs);
1699
 
1700
	/* clear the two environments to reduce reference counts */
1701
	CLEAR_ENTRY_CALLING_ENVIR(CAR(hs));
1702
	CLEAR_ENTRY_TARGET_ENVIR(CAR(hs));
1703
    }
1704
    return target;
1705
}
1706
 
73853 luke 1707
#define RESULT_SIZE 4
25523 luke 1708
 
73853 luke 1709
static SEXP R_HandlerResultToken = NULL;
1710
 
83446 ripley 1711
attribute_hidden void R_FixupExitingHandlerResult(SEXP result)
73853 luke 1712
{
73867 luke 1713
    /* The internal error handling mechanism stores the error message
73853 luke 1714
       in 'errbuf'.  If an on.exit() action is processed while jumping
1715
       to an exiting handler for such an error, then endcontext()
73867 luke 1716
       calls R_FixupExitingHandlerResult to save the error message
73853 luke 1717
       currently in the buffer before processing the on.exit
1718
       action. This is in case an error occurs in the on.exit action
1719
       that over-writes the buffer. The allocation should occur in a
1720
       more favorable stack context than before the jump. The
1721
       R_HandlerResultToken is used to make sure the result being
1722
       modified is associated with jumping to an exiting handler. */
1723
    if (result != NULL &&
1724
	TYPEOF(result) == VECSXP &&
1725
	XLENGTH(result) == RESULT_SIZE &&
73867 luke 1726
	VECTOR_ELT(result, 0) == R_NilValue &&
73853 luke 1727
	VECTOR_ELT(result, RESULT_SIZE - 1) == R_HandlerResultToken) {
1728
	SET_VECTOR_ELT(result, 0, mkString(errbuf));
1729
    }
1730
}
1731
 
83446 ripley 1732
attribute_hidden SEXP do_addCondHands(SEXP call, SEXP op, SEXP args, SEXP rho)
25523 luke 1733
{
1734
    SEXP classes, handlers, parentenv, target, oldstack, newstack, result;
1735
    int calling, i, n;
1736
    PROTECT_INDEX osi;
1737
 
73853 luke 1738
    if (R_HandlerResultToken == NULL) {
1739
	R_HandlerResultToken = allocVector(VECSXP, 1);
1740
	R_PreserveObject(R_HandlerResultToken);
1741
    }
1742
 
25523 luke 1743
    checkArity(op, args);
1744
 
1745
    classes = CAR(args); args = CDR(args);
1746
    handlers = CAR(args); args = CDR(args);
1747
    parentenv = CAR(args); args = CDR(args);
1748
    target = CAR(args); args = CDR(args);
1749
    calling = asLogical(CAR(args));
1750
 
1751
    if (classes == R_NilValue || handlers == R_NilValue)
1752
	return R_HandlerStack;
1753
 
1754
    if (TYPEOF(classes) != STRSXP || TYPEOF(handlers) != VECSXP ||
1755
	LENGTH(classes) != LENGTH(handlers))
32858 ripley 1756
	error(_("bad handler data"));
25523 luke 1757
 
1758
    n = LENGTH(handlers);
1759
    oldstack = R_HandlerStack;
1760
 
1761
    PROTECT(result = allocVector(VECSXP, RESULT_SIZE));
73853 luke 1762
    SET_VECTOR_ELT(result, RESULT_SIZE - 1, R_HandlerResultToken);
25523 luke 1763
    PROTECT_WITH_INDEX(newstack = oldstack, &osi);
1764
 
1765
    for (i = n - 1; i >= 0; i--) {
39866 duncan 1766
	SEXP klass = STRING_ELT(classes, i);
25523 luke 1767
	SEXP handler = VECTOR_ELT(handlers, i);
39866 duncan 1768
	SEXP entry = mkHandlerEntry(klass, parentenv, handler, target, result,
25523 luke 1769
				    calling);
1770
	REPROTECT(newstack = CONS(entry, newstack), osi);
1771
    }
1772
 
1773
    R_HandlerStack = newstack;
1774
    UNPROTECT(2);
1775
 
1776
    return oldstack;
1777
}
1778
 
83446 ripley 1779
attribute_hidden SEXP do_resetCondHands(SEXP call, SEXP op, SEXP args, SEXP rho)
25523 luke 1780
{
1781
    checkArity(op, args);
1782
    R_HandlerStack = CAR(args);
1783
    return R_NilValue;
1784
}
1785
 
44198 ripley 1786
static SEXP findSimpleErrorHandler(void)
25523 luke 1787
{
1788
    SEXP list;
1789
    for (list = R_HandlerStack; list != R_NilValue; list = CDR(list)) {
1790
	SEXP entry = CAR(list);
25526 luke 1791
	if (! strcmp(CHAR(ENTRY_CLASS(entry)), "simpleError") ||
1792
	    ! strcmp(CHAR(ENTRY_CLASS(entry)), "error") ||
25523 luke 1793
	    ! strcmp(CHAR(ENTRY_CLASS(entry)), "condition"))
1794
	    return list;
1795
    }
1796
    return R_NilValue;
1797
}
1798
 
1799
static void vsignalWarning(SEXP call, const char *format, va_list ap)
1800
{
1801
    char buf[BUFSIZE];
75529 kalibera 1802
    SEXP hooksym, hcall, qcall, qfun;
25523 luke 1803
 
1804
    hooksym = install(".signalSimpleWarning");
1805
    if (SYMVALUE(hooksym) != R_UnboundValue &&
48349 maechler 1806
	SYMVALUE(R_QuoteSymbol) != R_UnboundValue) {
75529 kalibera 1807
	qfun = lang3(R_DoubleColonSymbol, R_BaseSymbol, R_QuoteSymbol);
1808
	PROTECT(qfun);
1809
	PROTECT(qcall = LCONS(qfun, LCONS(call, R_NilValue)));
25523 luke 1810
	PROTECT(hcall = LCONS(qcall, R_NilValue));
79159 kalibera 1811
	Rvsnprintf_mbcs(buf, BUFSIZE - 1, format, ap);
48811 maechler 1812
	hcall = LCONS(mkString(buf), hcall);
25523 luke 1813
	PROTECT(hcall = LCONS(hooksym, hcall));
88719 kalibera 1814
	evalKeepVis(hcall, R_BaseEnv);
75529 kalibera 1815
	UNPROTECT(4);
25523 luke 1816
    }
1817
    else vwarningcall_dflt(call, format, ap);
1818
}
1819
 
83452 ripley 1820
NORET static void gotoExitingHandler(SEXP cond, SEXP call, SEXP entry)
25523 luke 1821
{
1822
    SEXP rho = ENTRY_TARGET_ENVIR(entry);
1823
    SEXP result = ENTRY_RETURN_RESULT(entry);
1824
    SET_VECTOR_ELT(result, 0, cond);
1825
    SET_VECTOR_ELT(result, 1, call);
1826
    SET_VECTOR_ELT(result, 2, ENTRY_HANDLER(entry));
1827
    findcontext(CTXT_FUNCTION, rho, result);
1828
}
1829
 
25526 luke 1830
static void vsignalError(SEXP call, const char *format, va_list ap)
25523 luke 1831
{
81111 luke 1832
    /* This function does not protect or restore the old handler
1833
       stack. On return R_HandlerStack will be R_NilValue (unless
1834
       R_RestartToken is encountered). */
41928 luke 1835
    char localbuf[BUFSIZE];
81111 luke 1836
    SEXP list;
25523 luke 1837
 
79159 kalibera 1838
    Rvsnprintf_mbcs(localbuf, BUFSIZE - 1, format, ap);
25526 luke 1839
    while ((list = findSimpleErrorHandler()) != R_NilValue) {
25523 luke 1840
	char *buf = errbuf;
1841
	SEXP entry = CAR(list);
1842
	R_HandlerStack = CDR(list);
75601 kalibera 1843
	Rstrncpy(buf, localbuf, BUFSIZE);
41928 luke 1844
	/*	Rvsnprintf(buf, BUFSIZE - 1, format, ap);*/
25523 luke 1845
	if (IS_CALLING_ENTRY(entry)) {
78125 kalibera 1846
	    if (ENTRY_HANDLER(entry) == R_RestartToken) {
1847
		UNPROTECT(1); /* oldstack */
81111 luke 1848
		break; /* go to default error handling */
78125 kalibera 1849
	    } else {
70315 luke 1850
		/* if we are in the process of handling a C stack
74860 kalibera 1851
		   overflow, treat all calling handlers as failed */
70315 luke 1852
		if (R_OldCStackLimit)
81058 luke 1853
		    continue;
75529 kalibera 1854
		SEXP hooksym, hcall, qcall, qfun;
81111 luke 1855
		PROTECT(entry); /* protect since no longer on the stack */
25526 luke 1856
		hooksym = install(".handleSimpleError");
75529 kalibera 1857
		qfun = lang3(R_DoubleColonSymbol, R_BaseSymbol,
1858
		             R_QuoteSymbol);
78125 kalibera 1859
		PROTECT(qfun);
75529 kalibera 1860
		PROTECT(qcall = LCONS(qfun,
48349 maechler 1861
				      LCONS(call, R_NilValue)));
25523 luke 1862
		PROTECT(hcall = LCONS(qcall, R_NilValue));
48811 maechler 1863
		hcall = LCONS(mkString(buf), hcall);
25523 luke 1864
		hcall = LCONS(ENTRY_HANDLER(entry), hcall);
1865
		PROTECT(hcall = LCONS(hooksym, hcall));
88719 kalibera 1866
		eval(hcall, R_BaseEnv);
75529 kalibera 1867
		UNPROTECT(5);
25523 luke 1868
	    }
1869
	}
1870
	else gotoExitingHandler(R_NilValue, call, entry);
1871
    }
1872
}
1873
 
1874
static SEXP findConditionHandler(SEXP cond)
1875
{
1876
    int i;
1877
    SEXP list;
1878
    SEXP classes = getAttrib(cond, R_ClassSymbol);
1879
 
1880
    if (TYPEOF(classes) != STRSXP)
1881
	return R_NilValue;
29340 murdoch 1882
 
25526 luke 1883
    /**** need some changes here to allow conditions to be S4 classes */
25523 luke 1884
    for (list = R_HandlerStack; list != R_NilValue; list = CDR(list)) {
1885
	SEXP entry = CAR(list);
1886
	for (i = 0; i < LENGTH(classes); i++)
1887
	    if (! strcmp(CHAR(ENTRY_CLASS(entry)),
1888
			 CHAR(STRING_ELT(classes, i))))
1889
		return list;
1890
    }
1891
    return R_NilValue;
1892
}
1893
 
83446 ripley 1894
attribute_hidden SEXP do_signalCondition(SEXP call, SEXP op, SEXP args, SEXP rho)
25523 luke 1895
{
26352 luke 1896
    SEXP list, cond, msg, ecall, oldstack;
25523 luke 1897
 
1898
    checkArity(op, args);
1899
 
1900
    cond = CAR(args);
1901
    msg = CADR(args);
1902
    ecall = CADDR(args);
1903
 
26352 luke 1904
    PROTECT(oldstack = R_HandlerStack);
25523 luke 1905
    while ((list = findConditionHandler(cond)) != R_NilValue) {
1906
	SEXP entry = CAR(list);
1907
	R_HandlerStack = CDR(list);
1908
	if (IS_CALLING_ENTRY(entry)) {
1909
	    SEXP h = ENTRY_HANDLER(entry);
1910
	    if (h == R_RestartToken) {
41784 ripley 1911
		const char *msgstr = NULL;
25523 luke 1912
		if (TYPEOF(msg) == STRSXP && LENGTH(msg) > 0)
40705 ripley 1913
		    msgstr = translateChar(STRING_ELT(msg, 0));
32858 ripley 1914
		else error(_("error message not a string"));
25523 luke 1915
		errorcall_dflt(ecall, "%s", msgstr);
1916
	    }
1917
	    else {
1918
		SEXP hcall = LCONS(h, LCONS(cond, R_NilValue));
1919
		PROTECT(hcall);
1920
		eval(hcall, R_GlobalEnv);
1921
		UNPROTECT(1);
1922
	    }
1923
	}
26353 luke 1924
	else gotoExitingHandler(cond, ecall, entry);
25523 luke 1925
    }
26352 luke 1926
    R_HandlerStack = oldstack;
1927
    UNPROTECT(1);
25523 luke 1928
    return R_NilValue;
1929
}
1930
 
44198 ripley 1931
static SEXP findInterruptHandler(void)
26354 luke 1932
{
1933
    SEXP list;
1934
    for (list = R_HandlerStack; list != R_NilValue; list = CDR(list)) {
1935
	SEXP entry = CAR(list);
1936
	if (! strcmp(CHAR(ENTRY_CLASS(entry)), "interrupt") ||
1937
	    ! strcmp(CHAR(ENTRY_CLASS(entry)), "condition"))
1938
	    return list;
1939
    }
1940
    return R_NilValue;
1941
}
1942
 
44198 ripley 1943
static SEXP getInterruptCondition(void)
26354 luke 1944
{
1945
    /**** FIXME: should probably pre-allocate this */
39866 duncan 1946
    SEXP cond, klass;
26354 luke 1947
    PROTECT(cond = allocVector(VECSXP, 0));
39866 duncan 1948
    PROTECT(klass = allocVector(STRSXP, 2));
1949
    SET_STRING_ELT(klass, 0, mkChar("interrupt"));
1950
    SET_STRING_ELT(klass, 1, mkChar("condition"));
40909 ripley 1951
    classgets(cond, klass);
26354 luke 1952
    UNPROTECT(2);
1953
    return cond;
1954
}
1955
 
1956
static void signalInterrupt(void)
1957
{
1958
    SEXP list, cond, oldstack;
1959
 
1960
    PROTECT(oldstack = R_HandlerStack);
1961
    while ((list = findInterruptHandler()) != R_NilValue) {
1962
	SEXP entry = CAR(list);
1963
	R_HandlerStack = CDR(list);
1964
	PROTECT(cond = getInterruptCondition());
1965
	if (IS_CALLING_ENTRY(entry)) {
1966
	    SEXP h = ENTRY_HANDLER(entry);
1967
	    SEXP hcall = LCONS(h, LCONS(cond, R_NilValue));
1968
	    PROTECT(hcall);
78071 luke 1969
	    evalKeepVis(hcall, R_GlobalEnv);
26354 luke 1970
	    UNPROTECT(1);
1971
	}
1972
	else gotoExitingHandler(cond, R_NilValue, entry);
1973
	UNPROTECT(1);
1974
    }
1975
    R_HandlerStack = oldstack;
1976
    UNPROTECT(1);
70850 luke 1977
 
1978
    SEXP h = GetOption1(install("interrupt"));
1979
    if (h != R_NilValue) {
1980
	SEXP call = PROTECT(LCONS(h, R_NilValue));
78071 luke 1981
	evalKeepVis(call, R_GlobalEnv);
78125 kalibera 1982
	UNPROTECT(1);
70850 luke 1983
    }
26354 luke 1984
}
1985
 
85087 luke 1986
 
1987
static void checkRestartStacks(RCNTXT *cptr)
25523 luke 1988
{
1989
    if ((cptr->handlerstack != R_HandlerStack ||
63292 luke 1990
	 cptr->restartstack != R_RestartStack)) {
25523 luke 1991
	if (IS_RESTART_BIT_SET(cptr->callflag))
1992
	    return;
1993
	else
32858 ripley 1994
	    error(_("handler or restart stack mismatch in old restart"));
25523 luke 1995
    }
85087 luke 1996
}
25523 luke 1997
 
85087 luke 1998
static void addInternalRestart(RCNTXT *cptr, const char *cname)
1999
{
2000
    checkRestartStacks(cptr);
2001
    SEXP entry, name;
2002
 
70852 luke 2003
    PROTECT(name = mkString(cname));
35163 tlumley 2004
    PROTECT(entry = allocVector(VECSXP, 2));
67013 luke 2005
    SET_VECTOR_ELT(entry, 0, name);
25523 luke 2006
    SET_VECTOR_ELT(entry, 1, R_MakeExternalPtr(cptr, R_NilValue, R_NilValue));
48811 maechler 2007
    setAttrib(entry, R_ClassSymbol, mkString("restart"));
25523 luke 2008
    R_RestartStack = CONS(entry, R_RestartStack);
67013 luke 2009
    UNPROTECT(2);
25523 luke 2010
}
2011
 
85087 luke 2012
attribute_hidden void
2013
R_InsertRestartHandlers(RCNTXT *cptr, const char *cname)
2014
{
2015
    SEXP klass, rho, entry;
2016
 
2017
    checkRestartStacks(cptr);
2018
 
2019
    /**** need more here to keep recursive errors in browser? */
85088 luke 2020
    SEXP h = GetOption1(install("browser.error.handler"));
2021
    if (! isFunction(h)) h = R_RestartToken;
85087 luke 2022
    rho = cptr->cloenv;
2023
    PROTECT(klass = mkChar("error"));
85088 luke 2024
    entry = mkHandlerEntry(klass, rho, h, rho, R_NilValue, TRUE);
85087 luke 2025
    R_HandlerStack = CONS(entry, R_HandlerStack);
2026
    UNPROTECT(1);
2027
 
2028
    addInternalRestart(cptr, cname);
2029
}
2030
 
83446 ripley 2031
attribute_hidden SEXP do_dfltWarn(SEXP call, SEXP op, SEXP args, SEXP rho)
25523 luke 2032
{
2033
    checkArity(op, args);
2034
 
2035
    if (TYPEOF(CAR(args)) != STRSXP || LENGTH(CAR(args)) != 1)
32858 ripley 2036
	error(_("bad error message"));
79942 maechler 2037
    const char *msg = translateChar(STRING_ELT(CAR(args), 0));
2038
    SEXP ecall = CADR(args);
25523 luke 2039
 
2040
    warningcall_dflt(ecall, "%s", msg);
2041
    return R_NilValue;
2042
}
2043
 
87740 ripley 2044
NORET attribute_hidden SEXP do_dfltStop(SEXP call, SEXP op, SEXP args, SEXP rho)
25523 luke 2045
{
2046
    checkArity(op, args);
2047
 
2048
    if (TYPEOF(CAR(args)) != STRSXP || LENGTH(CAR(args)) != 1)
32858 ripley 2049
	error(_("bad error message"));
79942 maechler 2050
    const char *msg = translateChar(STRING_ELT(CAR(args), 0));
2051
    SEXP ecall = CADR(args);
25523 luke 2052
 
2053
    errorcall_dflt(ecall, "%s", msg);
2054
}
2055
 
2056
 
2057
/*
2058
 * Restart Handling
2059
 */
2060
 
83446 ripley 2061
attribute_hidden SEXP do_getRestart(SEXP call, SEXP op, SEXP args, SEXP rho)
25523 luke 2062
{
2063
    int i;
2064
    SEXP list;
2065
    checkArity(op, args);
2066
    i = asInteger(CAR(args));
2067
    for (list = R_RestartStack;
2068
	 list != R_NilValue && i > 1;
2069
	 list = CDR(list), i--);
2070
    if (list != R_NilValue)
2071
	return CAR(list);
2072
    else if (i == 1) {
2073
	/**** need to pre-allocate */
2074
	SEXP name, entry;
48811 maechler 2075
	PROTECT(name = mkString("abort"));
67351 luke 2076
	PROTECT(entry = allocVector(VECSXP, 2));
25523 luke 2077
	SET_VECTOR_ELT(entry, 0, name);
2078
	SET_VECTOR_ELT(entry, 1, R_NilValue);
48811 maechler 2079
	setAttrib(entry, R_ClassSymbol, mkString("restart"));
67351 luke 2080
	UNPROTECT(2);
25523 luke 2081
	return entry;
2082
    }
2083
    else return R_NilValue;
2084
}
2085
 
2086
/* very minimal error checking --just enough to avoid a segfault */
2087
#define CHECK_RESTART(r) do { \
2088
    SEXP __r__ = (r); \
2089
    if (TYPEOF(__r__) != VECSXP || LENGTH(__r__) < 2) \
32858 ripley 2090
	error(_("bad restart")); \
25523 luke 2091
} while (0)
2092
 
83446 ripley 2093
attribute_hidden SEXP do_addRestart(SEXP call, SEXP op, SEXP args, SEXP rho)
25523 luke 2094
{
2095
    checkArity(op, args);
2096
    CHECK_RESTART(CAR(args));
2097
    R_RestartStack = CONS(CAR(args), R_RestartStack);
2098
    return R_NilValue;
2099
}
2100
 
2101
#define RESTART_EXIT(r) VECTOR_ELT(r, 1)
2102
 
83452 ripley 2103
NORET static void invokeRestart(SEXP r, SEXP arglist)
25523 luke 2104
{
2105
    SEXP exit = RESTART_EXIT(r);
2106
 
2107
    if (exit == R_NilValue) {
2108
	R_RestartStack = R_NilValue;
2109
	jump_to_toplevel();
2110
    }
2111
    else {
2112
	for (; R_RestartStack != R_NilValue;
2113
	     R_RestartStack = CDR(R_RestartStack))
2114
	    if (exit == RESTART_EXIT(CAR(R_RestartStack))) {
2115
		R_RestartStack = CDR(R_RestartStack);
2116
		if (TYPEOF(exit) == EXTPTRSXP) {
39866 duncan 2117
		    RCNTXT *c = (RCNTXT *) R_ExternalPtrAddr(exit);
25523 luke 2118
		    R_JumpToContext(c, CTXT_RESTART, R_RestartToken);
2119
		}
2120
		else findcontext(CTXT_FUNCTION, exit, arglist);
2121
	    }
32858 ripley 2122
	error(_("restart not on stack"));
25523 luke 2123
    }
2124
}
2125
 
87740 ripley 2126
NORET attribute_hidden 
83452 ripley 2127
SEXP do_invokeRestart(SEXP call, SEXP op, SEXP args, SEXP rho)
25523 luke 2128
{
2129
    checkArity(op, args);
2130
    CHECK_RESTART(CAR(args));
2131
    invokeRestart(CAR(args), CADR(args));
2132
}
2133
 
83446 ripley 2134
attribute_hidden SEXP do_addTryHandlers(SEXP call, SEXP op, SEXP args, SEXP rho)
25517 luke 2135
{
2136
    checkArity(op, args);
2137
    if (R_GlobalContext == R_ToplevelContext ||
47908 luke 2138
	! (R_GlobalContext->callflag & CTXT_FUNCTION))
70830 luke 2139
	error(_("not in a try context"));
25517 luke 2140
    SET_RESTART_BIT_ON(R_GlobalContext->callflag);
70852 luke 2141
    R_InsertRestartHandlers(R_GlobalContext, "tryRestart");
25517 luke 2142
    return R_NilValue;
2143
}
40798 luke 2144
 
83446 ripley 2145
attribute_hidden SEXP do_seterrmessage(SEXP call, SEXP op, SEXP args, SEXP env)
40798 luke 2146
{
2147
    SEXP msg;
2148
 
2149
    checkArity(op, args);
2150
    msg = CAR(args);
2151
    if(!isString(msg) || LENGTH(msg) != 1)
2152
	error(_("error message must be a character string"));
2153
    R_SetErrmessage(CHAR(STRING_ELT(msg, 0)));
2154
    return R_NilValue;
2155
}
40799 luke 2156
 
83446 ripley 2157
attribute_hidden SEXP
40799 luke 2158
do_printDeferredWarnings(SEXP call, SEXP op, SEXP args, SEXP env)
2159
{
2160
    checkArity(op, args);
2161
    R_PrintDeferredWarnings();
2162
    return R_NilValue;
2163
}
46580 luke 2164
 
83446 ripley 2165
attribute_hidden SEXP
46580 luke 2166
do_interruptsSuspended(SEXP call, SEXP op, SEXP args, SEXP env)
2167
{
87815 ripley 2168
    Rboolean orig_value = R_interrupts_suspended;
48349 maechler 2169
    if (args != R_NilValue)
87815 ripley 2170
	R_interrupts_suspended = asRbool(CAR(args), call);
46580 luke 2171
    return ScalarLogical(orig_value);
2172
}
48349 maechler 2173
 
82445 ripley 2174
#if 0
83446 ripley 2175
attribute_hidden void
75446 kalibera 2176
R_BadValueInRCode(SEXP value, SEXP call, SEXP rho, const char *rawmsg,
2177
                  const char *errmsg, const char *warnmsg,
82265 ripley 2178
                  const char *varname, Rboolean errByDefault)
75446 kalibera 2179
{
75533 kalibera 2180
    /* disable GC so that use of this temporary checking code does not
2181
       introduce new PROTECT errors e.g. in asLogical() use */
75618 luke 2182
    R_CHECK_THREAD;
75533 kalibera 2183
    int enabled = R_GCEnabled;
2184
    R_GCEnabled = FALSE;
75532 kalibera 2185
    int nprotect = 0;
75446 kalibera 2186
    char *check = getenv(varname);
2187
    const void *vmax = vmaxget();
2188
    Rboolean err = check && StringTrue(check);
2189
    if (!err && check && StringFalse(check))
2190
	check = NULL; /* disabled */
2191
    Rboolean abort = FALSE; /* R_Suicide/abort */
2192
    Rboolean verbose = FALSE;
2193
    Rboolean warn = FALSE;
2194
    const char *pkgname = 0;
2195
    if (!err && check) {
2196
	const char *pprefix = "package:";
2197
	const char *aprefix = "abort";
2198
	const char *vprefix = "verbose";
2199
	const char *wprefix = "warn";
2200
	const char *cpname = "_R_CHECK_PACKAGE_NAME_";
2201
	size_t lpprefix = strlen(pprefix);
2202
	size_t laprefix = strlen(aprefix);
2203
	size_t lvprefix = strlen(vprefix);
2204
	size_t lwprefix = strlen(wprefix);
2205
	size_t lcpname = strlen(cpname);
2206
	Rboolean ignore = FALSE;
2207
 
2208
	SEXP spkg = R_NilValue;
75532 kalibera 2209
	for(; rho != R_EmptyEnv; rho = ENCLOS(rho))
2210
	    if (R_IsPackageEnv(rho)) {
2211
		PROTECT(spkg = R_PackageEnvName(rho));
2212
		nprotect++;
2213
		break;
2214
	    } else if (R_IsNamespaceEnv(rho)) {
2215
		PROTECT(spkg = R_NamespaceEnvSpec(rho));
2216
		nprotect++;
2217
		break;
2218
	    }
75446 kalibera 2219
	if (spkg != R_NilValue)
2220
	    pkgname = translateChar(STRING_ELT(spkg, 0));
81758 ripley 2221
	/* Sometimes pkgname is like 
2222
	      package:MoTBFs,
81759 ripley 2223
	   so we need tp strip it off.
2224
	   This is independent of pprefix.
2225
	*/
81758 ripley 2226
	if (strstr(pkgname, "package:"))  pkgname += 8;
75446 kalibera 2227
 
2228
	while (check[0] != '\0') {
2229
	    if (!strncmp(pprefix, check, lpprefix)) {
2230
		/* check starts with "package:" */
2231
		check += lpprefix;
2232
		size_t arglen = 0;
2233
		const char *sep = strchr(check, ',');
2234
		if (sep)
2235
		    arglen = sep - check;
2236
		else
2237
		    arglen = strlen(check);
2238
		ignore = TRUE;
2239
		if (pkgname) {
81759 ripley 2240
		    // a named package
75446 kalibera 2241
		    if (!strncmp(check, pkgname, arglen) && strlen(pkgname) == arglen)
2242
			ignore = FALSE;
81759 ripley 2243
		    // 'this package' 
2244
		    else if (!strncmp(check, cpname, arglen) && lcpname == arglen) {
75446 kalibera 2245
			/* package name specified in _R_CHECK_PACKAGE_NAME */
2246
			const char *envpname = getenv(cpname);
2247
			if (envpname && !strcmp(envpname, pkgname))
2248
			    ignore = FALSE;
2249
		    }
81759 ripley 2250
		    // "all_base" , that is all standard packages.
2251
		    else if (!strncmp(check, "all_base", arglen) && arglen == 8) {
2252
			char *std[] = {
2253
			    "base",
2254
			    "compiler",
2255
			    // datasets has no code
2256
			    "grDevies",
2257
			    "graphics",
2258
			    "grid",
2259
			    "methods",
2260
			    "parallel",
2261
			    "splines",
2262
			    "stats",
2263
			    "stats4",
2264
			    "utils",
2265
			    "tools"
2266
			};
2267
			int nstd = sizeof(std)/sizeof(char *);
2268
			for (int i = 0; i < nstd; i++)
2269
			    if(!strcmp(std[i], pkgname)) {
2270
				ignore = FALSE;
2271
				break;
2272
			    }
2273
		    }
75446 kalibera 2274
		}
2275
		check += arglen;
2276
	    } else if (!strncmp(aprefix, check, laprefix)) {
2277
		/* check starts with "abort" */
2278
		check += laprefix;
2279
		abort = TRUE;
2280
	    } else if (!strncmp(vprefix, check, lvprefix)) {
2281
		/* check starts with "verbose" */
2282
		check += lvprefix;
2283
		verbose = TRUE;
2284
	    } else if (!strncmp(wprefix, check, lwprefix)) {
2285
		/* check starts with "warn" */
2286
		check += lwprefix;
2287
		warn = TRUE;
2288
	    } else if (check[0] == ',') {
2289
		check++;
2290
	    } else
2291
		error("invalid value of %s", varname);
81758 ripley 2292
	} // end of while (check[0] != '\0')
2293
 
75446 kalibera 2294
	if (ignore) {
2295
	    abort = FALSE; /* err is FALSE */
2296
	    verbose = FALSE;
2297
	    warn = FALSE;
2298
	} else if (!abort && !warn)
2299
	    err = TRUE;
2300
    }
2301
    if (verbose) {
2302
	int oldout = R_OutputCon;
2303
	R_OutputCon = 2;
2304
	int olderr = R_ErrorCon;
2305
	R_ErrorCon = 2;
2306
	REprintf(" ----------- FAILURE REPORT -------------- \n");
2307
	REprintf(" --- failure: %s ---\n", rawmsg);
2308
	REprintf(" --- srcref --- \n");
2309
	SrcrefPrompt("", R_getCurrentSrcref());
2310
	REprintf("\n");
2311
	if (pkgname) {
2312
	    REprintf(" --- package (from environment) --- \n");
2313
	    REprintf("%s\n", pkgname);
2314
	}
2315
	REprintf(" --- call from context --- \n");
2316
	PrintValue(R_GlobalContext->call);
2317
	REprintf(" --- call from argument --- \n");
2318
	PrintValue(call);
2319
	REprintf(" --- R stacktrace ---\n");
2320
	printwhere();
2321
	REprintf(" --- value of length: %d type: %s ---\n",
85146 luke 2322
		 length(value), R_typeToChar(value));
75446 kalibera 2323
	PrintValue(value);
2324
	REprintf(" --- function from context --- \n");
2325
	if (R_GlobalContext->callfun != NULL &&
2326
	    TYPEOF(R_GlobalContext->callfun) == CLOSXP)
2327
	    PrintValue(R_GlobalContext->callfun);
2328
	REprintf(" --- function search by body ---\n");
2329
	if (R_GlobalContext->callfun != NULL &&
2330
	    TYPEOF(R_GlobalContext->callfun) == CLOSXP)
2331
	    findFunctionForBody(R_ClosureExpr(R_GlobalContext->callfun));
2332
	REprintf(" ----------- END OF FAILURE REPORT -------------- \n");
2333
	R_OutputCon = oldout;
2334
	R_ErrorCon = olderr;
2335
    }
2336
    if (abort)
2337
	R_Suicide(rawmsg);
82265 ripley 2338
    else if (warn)
2339
	warningcall(call, warnmsg);
2340
    else if (err || errByDefault)
75446 kalibera 2341
	errorcall(call, errmsg);
2342
    vmaxset(vmax);
75532 kalibera 2343
    UNPROTECT(nprotect);
75533 kalibera 2344
    R_GCEnabled = enabled;
75446 kalibera 2345
}
82445 ripley 2346
#endif
75446 kalibera 2347
 
70047 ripley 2348
/* These functions are to be used in error messages, and available for others to use in the API
59375 murdoch 2349
   GetCurrentSrcref returns the first non-NULL srcref after skipping skip of them.  If it
2350
   doesn't find one it returns NULL. */
48349 maechler 2351
 
59375 murdoch 2352
SEXP
2353
R_GetCurrentSrcref(int skip)
2354
{
2355
    RCNTXT *c = R_GlobalContext;
87691 kalibera 2356
    SEXP srcref = NULL;
87647 kalibera 2357
    int keep_looking = skip == NA_INTEGER;
2358
    if (keep_looking) skip = 0;
59413 murdoch 2359
    if (skip < 0) { /* to count up from the bottom, we need to count them all first */
70047 ripley 2360
	while (c) {
87647 kalibera 2361
	    if (c->callflag & (CTXT_FUNCTION | CTXT_BUILTIN))
59413 murdoch 2362
		skip++;
70047 ripley 2363
	    c = c->nextcontext;
2364
	};
2365
	if (skip < 0) return R_NilValue; /* not enough there */
2366
	c = R_GlobalContext;
59413 murdoch 2367
    }
87647 kalibera 2368
 
2369
    /* If skip = NA, try current active srcref first. */
2370
    if (keep_looking) {
2371
    	srcref = R_getCurrentSrcref();
2372
        if (srcref && !isNull(srcref))
2373
    	  return srcref;
2374
    }
2375
 
2376
    /* Go to the first call */
2377
    while (c && !(c->callflag & (CTXT_FUNCTION | CTXT_BUILTIN)))
2378
    	c = c->nextcontext;
2379
 
2380
    /* Now skip enough calls, regardless of srcref presence */
2381
    while (c && skip) {
2382
    	if (c->callflag & (CTXT_FUNCTION | CTXT_BUILTIN))
59413 murdoch 2383
	    skip--;
70047 ripley 2384
	c = c->nextcontext;
59375 murdoch 2385
    }
87647 kalibera 2386
    /* Now get the next srcref.  If skip was not NA, don't
2387
       keep looking. */
2388
    do {
87690 kalibera 2389
	if (!c) break;
87647 kalibera 2390
        srcref = fixBCSrcref(c->srcref, c);
2391
        c = c->nextcontext;
87690 kalibera 2392
    } while (keep_looking && !(srcref && !isNull(srcref)));
87647 kalibera 2393
    if (!srcref)
70047 ripley 2394
	srcref = R_NilValue;
59375 murdoch 2395
    return srcref;
2396
}
2397
 
2398
/* Return the filename corresponding to a srcref, or "" if none is found */
2399
 
70047 ripley 2400
SEXP
59375 murdoch 2401
R_GetSrcFilename(SEXP srcref)
2402
{
2403
    SEXP srcfile = getAttrib(srcref, R_SrcfileSymbol);
70047 ripley 2404
    if (TYPEOF(srcfile) != ENVSXP)
2405
	return ScalarString(mkChar(""));
86821 luke 2406
    srcfile = R_findVar(install("filename"), srcfile);
59375 murdoch 2407
    if (TYPEOF(srcfile) != STRSXP)
70047 ripley 2408
	return ScalarString(mkChar(""));
59375 murdoch 2409
    return srcfile;
2410
}
71245 luke 2411
 
2412
 
2413
/*
2414
 * C level tryCatch support
2415
 */
2416
 
2417
/* There are two functions:
2418
 
2419
       R_TryCatchError    handles error conditions;
2420
 
2421
       R_TryCatch         can handle any condition type and allows a
2422
                          finalize action.
2423
*/
2424
 
2425
SEXP R_tryCatchError(SEXP (*body)(void *), void *bdata,
2426
		     SEXP (*handler)(SEXP, void *), void *hdata)
2427
{
2428
    SEXP val;
2429
    SEXP cond = Rf_mkString("error");
2430
 
2431
    PROTECT(cond);
2432
    val = R_tryCatch(body, bdata, cond, handler, hdata, NULL, NULL);
2433
    UNPROTECT(1);
2434
    return val;
2435
}
2436
 
2437
/* This implementation uses R's tryCatch via calls from C to R to
2438
   invoke R's tryCatch, and then back to C to infoke the C
2439
   body/handler functions via a .Internal helper. This makes the
2440
   implementation fairly simple but not fast. If performance becomes
2441
   an issue we can look into a pure C implementation. LT */
2442
 
2443
typedef struct {
2444
    SEXP (*body)(void *);
2445
    void *bdata;
2446
    SEXP (*handler)(SEXP, void *);
2447
    void *hdata;
2448
    void (*finally)(void *);
2449
    void *fdata;
87815 ripley 2450
    Rboolean suspended;
71245 luke 2451
} tryCatchData_t;
2452
 
2453
static SEXP default_tryCatch_handler(SEXP cond, void *data)
2454
{
2455
    return R_NilValue;
2456
}
2457
 
2458
static void default_tryCatch_finally(void *data) { }
2459
 
71260 luke 2460
static SEXP trycatch_callback = NULL;
2461
static const char* trycatch_callback_source =
77242 luke 2462
    "function(addr, classes, fin) {\n"
71260 luke 2463
    "    handler <- function(cond)\n"
77242 luke 2464
    "        .Internal(C_tryCatchHelper(addr, 1L, cond))\n"
2465
    "    handlers <- rep_len(alist(handler), length(classes))\n"
2466
    "    names(handlers) <- classes\n"
71260 luke 2467
    "    if (fin)\n"
77242 luke 2468
    "	     handlers <- c(handlers,\n"
2469
    "            alist(finally = .Internal(C_tryCatchHelper(addr, 2L))))\n"
2470
    "    args <- c(alist(.Internal(C_tryCatchHelper(addr, 0L))), handlers)\n"
2471
    "    do.call('tryCatch', args)\n"
71260 luke 2472
    "}";
2473
 
71245 luke 2474
SEXP R_tryCatch(SEXP (*body)(void *), void *bdata,
2475
		SEXP conds,
2476
		SEXP (*handler)(SEXP, void *), void *hdata,
2477
		void (*finally)(void *), void *fdata)
2478
{
2479
    if (body == NULL) error("must supply a body function");
2480
 
71260 luke 2481
    if (trycatch_callback == NULL) {
2482
	trycatch_callback = R_ParseEvalString(trycatch_callback_source,
2483
					      R_BaseNamespace);
2484
	R_PreserveObject(trycatch_callback);
2485
    }
74589 maechler 2486
 
71245 luke 2487
    tryCatchData_t tcd = {
2488
	.body = body,
2489
	.bdata = bdata,
2490
	.handler = handler != NULL ? handler : default_tryCatch_handler,
2491
	.hdata = hdata,
2492
	.finally = finally != NULL ? finally : default_tryCatch_finally,
74566 luke 2493
	.fdata = fdata,
2494
	.suspended = R_interrupts_suspended
71245 luke 2495
    };
2496
 
74566 luke 2497
    /* Interrupts are suspended while in the infrastructure R code and
78073 luke 2498
       enabled, if they were on entry to R_tryCatch, while calling the
74566 luke 2499
       body function in do_tryCatchHelper */
2500
 
2501
    R_interrupts_suspended = TRUE;
2502
 
74257 luke 2503
    if (conds == NULL) conds = allocVector(STRSXP, 0);
2504
    PROTECT(conds);
71245 luke 2505
    SEXP fin = finally != NULL ? R_TrueValue : R_FalseValue;
2506
    SEXP tcdptr = R_MakeExternalPtr(&tcd, R_NilValue, R_NilValue);
71260 luke 2507
    SEXP expr = lang4(trycatch_callback, tcdptr, conds, fin);
71245 luke 2508
    PROTECT(expr);
78071 luke 2509
    SEXP val = evalKeepVis(expr, R_GlobalEnv);
74257 luke 2510
    UNPROTECT(2); /* conds, expr */
74566 luke 2511
    R_interrupts_suspended = tcd.suspended;
71245 luke 2512
    return val;
2513
}
2514
 
83445 ripley 2515
attribute_hidden
71257 luke 2516
SEXP do_tryCatchHelper(SEXP call, SEXP op, SEXP args, SEXP env)
71245 luke 2517
{
2518
    SEXP eptr = CAR(args);
2519
    SEXP sw = CADR(args);
2520
    SEXP cond = CADDR(args);
74589 maechler 2521
 
71245 luke 2522
    if (TYPEOF(eptr) != EXTPTRSXP)
2523
	error("not an external pointer");
2524
 
2525
    tryCatchData_t *ptcd = R_ExternalPtrAddr(CAR(args));
2526
 
2527
    switch (asInteger(sw)) {
2528
    case 0:
74566 luke 2529
	if (ptcd->suspended)
2530
	    /* Interrupts were suspended for the call to R_TryCatch,
2531
	       so leave them that way */
2532
	    return ptcd->body(ptcd->bdata);
2533
	else {
2534
	    /* Interrupts were not suspended for the call to
2535
	       R_TryCatch, but were suspended for the call through
2536
	       R. So enable them for the body and suspend again on the
2537
	       way out. */
2538
	    R_interrupts_suspended = FALSE;
2539
	    SEXP val = ptcd->body(ptcd->bdata);
2540
	    R_interrupts_suspended = TRUE;
2541
	    return val;
2542
	}
71245 luke 2543
    case 1:
2544
	if (ptcd->handler != NULL)
2545
	    return ptcd->handler(cond, ptcd->hdata);
2546
	else return R_NilValue;
2547
    case 2:
2548
	if (ptcd->finally != NULL)
2549
	    ptcd->finally(ptcd->fdata);
2550
	return R_NilValue;
2551
    default: return R_NilValue; /* should not happen */
2552
    }
2553
}
77188 luke 2554
 
78073 luke 2555
 
2556
/* R_withCallingErrorHandler establishes a calling handler for
2557
   conditions inheriting from class 'error'. The handler is
2558
   established without calling back into the R implementation. This
2559
   should therefore be much more efficient than the current R_tryCatch
2560
   implementation. */
2561
 
2562
SEXP R_withCallingErrorHandler(SEXP (*body)(void *), void *bdata,
2563
			       SEXP (*handler)(SEXP, void *), void *hdata)
2564
{
2565
    /* This defines the lambda expression for th handler. The `addr`
79123 kalibera 2566
       variable will be defined in the closure environment and contain
78073 luke 2567
       an external pointer to the callback data. */
2568
    static const char* wceh_callback_source =
2569
	"function(cond) .Internal(C_tryCatchHelper(addr, 1L, cond))";
2570
 
2571
    static SEXP wceh_callback = NULL;
2572
    static SEXP wceh_class = NULL;
2573
    static SEXP addr_sym = NULL;
2574
 
2575
    if (body == NULL) error("must supply a body function");
2576
 
2577
    if (wceh_callback == NULL) {
2578
	wceh_callback = R_ParseEvalString(wceh_callback_source,
2579
					  R_BaseNamespace);
2580
	R_PreserveObject(wceh_callback);
2581
	wceh_class = mkChar("error");
2582
	R_PreserveObject(wceh_class);
2583
	addr_sym = install("addr");
2584
    }
2585
 
2586
    /* record the C-level handler information */
2587
    tryCatchData_t tcd = {
2588
	.handler = handler != NULL ? handler : default_tryCatch_handler,
2589
	.hdata = hdata
2590
    };
2591
    SEXP tcdptr = R_MakeExternalPtr(&tcd, R_NilValue, R_NilValue);
2592
 
2593
    /* create the R handler function closure */
2594
    SEXP env = CONS(tcdptr, R_NilValue);
2595
    SET_TAG(env, addr_sym);
2596
    env = NewEnvironment(R_NilValue, env, R_BaseNamespace);
2597
    PROTECT(env);
2598
    SEXP h = duplicate(wceh_callback);
2599
    SET_CLOENV(h, env);
2600
    UNPROTECT(1); /* env */
2601
 
2602
    /* push the handler on the handler stack */
2603
    SEXP oldstack = R_HandlerStack;
2604
    PROTECT(oldstack);
2605
    PROTECT(h);
2606
    SEXP entry = mkHandlerEntry(wceh_class, R_GlobalEnv, h, R_NilValue,
2607
				R_NilValue, /* OK for a calling handler */
2608
				TRUE);
2609
    R_HandlerStack = CONS(entry, R_HandlerStack);
2610
    UNPROTECT(1); /* h */
2611
 
2612
    SEXP val = body(bdata);
2613
 
2614
    /* restore the handler stack */
2615
    R_HandlerStack = oldstack;
2616
    UNPROTECT(1); /* oldstack */
2617
 
2618
    return val;
2619
}
2620
 
83446 ripley 2621
attribute_hidden SEXP do_addGlobHands(SEXP call, SEXP op,SEXP args, SEXP rho)
77188 luke 2622
{
81768 luke 2623
    /* check for handlers on the stack before proceeding (PR1826). */
77188 luke 2624
    SEXP oldstk = R_ToplevelContext->handlerstack;
81768 luke 2625
    for (RCNTXT *cptr = R_GlobalContext;
2626
	 cptr != R_ToplevelContext;
2627
	 cptr = cptr->nextcontext)
2628
	if (cptr->handlerstack != oldstk)
2629
	    error("should not be called with handlers on the stack");
77188 luke 2630
 
2631
    R_HandlerStack = R_NilValue;
2632
    do_addCondHands(call, op, args, rho);
2633
 
2634
    /* This is needed to handle intermediate contexts that would
2635
       restore the handler stack to the value when begincontext was
2636
       called. This function should only be called in a context where
2637
       there are no handlers on the stack. */
2638
    for (RCNTXT *cptr = R_GlobalContext;
2639
	 cptr != R_ToplevelContext;
2640
	 cptr = cptr->nextcontext)
2641
	if (cptr->handlerstack == oldstk)
2642
	    cptr->handlerstack = R_HandlerStack;
81768 luke 2643
	else /* should not happen after the check above */
2644
	    error("should not be called with handlers on the stack");
77188 luke 2645
 
2646
    R_ToplevelContext->handlerstack = R_HandlerStack;
78002 luke 2647
    return R_NilValue;
77188 luke 2648
}
81112 luke 2649
 
2650
 
2651
/* signaling conditions from C code */
2652
 
81150 luke 2653
static void R_signalCondition(SEXP cond, SEXP call,
2654
			      int restoreHandlerStack,
2655
			      int exitOnly)
81112 luke 2656
{
2657
    if (restoreHandlerStack) {
2658
	SEXP oldstack = R_HandlerStack;
2659
	PROTECT(oldstack);
2660
	R_signalCondition(cond, call, FALSE, exitOnly);
2661
	R_HandlerStack = oldstack;
2662
	UNPROTECT(1); /* oldstack */
2663
    }
2664
    else {
2665
	SEXP list;
2666
	while ((list = findConditionHandler(cond)) != R_NilValue) {
2667
	    SEXP entry = CAR(list);
2668
	    R_HandlerStack = CDR(list);
2669
	    if (IS_CALLING_ENTRY(entry)) {
2670
		SEXP h = ENTRY_HANDLER(entry);
2671
		if (h == R_RestartToken)
2672
		    break;
2673
		else if (! exitOnly) {
2674
		    R_CheckStack();
2675
		    SEXP hcall = LCONS(h, LCONS(cond, R_NilValue));
2676
		    PROTECT(hcall);
2677
		    eval(hcall, R_GlobalEnv);
2678
		    UNPROTECT(1); /* hcall */
2679
		}
2680
	    }
2681
	    else gotoExitingHandler(cond, call, entry);
2682
	}
2683
    }
2684
}
2685
 
87740 ripley 2686
NORET attribute_hidden /* for now */
2687
void R_signalErrorConditionEx(SEXP cond, SEXP call, int exitOnly)
81112 luke 2688
{
2689
    /* caller must make sure that 'cond' and 'call' are protected. */
86754 luke 2690
    R_signalCondition(cond, call, TRUE, exitOnly);
81112 luke 2691
 
2692
    /* the first element of 'cond' must be a scalar string to be used
2693
       as the error message in default error processing. */
2694
    if (TYPEOF(cond) != VECSXP || LENGTH(cond) == 0)
2695
	error(_("condition object must be a VECSXP of length at least one"));
2696
    SEXP elt = VECTOR_ELT(cond, 0);
2697
    if (TYPEOF(elt) != STRSXP || LENGTH(elt) != 1)
2698
	error(_("first element of condition object must be a scalar string"));
81162 maechler 2699
 
86754 luke 2700
    errorcall_dflt(call, "%s", translateChar(STRING_ELT(elt, 0)));
81112 luke 2701
}
2702
 
87740 ripley 2703
NORET attribute_hidden /* for now */
2704
void R_signalErrorCondition(SEXP cond, SEXP call)
81112 luke 2705
{
2706
    R_signalErrorConditionEx(cond, call, FALSE);
2707
}
2708
 
86755 luke 2709
attribute_hidden /* for now */
2710
void R_signalWarningCondition(SEXP cond)
2711
{
2712
    static SEXP condSym = NULL;
2713
    static SEXP expr = NULL;
2714
    if (expr == NULL) {
2715
        condSym = install("cond");
2716
        expr = R_ParseString("warning(cond)");
2717
        R_PreserveObject(expr);
2718
    }
2719
    SEXP env = PROTECT(R_NewEnv(R_BaseNamespace, FALSE, 0));
2720
    defineVar(condSym, cond, env);
2721
    evalKeepVis(expr, env);
2722
    UNPROTECT(1); /* env*/
2723
}
81112 luke 2724
 
86755 luke 2725
 
81112 luke 2726
/* creating internal error conditions */
2727
 
2728
/* use a static global buffer to create messages for the error
2729
   condition objects to save stack space */
2730
static char emsg_buf[BUFSIZE];
2731
 
81504 luke 2732
attribute_hidden /* for now */
2733
SEXP R_vmakeErrorCondition(SEXP call,
2734
			   const char *classname, const char *subclassname,
2735
			   int nextra, const char *format, va_list ap)
81112 luke 2736
{
2737
    if (call == R_CurrentExpression)
2738
	/* behave like error() */
2739
	call = getCurrentCall();
84166 kalibera 2740
    PROTECT(call);
81504 luke 2741
    int nelem = nextra + 2;
2742
    SEXP cond = PROTECT(allocVector(VECSXP, nelem));
2743
 
2744
    Rvsnprintf_mbcs(emsg_buf, BUFSIZE, format, ap);
81112 luke 2745
    SET_VECTOR_ELT(cond, 0, mkString(emsg_buf));
2746
    SET_VECTOR_ELT(cond, 1, call);
81162 maechler 2747
 
81504 luke 2748
    SEXP names = allocVector(STRSXP, nelem);
81112 luke 2749
    setAttrib(cond, R_NamesSymbol, names);
2750
    SET_STRING_ELT(names, 0, mkChar("message"));
2751
    SET_STRING_ELT(names, 1, mkChar("call"));
2752
 
81504 luke 2753
    SEXP klass = allocVector(STRSXP, subclassname == NULL ? 3 : 4);
81112 luke 2754
    setAttrib(cond, R_ClassSymbol, klass);
81504 luke 2755
    if (subclassname == NULL) {
2756
	SET_STRING_ELT(klass, 0, mkChar(classname));
2757
	SET_STRING_ELT(klass, 1, mkChar("error"));
2758
	SET_STRING_ELT(klass, 2, mkChar("condition"));
2759
    }
2760
    else {
2761
	SET_STRING_ELT(klass, 0, mkChar(subclassname));
2762
	SET_STRING_ELT(klass, 1, mkChar(classname));
2763
	SET_STRING_ELT(klass, 2, mkChar("error"));
2764
	SET_STRING_ELT(klass, 3, mkChar("condition"));
2765
    }
81112 luke 2766
 
84166 kalibera 2767
    UNPROTECT(2); /* cond, call */
81504 luke 2768
 
81112 luke 2769
    return cond;
2770
}
81144 luke 2771
 
81504 luke 2772
attribute_hidden /* for now */
2773
SEXP R_makeErrorCondition(SEXP call,
2774
			  const char *classname, const char *subclassname,
2775
			  int nextra, const char *format, ...)
2776
{
2777
    va_list(ap);
2778
    va_start(ap, format);
2779
    SEXP cond = R_vmakeErrorCondition(call, classname, subclassname,
2780
				      nextra, format, ap);
2781
    va_end(ap);
2782
    return cond;
2783
}
87097 maechler 2784
 
2785
NORET void R_MissingArgError_c(const char* arg, SEXP call, const char* subclass)
2786
{
2787
    if (call == R_CurrentExpression) /* as error() */
2788
	call = getCurrentCall();
2789
    PROTECT(call);
2790
    SEXP cond;
89935 luke 2791
    Rboolean non_empty_arg = arg[0] != 0;
2792
    if(non_empty_arg)
2793
	cond = R_makeErrorCondition(call, "missingArgError", subclass, 1,
87097 maechler 2794
				    _("argument \"%s\" is missing, with no default"), arg);
2795
    else
89935 luke 2796
	cond = R_makeErrorCondition(call, "missingArgError", subclass, 1,
87097 maechler 2797
				    _("argument is missing, with no default"));
2798
    PROTECT(cond);
89935 luke 2799
    if (non_empty_arg)
2800
	R_setConditionField(cond, 2, "name", install(arg));
2801
    else
2802
	R_setConditionField(cond, 2, "name", R_NilValue);
87097 maechler 2803
    R_signalErrorCondition(cond, call);
2804
    UNPROTECT(2); /* not reached */
2805
}
2806
 
2807
NORET void R_MissingArgError(SEXP symbol, SEXP call, const char* subclass)
2808
{
2809
    R_MissingArgError_c(CHAR(PRINTNAME(symbol)), call, subclass);
2810
}
2811
 
89924 luke 2812
NORET attribute_hidden void R_ObjectNotFoundError(SEXP sym, SEXP call,
2813
						  const char *mode)
2814
{
2815
    if (TYPEOF(sym) != SYMSXP)
2816
	error(_("not a symbol"));
2817
    if (call == R_CurrentExpression)
2818
	call = getCurrentCall();
2819
    PROTECT(call);
2820
    SEXP cond;
2821
    if (mode == NULL) {
2822
	cond = R_makeErrorCondition(call,
2823
				    "objectNotFoundError", NULL, 2,
2824
				    _("object '%s' not found"),
2825
				    EncodeChar(PRINTNAME(sym)));
2826
	mode = "any";
2827
    }
2828
    else {
2829
	cond = R_makeErrorCondition(call,
2830
				    "objectNotFoundError", NULL, 2,
2831
				    _("object '%s' of mode '%s' was not found"),
2832
				    EncodeChar(PRINTNAME(sym)),
2833
				    mode);
2834
    }
2835
    PROTECT(cond);
2836
    R_setConditionField(cond, 2, "name", sym);
2837
    R_setConditionField(cond, 3, "mode", mkString(mode));
2838
    R_signalErrorCondition(cond, call);
2839
    UNPROTECT(2); // not reached
2840
}
87097 maechler 2841
 
89924 luke 2842
NORET attribute_hidden void R_FunctionNotFoundError(SEXP sym, SEXP call)
89923 luke 2843
{
2844
    if (TYPEOF(sym) != SYMSXP)
2845
	error(_("not a symbol"));
89924 luke 2846
    if (call == R_CurrentExpression)
2847
	call = getCurrentCall();
2848
    PROTECT(call);
2849
    SEXP cond = R_makeErrorCondition(call,
2850
				     "objectNotFoundError",
2851
				     "functionNotFoundError",
2852
				     2,
89923 luke 2853
				     _("could not find function \"%s\""),
89924 luke 2854
				     EncodeChar(PRINTNAME(sym)));
89923 luke 2855
    PROTECT(cond);
2856
    R_setConditionField(cond, 2, "name", sym);
89924 luke 2857
    R_setConditionField(cond, 3, "mode", mkString("function"));
89923 luke 2858
    R_signalErrorCondition(cond, call);
89924 luke 2859
    UNPROTECT(2); // not reached
89923 luke 2860
}
2861
 
81504 luke 2862
attribute_hidden /* for now */
2863
void R_setConditionField(SEXP cond, R_xlen_t idx, const char *name, SEXP val)
2864
{
2865
    PROTECT(cond);
2866
    PROTECT(val);
2867
    /**** maybe this should be a general set named vector elt */
2868
    /**** or maybe it should check that cond inherits from "condition" */
2869
    /**** or maybe just fill in the next empty slot and not take an index */
2870
    if (TYPEOF(cond) != VECSXP)
2871
	error("bad condition argument");
2872
    if (idx < 0 || idx >= XLENGTH(cond))
2873
	error("bad field index");
2874
    SEXP names = getAttrib(cond, R_NamesSymbol);
2875
    if (TYPEOF(names) != STRSXP || XLENGTH(names) != XLENGTH(cond))
2876
	error("bad names attribute on condition object");
2877
    SET_VECTOR_ELT(cond, idx, val);
2878
    SET_STRING_ELT(names, idx, mkChar(name));
2879
    UNPROTECT(2); /* cond, val */
2880
}
2881
 
81144 luke 2882
attribute_hidden
81504 luke 2883
SEXP R_makeNotSubsettableError(SEXP x, SEXP call)
2884
{
2885
    SEXP cond = R_makeErrorCondition(call, "notSubsettableError", NULL, 1,
85146 luke 2886
				     R_MSG_ob_nonsub, R_typeToChar(x));
81504 luke 2887
    PROTECT(cond);
2888
    R_setConditionField(cond, 2, "object", x);
82544 maechler 2889
    UNPROTECT(1);
81504 luke 2890
    return cond;
2891
}
2892
 
2893
attribute_hidden
82544 maechler 2894
SEXP R_makeMissingSubscriptError(SEXP x, SEXP call)
2895
{
2896
    SEXP cond = R_makeErrorCondition(call, "MissingSubscriptError", NULL, 1,
2897
				     R_MSG_miss_subs);
2898
    PROTECT(cond);
2899
    R_setConditionField(cond, 2, "object", x);
2900
    UNPROTECT(1);
2901
    return cond;
2902
}
2903
 
2904
attribute_hidden
2905
SEXP R_makeMissingSubscriptError1(SEXP call) // "1" arg.: no 'x'
2906
{
2907
    return R_makeErrorCondition(call, "MissingSubscriptError", NULL, 0,
2908
				R_MSG_miss_subs);
2909
}
2910
 
2911
attribute_hidden
81144 luke 2912
SEXP R_makeOutOfBoundsError(SEXP x, int subscript, SEXP sindex,
2913
			    SEXP call, const char *prefix)
2914
{
81504 luke 2915
    SEXP cond;
2916
    const char *classname = "subscriptOutOfBoundsError";
2917
    int nextra = 3;
81144 luke 2918
 
81504 luke 2919
    if (prefix)
2920
	cond = R_makeErrorCondition(call, classname, NULL, nextra,
2921
				    "%s %s", prefix, R_MSG_subs_o_b);
2922
    else
2923
	cond = R_makeErrorCondition(call, classname, NULL, nextra,
2924
				    "%s", R_MSG_subs_o_b);
81144 luke 2925
    PROTECT(cond);
2926
 
87078 maechler 2927
    /* In some cases the 'subscript' argument is negative, indicating
81504 luke 2928
       that which subscript is out of bounds is not known. We could
2929
       probably do better, but for now report 'subscript' as NA in the
87078 maechler 2930
       condition object. */
81504 luke 2931
    SEXP ssub = ScalarInteger(subscript >= 0 ? subscript + 1 : NA_INTEGER);
82379 kalibera 2932
    PROTECT(ssub);
81144 luke 2933
 
81504 luke 2934
    R_setConditionField(cond, 2, "object", x);
2935
    R_setConditionField(cond, 3, "subscript", ssub);
2936
    R_setConditionField(cond, 4, "index", sindex);
82379 kalibera 2937
    UNPROTECT(2); /* cond, ssub */
81144 luke 2938
 
2939
    return cond;
2940
}
81150 luke 2941
 
2942
/* Do not translate this, to save stack space */
2943
static const char *C_SO_msg_fmt =
2944
    "C stack usage  %ld is too close to the limit";
2945
 
83446 ripley 2946
attribute_hidden SEXP R_makeCStackOverflowError(SEXP call, intptr_t usage)
81150 luke 2947
{
81504 luke 2948
    SEXP cond = R_makeErrorCondition(call, "stackOverflowError",
2949
				     "CStackOverflowError", 1,
2950
				     C_SO_msg_fmt, usage);
2951
    PROTECT(cond);
2952
    R_setConditionField(cond, 2, "usage", ScalarReal((double) usage));
81150 luke 2953
    UNPROTECT(1); /* cond */
2954
    return cond;
2955
}
2956
 
2957
static SEXP R_protectStackOverflowError = NULL;
83446 ripley 2958
attribute_hidden SEXP R_getProtectStackOverflowError(void)
81150 luke 2959
{
2960
    return R_protectStackOverflowError;
2961
}
2962
 
2963
static SEXP R_expressionStackOverflowError = NULL;
83446 ripley 2964
attribute_hidden SEXP R_getExpressionStackOverflowError(void)
81150 luke 2965
{
2966
    return R_expressionStackOverflowError;
2967
}
2968
 
2969
static SEXP R_nodeStackOverflowError = NULL;
83446 ripley 2970
attribute_hidden SEXP R_getNodeStackOverflowError(void)
81150 luke 2971
{
2972
    return R_nodeStackOverflowError;
2973
}
2974
 
86755 luke 2975
attribute_hidden /* for now */
2976
SEXP R_vmakeWarningCondition(SEXP call,
2977
			   const char *classname, const char *subclassname,
2978
			   int nextra, const char *format, va_list ap)
2979
{
2980
    if (call == R_CurrentExpression)
2981
	/* behave like warning() */
2982
	call = getCurrentCall();
2983
    PROTECT(call);
2984
    int nelem = nextra + 2;
2985
    SEXP cond = PROTECT(allocVector(VECSXP, nelem));
2986
 
2987
    Rvsnprintf_mbcs(emsg_buf, BUFSIZE, format, ap);
2988
    SET_VECTOR_ELT(cond, 0, mkString(emsg_buf));
2989
    SET_VECTOR_ELT(cond, 1, call);
2990
 
2991
    SEXP names = allocVector(STRSXP, nelem);
2992
    setAttrib(cond, R_NamesSymbol, names);
2993
    SET_STRING_ELT(names, 0, mkChar("message"));
2994
    SET_STRING_ELT(names, 1, mkChar("call"));
2995
 
2996
    SEXP klass = allocVector(STRSXP, subclassname == NULL ? 3 : 4);
2997
    setAttrib(cond, R_ClassSymbol, klass);
2998
    if (subclassname == NULL) {
2999
	SET_STRING_ELT(klass, 0, mkChar(classname));
3000
	SET_STRING_ELT(klass, 1, mkChar("warning"));
3001
	SET_STRING_ELT(klass, 2, mkChar("condition"));
3002
    }
3003
    else {
3004
	SET_STRING_ELT(klass, 0, mkChar(subclassname));
3005
	SET_STRING_ELT(klass, 1, mkChar(classname));
3006
	SET_STRING_ELT(klass, 2, mkChar("warning"));
3007
	SET_STRING_ELT(klass, 3, mkChar("condition"));
3008
    }
3009
 
3010
    UNPROTECT(2); /* cond, call */
3011
 
3012
    return cond;
3013
}
3014
 
3015
attribute_hidden /* for now */
3016
SEXP R_makeWarningCondition(SEXP call,
3017
			  const char *classname, const char *subclassname,
3018
			  int nextra, const char *format, ...)
3019
{
3020
    va_list(ap);
3021
    va_start(ap, format);
3022
    SEXP cond = R_vmakeWarningCondition(call, classname, subclassname,
3023
				      nextra, format, ap);
3024
    va_end(ap);
3025
    return cond;
3026
}
3027
 
90291 hornik 3028
SEXP R_makePartialMatchWarningCondition(SEXP call, SEXP input, SEXP target)
86755 luke 3029
{
3030
    SEXP cond =
3031
	R_makeWarningCondition(call, "partialMatchWarning", NULL, 2,
90283 hornik 3032
			       _("partial match of '%s' to '%s'"),
90294 hornik 3033
 			       TYPEOF(input) == SYMSXP ? 
3034
			       CHAR(PRINTNAME(input))  //EncodeChar??
3035
			       : translateChar(input),
3036
			       TYPEOF(target) == SYMSXP ?
3037
			       CHAR(PRINTNAME(target)) //EncodeChar??
3038
			       : translateChar(target));
90283 hornik 3039
    PROTECT(cond);
90294 hornik 3040
    R_setConditionField(cond, 2, "input", 
3041
			TYPEOF(input) == SYMSXP ? input :
3042
			ScalarString(input));
3043
    R_setConditionField(cond, 3, "target",
3044
			TYPEOF(target) == SYMSXP ? target :
3045
			ScalarString(target));
90283 hornik 3046
    // ideally we would want the function/object in a field also
3047
    UNPROTECT(1); /* cond */
3048
    return cond;
3049
}
3050
 
3051
SEXP R_makePartialArgumentMatchWarningCondition(SEXP call, SEXP argument, SEXP formal)
3052
{
3053
    SEXP cond =
90293 hornik 3054
	R_makeWarningCondition(call, "partialMatchWarning",
3055
			       "partialArgumentMatchWarning", 2,
86755 luke 3056
			       _("partial argument match of '%s' to '%s'"),
3057
			       CHAR(PRINTNAME(argument)),//EncodeChar??
3058
			       CHAR(PRINTNAME(formal)));//EncodeChar??
3059
    PROTECT(cond);
3060
    R_setConditionField(cond, 2, "argument", argument);
3061
    R_setConditionField(cond, 3, "formal", formal);
90280 hornik 3062
    // ideally we would want the function/object in a field also
86755 luke 3063
    UNPROTECT(1); /* cond */
3064
    return cond;
3065
}
3066
 
81504 luke 3067
#define PROT_SO_MSG _("protect(): protection stack overflow")
3068
#define EXPR_SO_MSG _("evaluation nested too deeply: infinite recursion / options(expressions=)?")
3069
#define NODE_SO_MSG _("node stack overflow")
3070
 
81150 luke 3071
attribute_hidden
82931 ripley 3072
void R_InitConditions(void)
81150 luke 3073
{
3074
    R_protectStackOverflowError =
81504 luke 3075
	R_makeErrorCondition(R_NilValue, "stackOverflowError",
3076
			     "protectStackOverflowError", 0, PROT_SO_MSG);
81150 luke 3077
    MARK_NOT_MUTABLE(R_protectStackOverflowError);
3078
    R_PreserveObject(R_protectStackOverflowError);
3079
 
3080
    R_expressionStackOverflowError =
81504 luke 3081
	R_makeErrorCondition(R_NilValue, "stackOverflowError",
3082
			     "expressionStackOverflowError", 0, EXPR_SO_MSG);
81150 luke 3083
    MARK_NOT_MUTABLE(R_expressionStackOverflowError);
3084
    R_PreserveObject(R_expressionStackOverflowError);
3085
 
3086
    R_nodeStackOverflowError =
81504 luke 3087
	R_makeErrorCondition(R_NilValue, "stackOverflowError",
3088
			     "nodeStackOverflowError", 0, NODE_SO_MSG);
81150 luke 3089
    MARK_NOT_MUTABLE(R_nodeStackOverflowError);
3090
    R_PreserveObject(R_nodeStackOverflowError);
3091
}