summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/lib/appweb/ejs/ejsInternal.h2
-rw-r--r--source4/lib/appweb/ejs/ejsLex.c7
-rw-r--r--source4/lib/appweb/ejs/ejsLib.c36
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);
}