diff options
Diffstat (limited to 'source4/lib/appweb/ejs-2.0/ejs/ejsCmd.c')
-rw-r--r-- | source4/lib/appweb/ejs-2.0/ejs/ejsCmd.c | 468 |
1 files changed, 468 insertions, 0 deletions
diff --git a/source4/lib/appweb/ejs-2.0/ejs/ejsCmd.c b/source4/lib/appweb/ejs-2.0/ejs/ejsCmd.c new file mode 100644 index 0000000000..74b57de4d0 --- /dev/null +++ b/source4/lib/appweb/ejs-2.0/ejs/ejsCmd.c @@ -0,0 +1,468 @@ +/* + * @file ejsCmd.c + * @brief Embedded JavaScript (EJS) command line program. + * @overview + */ +/********************************* Copyright **********************************/ +/* + * @copy default + * + * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved. + * Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved. + * + * This software is distributed under commercial and open source licenses. + * You may use the GPL open source license described below or you may acquire + * a commercial license from Mbedthis Software. You agree to be fully bound + * by the terms of either license. Consult the LICENSE.TXT distributed with + * this software for full details. + * + * This software is open source; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See the GNU General Public License for more + * details at: http://www.mbedthis.com/downloads/gplLicense.html + * + * This program is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * This GPL license does NOT permit incorporating this software into + * proprietary programs. If you are unable to comply with the GPL, you must + * acquire a commercial license to use this software. Commercial licenses + * for this software and support services are available from Mbedthis + * Software at http://www.mbedthis.com + * + * @end + */ +/********************************** Includes **********************************/ + +#include "ejs.h" + +#if BLD_FEATURE_EJS && !BREW + +/************************************ Defines *********************************/ + +#define EJS_MAX_CMD_LINE (16 * 1024) +#define EJS_MAX_SCRIPT (4 * 1024 * 1024) +#define EJS_MAX_RESULT_SIZE (4 * 1024 * 1024) +#define EJS_PROMPT "ejs> " + +/****************************** Forward Declarations **************************/ + +static int parseFile(EjsService *ejsService, Ejs *ejs, const char *fileName, + const char *testName, MprFile *testLogFile); +static int ifConsole(); + +static int interactiveUse(MprApp *app, Ejs *ejs, FILE *input, + char *fileName); +static char *readCmd(MprApp *app, FILE *input); + +static int memoryFailure(MprApp *app, uint size, uint total, bool granted); + +static int isConsole = 0; +static int traceCmds = 0; +static int stats = 0; +static int verbose = 0; + +/************************************ Main ************************************/ + +int main(int argc, char *argv[]) +{ + MprApp *app; + const char *programName; + MprFile *testLogFile; + EjsService *ejsService; + Ejs *ejs; + char *commandLine; + const char *testName; + char *argp, *cmd, *testLog; + int i, rc, nextArg, err, len, firstArg, iterations, debugLevel; + + app = mprInit(memoryFailure); + + isConsole = ifConsole(); + programName = mprGetBaseName(argv[0]); + debugLevel = 0; + + ejsService = ejsOpenService(app); + if (ejsService == 0) { + mprError(app, MPR_LOC, "Can't initialize the EJS service."); + return -1; + } + + err = 0; + iterations = 1; + stats = 0; + testLog = getenv("TEST_LOG"); + testLogFile = 0; + testName = 0; + + for (nextArg = 1; nextArg < argc; nextArg++) { + argp = argv[nextArg]; + if (*argp != '-') { + break; + } + if (strcmp(argp, "--debug") == 0) { + if (nextArg >= argc) { + err++; + } else { + debugLevel = atoi(argv[++nextArg]); + } + + } else if (strcmp(argp, "--stats") == 0) { + stats++; + + } else if (strcmp(argp, "--trace") == 0) { + traceCmds++; + + } else if (strcmp(argp, "--iterations") == 0) { + if (nextArg >= argc) { + err++; + } else { + iterations = atoi(argv[++nextArg]); + } + + } else if (strcmp(argp, "--log") == 0) { + /* Get file to log test results to when using ejs as a test shell */ + if (nextArg >= argc) { + err++; + } else { + testLog = argv[++nextArg]; + } + + } else if (strcmp(argp, "--testName") == 0) { + if (nextArg >= argc) { + err++; + } else { + testName = argv[++nextArg]; + } + + } else if (strcmp(argp, "-v") == 0) { + verbose++; + + } else if (strcmp(argp, "-vv") == 0) { + verbose += 2; + + } else if (strcmp(argp, "--verbose") == 0) { + verbose += 2; + + } else { + err++; + break; + } + if (err) { + mprErrorPrintf(app, + "Usage: %s [options] files... or\n" + " %s < file or\n" + " %s or\n" + " Switches:\n" + " --iterations num # Number of iterations to eval file\n" + " --stats # Output stats on exit\n" + " --testName name # Set the test name", + programName, programName, programName); + return -1; + } + } + + if (testName) { + i = 0; + commandLine = 0; + len = mprAllocStrcat(MPR_LOC_ARGS(app), &commandLine, 0, " ", + mprGetBaseName(argv[i++]), NULL); + for (; i < argc; i++) { + len = mprReallocStrcat(MPR_LOC_ARGS(app), &commandLine, 0, len, + " ", argv[i], NULL); + } + mprPrintf(app, " %s\n", commandLine); + } + if (testLog) { + testLogFile = mprOpen(app, testLog, + O_CREAT | O_APPEND | O_WRONLY | O_TEXT, 0664); + if (testLogFile == 0) { + mprError(app, MPR_LOC, "Can't open %s", testLog); + return MPR_ERR_CANT_OPEN; + } + mprFprintf(testLogFile, "\n %s\n", commandLine); + } + + ejs = ejsCreateInterp(ejsService, 0, 0, 0, 0); + if (ejs == 0) { + mprError(app, MPR_LOC, "Can't create EJS interpreter"); + ejsCloseService(ejsService, stats); + if (testLogFile) { + mprClose(testLogFile); + } + mprTerm(app, stats); + exit(-1); + } + + if (debugLevel > 0) { + ejsSetGCDebugLevel(ejs, debugLevel); + } + + rc = 0; + + if (nextArg < argc) { + /* + * Process files supplied on the command line + */ + firstArg = nextArg; + for (i = 0; i < iterations; i++) { + for (nextArg = firstArg; nextArg < argc; nextArg++) { + rc = parseFile(ejsService, ejs, argv[nextArg], testName, + testLogFile); + if (rc < 0) { + return rc; + } + } + } + if (testName) { + if (verbose == 1) { + mprPrintf(app, "\n"); + } + if (verbose <= 1) { + mprPrintf(app, " # PASSED all tests for \"%s\"\n", testName); + } + } + + } else if (! isConsole) { + /* + * Read a script from stdin + */ + cmd = readCmd(app, stdin); + + ejsSetFileName(ejs, "stdin"); + + rc = ejsEvalScript(ejs, cmd, 0); + if (rc < 0) { + mprPrintf(app, "ejs: Error: %s\n", ejsGetErrorMsg(ejs)); + } + mprFree(cmd); + + } else { + /* + * Interactive use. Read commands from the command line. + */ + rc = interactiveUse(app, ejs, stdin, "stdin"); + } + + /* + * Cleanup. Do stats if required. + */ + if (ejs) { + ejsCleanInterp(ejs, 0); + ejsCleanInterp(ejs->service->master, 0); + ejsDestroyInterp(ejs, 0); + } + + ejsCloseService(ejsService, stats); + + if (testLogFile) { + mprClose(testLogFile); + } + + mprTerm(app, stats); + return rc; +} + +/******************************************************************************/ + +static int parseFile(EjsService *ejsService, Ejs *ejs, const char *fileName, + const char *testName, MprFile *testLogFile) +{ + int rc; + + if (testName && verbose == 1) { + mprPrintf(ejs, "."); + } + if (verbose > 1) { + mprPrintf(ejs, "File: %s\n", fileName); + } + + rc = ejsEvalFile(ejs, fileName, 0); + + if (testName) { + char fileBuf[MPR_MAX_FNAME], *cp; + mprStrcpy(fileBuf, sizeof(fileBuf), fileName); + if ((cp = strstr(fileBuf, ".ejs")) != 0) { + *cp = '\0'; + } + if (rc == 0) { + if (verbose > 1) { + mprPrintf(ejs, " # PASSED test \"%s.%s\"\n", testName, + fileBuf); + } + if (testLogFile) { + mprFprintf(testLogFile, " # PASSED test \"%s.%s\"\n", + testName, fileBuf); + } + + } else { + + mprPrintf(ejs, "FAILED test \"%s.%s\"\nDetails: %s\n", + testName, fileBuf, ejsGetErrorMsg(ejs)); + + if (testLogFile) { + mprFprintf(testLogFile, + "FAILED test \"%s.%s\"\nDetails: %s\n", + testName, fileBuf, ejsGetErrorMsg(ejs)); + } + } + } else if (rc < 0) { + mprPrintf(ejs, "ejs: %sIn file \"%s\"\n", + ejsGetErrorMsg(ejs), fileName); + } + return rc; +} + +/******************************************************************************/ + +static char *readCmd(MprApp *app, FILE *input) +{ + char line[EJS_MAX_CMD_LINE]; + char *cmd; + int len, cmdLen; + + cmd = 0; + cmdLen = 0; + + line[sizeof(line) - 1] = '\0'; + + while (1) { + + if (fgets(line, sizeof(line) - 1, input) == NULL) { + break; + } + + len = strlen(line); + + if (line[len - 1] == '\\') { + line[len - 1] = '\0'; + } + cmdLen = mprReallocStrcat(MPR_LOC_ARGS(app), &cmd, EJS_MAX_SCRIPT, + cmdLen, 0, line, NULL); + } + return cmd; +} + +/******************************************************************************/ + +static int interactiveUse(MprApp *app, Ejs *ejs, FILE *input, char *fileName) +{ + EjsVar result; + char line[EJS_MAX_CMD_LINE]; + char *cmd, *buf; + int len, cmdLen, rc; + + cmd = 0; + cmdLen = 0; + + line[sizeof(line) - 1] = '\0'; + + ejsSetFileName(ejs, "console"); + + while (! ejsIsExiting(ejs)) { + + if (isConsole) { + write(1, EJS_PROMPT, strlen(EJS_PROMPT)); + } + + if (fgets(line, sizeof(line) - 1, input) == NULL) { + break; + } + + len = strlen(line); + while (len > 0 && + (line[len - 1] == '\n' || line[len - 1] == '\r')) { + len--; + line[len] = '\0'; + } + + if (line[len - 1] == '\\') { + line[len - 1] = '\0'; + cmdLen = mprReallocStrcat(MPR_LOC_ARGS(app), &cmd, EJS_MAX_SCRIPT, + cmdLen, 0, line, NULL); + + } else { + + cmdLen = mprReallocStrcat(MPR_LOC_ARGS(app), &cmd, EJS_MAX_SCRIPT, + cmdLen, 0, line, NULL); + + + if (traceCmds) { + mprPrintf(ejs, "# %s\n", cmd); + } + + if (cmd[0] == 0x4 || cmd[0] == 0x26 || strcmp(cmd, "quit") == 0) { + ejsExit(ejs, 0); + + } else if ((rc = ejsEvalScript(ejs, cmd, &result)) < 0) { + + mprPrintf(app, "ejs: Error: %s\n", ejsGetErrorMsg(ejs)); + + if (! isConsole) { + return rc; + } + + } else { + if (isConsole || traceCmds) { + buf = ejsVarToString(ejs, &result); + mprPrintf(ejs, "%s\n", buf); + } + } + mprFree(cmd); + cmd = 0; + cmdLen = 0; + } + } + return 0; +} + +/******************************************************************************/ + +static int ifConsole() +{ +#if WIN + INPUT_RECORD irec[1]; + int records = 0; + + if (PeekConsoleInput(GetStdHandle(STD_INPUT_HANDLE), irec, 1, + &records) != 0) { + return 1; + } +#else + return isatty(0); +#endif + return 0; +} + +/******************************************************************************/ + +static int memoryFailure(MprApp *app, uint size, uint total, bool granted) +{ + if (!granted) { + mprPrintf(app, "Can't allocate memory block of size %d\n", size); + mprPrintf(app, "Total memory used %d\n", total); + exit(255); + } + mprPrintf(app, "Memory request for %d bytes exceeds memory red-line\n", + size); + mprPrintf(app, "Total memory used %d\n", total); + return 0; +} + +/******************************************************************************/ + +#else +void ejsCmdLineDummy() {} + +/******************************************************************************/ +#endif /* BLD_FEATURE_EJS */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ |