static void printUsage(Mpr *mpr) { mprPrintfError("usage: makerom [options] files... >output.c\n"); mprPrintfError(" Makerom options:\n"); mprPrintfError(" --prefix prefix # File prefix to remove\n"); mprPrintfError(" --name structName # Name of top level C struct\n"); }
/* * Default memory handler */ static void memoryFailure(MprCtx ctx, int64 size, int64 total, bool granted) { if (!granted) { mprPrintfError(ctx, "Can't allocate memory block of size %d\n", size); mprPrintfError(ctx, "Total memory used %d\n", total); exit(255); } mprPrintfError(ctx, "Memory request for %d bytes exceeds memory red-line\n", size); mprPrintfError(ctx, "Total memory used %d\n", total); }
/* Default log output is just to the console */ static void logHandler(int flags, int level, cchar *msg) { if (flags & MPR_USER_MSG) { MessageBoxEx(NULL, msg, mprGetAppTitle(), MB_OK, 0); } mprWriteToOsLog(msg, 0, 0); mprPrintfError("%s\n", msg); }
/* * Start error and information logging. Note: this is not per-request access logging */ int maStartLogging(MprCtx ctx, cchar *logSpec) { Mpr *mpr; MprFile *file; char *levelSpec, *spec; int level; level = 0; mpr = mprGetMpr(ctx); if (logSpec == 0) { logSpec = "stdout:0"; } if (*logSpec && strcmp(logSpec, "none") != 0) { spec = mprStrdup(mpr, logSpec); if ((levelSpec = strrchr(spec, ':')) != 0 && isdigit((int) levelSpec[1])) { *levelSpec++ = '\0'; level = atoi(levelSpec); } if (strcmp(spec, "stdout") == 0) { file = mpr->fileSystem->stdOutput; } else { if ((file = mprOpen(mpr, spec, O_CREAT | O_WRONLY | O_TRUNC | O_TEXT, 0664)) == 0) { mprPrintfError(mpr, "Can't open log file %s\n", spec); return -1; } } mprSetLogLevel(mpr, level); mprSetLogHandler(mpr, logHandler, (void*) file); mprLog(mpr, MPR_CONFIG, "Configuration for %s", mprGetAppTitle(mpr)); mprLog(mpr, MPR_CONFIG, "---------------------------------------------"); mprLog(mpr, MPR_CONFIG, "Host: %s", mprGetHostName(mpr)); mprLog(mpr, MPR_CONFIG, "CPU: %s", BLD_CPU); mprLog(mpr, MPR_CONFIG, "OS: %s", BLD_OS); if (strcmp(BLD_DIST, "Unknown") != 0) { mprLog(mpr, MPR_CONFIG, "Distribution: %s %s", BLD_DIST, BLD_DIST_VER); } mprLog(mpr, MPR_CONFIG, "Version: %s-%s", BLD_VERSION, BLD_NUMBER); mprLog(mpr, MPR_CONFIG, "BuildType: %s", BLD_TYPE); mprLog(mpr, MPR_CONFIG, "---------------------------------------------"); } return 0; }
static void showUsage() { mprPrintfError("usage: %s [options] [files] url\n" " Options:\n" " --benchmark # Compute benchmark results.\n" " --cert file # Certificate CA file to validate server certs.\n" " --chunk size # Request response data to use this chunk size.\n" " --continue # Continue on errors.\n" " --cookie CookieString # Define a cookie header. Multiple uses okay.\n" " --data bodyData # Body data to send with PUT or POST.\n" " --debugger # Disable timeouts to make running in a debugger easier.\n" " --delete # Use the DELETE method. Shortcut for --method DELETE..\n" " --form string # Form data. Must already be form-www-urlencoded.\n" " --header 'key: value' # Add a custom request header.\n" " --host hostName # Host name or IP address for unqualified URLs.\n" " --insecure # Don't validate server certificates when using SSL\n" " --iterations count # Number of times to fetch the urls (default 1).\n" " --log logFile:level # Log to the file at the verbosity level.\n" " --method KIND # HTTP request method GET|OPTIONS|POST|PUT|TRACE (default GET).\n" " --nofollow # Don't automatically follow redirects.\n" " --noout # Don't output files to stdout.\n" " --out file # Send output to file\n" " --password pass # Password for authentication.\n" " --post # Use POST method. Shortcut for --method POST.\n" " --printable # Make binary output printable.\n" " --protocol PROTO # Set HTTP protocol to HTTP/1.0 or HTTP/1.1 .\n" " --put # Use PUT method. Shortcut for --method PUT.\n" " --range byteRanges # Request a subset range of the document.\n" " --retries count # Number of times to retry failing requests.\n" " --sequence # Sequence requests with a custom header.\n" " --showHeaders # Output response headers.\n" " --showStatus # Output the Http response status code.\n" " --single # Single step. Pause for input between requests.\n" " --threads count # Number of thread instances to spawn.\n" " --timeout secs # Request timeout period in seconds.\n" " --upload # Use multipart mime upload.\n" " --user name # User name for authentication.\n" " --verbose # Verbose operation. Trace progress.\n" " --workers count # Set maximum worker threads.\n" " --zero # Exit with zero status for any valid HTTP response\n" , mprGetAppName()); }
/* * Display the program command line usage */ static int printUsage(Mpr *mpr) { cchar *name; name = mprGetAppName(mpr); mprPrintfError(mpr, "\n\n%s Usage:\n\n" " %s [options]\n" " %s [options] [IPaddress][:port] [documentRoot] \n\n" " Options:\n" " --config configFile # Use named config file instead appweb.conf\n" " --chroot directory # Change root directory to run more securely (Unix)\n" " --debug # Run in debug mode\n" " --ejs appSpec # Create an ejs application at the path\n" " --home directory # Change to directory to run\n" " --name uniqueName # Unique name for this instance\n" " --log logFile:level # Log to file file at verbosity level\n" " --threads maxThreads # Set maximum worker threads\n" " --version # Output version information\n\n" " Without IPaddress, %s will read the appweb.conf configuration file.\n\n", name, name, name, name, name); return MPR_ERR; }
static void usageError(Mpr *mpr) { cchar *name; name = mprGetAppName(); mprPrintfError("\n%s Usage:\n\n" " %s [options] [IPaddress][:port] [documents]\n\n" " Options:\n" " --config configFile # Use named config file instead appweb.conf\n" " --chroot directory # Change root directory to run more securely (Unix)\n" " --debugger # Disable timeouts to make debugging easier\n" " --exe path # Set path to Appweb executable on Vxworks\n" " --home directory # Change to directory to run\n" " --log logFile:level # Log to file file at verbosity level\n" " --name uniqueName # Unique name for this instance\n" " --threads maxThreads # Set maximum worker threads\n" " --verbose # Same as --log stderr:2\n" " --version # Output version information\n\n" " Without IPaddress, %s will read the appweb.conf configuration file.\n\n", mprGetAppTitle(), name, name, name, name); exit(10); }
static int startLogging(Mpr *mpr, char *logSpec) { MprFile *file; char *levelSpec; int level; level = 0; if ((levelSpec = strchr(logSpec, ':')) != 0) { *levelSpec++ = '\0'; level = atoi(levelSpec); } if (strcmp(logSpec, "stdout") == 0) { file = mpr->fileSystem->stdOutput; } else { if ((file = mprOpen(mpr, logSpec, O_CREAT | O_WRONLY | O_TRUNC | O_TEXT, 0664)) == 0) { mprPrintfError(mpr, "Can't open log file %s\n", logSpec); return -1; } } mprSetLogLevel(mpr, level); mprSetLogHandler(mpr, logHandler, (void*) file); return 0; }
static bool parseArgs(int argc, char **argv) { char *argp, *key, *value; int i, setWorkers, nextArg; setWorkers = 0; for (nextArg = 1; nextArg < argc; nextArg++) { argp = argv[nextArg]; if (*argp != '-') { break; } if (smatch(argp, "--benchmark") || smatch(argp, "-b")) { app->benchmark++; } else if (smatch(argp, "--cert")) { if (nextArg >= argc) { return 0; } else { app->cert = sclone(argv[++nextArg]); } } else if (smatch(argp, "--chunk")) { if (nextArg >= argc) { return 0; } else { value = argv[++nextArg]; app->chunkSize = atoi(value); if (app->chunkSize < 0) { mprError("Bad chunksize %d", app->chunkSize); return 0; } } } else if (smatch(argp, "--continue")) { app->continueOnErrors++; } else if (smatch(argp, "--cookie")) { if (nextArg >= argc) { return 0; } else { mprAddItem(app->headers, mprCreateKeyPair("Cookie", argv[++nextArg])); } } else if (smatch(argp, "--data")) { if (nextArg >= argc) { return 0; } else { if (app->bodyData == 0) { app->bodyData = mprCreateBuf(-1, -1); } mprPutStringToBuf(app->bodyData, argv[++nextArg]); } } else if (smatch(argp, "--debugger") || smatch(argp, "-D")) { mprSetDebugMode(1); app->retries = 0; app->timeout = MAXINT; } else if (smatch(argp, "--delete")) { app->method = "DELETE"; } else if (smatch(argp, "--form") || smatch(argp, "-f")) { if (nextArg >= argc) { return 0; } else { if (app->formData == 0) { app->formData = mprCreateList(-1, 0); } addFormVars(argv[++nextArg]); } } else if (smatch(argp, "--header")) { if (nextArg >= argc) { return 0; } else { key = argv[++nextArg]; if ((value = strchr(key, ':')) == 0) { mprError("Bad header format. Must be \"key: value\""); return 0; } *value++ = '\0'; while (isspace((uchar) *value)) { value++; } mprAddItem(app->headers, mprCreateKeyPair(key, value)); } } else if (smatch(argp, "--host")) { if (nextArg >= argc) { return 0; } else { app->host = argv[++nextArg]; if (*app->host == ':') { app->host = &app->host[1]; } if (isPort(app->host)) { app->host = sfmt("http://127.0.0.1:%s", app->host); } else { app->host = sclone(app->host); } } } else if (smatch(argp, "--insecure")) { app->insecure++; } else if (smatch(argp, "--iterations") || smatch(argp, "-i")) { if (nextArg >= argc) { return 0; } else { app->iterations = atoi(argv[++nextArg]); } } else if (smatch(argp, "--log") || smatch(argp, "-l")) { if (nextArg >= argc) { return 0; } else { mprStartLogging(argv[++nextArg], 0); } } else if (smatch(argp, "--method") || smatch(argp, "-m")) { if (nextArg >= argc) { return 0; } else { app->method = argv[++nextArg]; } } else if (smatch(argp, "--out") || smatch(argp, "-o")) { if (nextArg >= argc) { return 0; } else { app->outFilename = sclone(argv[++nextArg]); } } else if (smatch(argp, "--noout") || smatch(argp, "-n") || smatch(argp, "--quiet") || smatch(argp, "-q")) { app->noout++; } else if (smatch(argp, "--nofollow")) { app->nofollow++; } else if (smatch(argp, "--password") || smatch(argp, "-p")) { if (nextArg >= argc) { return 0; } else { app->password = sclone(argv[++nextArg]); } } else if (smatch(argp, "--post")) { app->method = "POST"; } else if (smatch(argp, "--printable")) { app->printable++; } else if (smatch(argp, "--protocol")) { if (nextArg >= argc) { return 0; } else { app->protocol = supper(argv[++nextArg]); } } else if (smatch(argp, "--put")) { app->method = "PUT"; } else if (smatch(argp, "--range")) { if (nextArg >= argc) { return 0; } else { // TODO - should allow multiple ranges if (app->ranges == 0) { app->ranges = sfmt("bytes=%s", argv[++nextArg]); } else { app->ranges = srejoin(app->ranges, ",", argv[++nextArg], NULL); } } } else if (smatch(argp, "--retries") || smatch(argp, "-r")) { if (nextArg >= argc) { return 0; } else { app->retries = atoi(argv[++nextArg]); } } else if (smatch(argp, "--sequence")) { app->sequence++; } else if (smatch(argp, "--showHeaders") || smatch(argp, "--show") || smatch(argp, "-s")) { app->showHeaders++; } else if (smatch(argp, "--showStatus") || smatch(argp, "--showCode")) { app->showStatus++; } else if (smatch(argp, "--single") || smatch(argp, "-s")) { app->singleStep++; } else if (smatch(argp, "--text")) { app->text++; } else if (smatch(argp, "--threads") || smatch(argp, "-t")) { if (nextArg >= argc) { return 0; } else { app->loadThreads = atoi(argv[++nextArg]); } } else if (smatch(argp, "--timeout")) { if (nextArg >= argc) { return 0; } else { app->timeout = atoi(argv[++nextArg]) * MPR_TICKS_PER_SEC; } } else if (smatch(argp, "--upload") || smatch(argp, "-u")) { app->upload++; } else if (smatch(argp, "--user") || smatch(argp, "--username")) { if (nextArg >= argc) { return 0; } else { app->username = argv[++nextArg]; } } else if (smatch(argp, "--verbose") || smatch(argp, "-v")) { app->verbose++; } else if (smatch(argp, "--version") || smatch(argp, "-V")) { mprPrintfError("%s %s\n" "Copyright (C) Embedthis Software 2003-2012\n" "Copyright (C) Michael O'Brien 2003-2012\n", BIT_NAME, BIT_VERSION); exit(0); } else if (smatch(argp, "--workerTheads") || smatch(argp, "-w")) { if (nextArg >= argc) { return 0; } else { app->workers = atoi(argv[++nextArg]); } setWorkers++; } else if (smatch(argp, "--zero")) { app->zeroOnErrors++; } else if (smatch(argp, "--")) { nextArg++; break; } else if (smatch(argp, "-")) { break; } else { return 0; break; } } if (argc == nextArg) { return 0; } app->nextArg = nextArg; argc = argc - nextArg; argv = &argv[nextArg]; app->target = argv[argc - 1]; app->iterations *= app->loadThreads; if (--argc > 0) { /* Files present on command line */ app->files = mprCreateList(argc, MPR_LIST_STATIC_VALUES); for (i = 0; i < argc; i++) { mprAddItem(app->files, argv[i]); } } if (!setWorkers) { app->workers = app->loadThreads + 2; } if (app->method == 0) { if (app->bodyData || app->formData || app->upload) { app->method = "POST"; } else if (app->files) { app->method = "PUT"; } else { app->method = "GET"; } } return 1; }
MAIN(appweb, int argc, char **argv) { Mpr *mpr; MaHttp *http; cchar *ipAddrPort, *documentRoot, *argp, *logSpec; char *configFile, *ipAddr, *homeDir, *timeText, *ejsPrefix, *ejsPath, *changeRoot; int workers, outputVersion, argind, port; documentRoot = 0; changeRoot = ejsPrefix = ejsPath = 0; ipAddrPort = 0; ipAddr = 0; port = -1; logSpec = 0; server = 0; outputVersion = 0; workers = -1; configFile = BLD_FEATURE_CONFIG_FILE; homeDir = BLD_FEATURE_SERVER_ROOT; mpr = mprCreate(argc, argv, memoryFailure); argc = mpr->argc; argv = mpr->argv; #if BLD_FEATURE_ROMFS extern MprRomInode romFiles[]; mprSetRomFileSystem(mpr, romFiles); #endif if (osInit(mpr) < 0) { exit(2); } if (mprStart(mpr, 0) < 0) { mprUserError(mpr, "Can't start MPR for %s", mprGetAppName(mpr)); mprFree(mpr); return MPR_ERR_CANT_INITIALIZE; } for (argind = 1; argind < argc; argind++) { argp = argv[argind]; if (*argp != '-') { break; } if (strcmp(argp, "--config") == 0) { if (argind >= argc) { return printUsage(mpr); } configFile = argv[++argind]; #if BLD_UNIX_LIKE } else if (strcmp(argp, "--chroot") == 0) { if (argind >= argc) { return printUsage(mpr); } changeRoot = mprGetAbsPath(mpr, argv[++argind]); #endif } else if (strcmp(argp, "--debug") == 0 || strcmp(argp, "-D") == 0 || strcmp(argp, "-d") == 0 || strcmp(argp, "--debugger") == 0) { mprSetDebugMode(mpr, 1); } else if (strcmp(argp, "--ejs") == 0) { if (argind >= argc) { return printUsage(mpr); } ejsPrefix = mprStrdup(mpr, argv[++argind]); if ((ejsPath = strchr(ejsPrefix, ':')) != 0) { *ejsPath++ = '\0'; } ejsPath = mprGetAbsPath(mpr, ejsPath); } else if (strcmp(argp, "--home") == 0) { if (argind >= argc) { return printUsage(mpr); } homeDir = mprGetAbsPath(mpr, argv[++argind]); if (chdir((char*) homeDir) < 0) { mprPrintfError(mpr, "%s: Can't change directory to %s\n", mprGetAppName(mpr), homeDir); exit(2); } } else if (strcmp(argp, "--log") == 0 || strcmp(argp, "-l") == 0) { if (argind >= argc) { return printUsage(mpr); } logSpec = argv[++argind]; maStartLogging(mpr, logSpec); } else if (strcmp(argp, "--name") == 0 || strcmp(argp, "-n") == 0) { if (argind >= argc) { return printUsage(mpr); } mprSetAppName(mpr, argv[++argind], 0, 0); } else if (strcmp(argp, "--threads") == 0) { if (argind >= argc) { return printUsage(mpr); } workers = atoi(argv[++argind]); } else if (strcmp(argp, "--verbose") == 0 || strcmp(argp, "-v") == 0) { maStartLogging(mpr, "stdout:2"); } else if (strcmp(argp, "--version") == 0 || strcmp(argp, "-V") == 0) { outputVersion++; } else { mprPrintfError(mpr, "Unknown switch \"%s\"\n", argp); printUsage(mpr); exit(2); } } if (argc > argind) { if (argc > (argind + 2)) { return printUsage(mpr); } ipAddrPort = argv[argind++]; if (argc > argind) { documentRoot = argv[argind++]; } else { documentRoot = "."; } } if (outputVersion) { mprPrintf(mpr, "%s %s-%s\n", mprGetAppTitle(mpr), BLD_VERSION, BLD_NUMBER); exit(0); } if (ipAddrPort) { mprParseIp(mpr, ipAddrPort, &ipAddr, &port, MA_SERVER_DEFAULT_PORT_NUM); } else { #if BLD_FEATURE_CONFIG_PARSE if (configFile == 0) { configFile = mprStrcat(mpr, -1, mprGetAppName(mpr), ".conf", NULL); } if (!mprPathExists(mpr, configFile, R_OK)) { mprPrintfError(mpr, "Can't open config file %s\n", configFile); exit(2); } #else return printUsage(mpr); #endif #if !BLD_FEATURE_ROMFS if (homeDir == 0) { homeDir = mprGetPathParent(mpr, configFile); if (chdir((char*) homeDir) < 0) { mprPrintfError(mpr, "%s: Can't change directory to %s\n", mprGetAppName(mpr), homeDir); exit(2); } } #endif } homeDir = mprGetCurrentPath(mpr); if (checkEnvironment(mpr, argv[0], homeDir) < 0) { exit(3); } #if BLD_UNIX_LIKE if (changeRoot) { homeDir = mprGetAbsPath(mpr, changeRoot); if (chdir(homeDir) < 0) { mprError(mpr, "%s: Can't change directory to %s", homeDir); exit(4); } if (chroot(homeDir) < 0) { if (errno == EPERM) { mprError(mpr, "%s: Must be super user to use the --chroot option", mprGetAppName(mpr)); } else { mprError(mpr, "%s: Can't change change root directory to %s, errno %d", mprGetAppName(mpr), homeDir, errno); } exit(5); } } #endif /* * Create the top level HTTP service and default HTTP server. Set the initial server root to "." */ http = maCreateHttp(mpr); if (http == 0) { mprUserError(mpr, "Can't create HTTP service for %s", mprGetAppName(mpr)); return MPR_ERR_CANT_INITIALIZE; } server = maCreateServer(http, "default", ".", 0, -1); if (server == 0) { mprUserError(mpr, "Can't create HTTP server for %s", mprGetAppName(mpr)); return MPR_ERR_CANT_INITIALIZE; } if (maConfigureServer(mpr, http, server, configFile, ipAddr, port, documentRoot) < 0) { /* mprUserError(mpr, "Can't configure the server, exiting."); */ exit(6); } if (mpr->ipAddr) { mprLog(mpr, 2, "Server IP address %s", mpr->ipAddr); } timeText = mprFormatLocalTime(mpr, mprGetTime(mpr)); mprLog(mpr, 1, "Started at %s", timeText); mprFree(timeText); #if BLD_FEATURE_EJS if (ejsPrefix) { createEjsAlias(mpr, http, server, ejsPrefix, ejsPath); } #endif #if BLD_FEATURE_MULTITHREAD if (workers >= 0) { mprSetMaxWorkers(http, workers); } #endif #if BLD_WIN_LIKE if (!ejsPrefix) { writePort(server->defaultHost); } #endif if (maStartHttp(http) < 0) { mprUserError(mpr, "Can't start HTTP service, exiting."); exit(7); } #if BLD_FEATURE_MULTITHREAD mprLog(mpr, 1, "HTTP services are ready with max %d worker threads", mprGetMaxWorkers(mpr)); #else mprLog(mpr, 1, "HTTP services are ready (single-threaded)"); #endif /* * Service I/O events until instructed to exit */ while (!mprIsExiting(mpr)) { mprServiceEvents(mpr->dispatcher, -1, MPR_SERVICE_EVENTS | MPR_SERVICE_IO); } /* * Signal a graceful shutdown */ mprLog(http, 1, "Exiting ..."); maStopHttp(http); mprLog(http, 1, "Exit complete"); #if VXWORKS if (mprStop(mpr)) { mprFree(mpr); } #endif return 0; }
MAIN(ejsMain, int argc, char **argv) #endif { Mpr *mpr; EcCompiler *cp; EjsService *vmService; Ejs *ejs; MprList *useModules, *files; cchar *cmd, *className, *methodName; char *argp, *searchPath, *modules, *name, *tok, *extraFiles, *spec; int nextArg, err, ecFlags, run, merge, bind, noout, debug, optimizeLevel, warnLevel; int compilerMode, lang; /* * Create the Embedthis Portable Runtime (MPR) and setup a memory failure handler */ mpr = mprCreate(argc, argv, ejsMemoryFailure); mprSetAppName(mpr, argv[0], 0, 0); setupSignals(); if (mprStart(mpr, MPR_START_EVENTS_THREAD) < 0) { mprError(mpr, "Can't start mpr services"); return EJS_ERR; } err = 0; className = 0; cmd = 0; methodName = 0; searchPath = 0; run = 1; merge = 0; bind = 1; noout = 1; debug = 1; warnLevel = 1; optimizeLevel = 9; compilerMode = PRAGMA_MODE_STANDARD; lang = BLD_FEATURE_EJS_LANG; useModules = mprCreateList(mpr); files = mprCreateList(mpr); for (nextArg = 1; nextArg < argc; nextArg++) { argp = argv[nextArg]; if (*argp != '-') { break; } if (strcmp(argp, "--bind") == 0) { bind = 1; } else if (strcmp(argp, "--class") == 0) { if (nextArg >= argc) { err++; } else { className = argv[++nextArg]; } } else if (strcmp(argp, "--cmd") == 0 || strcmp(argp, "-c") == 0) { if (nextArg >= argc) { err++; } else { cmd = argv[++nextArg]; } } else if (strcmp(argp, "--debug") == 0) { debug = 1; } else if (strcmp(argp, "--lang") == 0) { if (nextArg >= argc) { err++; } else { spec = argv[++nextArg]; if (mprStrcmpAnyCase(spec, "ecma") == 0) { lang = EJS_SPEC_ECMA; } else if (mprStrcmpAnyCase(spec, "plus") == 0) { lang = EJS_SPEC_PLUS; } else if (mprStrcmpAnyCase(spec, "fixed") == 0) { lang = EJS_SPEC_FIXED; } } } else if (strcmp(argp, "--files") == 0 || strcmp(argp, "-f") == 0) { /* Compatibility with mozilla shell */ if (nextArg >= argc) { err++; } else { extraFiles = mprStrdup(mpr, argv[++nextArg]); name = mprStrTok(extraFiles, " \t", &tok); while (name != NULL) { mprAddItem(files, name); name = mprStrTok(NULL, " \t", &tok); } } } else if (strcmp(argp, "--log") == 0) { if (nextArg >= argc) { err++; } else { ejsStartLogging(mpr, argv[++nextArg]); } } else if (strcmp(argp, "--method") == 0) { if (nextArg >= argc) { err++; } else { methodName = argv[++nextArg]; } } else if (strcmp(argp, "--nobind") == 0) { bind = 0; } else if (strcmp(argp, "--nodebug") == 0) { debug = 0; } else if (strcmp(argp, "--optimize") == 0) { if (nextArg >= argc) { err++; } else { optimizeLevel = atoi(argv[++nextArg]); } } else if (strcmp(argp, "-s") == 0) { /* Compatibility with mozilla shell. Just ignore */ } else if (strcmp(argp, "--search") == 0 || strcmp(argp, "--searchpath") == 0) { if (nextArg >= argc) { err++; } else { searchPath = argv[++nextArg]; } } else if (strcmp(argp, "--standard") == 0) { compilerMode = PRAGMA_MODE_STANDARD; } else if (strcmp(argp, "--strict") == 0) { compilerMode = PRAGMA_MODE_STRICT; } else if (strcmp(argp, "--use") == 0) { if (nextArg >= argc) { err++; } else { modules = mprStrdup(mpr, argv[++nextArg]); name = mprStrTok(modules, " \t", &tok); while (name != NULL) { mprAddItem(useModules, name); name = mprStrTok(NULL, " \t", &tok); } } } else if (strcmp(argp, "--version") == 0 || strcmp(argp, "-V") == 0) { mprPrintfError(mpr, "%s %s-%s\n", BLD_NAME, BLD_VERSION, BLD_NUMBER); return 0; } else if (strcmp(argp, "--warn") == 0) { if (nextArg >= argc) { err++; } else { warnLevel = atoi(argv[++nextArg]); } } else { err++; break; } } if (err) { /* * If --method or --class is specified, then the named class.method will be run (method defaults to "main", class * defaults to first class with a "main"). * * Examples: * ejs * ejs script.es arg1 arg2 arg3 * ejs --class "Customer" --method "start" --files "script1.es script2.es" main.es */ mprPrintfError(mpr, "Usage: %s [options] script.es [arguments] ...\n" " Ejscript shell program options:\n" " --class className # Name of class containing method to run\n" " --cmd ejscriptCode # Literal ejscript statements to execute\n" " --debug # Use symbolic debugging information (default)\n" " --files \"files..\" # Extra source to compile\n" " --lang # Language compliance (ecma|plus|fixed)\n" " --log logSpec # Internal compiler diagnostics logging\n" " --method methodName # Name of method to run. Defaults to main\n" " --nodebug # Omit symbolic debugging information\n" " --optimize level # Set the optimization level (0-9 default is 9)\n" " --search ejsPath # Module search path\n" " --standard # Default compilation mode to standard (default)\n" " --strict # Default compilation mode to strict\n" " --use 'module, ...' # List of modules to pre-load\n" " --version # Emit the compiler version information\n" " --warn level # Set the warning message level (0-9 default is 0)\n\n", mpr->name); return -1; } vmService = ejsCreateService(mpr); if (vmService == 0) { return MPR_ERR_NO_MEMORY; } ecInitCompiler(vmService); ejs = ejsCreate(vmService, NULL, searchPath, 0); if (ejs == 0) { return MPR_ERR_NO_MEMORY; } ecFlags = 0; ecFlags |= (run) ? EC_FLAGS_RUN: 0; ecFlags |= (merge) ? EC_FLAGS_MERGE: 0; ecFlags |= (bind) ? EC_FLAGS_BIND: 0; ecFlags |= (noout) ? EC_FLAGS_NO_OUT: 0; ecFlags |= (debug) ? EC_FLAGS_DEBUG: 0; cp = ecCreateCompiler(ejs, ecFlags, lang); if (cp == 0) { return MPR_ERR_NO_MEMORY; } ecSetOptimizeLevel(cp, optimizeLevel); ecSetWarnLevel(cp, warnLevel); ecSetDefaultMode(cp, compilerMode); if (preloadModules(cp, useModules) < 0) { return EJS_ERR; } if (nextArg < argc) { mprAddItem(files, argv[nextArg]); } if (cmd) { if (interpretCommands(cp, cmd) < 0) { err++; } } else if (mprGetListCount(files) > 0) { if (interpretFiles(cp, files, argc - nextArg, &argv[nextArg], className, methodName, lang) < 0) { err++; } } else { /* * No args - run as an interactive shell */ if (interpretCommands(cp, NULL) < 0) { err++; } } #if VXWORKS mprFree(cp); mprFree(ejs); if (mprStop(mpr)) { mprFree(mpr); } #endif return err; }
static int startProcess(MprCmd *cmd) { MprCmdFile *files; int rc, i, err; files = cmd->files; /* * Create the child */ cmd->pid = vfork(); if (cmd->pid < 0) { mprError(cmd, "start: can't fork a new process to run %s, errno %d", cmd->program, mprGetOsError()); return MPR_ERR_CANT_INITIALIZE; } else if (cmd->pid == 0) { /* * Child */ umask(022); if (cmd->flags & MPR_CMD_NEW_SESSION) { setsid(); } if (cmd->dir) { if (chdir(cmd->dir) < 0) { mprLog(cmd, 0, "cmd: Can't change directory to %s", cmd->dir); return MPR_ERR_CANT_INITIALIZE; } } if (cmd->flags & MPR_CMD_IN) { if (files[MPR_CMD_STDIN].clientFd >= 0) { rc = dup2(files[MPR_CMD_STDIN].clientFd, 0); close(files[MPR_CMD_STDIN].fd); } else { close(0); } } if (cmd->flags & MPR_CMD_OUT) { if (files[MPR_CMD_STDOUT].clientFd >= 0) { rc = dup2(files[MPR_CMD_STDOUT].clientFd, 1); close(files[MPR_CMD_STDOUT].fd); } else { close(1); } } if (cmd->flags & MPR_CMD_ERR) { if (files[MPR_CMD_STDERR].clientFd >= 0) { rc = dup2(files[MPR_CMD_STDERR].clientFd, 2); close(files[MPR_CMD_STDERR].fd); } else { close(2); } } cmd->forkCallback(cmd->forkData); if (cmd->env) { rc = execve(cmd->program, cmd->argv, fixenv(cmd)); } else { rc = execv(cmd->program, cmd->argv); } err = errno; mprPrintfError(cmd, "Can't exec %s, err %d, cwd %s\n", cmd->program, err, mprGetCurrentPath(cmd)); /* * Use _exit to avoid flushing I/O any other I/O. */ _exit(-(MPR_ERR_CANT_INITIALIZE)); } else { /* * Close the client handles */ for (i = 0; i < MPR_CMD_MAX_PIPE; i++) { if (files[i].clientFd >= 0) { close(files[i].clientFd); files[i].clientFd = -1; } } } rc = 0; return rc; }
MAIN(ejsMain, int argc, char **argv, char **envp) { Mpr *mpr; Ejs *ejs; EcCompiler *ec; char *argp, *searchPath, *path, *homeDir; int nextArg, err, flags; /* Initialize Multithreaded Portable Runtime (MPR) */ mpr = mprCreate(argc, argv, 0); app = mprAllocObj(App, manageApp); mprAddRoot(app); mprAddStandardSignals(); if (mprStart(mpr) < 0) { mprError("Can't start mpr services"); return EJS_ERR; } err = 0; searchPath = 0; argc = mpr->argc; argv = (char**) mpr->argv; for (nextArg = 1; nextArg < argc; nextArg++) { argp = argv[nextArg]; if (*argp != '-') { break; } if (smatch(argp, "--chdir") || smatch(argp, "--home") || smatch(argp, "-C")) { if (nextArg >= argc) { err++; } else { homeDir = argv[++nextArg]; if (chdir((char*) homeDir) < 0) { mprError("Can't change directory to %s", homeDir); } } } else if (smatch(argp, "--debugger") || smatch(argp, "-D")) { mprSetDebugMode(1); } else if (smatch(argp, "--log")) { if (nextArg >= argc) { err++; } else { mprStartLogging(argv[++nextArg], 0); mprSetCmdlineLogging(1); } } else if (smatch(argp, "--name")) { /* Just ignore. Used to tag commands with a unique command line */ nextArg++; } else if (smatch(argp, "--search") || smatch(argp, "--searchpath")) { if (nextArg >= argc) { err++; } else { searchPath = argv[++nextArg]; } } else if (smatch(argp, "--verbose") || smatch(argp, "-v")) { mprStartLogging("stderr:1", 0); mprSetCmdlineLogging(1); } else if (smatch(argp, "--version") || smatch(argp, "-V")) { mprPrintfError("%s %s-%s\n", BIT_NAME, BIT_VERSION, BIT_NUMBER); return 0; } else { /* Ignore */ } } path = mprJoinPath(mprGetAppDir(), mprGetPathBase(argv[0])); path = mprReplacePathExt(path, ".es"); mprAddRoot(path); argv[0] = path; if ((ejs = ejsCreateVM(argc, (cchar **) &argv[0], 0)) == 0) { return MPR_ERR_MEMORY; } app->ejs = ejs; if (ejsLoadModules(ejs, searchPath, NULL) < 0) { return MPR_ERR_CANT_READ; } mprLog(2, "Load script \"%s\"", path); flags = EC_FLAGS_BIND | EC_FLAGS_DEBUG | EC_FLAGS_NO_OUT | EC_FLAGS_THROW; #if UNUSED if (ejsLoadScriptFile(ejs, path, NULL, flags) < 0) { ejsReportError(ejs, "Error in script"); err = MPR_ERR; } #else if ((ec = ecCreateCompiler(ejs, flags)) == 0) { return MPR_ERR_MEMORY; } mprAddRoot(ec); ecSetOptimizeLevel(ec, 9); ecSetWarnLevel(ec, 1); if (ecCompile(ec, 1, (char**) &path) < 0) { if (flags & EC_FLAGS_THROW) { ejsThrowSyntaxError(ejs, "%s", ec->errorMsg ? ec->errorMsg : "Can't parse script"); ejsReportError(ejs, "Error in script"); } err = MPR_ERR; } else { mprRemoveRoot(ec); if (ejsRunProgram(ejs, NULL, NULL) < 0) { ejsReportError(ejs, "Error in script"); err = MPR_ERR; } } #endif if (!err) { err = mpr->exitStatus; } app->ejs = 0; mprTerminate(MPR_EXIT_DEFAULT, err); ejsDestroyVM(ejs); mprDestroy(MPR_EXIT_DEFAULT); return err; }
MAIN(ejscMain, int argc, char **argv) #endif { Mpr *mpr; Ejs *ejs; EcCompiler *cp; EjsService *vmService; MprList *useModules; char *argp, *searchPath, *outputFile, *certFile, *name, *tok, *modules, *spec; int nextArg, err, ejsFlags, ecFlags, bind, debug, doc, empty, merge; int warnLevel, noout, parseOnly, tabWidth, optimizeLevel, compilerMode, lang; /* * Create the Embedthis Portable Runtime (MPR) and setup a memory failure handler */ mpr = mprCreate(argc, argv, ejsMemoryFailure); mprSetAppName(mpr, argv[0], 0, 0); if (mprStart(mpr, 0) < 0) { mprError(mpr, "Can't start mpr services"); return EJS_ERR; } err = 0; searchPath = 0; compilerMode = PRAGMA_MODE_STANDARD; certFile = 0; ecFlags = 0; bind = 0; debug = 0; doc = 0; empty = 0; merge = 0; noout = 0; parseOnly = 0; tabWidth = 4; warnLevel = 1; outputFile = 0; optimizeLevel = 9; lang = BLD_FEATURE_EJS_LANG; useModules = mprCreateList(mpr); for (nextArg = 1; nextArg < argc; nextArg++) { argp = argv[nextArg]; if (*argp != '-') { break; } if (strcmp(argp, "--bind") == 0) { bind = 1; } else if (strcmp(argp, "--debug") == 0) { debug = 1; } else if (strcmp(argp, "--doc") == 0) { doc = 1; } else if (strcmp(argp, "--lang") == 0) { if (nextArg >= argc) { err++; } else { spec = argv[++nextArg]; if (mprStrcmpAnyCase(spec, "ecma") == 0) { lang = EJS_SPEC_ECMA; } else if (mprStrcmpAnyCase(spec, "plus") == 0) { lang = EJS_SPEC_PLUS; } else if (mprStrcmpAnyCase(spec, "fixed") == 0) { lang = EJS_SPEC_FIXED; } } } else if (strcmp(argp, "--empty") == 0) { empty = 1; } else if (strcmp(argp, "--log") == 0) { /* * Undocumented logging switch */ if (nextArg >= argc) { err++; } else { ejsStartLogging(mpr, argv[++nextArg]); } } else if (strcmp(argp, "--merge") == 0) { merge = 1; } else if (strcmp(argp, "--nobind") == 0) { bind = 0; } else if (strcmp(argp, "--noout") == 0) { noout = 1; } else if (strcmp(argp, "--standard") == 0) { compilerMode = PRAGMA_MODE_STANDARD; } else if (strcmp(argp, "--strict") == 0) { compilerMode = PRAGMA_MODE_STRICT; } else if (strcmp(argp, "--optimize") == 0) { if (nextArg >= argc) { err++; } else { optimizeLevel = atoi(argv[++nextArg]); } } else if (strcmp(argp, "--out") == 0) { /* * Create a single output module file containing all modules */ if (nextArg >= argc) { err++; } else { outputFile = argv[++nextArg]; } } else if (strcmp(argp, "--parse") == 0) { parseOnly = 1; } else if (strcmp(argp, "--search") == 0 || strcmp(argp, "--searchpath") == 0) { if (nextArg >= argc) { err++; } else { searchPath = argv[++nextArg]; } } else if (strcmp(argp, "--sign") == 0) { if (nextArg >= argc) { err++; } else { certFile = argv[++nextArg]; } } else if (strcmp(argp, "--tabWidth") == 0) { if (nextArg >= argc) { err++; } else { tabWidth = atoi(argv[++nextArg]); } } else if (strcmp(argp, "--use") == 0) { if (nextArg >= argc) { err++; } else { modules = mprStrdup(mpr, argv[++nextArg]); name = mprStrTok(modules, " \t", &tok); while (name != NULL) { mprAddItem(useModules, name); name = mprStrTok(NULL, " \t", &tok); } } } else if (strcmp(argp, "--version") == 0 || strcmp(argp, "-V") == 0) { mprPrintfError(mpr, "%s %s-%s\n", BLD_NAME, BLD_VERSION, BLD_VERSION); return 0; } else if (strcmp(argp, "--warn") == 0) { if (nextArg >= argc) { err++; } else { warnLevel = atoi(argv[++nextArg]); } #if BLD_FEATURE_EJS_WEB } else if (strcmp(argp, "--web") == 0) { #if BLD_FEATURE_EJS_DB mprAddItem(useModules, "ejs.db"); #endif mprAddItem(useModules, "ejs.web"); #endif } else { err++; break; } } if (noout || merge) { bind = 1; } if (outputFile && noout) { mprPrintfError(mpr, "Can't use --out and --noout\n"); err++; } if (argc == nextArg) { err++; } if (err) { /* * Usage Examples: * ejsc Person.es User.es Customer.es * ejsc --out group.mod Person.es User.es Customer.es * ejsc --out group.mod Person.es User.es Customer.es */ mprPrintfError(mpr, "Usage: %s [options] files...\n" " Ejscript compiler options:\n" " --bind # Bind global properties to slots. Requires --out.\n" " --debug # Include symbolic debugging information in output\n" " --doc # Include documentation strings in output\n" " --lang # Language compliance (ecma|plus|fixed)\n" " --empty # Create empty interpreter\n" " --merge # Merge dependent input modules into the output\n" " --noout # Do not generate any output\n" " --optimize level # Set optimization level (0-9)\n" " --out filename # Name a single output module (default: \"default.mod\")\n" " --parse # Just parse source. No output\n" " --search ejsPath # Module search path\n" " --standard # Default compilation mode to standard (default)\n" " --strict # Default compilation mode to strict\n" #if FUTURE " --sign certFile # Sign the module file (not implemented) \n" " --tabwidth # Tab width for '^' error reporting\n" #endif " --use 'module, ...' # List of modules to pre-load\n" " --version # Emit the compiler version information\n" " --warn level # Set the warning message level (0-9)\n\n", mpr->name); return -1; } /* * Need an interpreter when compiling */ vmService = ejsCreateService(mpr); if (vmService == 0) { return MPR_ERR_NO_MEMORY; } ejsFlags = EJS_FLAG_NO_EXE; if (empty) { ejsFlags |= EJS_FLAG_EMPTY; } if (doc) { ejsFlags |= EJS_FLAG_DOC; } ejs = ejsCreate(vmService, NULL, searchPath, ejsFlags); if (ejs == 0) { return MPR_ERR_NO_MEMORY; } ecFlags = 0; ecFlags |= (debug) ? EC_FLAGS_DEBUG: 0; ecFlags |= (empty) ? EC_FLAGS_EMPTY: 0; ecFlags |= (merge) ? EC_FLAGS_MERGE: 0; ecFlags |= (bind) ? EC_FLAGS_BIND: 0; ecFlags |= (noout) ? EC_FLAGS_NO_OUT: 0; ecFlags |= (parseOnly) ? EC_FLAGS_PARSE_ONLY: 0; cp = ecCreateCompiler(ejs, ecFlags, lang); if (cp == 0) { return MPR_ERR_NO_MEMORY; } ecSetOptimizeLevel(cp, optimizeLevel); ecSetWarnLevel(cp, warnLevel); ecSetDefaultMode(cp, compilerMode); ecSetTabWidth(cp, tabWidth); ecSetOutputFile(cp, outputFile); ecSetCertFile(cp, certFile); if (preloadModules(cp, useModules) < 0) { return EJS_ERR; } if (nextArg < argc) { /* * Compile the source files supplied on the command line. This will compile in-memory and * optionally also save to module files. */ if (ecCompile(cp, argc - nextArg, &argv[nextArg], 0) < 0) { err++; } } if (cp->errorCount > 0) { err++; } #if VXWORKS mprFree(cp); mprFree(ejs); if (mprStop(mpr)) { mprFree(mpr); } #endif return err; }
MAIN(ejsmodMain, int argc, char **argv, char **envp) { Mpr *mpr; EjsMod *mp; Ejs *ejs; MprList *requiredModules; char *argp, *searchPath, *output, *modules, *name, *tok; int nextArg, err, flags; err = 0; output = searchPath = 0; requiredModules = 0; /* Initialze the Multithreaded Portable Runtime (MPR) */ mpr = mprCreate(argc, argv, 0); mprSetAppName(argv[0], 0, 0); /* Allocate the primary control structure */ if ((mp = mprAllocObj(EjsMod, manageMod)) == NULL) { return MPR_ERR_MEMORY; } mprAddRoot(mp); mp->lstRecords = mprCreateList(0, 0); mp->blocks = mprCreateList(0, 0); mp->docDir = sclone("."); mp->outputDir = sclone("."); for (nextArg = 1; nextArg < argc; nextArg++) { argp = argv[nextArg]; if (*argp != '-') { break; } if (strcmp(argp, "--cslots") == 0) { mp->cslots = 1; mp->genSlots = 1; } else if (strcmp(argp, "--debugger") == 0 || strcmp(argp, "-D") == 0) { mprSetDebugMode(1); } else if (strcmp(argp, "--depends") == 0) { mp->depends = 1; } else if (strcmp(argp, "--dir") == 0) { if (nextArg >= argc) { err++; } else { mp->outputDir = sclone(argv[++nextArg]); } } else if (strcmp(argp, "--error") == 0) { /* Undocumented switch */ mp->exitOnError++; mp->warnOnError++; } else if (strcmp(argp, "--html") == 0) { if (nextArg >= argc) { err++; } else { mp->docDir = sclone(argv[++nextArg]); mp->html = 1; } } else if (strcmp(argp, "--listing") == 0) { mp->listing = 1; mp->showAsm = 1; } else if (strcmp(argp, "--log") == 0) { /* Undocumented switch */ if (nextArg >= argc) { err++; } else { mprStartLogging(argv[++nextArg], 0); mprSetCmdlineLogging(1); } } else if (strcmp(argp, "--out") == 0) { if (nextArg >= argc) { err++; } else { output = argv[++nextArg]; mp->cslots = 1; mp->genSlots = 1; } } else if (strcmp(argp, "--search") == 0 || strcmp(argp, "--searchpath") == 0) { if (nextArg >= argc) { err++; } else { searchPath = argv[++nextArg]; } } else if (strcmp(argp, "--version") == 0 || strcmp(argp, "-V") == 0) { mprPrintfError("%s %s-%s\n", BIT_NAME, BIT_VERSION, BIT_NUMBER); return 0; } else if (strcmp(argp, "--require") == 0) { if (nextArg >= argc) { err++; } else { if (requiredModules == 0) { requiredModules = mprCreateList(-1, 0); } modules = sclone(argv[++nextArg]); /* Fix for Xcode and Visual Studio */ if (modules[0] == ' ' || scmp(modules, "null") == 0) { modules[0] = '\0'; } name = stok(modules, " \t", &tok); while (name != NULL) { require(requiredModules, name); name = stok(NULL, " \t", &tok); } } } else if (strcmp(argp, "--warn") == 0) { mp->warnOnError++; } else if (strcmp(argp, "--xml") == 0) { mp->xml = 1; } else { err++; break; } } if (argc == nextArg) { err++; } if (mp->genSlots == 0 && mp->listing == 0 && mp->html == 0 && mp->xml == 0 && mp->depends == 0) { mp->listing = 1; } if (mp->depends && requiredModules == 0) { requiredModules = mprCreateList(-1, 0); } if (err) { /* Examples: ejsmod file.mod # Defaults to --listing ejsmod --listing embedthis.mod ejsmod --out slots.h embedthis.mod */ mprPrintfError("Usage: %s [options] modules ...\n" " Ejscript module manager options:\n" " --cslots # Generate a C slot definitions file\n" " --html dir # Generate HTML documentation to the specified directory\n" " --listing # Create assembler listing files (default)\n" " --out file # Output file for all C slots (implies --cslots)\n" " --require \"modules\" # List of modules to preload\n" " --search ejsPath # Module file search path\n" " --version # Emit the program version information\n" " --warn # Warn about undocumented methods or parameters in doc\n\n", mpr->name); return -1; } /* Need an interpreter to load modules */ flags = EJS_FLAG_NO_INIT; if (mp->html || mp->xml) { flags |= EJS_FLAG_DOC; } if ((ejs = ejsCreateVM(0, 0, flags)) == 0) { return MPR_ERR_MEMORY; } if (ejsLoadModules(ejs, searchPath, requiredModules) < 0) { return MPR_ERR_CANT_READ; } mp->ejs = ejs; if (nextArg < argc) { if (process(mp, output, argc - nextArg, &argv[nextArg]) < 0) { err++; } } if (mp->errorCount > 0) { err = -1; } mprRemoveRoot(mp); ejsDestroyVM(ejs); mprDestroy(MPR_EXIT_DEFAULT); return err; }
MAIN(runProgramMain, int argc, char* argv[]) { Mpr *mpr; MprFile *out; char buf[256], *ep; int i, len, exitCode, sofar; mpr = mprCreate(argc, argv, NULL); #if TRACE_PROGRESS MprFile *f = mprOpen(mpr, "/tmp/r.log", O_CREAT|O_TRUNC|O_WRONLY, 0664); mprWriteFormat(f, "runProgram: argc %d\n", argc); for (i = 0; i < argc; i++) { mprWriteFormat(f, "runProgram: arg[%d] = %s\n", i, argv[i]); } mprFree(f); #endif if (argc < 2) { mprPrintfError(mpr, "Usage: runProgram exitCode args...\n"); exit(3); } exitCode = atoi(argv[1]); out = mprGetStdout(mpr); if (exitCode != 99) { /* * Echo the args */ for (i = 2; i < argc; ) { mprPuts(out, argv[i]); if (++i != argc) { mprPutc(out, ' '); } } mprPutc(out, '\n'); /* * Echo the CMD_ENV environment variable value */ ep = getenv("CMD_ENV"); if (ep) { mprPuts(out, "CMD_ENV="); mprPuts(out, ep); } else { mprPuts(out, "Can't find CMD_ENV"); } mprPutc(out, '\n'); mprFlush(out); } /* * Read the input */ sofar = 0; while ((len = (int) read(0, buf, sizeof(buf))) > 0) { sofar += (int) write(1, buf, len); } if (exitCode != 99) { mprPuts(out, "END"); mprPutc(out, '\n'); } mprFlush(out); return exitCode; }
MAIN(ejsCgiMain, int argc, char **argv) { cchar *searchPath, *argp; int nextArg, err; /* * Create the Embedthis Portable Runtime (MPR) and setup a memory failure handler */ mpr = mprCreate(argc, argv, ejsMemoryFailure); mprSetAppName(mpr, argv[0], 0, 0); if (strcmp(mprGetAppName(mpr), "ejscgi-debug") == 0) { debug++; } if (mprStart(mpr, MPR_START_EVENTS_THREAD) < 0) { mprError(mpr, "Can't start mpr services"); return EJS_ERR; } for (err = 0, nextArg = 1; nextArg < argc; nextArg++) { argp = argv[nextArg]; if (*argp != '-') { break; } if (strcmp(argp, "--debug") == 0 || strcmp(argp, "-d") == 0) { debug++; #if BLD_DEBUG } else if (strcmp(argp, "--dummy") == 0) { dummy++; #endif } else if (strcmp(argp, "--log") == 0 || strcmp(argp, "-l") == 0) { if (nextArg >= argc) { err++; } else { ejsStartLogging(mpr, argv[++nextArg]); } } else if (strcmp(argp, "--searchpath") == 0) { if (nextArg >= argc) { err++; } else { searchPath = argv[++nextArg]; } } else if (strcmp(argp, "--version") == 0 || strcmp(argp, "-V") == 0) { mprPrintfError(mpr, "%s %s\n" "Copyright (C) Embedthis Software 2003-2011\n" "Copyright (C) Michael O'Brien 2003-2011\n", BLD_NAME, BLD_VERSION); exit(0); } else { err++; break; } } if (err) { mprPrintfError(mpr, "Usage: %s [options]\n" " Options:\n" " --log logSpec # Diagnostic trace\n" " --searchpath ejsPath # Module search path\n" " --version # Emit the program version information\n\n", mpr->name); return -1; } if (initControlBlock() < 0) { error(NULL, 0, "Can't initialize control block"); exit(1); } // FAST CGI must update this currentDate = makeDateString(0); if (getRequest() < 0) { error(NULL, 0, "Can't get request"); } else { processRequest(); } if (responseCode && responseMsg) { fprintf(stderr, "ejscgi: ERROR: %s\n", responseMsg); } return 0; }
MAIN(ejsMain, int argc, char **argv, char **envp) { Mpr *mpr; EcCompiler *cp; Ejs *ejs; cchar *cmd, *className, *method, *homeDir; char *argp, *searchPath, *modules, *name, *tok, *extraFiles; int nextArg, err, ecFlags, stats, merge, bind, noout, debug, optimizeLevel, warnLevel, strict, i, next; /* Initialize Multithreaded Portable Runtime (MPR) */ mpr = mprCreate(argc, argv, 0); app = mprAllocObj(App, manageApp); mprAddRoot(app); mprAddStandardSignals(); if (mprStart(mpr) < 0) { mprError("Cannot start mpr services"); return EJS_ERR; } err = 0; className = 0; cmd = 0; method = 0; searchPath = 0; stats = 0; merge = 0; bind = 1; noout = 1; debug = 1; warnLevel = 1; optimizeLevel = 9; strict = 0; app->files = mprCreateList(-1, 0); app->iterations = 1; argc = mpr->argc; argv = (char**) mpr->argv; for (nextArg = 1; nextArg < argc; nextArg++) { argp = argv[nextArg]; if (*argp != '-') { break; } if (smatch(argp, "--bind")) { bind = 1; } else if (smatch(argp, "--class")) { if (nextArg >= argc) { err++; } else { className = argv[++nextArg]; } } else if (smatch(argp, "--chdir") || smatch(argp, "--home") || smatch(argp, "-C")) { if (nextArg >= argc) { err++; } else { homeDir = argv[++nextArg]; if (chdir((char*) homeDir) < 0) { mprError("Cannot change directory to %s", homeDir); } } #if BIT_UNIX_LIKE } else if (smatch(argp, "--chroot")) { /* Not documented or supported */ if (nextArg >= argc) { err++; } else { homeDir = mprGetAbsPath(argv[++nextArg]); if (chroot(homeDir) < 0) { if (errno == EPERM) { mprPrintfError("%s: Must be super user to use the --chroot option", mprGetAppName(mpr)); } else { mprPrintfError("%s: Cannot change change root directory to %s, errno %d", mprGetAppName(), homeDir, errno); } return 4; } } #endif } else if (smatch(argp, "--cmd") || smatch(argp, "-c")) { if (nextArg >= argc) { err++; } else { cmd = argv[++nextArg]; } #if BIT_WIN_LIKE } else if (smatch(argp, "--cygroot")) { if (nextArg >= argc) { err++; } else { app->cygroot = sclone(argv[++nextArg]); } #endif } else if (smatch(argp, "--debug")) { debug = 1; } else if (smatch(argp, "--debugger") || smatch(argp, "-D")) { mprSetDebugMode(1); } else if (smatch(argp, "--files") || smatch(argp, "-f")) { /* Compatibility with mozilla shell */ if (nextArg >= argc) { err++; } else { extraFiles = sclone(argv[++nextArg]); name = stok(extraFiles, " \t", &tok); while (name != NULL) { mprAddItem(app->files, sclone(name)); name = stok(NULL, " \t", &tok); } } } else if (smatch(argp, "--iterations") || smatch(argp, "-i")) { if (nextArg >= argc) { err++; } else { app->iterations = atoi(argv[++nextArg]); } } else if (smatch(argp, "--log")) { if (nextArg >= argc) { err++; } else { mprStartLogging(argv[++nextArg], 0); mprSetCmdlineLogging(1); } } else if (smatch(argp, "--method")) { if (nextArg >= argc) { err++; } else { method = argv[++nextArg]; } } else if (smatch(argp, "--name")) { /* Just ignore. Used to tag commands with a unique command line */ nextArg++; } else if (smatch(argp, "--nobind")) { bind = 0; } else if (smatch(argp, "--nodebug")) { debug = 0; } else if (smatch(argp, "--optimize")) { if (nextArg >= argc) { err++; } else { optimizeLevel = atoi(argv[++nextArg]); } } else if (smatch(argp, "-s")) { /* Compatibility with mozilla shell. Just ignore */ } else if (smatch(argp, "--search") || smatch(argp, "--searchpath")) { if (nextArg >= argc) { err++; } else { searchPath = argv[++nextArg]; } } else if (smatch(argp, "--standard")) { strict = 0; } else if (smatch(argp, "--stats")) { stats = 1; } else if (smatch(argp, "--strict")) { strict = 1; } else if (smatch(argp, "--require")) { if (nextArg >= argc) { err++; } else { if (app->modules == 0) { app->modules = mprCreateList(-1, 0); } modules = sclone(argv[++nextArg]); name = stok(modules, " \t", &tok); while (name != NULL) { require(name); name = stok(NULL, " \t", &tok); } } } else if (smatch(argp, "--verbose") || smatch(argp, "-v")) { mprStartLogging("stderr:2", 0); mprSetCmdlineLogging(1); } else if (smatch(argp, "--version") || smatch(argp, "-V")) { mprPrintf("%s-%s\n", BIT_VERSION, BIT_BUILD_NUMBER); return 0; } else if (smatch(argp, "--warn")) { if (nextArg >= argc) { err++; } else { warnLevel = atoi(argv[++nextArg]); } } else { err++; break; } } if (err) { /* If --method or --class is specified, then the named class.method will be run (method defaults to "main", class defaults to first class with a "main"). Examples: ejs ejs script.es arg1 arg2 arg3 ejs --class "Customer" --method "start" --files "script1.es script2.es" main.es */ mprPrintfError("Usage: %s [options] script.es [arguments] ...\n" " Ejscript shell program options:\n" " --class className # Name of class containing method to run\n" " --cmd ejscriptCode # Literal ejscript statements to execute\n" " --cygroot path # Set cygwin root for resolving script paths\n" " --debug # Use symbolic debugging information (default)\n" " --debugger # Disable timeouts to make using a debugger easier\n" " --files \"files..\" # Extra source to compile\n" " --log logSpec # Internal compiler diagnostics logging\n" " --method methodName # Name of method to run. Defaults to main\n" " --nodebug # Omit symbolic debugging information\n" " --optimize level # Set the optimization level (0-9 default is 9)\n" " --require 'module,...' # Required list of modules to pre-load\n" " --search ejsPath # Module search path\n" " --standard # Default compilation mode to standard (default)\n" " --stats # Print memory stats on exit\n" " --strict # Default compilation mode to strict\n" " --verbose | -v # Same as --log stderr:2 \n" " --version # Emit the compiler version information\n" " --warn level # Set the warning message level (0-9 default is 0)\n\n", mpr->name); return -1; } if ((ejs = ejsCreateVM(argc - nextArg, (cchar **) &argv[nextArg], 0)) == 0) { return MPR_ERR_MEMORY; } app->ejs = ejs; if (ejsLoadModules(ejs, searchPath, app->modules) < 0) { return MPR_ERR_CANT_READ; } ecFlags = 0; ecFlags |= (merge) ? EC_FLAGS_MERGE: 0; ecFlags |= (bind) ? EC_FLAGS_BIND: 0; ecFlags |= (noout) ? EC_FLAGS_NO_OUT: 0; ecFlags |= (debug) ? EC_FLAGS_DEBUG: 0; cp = app->compiler = ecCreateCompiler(ejs, ecFlags); if (cp == 0) { return MPR_ERR_MEMORY; } ecSetRequire(cp, app->modules); ecSetOptimizeLevel(cp, optimizeLevel); ecSetWarnLevel(cp, warnLevel); ecSetStrictMode(cp, strict); if (nextArg < argc) { mprAddItem(app->files, sclone(argv[nextArg])); } if (app->cygroot) { /* When cygwin invokes a script with shebang, it passes a cygwin path to the script The ejs --cygroot option permits ejscript to conver this to a native path */ for (next = 0; (name = mprGetNextItem(app->files, &next)) != 0; ) { if (*name == '/' || *name == '\\') { mprSetItem(app->files, next - 1, sjoin(app->cygroot, name, NULL)); } } } for (i = 0; !err && i < app->iterations; i++) { if (cmd) { if (interpretCommands(cp, cmd) < 0) { err++; } } else if (mprGetListLength(app->files) > 0) { if (interpretFiles(cp, app->files, argc - nextArg, &argv[nextArg], className, method) < 0) { err++; } } else { /* No args - run as an interactive shell */ if (interpretCommands(cp, NULL) < 0) { err++; } } } if (stats) { #if BIT_DEBUG mprSetLogLevel(1); mprPrintMem("Memory Usage", 1); #endif } if (!err) { err = mpr->exitStatus; } app->ejs = 0; mprTerminate(MPR_EXIT_DEFAULT, err); ejsDestroyVM(ejs); mprDestroy(MPR_EXIT_DEFAULT); return err; }
/* Interpret the code for a function */ static void interp(EjsMod *mp, EjsModule *module, EjsFunction *fun) { EjsOptable *optable, *opt; EjsCode *code; MprChar *currentLine; uchar *start; char argbuf[MPR_MAX_STRING], lineInfo[MPR_MAX_STRING], name[MPR_MAX_STRING]; char *currentFile, *src, *dest; int maxOp, opcode, lineNumber, stack, codeLen, address, stackEffect, nbytes, i, lastLine; mprAssert(mp); mprAssert(module); mprAssert(fun); /* Store so that getNum and getString can easily read instructions */ code = fun->body.code; mp->fun = fun; mp->module = module; mp->pc = code->byteCode; codeLen = code->codeLen; start = mp->pc; stack = 0; currentLine = 0; lineNumber = 0; currentFile = 0; lastLine = -1; optable = ejsGetOptable(mp); for (maxOp = 0, opt = optable; opt->name; opt++) { maxOp++; } while ((mp->pc - start) < codeLen) { address = (int) (mp->pc - start); opcode = *mp->pc++; argbuf[0] = '\0'; stackEffect = 0; if (opcode < 0 || opcode >= maxOp) { mprError("Bad opcode %x at address %d.\n", opcode, address); return; } opt = &optable[opcode]; if (mp->showAsm) { /* Output address [stack] opcode Format: "address: [stackDepth] opcode <args> ..." */ mprFprintf(mp->file, " %04d: [%d] %02x ", address, stack, opcode); } nbytes = decodeOperands(mp, opt, argbuf, (int) sizeof(argbuf), (int) (mp->pc - start), &stackEffect); if (mp->showAsm) { for (i = 24 - (nbytes * 3); i >= 0; i--) { mprFprintf(mp->file, "."); } for (dest = name, src = opt->name; *src; src++, dest++) { if (*src == '_') { *dest = *++src; } else { *dest = tolower((uchar) *src); } } *dest++ = '\0'; mprFprintf(mp->file, " %s %s\n", name, argbuf); } else { for (i = 24 - (nbytes * 3); i >= 0; i--) { mprFprintf(mp->file, " "); } mprFprintf(mp->file, " %s\n", argbuf); } stack += stackEffect; if (opcode == EJS_OP_RETURN_VALUE || opcode == EJS_OP_RETURN) { stack = 0; } if (stack < 0) { if (mp->warnOnError) { mprPrintfError("Instruction stack is negative %d\n", stack); } if (mp->exitOnError) { exit(255); } } ejsGetDebugInfo(mp->ejs, fun, mp->pc, ¤tFile, &lineNumber, ¤tLine); if (currentFile && currentLine && *currentLine && lineNumber != lastLine) { mprSprintf(lineInfo, sizeof(lineInfo), "%s:%d", currentFile, lineNumber); mprFprintf(mp->file, "\n # %-25s %w\n\n", lineInfo, currentLine); lastLine = lineNumber; } } }