Пример #1
0
Файл: debug.c Проект: skyguy94/R
SEXP attribute_hidden do_debug(SEXP call, SEXP op, SEXP args, SEXP rho)
{
    SEXP ans = R_NilValue;

    checkArity(op,args);
#define find_char_fun \
    if (isValidString(CAR(args))) {				\
	SEXP s;							\
	PROTECT(s = installTrChar(STRING_ELT(CAR(args), 0)));	\
	SETCAR(args, findFun(s, rho));				\
	UNPROTECT(1);						\
    }
    find_char_fun

    if (TYPEOF(CAR(args)) != CLOSXP && TYPEOF(CAR(args)) != SPECIALSXP 
         &&  TYPEOF(CAR(args)) != BUILTINSXP )
	errorcall(call, _("argument must be a closure"));
    switch(PRIMVAL(op)) {
    case 0:
	SET_RDEBUG(CAR(args), 1);
	break;
    case 1:
	if( RDEBUG(CAR(args)) != 1 )
	    warningcall(call, "argument is not being debugged");
	SET_RDEBUG(CAR(args), 0);
	break;
    case 2:
        ans = ScalarLogical(RDEBUG(CAR(args)));
        break;
    case 3:
        SET_RSTEP(CAR(args), 1);
        break;
    }
    return ans;
}
Пример #2
0
static int ParseBrowser(SEXP CExpr, SEXP rho)
{
    int rval = 0;
    if (isSymbol(CExpr)) {
	const char *expr = CHAR(PRINTNAME(CExpr));
	if (!strcmp(expr, "c") || !strcmp(expr, "cont")) {
	    rval = 1;
	    SET_RDEBUG(rho, 0);
	} else if (!strcmp(expr, "f")) {
	    rval = 1;
	    RCNTXT *cntxt = R_GlobalContext;
	    while (cntxt != R_ToplevelContext 
		      && !(cntxt->callflag & (CTXT_RETURN | CTXT_LOOP))) {
		cntxt = cntxt->nextcontext;
	    }
	    cntxt->browserfinish = 1;	    
	    SET_RDEBUG(rho, 1);
	    R_BrowserLastCommand = 'f';
	} else if (!strcmp(expr, "help")) {
	    rval = 2;
	    printBrowserHelp();
	} else if (!strcmp(expr, "n")) {
	    rval = 1;
	    SET_RDEBUG(rho, 1);
	    R_BrowserLastCommand = 'n';
	} else if (!strcmp(expr, "Q")) {

	    /* Run onexit/cend code for everything above the target.
	       The browser context is still on the stack, so any error
	       will drop us back to the current browser.  Not clear
	       this is a good thing.  Also not clear this should still
	       be here now that jump_to_toplevel is used for the
	       jump. */
	    R_run_onexits(R_ToplevelContext);

	    /* this is really dynamic state that should be managed as such */
	    SET_RDEBUG(rho, 0); /*PR#1721*/

	    jump_to_toplevel();
	} else if (!strcmp(expr, "s")) {
	    rval = 1;
	    SET_RDEBUG(rho, 1);
	    R_BrowserLastCommand = 's';	    
	} else if (!strcmp(expr, "where")) {
	    rval = 2;
	    printwhere();
	    /* SET_RDEBUG(rho, 1); */
	}
    }
    return rval;
}
Пример #3
0
SEXP attribute_hidden do_sysbrowser(SEXP call, SEXP op, SEXP args, SEXP rho)
{
    SEXP rval=R_NilValue;
    RCNTXT *cptr;
    int n;

    checkArity(op, args);
    n = asInteger(CAR(args));
    if(n < 1 ) error(_("number of contexts must be positive"));

    /* first find the closest  browser context */
    cptr = R_GlobalContext;
    while (cptr != R_ToplevelContext) {
        if (cptr->callflag == CTXT_BROWSER) {
            break;
        }
        cptr = cptr->nextcontext;
    }
    /* error if not a browser context */

    if( !(cptr->callflag == CTXT_BROWSER) )
        error(_("no browser context to query"));

    switch (PRIMVAL(op)) {
    case 1: /* text */
    case 2: /* condition */
        /* first rewind to the right place if needed */
        /* note we want n>1, as we have already      */
        /* rewound to the first context              */
        if( n > 1 ) {
            while (cptr != R_ToplevelContext && n > 0 ) {
                if (cptr->callflag == CTXT_BROWSER) {
                    n--;
                    break;
                }
                cptr = cptr->nextcontext;
            }
        }
        if( !(cptr->callflag == CTXT_BROWSER) )
            error(_("not that many calls to browser are active"));

        if( PRIMVAL(op) == 1 )
            rval = CAR(cptr->promargs);
        else
            rval = CADR(cptr->promargs);
        break;
    case 3: /* turn on debugging n levels up */
        while ( (cptr != R_ToplevelContext) && n > 0 ) {
            if (cptr->callflag & CTXT_FUNCTION)
                n--;
            cptr = cptr->nextcontext;
        }
        if( !(cptr->callflag & CTXT_FUNCTION) )
            error(_("not that many functions on the call stack"));
        else
            SET_RDEBUG(cptr->cloenv, 1);
        break;
    }
    return(rval);
}
Пример #4
0
/* browser(text = "", condition = NULL, expr = TRUE, skipCalls = 0L)
 * ------- but also called from ./eval.c */
SEXP attribute_hidden do_browser(SEXP call, SEXP op, SEXP args, SEXP rho)
{
    RCNTXT *saveToplevelContext;
    RCNTXT *saveGlobalContext;
    RCNTXT thiscontext, returncontext, *cptr;
    int savestack, browselevel;
    SEXP ap, topExp, argList;

    /* argument matching */
    PROTECT(ap = list4(R_NilValue, R_NilValue, R_NilValue, R_NilValue));
    SET_TAG(ap,  install("text"));
    SET_TAG(CDR(ap), install("condition"));
    SET_TAG(CDDR(ap), install("expr"));
    SET_TAG(CDDDR(ap), install("skipCalls"));
    argList = matchArgs(ap, args, call);
    UNPROTECT(1);
    PROTECT(argList);
    /* substitute defaults */
    if(CAR(argList) == R_MissingArg)
	SETCAR(argList, mkString(""));
    if(CADR(argList) == R_MissingArg)
	SETCAR(CDR(argList), R_NilValue);
    if(CADDR(argList) == R_MissingArg) 
	SETCAR(CDDR(argList), ScalarLogical(1));
    if(CADDDR(argList) == R_MissingArg) 
	SETCAR(CDDDR(argList), ScalarInteger(0));

    /* return if 'expr' is not TRUE */
    if( !asLogical(CADDR(argList)) ) {
        UNPROTECT(1);
        return R_NilValue;
    }

    /* Save the evaluator state information */
    /* so that it can be restored on exit. */

    browselevel = countContexts(CTXT_BROWSER, 1);
    savestack = R_PPStackTop;
    PROTECT(topExp = R_CurrentExpr);
    saveToplevelContext = R_ToplevelContext;
    saveGlobalContext = R_GlobalContext;

    if (!RDEBUG(rho)) {
        int skipCalls = asInteger(CADDDR(argList));
	cptr = R_GlobalContext;
	while ( ( !(cptr->callflag & CTXT_FUNCTION) || skipCalls--) 
		&& cptr->callflag )
	    cptr = cptr->nextcontext;
	Rprintf("Called from: ");
	int tmp = asInteger(GetOption(install("deparse.max.lines"), R_BaseEnv));
	if(tmp != NA_INTEGER && tmp > 0) R_BrowseLines = tmp;
        if( cptr != R_ToplevelContext ) {
	    PrintValueRec(cptr->call, rho);
	    SET_RDEBUG(cptr->cloenv, 1);
        } else
            Rprintf("top level \n");

	R_BrowseLines = 0;
    }

    R_ReturnedValue = R_NilValue;

    /* Here we establish two contexts.  The first */
    /* of these provides a target for return */
    /* statements which a user might type at the */
    /* browser prompt.  The (optional) second one */
    /* acts as a target for error returns. */

    begincontext(&returncontext, CTXT_BROWSER, call, rho,
		 R_BaseEnv, argList, R_NilValue);
    if (!SETJMP(returncontext.cjmpbuf)) {
	begincontext(&thiscontext, CTXT_RESTART, R_NilValue, rho,
		     R_BaseEnv, R_NilValue, R_NilValue);
	if (SETJMP(thiscontext.cjmpbuf)) {
	    SET_RESTART_BIT_ON(thiscontext.callflag);
	    R_ReturnedValue = R_NilValue;
	    R_Visible = FALSE;
	}
	R_GlobalContext = &thiscontext;
	R_InsertRestartHandlers(&thiscontext, TRUE);
	R_ReplConsole(rho, savestack, browselevel+1);
	endcontext(&thiscontext);
    }
    endcontext(&returncontext);

    /* Reset the interpreter state. */

    R_CurrentExpr = topExp;
    UNPROTECT(1);
    R_PPStackTop = savestack;
    UNPROTECT(1);
    R_CurrentExpr = topExp;
    R_ToplevelContext = saveToplevelContext;
    R_GlobalContext = saveGlobalContext;
    return R_ReturnedValue;
}