int attribute_hidden Rstd_ChooseFile(int _new, char *buf, int len) { size_t namelen; char *bufp; R_ReadConsole("Enter file name: ", (unsigned char *)buf, len, 0); namelen = strlen(buf); bufp = &buf[namelen - 1]; while (bufp >= buf && isspace((int)*bufp)) *bufp-- = '\0'; return (int) strlen(buf); }
void NewFrameConfirm(pDevDesc dd) { if(!R_Interactive) return; /* dd->newFrameConfirm(dd) will either handle this, or return FALSE to ask the engine to do so. */ if(dd->newFrameConfirm && dd->newFrameConfirm(dd)) ; else { unsigned char buf[1024]; R_ReadConsole(_("Hit <Return> to see next plot: "), buf, 1024, 0); } }
/* used by readline() and menu() */ static int ConsoleGetchar(void) { if (--ConsoleBufCnt < 0) { ConsoleBuf[CONSOLE_BUFFER_SIZE] = '\0'; if (R_ReadConsole(ConsolePrompt, ConsoleBuf, CONSOLE_BUFFER_SIZE, 0) == 0) { R_ClearerrConsole(); return R_EOF; } ConsoleBufp = ConsoleBuf; ConsoleBufCnt = (int) strlen((char *)ConsoleBuf); ConsoleBufCnt--; } /* at this point we need to use unsigned char or similar */ return (int) *ConsoleBufp++; }
void attribute_hidden Rstd_CleanUp(SA_TYPE saveact, int status, int runLast) { if(saveact == SA_DEFAULT) /* The normal case apart from R_Suicide */ saveact = SaveAction; if(saveact == SA_SAVEASK) { if(R_Interactive) { unsigned char buf[1024]; qask: R_ClearerrConsole(); R_FlushConsole(); int res = R_ReadConsole("Save workspace image? [y/n/c]: ", buf, 128, 0); if(res) { switch (buf[0]) { case 'y': case 'Y': saveact = SA_SAVE; break; case 'n': case 'N': saveact = SA_NOSAVE; break; case 'c': case 'C': jump_to_toplevel(); break; default: goto qask; } } else saveact = SA_NOSAVE; /* probably EOF */ } else saveact = SaveAction; } switch (saveact) { case SA_SAVE: if(runLast) R_dot_Last(); if(R_DirtyImage) R_SaveGlobalEnv(); #ifdef HAVE_LIBREADLINE # ifdef HAVE_READLINE_HISTORY_H if(R_Interactive && UsingReadline) { int err; R_setupHistory(); /* re-read the history size and filename */ stifle_history(R_HistorySize); err = write_history(R_HistoryFile); if(err) warning(_("problem in saving the history file '%s'"), R_HistoryFile); } # endif /* HAVE_READLINE_HISTORY_H */ #endif /* HAVE_LIBREADLINE */ break; case SA_NOSAVE: if(runLast) R_dot_Last(); break; case SA_SUICIDE: default: break; } R_RunExitFinalizers(); CleanEd(); if(saveact != SA_SUICIDE) KillAllDevices(); R_CleanTempDir(); if(saveact != SA_SUICIDE && R_CollectWarnings) PrintWarnings(); /* from device close and (if run) .Last */ if(ifp) fclose(ifp); /* input file from -f or --file= */ fpu_setup(FALSE); exit(status); }
static void sigactionSegv(int signum, siginfo_t *ip, void *context) { char *s; /* First check for stack overflow if we know the stack position. We assume anything within 16Mb beyond the stack end is a stack overflow. */ if(signum == SIGSEGV && (ip != (siginfo_t *)0) && (intptr_t) R_CStackStart != -1) { uintptr_t addr = (uintptr_t) ip->si_addr; intptr_t diff = (R_CStackDir > 0) ? R_CStackStart - addr: addr - R_CStackStart; uintptr_t upper = 0x1000000; /* 16Mb */ if((intptr_t) R_CStackLimit != -1) upper += R_CStackLimit; if(diff > 0 && diff < upper) { REprintf(_("Error: segfault from C stack overflow\n")); jump_to_toplevel(); } } /* need to take off stack checking as stack base has changed */ R_CStackLimit = (uintptr_t)-1; /* Do not translate these messages */ REprintf("\n *** caught %s ***\n", signum == SIGILL ? "illegal operation" : signum == SIGBUS ? "bus error" : "segfault"); if(ip != (siginfo_t *)0) { if(signum == SIGILL) { switch(ip->si_code) { #ifdef ILL_ILLOPC case ILL_ILLOPC: s = "illegal opcode"; break; #endif #ifdef ILL_ILLOPN case ILL_ILLOPN: s = "illegal operand"; break; #endif #ifdef ILL_ILLADR case ILL_ILLADR: s = "illegal addressing mode"; break; #endif #ifdef ILL_ILLTRP case ILL_ILLTRP: s = "illegal trap"; break; #endif #ifdef ILL_COPROC case ILL_COPROC: s = "coprocessor error"; break; #endif default: s = "unknown"; break; } } else if(signum == SIGBUS) switch(ip->si_code) { #ifdef BUS_ADRALN case BUS_ADRALN: s = "invalid alignment"; break; #endif #ifdef BUS_ADRERR /* not on MacOS X, apparently */ case BUS_ADRERR: s = "non-existent physical address"; break; #endif #ifdef BUS_OBJERR /* not on MacOS X, apparently */ case BUS_OBJERR: s = "object specific hardware error"; break; #endif default: s = "unknown"; break; } else switch(ip->si_code) { #ifdef SEGV_MAPERR case SEGV_MAPERR: s = "memory not mapped"; break; #endif #ifdef SEGV_ACCERR case SEGV_ACCERR: s = "invalid permissions"; break; #endif default: s = "unknown"; break; } REprintf("address %p, cause '%s'\n", ip->si_addr, s); } { /* A simple customized print of the traceback */ SEXP trace, p, q; int line = 1, i; PROTECT(trace = R_GetTraceback(0)); if(trace != R_NilValue) { REprintf("\nTraceback:\n"); for(p = trace; p != R_NilValue; p = CDR(p), line++) { q = CAR(p); /* a character vector */ REprintf("%2d: ", line); for(i = 0; i < LENGTH(q); i++) REprintf("%s", CHAR(STRING_ELT(q, i))); REprintf("\n"); } UNPROTECT(1); } } if(R_Interactive) { REprintf("\nPossible actions:\n1: %s\n2: %s\n3: %s\n4: %s\n", "abort (with core dump, if enabled)", "normal R exit", "exit R without saving workspace", "exit R saving workspace"); while(1) { if(R_ReadConsole("Selection: ", ConsoleBuf, CONSOLE_BUFFER_SIZE, 0) > 0) { if(ConsoleBuf[0] == '1') break; if(ConsoleBuf[0] == '2') R_CleanUp(SA_DEFAULT, 0, 1); if(ConsoleBuf[0] == '3') R_CleanUp(SA_NOSAVE, 70, 0); if(ConsoleBuf[0] == '4') R_CleanUp(SA_SAVE, 71, 0); } } } REprintf("aborting ...\n"); R_CleanTempDir(); /* now do normal behaviour, e.g. core dump */ signal(signum, SIG_DFL); raise(signum); }
/* FIXME: this should be re-written to use Rf_ReplIteration since it gets out of sync with it over time */ int R_ReplDLLdo1(void) { int c; ParseStatus status; SEXP rho = R_GlobalEnv, lastExpr; Rboolean wasDisplayed = FALSE; if(!*DLLbufp) { R_Busy(0); if (R_ReadConsole(R_PromptString(0, prompt_type), DLLbuf, CONSOLE_BUFFER_SIZE, 1) == 0) return -1; DLLbufp = DLLbuf; } while((c = *DLLbufp++)) { R_IoBufferPutc(c, &R_ConsoleIob); if(c == ';' || c == '\n') break; } R_PPStackTop = 0; R_CurrentExpr = R_Parse1Buffer(&R_ConsoleIob, 0, &status); switch(status) { case PARSE_NULL: R_IoBufferWriteReset(&R_ConsoleIob); prompt_type = 1; break; case PARSE_OK: R_IoBufferReadReset(&R_ConsoleIob); R_CurrentExpr = R_Parse1Buffer(&R_ConsoleIob, 1, &status); R_Visible = FALSE; R_EvalDepth = 0; resetTimeLimits(); PROTECT(R_CurrentExpr); R_Busy(1); lastExpr = R_CurrentExpr; R_CurrentExpr = eval(R_CurrentExpr, rho); SET_SYMVALUE(R_LastvalueSymbol, R_CurrentExpr); wasDisplayed = R_Visible; if (R_Visible) PrintValueEnv(R_CurrentExpr, rho); if (R_CollectWarnings) PrintWarnings(); Rf_callToplevelHandlers(lastExpr, R_CurrentExpr, TRUE, wasDisplayed); UNPROTECT(1); R_IoBufferWriteReset(&R_ConsoleIob); R_Busy(0); prompt_type = 1; break; case PARSE_ERROR: parseError(R_NilValue, 0); R_IoBufferWriteReset(&R_ConsoleIob); prompt_type = 1; break; case PARSE_INCOMPLETE: R_IoBufferReadReset(&R_ConsoleIob); prompt_type = 2; break; case PARSE_EOF: return -1; break; } return prompt_type; }
/** This is the body of the REPL. It attempts to parse the first line or expression of its input, and optionally request input from the user if none is available. If the input can be parsed correctly, i) the resulting expression is evaluated, ii) the result assigned to .Last.Value, iii) top-level task handlers are invoked. If the input cannot be parsed, i.e. there is a syntax error, it is incomplete, or we encounter an end-of-file, then we change the prompt accordingly. The "cursor" for the input buffer is moved to the next starting point, i.e. the end of the first line or after the first ;. */ int Rf_ReplIteration(SEXP rho, int savestack, int browselevel, R_ReplState *state) { int c, browsevalue; SEXP value, thisExpr; Rboolean wasDisplayed = FALSE; if(!*state->bufp) { R_Busy(0); if (R_ReadConsole(R_PromptString(browselevel, state->prompt_type), state->buf, CONSOLE_BUFFER_SIZE, 1) == 0) return(-1); state->bufp = state->buf; } #ifdef SHELL_ESCAPE /* not default */ if (*state->bufp == '!') { R_system(&(state->buf[1])); state->buf[0] = '\0'; return(0); } #endif /* SHELL_ESCAPE */ while((c = *state->bufp++)) { R_IoBufferPutc(c, &R_ConsoleIob); if(c == ';' || c == '\n') break; } R_PPStackTop = savestack; R_CurrentExpr = R_Parse1Buffer(&R_ConsoleIob, 0, &state->status); switch(state->status) { case PARSE_NULL: /* The intention here is to break on CR but not on other null statements: see PR#9063 */ if (browselevel && !R_DisableNLinBrowser && !strcmp((char *) state->buf, "\n")) return -1; R_IoBufferWriteReset(&R_ConsoleIob); state->prompt_type = 1; return 1; case PARSE_OK: R_IoBufferReadReset(&R_ConsoleIob); R_CurrentExpr = R_Parse1Buffer(&R_ConsoleIob, 1, &state->status); if (browselevel) { browsevalue = ParseBrowser(R_CurrentExpr, rho); if(browsevalue == 1) return -1; if(browsevalue == 2) { R_IoBufferWriteReset(&R_ConsoleIob); return 0; } /* PR#15770 We don't want to step into expressions entered at the debug prompt. The 'S' will be changed back to 's' after the next eval. */ if (R_BrowserLastCommand == 's') R_BrowserLastCommand = 'S'; } R_Visible = FALSE; R_EvalDepth = 0; resetTimeLimits(); PROTECT(thisExpr = R_CurrentExpr); R_Busy(1); value = eval(thisExpr, rho); SET_SYMVALUE(R_LastvalueSymbol, value); wasDisplayed = R_Visible; if (R_Visible) PrintValueEnv(value, rho); if (R_CollectWarnings) PrintWarnings(); Rf_callToplevelHandlers(thisExpr, value, TRUE, wasDisplayed); R_CurrentExpr = value; /* Necessary? Doubt it. */ UNPROTECT(1); if (R_BrowserLastCommand == 'S') R_BrowserLastCommand = 's'; R_IoBufferWriteReset(&R_ConsoleIob); state->prompt_type = 1; return(1); case PARSE_ERROR: state->prompt_type = 1; parseError(R_NilValue, 0); R_IoBufferWriteReset(&R_ConsoleIob); return(1); case PARSE_INCOMPLETE: R_IoBufferReadReset(&R_ConsoleIob); state->prompt_type = 2; return(2); case PARSE_EOF: return(-1); break; } return(0); }