summaryrefslogtreecommitdiff
path: root/source4/lib/appweb/ejs-2.0/ejs/ejsCmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/appweb/ejs-2.0/ejs/ejsCmd.c')
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/ejsCmd.c468
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..b5279c949a
--- /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++]), 0);
+ for (; i < argc; i++) {
+ len = mprReallocStrcat(MPR_LOC_ARGS(app), &commandLine, 0, len,
+ " ", argv[i], 0);
+ }
+ 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, 0);
+ }
+ 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, 0);
+
+ } else {
+
+ cmdLen = mprReallocStrcat(MPR_LOC_ARGS(app), &cmd, EJS_MAX_SCRIPT,
+ cmdLen, 0, line, 0);
+
+
+ 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
+ */