From 0253adcab3157ec73cc96ad74b19faa2c87e067a Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 3 Jun 2005 07:47:06 +0000 Subject: r7213: Add a small bit to the ejs parser to ignore a #!/path/to/interpreter as the first line of the script. This allows smbscript to be used as an interpreter. (This used to be commit 875c8164096e7334de25cc57ac4b8bdc39b9c46b) --- source4/lib/ejs/ejs.c | 4 +++- source4/lib/ejs/ejsInternal.h | 5 ++--- source4/lib/ejs/ejsLex.c | 20 ++++++++++++++++++++ source4/lib/ejs/ejsParser.c | 27 +++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/source4/lib/ejs/ejs.c b/source4/lib/ejs/ejs.c index 41af795370..d0eaf6e389 100644 --- a/source4/lib/ejs/ejs.c +++ b/source4/lib/ejs/ejs.c @@ -418,8 +418,10 @@ int ejsEvalScript(EjsId eid, char *script, MprVar *vp, char **emsg) endlessLoopTest = NULL; ep->exitStatus = 0; + ejsParse(ep, EJS_STATE_BEGIN, EJS_FLAGS_EXE); /* Skip over #! */ + do { - state = ejsParse(ep, EJS_STATE_BEGIN, EJS_FLAGS_EXE); + state = ejsParse(ep, EJS_STATE_STMT, EJS_FLAGS_EXE); if (state == EJS_STATE_RET) { state = EJS_STATE_EOF; diff --git a/source4/lib/ejs/ejsInternal.h b/source4/lib/ejs/ejsInternal.h index 4d54c4e8c6..2f776b8b79 100644 --- a/source4/lib/ejs/ejsInternal.h +++ b/source4/lib/ejs/ejsInternal.h @@ -100,7 +100,7 @@ extern "C" { #define EJS_TOK_IN 26 /* in */ #define EJS_TOK_FUNCTION 27 /* function */ #define EJS_TOK_NUMBER 28 /* Number */ - +#define EJS_TOK_HASHBANG 29 /* #!/path/to/interpreter */ /* * Expression operators */ @@ -150,8 +150,7 @@ extern "C" { #define EJS_STATE_DEC 18 /* Declaration statement */ #define EJS_STATE_DEC_DONE 19 #define EJS_STATE_RET 20 /* Return statement */ - -#define EJS_STATE_BEGIN EJS_STATE_STMT +#define EJS_STATE_BEGIN 21 /* Start of script */ /* * General parsing flags. diff --git a/source4/lib/ejs/ejsLex.c b/source4/lib/ejs/ejsLex.c index b0d6483c2a..81f56b092e 100644 --- a/source4/lib/ejs/ejsLex.c +++ b/source4/lib/ejs/ejsLex.c @@ -674,6 +674,26 @@ static int getLexicalToken(Ejs *ep, int state) inputPutback(ep, c); return EJS_TOK_NUMBER; + case '#': + if (ip->lineNumber == 1) { + if ((c = inputGetc(ep)) < 0) { + ejsError(ep, "Syntax Error"); + return EJS_TOK_ERR; + } + if (c != '!') { + ejsError(ep, "Syntax Error"); + return EJS_TOK_ERR; + } + while ((c = inputGetc(ep)) != -1) { + if (c == '\r' || c == '\n') + break; + tokenAddChar(ep, c); + } + return EJS_TOK_HASHBANG; + } + + /* Fall through to default handling */ + default: /* * Identifiers or a function names diff --git a/source4/lib/ejs/ejsParser.c b/source4/lib/ejs/ejsParser.c index 17fe0ce98a..942b08272e 100644 --- a/source4/lib/ejs/ejsParser.c +++ b/source4/lib/ejs/ejsParser.c @@ -67,6 +67,7 @@ static int parseId(Ejs *ep, int state, int flags, char **id, static int parseInc(Ejs *ep, int state, int flags); static int parseIf(Ejs *ep, int state, int flags, int *done); static int parseStmt(Ejs *ep, int state, int flags); +static int parseHashBang(Ejs *ep, int state, int flags); static void removeNewlines(Ejs *ep, int state); static void updateResult(Ejs *ep, int state, int flags, MprVar *vp); @@ -80,6 +81,12 @@ int ejsParse(Ejs *ep, int state, int flags) mprAssert(ep); switch (state) { + /* + * The very start of a script. + */ + case EJS_STATE_BEGIN: + state = parseHashBang(ep, state, flags); + break; /* * Any statement, function arguments or conditional expressions */ @@ -140,6 +147,26 @@ int ejsParse(Ejs *ep, int state, int flags) return state; } +/******************************************************************************/ +/* + * Parse a #!/path/to/interpreter line which we just throw away. + */ + +static int parseHashBang(Ejs *ep, int state, int flags) +{ + int tid; + + /* Look for #! */ + + tid = ejsLexGetToken(ep, state); + + if (tid != EJS_TOK_HASHBANG) { + ejsLexPutbackToken(ep, tid, ep->token); + } + + return EJS_STATE_STMT; +} + /******************************************************************************/ /* * Parse any statement including functions and simple relational operations -- cgit