diff options
-rw-r--r-- | source4/lib/appweb/ejs/ejsInternal.h | 2 | ||||
-rw-r--r-- | source4/lib/appweb/ejs/ejsLex.c | 7 | ||||
-rw-r--r-- | source4/lib/appweb/ejs/ejsLib.c | 36 |
3 files changed, 25 insertions, 20 deletions
diff --git a/source4/lib/appweb/ejs/ejsInternal.h b/source4/lib/appweb/ejs/ejsInternal.h index 3bf99d88b9..8b66dafdca 100644 --- a/source4/lib/appweb/ejs/ejsInternal.h +++ b/source4/lib/appweb/ejs/ejsInternal.h @@ -192,6 +192,8 @@ typedef struct ejEval { char *tokEndp; /* Pointer past end of token */ char *tokServp; /* Pointer to next token char */ int tokSize; /* Size of token buffer */ + struct ejEval *next; /* used for backtraces */ + const char *procName; /* gives name in backtrace */ } EjsInput; /* diff --git a/source4/lib/appweb/ejs/ejsLex.c b/source4/lib/appweb/ejs/ejsLex.c index a5f15c2979..b4617a638e 100644 --- a/source4/lib/appweb/ejs/ejsLex.c +++ b/source4/lib/appweb/ejs/ejsLex.c @@ -60,11 +60,13 @@ int ejsLexOpenScript(Ejs *ep, char *script) mprAssert(ep); mprAssert(script); - if ((ep->input = mprMalloc(sizeof(EjsInput))) == NULL) { + if ((ip = mprMalloc(sizeof(EjsInput))) == NULL) { return -1; } - ip = ep->input; memset(ip, 0, sizeof(*ip)); + ip->next = ep->input; + ep->input = ip; + ip->procName = ep->proc?ep->proc->procName:NULL; /* * Create the parse token buffer and script buffer @@ -102,6 +104,7 @@ void ejsLexCloseScript(Ejs *ep) ip = ep->input; mprAssert(ip); + ep->input = ip->next; for (i = 0; i < EJS_TOKEN_STACK; i++) { mprFree(ip->putBack[i].token); diff --git a/source4/lib/appweb/ejs/ejsLib.c b/source4/lib/appweb/ejs/ejsLib.c index b3e61ec375..eed6d67fb4 100644 --- a/source4/lib/appweb/ejs/ejsLib.c +++ b/source4/lib/appweb/ejs/ejsLib.c @@ -385,7 +385,6 @@ int ejsEvalBlock(EjsId eid, char *script, MprVar *vp, char **emsg) int ejsEvalScript(EjsId eid, char *script, MprVar *vp, char **emsg) { Ejs *ep; - EjsInput *oldBlock; int state; void *endlessLoopTest; int loopCounter; @@ -408,7 +407,6 @@ int ejsEvalScript(EjsId eid, char *script, MprVar *vp, char **emsg) /* * Allocate a new evaluation block, and save the old one */ - oldBlock = ep->input; ejsLexOpenScript(ep, script); /* @@ -447,11 +445,6 @@ int ejsEvalScript(EjsId eid, char *script, MprVar *vp, char **emsg) *emsg = mprStrdup(ep->error); } - /* - * Restore the old evaluation block - */ - ep->input = oldBlock; - if (state == EJS_STATE_ERR) { return -1; } @@ -475,24 +468,31 @@ static void ejsErrorCore(Ejs* ep, const char *fmt, va_list args) { EjsInput *ip; char *errbuf, *msgbuf; + int frame = 0; mprAssert(ep); msgbuf = NULL; mprAllocVsprintf(&msgbuf, MPR_MAX_STRING, fmt, args); - if (ep) { - ip = ep->input; - if (ip) { - mprAllocSprintf(&errbuf, MPR_MAX_STRING, - "%s\nError on line %d. Offending line: %s\n\n", - msgbuf, ip->lineNumber, ip->line); - } else { - mprAllocSprintf(&errbuf, MPR_MAX_STRING, "%s\n", msgbuf); - } - mprFree(ep->error); - ep->error = errbuf; + ip = ep->input; + mprAllocSprintf(&errbuf, MPR_MAX_STRING, "%s\nBacktrace:\n", msgbuf); + + /* form a backtrace */ + while (ip) { + char *msg2, *ebuf2; + mprAllocSprintf(&msg2, MPR_MAX_STRING, + "\t[%2d] %20s:%-4d -> %s\n", + frame++, ip->procName?ip->procName:"", ip->lineNumber, ip->line); + ebuf2 = mprRealloc(errbuf, strlen(errbuf) + strlen(msg2) + 1); + if (ebuf2 == NULL) break; + errbuf = ebuf2; + memcpy(errbuf+strlen(errbuf), msg2, strlen(msg2)+1); + mprFree(msg2); + ip = ip->next; } + mprFree(ep->error); + ep->error = errbuf; mprFree(msgbuf); } |